ca65 V2.17 - Git 582aa41 Main file : promer3.ca65 Current file: promer3.ca65 000000r 1 ; 000000r 1 ; ****** PROMER V3.0 ****** 000000r 1 ; 000000r 1 ; Based on the original Acorn PROM Programmer Board (200.007) 000000r 1 ; software 'PROMER' listed in the Technical Manual Issue 2 January 1981 000000r 1 ; 000000r 1 ; The original Acorn PROM Programmer Board supports National 000000r 1 ; Semiconductors (NSC) fusible link PROM's and single supply rail 000000r 1 ; 1K, 2K and 4K EPROM's. 000000r 1 ; 000000r 1 ; This version of PROMER has an improved user interface with 000000r 1 ; additional commands for memory manipulation as well as providing 000000r 1 ; support for NSC 74S287 256 x 4-bit PROM's and TESLA MH74S287 000000r 1 ; and MH74S571 PROM's. 000000r 1 ; 000000r 1 ; For TESLA support my Tesla PROM Programmer Board is required. 000000r 1 ; 000000r 1 ; Chris Oddy July 2022 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 type := $80 ; 0 - EPROM, 1 - NSC PROM, 2 - Tesla PROM (1 byte) 000000r 1 size := $81 ; PROM size 256 ($00) or 512 bytes ($01) (1 byte) 000000r 1 hilow := $82 ; PROM low ($00) or high nibble ($80) (1 byte) 000000r 1 prctrl := $83 ; control byte for EPROM program (1 byte) 000000r 1 vectrl := $84 ; control byte for EPROM verify (1 byte) 000000r 1 rdctrl := $85 ; control byte for EPROM read (1 byte) 000000r 1 ppctrl := $86 ; control byte for EPROM program pulse (1 byte) 000000r 1 device := $87 ; pointer to DEVTAB current device 000000r 1 ;($FF if not set) (1 byte) 000000r 1 temp := $88 ; temporary storage (1 byte) 000000r 1 ctrl := $89 ; control byte (1 byte) 000000r 1 from := $8A ; from address (2 bytes) 000000r 1 to := $8C ; to address (2 bytes) 000000r 1 point := $8E ; pointer in E/PROM routines (2 bytes) 000000r 1 fill := $8E ; fill byte in FILL command (1 byte) 000000r 1 column := $8F ; column in DUMP command (1 byte) 000000r 1 crc := $90 ; CRC checksum (1 byte) 000000r 1 mask := $91 ; bit mask in PROM (1 byte) 000000r 1 tries := $92 ; number of tries in PROM program (1 byte) 000000r 1 extra := $93 ; number of extra blows in PROM program (1 byte) 000000r 1 count := $94 ; counter (1 byte) 000000r 1 page := $95 ; page counter (1 byte) 000000r 1 progs := $96 ; programmers present: (1 byte) 000000r 1 ; bit 0 set if Acorn PROM Programmer present 000000r 1 ; bit 1 set if TESLA PROM Programmer present 000000r 1 base := $97 ; base address for memory workspace (2 bytes) 000000r 1 fail := $99 ; failed address in blank and verify (2 bytes) 000000r 1 buffer := $0100 ; command input buffer (64 bytes) 000000r 1 ; 000000r 1 ; *** Debug Storage *** 000000r 1 ; 000000r 1 brk_a := $C4 ; breakpoint A storage (1 byte) 000000r 1 brk_x := $C5 ; breakpoint X storage (1 byte) 000000r 1 brk_y := $C6 ; breakpoint Y storage (1 byte) 000000r 1 brkpcl := $C7 ; breakpoint PCL storage (1 byte) 000000r 1 brkpch := $C8 ; breakpoint PCH storage (1 byte) 000000r 1 brk_sr := $C9 ; breakpoint status register (1 byte) 000000r 1 stack := $100 ; bottom of processor stack 000000r 1 BRKVEC := $0202 ; BRK vector (2 bytes) 000000r 1 ; 000000r 1 ; Hardware Addresses 000000r 1 ; 000000r 1 keybrd := $0E21 ; keyboard 000000r 1 ; 000000r 1 ; Acorn PROM Programmer (NSC PROM's and all EPROM's) 000000r 1 aporta := $1980 ; 8255 Port A - PROM Data D0 to D3 / EPROM Data D0 to D7 000000r 1 aportb := $1981 ; 8255 Port B - PROM/EPROM Address A0 to A7 000000r 1 aportc := $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 actlrg := $1983 ; 8255 control register 000000r 1 ; writing these values has this effect: 000000r 1 ; $00 resets C0 A8 low 000000r 1 ; $01 sets C0 A8 high 000000r 1 ; $02 resets C1 A9 low 000000r 1 ; $03 sets C1 A9 high 000000r 1 ; $04 resets C2 A10 low 000000r 1 ; $05 sets C2 A10 high 000000r 1 ; $06 resets C3 PROM CE or A11 active/low 000000r 1 ; $07 sets C3 PROM CE or A11 inactive/high 000000r 1 ; $08 resets C4 EPROM OE or PD/PGM low 000000r 1 ; $09 set C4 EPROM OE or PD/PGM high 000000r 1 ; $0A resets C5 RW Control Write 000000r 1 ; $0B set C5 RW Control Read 000000r 1 ; $0C resets C6 PROM Power Control OFF 000000r 1 ; $0D sets C6 PROM Power Control ON 000000r 1 ; 000000r 1 ; TESLA PROM Programmer (Tesla PROM's) 000000r 1 tporta := $1A80 ; 8255 Port A - PROM Data D0 to D3 for reading 000000r 1 tportb := $1A81 ; 8255 Port B - PROM Address A0 to A7 000000r 1 tportc := $1A82 ; 8255 Port C - C0 PROM Address A8 000000r 1 ; C1 Vcc ON/OFF (0 = Vcc ON) 000000r 1 ; C2 Switches between 5V and 10.5V Vcc (0 = 5V, 1 = 10.5V) 000000r 1 ; C3 PROM OE (1 = active i.e. low) 000000r 1 ; C4-7 PROM Data D0 to D3 for writing 000000r 1 tctlrg := $1A83 ; 8255 control register 000000r 1 ; writing these values has this effect: 000000r 1 ; $00 resets C0 A8 low 000000r 1 ; $01 sets C0 A8 high 000000r 1 ; $02 resets C1 Vcc ON 000000r 1 ; $03 sets C1 Vcc OFF 000000r 1 ; $04 resets C2 Vcc=5V 000000r 1 ; $05 sets C2 Vcc=10.5V 000000r 1 ; $06 resets C3 OE inactive 000000r 1 ; $07 sets C3 OE active 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 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 B2 3C START: jsr OUTSTR ; output start-up message 002803 1 0D 0A 2A 2A .byte CR,LF,"*** PROMER V3.0 ***",CR,LF,LF 002807 1 2A 20 50 52 00280B 1 4F 4D 45 52 00281B 1 45 6E 73 75 .byte "Ensure no ICs are fitted in sockets",CR,LF,LF 00281F 1 72 65 20 6E 002823 1 6F 20 49 43 002841 1 EA nop 002842 1 A9 00 lda #$00 ; determine which programmers are present 002844 1 85 96 sta progs ; set no programmers found 002846 1 A9 9B lda #$9B ; write $91B to each 8255 control register (all Ports inputs) 002848 1 8D 83 19 sta actlrg 00284B 1 8D 83 1A sta tctlrg 00284E 1 AD 80 19 lda aporta ; check for Acorn PROM Programmer 002851 1 D0 39 bne nacorn ; if Port A = 00 its present 002853 1 20 B2 3C jsr OUTSTR ; output message 002856 1 41 63 6F 72 .byte "Acorn PROM Programmer found at $1980",CR,LF,LF 00285A 1 6E 20 50 52 00285E 1 4F 4D 20 50 00287D 1 EA nop 00287E 1 A9 01 lda #$01 ; set bit 0 002880 1 85 96 sta progs ; and save 002882 1 A9 90 lda #$90 ; initialise Acorn PROM Programmer 002884 1 8D 83 19 sta actlrg ; control register (Port A input, Ports B & C outputs) 002887 1 A9 00 lda #$00 ; Port C - A8,A9,A10 low (C0,1,2=0), CE,OE low C3,4=0), 002889 1 ; RW write (C5-0), PROM power +5 (C6=0), EPROM power +5 (C7=0) 002889 1 8D 82 19 sta aportc 00288C 1 AD 80 1A nacorn: lda tporta ; check for TESLA PROM Programmer 00288F 1 C9 0F cmp #$0F ; if Port A <> $0F 002891 1 D0 3B bne ntesla ; its not present 002893 1 20 B2 3C jsr OUTSTR ; output message 002896 1 54 45 53 4C .byte "TESLA PROM Programmer found at $1A80",CR,LF,LF 00289A 1 41 20 50 52 00289E 1 4F 4D 20 50 0028BD 1 EA nop 0028BE 1 A5 96 lda progs ; retrieve acorn programmer status 0028C0 1 09 02 ora #$02 ; and set bit 1 0028C2 1 85 96 sta progs ; and save 0028C4 1 A9 90 lda #$90 ; initialise Tesla PROM Programmer 0028C6 1 8D 83 1A sta tctlrg ; control register (Port A inputs, Ports B & C outputs) 0028C9 1 A9 02 lda #$02 ; Port C - A8 low (C0=0), Vcc OFF,5V (C1=1,C2=0), 0028CB 1 ; OE inactive (C3=0),D0-3 low (C4-7=1) 0028CB 1 8D 82 1A sta tportc 0028CE 1 A5 96 ntesla: lda progs 0028D0 1 D0 1E bne prgsok ; if non-zero then at least one programmer is present 0028D2 1 20 B2 3C jsr OUTSTR ; otherwise no programmers found ? 0028D5 1 4E 6F 20 50 .byte "No Programmers Found ?",CR,LF,LF 0028D9 1 72 6F 67 72 0028DD 1 61 6D 6D 65 0028EE 1 EA nop 0028EF 1 60 rts ; return to OS 0028F0 1 A2 FF prgsok: ldx #$FF 0028F2 1 86 87 stx device ; clear current device 0028F4 1 E8 inx ; X = 0 0028F5 1 86 97 stx base ; set default base to $4000 0028F7 1 A2 40 ldx #$40 0028F9 1 86 98 stx base+1 0028FB 1 20 44 2A jsr OUTBAS ; output default BASE address 0028FE 1 20 ED FF jsr OSCRLF 002901 1 002901 1 .if DEBUG = 'Y' ; BRK vector redirection required for DEBUG 002901 1 lda #BRKPNT 002901 1 sta BRKVEC+1 002901 1 .endif 002901 1 002901 1 20 CF 3C RESTRT: jsr COMIN ; read command into buffer 002904 1 20 0A 29 jsr PRCLI ; action command 002907 1 4C 01 29 jmp RESTRT ; and do it again 00290A 1 00290A 1 A2 FF PRCLI: ldx #$FF ; *** PROMER3 Command Line Interpreter *** 00290C 1 D8 cld ; X is command table pointer 00290D 1 A0 00 nxtcom: ldy #$00 ; Y is buffer pointer 00290F 1 20 25 3D jsr RDIBUF ; ignore leading spaces in buffer 002912 1 B9 00 01 lda buffer,y ; check for CR and no command 002915 1 C9 0D cmp #CR 002917 1 D0 01 bne nocr ; no - continue to extract command 002919 1 60 rts ; yes - return 00291A 1 88 nocr: dey ; backup buffer pointer 00291B 1 C8 chkcom: iny ; increment buffer pointer 00291C 1 E8 inx ; increment command table pointer 00291D 1 BD 47 29 rdcom: lda COMTAB,x ; read command table 002920 1 F0 17 beq addres ; end of string found (0) ? 002922 1 D9 00 01 cmp buffer,y ; compare with buffer 002925 1 F0 F4 beq chkcom ; if equal compare whole string 002927 1 E8 noteos: inx ; until a difference is found 002928 1 BD 47 29 lda COMTAB,x 00292B 1 D0 FA bne noteos ; find end of string (00) 00292D 1 E8 inx ; adjust command table pointer for next command string 00292E 1 E8 inx ; i.e. point at 2nd byte of address 00292F 1 B9 00 01 lda buffer,y 002932 1 C9 2E cmp #'.' ; was command abbreviated ? 002934 1 D0 D7 bne nxtcom ; no - try next command from table 002936 1 C8 iny ; increment buffer pointer past '.' 002937 1 CA dex ; backup command table pointer to end of string (0) 002938 1 CA dex 002939 1 E8 addres: inx ; increment pointer to command address 00293A 1 BD 47 29 lda COMTAB,x ; load MSB 00293D 1 85 8B sta from+1 ; save 00293F 1 BD 48 29 lda COMTAB+1,x ; load LSB 002942 1 85 8A sta from ; save 002944 1 6C 8A 00 jmp (from) ; and call command routine 002947 1 002947 1 ; COMMAND TABLE 002947 1 42 41 53 45 COMTAB: .byte "BASE",$00,>BASE, 00294B 1 00 2A 3D 00294E 1 42 4C 41 4E .byte "BLANK",CR,$00,>BLANK,DEVICE, 00295B 1 43 45 00 2B 00295F 1 8A 002960 1 44 55 4D 50 .byte "DUMP",$00,>DUMP, 002964 1 00 2D 01 002967 1 45 58 49 54 .byte "EXIT",$00,>EXIT,FILL, 002972 1 00 2D 5D 002975 1 48 45 4C 50 .byte "HELP",CR,$00,>HELP,HLPBAS,HLPBLK,HLPDEV,HLPDMP,HLPEXT,HLPFIL,HLPMEM,HLPPGM,HLPRED,HLPVER,MEM, 002A0A 1 36 E1 002A0C 1 50 52 4F 47 .byte "PROGRAM",$00,>PROGRM,) 002A10 1 52 41 4D 00 002A14 1 37 4C 002A16 1 52 45 41 44 .byte "READ",$00,>READ,) 002A1A 1 00 37 AF 002A1D 1 56 45 52 49 .byte "VERIFY",$00,>VERIFY,) 002A21 1 46 59 00 38 002A25 1 1B 002A26 1 2A 00 37 33 .byte "*",$00,>OSCOM,COMMES,, if no parameter 002A3D 1 ; is entered then the current BASE address is output. 002A3D 1 20 25 3D BASE: jsr RDIBUF ; read next character from input buffer ignoring leading spaces 002A40 1 C9 0D cmp #CR 002A42 1 D0 22 bne getbas ; yes - get
parameter 002A44 1 20 B2 3C OUTBAS: jsr OUTSTR ; no - output current BASE address 002A47 1 42 41 53 45 .byte "BASE Address set to: " 002A4B 1 20 41 64 64 002A4F 1 72 65 73 73 002A5C 1 EA nop 002A5D 1 A2 97 ldx #base ; point X at base address 002A5F 1 20 72 3D jsr OUTWRD ; output 002A62 1 20 ED FF jsr OSCRLF 002A65 1 60 rts ; and return 002A66 1 A2 97 getbas: ldx #base ; point X at base 002A68 1 20 F9 3C jsr HXPARA ; get value 002A6B 1 D0 3E bne baseok ; valid hex value entered ? 002A6D 1 20 B2 3C jsr OUTSTR ; no - output error message 002A70 1 4D 75 73 74 .byte "Must be a hex address",CR,LF 002A74 1 20 62 65 20 002A78 1 61 20 68 65 002A87 1 EA nop 002A88 1 60 rts ; and return 002A89 1 20 B2 3C nobase: jsr OUTSTR ; output error message 002A8C 1 4E 6F 20 76 .byte "No valid hex value entered ?",CR,LF 002A90 1 61 6C 69 64 002A94 1 20 68 65 78 002AAA 1 EA nop 002AAB 1 20 43 3D baseok: jsr ENDTST ; check for end of input buffer 002AAE 1 60 rts ; and return 002AAF 1 002AAF 1 ; *** BLANK Command - check device is blank *** 002AAF 1 ; no parameters required 002AAF 1 20 ED 3D BLANK: jsr CHKDEV ; check a device has been set 002AB2 1 90 0B bcc bnodev ; if carry clear no device set - exit 002AB4 1 20 08 2B brept: jsr CBLANK ; do blank check 002AB7 1 20 C0 2A jsr BLMESS ; output blank/not blank message 002ABA 1 20 C4 3D jsr REPEAT ; do it again ? 002ABD 1 F0 F5 beq brept ; yes - repeat 002ABF 1 60 bnodev: rts ; otherwise return 002AC0 1 002AC0 1 ; Output Blank or Not Blank Message 002AC0 1 D0 17 BLMESS: bne nblank 002AC2 1 20 B2 3C jsr OUTSTR ; output blank message 002AC5 1 0D 0A 44 65 .byte CR,LF,"Device is Blank" 002AC9 1 76 69 63 65 002ACD 1 20 69 73 20 002AD6 1 EA nop 002AD7 1 30 2B bmi done ; always branch 002AD9 1 20 B2 3C nblank: jsr OUTSTR ; output not blank message 002ADC 1 0D 0A 44 65 .byte CR,LF,"Device is Not Blank at Address: " 002AE0 1 76 69 63 65 002AE4 1 20 69 73 20 002AFE 1 EA nop ; and first non-blank address 002AFF 1 A2 99 ldx #fail ; point X at fail address 002B01 1 20 72 3D jsr OUTWRD ; output address 002B04 1 20 ED FF done: jsr OSCRLF ; final CRLF 002B07 1 60 rts ; and return 002B08 1 002B08 1 ; *** BLANK Core *** 002B08 1 ; (used by BLANK and PROGRAM commands) 002B08 1 20 B2 3C CBLANK: jsr OUTSTR 002B0B 1 43 68 65 63 .byte "Checking Device is Blank: " 002B0F 1 6B 69 6E 67 002B13 1 20 44 65 76 002B25 1 EA nop 002B26 1 20 0B 3E jsr INIPTR ; initialise pointers 002B29 1 A6 80 ldx type ; call either EPROM Blank (0), NSC PROM Blank (1) or Tesla PROM Blank (2) 002B2B 1 F0 0B beq beprom ; if 0 - EPROM 002B2D 1 CA dex ; NSC PROM ? 002B2E 1 D0 04 bne btesla ; if not must be Tesla PROM 002B30 1 20 F1 39 jsr PBLANK ; call NSC PROM Blank routine 002B33 1 60 rts ; and return 002B34 1 20 39 3B btesla: jsr TBLANK ; call Tesla PROM Blank routine 002B37 1 60 rts ; and return 002B38 1 A4 81 beprom: ldy size ; get EPROM size 002B3A 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 002B3C 1 F0 2D beq betwo ; branch if 2K 002B3E 1 30 40 bmi beone ; branch if 1K 002B40 1 ; blank check first 1K of 4K EPROM 002B40 1 A9 00 lda #$00 ; set address MSB for a fail 002B42 1 85 9A sta fail+1 002B44 1 A5 85 lda rdctrl ; load control byte (A10 and A11 low) 002B46 1 20 F5 38 jsr EBLANK ; blank check 4K device (1st quarter) 002B49 1 D0 34 bne bedone ; not blank return 002B4B 1 ; blank check second 1K of 4K EPROM 002B4B 1 A9 04 lda #$04 ; set address MSB for a fail 002B4D 1 85 9A sta fail+1 002B4F 1 05 84 ora vectrl ; add control byte 002B51 1 20 F5 38 jsr EBLANK ; blank check 2nd quarter 002B54 1 D0 29 bne bedone ; not blank return 002B56 1 ; blank check third 1K of 4K EPROM 002B56 1 A9 08 lda #$08 ; set A11 high 002B58 1 85 9A sta fail+1 ; save as fail address MSB 002B5A 1 05 85 ora rdctrl ; add control byte 002B5C 1 20 F5 38 jsr EBLANK ; blank check 3rd quarter 002B5F 1 D0 1E bne bedone ; not blank return 002B61 1 ; blank check fourth 1K of 4K EPROM 002B61 1 A9 0C lda #$0C ; set A10 and A11 high 002B63 1 85 9A sta fail+1 ; save as fail address MSB 002B65 1 05 85 ora rdctrl ; add control byte 002B67 1 20 F5 38 jsr EBLANK ; blank check 4th quarter 002B6A 1 60 rts ; and return 002B6B 1 betwo: ; blank check first 1K of 2K EPROM 002B6B 1 A9 00 lda #$00 ; set A10 low 002B6D 1 85 9A sta fail+1 ; save as fail address MSB 002B6F 1 05 85 ora rdctrl ; add control byte 002B71 1 20 F5 38 jsr EBLANK ; blank check first half of 2K EPROM 002B74 1 D0 09 bne bedone ; not blank return 002B76 1 ; blank check second 1K of 2K EPROM 002B76 1 A9 04 lda #$04 ; set A10 high 002B78 1 85 9A sta fail+1 ; save as fail address MSB 002B7A 1 05 85 ora rdctrl ; add control byte 002B7C 1 20 F5 38 jsr EBLANK ; blank check second half of 2K EPROM 002B7F 1 60 bedone: rts ; and return 002B80 1 beone: ; blank check 1K EPROM 002B80 1 A9 00 lda #$00 ; set fail address MSB 002B82 1 85 9A sta fail+1 002B84 1 05 85 ora rdctrl ; add control byte 002B86 1 20 F5 38 jsr EBLANK ; blank check 1K device 002B89 1 60 bdone: rts ; and return 002B8A 1 002B8A 1 ; *** DEVICE Command - select device *** 002B8A 1 ; takes one parameter: 002B8A 1 ; If no parameter specified then the current 002B8A 1 ; is displayed (if one has been set). 002B8A 1 20 25 3D DEVICE: jsr RDIBUF ; ignore leading spaces 002B8D 1 B9 00 01 lda buffer,y ; is there a parameter ? 002B90 1 C9 0D cmp #CR 002B92 1 D0 14 bne setdev ; yes - get parameter 002B94 1 20 ED 3D jsr CHKDEV ; no - so display current device, has one been set ? 002B97 1 90 45 bcc devrtn ; no - return 002B99 1 20 B2 3C jsr OUTSTR ; yes - display it 002B9C 1 44 65 76 69 .byte "Device: " 002BA0 1 63 65 3A 20 002BA4 1 EA nop 002BA5 1 4C 33 3E jmp OUTDEV ; output device label and return 002BA8 1 A2 00 setdev: ldx #$00 ; initialise device table pointer 002BAA 1 84 88 sty temp ; save input buffer pointer current position 002BAC 1 A4 88 find: ldy temp ; retrieve input buffer pointer 002BAE 1 86 87 stx device ; save pointer to start of current device label 002BB0 1 B9 00 01 fnddev: lda buffer,y ; get next character from input buffer 002BB3 1 DD 80 2C cmp DEVTAB,x ; compare with device label in table 002BB6 1 F0 27 beq match ; branch if a match 002BB8 1 E8 findff: inx ; not this one so pass over rest of this device entry 002BB9 1 BD 80 2C lda DEVTAB,x 002BBC 1 C9 FF cmp #$FF ; entry is terminated by $FF 002BBE 1 D0 F8 bne findff ; keep going till we find it 002BC0 1 E8 inx 002BC1 1 BD 80 2C lda DEVTAB,X ; then read next entry in table to 002BC4 1 C9 FF cmp #$FF ; check for end of table (2nd $FF) 002BC6 1 90 E4 bcc find ; no - try and match next device 002BC8 1 20 B2 3C jsr OUTSTR ; yes - no match found ? 002BCB 1 49 6E 76 61 .byte "Invalid Device ?",CR,LF 002BCF 1 6C 69 64 20 002BD3 1 44 65 76 69 002BDD 1 EA nop 002BDE 1 60 devrtn: rts ; return 002BDF 1 E8 match: inx ; increment device table pointer 002BE0 1 C8 iny ; increment input buffer pointer 002BE1 1 C9 0D cmp #CR ; have we reached the terminating CR ? 002BE3 1 D0 CB bne fnddev ; no - continue comparing characters 002BE5 1 BD 80 2C lda DEVTAB,x ; read device type from table 002BE8 1 85 80 sta type ; and store 002BEA 1 C9 02 cmp #$02 ; check appropriate programmer present 002BEC 1 F0 29 beq chktes ; is device type a Tesla PROM ? 002BEE 1 A5 96 lda progs ; no - must be EPROM or NSC PROM 002BF0 1 ; check Acorn programmer present 002BF0 1 29 01 and #$01 ; check bit 0 002BF2 1 D0 4F bne progok ; if set programmer present 002BF4 1 20 B2 3C jsr OUTSTR ; no - output message 002BF7 1 52 65 71 75 .byte "Requires Acorn Programmer ?",CR,LF 002BFB 1 69 72 65 73 002BFF 1 20 41 63 6F 002C14 1 EA nop 002C15 1 30 27 bmi clrdev ; always branch 002C17 1 A5 96 chktes: lda progs ; check Tesla Programmer present 002C19 1 29 02 and #$02 ; check bit 1 002C1B 1 D0 26 bne progok ; if set programmer present 002C1D 1 20 B2 3C jsr OUTSTR ; no - output message 002C20 1 52 65 71 75 .byte "Requires Tesla Programmer ?",CR,LF 002C24 1 69 72 65 73 002C28 1 20 54 65 73 002C3D 1 EA nop 002C3E 1 A9 FF clrdev: lda #$FF ; set no device defined 002C40 1 85 87 sta device 002C42 1 60 rts ; and return 002C43 1 BD 81 2C progok: lda DEVTAB+1,x ; read device size from table 002C46 1 85 81 sta size ; and store 002C48 1 A5 80 lda type ; reload device type 002C4A 1 D0 16 bne dvprom ; is it an EPROM ? 002C4C 1 BD 82 2C lda DEVTAB+2,x ; yes - read EPROM BLOW control parameter from table 002C4F 1 85 83 sta prctrl ; and store 002C51 1 BD 83 2C lda DEVTAB+3,x ; read EPROM VERIFY control parameter from table 002C54 1 85 84 sta vectrl ; and store 002C56 1 BD 84 2C lda DEVTAB+4,x ; read EPROM READ control parameter from table 002C59 1 85 85 sta rdctrl ; and store 002C5B 1 BD 85 2C lda DEVTAB+5,x ; read EPROM Program Pulse parameter from table 002C5E 1 85 86 sta ppctrl ; and store 002C60 1 D0 05 bne dvset ; always branches 002C62 1 BD 82 2C dvprom: lda DEVTAB+2,x ; no - must be a PROM so read PROM hilo parameter from table 002C65 1 85 82 sta hilow ; and store 002C67 1 20 B2 3C dvset: jsr OUTSTR 002C6A 1 44 65 76 69 .byte "Device Set to:" 002C6E 1 63 65 20 53 002C72 1 65 74 20 74 002C78 1 EA nop 002C79 1 20 33 3E jsr OUTDEV ; output device label 002C7C 1 20 46 3E jsr SOCKET ; output message as to which socket to use 002C7F 1 60 rts ; and return 002C80 1 002C80 1 ; *** PROM/EPROM Device Data *** 002C80 1 ; 002C80 1 ; The format of the table is as follows: 002C80 1 ; "device label" followed by CR 002C80 1 ; device type: 0 - EPROM, 1 - NSC PROM, 2 - Tesla PROM 002C80 1 ; size: for PROM's 0 - 256bytes, 1 - 512bytes 002C80 1 ; for EPROMs 1 - 1K, 2 - 2K, 4 - 4K 002C80 1 ; for PROM's only: nibble $00 - low, $80 - high 002C80 1 ; for EPROM's only: control byte for BLOW 002C80 1 ; control byte for VERIFY 002C80 1 ; control byte for READ 002C80 1 ; control byte for program pulse 002C80 1 ; and a final $FF to terminate each entry 002C80 1 ; 002C80 1 32 37 35 38 DEVTAB: .byte "2758",CR ; 2758 1Kbyte EPROM 002C84 1 0D 002C85 1 00 .byte 0 ; EPROM 002C86 1 01 .byte 1 ; 1 Kbytes 002C87 1 90 .byte $90 ; control byte for BLOW 002C88 1 80 .byte $80 ; control byte for VERIFY 002C89 1 00 .byte $00 ; control byte for READ 002C8A 1 07 .byte $07 ; control byte for program pulse 002C8B 1 FF .byte $FF 002C8C 1 002C8C 1 32 35 31 36 .byte "2516",CR ; 2516 2Kbyte EPROM (same as 2716) 002C90 1 0D 002C91 1 00 .byte 0 ; EPROM 002C92 1 02 .byte 2 ; 2 Kbytes 002C93 1 90 .byte $90 ; control byte for BLOW 002C94 1 80 .byte $80 ; control byte for VERIFY 002C95 1 00 .byte $00 ; control byte for READ 002C96 1 07 .byte $07 ; control byte for program pulse 002C97 1 FF .byte $FF 002C98 1 002C98 1 32 37 31 36 .byte "2716",CR ; 2716 2Kbyte EPROM 002C9C 1 0D 002C9D 1 00 .byte 0 ; EPROM type 002C9E 1 02 .byte 2 ; 2 Kbytes 002C9F 1 90 .byte $90 ; control byte for BLOW 002CA0 1 80 .byte $80 ; control byte for VERIFY 002CA1 1 00 .byte $00 ; control byte for READ 002CA2 1 07 .byte $07 ; control byte for program pulse 002CA3 1 FF .byte $FF 002CA4 1 002CA4 1 32 35 33 32 .byte "2532",CR ; 2532 4Kbyte EPROM 002CA8 1 0D 002CA9 1 00 .byte 0 ; EPROM 002CAA 1 04 .byte 4 ; 4 Kbytes 002CAB 1 90 .byte $90 ; control byte for BLOW 002CAC 1 00 .byte $00 ; control byte for VERIFY 002CAD 1 00 .byte $00 ; control byte for READ 002CAE 1 08 .byte $08 ; control byte for program pulse 002CAF 1 FF .byte $FF 002CB0 1 002CB0 1 32 38 37 4C .byte "287L",CR ; NSC 74S287 256byte x 4-bits PROM 002CB4 1 0D 002CB5 1 01 .byte 1 ; fusible link PROM type 002CB6 1 00 .byte 0 ; 256 bytes 002CB7 1 00 .byte 0 ; low nibble 002CB8 1 FF .byte $FF 002CB9 1 002CB9 1 32 38 37 48 .byte "287H",CR ; NSC 74S287 256byte x 4-bits PROM 002CBD 1 0D 002CBE 1 01 .byte 1 ; fusible link PROM type 002CBF 1 00 .byte 0 ; 256 bytes 002CC0 1 80 .byte $80 ; high nibble 002CC1 1 FF .byte $FF 002CC2 1 002CC2 1 35 37 31 4C .byte "571L",CR ; NSC 74S571 512byte x 4-bits PROM 002CC6 1 0D 002CC7 1 01 .byte 1 ; fusible link PROM type 002CC8 1 01 .byte 1 ; 512 bytes 002CC9 1 00 .byte 0 ; low nibble 002CCA 1 FF .byte $FF 002CCB 1 002CCB 1 35 37 31 48 .byte "571H",CR ; NSC 74S571 512byte x 4-bits PROM 002CCF 1 0D 002CD0 1 01 .byte 1 ; fusible link PROM type 002CD1 1 01 .byte 1 ; 512 bytes 002CD2 1 80 .byte $80 ; high nibble 002CD3 1 FF .byte $FF 002CD4 1 002CD4 1 4D 48 32 38 .byte "MH287L",CR ; Tesla MH74S287 256 byte x 4-bits PROM 002CD8 1 37 4C 0D 002CDB 1 02 .byte 2 ; fusible link PROM type 002CDC 1 00 .byte 0 ; 256 bytes 002CDD 1 00 .byte 0 ; low nibble 002CDE 1 FF .byte $FF 002CDF 1 002CDF 1 4D 48 32 38 .byte "MH287H",CR ; Tesla MH74S287 256byte x 4-bits PROM 002CE3 1 37 48 0D 002CE6 1 02 .byte 2 ; fusible link PROM type 002CE7 1 00 .byte 0 ; 256 bytes 002CE8 1 80 .byte $80 ; high nibble 002CE9 1 FF .byte $FF 002CEA 1 002CEA 1 4D 48 35 37 .byte "MH571L",CR ; Tesla MH74S571 512 byte x 4-bits PROM 002CEE 1 31 4C 0D 002CF1 1 02 .byte 2 ; fusible link PROM type 002CF2 1 01 .byte 1 ; 512 bytes 002CF3 1 00 .byte 0 ; low nibble 002CF4 1 FF .byte $FF 002CF5 1 002CF5 1 4D 48 35 37 .byte "MH571H",CR ; Tesla MH74S571 512byte x 4-bits PROM 002CF9 1 31 48 0D 002CFC 1 02 .byte 2 ; fusible link PROM type 002CFD 1 01 .byte 1 ; 512 bytes 002CFE 1 80 .byte $80 ; high nibble 002CFF 1 FF .byte $FF 002D00 1 FF .byte $FF ; end of table 002D01 1 002D01 1 ; *** DUMP Command - Dump block of Memory *** 002D01 1 ; takes three parameters: and addresses 002D01 1 ; and optional 002D01 1 A2 8A DUMP: ldx #from ; point X at address 002D03 1 20 F3 3C jsr PARAM ; get address from input buffer 002D06 1 A2 8C ldx #to ; point X at address 002D08 1 20 F3 3C jsr PARAM ; get address from input buffer 002D0B 1 E6 8C inc to ; add one to address 002D0D 1 D0 02 bne dnoinc 002D0F 1 E6 8D inc to+1 002D11 1 A2 8F dnoinc: ldx #column ; and optionally number of 002D13 1 20 F9 3C jsr HXPARA ; in output 002D16 1 D0 04 bne dodump ; use default number of columns ? 002D18 1 A9 08 lda #$08 ; yes = 8 002D1A 1 85 8F sta column 002D1C 1 20 43 3D dodump: jsr ENDTST ; test for end of input buffer 002D1F 1 A5 8F nxtlin: lda column 002D21 1 85 88 sta temp 002D23 1 20 ED FF jsr OSCRLF ; output address 002D26 1 A2 8A ldx #from 002D28 1 20 72 3D jsr OUTWRD 002D2B 1 A9 7C lda #'|' ; and a delimiter '|' 002D2D 1 20 F4 FF jsr OSWRCH 002D30 1 A0 00 ldy #$00 ; y=0 002D32 1 A2 8A ldx #from ; point X at from address 002D34 1 A9 20 nxtcol: lda #SPACE 002D36 1 20 F4 FF jsr OSWRCH 002D39 1 B1 8A lda (from),y ; get a byte 002D3B 1 20 95 3D jsr OUTBYT ; output 002D3E 1 20 61 3D jsr INCCMP ; check if last one 002D41 1 F0 06 beq finish ; if so return 002D43 1 C6 88 dec temp ; otherwise check for end of line 002D45 1 D0 ED bne nxtcol ; if not output next byte 002D47 1 F0 D6 beq nxtlin ; last column - output next line 002D49 1 20 ED FF finish: jsr OSCRLF ; finished - output 2 CRLF's 002D4C 1 4C ED FF jmp OSCRLF ; and return 002D4F 1 002D4F 1 ; *** EXIT Command - Return to OS *** 002D4F 1 20 B2 3C EXIT: jsr OUTSTR 002D52 1 47 6F 6F 64 .byte "Goodbye",CR,LF 002D56 1 62 79 65 0D 002D5A 1 0A 002D5B 1 EA nop 002D5C 1 00 brk ; and return to OS (doesn't work if DEBUG enabled) 002D5D 1 002D5D 1 ; *** FILL Command - Fill block of Memory *** 002D5D 1 ; takes three parameters: and addresses 002D5D 1 ; and optional byte to with 002D5D 1 A2 8A FILL: ldx #from ; point X at address 002D5F 1 20 F3 3C jsr PARAM ; get address from input buffer 002D62 1 A2 8C ldx #to ; point X at address 002D64 1 20 F3 3C jsr PARAM ; get address from input buffer 002D67 1 18 clc 002D68 1 E6 8C inc to ; add one to address 002D6A 1 90 02 bcc fnoinc 002D6C 1 E6 8D inc to+1 002D6E 1 A2 8E fnoinc: ldx #fill ; point X at temp for parameter 002D70 1 20 F9 3C jsr HXPARA ; get fill byte 002D73 1 D0 04 bne dofill ; specified ? 002D75 1 A9 FF lda #$FF ; no - use default value $FF 002D77 1 85 8E sta fill 002D79 1 20 43 3D dofill: jsr ENDTST ; test for end of input buffer 002D7C 1 A2 8A ldx #from 002D7E 1 A0 00 ldy #$00 002D80 1 A5 8E nxtfil: lda fill ; byte to fill with 002D82 1 91 8A sta (from),y ; store the byte 002D84 1 20 61 3D jsr INCCMP ; increment pointers and compare 002D87 1 D0 F7 bne nxtfil ; finished ? 002D89 1 60 rts ; return 002D8A 1 002D8A 1 20 B2 3C HELP: jsr OUTSTR ; *** HELP Command - output help *** 002D8D 1 0D 0A 54 68 .byte CR,LF,"The following commands are available:",CR,LF,LF 002D91 1 65 20 66 6F 002D95 1 6C 6C 6F 77 002DB7 1 42 41 53 45 .byte "BASE
",CR,LF 002DBB 1 20 3C 61 64 002DBF 1 64 72 65 73 002DC7 1 42 4C 41 4E .byte "BLANK",CR,LF 002DCB 1 4B 0D 0A 002DCE 1 44 45 56 49 .byte "DEVICE ",CR,LF 002DD2 1 43 45 20 3C 002DD6 1 64 65 76 69 002DDF 1 44 55 4D 50 .byte "DUMP ",CR,LF 002DE3 1 20 3C 66 72 002DE7 1 6F 6D 3E 20 002DFB 1 45 58 49 54 .byte "EXIT",CR,LF 002DFF 1 0D 0A 002E01 1 46 49 4C 4C .byte "FILL ",CR,LF 002E05 1 20 3C 66 72 002E09 1 6F 6D 3E 20 002E1A 1 4D 45 4D 20 .byte "MEM ",CR,LF 002E1E 1 3C 66 72 6F 002E22 1 6D 3E 0D 0A 002E26 1 50 52 4F 47 .byte "PROGRAM ",CR,LF 002E2A 1 52 41 4D 20 002E2E 1 3C 66 72 6F 002E36 1 52 45 41 44 .byte "READ ",CR,LF 002E3A 1 20 3C 66 72 002E3E 1 6F 6D 3E 0D 002E43 1 56 45 52 49 .byte "VERIFY ",CR,LF 002E47 1 46 59 20 3C 002E4B 1 66 72 6F 6D 002E52 1 2A 20 3C 4F .byte "* ",CR,LF,LF 002E56 1 53 20 43 6F 002E5A 1 6D 6D 61 6E 002E63 1 54 79 70 65 .byte "Type HELP for help on a",CR,LF 002E67 1 20 48 45 4C 002E6B 1 50 20 3C 63 002E86 1 70 61 72 74 .byte "particular command.",CR,LF,LF 002E8A 1 69 63 75 6C 002E8E 1 61 72 20 63 002E9C 1 43 6F 6D 6D .byte "Commands can be abbreviated with '.'",CR,LF,LF 002EA0 1 61 6E 64 73 002EA4 1 20 63 61 6E 002EC3 1 EA nop 002EC4 1 60 rts ; and return 002EC5 1 002EC5 1 ; *** HELP BASE Command - output help *** 002EC5 1 20 B2 3C HLPBAS: jsr OUTSTR 002EC8 1 0D 0A 54 68 .byte CR,LF,"The BASE command takes one parameter",CR,LF,LF 002ECC 1 65 20 42 41 002ED0 1 53 45 20 63 002EF1 1 20 20 20 42 .byte " BASE (
)",CR,LF,LF 002EF5 1 41 53 45 20 002EF9 1 28 3C 61 64 002F07 1 54 68 65 20 .byte "The command sets the BASE address of the",CR 002F0B 1 63 6F 6D 6D 002F0F 1 61 6E 64 20 002F30 1 6D 65 6D 6F .byte "memory workspace",CR,LF,LF 002F34 1 72 79 20 77 002F38 1 6F 72 6B 73 002F43 1 54 68 65 20 .byte "The default address is $4000",CR,LF,LF 002F47 1 64 65 66 61 002F4B 1 75 6C 74 20 002F62 1 49 66 20 6E .byte "If no parameter is entered then the",CR,LF 002F66 1 6F 20 70 61 002F6A 1 72 61 6D 65 002F87 1 63 75 72 72 .byte "current BASE address is output",CR,LF,LF 002F8B 1 65 6E 74 20 002F8F 1 42 41 53 45 002FA8 1 EA nop 002FA9 1 60 rts ; and return 002FAA 1 002FAA 1 ; *** HELP BLANK Command - output help *** 002FAA 1 20 B2 3C HLPBLK: jsr OUTSTR 002FAD 1 0D 0A 54 68 .byte CR,LF,"The BLANK command takes no parameters",CR,LF,LF 002FB1 1 65 20 42 4C 002FB5 1 41 4E 4B 20 002FD7 1 54 68 65 20 .byte "The command carries out a blank check of",CR 002FDB 1 63 6F 6D 6D 002FDF 1 61 6E 64 20 003000 1 74 68 65 20 .byte "the selected device.",CR,LF,LF 003004 1 73 65 6C 65 003008 1 63 74 65 64 003017 1 EA nop 003018 1 60 rts ; and return 003019 1 003019 1 ; *** HELP DEVICE Command - output help *** 003019 1 20 B2 3C HLPDEV: jsr OUTSTR 00301C 1 0D 0A 54 68 .byte CR,LF,"The DEVICE command takes one parameter",CR,LF,LF 003020 1 65 20 44 45 003024 1 56 49 43 45 003047 1 20 20 20 44 .byte " DEVICE ",CR,LF,LF 00304B 1 45 56 49 43 00304F 1 45 20 3C 64 00305C 1 3C 64 65 76 .byte " specifies the programmable",CR,LF 003060 1 69 63 65 3E 003064 1 20 73 70 65 003081 1 64 65 76 69 .byte "device which can be one of:",CR,LF 003085 1 63 65 20 77 003089 1 68 69 63 68 00309E 1 45 50 52 4F .byte "EPROMs: 2758, 2516, 2716 or 2532",CR,LF 0030A2 1 4D 73 3A 20 0030A6 1 32 37 35 38 0030C0 1 4E 53 43 20 .byte "NSC PROMs: 287L, 287H, 571L or 571H",CR,LF 0030C4 1 50 52 4F 4D 0030C8 1 73 3A 09 32 0030E5 1 54 65 73 6C .byte "Tesla PROMs: MH287L, MH287H, MH571L or",CR,LF 0030E9 1 61 20 50 52 0030ED 1 4F 4D 73 3A 00310D 1 4D 48 35 37 .byte "MH571H",CR,LF,LF 003111 1 31 48 0D 0A 003115 1 0A 003116 1 EA nop 003117 1 60 rts ; and return 003118 1 003118 1 ; *** HELP DUMP Command - output help *** 003118 1 20 B2 3C HLPDMP: jsr OUTSTR 00311B 1 0D 0A 54 68 .byte CR,LF,"The DUMP command takes 3 parameters",CR,LF,LF 00311F 1 65 20 44 55 003123 1 4D 50 20 63 003143 1 20 20 20 44 .byte " DUMP ()",CR,LF,LF 003147 1 55 4D 50 20 00314B 1 3C 66 72 6F 003165 1 54 68 65 20 .byte "The command dumps the specified memory",CR,LF 003169 1 63 6F 6D 6D 00316D 1 61 6E 64 20 00318D 1 72 61 6E 67 .byte "range to the screen with the address",CR,LF 003191 1 65 20 74 6F 003195 1 20 74 68 65 0031B3 1 66 6F 6C 6C .byte "followed by 8 bytes.",CR,LF,LF 0031B7 1 6F 77 65 64 0031BB 1 20 62 79 20 0031CA 1 54 68 65 20 .byte "The third optional parameter specifies",CR,LF 0031CE 1 74 68 69 72 0031D2 1 64 20 6F 70 0031F2 1 61 20 64 69 .byte "a different number of bytes to display",CR,LF 0031F6 1 66 66 65 72 0031FA 1 65 6E 74 20 00321A 1 6F 6E 20 61 .byte "on a line.",CR,LF,LF 00321E 1 20 6C 69 6E 003222 1 65 2E 0D 0A 003227 1 41 6C 6C 20 .byte "All values are in hex.",CR,LF,LF 00322B 1 76 61 6C 75 00322F 1 65 73 20 61 003240 1 EA nop 003241 1 60 rts ; and return 003242 1 003242 1 ; *** HELP EXIT Command - output help *** 003242 1 20 B2 3C HLPEXT: jsr OUTSTR 003245 1 0D 0A 54 68 .byte CR,LF,"The EXIT command returns to the OS",CR,LF,LF 003249 1 65 20 45 58 00324D 1 49 54 20 63 00326C 1 EA nop 00326D 1 60 rts ; and return 00326E 1 00326E 1 ; *** HELP FILL Command - output help *** 00326E 1 20 B2 3C HLPFIL: jsr OUTSTR 003271 1 0D 0A 54 68 .byte CR,LF,"The FILL command takes three parameters",CR,LF,LF 003275 1 65 20 46 49 003279 1 4C 4C 20 63 00329D 1 20 20 20 46 .byte " FILL ",CR,LF,LF 0032A1 1 49 4C 4C 20 0032A5 1 3C 66 72 6F 0032BA 1 54 68 65 20 .byte "The command fills the specified memory",CR,LF 0032BE 1 63 6F 6D 6D 0032C2 1 61 6E 64 20 0032E2 1 72 61 6E 67 .byte "range with the value .",CR,LF,LF 0032E6 1 65 20 77 69 0032EA 1 74 68 20 74 003301 1 41 6C 6C 20 .byte "All values are in hex.",CR,LF,LF 003305 1 76 61 6C 75 003309 1 65 73 20 61 00331A 1 EA nop 00331B 1 60 rts ; and return 00331C 1 00331C 1 ; *** HELP MEM Command - output help *** 00331C 1 20 B2 3C HLPMEM: jsr OUTSTR 00331F 1 0D 0A 54 68 .byte CR,LF,"The MEM command takes one parameter",CR,LF,LF 003323 1 65 20 4D 45 003327 1 4D 20 63 6F 003347 1 20 20 20 4D .byte " MEM ",CR,LF,LF 00334B 1 45 4D 20 3C 00334F 1 66 72 6F 6D 003357 1 54 68 65 20 .byte "The command displays the address",CR,LF 00335B 1 63 6F 6D 6D 00335F 1 61 6E 64 20 003380 1 61 6E 64 20 .byte "and current contents of that address.",CR,LF,LF 003384 1 63 75 72 72 003388 1 65 6E 74 20 0033A8 1 50 72 65 73 .byte "Pressing the U key will move 'up' to",CR,LF 0033AC 1 73 69 6E 67 0033B0 1 20 74 68 65 0033CE 1 74 68 65 20 .byte "the next address, pressing V will move",CR,LF 0033D2 1 6E 65 78 74 0033D6 1 20 61 64 64 0033F6 1 27 64 6F 77 .byte "'down' to the previous address.",CR,LF,LF 0033FA 1 6E 27 20 74 0033FE 1 6F 20 74 68 003418 1 54 68 65 20 .byte "The contents can be changed by typing a hex value.",CR,LF,LF 00341C 1 63 6F 6E 74 003420 1 65 6E 74 73 00344D 1 50 72 65 73 .byt "Pressing any other key will exit.",CR,LF,LF 003451 1 73 69 6E 67 003455 1 20 61 6E 79 003471 1 EA nop 003472 1 60 rts ; and return 003473 1 003473 1 ; *** HELP PROGRAM Command - output help *** 003473 1 20 B2 3C HLPPGM: jsr OUTSTR 003476 1 0D 0A 54 68 .byte CR,LF,"The PROGRAM command takes one parameter",CR,LF,LF 00347A 1 65 20 50 52 00347E 1 4F 47 52 41 0034A2 1 20 20 20 50 .byte " PROGRAM ()",CR,LF,LF 0034A6 1 52 4F 47 52 0034AA 1 41 4D 20 28 0034B8 1 50 72 6F 67 .byte "Programs the selected device with the",CR,LF 0034BC 1 72 61 6D 73 0034C0 1 20 74 68 65 0034DF 1 64 61 74 61 .byte "data stored at address .",CR,LF,LF 0034E3 1 20 73 74 6F 0034E7 1 72 65 64 20 003500 1 49 66 20 6E .byte "If no address is entered then the BASE",CR,LF 003504 1 6F 20 61 64 003508 1 64 72 65 73 003528 1 61 64 64 72 .byte "address is used.",CR,LF,LF 00352C 1 65 73 73 20 003530 1 69 73 20 75 00353B 1 EA nop 00353C 1 60 rts ; and return 00353D 1 00353D 1 ; *** HELP READ Command - output help *** 00353D 1 20 B2 3C HLPRED: jsr OUTSTR 003540 1 0D 0A 54 68 .byte CR,LF,"The READ command takes one parameter",CR,LF,LF 003544 1 65 20 52 45 003548 1 41 44 20 63 003569 1 20 20 20 52 .byte " READ ()",CR,LF,LF 00356D 1 45 41 44 20 003571 1 28 3C 66 72 00357C 1 52 65 61 64 .byte "Reads the selected device and writes",CR,LF 003580 1 73 20 74 68 003584 1 65 20 73 65 0035A2 1 74 68 65 20 .byte "the data to the address.",CR,LF,LF 0035A6 1 64 61 74 61 0035AA 1 20 74 6F 20 0035C4 1 49 66 20 6E .byte "If no address is entered then the BASE",CR,LF 0035C8 1 6F 20 61 64 0035CC 1 64 72 65 73 0035EC 1 61 64 64 72 .byte "address is used.",CR,LF,LF 0035F0 1 65 73 73 20 0035F4 1 69 73 20 75 0035FF 1 EA nop 003600 1 60 rts ; and return 003601 1 003601 1 ; *** HELP VERIFY Command - output help *** 003601 1 20 B2 3C HLPVER: jsr OUTSTR 003604 1 0D 0A 54 68 .byte CR,LF,"The VERIFY command takes one parameter",CR,LF,LF 003608 1 65 20 56 45 00360C 1 52 49 46 59 00362F 1 20 20 20 56 .byte " VERIFY ()",CR,LF,LF 003633 1 45 52 49 46 003637 1 59 20 28 3C 003644 1 52 65 61 64 .byte "Reads the selected device and compares",CR,LF 003648 1 73 20 74 68 00364C 1 65 20 73 65 00366C 1 74 68 65 20 .byte "the contents with the data stored at",CR,LF 003670 1 63 6F 6E 74 003674 1 65 6E 74 73 003692 1 61 64 64 72 .byte "address .",CR,LF,LF 003696 1 65 73 73 20 00369A 1 3C 66 72 6F 0036A4 1 49 66 20 6E .byte "If no address is entered then the BASE",CR,LF 0036A8 1 6F 20 61 64 0036AC 1 64 72 65 73 0036CC 1 61 64 64 72 .byte "address is used.",CR,LF,LF 0036D0 1 65 73 73 20 0036D4 1 69 73 20 75 0036DF 1 EA nop 0036E0 1 60 rts ; and return 0036E1 1 0036E1 1 ; *** MEM Command - read/modify memory *** 0036E1 1 ; takes one parameter: address 0036E1 1 A2 8A MEM: ldx #from ; point X at address 0036E3 1 20 F3 3C jsr PARAM ; get address from input buffer 0036E6 1 20 43 3D jsr ENDTST ; test for end of input 0036E9 1 20 ED FF wraddr: jsr OSCRLF ; output CR LF 0036EC 1 20 72 3D jsr OUTWRD ; output address 0036EF 1 CA dex ; backup X to point at from address 0036F0 1 CA dex 0036F1 1 A1 00 wrdata: lda ($00,x) ; read data from memory location 0036F3 1 85 88 sta temp ; save it 0036F5 1 20 95 3D jsr OUTBYT ; output byte 0036F8 1 20 E3 FF jsr OSRDCH ; read input channel 0036FB 1 A8 tay 0036FC 1 20 2D 3D jsr HEXKEY ; hex key pressed ? 0036FF 1 B0 15 bcs updown ; no - try up and down 003701 1 A0 04 ldy #$04 003703 1 06 88 shift: asl temp ; shift old byte one digit left 003705 1 88 dey 003706 1 D0 FB bne shift 003708 1 05 88 ora temp ; OR new digit in 00370A 1 81 00 sta ($00,x) ; alter memory location contents 00370C 1 A9 7F lda #DEL ; move cursor over old byte 00370E 1 20 F4 FF jsr OSWRCH ; with two deletes 003711 1 20 F4 FF jsr OSWRCH 003714 1 D0 DB bne wrdata ; write out new data 003716 1 C0 55 updown: cpy #'U' ; up key 'U' pressed ? 003718 1 D0 08 bne down 00371A 1 E6 8A inc from ; increment address 00371C 1 D0 CB bne wraddr ; then rewrite it 00371E 1 E6 8B inc from+1 003720 1 B0 C7 bcs wraddr 003722 1 C0 56 down: cpy #'V' ; down key 'V' pressed ? 003724 1 D0 0A bne crlf ; some other key ? - output CR LF and return 003726 1 A5 8A lda from ; decrement address 003728 1 D0 02 bne nodec 00372A 1 C6 8B dec from+1 00372C 1 C6 8A nodec: dec from 00372E 1 B0 B9 bcs wraddr ; always branch to rewrite address 003730 1 4C ED FF crlf: jmp OSCRLF ; output CR LF and return 003733 1 003733 1 ; *** OS Command *** 003733 1 A0 00 OSCOM: ldy #$00 ; move command in buffer down one to overwrite '*' 003735 1 B9 01 01 movcom: lda buffer+1,y ; get command from input buffer 003738 1 99 00 01 sta buffer,y ; put back in input buffer 00373B 1 C9 0D cmp #CR ; until CR found 00373D 1 F0 0A beq calcom ; finished 00373F 1 C8 iny ; else increment pointer 003740 1 C0 3F cpy #$3F ; check for end of buffer (64 characters) 003742 1 D0 F1 bne movcom ; and move rest of command 003744 1 A9 0D lda #CR ; end of buffer reached 003746 1 99 00 01 sta buffer,y ; put a CR at end of buffer and 003749 1 4C F7 FF calcom: jmp OSCLI ; pass to OS and return 00374C 1 00374C 1 ; *** PROGRAM Command - program device *** 00374C 1 ; takes one parameter: address of data 00374C 1 20 ED 3D PROGRM: jsr CHKDEV ; check a device has been set 00374F 1 90 28 bcc prexit ; if carry clear no device set - exit 003751 1 20 D3 3E jsr CPYBAS ; copy BASE address to 003754 1 20 25 3D jsr RDIBUF ; read next character from input buffer ignoring leading spaces 003757 1 C9 0D cmp #CR ; is it a CR ? 003759 1 F0 05 beq puseb ; yes - use BASE 00375B 1 A2 8A ldx #from ; no - get parameter, point X at address 00375D 1 20 F3 3C jsr PARAM ; get address from input buffer 003760 1 20 43 3D puseb: jsr ENDTST ; check for end of input buffer 003763 1 20 08 2B prrept: jsr CBLANK ; check device is blank 003766 1 20 C0 2A jsr BLMESS ; output blank/not blank message 003769 1 20 AB 3D jsr CONTIN ; continue ? 00376C 1 D0 0B bne prexit ; no - return 00376E 1 20 7A 37 jsr PRCORE ; do program 003771 1 20 ED FF jsr OSCRLF 003774 1 20 C4 3D jsr REPEAT ; do it again ? 003777 1 F0 EA beq prrept ; yes - repeat 003779 1 60 prexit: rts ; otherwise return 00377A 1 00377A 1 ; *** PROGRAM Core *** 00377A 1 20 0B 3E PRCORE: jsr INIPTR ; initialise pointers for programming 00377D 1 20 DB 3D jsr PRGMES ; output Programming message 003780 1 A6 80 ldx type ; call either EPROM Program (0), NSC PROM Program (1) 003782 1 ; or Tesla PROM Program (2) 003782 1 F0 0B beq eprog ; if 0 - EPROM 003784 1 CA dex ; NSC PROM ? 003785 1 D0 04 bne ptesla ; if not must be Tesla PROM 003787 1 20 A7 3A jsr PPROG ; call NSC PROM Program routine 00378A 1 60 rts ; and return 00378B 1 20 FE 3B ptesla: jsr TPROG ; call Tesla PROM Program routine 00378E 1 60 rts ; and return 00378F 1 A5 83 eprog: lda prctrl ; EPROM - load control byte 003791 1 A4 81 ldy size ; get EPROM size 003793 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 003795 1 F0 0C beq eptwo ; branch if 2K 003797 1 30 0F bmi epone ; branch if 1K 003799 1 20 97 39 jsr EPROG ; program 4K device (1st quarter) 00379C 1 09 04 ora #$04 ; control byte for 2nd quarter (A10 high, A11 low) 00379E 1 20 97 39 jsr EPROG ; program 2nd quarter 0037A1 1 49 0C eor #$0C ; control byte for 3rd quarter (A10 low, A11 high) 0037A3 1 20 97 39 eptwo: jsr EPROG ; program 2K device 1st half / 3rd quarter 0037A6 1 09 04 ora #$04 ; control byte for 2nd half / 4th quarter (A10 high) 0037A8 1 20 97 39 epone: jsr EPROG ; program 1K device / 2nd half / 4th quarter 0037AB 1 20 ED FF pdone: jsr OSCRLF 0037AE 1 60 rts ; otherwise return 0037AF 1 0037AF 1 ; *** READ Command - read device into memory *** 0037AF 1 ; takes one parameter: (
) 0037AF 1 ; if no parameter is entered then the BASE address is used 0037AF 1 20 ED 3D READ: jsr CHKDEV ; check a device has been set ? 0037B2 1 90 31 bcc rexit ; if carry clear no device set - return 0037B4 1 20 D3 3E jsr CPYBAS ; copy BASE address to 0037B7 1 20 25 3D jsr RDIBUF ; read next character from input buffer ignoring leading spaces 0037BA 1 C9 0D cmp #CR ; is it a CR ? 0037BC 1 F0 05 beq ruseb ; yes - use BASE 0037BE 1 A2 8A ldx #from ; no - get parameter, point X at address 0037C0 1 20 F3 3C jsr PARAM ; get address from input buffer 0037C3 1 20 43 3D ruseb: jsr ENDTST ; check for end of input buffer 0037C6 1 20 B2 3C rrept: jsr OUTSTR 0037C9 1 52 65 61 64 .byte "Reading Device: " 0037CD 1 69 6E 67 20 0037D1 1 44 65 76 69 0037D9 1 EA nop 0037DA 1 20 E6 37 jsr CREAD ; do read 0037DD 1 20 ED FF jsr OSCRLF 0037E0 1 20 C4 3D jsr REPEAT ; do it again ? 0037E3 1 F0 E1 beq rrept ; yes - repeat 0037E5 1 60 rexit: rts ; otherwise return 0037E6 1 0037E6 1 ; *** READ Core *** 0037E6 1 20 0B 3E CREAD: jsr INIPTR ; initialise pointers and CRC 0037E9 1 A6 80 ldx type ; call either EPROM Read (0), NSC PROM Read (1) 0037EB 1 ; or Tesla PROM Read (2) 0037EB 1 F0 0B beq eread ; if 0 - EPROM 0037ED 1 CA dex ; NSC PROM ? 0037EE 1 D0 04 bne rtesla ; if not must be Tesla PROM 0037F0 1 20 1D 3A jsr PREAD ; call NSC PROM Read routine 0037F3 1 60 rts ; and return 0037F4 1 20 6C 3B rtesla: jsr TREAD ; call Tesla PROM Read routine 0037F7 1 60 rts ; and return 0037F8 1 A9 00 eread: lda #$00 ; EPROM - load initial control byte (A10 and A11 low) 0037FA 1 A4 81 ldy size ; get EPROM size 0037FC 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 0037FE 1 F0 0C beq ertwo ; branch if 2K 003800 1 30 0F bmi erone ; branch if 1K 003802 1 20 2B 39 jsr EREAD ; read 4K device (1st quarter) 003805 1 A9 04 lda #$04 ; control byte for 2nd quarter (A10 high, A11 low) 003807 1 20 2B 39 jsr EREAD ; read 2nd quarter 00380A 1 A9 08 lda #$08 ; control byte for 3rd quarter (A10 low, A11 high) 00380C 1 20 2B 39 ertwo: jsr EREAD ; read 2K device 1st half / 3rd quarter 00380F 1 09 04 ora #$04 ; control byte for 2nd half / 4th quarter (A10 high) 003811 1 20 2B 39 erone: jsr EREAD ; read 1K device / 2nd half / 4th quarter 003814 1 20 83 3D jsr CRCOUT ; output CRC (EPROM only) 003817 1 20 ED FF rdrept: jsr OSCRLF ; output CR LF 00381A 1 60 rts ; and return 00381B 1 00381B 1 ; *** VERIFY Command - verify device against memory *** 00381B 1 ; takes one parameter: address for data 00381B 1 20 ED 3D VERIFY: jsr CHKDEV ; check a device has been set ? 00381E 1 90 1A bcc vnodev ; if carry clear no device set - return 003820 1 20 D3 3E jsr CPYBAS ; copy BASE address to 003823 1 20 25 3D jsr RDIBUF ; read next character from input buffer ignoring leading spaces 003826 1 C9 0D cmp #CR ; is it a CR ? 003828 1 F0 05 beq vuseb ; yes - use BASE 00382A 1 A2 8A ldx #from ; no - get parameter, point X at address 00382C 1 20 F3 3C jsr PARAM ; get address from input buffer 00382F 1 20 43 3D vuseb: jsr ENDTST ; check for end of input buffer 003832 1 20 3B 38 vrept: jsr CVERFY ; do verify 003835 1 003835 1 20 C4 3D jsr REPEAT ; do it again ? 003838 1 F0 F8 beq vrept ; yes - repeat 00383A 1 60 vnodev: rts ; otherwise return 00383B 1 00383B 1 ; *** VERIFY Core *** 00383B 1 20 B2 3C CVERFY: jsr OUTSTR 00383E 1 56 65 72 69 .byte "Verifying Device: " 003842 1 66 79 69 6E 003846 1 67 20 44 65 003850 1 EA nop 003851 1 20 0B 3E jsr INIPTR ; initialise pointers and CRC 003854 1 A6 80 ldx type ; call either EPROM Verify (0), NSC PROM verify (1) or Tesla PROM verify (2) 003856 1 F0 11 beq veprom ; if 0 - EPROM 003858 1 CA dex ; NSC PROM ? 003859 1 D0 07 bne vtesla ; if not must be Tesla PROM 00385B 1 20 61 3A jsr PVERFY ; call NSC PROM Verify routine 00385E 1 F0 62 beq verok ; verify OK 003860 1 D0 73 bne vernok ; verify not OK 003862 1 20 B8 3B vtesla: jsr TVERFY ; call Tesla PROM Verify routine 003865 1 F0 5B beq verok ; verify OK 003867 1 D0 6C bne vernok ; verify not OK 003869 1 A4 81 veprom: ldy size ; get EPROM size 00386B 1 C0 02 cpy #$02 ; 1, 2 or 4K ? 00386D 1 F0 30 beq evtwo ; branch if 2K 00386F 1 30 46 bmi evone ; branch if 1K 003871 1 ; verify first 1K of 4K EPROM 003871 1 A9 00 lda #$00 ; set address MSB for a fail 003873 1 85 9A sta fail+1 003875 1 A5 84 lda vectrl ; load control byte (A10 and A11 low) 003877 1 20 5E 39 jsr EVERFY ; verify 4K device (1st quarter) 00387A 1 D0 59 bne vernok 00387C 1 ; verify second 1K of 4K EPROM 00387C 1 A9 04 lda #$04 ; set address MSB for a fail 00387E 1 85 9A sta fail+1 003880 1 05 84 ora vectrl ; add control byte 003882 1 20 5E 39 jsr EVERFY ; verify 2nd quarter 003885 1 D0 4E bne vernok ; verify fail - branch 003887 1 ; verify third 1K of 4K EPROM 003887 1 A9 08 lda #$08 ; set A11 high 003889 1 85 9A sta fail+1 ; save as fail address MSB 00388B 1 05 84 ora vectrl ; add control byte 00388D 1 20 5E 39 jsr EVERFY ; verify 3rd quarter 003890 1 D0 43 bne vernok ; verify fail - branch 003892 1 ; verify fourth 1K of 4K EPROM 003892 1 A9 0C lda #$0C ; set A10 and A11 high 003894 1 85 9A sta fail+1 ; save as fail address MSB 003896 1 05 84 ora vectrl ; add control byte 003898 1 20 5E 39 jsr EVERFY ; verify 4th quarter 00389B 1 D0 38 bne vernok ; verify fail - branch 00389D 1 F0 23 beq verok ; 4K EPROM verify OK 00389F 1 evtwo: ; verify first 1K of 2K EPROM 00389F 1 A9 00 lda #$00 ; set A10 low 0038A1 1 85 9A sta fail+1 ; save as fail address MSB 0038A3 1 05 84 ora vectrl ; add control byte 0038A5 1 20 5E 39 jsr EVERFY ; verify first half of 2K EPROM 0038A8 1 D0 2B bne vernok ; verify fail - branch 0038AA 1 ; verify second 1K of 2K EPROM 0038AA 1 A9 04 lda #$04 ; set A10 high 0038AC 1 85 9A sta fail+1 ; save as fail address MSB 0038AE 1 05 84 ora vectrl ; add control byte 0038B0 1 20 5E 39 jsr EVERFY ; verify second half of 2K EPROM 0038B3 1 D0 20 bne vernok ; verify fail - branch 0038B5 1 F0 0B beq verok ; 2K EPROM verify OK 0038B7 1 evone: ; verify 1K EPROM 0038B7 1 A9 00 lda #$00 ; set fail address MSB 0038B9 1 85 9A sta fail+1 0038BB 1 05 84 ora vectrl ; add control byte 0038BD 1 20 5E 39 jsr EVERFY ; verify 1K device 0038C0 1 D0 13 bne vernok ; verify fail - branch 0038C2 1 20 B2 3C verok: jsr OUTSTR ; verify OK - output message 0038C5 1 0D 0A 4F 4B .byte CR,LF,"OK" 0038C9 1 EA nop 0038CA 1 A6 80 ldx type ; only output CRC for EPROM 0038CC 1 D0 03 bne nocrc 0038CE 1 20 83 3D jsr CRCOUT ; output CRC 0038D1 1 20 ED FF nocrc: jsr OSCRLF ; CR LF 0038D4 1 60 rts ; and return 0038D5 1 20 B2 3C vernok: jsr OUTSTR ; verify not OK - output message 0038D8 1 0D 0A 46 41 .byte CR,LF,"FAIL at Address: " 0038DC 1 49 4C 20 61 0038E0 1 74 20 41 64 0038EB 1 EA nop 0038EC 1 A2 99 ldx #fail ; point X at fail address 0038EE 1 20 72 3D jsr OUTWRD ; output 0038F1 1 20 ED FF jsr OSCRLF 0038F4 1 60 rts ; and return 0038F5 1 0038F5 1 ; **** EPROM ROUTINES **** 0038F5 1 0038F5 1 ; *** EPROM Blank *** 0038F5 1 ; no entry parameters, return Z=1 if blank 0038F5 1 85 89 EBLANK: sta ctrl ; save control byte 0038F7 1 A9 90 lda #$90 ; set Port A (Data) to input 0038F9 1 8D 83 19 sta actlrg 0038FC 1 A9 00 lda #$00 0038FE 1 85 95 sta page ; clear page counter 003900 1 A8 tay ; and byte pointer 003901 1 A5 95 ecpage: lda page ; get page counter (A8 and A9) 003903 1 05 89 ora ctrl ; OR in control byte 003905 1 8D 82 19 sta aportc ; and update Port C 003908 1 8C 81 19 ecnloc: sty aportb ; set address LSB 00390B 1 84 99 sty fail ; save as fail address LSB in case not blank 00390D 1 AD 80 19 lda aporta ; read EPROM data 003910 1 C9 FF cmp #$FF ; blank ? 003912 1 D0 16 bne ecfail ; branch if not 003914 1 C8 iny ; next location 003915 1 D0 EA bne ecpage ; do all 256 bytes of page 003917 1 A9 2A lda #'*' ; output a * for each page checked 003919 1 20 F4 FF jsr OSWRCH 00391C 1 E6 95 inc page ; increment page counter 00391E 1 E6 9A inc fail+1 ; increment fail address MSB 003920 1 A5 95 lda page ; read page counter 003922 1 C9 04 cmp #$04 003924 1 D0 DB bne ecpage ; do all 4 pages 003926 1 08 php ; save status 003927 1 A5 89 lda ctrl ; reload control byte 003929 1 28 plp ; retrieve status 00392A 1 60 ecfail: rts ; and return (Z=1 if blank) 00392B 1 00392B 1 ; *** EPROM Read *** 00392B 1 85 89 EREAD: sta ctrl ; save control byte 00392D 1 A9 90 lda #$90 ; set Port A, data to input 00392F 1 8D 83 19 sta actlrg 003932 1 A9 00 lda #$00 003934 1 85 95 sta page ; clear page counter 003936 1 A8 tay ; and byte pointer 003937 1 A5 95 erpage: lda page ; get page counter (A8 and A9) 003939 1 05 89 ora ctrl ; combine with control byte 00393B 1 8D 82 19 sta aportc ; and update Port C 00393E 1 8C 81 19 ernloc: sty aportb ; set address 003941 1 AD 80 19 lda aporta ; read EPROM location 003944 1 91 8E sta (point),y ; store it 003946 1 20 1C 3E jsr CRC ; add to CRC 003949 1 C8 iny ; next location 00394A 1 D0 F2 bne ernloc ; do all 256 bytes of page 00394C 1 E6 8F inc point+1 ; increment address pointer MSB 00394E 1 A9 2A lda #'*' ; output a * for each page read 003950 1 20 F4 FF jsr OSWRCH 003953 1 E6 95 inc page ; increment page counter 003955 1 A5 95 lda page ; read page counter 003957 1 C9 04 cmp #$04 003959 1 D0 DC bne erpage ; do all 4 pages 00395B 1 A5 89 lda ctrl ; reload control byte 00395D 1 60 rts ; and return 00395E 1 00395E 1 ; *** EPROM Verify *** 00395E 1 ; no entry parameters, on exit Z=1 if verify OK 00395E 1 ; verifies 1K of EPROM i.e. four 256 byte pages 00395E 1 85 89 EVERFY: sta ctrl ; save control byte 003960 1 A9 90 lda #$90 ; set Port A, data to input 003962 1 8D 83 19 sta actlrg 003965 1 A9 00 lda #$00 003967 1 85 95 sta page ; clear page counter 003969 1 A8 tay ; and byte pointer 00396A 1 A5 95 evpage: lda page ; get page counter (A8 and A9) 00396C 1 05 89 ora ctrl ; OR with ctrl 00396E 1 8D 82 19 sta aportc ; and update Port C 003971 1 8C 81 19 evnloc: sty aportb ; set address LSB 003974 1 84 99 sty fail ; save as fail address LSB in case verify fails 003976 1 AD 80 19 lda aporta ; read EPROM 003979 1 20 1C 3E jsr CRC ; add to CRC 00397C 1 D1 8E cmp (point),y ; compare with memory 00397E 1 D0 16 bne evrtn ; return with Z=0 003980 1 C8 iny ; next location 003981 1 D0 EE bne evnloc ; do all 256 bytes of page 003983 1 E6 8F inc point+1 ; increment address pointer MSB 003985 1 A9 2A lda #'*' ; output a * for each page checked 003987 1 20 F4 FF jsr OSWRCH 00398A 1 E6 95 inc page ; increment page counter 00398C 1 E6 9A inc fail+1 ; increment fail address MSB 00398E 1 A5 95 lda page ; read page counter 003990 1 C9 04 cmp #$04 003992 1 D0 D6 bne evpage ; do all 4 pages 003994 1 ; lda ctrl ; reload control byte 003994 1 A2 00 ldx #$00 ; Z=1 003996 1 60 evrtn: rts ; and return 003997 1 003997 1 ; *** EPROM Program *** 003997 1 85 89 EPROG: sta ctrl ; save control byte 003999 1 A9 80 lda #$80 ; all Ports are outputs 00399B 1 8D 83 19 sta actlrg 00399E 1 A9 00 lda #$00 0039A0 1 85 94 sta count 0039A2 1 A8 tay 0039A3 1 A5 94 eppage: lda count ; page counter (A8 and A9) 0039A5 1 05 89 ora ctrl ; OR with ctrl 0039A7 1 8D 82 19 sta aportc ; and update Port C 0039AA 1 8C 81 19 epnloc: sty aportb ; set address 0039AD 1 AD 21 0E lda keybrd ; check for escape key 0039B0 1 C9 1B cmp #ESC 0039B2 1 D0 01 bne noesc 0039B4 1 00 brk ; emergency exit - return to OS 0039B5 1 B1 8E noesc: lda (point),y ; read from memory 0039B7 1 C9 FF cmp #$FF ; if $FF 0039B9 1 F0 06 beq goon ; then nothing to do 0039BB 1 8D 80 19 sta aporta ; send to Port A data 0039BE 1 20 DD 39 jsr FLIPBT ; and apply program pulse 0039C1 1 C8 goon: iny ; next location 0039C2 1 D0 E6 bne epnloc ; do all 256 bytes 0039C4 1 E6 8F inc point+1 ; increment pointer MSB 0039C6 1 E6 94 inc count 0039C8 1 A9 2A lda #'*' ; output a * for each page programmed 0039CA 1 20 F4 FF jsr OSWRCH 0039CD 1 E6 95 inc page 0039CF 1 A5 94 lda count 0039D1 1 C9 04 cmp #$04 0039D3 1 D0 CE bne eppage ; do all 4 pages 0039D5 1 A9 90 lda #$90 0039D7 1 8D 83 19 sta actlrg ; switch things off 0039DA 1 A5 89 lda ctrl ; retrieve control byte 0039DC 1 60 rts ; and return 0039DD 1 0039DD 1 ; *** EPROM Programming Pulse *** 0039DD 1 A5 86 FLIPBT: lda ppctrl 0039DF 1 8D 83 19 sta actlrg ; flip bit defined in ppctrl 0039E2 1 A2 19 ldx #$19 ; now wait 50mS 0039E4 1 C6 88 dlylp: dec temp 0039E6 1 D0 FC bne dlylp 0039E8 1 CA dex 0039E9 1 D0 F9 bne dlylp 0039EB 1 49 01 eor #$01 0039ED 1 8D 83 19 sta actlrg ; return bit to previous level 0039F0 1 60 rts ; and return 0039F1 1 0039F1 1 ; **** NSC Fusible Link PROM Routines **** 0039F1 1 0039F1 1 ; *** NSC PROM BLANK **** 0039F1 1 ; no entry parameters, returns Z=1 if blank 0039F1 1 A0 00 PBLANK: ldy #$00 ; reset byte pointer 0039F3 1 84 9A sty fail+1 ; save address MSB for a fail 0039F5 1 A6 81 ldx size ; 256 or 512 bytes (0 or 1) 0039F7 1 A9 90 lda #$90 ; set control byte for reading (Port A input) 0039F9 1 8D 83 19 sta actlrg 0039FC 1 A9 30 lda #$30 ; set Port C for lower half C5=1 for read, C0(A8)=0 0039FE 1 8D 82 19 pbfull: sta aportc 003A01 1 8C 81 19 pbpage: sty aportb ; set address LSB 003A04 1 AD 80 19 lda aporta ; read PROM data 003A07 1 29 0F and #$0F ; mask lower nibble 003A09 1 D0 11 bne pbfail ; blank (0) ? - branch if not 003A0B 1 C8 iny ; next location 003A0C 1 D0 F3 bne pbpage ; read all 256 bytes of page 003A0E 1 A9 2A lda #'*' ; output a * for each page checked 003A10 1 20 F4 FF jsr OSWRCH 003A13 1 A9 31 lda #$31 ; set Port C for upper half C5(PROM RW)=1 Read, C0(A8) = 1 003A15 1 E6 9A inc fail+1 ; increment fail address MSB 003A17 1 CA dex ; decrement PROM size 003A18 1 F0 E4 beq pbfull ; do the other half if 512 byte PROM 003A1A 1 A9 00 lda #$00 ; set Z 003A1C 1 60 pbfail: rts ; and return (Z=1 if blank) 003A1D 1 003A1D 1 ; *** NSC PROM Read *** 003A1D 1 ; no entry parameters, no return values 003A1D 1 A0 00 PREAD: ldy #$00 ; reset byte pointer 003A1F 1 A6 81 ldx size ; 256 or 512 bytes (0 or 1) 003A21 1 A9 90 lda #$90 ; set control byte for reading (Port A input) 003A23 1 8D 83 19 sta actlrg 003A26 1 A9 20 lda #$20 ; set Port C for lower half C5(PROM RW)=1 Read, C0(A8)=0 003A28 1 8D 82 19 prfull: sta aportc 003A2B 1 8C 81 19 prpage: sty aportb ; set address LSB 003A2E 1 B1 8A lda (from),y ; get current data from destination location 003A30 1 24 82 bit hilow ; check for upper or lower nibble 003A32 1 10 0E bpl prlow ; lower - branch 003A34 1 29 0F and #$0F ; upper nibble - mask and save lower half 003A36 1 85 88 sta temp ; of current data 003A38 1 AD 80 19 lda aporta ; read byte from PROM 003A3B 1 0A asl a ; shift to upper nibble 003A3C 1 0A asl a 003A3D 1 0A asl a 003A3E 1 0A asl a 003A3F 1 4C 4B 3A jmp prcom ; and combine data 003A42 1 29 F0 prlow: and #$F0 ; save upper nibble of current data 003A44 1 85 88 sta temp 003A46 1 AD 80 19 lda aporta ; load byte from PROM 003A49 1 29 0F and #$0F ; mask off lower nibble 003A4B 1 05 88 prcom: ora temp ; assemble new byte 003A4D 1 91 8A sta (from),y ; and put it back 003A4F 1 C8 iny ; increment byte pointer 003A50 1 D0 D9 bne prpage ; read all 256 bytes of page 003A52 1 A9 2A lda #'*' ; output a * for each page read 003A54 1 20 F4 FF jsr OSWRCH 003A57 1 CA dex ; decrement PROM size 003A58 1 D0 06 bne prrts ; when not zero ($FF) finished 003A5A 1 E6 8B inc from+1 ; increment memory pointer MSB 003A5C 1 A9 21 lda #$21 ; set Port C for upper half C5(PROM RW)=1 Read, C0(A8)=1 003A5E 1 D0 C8 bne prfull ; and do the other half if 512 bytes 003A60 1 60 prrts: rts ; and return 003A61 1 003A61 1 ; *** NSC PROM Verify *** 003A61 1 ; no entry parameters, on exit Z=1 if verify OK 003A61 1 A0 00 PVERFY: ldy #$00 ; reset byte pointer 003A63 1 84 9A sty fail+1 ; save address MSB for a fail 003A65 1 A6 81 ldx size ; 256 or 512 bytes (0 or 1) 003A67 1 A5 8B lda from+1 ; save a copy of from address MSB for repeat 003A69 1 85 88 sta temp 003A6B 1 A9 90 lda #$90 ; set control byte for reading (Port A input) 003A6D 1 8D 83 19 sta actlrg 003A70 1 A9 20 lda #$20 ; set Port C for lower half C5(PROM RW)=1 Read, C0(A8)=0 003A72 1 8D 82 19 pvfull: sta aportc 003A75 1 8C 81 19 pvpage: sty aportb ; set address (A0 to A7) 003A78 1 B1 8A lda (from),y ; get data from memory 003A7A 1 24 82 bit hilow ; check for upper or lower nibble 003A7C 1 10 04 bpl pvlow ; lower - branch 003A7E 1 4A lsr a ; upper - shift upper to lower 003A7F 1 4A lsr a 003A80 1 4A lsr a 003A81 1 4A lsr a 003A82 1 4D 80 19 pvlow: eor aporta ; match against data in PROM 003A85 1 29 0F and #$0F ; keep lower nibble, result should be 0 003A87 1 D0 15 bne pvnok ; if not return with Z=0 003A89 1 C8 pnoflg: iny ; increment byte pointer 003A8A 1 D0 E9 bne pvpage ; read all 256 bytes of page 003A8C 1 A9 2A lda #'*' ; output a * for each page verified 003A8E 1 20 F4 FF jsr OSWRCH 003A91 1 CA dex ; decrement PROM size 003A92 1 D0 08 bne pvok ; when not zero ($FF) finished 003A94 1 E6 8B inc from+1 ; increment memory pointer MSB 003A96 1 E6 9A inc fail+1 ; increment fail address MSB 003A98 1 A9 21 lda #$21 ; set Port C for upper half C5(PROM RW)=1 Read, C0(A8)=1 003A9A 1 D0 D6 bne pvfull ; and do the upper half if 512 bytes 003A9C 1 A2 00 pvok: ldx #$00 ; Z=1 003A9E 1 08 pvnok: php 003A9F 1 84 99 sty fail ; save fail address LSB 003AA1 1 A5 88 lda temp 003AA3 1 85 8B sta from+1 ; restore from 003AA5 1 28 plp 003AA6 1 60 rts ; and return 003AA7 1 003AA7 1 ; *** NSC PROM Program *** 003AA7 1 A0 00 PPROG: ldy #$00 ; reset byte pointer 003AA9 1 A2 00 ldx #$00 ; set A8 low for first 256 bytes 003AAB 1 A9 08 halfp: lda #$08 ; start on most significant bit 003AAD 1 85 91 sta mask 003AAF 1 A9 80 p4bit: lda #$80 ; no of tries at blowing each location 003AB1 1 85 92 sta tries 003AB3 1 A9 10 lda #$10 ; no of extra pulses after blowing 003AB5 1 85 93 sta extra 003AB7 1 20 D7 3A jsr PCORE ; go and blow a bit 003ABA 1 46 91 lsr mask ; step to next bit in byte 003ABC 1 90 F1 bcc p4bit ; do all four bits 003ABE 1 C8 iny 003ABF 1 D0 EA bne halfp ; and for all 256 bytes 003AC1 1 A9 2A lda #'*' ; output a * for each page programmed 003AC3 1 20 F4 FF jsr OSWRCH 003AC6 1 E0 01 cpx #$01 ; if A8 high then we have completed 2nd page of 512 byte PROM 003AC8 1 F0 0A beq ppfin ; so finished 003ACA 1 A6 81 ldx size ; check PROM size 256 or 512 byte (0 or 1) 003ACC 1 F0 06 beq ppfin ; if 256 byte then we are finished 003ACE 1 E6 8B inc from+1 ; 512 byte - increment memory pointer MSB 003AD0 1 A2 01 ldx #$01 ; set A8 high 003AD2 1 D0 D7 bne halfp ; and do the other half 003AD4 1 C6 8B ppfin: dec from+1 ; restore memory pointer MSB 003AD6 1 60 rts ; and return 003AD7 1 003AD7 1 ; *** Blow an NSC PROM Bit *** 003AD7 1 A9 80 PCORE: lda #$80 ; set up Ports for programming (all outputs) 003AD9 1 8D 83 19 sta actlrg 003ADC 1 8C 81 19 sty aportb ; set address - LSB 003ADF 1 8A txa ; and A8 003AE0 1 09 08 ora #$08 ; add control bits C3=1 (PROM CE inactive) 003AE2 1 8D 82 19 sta aportc 003AE5 1 B1 8A lda (from),y ; load data to blow 003AE7 1 24 82 bit hilow ; blowing upper or lower nibble ? (N=bit 7) 003AE9 1 10 04 bpl plow 003AEB 1 6A ror a ; shift upper nibble down 003AEC 1 6A ror a 003AED 1 6A ror a 003AEE 1 6A ror a 003AEF 1 25 91 plow: and mask ; mask off current bit 003AF1 1 F0 45 beq pcorex ; if zero nothing to program so return 003AF3 1 8D 80 19 sta aporta ; set bit to program 003AF6 1 A9 0D lda #$0D ; flip power on C6(PROM Power Control)=1 ON 003AF8 1 8D 83 19 sta actlrg 003AFB 1 EA nop ; delay for program pulse width 003AFC 1 EA nop 003AFD 1 EA nop 003AFE 1 EA nop 003AFF 1 EA nop 003B00 1 A9 06 lda #$06 ; flip enable on C3(PROM CE)=0 active 003B02 1 8D 83 19 sta actlrg 003B05 1 EA nop ; delay for program pulse width 003B06 1 EA nop 003B07 1 A9 07 lda #$07 ; enable off C3(PROM CE)=1 inactive 003B09 1 8D 83 19 sta actlrg 003B0C 1 A9 0C lda #$0C 003B0E 1 8D 83 19 sta actlrg ; power off C6 (PROM Power Control)=0 OFF 003B11 1 A9 90 lda #$90 ; set Port A to input to verify bit 003B13 1 8D 83 19 sta actlrg 003B16 1 8C 81 19 sty aportb ; set address again - LSB 003B19 1 8A txa ; and A8 003B1A 1 09 20 ora #$20 ; add control bits C5(PROM RW)=1 Read), C3(PROM CE)=0 active 003B1C 1 8D 82 19 sta aportc 003B1F 1 AD 80 19 lda aporta ; read data back from PROM 003B22 1 25 91 and mask ; is the bit programmed ? 003B24 1 D0 0E bne pblown ; yes - branch 003B26 1 C6 92 dec tries ; no - decrement tries 003B28 1 D0 AD bne PCORE ; try again ? 003B2A 1 98 tya ; no - failed 003B2B 1 48 pha 003B2C 1 20 B2 3C jsr OUTSTR ; print a '.' for each failed bit 003B2F 1 2E .byte "." 003B30 1 EA nop 003B31 1 68 pla 003B32 1 A8 tay 003B33 1 60 rts ; and give up 003B34 1 C6 93 pblown: dec extra ; extra blows for luck 003B36 1 D0 9F bne PCORE 003B38 1 60 pcorex: rts ; and return 003B39 1 003B39 1 ; **** Tesla Fusible Link PROM Routines **** 003B39 1 003B39 1 ; *** Tesla PROM BLANK **** 003B39 1 ; no entry parameters, returns Z=1 if blank 003B39 1 A0 00 TBLANK: ldy #$00 ; reset byte pointer 003B3B 1 84 9A sty fail+1 ; save address MSB for a fail 003B3D 1 A6 81 ldx size ; 256 or 512 bytes (0 or 1) 003B3F 1 A9 08 lda #$08 ; set Port C for lower half A8 low (C0=0), Vcc 5V (C1=0,C2=0), 003B41 1 ; OE active (C3=1), D0-3 inactive (C4-7=0) 003B41 1 8D 82 1A sta tportc 003B44 1 8C 81 1A tbpage: sty tportb ; set address LSB 003B47 1 84 99 sty fail ; save as fail address LSB in case not blank 003B49 1 AD 80 1A lda tporta ; read PROM data 003B4C 1 29 0F and #$0F ; mask lower nibble 003B4E 1 D0 14 bne tbfail ; blank (0) ? - branch if not 003B50 1 C8 iny ; next location 003B51 1 D0 F1 bne tbpage ; read all 256 bytes of page 003B53 1 A9 2A lda #'*' ; output a * for each page checked 003B55 1 20 F4 FF jsr OSWRCH 003B58 1 A9 01 lda #$01 ; set A8 high for upper half of PROM 003B5A 1 8D 83 1A sta tctlrg 003B5D 1 85 9A sta fail+1 ; and save as fail address MSB 003B5F 1 CA dex ; decrement page count (size) 003B60 1 F0 E2 beq tbpage ; do the other half if 512 byte PROM 003B62 1 A9 00 lda #$00 ; set Z 003B64 1 08 tbfail: php ; save status 003B65 1 003B65 1 A9 02 lda #$02 ; finished, switch off power - A8 low (C0=0), Vcc OFF,5V (C1=1,C2=0), 003B67 1 ; OE inactive (C3=0), D0-3 inactive (C4-7=0) 003B67 1 8D 82 1A sta tportc 003B6A 1 28 plp ; retrieve status 003B6B 1 60 rts ; and return (Z=1 if blank) 003B6C 1 003B6C 1 ; *** Tesla PROM Read *** 003B6C 1 ; no entry parameters, no return values 003B6C 1 A0 00 TREAD: ldy #$00 ; reset byte pointer 003B6E 1 A6 81 ldx size ; page count 256 or 512 bytes (0 or 1) 003B70 1 A9 08 lda #$08 ; set Port C for lower half A8 low (C0=0), Vcc 5V (C1=0,C2=0), 003B72 1 ; OE active (C3=1), D0-3 inactive (C4-7=0) 003B72 1 8D 82 1A trfull: sta tportc ; and write to Port C 003B75 1 8C 81 1A trpage: sty tportb ; set address LSB 003B78 1 B1 8A lda (from),y ; get current data from destination location 003B7A 1 24 82 bit hilow ; check for upper or lower nibble 003B7C 1 10 0E bpl trlow ; lower - branch 003B7E 1 29 0F and #$0F ; upper nibble - mask and save lower half 003B80 1 85 88 sta temp ; of current data 003B82 1 AD 80 1A lda tporta ; read byte from PROM 003B85 1 0A asl a ; shift to upper nibble 003B86 1 0A asl a 003B87 1 0A asl a 003B88 1 0A asl a 003B89 1 4C 95 3B jmp trcom ; and combine data 003B8C 1 29 F0 trlow: and #$F0 ; save upper nibble of current data 003B8E 1 85 88 sta temp 003B90 1 AD 80 1A lda tporta ; load byte from PROM 003B93 1 29 0F and #$0F ; mask off lower nibble 003B95 1 05 88 trcom: ora temp ; assemble new byte 003B97 1 91 8A sta (from),y ; and put it back 003B99 1 C8 iny ; increment byte pointer 003B9A 1 D0 D9 bne trpage ; read all 256 bytes of page 003B9C 1 A9 2A lda #'*' ; output a * for each page read 003B9E 1 20 F4 FF jsr OSWRCH 003BA1 1 E0 00 cpx #$00 ; if page count 256 bytes (0) 003BA3 1 F0 07 beq trfin ; then we are finished 003BA5 1 CA dex ; decrement page count 003BA6 1 E6 8B inc from+1 ; increment memory pointer for 2nd page 003BA8 1 A9 09 lda #$09 ; set Port C for A8 high (C0=1), Vcc 5V (C1=0,C2=0), 003BAA 1 ; OE active (C3=1), D0-3 inactive (C4-7=0) 003BAA 1 D0 C6 bne trfull ; and do the other half (branch always) 003BAC 1 A6 81 trfin: ldx size ; check PROM size 256 or 512 byte (0 or 1) 003BAE 1 F0 02 beq troff ; if 256 byte then we are finished 003BB0 1 C6 8B dec from+1 ; if 512 byte restore memory pointer MSB 003BB2 1 A9 02 troff: lda #$02 ; switch off power - A8 low (C0=0), Vcc OFF,5V (C1=1,C2=0), 003BB4 1 ; OE inactive (C3=0), D0-3 inactive (C4-7=0) 003BB4 1 8D 82 1A sta tportc ; write to Port C 003BB7 1 60 rts ; and return 003BB8 1 003BB8 1 ; *** Tesla PROM Verify *** 003BB8 1 ; no entry parameters, on exit Z=1 if verify OK 003BB8 1 A0 00 TVERFY: ldy #$00 ; reset byte pointer 003BBA 1 84 9A sty fail+1 ; save address MSB for a fail 003BBC 1 A6 81 ldx size ; 256 or 512 bytes (0 or 1) 003BBE 1 A5 8B lda from+1 ; save a copy of from address MSB for repeat 003BC0 1 85 88 sta temp 003BC2 1 A9 08 lda #$08 ; set Port C for lower half A8=0 (C0=0),Vcc 5V (C1=0,C2=0), 003BC4 1 ; OE active (C3=1) 003BC4 1 8D 82 1A tvfull: sta tportc 003BC7 1 8C 81 1A tvpage: sty tportb ; set address (A0 to A7) 003BCA 1 B1 8A lda (from),y ; get data from memory 003BCC 1 24 82 bit hilow ; check for upper or lower nibble 003BCE 1 10 04 bpl tvlow ; lower - branch 003BD0 1 4A lsr a ; upper - shift upper to lower 003BD1 1 4A lsr a 003BD2 1 4A lsr a 003BD3 1 4A lsr a 003BD4 1 4D 80 1A tvlow: eor tporta ; match against data in PROM 003BD7 1 29 0F and #$0F ; keep lower nibble, result should be 0 003BD9 1 D0 15 bne tvnok ; if not return with Z=0 003BDB 1 C8 tnoflg: iny ; increment byte pointer 003BDC 1 D0 E9 bne tvpage ; read all 256 bytes of page 003BDE 1 A9 2A lda #'*' ; output a * for each page verified 003BE0 1 20 F4 FF jsr OSWRCH 003BE3 1 CA dex ; decrement PROM size 003BE4 1 D0 08 bne tvok ; when not zero ($FF) finished 003BE6 1 E6 8B inc from+1 ; increment memory pointer MSB 003BE8 1 E6 9A inc fail+1 ; increment fail address MSB 003BEA 1 A9 09 lda #$09 ; set Port C for upper half A8 high (C0=1), Vcc 5V (C1=0,C2=0), 003BEC 1 ; OE active (C3=1), D0-3 inactive (C4-7=0) 003BEC 1 D0 D6 bne tvfull ; and do the upper half if 512 bytes 003BEE 1 A2 00 tvok: ldx #$00 ; finished - verified OK, set Z=1 003BF0 1 08 tvnok: php ; save status 003BF1 1 84 99 sty fail ; save fail address LSB 003BF3 1 A5 88 lda temp 003BF5 1 85 8B sta from+1 ; restore from address MSB 003BF7 1 A9 02 lda #$02 ; finished, switch off power - Vcc OFF,5V (C1=1,C2=0), 003BF9 1 ; OE inactive (C3=0), D0-3 inactive (C4-7=0) 003BF9 1 8D 82 1A sta tportc 003BFC 1 28 plp ; retrieve status 003BFD 1 60 rts ; and return (Z=1 if verified OK) 003BFE 1 003BFE 1 ; *** Tesla PROM Program *** 003BFE 1 A0 00 TPROG: ldy #$00 ; reset byte pointer (address LSByte) 003C00 1 A2 00 ldx #$00 ; set A8 low for first 256 bytes (address MSBit) 003C02 1 A9 08 halft: lda #$08 ; start on most significant bit 003C04 1 85 91 sta mask 003C06 1 20 24 3C t4bit: jsr TCORE ; go and blow a bit 003C09 1 46 91 lsr mask ; step to next bit in byte 003C0B 1 90 F9 bcc t4bit ; do all four bits 003C0D 1 C8 iny 003C0E 1 D0 F2 bne halft ; and for all 256 bytes 003C10 1 A9 2A lda #'*' ; output a * for each page programmed 003C12 1 20 F4 FF jsr OSWRCH 003C15 1 E0 01 cpx #$01 ; if A8 is high then we have completed 2nd page of 512 byte PROM 003C17 1 F0 08 beq tpfin ; so finished 003C19 1 A6 81 ldx size ; check PROM size 256 or 512 byte (0 or 1) 003C1B 1 F0 06 beq tpexit ; if 256 byte then we are finished 003C1D 1 E6 8B inc from+1 ; 512 byte so increment memory pointer MSB 003C1F 1 D0 E1 bne halft ; and do the other half (branch always) 003C21 1 C6 8B tpfin: dec from+1 ; restore memory pointer MSB 003C23 1 60 tpexit: rts ; and return 003C24 1 003C24 1 ; *** Blow a Tesla PROM Bit *** 003C24 1 B1 8A TCORE: lda (from),y ; load data to blow 003C26 1 24 82 bit hilow ; blowing upper or lower nibble ? (N=bit 7) 003C28 1 10 04 bpl tlow ; low nibble - branch 003C2A 1 6A ror a ; high nibble - shift to lower nibble 003C2B 1 6A ror a 003C2C 1 6A ror a 003C2D 1 6A ror a 003C2E 1 25 91 tlow: and mask ; mask off current bit 003C30 1 F0 6D beq tcorex ; if zero nothing to program, return 003C32 1 8A txa ; get A8 and add control bits 003C33 1 09 08 ora #$08 ; enable 5V Vcc and OE active - Vcc 5V (C1=0,C2=0), 003C35 1 ; OE active (C3=1), D0-3 inactive (C4-7=0) 003C35 1 8D 82 1A sta tportc ; and write to Port C 003C38 1 8C 81 1A sty tportb ; write address 003C3B 1 AD 80 1A lda tporta ; read current contents of PROM location 003C3E 1 25 91 and mask ; is it already programmed (1) ? 003C40 1 F0 06 beq tblow ; no - branch 003C42 1 A9 02 lda #$02 ; switch off - A8 low (C0=0), Vcc OFF,5V (C1=1,C2=0), 003C44 1 ; OE inactive (C3=0), D0-3 inactive (C4-7=0) 003C44 1 8D 82 1A sta tportc ; write to Port C 003C47 1 60 rts ; and return 003C48 1 A5 91 tblow: lda mask ; reload bit to program 003C4A 1 0A asl a ; shift to upper nibble for writing 003C4B 1 0A asl a 003C4C 1 0A asl a 003C4D 1 0A asl a ; this clears the lower nibble (control bits) 003C4E 1 ; i.e. A8 low, Vcc 5V (C1=0,C2=0), OE inactive (C3=0) 003C4E 1 E0 00 cpx #$00 ; low or high page ? 003C50 1 F0 02 beq A8low 003C52 1 09 01 ora #$01 ; high page - set A8 high 003C54 1 8D 82 1A A8low: sta tportc ; and write to Port C 003C57 1 48 pha ; save control bits on stack (A8) 003C58 1 A9 05 lda #$05 ; increase Vcc to 10.5V (C2=1) 003C5A 1 8D 83 1A sta tctlrg 003C5D 1 20 A0 3C jsr T60DEL ; settling delay 003C60 1 A9 07 lda #$07 ; take OE active (low) 003C62 1 8D 83 1A sta tctlrg 003C65 1 20 A6 3C jsr T10DEL ; 10mS delay 003C68 1 A9 06 lda #$06 ; take OE inactive (high) 003C6A 1 8D 83 1A sta tctlrg 003C6D 1 20 A0 3C jsr T60DEL ; settling delay 003C70 1 68 pla ; retrieve control bits 003C71 1 29 01 and #$01 ; reduce Vcc to 5V and remove data - Vcc 5V (C1=0,C2=0), 003C73 1 ; OE inactive (C3=0), D0-3 inactive (C4-7=0) 003C73 1 8D 82 1A sta tportc 003C76 1 20 A0 3C jsr T60DEL ; settling delay 003C79 1 A9 07 lda #$07 ; take OE active (C3=1) 003C7B 1 8D 83 1A sta tctlrg 003C7E 1 AD 80 1A lda tporta ; read data back from PROM 003C81 1 25 91 and mask ; is the bit programmed ? 003C83 1 D0 09 bne tblown ; yes - branch 003C85 1 98 tya 003C86 1 48 pha 003C87 1 20 B2 3C jsr OUTSTR ; no - print a '.' for each failed bit 003C8A 1 2E .byte "." 003C8B 1 EA nop 003C8C 1 68 pla 003C8D 1 A8 tay 003C8E 1 A9 02 tblown: lda #$02 ; switch off - A8 low (C0=0), Vcc OFF,5V (C1=1,C2=0), 003C90 1 ; OE inactive (C3=0), D0-3 inactive (C4-7=0) 003C90 1 8D 82 1A sta tportc 003C93 1 20 A6 3C jsr T10DEL ; 40mS cooling period 003C96 1 20 A6 3C jsr T10DEL 003C99 1 20 A6 3C jsr T10DEL 003C9C 1 20 A6 3C jsr T10DEL 003C9F 1 60 tcorex: rts ; and return 003CA0 1 003CA0 1 ; *** Settling Delay (~50uS) *** 003CA0 1 ; (the Tesla spec for settling time is 10 to 1000uS) 003CA0 1 A9 FF T60DEL: lda #$FF ; delay is approximatly 60uS 003CA2 1 0A t60: asl a 003CA3 1 B0 FD bcs t60 003CA5 1 60 rts ; and return 003CA6 1 003CA6 1 ; *** Tesla 10mS Delay *** 003CA6 1 A9 8F T10DEL: lda #$8F 003CA8 1 48 t10: pha 003CA9 1 20 A0 3C jsr T60DEL ; 60uS delay 003CAC 1 68 pla 003CAD 1 E9 00 sbc #$00 ; decrement accumulator (carry is clear) 003CAF 1 D0 F7 bne t10 003CB1 1 60 rts ; and return 003CB2 1 003CB2 1 ; ***** User Input / Output and Other Routines ***** 003CB2 1 003CB2 1 ; *** Output a String of Characters *** 003CB2 1 68 OUTSTR: pla ; retrieve return PC (-1) LSB 003CB3 1 85 88 sta temp 003CB5 1 68 pla 003CB6 1 85 89 sta temp+1 ; and MSB 003CB8 1 A0 00 outnxt: ldy #$00 ; Y=0 003CBA 1 A2 88 ldx #temp ; point x at pc 003CBC 1 20 61 3D jsr INCCMP ; increment pointer 003CBF 1 B1 88 lda (temp),y ; get character from string 003CC1 1 30 06 bmi eos ; end of string ? 003CC3 1 20 F4 FF jsr OSWRCH ; output character 003CC6 1 4C B8 3C jmp outnxt ; next character 003CC9 1 6C 88 00 eos: jmp (temp) ; continue execution after string 003CCC 1 003CCC 1 20 ED FF cancel: jsr OSCRLF 003CCF 1 ; *** Get Command From Buffer *** 003CCF 1 A9 3E COMIN: lda #'>' ; display prompt 003CD1 1 20 F4 FF jsr OSWRCH 003CD4 1 A2 FF buffin: ldx #$FF 003CD6 1 E8 nxtchr: inx ; increment buffer pointer 003CD7 1 E0 40 cpx #$40 ; buffer full ? (64 bytes) 003CD9 1 B0 0B bcs bufful 003CDB 1 20 E6 FF readch: jsr OSECHO ; read character from input channel and echo 003CDE 1 C9 18 cmp #CAN ; cancel ? 003CE0 1 F0 EA beq cancel ; yes - start again 003CE2 1 C9 7F cmp #DEL ; delete ? 003CE4 1 D0 05 bne nodel ; no - branch 003CE6 1 CA bufful: dex ; backup buffer pointer 003CE7 1 10 F2 bpl readch ; and read another character 003CE9 1 30 E9 bmi buffin ; start of line - start again 003CEB 1 9D 00 01 nodel: sta buffer,x ; put character in buffer 003CEE 1 C9 0D cmp #CR ; CR ? 003CF0 1 D0 E4 bne nxtchr ; no - read next character 003CF2 1 60 rts ; yes - return 003CF3 1 003CF3 1 ; *** Read Parameter from Input Buffer *** 003CF3 1 20 F9 3C PARAM: jsr HXPARA ; get hex parameter from input buffer 003CF6 1 F0 52 beq synerr ; if not hex - syntax error 003CF8 1 60 rts ; hex - return 003CF9 1 003CF9 1 ; *** Get (up to) 4-digit Hex Parameter and Store at X *** 003CF9 1 A9 00 HXPARA: lda #$00 ; set parameter to 0 003CFB 1 95 00 sta $00,x 003CFD 1 95 01 sta $01,x 003CFF 1 85 88 sta temp ; clear parameter found flag 003D01 1 20 25 3D jsr RDIBUF ; ignore leading spaces 003D04 1 B9 00 01 rdnxch: lda buffer,y ; read character from input buffer 003D07 1 20 2D 3D jsr HEXKEY ; is it hex ? 003D0A 1 B0 15 bcs delim ; branch if not hex (delimiter character ?) 003D0C 1 0A asl a ; shift up a digit 003D0D 1 0A asl a 003D0E 1 0A asl a 003D0F 1 0A asl a 003D10 1 84 88 sty temp ; temporarily save the input buffer pointer and set parameter flag 003D12 1 A0 04 ldy #$04 003D14 1 0A shfdig: asl a ; shift X, X+1 and A left one digit (4-bits) 003D15 1 36 00 rol $00,x 003D17 1 36 01 rol $01,x 003D19 1 88 dey 003D1A 1 D0 F8 bne shfdig 003D1C 1 A4 88 ldy temp ; retrieve the input buffer pointer 003D1E 1 C8 iny ; increment buffer pointer 003D1F 1 D0 E3 bne rdnxch ; always branch to read next character 003D21 1 A5 88 delim: lda temp ; sets Z if no parameter was found 003D23 1 60 rts ; and return 003D24 1 003D24 1 C8 space: iny 003D25 1 ; *** Read the Yth Character From the Input Buffer *** 003D25 1 B9 00 01 RDIBUF: lda buffer,y 003D28 1 C9 20 cmp #SPACE ; ignoring spaces 003D2A 1 F0 F8 beq space 003D2C 1 60 rts ; and return 003D2D 1 003D2D 1 ; *** Test Key Value In A For Hex *** 003D2D 1 C9 30 HEXKEY: cmp #'0' ; > '0' ? 003D2F 1 90 10 bcc nothex ; return invalid hex 003D31 1 C9 3A cmp #':' ; < '9' ? 003D33 1 90 08 bcc hex ; yes - valid hex 003D35 1 E9 07 sbc #$07 ; convert 'A' to 'F' 003D37 1 90 08 bcc nothex ; if < 'A' then not hex 003D39 1 C9 40 cmp #'@' ; > 'F' ? 003D3B 1 B0 03 bcs hexrtn ; return with C=1, invalid hex digit 003D3D 1 29 0F hex: and #$0F ; valid hex digit, convert to ASCII 003D3F 1 18 clc ; (unnecessarily set) C=0 003D40 1 60 hexrtn: rts ; and return, valid hex digit 003D41 1 38 nothex: sec ; C=1 003D42 1 60 rtn: rts ; and return, invalid hex digit 003D43 1 003D43 1 ; *** Test For End Of Input Buffer *** 003D43 1 20 25 3D ENDTST: jsr RDIBUF ; read character from input buffer 003D46 1 C9 0D cmp #CR ; CR ? 003D48 1 F0 F8 beq rtn ; yes - return, end found 003D4A 1 20 B2 3C synerr: jsr OUTSTR ; no - output 'Syntax Error ?' error 003D4D 1 53 79 6E 74 .byte "Syntax Error ?",CR,LF 003D51 1 61 78 20 45 003D55 1 72 72 6F 72 003D5D 1 EA nop 003D5E 1 4C 01 29 jmp RESTRT ; abort command 003D61 1 003D61 1 ; *** Increment the Word at X,X+1 and Compare with X+2,3 *** 003D61 1 F6 00 INCCMP: inc $00,x ; increment LSB 003D63 1 D0 02 bne do_cmp ; carry ? 003D65 1 F6 01 inc $01,x ; increment MSB 003D67 1 B5 00 do_cmp: lda $00,x ; compare LSB 003D69 1 D5 02 cmp $02,x 003D6B 1 D0 04 bne notequ ; if not equal return 003D6D 1 B5 01 lda $01,x ; otherwise compare MSB 003D6F 1 D5 03 cmp $03,x 003D71 1 60 notequ: rts ; and return 003D72 1 003D72 1 ; *** Output the Word at X+1, X *** 003D72 1 B5 01 OUTWRD: lda $01,x ; first byte 003D74 1 20 95 3D jsr OUTBYT ; output the second byte (at X+1) 003D77 1 E8 inx ; increment the pointer to the next word 003D78 1 E8 inx 003D79 1 B5 FE lda $FE,x ; output the first byte (now at X-2) 003D7B 1 20 95 3D jsr OUTBYT 003D7E 1 A9 20 outspc: lda #SPACE ; followed by a space 003D80 1 4C F4 FF jmp OSWRCH ; and return 003D83 1 003D83 1 ; Output CRC 003D83 1 20 B2 3C CRCOUT: jsr OUTSTR ; print out CRC header 003D86 1 0D 0A 43 52 .byte CR,LF,"CRC: " 003D8A 1 43 3A 20 003D8D 1 EA nop 003D8E 1 A5 91 lda crc+1 ; first byte 003D90 1 20 95 3D jsr OUTBYT 003D93 1 A5 90 lda crc ; and second byte 003D95 1 003D95 1 ; *** Output the Byte in A In Hex *** 003D95 1 48 OUTBYT: pha ; save A 003D96 1 4A lsr a ; start with the upper nibble 003D97 1 4A lsr a ; shift to the lower nibble position 003D98 1 4A lsr a 003D99 1 4A lsr a 003D9A 1 20 9E 3D jsr OUTDIG ; and output 003D9D 1 68 pla ; retrieve A and output the lower nibble 003D9E 1 003D9E 1 ; *** Output the Hex Digit in A *** 003D9E 1 29 0F OUTDIG: and #$0F ; mask off the upper nibble 003DA0 1 C9 0A cmp #$0A ; is it A-F ? 003DA2 1 90 02 bcc ascii ; no 003DA4 1 69 06 adc #$06 ; yes - add offset to 'A' 003DA6 1 69 30 ascii: adc #'0' ; convert to ASCII 003DA8 1 4C F4 FF jmp OSWRCH ; output character and return 003DAB 1 003DAB 1 ; *** Output "Continue ?" Message and Get Reply *** 003DAB 1 20 B2 3C CONTIN: jsr OUTSTR ; output message 003DAE 1 43 6F 6E 74 .byte "Continue ?" 003DB2 1 69 6E 75 65 003DB6 1 20 3F 003DB8 1 EA nop 003DB9 1 20 E6 FF jsr OSECHO ; get reply 003DBC 1 48 pha 003DBD 1 20 ED FF jsr OSCRLF 003DC0 1 68 pla 003DC1 1 C9 59 cmp #'Y' ; if yes Z=1 003DC3 1 60 rts ; return 003DC4 1 003DC4 1 ; *** Output "Repeat ?" Message and Get Reply *** 003DC4 1 20 B2 3C REPEAT: jsr OUTSTR ; output message 003DC7 1 52 65 70 65 .byte "Repeat ?" 003DCB 1 61 74 20 3F 003DCF 1 EA nop 003DD0 1 20 E6 FF jsr OSECHO ; get reply 003DD3 1 48 pha 003DD4 1 20 ED FF jsr OSCRLF 003DD7 1 68 pla 003DD8 1 C9 59 cmp #'Y' ; if yes Z=1 003DDA 1 60 rts ; return 003DDB 1 003DDB 1 ; *** Output "Programming:" Message *** 003DDB 1 20 B2 3C PRGMES: jsr OUTSTR 003DDE 1 50 72 6F 67 .byte "Programming: " 003DE2 1 72 61 6D 6D 003DE6 1 69 6E 67 3A 003DEB 1 EA nop 003DEC 1 60 rts ; and return 003DED 1 003DED 1 ; *** Check a Device Has Been Set *** 003DED 1 38 CHKDEV: sec ; set carry (device set) 003DEE 1 A6 87 ldx device ; device will be $FF if device set 003DF0 1 E8 inx 003DF1 1 D0 17 bne devset ; yes - return set 003DF3 1 20 B2 3C jsr OUTSTR ; no - output message 003DF6 1 44 65 76 69 .byte "Device Not Set ?",CR,LF 003DFA 1 63 65 20 4E 003DFE 1 6F 74 20 53 003E08 1 EA nop 003E09 1 18 clc ; clear carry - no device set 003E0A 1 60 devset: rts ; and return 003E0B 1 003E0B 1 ; *** Initialise Pointers *** 003E0B 1 A6 8A INIPTR: ldx from ; copy from address to point 003E0D 1 86 8E stx point 003E0F 1 A6 8B ldx from+1 003E11 1 86 8F stx point+1 003E13 1 A2 00 ldx #$00 003E15 1 86 95 stx page ; reset page count 003E17 1 86 90 stx crc ; clear checksum 003E19 1 86 91 stx crc+1 003E1B 1 60 rts ; and return 003E1C 1 003E1C 1 ; *** Calculate CRC *** 003E1C 1 A2 08 CRC: ldx #$08 003E1E 1 48 pha ; save A 003E1F 1 4A crclp: lsr A 003E20 1 26 90 rol crc 003E22 1 26 91 rol crc+1 003E24 1 90 08 bcc noc 003E26 1 48 pha 003E27 1 A5 90 lda crc 003E29 1 49 2D eor #$2D 003E2B 1 85 90 sta crc 003E2D 1 68 pla 003E2E 1 CA noc: dex 003E2F 1 D0 EE bne crclp 003E31 1 68 pla ; retrieve A 003E32 1 60 rts ; and return 003E33 1 003E33 1 ; *** Output Device Label *** 003E33 1 A6 87 OUTDEV: ldx device ; pointer to device label 003E35 1 BD 80 2C nxdvch: lda DEVTAB,x ; get device label character 003E38 1 C9 0D cmp #CR ; and check for end of device label 003E3A 1 F0 06 beq dvcrlf ; yes - done 003E3C 1 20 F4 FF jsr OSWRCH ; no - output character 003E3F 1 E8 inx ; increment device table pointer 003E40 1 D0 F3 bne nxdvch ; and always branch to get next character 003E42 1 20 ED FF dvcrlf: jsr OSCRLF 003E45 1 60 rts ; and return 003E46 1 003E46 1 ; *** Output Socket Message *** 003E46 1 20 ED 3D SOCKET: jsr CHKDEV ; check a device has been set ? 003E49 1 90 30 bcc srtn ; if carry clear no device set - return 003E4B 1 A6 80 ldx type ; get device type 003E4D 1 D0 2D bne neprom ; 0 - EPROM 003E4F 1 20 B2 3C jsr OUTSTR ; output message 003E52 1 55 73 65 20 .byte "Use Acorn PROM Programmer lower socket",CR,LF 003E56 1 41 63 6F 72 003E5A 1 6E 20 50 52 003E7A 1 EA nop 003E7B 1 60 srtn: rts ; and return 003E7C 1 CA neprom: dex 003E7D 1 D0 2D bne nnsc ; 1 - NSC PROM 003E7F 1 20 B2 3C jsr OUTSTR ; output message 003E82 1 55 73 65 20 .byte "Use Acorn PROM Programmer upper socket",CR,LF 003E86 1 41 63 6F 72 003E8A 1 6E 20 50 52 003EAA 1 EA nop 003EAB 1 60 rts ; and return 003EAC 1 20 B2 3C nnsc: jsr OUTSTR ; must be Tesla - output message 003EAF 1 55 73 65 20 .byte "Use Tesla PROM Programmer socket",CR,LF 003EB3 1 54 65 73 6C 003EB7 1 61 20 50 52 003ED1 1 EA nop 003ED2 1 60 rts ; and return 003ED3 1 003ED3 1 ; *** Copy BASE address to from *** 003ED3 1 A5 97 CPYBAS: lda base 003ED5 1 85 8A sta from 003ED7 1 A5 98 lda base+1 003ED9 1 85 8B sta from+1 003EDB 1 60 rts ; and return 003EDC 1 003EDC 1 ; ****** DEBUG CODE ****** 003EDC 1 .if DEBUG = 'Y' ; Breakpoint Handler for DEBUG 003EDC 1 003EDC 1 BRKPNT: cld ; Breakpoint Routine Entry 003EDC 1 sta brk_a ; save A, X and Y 003EDC 1 stx brk_x 003EDC 1 sty brk_y 003EDC 1 tsx ; retrieve stack pointer 003EDC 1 lda stack+2,x ; pc=pc-2 003EDC 1 sec ; i.e. address of BRK instruction 003EDC 1 sbc #$02 003EDC 1 tay 003EDC 1 sta brkpcl 003EDC 1 lda stack+3,x 003EDC 1 sbc #$00 003EDC 1 sta brkpch ; save pc 003EDC 1 lda stack+1,x ; get status register from stack 003EDC 1 sta brk_sr ; and save 003EDC 1 jsr OUTSTR ; output pc = program counter value 003EDC 1 .byte CR,LF,"BREAK at PC=" 003EDC 1 lda brkpch 003EDC 1 jsr OUTBYT 003EDC 1 lda brkpcl 003EDC 1 jsr OUTBYT 003EDC 1 jsr OUTSTR ; output CRLF A = accumulator value 003EDC 1 .byte " A=" 003EDC 1 lda brk_a 003EDC 1 jsr OUTBYT 003EDC 1 jsr OUTSTR ; output X = X register value 003EDC 1 .byte " X=" 003EDC 1 lda brk_x 003EDC 1 jsr OUTBYT 003EDC 1 jsr OUTSTR ; output Y = Y register value 003EDC 1 .byte " Y=" 003EDC 1 lda brk_y 003EDC 1 jsr OUTBYT 003EDC 1 jsr OUTSTR ; output PS = status register value 003EDC 1 .byte " PS=" 003EDC 1 lda brk_sr 003EDC 1 jsr OUTBYT 003EDC 1 jsr OSCRLF ; and a final CR LF 003EDC 1 jmp RESTRT ; re-enter command line interpreter 003EDC 1 .endif 003EDC 1