📄 icd仿真器的源程序.txt
字号:
title "SA11a - PIC Programmer/Fixing the Code."
;
; SA11 - Checking Last Char for ":"
; SA11a - Put in "DEBUG" Check
; - Put in Simplified "RXBufReset"
; - Fixed up 16 Bit Variables to MPLAB Standard
;
; SA10 - Simplify the ASCII to Nybble Conversion
;
; SA9 - Make "Command" Upper Case Before Saving
;
; SA8 - Look for the Two Problems Before
; 1. "Invalid File" Message (Suspect Missing LF at the End of the Data Sent)
; 2. Garbage at "Ctrl-C"
; - Have to Make Space for Everything
;
; SA7 Finishes off with Adding the EEPROM Memory Clear. Also, the Cmdxxx Routines Disable
; Interrupts on Entry and Enable them Before Exit.
;
; SA6 has the following enhancements:
; 1. Some Minor Display Formatting
; 2. Before returning to the caller in an Error in Program or Verify, the Input line is
; polled until no characters are received for one second.
;
; SA5 has the following enhancements to SA4:
; 1. BlankCheck is Now a Subroutine
; 2. Programming Code Has Been Added
;
; SA4 is an enhancement from SA3 because:
; 1. Real Time Clock Added - One "Tick" Every 3 Timer Interrupt Entries
; 2. Extra Messages - All the Messages Required for the Program
; 3. Blank Checking is Carried Out
;
; SA3 goes beyond what SA2 did with the Serial and create the User Interface.
;
; The Programmer Commands are:
;
; E|F - Select Between EPROM or FLASH Parts
; P - Program, Download the Code
; B - Device Blank Check
; V - Verify the Contents of the (E)EPROM
; 1|2|4|8 - Run PIC in the Socket at the Specified Speed (in MHz)
;
; This Program Will Create the Interface and run the PIC. The Interface is RS-232 at 1200 bps.
;
;
; Hardware Notes:
; Reset is tied directly to Vcc and PWRT is Enabled.
; The PIC is a 16C61 Running with a 16 MHz Ceramic Resonator.
; RA0 is U2's Power Control (Active High)
; RA1 is Connected to the External Serial Line Output
; RA2 is Connected to the Low Value of the ECS-16000 Oscillator Speed Select
; RA3 is Connected to the High Value of the ECS-16000 Oscillator Speed Select
; RA4 is Connected to the External Serial Line Input
; RB0 is Connected to RS-232 "RX" Line from Host (Read Note above for Interrupt Requirements)
; RB1 is U2's Vpp Control
; RB2 is Programmer Reset
; RB3 is U2's Execution Enable (High to Enable Clock and _MCLR)
; RB4 is U2's RB6
; RB5 is U2's RB7
; RB6 is External Reset
; RB7 is Connected to RS-232 "TX" Line for the Host
; Modem Control Bits are Hardcoded as "ON"
;
; Myke Predko
; 98.11.02
;
LIST P=16C61, R=DEC ; 16C61 Runs at 16 MHz
errorlevel 0,-305
INCLUDE "p16c61.inc"
; Register Usage
CBLOCK 0x00C ; Start Registers at End of the Values
_w, _status, _fsr ; Execution Context Save Values
Flags ; Current Operation Values
RTClo, RTCHI, RTCycle ; Real Time Clock Variables
Temp, SpeedTemp, CSTemp
CCount
LineCount ; Programming Counters/Storage Areas
TData:2 ; Programming Storage - Formerly "TDataHI"/"TDatalo"
RXBit, TXBit ; How Many Bits Have Been XFerred
RXIn, TXOut ; Transmit/Receive Values
RXCycle, TXCycle ; Setup the Cycle Values
NextRX, NextINS, CmdReady ; Offsets into the RX Buffer for Data/Offsets
Command ; Command Entered in to the Programmer
PData:2 ; Data Transferred with U2 - Formerly ("Datalo"/"DataHi")
PC:2 ; Data Transferr Program Counter - Formerly "PClo"/"PCHi"
RXBuf ; #### - Put this at the End of the Variables
ENDC
RXBufEnd EQU 0x02F ; Mark the End of the RXBuffer
; Flag Offsets/Definitions
#define RXStart Flags,0 ; When Set, Have Received Start of Something
#define RXRead Flags,1 ; When Set, Are Reading Data from Host
#define TXStart Flags,2 ; Sending the TX Start Bit
#define Passthru Flags,3 ; Can Passthrough the PIC between External and Host
#define FlashEPROM Flags,4 ; Set Low for Flash (16C8x), High for EPROM
#define CurError Flags,5 ; Set if the Current Operation was in Error
#define LastError Flags,6 ; Set if the Last EPROM Program was in Error
#define Verify Flags,7 ; Set if the Programmer Code is Used to Verify
PAGE
__CONFIG _CP_OFF & _HS_OSC & _PWRTE_ON & _WDT_OFF
; Note that the WatchDog Timer is OFF
; Code for SA11
org 0
movlw RXBuf ; Setup the Locations for the Data
movwf NextRX
clrf Flags ; Clear the Status Flags
goto MainLine ; Skip Over Data Output Tables
PAGE
; TMR0 Interrupt Handler - Handle Serial Stuff
org 4 ; Interrupt Handler at Address 4
Int
movwf _w ; Save the Context Registers
movf STATUS, w
movwf _status
bcf STATUS, RP0 ; Make Sure we're in Bank 1
movf FSR, w ; Save the FSR Register
movwf _fsr
call Dlay4 ; Dlay 4 Cycles to Meet Intrinsic Delay Value
; Increment the RTC as Appropriate - 9 Cycles Intrinsically
decfsz RTCycle ; Increment the RTC?
goto Int_NotRTC ; Nope
movlw 3 ; Reset the Counter
movwf RTCycle
incf RTClo ; Increment the RTC Clock
btfsc STATUS, Z
incf RTCHI
goto Int_RX
Int_NotRTC ; Put in Proper Delay for NOT RTC
call Dlay4 ; Have to Dlay 6 Cycles for a Total of 9
goto Int_RX
; First, Check for a Received Character - Intrinsic Delay 26 Cycles
Int_RX
btfsc RXStart
goto Int_ReadChar ; Something's Already Coming In
btfss PORTB, 0
goto Int_StartRead ; Start Reading Something
call Dlay16 ; Dlay20 to get the Intrinsic RX Dlay of
call Dlay4 ; 26 Cycles
goto Int_TX
Int_StartRead ; Start Reading the Character
bsf RXStart ; Indicate that Something is Coming in
call Dlay16 ; Dlay18 to Get the Intrinsic RX Dlay of
goto $ + 1 ; 26 Cycles
goto Int_TX
Int_ReadChar ; Continue with the Character Read
btfsc RXRead ; Are we Reading Something?
goto Int_ContRead ; Yes, Continue Reading It
btfsc PORTB, 0 ; Did we Have a Glitch?
goto Int_Glitch ; Yes,
bsf RXRead ; Now, We're Reading
movlw 3
movwf RXCycle ; Setup the Cycle Count
movlw 8 ; Get the Number of Bits to Read (8 of Course)
movwf RXBit
call Dlay8 ; Dlay 12 Cycles to get the Intrinsic RX Dlay
call Dlay4
goto Int_TX
Int_Glitch ; Turn OFF the Flags and Continue
bcf RXStart
call Dlay8 ; Dlay 15 Cycles to get the Intrinsic RX
call Dlay4 ; Delay
goto $ + 1
nop
goto Int_TX
Int_ContRead ; Keep Reading in Values
decfsz RXCycle ; Are we at the End of a Cycle?
goto Int_ReadCycle ; Nope, Just Delay and Continue On
movf RXBit ; Are we At the End?
btfsc STATUS, Z
goto Int_CheckStop ; Yes, Check the Stop Bit
rrf PORTB, w ; No - Shift in the Data
rrf RXIn
decf RXBit ; Decrement the Number of Bits Left
movlw 3 ; Reset the Cycle Count
movwf RXCycle
call Dlay8 ; Dlay 8 to Get the Intrinsic Dlay of RX
goto Int_TX
Int_CheckStop ; At the Last Bit - Is it Valid?
bcf RXStart ; Clear the Active Flags
bcf RXRead
btfss PORTB, 0
goto IntCS_Skip ; No it's Not High - Ignore the Character
movf NextRX, w ; Setup the Buffer Pointer
movwf FSR
movf RXIn, w ; Save the Character
movwf INDF
incf NextRX, w ; Figure Out Where we Should Be
call RXBufReset
goto $ + 1
movwf NextRX
goto Int_TX
IntCS_Skip ; Invalid Character - No Stop Bit
call Dlay4 ; Dlay 6 to get Intrinsic RX Dlay
goto $ + 1
goto Int_TX
Int_ReadCycle ; Just Delay and Continue
call Dlay8 ; Have to Dlay 15 Cycles to Get the RX
call Dlay4 ; Intrinsic Delay of 26 Cycles
goto $ + 1
nop
goto Int_TX
; Next, Check for Transmitting a Character - Intrinsic Dlay 22 Cycles
Int_TX
btfsc TXStart ; Are we Sending Anything?
goto IntTX_Yes
call Dlay16 ; Have to Delay 18 Cycles to get the
goto $ + 1 ; Intrinsic TX Delay of 22 Cycles
goto Int_Passthru
IntTX_Yes ; Yes, We're Starting to XMit
movf TXCycle ; Are We Sending the Start Bit?
btfss STATUS, Z
goto IntTX_Send ; No - Send Some Data, Willya?
movlw 3 ; Wait 3 Cycles
movwf TXCycle
movlw 10 ; Actually Sending 9 Bits
movwf TXBit
call Dlay8 ; Dlay 9 Cycles to Get Intrinsic Delay of
nop ; 22 Cycles for TX
bcf PORTB, 7 ; Start Sending the Start Bit
goto Int_Passthru
IntTX_Send ; Now, Sending a New Bit?
decfsz TXCycle ; Check the Cycle
goto IntTX_NoBitSend ; Not Sending a Value
IntTX_BitSend ; Send the Next Available Bit?
decfsz TXBit ; Are we at the Last Bit?
goto IntTX_BitTX ; No, Something Else to Transmit
bcf TXStart ; All Finished with XMit
call Dlay8 ; Put in 8 Cycles to Meet with the Intrinsic TX Dlay of 23 Cycles
goto Int_Passthru
IntTX_NoBitSend
call Dlay8 ; Put in 10 Cycles to Meet the Intrinsic
goto $ + 1 ; TX Delay of 22 Cycles
goto Int_Passthru
IntTX_BitTX ; Can Actually Transmit the Bit
movlw 3 ; Reset the Cycle Count
movwf TXCycle
bsf STATUS, C ; Get Bit, But Make Sure High Put In
rrf TXOut
btfsc STATUS, C ; Do we Send a High?
goto IntTX_HIGH ; Yes...
nop ; Make Sure Cycles Match
bcf PORTB, 7
goto Int_Passthru
IntTX_HIGH ; Send the High Value
bsf PORTB, 7
goto Int_Passthru ; Make Sure Cycles Match
; Last, Check for RX/TX Passthrough - Dlay 15 Cycles
Int_Passthru
btfsc Passthru ; Do we Passthrough?
goto IntPT_Yes
call Dlay8 ; Wait 11 Cycles to Keep with Passthru
goto $ + 1 ; Intrinsic Delay of 15 Cycles
nop
goto IntEnd
IntPT_Yes ; Yes, we Passthrough, Send Bits back and Forth Data back
btfsc PORTA, 4 ; PORTA is the External Input Bit
goto IntPT_EHigh ; The External is High
nop
bcf PORTB, 7 ; Send out a Low
goto IntPT_H ; Now, See what the Host is Sending
IntPT_EHigh ; Send out the High Value
bsf PORTB, 7
goto IntPT_H ; Match the Cycles
IntPT_H ; Now, If the Host is High, Send to the External
btfsc PORTB, 0
goto IntPT_HHigh ; The Host Is High
nop
bcf PORTA, 1 ; The Host is Low
goto IntEnd
IntPT_HHigh ; Send the High Value
bsf PORTA, 1
goto IntEnd ; Cycle Match
IntEnd ; Finished with the Interrupt
clrf TMR0 ; Reset the Timer
bcf INTCON, T0IF ; Reset the Interrupt Flag
movf _fsr, w ; Restore the Context Registers and Return
movwf FSR
movf _status, w
movwf STATUS
swapf _w
swapf _w, w
retfie
PAGE
; Message Table
Msg
addwf PCL ; Get the Offset into the Program
Msg0 ; Welcome Message
dt "PIC Programmer", 0x0D, 0x0A, 0
Msg1 ; New Line
dt 0x0D, 0x0A, 0
Msg2 ; Help Screen
dt 0 ; TAKEN OUT 97.01.30 - Takes Up Too Much Space
Msg3 ; Invalid Message
dt " <==Invalid", 0x0D, 0x0A, 0
Msg4 ; Running Message
dt "Running", 0
Msg5 ; Blank Check Result Message
dt "Blank ", 0
Msg6 ; Error Message
dt "Error ", 0
Msg7 ; Jump Too Big Error
dt "Jump ", 0
Msg8 ; File Error
dt "File ", 0
Msg9 ; Start DownLoad for Program/Verify
dt "DownLoad", 0
Msg10 ; Indicate Timeout Happened for Download
dt " TimeOut", 0
Msg11 ; Put in Ctrl-C Message
dt " - Stop Ctrl-C", 0
PAGE
MainLine ; Initialize LCD and Variables/Handle Incoming Chars
clrf RTClo ; Clear the Real Time Clock Values
clrf RTCHI
movlw 3 ; Make Sure RTC Cycle Count is Correct
movwf RTCycle
clrf TXCycle ; Make Sure Everything is Initialized
clrf RXCycle
clrf TXBit
clrf RXBit
movlw 0x080 ; Initialize the Ports
movwf PORTB
movlw 0x002
movwf PORTA
bsf STATUS, RP0
movlw 0x010 ; Initialize PORTA
movwf TRISA & 0x07F
movlw 0x00035 ; Initialize PORTB
movwf TRISB & 0x07F
movlw 0x0D1 ; Setup Timer to work off Internal Clock at Half Speed
movwf OPTION_REG & 0x07F ; (At least for Timer; One Tick every four Instructions)
bcf STATUS, RP0
clrf TMR0 ; Start the Timer from Scratch
movlw 0x0A0 ; Enable the Timer Interrupt
movwf INTCON
PAGE
; Handle the Execution from here
#define noDebug
ifdef Debug
nop
nop
; movlw 1 ; Start a New Line
; call DispMSG
nop
nop
; clrw ; Put in the Welcoming Message
; call DispMSG
Prompt ; Print the Prompt on the Screen
nop
nop
; movlw 1 ; Start the New Line
; call DispMSG
else
movlw 1 ; Start a New Line
call DispMSG
clrw ; Put in the Welcoming Message
call DispMSG
Prompt ; Print the Prompt on the Screen
movlw 1 ; Start the New Line
call DispMSG
endif
movlw 'F' ; Assume the Flash First
btfsc FlashEPROM
movlw 'E'
call SendCHAR
movlw '>'
call SendCHAR
movlw ' '
call SendCHAR
clrf Command ; Nothing Entered Yet
bcf LastError ; See if Last Error Should be Set
btfsc CurError
bsf LastError ; It Should be, the Last one was an Error
bcf CurError ; Four Instructions is Really a Simple Shift
bcf Verify ; Make Sure that Programmer doesn't Verify
movf NextRX, w ; Make Sure Reading from the Start
movwf NextINS
Loop
movf NextINS, w ; See if the Value Has Moved
subwf NextRX, w
btfsc STATUS, Z
goto Loop ; It Hasn't, Keep Looping Around
movf NextINS, w ; Get the Instruction Read In
movwf FSR ; Output It
incf NextINS, w ; Point to the Next Value in the Buffer
call RXBufReset
movwf NextINS
movf INDF, w ; Get the Character That Was Just Read in
xorlw 8 ; Do we have a BackSpace Character?
btfss STATUS, Z
goto Loop_NotBS
movf Command ; Can Only BackSpace Over a Command
btfsc STATUS, Z
goto Loop ; Nothing There
movlw 8 ; Send the BackSpace
call SendCHAR
clrf Command ; Now you can Execute the Values
goto Loop ; Wait for the Next Character
Loop_NotBS ; Not a BackSpace - Enter (CR) or Line Feed?
xorlw 8 ^ 13
btfsc STATUS, Z
goto Loop_Enter ; Yes
xorlw 13 ^ 10
btfss STATUS, Z ; Treat a Line Feed the Same Way
goto Loop_NoEnter ; Else, Handle the Character
Loop_Enter
movf Command ; Can Only do if Something is There
btfsc STATUS, Z
goto Loop ; Nothing There... Ignore
goto Handle_Command ; Now, Execute the Command
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -