ca65 V2.17 - Git 582aa41 Main file : PROMER2.ca65 Current file: PROMER2.ca65 000000r 1 ; 000000r 1 ; ****** PROMER V2.1 ****** 000000r 1 ; 000000r 1 ; Based on original Acorn PROM Programmer Board (200.007) 000000r 1 ; Software 'PROMER' from Technical Manual Issue-2 Jan-1981 000000r 1 ; 000000r 1 ; Improved user interface with additional commands and support added for 74S287 256x4 PROM's 000000r 1 ; 000000r 1 ; Chris Oddy January 2021 000000r 1 ; 000000r 1 ; Execute from $2800 (START) 000000r 1 ; 000000r 1 .define DEBUG 'N' ; if set to 'Y' includes Breakpoint code 000000r 1 ; 000000r 1 ; Zeropage Registers 000000r 1 ; 000000r 1 ppctrl := $80 ; control byte for EPROM program pulse (1 byte) 000000r 1 rdctrl := $81 ; control byte for EPROM read (1 byte) 000000r 1 vectrl := $82 ; control byte for EPROM verify (1 byte) 000000r 1 prctrl := $83 ; control byte for EPROM program (1 byte) 000000r 1 hilow := $83 ; PROM high ($00) or low nibble ($FF) (1 byte) 000000r 1 size := $84 ; PROM size 256 bytes ($00) or 512 bytes ($01) (1 byte) 000000r 1 type := $85 ; PROM or EPROM (0 or 1) (1 byte) 000000r 1 device := $86 ; pointer to DEVTAB current device ($FF if not set) 000000r 1 temp := $87 ; temporary storage (1 byte) 000000r 1 ctrl := $88 ; control byte (1 byte) 000000r 1 from := $89 ; from address (2 bytes) 000000r 1 to := $8B ; to address (2 bytes) 000000r 1 point := $8D ; pointer in E/PROM routines (2 bytes) 000000r 1 fill := $8D ; fill byte in FILL command (1 byte) 000000r 1 column := $8E ; column in DUMP command (1 byte) 000000r 1 crc := $8F ; CRC checksum (1 byte) 000000r 1 mask := $90 ; bit mask in PROM (1 byte) 000000r 1 tries := $91 ; number of tries in PROM program (1 byte) 000000r 1 extra := $92 ; number of extra blows in PROM program (1 byte) 000000r 1 count := $93 ; counter (1 byte) 000000r 1 page := $94 ; page counter (1 byte) 000000r 1 buffer := $0100 ; command input buffer (64 bytes) 000000r 1 ; 000000r 1 ; Hardware Addresses 000000r 1 ; 000000r 1 keybrd := $0E21 ; keyboard 000000r 1 porta := $1980 ; 8255 port A - PROM Data D0 to D3 / EPROM Data D0 to D7 000000r 1 portb := $1981 ; 8255 port B - PROM/EPROM Address A0 to A7 000000r 1 portc := $1982 ; 8255 port C - C0 PROM/EPROM Address A8 000000r 1 ; C1 EPROM Pin 22 Address A9 000000r 1 ; C2 EPROM Pin 19 Address A10 except 2758 AR(0) 000000r 1 ; C3 EPROM Pin 18 CE/PGM or Address A11, PROM CE 000000r 1 ; C4 EPROM Pin 20 OE or PD/PGM 000000r 1 ; C5 PROM RW Control (1 enables read) 000000r 1 ; C6 PROM Power Control (1 enables +10.2V VCC) 000000r 1 ; C7 EPROM Power Control (1 enables +26V VPP) 000000r 1 ctrlrg := $1983 ; 8255 control register 000000r 1 ; 000000r 1 ; ASCII Codes 000000r 1 ; 000000r 1 LF := $0A ; LineFeed 000000r 1 CR := $0D ; Carriage Return 000000r 1 CAN := $18 ; CANcel 000000r 1 ESC := $1B ; ESCape 000000r 1 SPACE := $20 ; space 000000r 1 DEL := $7F ; DELete 000000r 1 ; 000000r 1 ; OS Calls 000000r 1 ; 000000r 1 OSWRCH := $FFF4 ; WRite CHaracter to output channel 000000r 1 OSRDCH := $FFE3 ; ReaD CHaracter from input channel 000000r 1 OSCRLF := $FFED ; write CRLF to output channel 000000r 1 OSECHO := $FFE6 ; reads character from Input channel and ECHOs it to output channel 000000r 1 OSCLI := $FFF7 ; call Command Line Interpreter 000000r 1 ; 000000r 1 .org $2800 002800 1 ; 002800 1 ; ; *** Entry Point *** 002800 1 20 93 36 START: jsr OUTSTR ; output start-up message 002803 1 0D 0A 2A 2A .byte CR,LF,"*** PROMER V2.1 ***",CR,LF,LF 002807 1 2A 20 50 52 00280B 1 4F 4D 45 52 00281B 1 EA nop 00281C 1 A2 FF ldx #$FF 00281E 1 86 86 stx device ; clear current device 002820 1 002820 1 .if DEBUG = 'Y' ; BRK vector redirection required for DEBUG 002820 1 lda #BRKPNT 002820 1 sta BRKVEC+1 002820 1 .endif 002820 1 002820 1 20 B0 36 RESTRT: jsr COMIN ; read command into buffer 002823 1 20 29 28 jsr PRCLI ; action command 002826 1 4C 20 28 jmp RESTRT ; and do it again 002829 1 002829 1 A2 FF PRCLI: ldx #$FF ; *** PROMER2 Command Line Interpreter *** 00282B 1 D8 cld ; X is command table pointer 00282C 1 A0 00 nxtcom: ldy #$00 ; Y is buffer pointer 00282E 1 20 06 37 jsr RDIBUF ; ignore leading spaces in buffer 002831 1 B9 00 01 lda buffer,y ; check for CR and no command 002834 1 C9 0D cmp #CR 002836 1 D0 01 bne nocr ; no - continue to extract command 002838 1 60 rts ; return 002839 1 88 nocr: dey ; backup buffer pointer 00283A 1 C8 chkcom: iny ; increment buffer pointer 00283B 1 E8 inx ; increment command table pointer 00283C 1 BD 66 28 rdcom: lda COMTAB,x ; read command table 00283F 1 F0 17 beq addres ; end of string found (0) ? 002841 1 D9 00 01 cmp buffer,y ; compare with buffer 002844 1 F0 F4 beq chkcom ; if equal compare whole string 002846 1 E8 noteos: inx ; until a difference is found 002847 1 BD 66 28 lda COMTAB,x 00284A 1 D0 FA bne noteos ; find end of string (00) 00284C 1 E8 inx ; adjust command table pointer for next command string 00284D 1 E8 inx ; i.e. point at 2nd byte of address 00284E 1 B9 00 01 lda buffer,y 002851 1 C9 2E cmp #'.' ; was command abbreviated ? 002853 1 D0 D7 bne nxtcom ; no - try next command from table 002855 1 C8 iny ; increment buffer pointer past '.' 002856 1 CA dex ; backup command table pointer to end of string (0) 002857 1 CA dex 002858 1 E8 addres: inx ; increment pointer to command address 002859 1 BD 66 28 lda COMTAB,x ; load MSB 00285C 1 85 8A sta from+1 ; save 00285E 1 BD 67 28 lda COMTAB+1,x ; load LSB 002861 1 85 89 sta from ; save 002863 1 6C 89 00 jmp (from) ; and call command routine 002866 1 002866 1 ; Command Table 002866 1 42 4C 41 4E COMTAB: .byte "BLANK",CR,$00,>BLANK,DEVICE, 002873 1 43 45 00 29 002877 1 8F 002878 1 44 55 4D 50 .byte "DUMP",$00,>DUMP, 00287C 1 00 2A 75 00287F 1 46 49 4C 4C .byte "FILL",$00,>FILL, 002883 1 00 2A C3 002886 1 48 45 4C 50 .byte "HELP",CR,$00,>HELP,HLPBLK,HLPDEV,HLPDMP,HLPFIL,HLPMEM,HLPPGM,HLPRED,HLPVER,MEM, 002901 1 32 35 002903 1 50 52 4F 47 .byte "PROGRAM",$00,>PROGRM, 002907 1 52 41 4D 00 00290B 1 32 A0 00290D 1 52 45 41 44 .byte "READ",$00,>READ, 002911 1 00 32 EA 002914 1 56 45 52 49 .byte "VERIFY",$00,>VERIFY, 002918 1 46 59 00 33 00291C 1 3A 00291D 1 2A 00 32 87 .byte "*",$00,>OSCOM,COMMES,, if not specified then current device is displayed if one set 00298F 1 20 06 37 DEVICE: jsr RDIBUF ; ignore leading spaces 002992 1 B9 00 01 lda buffer,y ; is there a parameter ? 002995 1 C9 0D cmp #CR 002997 1 D0 23 bne setdev ; yes - get parameter 002999 1 20 B6 33 jsr CHKDEV ; no - so display current device, has one been set ? 00299C 1 90 1D bcc devrtn ; no - return 00299E 1 20 93 36 jsr OUTSTR ; yes - display it 0029A1 1 44 65 76 69 .byte "Device: " 0029A5 1 63 65 3A 20 0029A9 1 EA nop 0029AA 1 A6 86 ldx device ; pointer to device name 0029AC 1 A0 04 ldy #$04 ; device is 4 characters long 0029AE 1 BD 25 2A outdev: lda DEVTAB,x ; get device character 0029B1 1 20 F4 FF jsr OSWRCH ; output 0029B4 1 E8 inx ; increment device table pointer 0029B5 1 88 dey ; decrement character count 0029B6 1 D0 F6 bne outdev ; do all 4 characters 0029B8 1 20 ED FF jsr OSCRLF 0029BB 1 60 devrtn: rts ; and return 0029BC 1 A2 00 setdev: ldx #$00 ; device table pointer 0029BE 1 86 86 stx device ; clear current device 0029C0 1 84 87 sty temp ; save input buffer pointer 0029C2 1 A4 87 find: ldy temp ; retrieve input buffer pointer 0029C4 1 A9 00 lda #$00 0029C6 1 85 93 sta count ; reset entry counter 0029C8 1 B9 00 01 fnddev: lda buffer,y ; get next character from input buffer 0029CB 1 DD 25 2A cmp DEVTAB,x ; compare with entry in table 0029CE 1 D0 30 bne nxtdev ; not this entry 0029D0 1 E8 inx ; increment device table pointer 0029D1 1 C8 iny ; increment input buffer pointer 0029D2 1 E6 93 inc count ; increment entry counter 0029D4 1 A5 93 lda count 0029D6 1 C9 04 cmp #$04 0029D8 1 D0 EE bne fnddev ; compare all four characters of device 0029DA 1 20 24 37 jsr ENDTST ; found a match - check for end of input buffer 0029DD 1 CA dex ; backup device table pointer to start of entry 0029DE 1 CA dex 0029DF 1 CA dex 0029E0 1 CA dex 0029E1 1 86 86 stx device ; and save device table entry 0029E3 1 A0 05 ldy #$05 0029E5 1 BD 29 2A found: lda DEVTAB+4,x ; read parameters from table (6 bytes) 0029E8 1 99 80 00 sta ppctrl,y ; and store 0029EB 1 E8 inx ; increment device table pointer 0029EC 1 88 dey ; decrement parameter pointer 0029ED 1 10 F6 bpl found ; save all parameters 0029EF 1 20 93 36 jsr OUTSTR 0029F2 1 44 65 76 69 .byte "Device Set",CR,LF 0029F6 1 63 65 20 53 0029FA 1 65 74 0D 0A 0029FE 1 EA nop 0029FF 1 60 rts ; and return 002A00 1 E8 nxtdev: inx ; pass over rest of this device entry 002A01 1 C8 iny 002A02 1 E6 93 inc count 002A04 1 A5 93 lda count 002A06 1 C9 0A cmp #$0A ; each entry is 10 bytes 002A08 1 D0 F6 bne nxtdev 002A0A 1 E0 50 cpx #$50 ; check for end of table 002A0C 1 90 B4 bcc find ; no - try and match next device 002A0E 1 20 93 36 jsr OUTSTR ; yes - no match found ? 002A11 1 49 6E 76 61 .byte "Invalid Device ?",CR,LF 002A15 1 6C 69 64 20 002A19 1 44 65 76 69 002A23 1 EA nop 002A24 1 60 rts ; return 002A25 1 002A25 1 ; *** PROM/EPROM Device Data *** 002A25 1 32 38 37 48 DEVTAB: .byte "287H" ; 74S287 256 byte x 4-bits PROM 002A29 1 00 .byte 0 ; fusible link PROM type 002A2A 1 00 .byte 0 ; 256 bytes 002A2B 1 00 .byte 0 ; high nibble 002A2C 1 00 .byte 0 ; not used 002A2D 1 00 .byte 0 ; not used 002A2E 1 00 .byte 0 ; not used 002A2F 1 002A2F 1 32 38 37 4C .byte "287L" ; 74S287 256 byte x 4-bits PROM 002A33 1 00 .byte 0 ; fusible link PROM type 002A34 1 00 .byte 0 ; 256 bytes 002A35 1 FF .byte $FF ; low nibble 002A36 1 00 .byte 0 ; not used 002A37 1 00 .byte 0 ; not used 002A38 1 00 .byte 0 ; not used 002A39 1 002A39 1 35 37 31 48 .byte "571H" ; 74S571 512 byte x 4-bits PROM 002A3D 1 00 .byte 0 ; fusible link PROM type 002A3E 1 01 .byte 1 ; 512 bytes 002A3F 1 00 .byte 0 ; high nibble 002A40 1 00 .byte 0 ; not used 002A41 1 00 .byte 0 ; not used 002A42 1 00 .byte 0 ; not used 002A43 1 002A43 1 35 37 31 4C .byte "571L" ; 74S571 512 byte x 4-bits PROM 002A47 1 00 .byte 0 ; fusible link PROM type 002A48 1 01 .byte 1 ; 512 bytes 002A49 1 FF .byte $FF ; low nibble 002A4A 1 00 .byte 0 ; not used 002A4B 1 00 .byte 0 ; not used 002A4C 1 00 .byte 0 ; not used 002A4D 1 002A4D 1 32 37 35 38 .byte "2758" ; 2758 1 Kbyte EPROM 002A51 1 01 .byte 1 ; EPROM 002A52 1 01 .byte 1 ; 1 Kbytes 002A53 1 90 .byte $90 ; control byte for BLOW 002A54 1 80 .byte $80 ; control byte for VERIFY 002A55 1 00 .byte $00 ; control byte for READ 002A56 1 07 .byte $07 ; control byte for program pulse 002A57 1 002A57 1 32 37 31 36 .byte "2716" ; 2716 2 Kbyte EPROM 002A5B 1 01 .byte 1 ; EPROM type 002A5C 1 02 .byte 2 ; 2 Kbytes 002A5D 1 90 .byte $90 ; control byte for BLOW 002A5E 1 80 .byte $80 ; control byte for VERIFY 002A5F 1 00 .byte $00 ; control byte for READ 002A60 1 07 .byte $07 ; control byte for program pulse 002A61 1 002A61 1 32 35 31 36 .byte "2516" ; 2516 2 Kbyte EPROM (same as 2716) 002A65 1 01 .byte 1 ; EPROM 002A66 1 02 .byte 2 ; 2 Kbytes 002A67 1 90 .byte $90 ; control byte for BLOW 002A68 1 80 .byte $80 ; control byte for VERIFY 002A69 1 00 .byte $00 ; control byte for READ 002A6A 1 07 .byte $07 ; control byte for program pulse 002A6B 1 002A6B 1 32 35 33 32 .byte "2532" ; 2532 4 Kbyte EPROM 002A6F 1 01 .byte 1 ; EPROM 002A70 1 04 .byte 4 ; 4 Kbytes 002A71 1 90 .byte $90 ; control byte for BLOW 002A72 1 00 .byte $00 ; control byte for VERIFY 002A73 1 00 .byte $00 ; control byte for READ 002A74 1 08 .byte $08 ; control byte for program pulse 002A75 1 002A75 1 ; DUMP Command - Dump block of Memory 002A75 1 ; takes three parameters: and addresses and optional 002A75 1 A2 89 DUMP: ldx #from ; point X at address 002A77 1 20 D4 36 jsr PARAM ; get address from input buffer 002A7A 1 A2 8B ldx #to ; point X at address 002A7C 1 20 D4 36 jsr PARAM ; get address from input buffer 002A7F 1 E6 8B inc to ; add one to address 002A81 1 D0 02 bne dnoinc 002A83 1 E6 8C inc to+1 002A85 1 A2 8E dnoinc: ldx #column ; and optionally number of 002A87 1 20 DA 36 jsr HXPARA ; in output 002A8A 1 D0 04 bne dodump ; use default number of columns ? 002A8C 1 A9 08 lda #$08 ; yes = 8 002A8E 1 85 8E sta column 002A90 1 20 24 37 dodump: jsr ENDTST ; test for end of input buffer 002A93 1 A5 8E nxtlin: lda column 002A95 1 85 87 sta temp 002A97 1 20 ED FF jsr OSCRLF ; output address 002A9A 1 A2 89 ldx #from 002A9C 1 20 53 37 jsr OUTADR 002A9F 1 A9 7C lda #'|' ; and a delimiter '|' 002AA1 1 20 F4 FF jsr OSWRCH 002AA4 1 A0 00 ldy #$00 ; y=0 002AA6 1 A2 89 ldx #from ; point X at from address 002AA8 1 A9 20 nxtcol: lda #SPACE 002AAA 1 20 F4 FF jsr OSWRCH 002AAD 1 B1 89 lda (from),y ; get a byte 002AAF 1 20 76 37 jsr OUTBYT ; output 002AB2 1 20 42 37 jsr INCCMP ; check if last one 002AB5 1 F0 06 beq finish ; if so return 002AB7 1 C6 87 dec temp ; otherwise check for end of line 002AB9 1 D0 ED bne nxtcol ; if not output next byte 002ABB 1 F0 D6 beq nxtlin ; last column - output next line 002ABD 1 20 ED FF finish: jsr OSCRLF ; finished - output 2 CRLF's 002AC0 1 4C ED FF jmp OSCRLF ; and return 002AC3 1 002AC3 1 ; *** FILL Command - Fill block of Memory *** 002AC3 1 ; takes three parameters: and addresses and optional byte to with 002AC3 1 A2 89 FILL: ldx #from ; point X at address 002AC5 1 20 D4 36 jsr PARAM ; get address from input buffer 002AC8 1 A2 8B ldx #to ; point X at address 002ACA 1 20 D4 36 jsr PARAM ; get address from input buffer 002ACD 1 18 clc 002ACE 1 E6 8B inc to ; add one to address 002AD0 1 90 02 bcc fnoinc 002AD2 1 E6 8C inc to+1 002AD4 1 A2 8D fnoinc: ldx #fill ; point X at temp for parameter 002AD6 1 20 DA 36 jsr HXPARA ; get fill byte 002AD9 1 D0 04 bne dofill ; specified ? 002ADB 1 A9 FF lda #$FF ; no - use default value $FF 002ADD 1 85 8D sta fill 002ADF 1 20 24 37 dofill: jsr ENDTST ; test for end of input buffer 002AE2 1 A2 89 ldx #from 002AE4 1 A0 00 ldy #$00 002AE6 1 A5 8D nxtfil: lda fill ; byte to fill with 002AE8 1 91 89 sta (from),y ; store the byte 002AEA 1 20 42 37 jsr INCCMP ; increment pointers and compare 002AED 1 D0 F7 bne nxtfil ; finished ? 002AEF 1 60 rts ; return 002AF0 1 002AF0 1 20 93 36 HELP: jsr OUTSTR ; *** HELP Command - output help *** 002AF3 1 0D 0A 54 68 .byte CR,LF,"The following commands are available:",CR,LF,LF 002AF7 1 65 20 66 6F 002AFB 1 6C 6C 6F 77 002B1D 1 42 4C 41 4E .byte "BLANK",CR,LF 002B21 1 4B 0D 0A 002B24 1 44 45 56 49 .byte "DEVICE ",CR,LF 002B28 1 43 45 20 3C 002B2C 1 64 65 76 69 002B35 1 44 55 4D 50 .byte "DUMP ",CR,LF 002B39 1 20 3C 66 72 002B3D 1 6F 6D 3E 20 002B51 1 46 49 4C 4C .byte "FILL ",CR,LF 002B55 1 20 3C 66 72 002B59 1 6F 6D 3E 20 002B6A 1 4D 45 4D 20 .byte "MEM ",CR,LF 002B6E 1 3C 66 72 6F 002B72 1 6D 3E 0D 0A 002B76 1 50 52 4F 47 .byte "PROGRAM ",CR,LF 002B7A 1 52 41 4D 20 002B7E 1 3C 66 72 6F 002B86 1 52 45 41 44 .byte "READ ",CR,LF 002B8A 1 20 3C 66 72 002B8E 1 6F 6D 3E 0D 002B93 1 56 45 52 49 .byte "VERIFY ",CR,LF 002B97 1 46 59 20 3C 002B9B 1 66 72 6F 6D 002BA2 1 2A 20 3C 4F .byte "* ",CR,LF,LF 002BA6 1 53 20 43 6F 002BAA 1 6D 6D 61 6E 002BB3 1 54 79 70 65 .byte "Type HELP for help on a",CR,LF 002BB7 1 20 48 45 4C 002BBB 1 50 20 3C 63 002BD6 1 70 61 72 74 .byte "particular command.",CR,LF,LF 002BDA 1 69 63 75 6C 002BDE 1 61 72 20 63 002BEC 1 43 6F 6D 6D .byte "Commands can be abbreviated with '.'",CR,LF,LF 002BF0 1 61 6E 64 73 002BF4 1 20 63 61 6E 002C13 1 EA nop 002C14 1 60 rts 002C15 1 002C15 1 ; *** HELP BLANK Command - output help *** 002C15 1 20 93 36 HLPBLK: jsr OUTSTR 002C18 1 0D 0A 54 68 .byte CR,LF,"The BLANK command takes no parameters",CR,LF,LF 002C1C 1 65 20 42 4C 002C20 1 41 4E 4B 20 002C42 1 54 68 65 20 .byte "The command carries out a blank check of",CR 002C46 1 63 6F 6D 6D 002C4A 1 61 6E 64 20 002C6B 1 74 68 65 20 .byte "the selected device.",CR,LF,LF 002C6F 1 73 65 6C 65 002C73 1 63 74 65 64 002C82 1 EA nop 002C83 1 60 rts 002C84 1 002C84 1 ; *** HELP DEVICE Command - output help *** 002C84 1 20 93 36 HLPDEV: jsr OUTSTR 002C87 1 0D 0A 54 68 .byte CR,LF,"The DEVICE command takes one parameter",CR,LF,LF 002C8B 1 65 20 44 45 002C8F 1 56 49 43 45 002CB2 1 20 20 20 44 .byte " DEVICE ",CR,LF,LF 002CB6 1 45 56 49 43 002CBA 1 45 20 3C 64 002CC7 1 3C 64 65 76 .byte " specifies the programmable",CR,LF 002CCB 1 69 63 65 3E 002CCF 1 20 73 70 65 002CEC 1 64 65 76 69 .byte "device which can be one of:",CR,LF 002CF0 1 63 65 20 77 002CF4 1 68 69 63 68 002D09 1 50 52 4F 4D .byte "PROMs: 287L, 287H, 571L or 571H",CR,LF 002D0D 1 73 3A 09 32 002D11 1 38 37 4C 2C 002D2A 1 45 50 52 4F .byte "EPROMs: 2758, 2516, 2716 or 2532",CR,LF,LF 002D2E 1 4D 73 3A 20 002D32 1 32 37 35 38 002D4D 1 EA nop 002D4E 1 60 rts 002D4F 1 002D4F 1 ; *** HELP DUMP Command - output help *** 002D4F 1 20 93 36 HLPDMP: jsr OUTSTR 002D52 1 0D 0A 54 68 .byte CR,LF,"The DUMP command takes 3 parameters",CR,LF,LF 002D56 1 65 20 44 55 002D5A 1 4D 50 20 63 002D7A 1 20 20 20 44 .byte " DUMP ()",CR,LF,LF 002D7E 1 55 4D 50 20 002D82 1 3C 66 72 6F 002D9C 1 54 68 65 20 .byte "The command dumps the specified memory",CR,LF 002DA0 1 63 6F 6D 6D 002DA4 1 61 6E 64 20 002DC4 1 72 61 6E 67 .byte "range to the screen with the address",CR,LF 002DC8 1 65 20 74 6F 002DCC 1 20 74 68 65 002DEA 1 66 6F 6C 6C .byte "followed by 8 bytes.",CR,LF,LF 002DEE 1 6F 77 65 64 002DF2 1 20 62 79 20 002E01 1 54 68 65 20 .byte "The third optional parameter specifies",CR,LF 002E05 1 74 68 69 72 002E09 1 64 20 6F 70 002E29 1 61 20 64 69 .byte "a different number of bytes to display",CR,LF 002E2D 1 66 66 65 72 002E31 1 65 6E 74 20 002E51 1 6F 6E 20 61 .byte "on a line.",CR,LF,LF 002E55 1 20 6C 69 6E 002E59 1 65 2E 0D 0A 002E5E 1 41 6C 6C 20 .byte "All values are in hex.",CR,LF,LF 002E62 1 76 61 6C 75 002E66 1 65 73 20 61 002E77 1 EA nop 002E78 1 60 rts 002E79 1 002E79 1 ; *** HELP FILL Command - output help *** 002E79 1 20 93 36 HLPFIL: jsr OUTSTR 002E7C 1 0D 0A 54 68 .byte CR,LF,"The FILL command takes three parameters",CR,LF,LF 002E80 1 65 20 46 49 002E84 1 4C 4C 20 63 002EA8 1 20 20 20 46 .byte " FILL ",CR,LF,LF 002EAC 1 49 4C 4C 20 002EB0 1 3C 66 72 6F 002EC5 1 54 68 65 20 .byte "The command fills the specified memory",CR,LF 002EC9 1 63 6F 6D 6D 002ECD 1 61 6E 64 20 002EED 1 72 61 6E 67 .byte "range with the value .",CR,LF,LF 002EF1 1 65 20 77 69 002EF5 1 74 68 20 74 002F0C 1 41 6C 6C 20 .byte "All values are in hex.",CR,LF,LF 002F10 1 76 61 6C 75 002F14 1 65 73 20 61 002F25 1 EA nop 002F26 1 60 rts 002F27 1 ; *** HELP MEM Command - output help *** 002F27 1 20 93 36 HLPMEM: jsr OUTSTR 002F2A 1 0D 0A 54 68 .byte CR,LF,"The MEM command takes one parameter",CR,LF,LF 002F2E 1 65 20 4D 45 002F32 1 4D 20 63 6F 002F52 1 20 20 20 4D .byte " MEM ",CR,LF,LF 002F56 1 45 4D 20 3C 002F5A 1 66 72 6F 6D 002F62 1 54 68 65 20 .byte "The command displays the address",CR,LF 002F66 1 63 6F 6D 6D 002F6A 1 61 6E 64 20 002F8B 1 61 6E 64 20 .byte "and current contents of that address.",CR,LF,LF 002F8F 1 63 75 72 72 002F93 1 65 6E 74 20 002FB3 1 50 72 65 73 .byte "Pressing the U key will move 'up' to",CR,LF 002FB7 1 73 69 6E 67 002FBB 1 20 74 68 65 002FD9 1 74 68 65 20 .byte "the next address, pressing V will move",CR,LF 002FDD 1 6E 65 78 74 002FE1 1 20 61 64 64 003001 1 27 64 6F 77 .byte "'down' to the previous address.",CR,LF,LF 003005 1 6E 27 20 74 003009 1 6F 20 74 68 003023 1 54 68 65 20 .byte "The contents can be changed by typing a hex value.",CR,LF,LF 003027 1 63 6F 6E 74 00302B 1 65 6E 74 73 003058 1 50 72 65 73 .byt "Pressing any other key will exit.",CR,LF,LF 00305C 1 73 69 6E 67 003060 1 20 61 6E 79 00307C 1 EA nop 00307D 1 60 rts 00307E 1 00307E 1 ; *** HELP PROGRAM Command - output help *** 00307E 1 20 93 36 HLPPGM: jsr OUTSTR 003081 1 0D 0A 54 68 .byte CR,LF,"The PROGRAM command takes one parameter",CR,LF,LF 003085 1 65 20 50 52 003089 1 4F 47 52 41 0030AD 1 20 20 20 50 .byte " PROGRAM ",CR,LF,LF 0030B1 1 52 4F 47 52 0030B5 1 41 4D 20 3C 0030C1 1 50 72 6F 67 .byte "Programs the selected device with the",CR,LF 0030C5 1 72 61 6D 73 0030C9 1 20 74 68 65 0030E8 1 64 61 74 61 .byte "data stored at address .",CR,LF,LF 0030EC 1 20 73 74 6F 0030F0 1 72 65 64 20 003109 1 EA nop 00310A 1 60 rts 00310B 1 00310B 1 ; *** HELP READ Command - output help *** 00310B 1 20 93 36 HLPRED: jsr OUTSTR 00310E 1 0D 0A 54 68 .byte CR,LF,"The READ command takes one parameter",CR,LF,LF 003112 1 65 20 52 45 003116 1 41 44 20 63 003137 1 20 20 20 52 .byte " READ ",CR,LF,LF 00313B 1 45 41 44 20 00313F 1 3C 66 72 6F 003148 1 52 65 61 64 .byte "Reads the selected device and writes",CR,LF 00314C 1 73 20 74 68 003150 1 65 20 73 65 00316E 1 74 68 65 20 .byte "the data to the address.",CR,LF,LF 003172 1 64 61 74 61 003176 1 20 74 6F 20 003190 1 EA nop 003191 1 60 rts 003192 1 003192 1 ; *** HELP VERIFY Command - output help *** 003192 1 20 93 36 HLPVER: jsr OUTSTR 003195 1 0D 0A 54 68 .byte CR,LF,"The VERIFY command takes one parameter",CR,LF,LF 003199 1 65 20 56 45 00319D 1 52 49 46 59 0031C0 1 20 20 20 56 .byte " VERIFY ",CR,LF,LF 0031C4 1 45 52 49 46 0031C8 1 59 20 3C 66 0031D3 1 52 65 61 64 .byte "Reads the selected device and compares",CR,LF 0031D7 1 73 20 74 68 0031DB 1 65 20 73 65 0031FB 1 74 68 65 20 .byte "the contents with the data stored at",CR,LF 0031FF 1 63 6F 6E 74 003203 1 65 6E 74 73 003221 1 61 64 64 72 .byte "address .",CR,LF,LF 003225 1 65 73 73 20 003229 1 3C 66 72 6F 003233 1 EA nop 003234 1 60 rts 003235 1 003235 1 ; *** MEM Command - read/modify memory *** 003235 1 ; takes one parameter: address 003235 1 A2 89 MEM: ldx #from ; point X at address 003237 1 20 D4 36 jsr PARAM ; get address from input buffer 00323A 1 20 24 37 jsr ENDTST ; test for end of input 00323D 1 20 ED FF wraddr: jsr OSCRLF ; output CR LF 003240 1 20 53 37 jsr OUTADR ; output address 003243 1 CA dex ; backup X to point at from address 003244 1 CA dex 003245 1 A1 00 wrdata: lda ($00,x) ; read data from memory location 003247 1 85 87 sta temp ; save it 003249 1 20 76 37 jsr OUTBYT ; output byte 00324C 1 20 E3 FF jsr OSRDCH ; read input channel 00324F 1 A8 tay 003250 1 20 0E 37 jsr HEXKEY ; hex key pressed ? 003253 1 B0 15 bcs updown ; no - try up and down 003255 1 A0 04 ldy #$04 003257 1 06 87 shift: asl temp ; shift old byte one digit left 003259 1 88 dey 00325A 1 D0 FB bne shift 00325C 1 05 87 ora temp ; OR new digit in 00325E 1 81 00 sta ($00,x) ; alter memory location contents 003260 1 A9 7F lda #DEL ; move cursor over old byte 003262 1 20 F4 FF jsr OSWRCH ; with two deletes 003265 1 20 F4 FF jsr OSWRCH 003268 1 D0 DB bne wrdata ; write out new data 00326A 1 C0 55 updown: cpy #'U' ; up key 'U' pressed ? 00326C 1 D0 08 bne down 00326E 1 E6 89 inc from ; increment address 003270 1 D0 CB bne wraddr ; then rewrite it 003272 1 E6 8A inc from+1 003274 1 B0 C7 bcs wraddr 003276 1 C0 56 down: cpy #'V' ; down key 'V' pressed ? 003278 1 D0 0A bne crlf ; some other key ? - output CR LF and return 00327A 1 A5 89 lda from ; decrement address 00327C 1 D0 02 bne nodec 00327E 1 C6 8A dec from+1 003280 1 C6 89 nodec: dec from 003282 1 B0 B9 bcs wraddr ; always branch to rewrite address 003284 1 4C ED FF crlf: jmp OSCRLF ; output CR LF and return 003287 1 003287 1 ; *** OS Command *** 003287 1 A0 00 OSCOM: ldy #$00 ; move command in buffer down one to overwrite '*' 003289 1 B9 01 01 movcom: lda buffer+1,y ; get command from input buffer 00328C 1 99 00 01 sta buffer,y ; put back in input buffer 00328F 1 C9 0D cmp #CR ; until CR found 003291 1 F0 0A beq calcom ; finished 003293 1 C8 iny ; else increment pointer 003294 1 C0 3F cpy #$3F ; check for end of buffer (64 characters) 003296 1 D0 F1 bne movcom ; and move rest of command 003298 1 A9 0D lda #CR ; end of buffer reached 00329A 1 99 00 01 sta buffer,y ; put a CR at end of buffer and 00329D 1 4C F7 FF calcom: jmp OSCLI ; pass to OS and return 0032A0 1 0032A0 1 ; *** PROGRAM Command - program device *** 0032A0 1 ; takes one parameter: address of data 0032A0 1 20 B6 33 PROGRM: jsr CHKDEV ; check a device has been set 0032A3 1 90 44 bcc prts ; if carry clear no device set - return 0032A5 1 A2 89 ldx #from ; point X at address 0032A7 1 20 D4 36 jsr PARAM ; get address from input buffer 0032AA 1 20 24 37 jsr ENDTST ; check for end of input buffer 0032AD 1 20 42 29 prep: jsr CBLANK ; check device is blank 0032B0 1 20 F9 33 jsr CONTIN ; continue ? 0032B3 1 D0 34 bne prts ; no - return 0032B5 1 20 6B 36 jsr INIPTR ; initialise pointers for programming 0032B8 1 20 29 34 jsr PRGMES ; output Programming message 0032BB 1 A6 85 ldx type ; call either PROM Program (0) or EPROM Program (1) 0032BD 1 D0 06 bne eprog 0032BF 1 20 D9 35 jsr PPROG ; call PROM Program routine 0032C2 1 4C E1 32 jmp pdone 0032C5 1 A5 83 eprog: lda prctrl ; program EPROM - load control byte 0032C7 1 A4 84 ldy size ; get EPROM size 0032C9 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 0032CB 1 F0 0C beq eptwo ; branch if 2K 0032CD 1 30 0F bmi epone ; branch if 1K 0032CF 1 20 D7 34 jsr EPROG ; program 4K device (1st quarter) 0032D2 1 09 04 ora #$04 ; control byte for 2nd quarter (A10 high, A11 low) 0032D4 1 20 D7 34 jsr EPROG ; program 2nd quarter 0032D7 1 49 0C eor #$0C ; control byte for 3rd quarter (A10 low, A11 high) 0032D9 1 20 D7 34 eptwo: jsr EPROG ; program 2K device 1st half / 3rd quarter 0032DC 1 09 04 ora #$04 ; control byte for 2nd half / 4th quarter (A10 high) 0032DE 1 20 D7 34 epone: jsr EPROG ; program 1K device / 2nd half / 4th quarter 0032E1 1 20 ED FF pdone: jsr OSCRLF 0032E4 1 20 12 34 jsr REPEAT ; do it again ? 0032E7 1 F0 C4 beq prep ; yes - repeat 0032E9 1 60 prts: rts ; otherwise return 0032EA 1 0032EA 1 ; *** READ Command - read device into memory *** 0032EA 1 ; takes one parameter:
0032EA 1 20 B6 33 READ: jsr CHKDEV ; check a device has been set ? 0032ED 1 90 FA bcc prts ; if carry clear no device set - return 0032EF 1 A2 89 ldx #from ; point X at address 0032F1 1 20 D4 36 jsr PARAM ; get address from input buffer 0032F4 1 20 24 37 jsr ENDTST ; check for end of input buffer 0032F7 1 20 93 36 jsr OUTSTR 0032FA 1 52 65 61 64 .byte "Reading Device: " 0032FE 1 69 6E 67 20 003302 1 44 65 76 69 00330A 1 EA nop 00330B 1 20 6B 36 jsr INIPTR ; initialise pointers and CRC 00330E 1 A6 85 ldx type ; call either PROM Read (0) or EPROM Read (1) 003310 1 D0 06 bne eread 003312 1 20 55 35 jsr PREAD ; PROM Read routine 003315 1 4C 37 33 jmp rdone ; done 003318 1 A9 00 eread: lda #$00 ; load initial control byte (A10 and A11 low) 00331A 1 A4 84 ldy size ; get EPROM size 00331C 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 00331E 1 F0 0C beq ertwo ; branch if 2K 003320 1 30 0F bmi erone ; branch if 1K 003322 1 20 6D 34 jsr EREAD ; read 4K device (1st quarter) 003325 1 A9 04 lda #$04 ; control byte for 2nd quarter (A10 high, A11 low) 003327 1 20 6D 34 jsr EREAD ; read 2nd quarter 00332A 1 A9 08 lda #$08 ; control byte for 3rd quarter (A10 low, A11 high) 00332C 1 20 6D 34 ertwo: jsr EREAD ; read 2K device 1st half / 3rd quarter 00332F 1 09 04 ora #$04 ; control byte for 2nd half / 4th quarter (A10 high) 003331 1 20 6D 34 erone: jsr EREAD ; read 1K device / 2nd half / 4th quarter 003334 1 20 64 37 jsr CRCOUT ; output CRC 003337 1 4C ED FF rdone: jmp OSCRLF ; CR LF and return 00333A 1 00333A 1 ; *** VERIFY Command - verify device against memory *** 00333A 1 ; takes one parameter: address for data 00333A 1 20 B6 33 VERIFY: jsr CHKDEV ; check a device has been set ? 00333D 1 90 67 bcc vnodev ; if carry clear no device set - return 00333F 1 A2 89 ldx #from ; point X at address 003341 1 20 D4 36 jsr PARAM ; get address from input buffer 003344 1 20 24 37 jsr ENDTST ; check for end of input buffer 003347 1 20 93 36 vrep: jsr OUTSTR 00334A 1 56 65 72 69 .byte "Verifying Device: " 00334E 1 66 79 69 6E 003352 1 67 20 44 65 00335C 1 EA nop 00335D 1 20 6B 36 jsr INIPTR ; initialise pointers and CRC 003360 1 A6 85 ldx type ; call either PROM Verify (0) or EPROM Verify (1) 003362 1 D0 07 bne ever 003364 1 20 99 35 jsr PVERFY ; PROM Verify routine 003367 1 F0 26 beq verok ; verify OK 003369 1 D0 3C bne vernok ; verify not OK 00336B 1 A5 82 ever: lda vectrl ; EPROM verify - load initial control byte (A10 and A11 low) 00336D 1 A4 84 ldy size ; get EPROM size 00336F 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 003371 1 F0 10 beq evtwo ; branch if 2K 003373 1 30 15 bmi evone ; branch if 1K 003375 1 20 A0 34 jsr EVERFY ; verify 4K device (1st quarter) 003378 1 D0 2D bne vernok 00337A 1 09 04 ora #$04 ; control byte for 2nd quarter (A10 high, A11 low) 00337C 1 20 A0 34 jsr EVERFY ; verify 2nd quarter 00337F 1 D0 26 bne vernok ; verify fail - branch 003381 1 49 0C eor #$0C ; control byte for 3rd quarter (A10 low, A11 high) 003383 1 20 A0 34 evtwo: jsr EVERFY ; verify 2K device 1st half / 3rd quarter 003386 1 D0 1F bne vernok ; verify fail - branch 003388 1 09 04 ora #$04 ; control byte for 2nd half / 4th quarter (A10 high) 00338A 1 20 A0 34 evone: jsr EVERFY ; verify 1K device / 2nd half / 4th quarter 00338D 1 D0 18 bne vernok ; verify fail - branch 00338F 1 20 93 36 verok: jsr OUTSTR ; verify OK - output message 003392 1 0D 0A 4F 4B .byte CR,LF,"OK" 003396 1 EA nop 003397 1 A6 85 ldx type 003399 1 F0 03 beq nocrc 00339B 1 20 64 37 jsr CRCOUT ; CRC 00339E 1 20 ED FF nocrc: jsr OSCRLF ; and CR LF 0033A1 1 20 12 34 verrpt: jsr REPEAT ; do it again ? 0033A4 1 F0 A1 beq vrep ; yes - repeat 0033A6 1 60 vnodev: rts ; otherwise return 0033A7 1 20 93 36 vernok: jsr OUTSTR ; verify not OK - output message 0033AA 1 0D 0A 46 41 .byte CR,LF,"FAIL",CR,LF 0033AE 1 49 4C 0D 0A 0033B2 1 EA nop 0033B3 1 4C A1 33 jmp verrpt ; repeat ? 0033B6 1 0033B6 1 ; Check a Device has been set 0033B6 1 38 CHKDEV: sec ; set carry (device set) 0033B7 1 A6 86 ldx device ; device will be $FF if device set 0033B9 1 E8 inx 0033BA 1 D0 17 bne devset ; yes - return set 0033BC 1 20 93 36 jsr OUTSTR ; no - output message 0033BF 1 44 65 76 69 .byte "Device Not Set ?",CR,LF 0033C3 1 63 65 20 4E 0033C7 1 6F 74 20 53 0033D1 1 EA nop 0033D2 1 18 clc ; clear carry - no device set 0033D3 1 60 devset: rts ; and return 0033D4 1 0033D4 1 ; Output "Device (Not) Blank" Message 0033D4 1 ; on entry if Z=1 Blank 0033D4 1 08 BLAMES: php ; save Z 0033D5 1 20 93 36 jsr OUTSTR 0033D8 1 0D 0A 44 65 .byte CR,LF,"Device " 0033DC 1 76 69 63 65 0033E0 1 20 0033E1 1 EA nop 0033E2 1 28 plp ; retrieve Z 0033E3 1 F0 08 beq blank ; print Blank or Not Blank dependant on Z 0033E5 1 20 93 36 jsr OUTSTR 0033E8 1 4E 6F 74 20 .byte "Not " 0033EC 1 EA nop 0033ED 1 20 93 36 blank: jsr OUTSTR 0033F0 1 42 6C 61 6E .byte "Blank",CR,LF 0033F4 1 6B 0D 0A 0033F7 1 EA nop 0033F8 1 60 rts ; and return 0033F9 1 0033F9 1 ; Output "Continue ?" message and get Reply 0033F9 1 20 93 36 CONTIN: jsr OUTSTR ; output message 0033FC 1 43 6F 6E 74 .byte "Continue ?" 003400 1 69 6E 75 65 003404 1 20 3F 003406 1 EA nop 003407 1 20 E6 FF jsr OSECHO ; get reply 00340A 1 48 pha 00340B 1 20 ED FF jsr OSCRLF 00340E 1 68 pla 00340F 1 C9 59 cmp #'Y' ; if yes Z=1 003411 1 60 rts ; return 003412 1 003412 1 ; Output "Repeat ?" message and get Reply 003412 1 20 93 36 REPEAT: jsr OUTSTR ; output message 003415 1 52 65 70 65 .byte "Repeat ?" 003419 1 61 74 20 3F 00341D 1 EA nop 00341E 1 20 E6 FF jsr OSECHO ; get reply 003421 1 48 pha 003422 1 20 ED FF jsr OSCRLF 003425 1 68 pla 003426 1 C9 59 cmp #'Y' ; if yes Z=1 003428 1 60 rts ; return 003429 1 003429 1 ; Output "Programming:" Message 003429 1 20 93 36 PRGMES: jsr OUTSTR 00342C 1 50 72 6F 67 .byte "Programming: " 003430 1 72 61 6D 6D 003434 1 69 6E 67 3A 003439 1 EA nop 00343A 1 60 rts ; and return 00343B 1 00343B 1 ; **** EPROM ROUTINES **** 00343B 1 00343B 1 ; *** EPROM Blank *** 00343B 1 ; no entry parameters, return Z=1 if blank 00343B 1 85 88 EBLANK: sta ctrl ; save control byte 00343D 1 A9 90 lda #$90 ; set Port A (Data) to input 00343F 1 8D 83 19 sta ctrlrg 003442 1 A9 00 lda #$00 003444 1 85 94 sta page ; clear page counter 003446 1 A8 tay ; and byte pointer 003447 1 A5 94 ecpage: lda page ; get page counter (A8 and A9) 003449 1 05 88 ora ctrl ; OR in control byte 00344B 1 8D 82 19 sta portc ; and update port C 00344E 1 8C 81 19 ecnloc: sty portb ; set address LSB 003451 1 AD 80 19 lda porta ; read EPROM data 003454 1 C9 FF cmp #$FF ; blank ? 003456 1 D0 14 bne ecfail ; branch if not 003458 1 C8 iny ; next location 003459 1 D0 EC bne ecpage ; do all 256 bytes of page 00345B 1 A9 2A lda #'*' ; output a * for each page checked 00345D 1 20 F4 FF jsr OSWRCH 003460 1 E6 94 inc page ; increment page counter 003462 1 A5 94 lda page ; read page counter 003464 1 C9 04 cmp #$04 003466 1 D0 DF bne ecpage ; do all 4 pages 003468 1 08 php ; save status 003469 1 A5 88 lda ctrl ; reload control byte 00346B 1 28 plp ; retrieve status 00346C 1 60 ecfail: rts ; and return (Z=1 if blank) 00346D 1 00346D 1 ; *** EPROM Read *** 00346D 1 85 88 EREAD: sta ctrl ; save control byte 00346F 1 A9 90 lda #$90 ; set Port A, data to input 003471 1 8D 83 19 sta ctrlrg 003474 1 A9 00 lda #$00 003476 1 85 94 sta page ; clear page counter 003478 1 A8 tay ; and byte pointer 003479 1 A5 94 erpage: lda page ; get page counter (A8 and A9) 00347B 1 05 88 ora ctrl ; combine with control byte 00347D 1 8D 82 19 sta portc ; and update port C 003480 1 8C 81 19 ernloc: sty portb ; set address 003483 1 AD 80 19 lda porta ; read EPROM location 003486 1 91 8D sta (point),y ; store it 003488 1 20 7C 36 jsr CRC ; add to CRC 00348B 1 C8 iny ; next location 00348C 1 D0 F2 bne ernloc ; do all 256 bytes of page 00348E 1 E6 8E inc point+1 ; increment address pointer MSB 003490 1 A9 2A lda #'*' ; output a * for each page read 003492 1 20 F4 FF jsr OSWRCH 003495 1 E6 94 inc page ; increment page counter 003497 1 A5 94 lda page ; read page counter 003499 1 C9 04 cmp #$04 00349B 1 D0 DC bne erpage ; do all 4 pages 00349D 1 A5 88 lda ctrl ; reload control byte 00349F 1 60 rts ; and return 0034A0 1 0034A0 1 ; *** EPROM Verify *** 0034A0 1 ; no entry parameters, on exit Z=1 if verify OK 0034A0 1 85 88 EVERFY: sta ctrl ; save control byte 0034A2 1 A9 90 lda #$90 ; set Port A, data to input 0034A4 1 8D 83 19 sta ctrlrg 0034A7 1 A9 00 lda #$00 0034A9 1 85 94 sta page ; clear page counter 0034AB 1 A8 tay ; and byte pointer 0034AC 1 A5 94 evpage: lda page ; get page counter (A8 and A9) 0034AE 1 05 88 ora ctrl ; OR with ctrl 0034B0 1 8D 82 19 sta portc ; and update port C 0034B3 1 8C 81 19 evnloc: sty portb ; set address 0034B6 1 AD 80 19 lda porta ; read EPROM 0034B9 1 20 7C 36 jsr CRC ; add to CRC 0034BC 1 D1 8D cmp (point),y ; compare with memory 0034BE 1 D0 16 bne evrtn ; return with Z=0 0034C0 1 C8 iny ; next location 0034C1 1 D0 F0 bne evnloc ; do all 256 bytes of page 0034C3 1 E6 8E inc point+1 ; increment address pointer MSB 0034C5 1 A9 2A lda #'*' ; output a * for each page checked 0034C7 1 20 F4 FF jsr OSWRCH 0034CA 1 E6 94 inc page ; increment page counter 0034CC 1 A5 94 lda page ; read page counter 0034CE 1 C9 04 cmp #$04 0034D0 1 D0 DA bne evpage ; do all 4 pages 0034D2 1 A5 88 lda ctrl ; reload control byte 0034D4 1 A2 00 ldx #$00 ; Z=1 0034D6 1 60 evrtn: rts ; and return 0034D7 1 0034D7 1 ; *** EPROM Program *** 0034D7 1 85 88 EPROG: sta ctrl ; save control byte 0034D9 1 A9 80 lda #$80 ; all ports output 0034DB 1 8D 83 19 sta ctrlrg 0034DE 1 A9 00 lda #$00 0034E0 1 85 93 sta count 0034E2 1 A8 tay 0034E3 1 A5 93 eppage: lda count ; page counter (A8 and A9) 0034E5 1 05 88 ora ctrl ; OR with ctrl 0034E7 1 8D 82 19 sta portc ; and update port C 0034EA 1 8C 81 19 epnloc: sty portb ; set address 0034ED 1 AD 21 0E lda keybrd ; check for escape key 0034F0 1 C9 1B cmp #ESC 0034F2 1 D0 01 bne noesc 0034F4 1 00 brk 0034F5 1 B1 8D noesc: lda (point),y ; read from memory 0034F7 1 8D 80 19 sta porta ; send to port A data 0034FA 1 20 19 35 jsr FLIPBT ; and apply program pulse 0034FD 1 C8 goon: iny ; next location 0034FE 1 D0 EA bne epnloc ; do all 256 bytes 003500 1 E6 8E inc point+1 ; increment pointer MSB 003502 1 E6 93 inc count 003504 1 A9 2A lda #'*' ; output a * for each page programmed 003506 1 20 F4 FF jsr OSWRCH 003509 1 E6 94 inc page 00350B 1 A5 93 lda count 00350D 1 C9 04 cmp #$04 00350F 1 D0 D2 bne eppage ; do all 4 pages 003511 1 A9 90 lda #$90 003513 1 8D 83 19 sta ctrlrg ; switch things off 003516 1 A5 88 lda ctrl ; retrieve control byte 003518 1 60 rts ; and return 003519 1 003519 1 ; EPROM Programming Pulse 003519 1 A5 80 FLIPBT: lda ppctrl 00351B 1 8D 83 19 sta ctrlrg ; flip bit defined in ppctrl 00351E 1 A2 19 ldx #$19 ; now wait 50mS 003520 1 C6 87 dlylp: dec temp 003522 1 D0 FC bne dlylp 003524 1 CA dex 003525 1 D0 F9 bne dlylp 003527 1 49 01 eor #$01 003529 1 8D 83 19 sta ctrlrg ; return bit to previous level 00352C 1 60 rts 00352D 1 00352D 1 ; **** Fusible Link PROM Routines **** 00352D 1 00352D 1 ; *** PROM BLANK **** 00352D 1 ; no entry parameters, return Z=1 if blank 00352D 1 A0 00 PBLANK: ldy #$00 ; reset byte pointer 00352F 1 A6 84 ldx size ; 256 or 512 bytes (0 or 1) 003531 1 A9 90 lda #$90 ; set control byte for reading (Port A input) 003533 1 8D 83 19 sta ctrlrg 003536 1 A9 30 lda #$30 ; set port C for lower half C5=1 for read, C0(A8)=0 003538 1 8D 82 19 pbfull: sta portc 00353B 1 8C 81 19 pbpage: sty portb ; set address LSB 00353E 1 AD 80 19 lda porta ; read PROM data 003541 1 29 0F and #$0F ; mask lower nibble 003543 1 D0 0F bne pbfail ; blank (0) ? - branch if not 003545 1 C8 iny ; next location 003546 1 D0 F3 bne pbpage ; read all 256 bytes of page 003548 1 A9 2A lda #'*' ; output a * for each page checked 00354A 1 20 F4 FF jsr OSWRCH 00354D 1 A9 31 lda #$31 ; set port C for upper half C5(PROM RW)=1 Read, C0(A8) = 1 00354F 1 CA dex 003550 1 F0 E6 beq pbfull ; do the other half if 512 byte PROM 003552 1 A9 00 lda #$00 ; set Z 003554 1 60 pbfail: rts ; and return (Z=1 if blank) 003555 1 003555 1 ; *** PROM Read *** 003555 1 ; no entry parameters, no return values 003555 1 A0 00 PREAD: ldy #$00 ; reset byte pointer 003557 1 A6 84 ldx size ; 256 or 512 bytes (0 or 1) 003559 1 A9 90 lda #$90 ; set control byte for reading (Port A input) 00355B 1 8D 83 19 sta ctrlrg 00355E 1 A9 20 lda #$20 ; set port C for lower half C5(PROM RW)=1 Read, C0(A8)=0 003560 1 8D 82 19 prfull: sta portc 003563 1 8C 81 19 prpage: sty portb ; set address LSB 003566 1 B1 89 lda (from),y ; get current data from destination location 003568 1 24 83 bit hilow ; check for upper or lower nibble 00356A 1 30 0E bmi prlow ; lower - branch 00356C 1 29 0F and #$0F ; upper nibble - mask and save lower half 00356E 1 85 87 sta temp ; of current data 003570 1 AD 80 19 lda porta ; read byte from PROM 003573 1 0A asl a ; shift to upper nibble 003574 1 0A asl a 003575 1 0A asl a 003576 1 0A asl a 003577 1 4C 83 35 jmp prcom ; and combine data 00357A 1 29 F0 prlow: and #$F0 ; save upper nibble of current data 00357C 1 85 87 sta temp 00357E 1 AD 80 19 lda porta ; load byte from PROM 003581 1 29 0F and #$0F ; mask off lower nibble 003583 1 05 87 prcom: ora temp ; assemble new byte 003585 1 91 89 sta (from),y ; and put it back 003587 1 C8 iny ; increment byte pointer 003588 1 D0 D9 bne prpage ; read all 256 bytes of page 00358A 1 A9 2A lda #'*' ; output a * for each page read 00358C 1 20 F4 FF jsr OSWRCH 00358F 1 CA dex ; decrement PROM size 003590 1 D0 06 bne prrts ; when not zero ($FF) finished 003592 1 E6 8A inc from+1 ; increment memory pointer MSB 003594 1 A9 21 lda #$21 ; set port C for upper half C5(PROM RW)=1 Read, C0(A8)=1 003596 1 D0 C8 bne prfull ; and do the other half if 512 bytes 003598 1 60 prrts: rts ; and return 003599 1 003599 1 ; *** PROM Verify *** 003599 1 ; no entry parameters, on exit Z=1 if verify OK 003599 1 A0 00 PVERFY: ldy #$00 ; reset byte pointer 00359B 1 A6 84 ldx size ; 256 or 512 bytes (0 or 1) 00359D 1 A5 8A lda from+1 ; save a copy of from address MSB for repeat 00359F 1 85 87 sta temp 0035A1 1 A9 90 lda #$90 ; set control byte for reading (Port A input) 0035A3 1 8D 83 19 sta ctrlrg 0035A6 1 A9 20 lda #$20 ; set port C for lower half C5(PROM RW)=1 Read, C0(A8)=0 0035A8 1 8D 82 19 pvfull: sta portc 0035AB 1 8C 81 19 pvpage: sty portb ; set address (A0 to A7) 0035AE 1 B1 89 lda (from),y ; get data from memory 0035B0 1 24 83 bit hilow ; check for upper or lower nibble 0035B2 1 30 04 bmi pvlow ; lower - branch 0035B4 1 4A lsr a ; upper - shift upper to lower 0035B5 1 4A lsr a 0035B6 1 4A lsr a 0035B7 1 4A lsr a 0035B8 1 4D 80 19 pvlow: eor porta ; match against data in PROM 0035BB 1 29 0F and #$0F ; keep lower nibble, result should be 0 0035BD 1 D0 13 bne pvnok ; if not return with Z=0 0035BF 1 C8 pnoflg: iny ; increment byte pointer 0035C0 1 D0 E9 bne pvpage ; read all 256 bytes of page 0035C2 1 A9 2A lda #'*' ; output a * for each page verified 0035C4 1 20 F4 FF jsr OSWRCH 0035C7 1 CA dex ; decrement PROM size 0035C8 1 D0 06 bne pvok ; when not zero ($FF) finished 0035CA 1 E6 8A inc from+1 ; increment memory pointer MSB 0035CC 1 A9 21 lda #$21 ; set port C for upper half C5(PROM RW)=1 Read, C0(A8)=1 0035CE 1 D0 D8 bne pvfull ; and do the upper half if 512 bytes 0035D0 1 A2 00 pvok: ldx #$00 ; Z=1 0035D2 1 08 pvnok: php 0035D3 1 A5 87 lda temp 0035D5 1 85 8A sta from+1 0035D7 1 28 plp 0035D8 1 60 rts ; and return 0035D9 1 0035D9 1 ; *** PROM Program *** 0035D9 1 A0 00 PPROG: ldy #$00 ; reset byte pointer 0035DB 1 A2 00 ldx #$00 ; set A8=0 for first 256 bytes 0035DD 1 A9 08 halfb: lda #$08 ; start on most significant bit 0035DF 1 85 90 sta mask 0035E1 1 A9 80 forbit: lda #$80 ; no of tries at blowing each location 0035E3 1 85 91 sta tries 0035E5 1 A9 10 lda #$10 ; no of extra pulses after blowing 0035E7 1 85 92 sta extra 0035E9 1 20 09 36 jsr PCORE ; go and blow a bit 0035EC 1 46 90 lsr mask ; step to next bit in byte 0035EE 1 90 F1 bcc forbit ; do all four bits 0035F0 1 C8 iny 0035F1 1 D0 EA bne halfb ; and for all 256 bytes 0035F3 1 A9 2A lda #'*' ; output a * for each page programmed 0035F5 1 20 F4 FF jsr OSWRCH 0035F8 1 E0 01 cpx #$01 ; if A8=1 then we have completed 2nd page of 512 byte PROM 0035FA 1 F0 0A beq ppfin ; so finished 0035FC 1 A6 84 ldx size ; check PROM size 256 or 512 byte (0 or 1) 0035FE 1 F0 06 beq ppfin ; if 256 byte then we are finished 003600 1 E6 8A inc from+1 ; 512 byte - increment memory pointer MSB 003602 1 A2 01 ldx #$01 ; set A8=1 003604 1 D0 D7 bne halfb ; and do the other half 003606 1 C6 8A ppfin: dec from+1 ; restore memory pointer MSB 003608 1 60 rts ; and exit 003609 1 003609 1 ; Blow a PROM Bit 003609 1 A9 80 PCORE: lda #$80 ; set up port for programming (all outputs) 00360B 1 8D 83 19 sta ctrlrg 00360E 1 8C 81 19 sty portb ; set address - LSB 003611 1 8A txa ; and A8 003612 1 09 08 ora #$08 ; add control bits C3(PROM CE)=1 inactive 003614 1 8D 82 19 sta portc 003617 1 B1 89 lda (from),y ; load data to blow 003619 1 24 83 bit hilow ; blowing upper or lower nibble ? 00361B 1 30 04 bmi low 00361D 1 6A ror a ; shift upper nibble down 00361E 1 6A ror a 00361F 1 6A ror a 003620 1 6A ror a 003621 1 25 90 low: and mask ; mask off current bit 003623 1 F0 45 beq pcorx ; if zero nothing to program so return 003625 1 8D 80 19 sta porta ; set bit to program 003628 1 A9 0D lda #$0D ; flip power on C6(PROM Power Control)=1 ON 00362A 1 8D 83 19 sta ctrlrg 00362D 1 EA nop ; delay for program pulse width 00362E 1 EA nop 00362F 1 EA nop 003630 1 EA nop 003631 1 EA nop 003632 1 A9 06 lda #$06 ; flip enable on C3(PROM CE)=0 active 003634 1 8D 83 19 sta ctrlrg 003637 1 EA nop ; delay for program pulse width 003638 1 EA nop 003639 1 A9 07 lda #$07 ; enable off C3(PROM CE)=1 inactive 00363B 1 8D 83 19 sta ctrlrg 00363E 1 A9 0C lda #$0C 003640 1 8D 83 19 sta ctrlrg ; power off C6 (PROM Power Control)=0 OFF 003643 1 A9 90 lda #$90 ; set port A to input to verify bit 003645 1 8D 83 19 sta ctrlrg 003648 1 8C 81 19 sty portb ; set address again - LSB 00364B 1 8A txa ; and A8 00364C 1 09 20 ora #$20 ; add control bits C5(PROM RW)=1 Read), C3(PROM CE)=0 active 00364E 1 8D 82 19 sta portc 003651 1 AD 80 19 lda porta ; get bit 003654 1 25 90 and mask 003656 1 D0 0E bne blown ; good the bits blown 003658 1 C6 91 dec tries ; try to blow again 00365A 1 D0 AD bne PCORE 00365C 1 98 tya 00365D 1 48 pha 00365E 1 20 93 36 jsr OUTSTR ; print a. for each failed bit 003661 1 2E .byte "." 003662 1 EA nop 003663 1 68 pla 003664 1 A8 tay 003665 1 60 rts ; and give up 003666 1 C6 92 blown: dec extra ; extra blows for luck 003668 1 D0 9F bne PCORE 00366A 1 60 pcorx: rts ; and return 00366B 1 00366B 1 ; Initialises pointers 00366B 1 A6 89 INIPTR: ldx from ; copy from address to point 00366D 1 86 8D stx point 00366F 1 A6 8A ldx from+1 003671 1 86 8E stx point+1 003673 1 A2 00 ldx #$00 003675 1 86 94 stx page ; reset page count 003677 1 86 8F stx crc ; clear checksum 003679 1 86 90 stx crc+1 00367B 1 60 rts ; and return 00367C 1 00367C 1 ; Calculate CRC 00367C 1 A2 08 CRC: ldx #$08 00367E 1 48 pha ; save A 00367F 1 4A crclp: lsr A 003680 1 26 8F rol crc 003682 1 26 90 rol crc+1 003684 1 90 08 bcc noc 003686 1 48 pha 003687 1 A5 8F lda crc 003689 1 49 2D eor #$2D 00368B 1 85 8F sta crc 00368D 1 68 pla 00368E 1 CA noc: dex 00368F 1 D0 EE bne crclp 003691 1 68 pla ; retrieve A 003692 1 60 rts ; and return 003693 1 003693 1 ; *** User Input / Output Routines *** 003693 1 003693 1 ; *** Output a String of Characters *** 003693 1 68 OUTSTR: pla ; retrieve return PC (-1) LSB 003694 1 85 87 sta temp 003696 1 68 pla 003697 1 85 88 sta temp+1 ; and MSB 003699 1 A0 00 outnxt: ldy #$00 ; Y=0 00369B 1 A2 87 ldx #temp ; point x at pc 00369D 1 20 42 37 jsr INCCMP ; increment pointer 0036A0 1 B1 87 lda (temp),y ; get character from string 0036A2 1 30 06 bmi eos ; end of string ? 0036A4 1 20 F4 FF jsr OSWRCH ; output character 0036A7 1 4C 99 36 jmp outnxt ; next character 0036AA 1 6C 87 00 eos: jmp (temp) ; continue execution after string 0036AD 1 0036AD 1 0036AD 1 20 ED FF cancel: jsr OSCRLF 0036B0 1 ; *** Get Command From Buffer *** 0036B0 1 A9 3E COMIN: lda #'>' ; display prompt 0036B2 1 20 F4 FF jsr OSWRCH 0036B5 1 A2 FF buffin: ldx #$FF 0036B7 1 E8 nxtchr: inx ; increment buffer pointer 0036B8 1 E0 40 cpx #$40 ; buffer full ? (64 bytes) 0036BA 1 B0 0B bcs bufful 0036BC 1 20 E6 FF readch: jsr OSECHO ; read character from input channel and echo 0036BF 1 C9 18 cmp #CAN ; cancel ? 0036C1 1 F0 EA beq cancel ; yes - start again 0036C3 1 C9 7F cmp #DEL ; delete ? 0036C5 1 D0 05 bne nodel ; no - branch 0036C7 1 CA bufful: dex ; backup buffer pointer 0036C8 1 10 F2 bpl readch ; and read another character 0036CA 1 30 E9 bmi buffin ; start of line - start again 0036CC 1 9D 00 01 nodel: sta buffer,x ; put character in buffer 0036CF 1 C9 0D cmp #CR ; CR ? 0036D1 1 D0 E4 bne nxtchr ; no - read next character 0036D3 1 60 rts ; yes - return 0036D4 1 0036D4 1 ; *** Read Parameter from Input Buffer *** 0036D4 1 20 DA 36 PARAM: jsr HXPARA ; get hex parameter from input buffer 0036D7 1 F0 52 beq synerr ; if not hex - syntax error 0036D9 1 60 rts ; hex - return 0036DA 1 0036DA 1 ; *** Get (up to) 4-digit Hex Parameter from Input Buffer and Store at X *** 0036DA 1 A9 00 HXPARA: lda #$00 ; set parameter to 0 0036DC 1 95 00 sta $00,x 0036DE 1 95 01 sta $01,x 0036E0 1 85 87 sta temp ; clear parameter found flag 0036E2 1 20 06 37 jsr RDIBUF ; ignore leading spaces 0036E5 1 B9 00 01 rdnxch: lda buffer,y ; read character from input buffer 0036E8 1 20 0E 37 jsr HEXKEY ; is it hex ? 0036EB 1 B0 15 bcs delim ; branch if not hex (delimiter character ?) 0036ED 1 0A asl a ; shift up a digit 0036EE 1 0A asl a 0036EF 1 0A asl a 0036F0 1 0A asl a 0036F1 1 84 87 sty temp ; temporarily save the input buffer pointer and set parameter flag 0036F3 1 A0 04 ldy #$04 0036F5 1 0A shfdig: asl a ; shift X, X+1 and A left one digit (4-bits) 0036F6 1 36 00 rol $00,x 0036F8 1 36 01 rol $01,x 0036FA 1 88 dey 0036FB 1 D0 F8 bne shfdig 0036FD 1 A4 87 ldy temp ; retrieve the input buffer pointer 0036FF 1 C8 iny ; increment buffer pointer 003700 1 D0 E3 bne rdnxch ; always branch to read next character 003702 1 A5 87 delim: lda temp ; sets Z if no parameter was found 003704 1 60 rts ; and return 003705 1 003705 1 C8 space: iny 003706 1 ; *** Read the Yth Character From the Input Buffer *** 003706 1 B9 00 01 RDIBUF: lda buffer,y 003709 1 C9 20 cmp #SPACE ; ignoring spaces 00370B 1 F0 F8 beq space 00370D 1 60 rts ; and return 00370E 1 00370E 1 ; *** Test Key Value In A For Hex *** 00370E 1 C9 30 HEXKEY: cmp #'0' ; > '0' ? 003710 1 90 10 bcc nothex ; return invalid hex 003712 1 C9 3A cmp #':' ; < '9' ? 003714 1 90 08 bcc hex ; yes - valid hex 003716 1 E9 07 sbc #$07 ; convert 'A' to 'F' 003718 1 90 08 bcc nothex ; if < 'A' then not hex 00371A 1 C9 40 cmp #'@' ; > 'F' ? 00371C 1 B0 03 bcs hexrtn ; return with C=1, invalid hex digit 00371E 1 29 0F hex: and #$0F ; valid hex digit, convert to ASCII 003720 1 18 clc ; (unnecessarily set) C=0 003721 1 60 hexrtn: rts ; and return, valid hex digit 003722 1 38 nothex: sec ; C=1 003723 1 60 rtn: rts ; and return, invalid hex digit 003724 1 003724 1 ; *** Test For End Of Input Buffer *** 003724 1 20 06 37 ENDTST: jsr RDIBUF ; read character from input buffer 003727 1 C9 0D cmp #CR ; CR ? 003729 1 F0 F8 beq rtn ; yes - return, end found 00372B 1 20 93 36 synerr: jsr OUTSTR ; no - output 'Syntax Error ?' error 00372E 1 53 79 6E 74 .byte "Syntax Error ?",CR,LF 003732 1 61 78 20 45 003736 1 72 72 6F 72 00373E 1 EA nop 00373F 1 4C 20 28 jmp RESTRT ; abort command 003742 1 003742 1 ; *** Increment the Address at X,X+1 and Compare with X+2,3 *** 003742 1 F6 00 INCCMP: inc $00,x ; increment LSB 003744 1 D0 02 bne do_cmp ; carry ? 003746 1 F6 01 inc $01,x ; increment MSB 003748 1 B5 00 do_cmp: lda $00,x ; compare LSB 00374A 1 D5 02 cmp $02,x 00374C 1 D0 04 bne notequ ; if not equal return 00374E 1 B5 01 lda $01,x ; otherwise compare MSB 003750 1 D5 03 cmp $03,x 003752 1 60 notequ: rts ; and return 003753 1 003753 1 ; *** Output the Address at X+1, X *** 003753 1 B5 01 OUTADR: lda $01,x ; first byte 003755 1 20 76 37 jsr OUTBYT ; output the second byte (at X+1) 003758 1 E8 inx ; increment the pointer to the next address 003759 1 E8 inx 00375A 1 B5 FE lda $FE,x ; output the first byte (now at X-2) 00375C 1 20 76 37 jsr OUTBYT 00375F 1 A9 20 outspc: lda #SPACE ; followed by a space 003761 1 4C F4 FF jmp OSWRCH ; and return 003764 1 003764 1 ; Output CRC 003764 1 20 93 36 CRCOUT: jsr OUTSTR ; print out CRC header 003767 1 0D 0A 43 52 .byte CR,LF,"CRC: " 00376B 1 43 3A 20 00376E 1 EA nop 00376F 1 A5 90 lda crc+1 ; first byte 003771 1 20 76 37 jsr OUTBYT 003774 1 A5 8F lda crc ; and second byte 003776 1 003776 1 ; *** Output the Byte in A In Hex *** 003776 1 48 OUTBYT: pha ; save A 003777 1 4A lsr a ; start with the upper nibble 003778 1 4A lsr a ; shift to the lower nibble position 003779 1 4A lsr a 00377A 1 4A lsr a 00377B 1 20 7F 37 jsr OUTDIG ; and output 00377E 1 68 pla ; retrieve A and output the lower nibble 00377F 1 00377F 1 ; *** Output the Hex Digit in A *** 00377F 1 29 0F OUTDIG: and #$0F ; mask off the upper nibble 003781 1 C9 0A cmp #$0A ; is it A-F ? 003783 1 90 02 bcc ascii ; no 003785 1 69 06 adc #$06 ; yes - add offset to 'A' 003787 1 69 30 ascii: adc #'0' ; convert to ASCII 003789 1 4C F4 FF jmp OSWRCH ; output character and return 00378C 1 00378C 1 ; ****** DEBUG CODE ****** 00378C 1 .if DEBUG = 'Y' ; Breakpoint Handler for DEBUG 00378C 1 00378C 1 BRKPNT: cld ; Breakpoint Routine Entry 00378C 1 sta brk_a ; save A, X and Y 00378C 1 stx brk_x 00378C 1 sty brk_y 00378C 1 pla ; retrieve status register 00378C 1 sta brk_sr ; and save 00378C 1 pla ; retrieve PC and save 00378C 1 sta brkpcl 00378C 1 pla 00378C 1 sta brkpch 00378C 1 jsr OUTSTR ; output pc = program counter value 00378C 1 .byte "BREAK at PC=" 00378C 1 lda brkpch 00378C 1 jsr OUTBYT 00378C 1 lda brkpcl 00378C 1 jsr OUTBYT 00378C 1 jsr OUTSTR ; output CRLF A = accumulator value 00378C 1 .byte " A=" 00378C 1 lda brk_a 00378C 1 jsr OUTBYT 00378C 1 jsr OUTSTR ; output X = X register value 00378C 1 .byte " X=" 00378C 1 lda brk_x 00378C 1 jsr OUTBYT 00378C 1 jsr OUTSTR ; output Y = Y register value 00378C 1 .byte " Y=" 00378C 1 lda brk_y 00378C 1 jsr OUTBYT 00378C 1 jsr OUTSTR ; output PS = status register value 00378C 1 .byte " PS=" 00378C 1 lda brk_sr 00378C 1 jsr OUTBYT 00378C 1 jsr OSCRLF ; and a final CR LF 00378C 1 jmp RESTRT ; re-enter command line interpreter 00378C 1 .endif 00378C 1