ca65 V2.17 - Git 582aa41 Main file : RAMTEST.ca65 Current file: RAMTEST.ca65 000000r 1 ; 000000r 1 ; ****** RAMTEST V1.0 ****** 000000r 1 ; 000000r 1 ; A suite of utilities for testing RAM 000000r 1 ; 000000r 1 ; Chris Oddy July 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 frombl := $80 ; start block of test range (1 byte, 0 to $3F) (if MSB is set no block/address has been defined) 000000r 1 tobl := $81 ; end block of test range (1 byte, 0 to $3F) 000000r 1 fromad := $82 ; start address of test range (2 bytes, multiple of 1024) 000000r 1 toad := $84 ; end address of test range (2 bytes, multiple of 1024) 000000r 1 seed := $86 ; seed for the random number generator (2 bytes, only 1 used) 000000r 1 temp := $88 ; temporary storage (1 byte) 000000r 1 random := $89 ; current random number generator value (1 byte) 000000r 1 cycle := $8A ; cycle on/off flag (1 byte, 0 = OFF, $FF = ON) 000000r 1 mesage := $8B ; messages on/off flag (1 byte, 0 = OFF, $FF = ON) 000000r 1 from := $8C ; from address (2 bytes) 000000r 1 to := $8E ; to address (2 bytes) 000000r 1 fill := $90 ; fill byte in FILL command (1 byte) 000000r 1 column := $91 ; column in DUMP command (1 byte) 000000r 1 mask := $92 ; test mask (1 byte) 000000r 1 faults := $93 ; faults counter (2 bytes) 000000r 1 cyccnt := $95 ; test cycle count (2 bytes) 000000r 1 pc := $97 ; return pc used by OUTSTR (2 bytes) 000000r 1 para := $99 ; parameter flag and pointer used by HXPARA (1 byte) 000000r 1 invert := $9A ; invert mask used by RANDOM (1 byte) 000000r 1 wrpatn := $9B ; pattern written during testing (1 byte) 000000r 1 rdpatn := $9C ; pattern read back during testing (1 byte) 000000r 1 buffer := $0100 ; command input buffer (64 bytes) 000000r 1 000000r 1 ; *** Debug Storage *** 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 000000r 1 BRKVEC := $0202 ; BRK vector 000000r 1 ; 000000r 1 ; Hardware Addresses 000000r 1 ; 000000r 1 keybrd := $0E21 ; keyboard 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 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 0A 3E START: jsr OUTSTR ; output start-up message 002803 1 0D 0A 2A 2A .byte CR,LF,"*** RAMTEST V1.0 ***",CR,LF,LF 002807 1 2A 20 52 41 00280B 1 4D 54 45 53 00281C 1 EA nop 00281D 1 A2 00 ldx #$00 00281F 1 86 8A stx cycle ; set Cycle OFF 002821 1 86 92 stx mask ; set default Mask 002823 1 CA dex ; X = $FF 002824 1 86 8B stx mesage ; set Messages ON 002826 1 86 80 stx frombl ; set no address/block defined 002828 1 002828 1 .if DEBUG = 'Y' ; BRK vector redirection required for DEBUG 002828 1 lda #BRKPNT 002828 1 sta BRKVEC+1 002828 1 .endif 002828 1 002828 1 20 27 3E RESTRT: jsr COMIN ; read command into buffer 00282B 1 20 31 28 jsr RAMCLI ; action command 00282E 1 4C 28 28 jmp RESTRT ; and do it again 002831 1 002831 1 A2 FF RAMCLI: ldx #$FF ; *** RAMTEST Command Line Interpreter *** 002833 1 D8 cld ; X is command table pointer 002834 1 A0 00 nxtcom: ldy #$00 ; Y is buffer pointer 002836 1 20 CF 3E jsr RDIBUF ; ignore leading spaces in buffer 002839 1 B9 00 01 lda buffer,y ; check for CR and no command 00283C 1 C9 0D cmp #CR 00283E 1 D0 01 bne nocr ; no - continue to extract command 002840 1 60 rts ; return 002841 1 88 nocr: dey ; backup buffer pointer 002842 1 C8 chkcom: iny ; increment buffer pointer 002843 1 E8 inx ; increment command table pointer 002844 1 BD 6E 28 rdcom: lda COMTAB,x ; read command table 002847 1 F0 17 beq addres ; end of string found (0) ? 002849 1 D9 00 01 cmp buffer,y ; compare with buffer 00284C 1 F0 F4 beq chkcom ; if equal compare whole string 00284E 1 E8 noteos: inx ; until a difference is found 00284F 1 BD 6E 28 lda COMTAB,x 002852 1 D0 FA bne noteos ; find end of string (00) 002854 1 E8 inx ; adjust command table pointer for next command string 002855 1 E8 inx ; i.e. point at 2nd byte of address 002856 1 B9 00 01 lda buffer,y 002859 1 C9 2E cmp #'.' ; was command abbreviated ? 00285B 1 D0 D7 bne nxtcom ; no - try next command from table 00285D 1 C8 iny ; increment buffer pointer past '.' 00285E 1 CA dex ; backup command table pointer to end of string (0) 00285F 1 CA dex 002860 1 E8 addres: inx ; increment pointer to command address 002861 1 BD 6E 28 lda COMTAB,x ; load MSB 002864 1 85 8D sta from+1 ; save 002866 1 BD 6F 28 lda COMTAB+1,x ; load LSB 002869 1 85 8C sta from ; save 00286B 1 6C 8C 00 jmp (from) ; and call command routine 00286E 1 00286E 1 ; Command Table 00286E 1 41 44 44 52 COMTAB: .byte "ADDRESS",$00,>ADDRES, 002872 1 45 53 53 00 002876 1 29 7E 002878 1 42 4C 4F 43 .byte "BLOCK",$00,>BLOCK, 00287C 1 4B 00 2A 29 002880 1 43 59 43 4C .byte "CYCLE",$00,>CYCLE, 002884 1 45 00 2A DD 002888 1 44 55 4D 50 .byte "DUMP",$00,>DUMP, 00288C 1 00 2B 11 00288F 1 46 49 4C 4C .byte "FILL",$00,>FILL, 002893 1 00 2B 5F 002896 1 48 45 4C 50 .byte "HELP",CR,$00,>HELP,HLPADR,HLPBLK,HLPCYC,HLPDMP,HLPFIL,HLPMSK,HLPMEM,HLPMES,HLPRND,HLPSED,HLPTST,MASK, 00293A 1 00 3A 10 00293D 1 4D 45 4D 00 .byte "MEM",$00,>MEM, 002941 1 3A 87 002943 1 4D 45 53 53 .byte "MESSAGES",$00,>MESAGE, 002947 1 41 47 45 53 00294B 1 00 3A D9 00294E 1 52 41 4E 44 .byte "RANDOM",CR,$00,>RANDOM,SEED, 00295C 1 00 3C 07 00295F 1 54 45 53 54 .byte "TEST",CR,$00,>TEST,OSCOM,COMMES, and address 00297E 1 ; the address will be truncated to a multiple of 1024 (a block) 00297E 1 20 CF 3E ADDRES: jsr RDIBUF ; if no parameter provided output current address range 002981 1 B9 00 01 lda buffer,y 002984 1 C9 0D cmp #CR 002986 1 D0 06 bne setadr ; yes - get parameters 002988 1 20 74 3D jsr CHKBLK ; no - has an address range been defined ? 00298B 1 10 6C bpl outad ; yes - output the range 00298D 1 60 rts ; no - return 00298E 1 A2 82 setadr: ldx #fromad ; point X at from address 002990 1 20 9D 3E jsr PARAM ; get address from input buffer 002993 1 A2 84 ldx #toad ; point X at to address 002995 1 20 9D 3E jsr PARAM ; get address from input buffer 002998 1 A0 00 ldy #$00 ; truncate Address's to multiple of 1K ($0400) 00299A 1 A5 83 lda fromad+1 ; zero the 2 LS bits of the MSB 00299C 1 29 FC and #$FC 00299E 1 85 83 sta fromad+1 0029A0 1 84 82 sty fromad ; and zero the LSB 0029A2 1 A2 84 ldx #toad ; repeat for to address 0029A4 1 20 20 3F jsr WRDINC ; but first add 1 0029A7 1 A5 85 lda toad+1 0029A9 1 29 FC and #$FC 0029AB 1 85 85 sta toad+1 0029AD 1 84 84 sty toad 0029AF 1 20 27 3F jsr WRDDEC ; and then subtract 1 0029B2 1 A5 82 lda fromad ; next check to address > from address 0029B4 1 C5 84 cmp toad ; compare LSB (result in C) 0029B6 1 A5 83 lda fromad+1 ; compare MSB 0029B8 1 E5 85 sbc toad+1 0029BA 1 90 31 bcc adok ; C = 0 if OK 0029BC 1 20 0A 3E jsr OUTSTR ; from is greater > to so output error message 0029BF 1 54 6F 20 61 .byte "To address must be greater than from !",CR,LF 0029C3 1 64 64 72 65 0029C7 1 73 73 20 6D 0029E7 1 EA nop 0029E8 1 A9 FF lda #$FF ; set no address/block range defined 0029EA 1 85 80 sta frombl 0029EC 1 60 rts ; and return 0029ED 1 A5 83 adok: lda fromad+1 ; convert Addresses to Blocks 0029EF 1 4A lsr ; by dividing the MSB address by 4 0029F0 1 4A lsr 0029F1 1 85 80 sta frombl ; and save 0029F3 1 A5 85 lda toad+1 ; repeat for the to address 0029F5 1 4A lsr 0029F6 1 4A lsr 0029F7 1 85 81 sta tobl 0029F9 1 20 0A 3E outad: jsr OUTSTR ; output address range 0029FC 1 41 64 64 72 .byte "Address range set to: " 002A00 1 65 73 73 20 002A04 1 72 61 6E 67 002A12 1 EA nop 002A13 1 A2 82 ldx #fromad 002A15 1 20 3B 3F jsr OUTWRD ; output from address 002A18 1 20 0A 3E jsr OUTSTR 002A1B 1 20 74 6F 20 .byte " to " 002A1F 1 EA nop 002A20 1 A2 84 ldx #toad 002A22 1 20 3B 3F jsr OUTWRD ; and to address 002A25 1 20 ED FF jsr OSCRLF 002A28 1 60 rts ; and return 002A29 1 002A29 1 ; *** BLOCK Command - define block(s) of RAM to test *** 002A29 1 ; takes two parameters: and block 002A29 1 20 CF 3E BLOCK: jsr RDIBUF ; if no parameter provided output current block range 002A2C 1 B9 00 01 lda buffer,y 002A2F 1 C9 0D cmp #CR 002A31 1 D0 06 bne setblk ; yes - get parameters 002A33 1 20 74 3D jsr CHKBLK ; no - has a block range been defined ? 002A36 1 10 71 bpl outbl ; yes - output the range 002A38 1 60 rts ; no - return 002A39 1 A2 80 setblk: ldx #frombl ; point X at from block 002A3B 1 20 A5 3D jsr GETBLK ; get block from input buffer 002A3E 1 B0 4E bcs blkrtn ; error - return 002A40 1 20 CF 3E jsr RDIBUF ; has a second parameter been provided ? 002A43 1 B9 00 01 lda buffer,y 002A46 1 C9 0D cmp #CR 002A48 1 D0 07 bne getto ; yes - get to parameter 002A4A 1 A5 80 lda frombl ; no - to = from 002A4C 1 85 81 sta tobl 002A4E 1 4C 8F 2A jmp blok 002A51 1 A2 81 getto: ldx #tobl ; point X at to block 002A53 1 20 A5 3D jsr GETBLK ; get block from input buffer 002A56 1 B0 36 bcs blkrtn ; error - return 002A58 1 A5 81 lda tobl ; check to block > from block 002A5A 1 C5 80 cmp frombl 002A5C 1 B0 31 bcs blok ; if to > from carry on 002A5E 1 F0 2F beq blok 002A60 1 20 0A 3E jsr OUTSTR ; from is greater > to so output error message 002A63 1 54 6F 20 62 .byte "To block must be greater than from !",CR,LF 002A67 1 6C 6F 63 6B 002A6B 1 20 6D 75 73 002A89 1 EA nop 002A8A 1 A9 FF lda #$FF ; set no address/block range defined 002A8C 1 85 80 sta frombl 002A8E 1 60 blkrtn: rts ; and return 002A8F 1 A2 00 blok: ldx #$00 ; convert blocks to addresses 002A91 1 A5 80 lda frombl ; by multiplying block by 4 002A93 1 0A asl 002A94 1 0A asl 002A95 1 85 83 sta fromad+1 002A97 1 86 82 stx fromad ; and zeroing the LSB 002A99 1 A5 81 lda tobl ; repeat for to block 002A9B 1 18 clc ; but first add 1 002A9C 1 69 01 adc #$01 002A9E 1 0A asl ; then multiply by 4 002A9F 1 0A asl 002AA0 1 38 sec 002AA1 1 E9 01 sbc #$01 ; and subtract 1 002AA3 1 85 85 sta toad+1 002AA5 1 CA dex ; x = $FF 002AA6 1 86 84 stx toad ; set the LSB to $FF 002AA8 1 60 rts 002AA9 1 20 0A 3E outbl: jsr OUTSTR ; output block range 002AAC 1 42 6C 6F 63 .byte "Block range set to: " 002AB0 1 6B 20 72 61 002AB4 1 6E 67 65 20 002AC0 1 EA nop 002AC1 1 A5 80 lda frombl 002AC3 1 20 4C 3F jsr OUTBYT ; output from block 002AC6 1 A5 80 lda frombl ; does block range cover more than one block ? 002AC8 1 C5 81 cmp tobl 002ACA 1 F0 0D beq onebl ; no - so don't output the second value 002ACC 1 20 0A 3E jsr OUTSTR ; yes - output the to block 002ACF 1 20 74 6F 20 .byte " to " 002AD3 1 EA nop 002AD4 1 A5 81 lda tobl 002AD6 1 20 4C 3F jsr OUTBYT ; and to block 002AD9 1 20 ED FF onebl: jsr OSCRLF 002ADC 1 60 rts ; and return 002ADD 1 002ADD 1 ; *** CYCLE Command - switch cycling on/off *** 002ADD 1 ; takes one parameter: 002ADD 1 20 CF 3E CYCLE: jsr RDIBUF ; ignore leading spaces 002AE0 1 B9 00 01 lda buffer,y ; is there a parameter ? 002AE3 1 C9 0D cmp #CR 002AE5 1 F0 08 beq cycmes ; no - output current CYCLE state 002AE7 1 20 4B 3E jsr ONOFF ; yes - get ON/OFF parameter 002AEA 1 30 24 bmi cycrtn ; if negative there was an error in the parameter 002AEC 1 85 8A sta cycle ; save result 002AEE 1 60 rts ; and return 002AEF 1 20 0A 3E cycmes: jsr OUTSTR ; output current CYCLE state 002AF2 1 43 59 43 4C .byte "CYCLE: " 002AF6 1 45 3A 20 002AF9 1 EA nop 002AFA 1 A5 8A lda cycle ; output current CYCLE state 002AFC 1 F0 09 beq cycoff ; if 0 CYCLE is OFF 002AFE 1 20 0A 3E jsr OUTSTR ; else CYCLE is ON 002B01 1 4F 4E 0D 0A .byte "ON",CR,LF 002B05 1 EA nop 002B06 1 60 rts ; and return 002B07 1 20 0A 3E cycoff: jsr OUTSTR ; output 'OFF' 002B0A 1 4F 46 46 0D .byte "OFF",CR,LF 002B0E 1 0A 002B0F 1 EA nop 002B10 1 60 cycrtn: rts ; and return 002B11 1 002B11 1 ; DUMP Command - Dump block of Memory 002B11 1 ; takes three parameters: and addresses and optional 002B11 1 A2 8C DUMP: ldx #from ; point X at address 002B13 1 20 9D 3E jsr PARAM ; get address from input buffer 002B16 1 A2 8E ldx #to ; point X at address 002B18 1 20 9D 3E jsr PARAM ; get address from input buffer 002B1B 1 E6 8E inc to ; add one to address 002B1D 1 D0 02 bne dnoinc 002B1F 1 E6 8F inc to+1 002B21 1 A2 91 dnoinc: ldx #column ; and optionally number of 002B23 1 20 A3 3E jsr HXPARA ; in output 002B26 1 D0 04 bne dodump ; use default number of columns ? 002B28 1 A9 08 lda #$08 ; yes = 8 002B2A 1 85 91 sta column 002B2C 1 20 ED 3E dodump: jsr ENDTST ; test for end of input buffer 002B2F 1 A5 91 nxtlin: lda column 002B31 1 85 88 sta temp 002B33 1 20 ED FF jsr OSCRLF ; output address 002B36 1 A2 8C ldx #from 002B38 1 20 3B 3F jsr OUTWRD 002B3B 1 A9 7C lda #'|' ; and a delimiter '|' 002B3D 1 20 F4 FF jsr OSWRCH 002B40 1 A0 00 ldy #$00 ; y = 0 002B42 1 A2 8C ldx #from ; point X at from address 002B44 1 A9 20 nxtcol: lda #SPACE 002B46 1 20 F4 FF jsr OSWRCH 002B49 1 B1 8C lda (from),y ; get a byte 002B4B 1 20 4C 3F jsr OUTBYT ; output 002B4E 1 20 0F 3F jsr INCCMP ; check if last one 002B51 1 F0 06 beq finish ; if so return 002B53 1 C6 88 dec temp ; otherwise check for end of line 002B55 1 D0 ED bne nxtcol ; if not output next byte 002B57 1 F0 D6 beq nxtlin ; last column - output next line 002B59 1 20 ED FF finish: jsr OSCRLF ; finished - output 2 CRLF's 002B5C 1 4C ED FF jmp OSCRLF ; and return 002B5F 1 002B5F 1 ; *** FILL Command - fill memory *** 002B5F 1 ; takes three parameters: and addresses and optional byte to with 002B5F 1 A2 8C FILL: ldx #from ; point X at address 002B61 1 20 9D 3E jsr PARAM ; get address from input buffer 002B64 1 A2 8E ldx #to ; point X at address 002B66 1 20 9D 3E jsr PARAM ; get address from input buffer 002B69 1 18 clc 002B6A 1 E6 8E inc to ; add one to address 002B6C 1 90 02 bcc fnoinc 002B6E 1 E6 8F inc to+1 002B70 1 A2 90 fnoinc: ldx #fill ; point X at temp for parameter 002B72 1 20 A3 3E jsr HXPARA ; get fill byte 002B75 1 D0 04 bne dofill ; specified ? 002B77 1 A9 FF lda #$FF ; no - use default value $FF 002B79 1 85 90 sta fill 002B7B 1 20 ED 3E dofill: jsr ENDTST ; test for end of input buffer 002B7E 1 A2 8C ldx #from 002B80 1 A0 00 ldy #$00 002B82 1 A5 90 nxtfil: lda fill ; byte to fill with 002B84 1 91 8C sta (from),y ; store the byte 002B86 1 20 0F 3F jsr INCCMP ; increment pointers and compare 002B89 1 D0 F7 bne nxtfil ; finished ? 002B8B 1 60 rts ; return 002B8C 1 002B8C 1 ; *** HELP Command - output help *** 002B8C 1 20 0A 3E HELP: jsr OUTSTR 002B8F 1 0D 0A 54 68 .byte CR,LF,"The following commands are available:",CR,LF,LF 002B93 1 65 20 66 6F 002B97 1 6C 6C 6F 77 002BB9 1 41 44 44 52 .byte "ADDRESS ",CR,LF 002BBD 1 45 53 53 20 002BC1 1 3C 66 72 6F 002BCE 1 42 4C 4F 43 .byte "BLOCK ()",CR,LF 002BD2 1 4B 20 3C 66 002BD6 1 72 6F 6D 3E 002BE3 1 43 59 43 4C .byte "CYCLE ()",CR,LF 002BE7 1 45 20 28 3C 002BEB 1 4F 4E 2F 4F 002BF5 1 44 55 4D 50 .byte "DUMP ()",CR,LF 002BF9 1 20 3C 66 72 002BFD 1 6F 6D 3E 20 002C13 1 46 49 4C 4C .byte "FILL ",CR,LF 002C17 1 20 3C 66 72 002C1B 1 6F 6D 3E 20 002C2C 1 4D 41 53 4B .byte "MASK ()",CR,LF 002C30 1 20 28 3C 6D 002C34 1 61 73 6B 3E 002C3B 1 4D 45 4D 20 .byte "MEM
",CR,LF 002C3F 1 3C 61 64 64 002C43 1 72 65 73 73 002C4A 1 4D 45 53 53 .byte "MESSAGES ()",CR,LF 002C4E 1 41 47 45 53 002C52 1 20 28 3C 4F 002C5F 1 52 41 4E 44 .byte "RANDOM",CR,LF 002C63 1 4F 4D 0D 0A 002C67 1 53 45 45 44 .byte "SEED ()",CR,LF 002C6B 1 20 28 3C 73 002C6F 1 65 65 64 3E 002C76 1 54 45 53 54 .byte "TEST",CR,LF 002C7A 1 0D 0A 002C7C 1 2A 20 3C 4F .byte "* ",CR,LF,LF 002C80 1 53 20 43 6F 002C84 1 6D 6D 61 6E 002C8D 1 54 79 70 65 .byte "Type HELP for help on a",CR,LF 002C91 1 20 48 45 4C 002C95 1 50 20 3C 63 002CB0 1 70 61 72 74 .byte "particular command.",CR,LF,LF 002CB4 1 69 63 75 6C 002CB8 1 61 72 20 63 002CC6 1 43 6F 6D 6D .byte "Commands can be abbreviated with '.'",CR,LF,LF 002CCA 1 61 6E 64 73 002CCE 1 20 63 61 6E 002CED 1 EA nop 002CEE 1 60 rts 002CEF 1 ; *** HELP ADDRESS Command - output help *** 002CEF 1 20 0A 3E HLPADR: jsr OUTSTR 002CF2 1 0D 0A 54 68 .byte CR,LF,"The ADDRESS command takes two parameters",CR,LF 002CF6 1 65 20 41 44 002CFA 1 44 52 45 53 002D1E 1 20 20 20 41 .byte " ADDRESS ",CR,LF,LF 002D22 1 44 44 52 45 002D26 1 53 53 20 3C 002D37 1 54 68 65 20 .byte "The parameters specify the area of RAM",CR,LF 002D3B 1 70 61 72 61 002D3F 1 6D 65 74 65 002D5F 1 74 6F 20 74 .byte "to test as absolute addresses in hex.",CR,LF,LF 002D63 1 65 73 74 20 002D67 1 61 73 20 61 002D87 1 49 66 20 6E .byte "If no parameters are given then the",CR,LF 002D8B 1 6F 20 70 61 002D8F 1 72 61 6D 65 002DAC 1 63 75 72 72 .byte "current Address & Block range are output",CR 002DB0 1 65 6E 74 20 002DB4 1 41 64 64 72 002DD5 1 28 69 66 20 .byte "(if previously defined).",CR,LF,LF 002DD9 1 70 72 65 76 002DDD 1 69 6F 75 73 002DF0 1 EA nop 002DF1 1 60 rts 002DF2 1 002DF2 1 ; *** HELP BLOCK Command - output help *** 002DF2 1 20 0A 3E HLPBLK: jsr OUTSTR 002DF5 1 0D 0A 54 68 .byte CR,LF,"The BLOCK command takes two parameters",CR,LF,LF 002DF9 1 65 20 42 4C 002DFD 1 4F 43 4B 20 002E20 1 20 20 20 42 .byte " BLOCK ()",CR,LF,LF 002E24 1 4C 4F 43 4B 002E28 1 20 3C 66 72 002E39 1 54 68 65 20 .byte "The parameters specify the area of RAM",CR,LF 002E3D 1 70 61 72 61 002E41 1 6D 65 74 65 002E61 1 74 6F 20 74 .byte "to test in hex 1K blocks (0 to $3F).",CR,LF,LF 002E65 1 65 73 74 20 002E69 1 69 6E 20 68 002E88 1 49 66 20 74 .byte "If the parameter is not specified",CR,LF 002E8C 1 68 65 20 3C 002E90 1 74 6F 3E 20 002EB0 1 74 68 65 6E .byte "then the block range is set to a single",CR,LF 002EB4 1 20 74 68 65 002EB8 1 20 62 6C 6F 002ED9 1 62 6C 6F 63 .byte "block.",CR,LF,LF 002EDD 1 6B 2E 0D 0A 002EE1 1 0A 002EE2 1 49 66 20 6E .byte "If no parameters are given then the",CR,LF 002EE6 1 6F 20 70 61 002EEA 1 72 61 6D 65 002F07 1 63 75 72 72 .byte "current Block & Address range are output",CR 002F0B 1 65 6E 74 20 002F0F 1 42 6C 6F 63 002F30 1 28 69 66 20 .byte "(if previously defined).",CR,LF,LF 002F34 1 70 72 65 76 002F38 1 69 6F 75 73 002F4B 1 EA nop 002F4C 1 60 rts 002F4D 1 002F4D 1 ; *** HELP CYCLE Command - output help *** 002F4D 1 20 0A 3E HLPCYC: jsr OUTSTR 002F50 1 0D 0A 54 68 .byte CR,LF,"The CYCLE command takes one parameter",CR,LF,LF 002F54 1 65 20 43 59 002F58 1 43 4C 45 20 002F7A 1 20 20 20 43 .byte " CYCLE ()",CR,LF,LF 002F7E 1 59 43 4C 45 002F82 1 20 28 3C 4F 002F90 1 54 68 65 20 .byte "The parameter sets the CYCLE state to",CR,LF 002F94 1 70 61 72 61 002F98 1 6D 65 74 65 002FB7 1 65 69 74 68 .byte "either ON or OFF.",CR,LF,LF 002FBB 1 65 72 20 4F 002FBF 1 4E 20 6F 72 002FCB 1 57 68 65 6E .byte "When ON, RAM testing will be repeated",CR,LF 002FCF 1 20 4F 4E 2C 002FD3 1 20 52 41 4D 002FF2 1 75 6E 74 69 .byte "until the space-bar is pressed.",CR,LF,LF 002FF6 1 6C 20 74 68 002FFA 1 65 20 73 70 003014 1 49 66 20 6E .byte "If no parameter is given then the",CR,LF 003018 1 6F 20 70 61 00301C 1 72 61 6D 65 003037 1 63 75 72 72 .byte "current CYCLE state is output.",CR,LF,LF 00303B 1 65 6E 74 20 00303F 1 43 59 43 4C 003058 1 54 68 65 20 .byte "The default value is OFF.",CR,LF,LF 00305C 1 64 65 66 61 003060 1 75 6C 74 20 003074 1 EA nop 003075 1 60 rts 003076 1 003076 1 ; *** HELP DUMP Command - output help *** 003076 1 20 0A 3E HLPDMP: jsr OUTSTR 003079 1 0D 0A 54 68 .byte CR,LF,"The DUMP command takes 3 parameters",CR,LF,LF 00307D 1 65 20 44 55 003081 1 4D 50 20 63 0030A1 1 20 20 20 44 .byte " DUMP ()",CR,LF,LF 0030A5 1 55 4D 50 20 0030A9 1 3C 66 72 6F 0030C3 1 54 68 65 20 .byte "The command dumps the specified memory",CR,LF 0030C7 1 63 6F 6D 6D 0030CB 1 61 6E 64 20 0030EB 1 72 61 6E 67 .byte "range to the screen with the address",CR,LF 0030EF 1 65 20 74 6F 0030F3 1 20 74 68 65 003111 1 66 6F 6C 6C .byte "followed by 8 bytes.",CR,LF,LF 003115 1 6F 77 65 64 003119 1 20 62 79 20 003128 1 54 68 65 20 .byte "The third optional parameter specifies",CR,LF 00312C 1 74 68 69 72 003130 1 64 20 6F 70 003150 1 61 20 64 69 .byte "a different number of bytes to display",CR,LF 003154 1 66 66 65 72 003158 1 65 6E 74 20 003178 1 6F 6E 20 61 .byte "on a line.",CR,LF,LF 00317C 1 20 6C 69 6E 003180 1 65 2E 0D 0A 003185 1 41 6C 6C 20 .byte "All values are in hex.",CR,LF,LF 003189 1 76 61 6C 75 00318D 1 65 73 20 61 00319E 1 EA nop 00319F 1 60 rts 0031A0 1 0031A0 1 ; *** HELP FILL Command - output help *** 0031A0 1 20 0A 3E HLPFIL: jsr OUTSTR 0031A3 1 0D 0A 54 68 .byte CR,LF,"The FILL command takes three parameters",CR,LF,LF 0031A7 1 65 20 46 49 0031AB 1 4C 4C 20 63 0031CF 1 20 20 20 46 .byte " FILL ",CR,LF,LF 0031D3 1 49 4C 4C 20 0031D7 1 3C 66 72 6F 0031EC 1 54 68 65 20 .byte "The command fills the specified memory",CR,LF 0031F0 1 63 6F 6D 6D 0031F4 1 61 6E 64 20 003214 1 72 61 6E 67 .byte "range with the value .",CR,LF,LF 003218 1 65 20 77 69 00321C 1 74 68 20 74 003233 1 41 6C 6C 20 .byte "All values are in hex.",CR,LF,LF 003237 1 76 61 6C 75 00323B 1 65 73 20 61 00324C 1 EA nop 00324D 1 60 rts 00324E 1 00324E 1 ; *** HELP MASK Command - output help *** 00324E 1 20 0A 3E HLPMSK: jsr OUTSTR 003251 1 0D 0A 54 68 .byte CR,LF,"The MASK command takes one parameter",CR,LF,LF 003255 1 65 20 4D 41 003259 1 53 4B 20 63 00327A 1 20 20 20 4D .byte " MASK ()",CR,LF,LF 00327E 1 41 53 4B 20 003282 1 28 3C 6D 61 00328D 1 54 68 65 20 .byte "The value of will be used by",CR,LF 003291 1 76 61 6C 75 003295 1 65 20 6F 66 0032B2 1 74 68 65 20 .byte "the TEST command to write to RAM.",CR,LF,LF 0032B6 1 54 45 53 54 0032BA 1 20 63 6F 6D 0032D6 1 49 66 20 6E .byte "If no parameter is given then the",CR,LF 0032DA 1 6F 20 70 61 0032DE 1 72 61 6D 65 0032F9 1 63 75 72 72 .byte "current value is output.",CR,LF,LF 0032FD 1 65 6E 74 20 003301 1 76 61 6C 75 003314 1 54 68 65 20 .byte "The default value is $00,",CR,LF 003318 1 64 65 66 61 00331C 1 75 6C 74 20 00332F 1 69 2E 65 2E .byte "i.e. TEST will write $00 and $FF to",CR,LF 003333 1 20 54 45 53 003337 1 54 20 77 69 003354 1 65 61 63 68 .byte "each location in turn.",CR,LF,LF 003358 1 20 6C 6F 63 00335C 1 61 74 69 6F 00336D 1 EA nop 00336E 1 60 rts 00336F 1 00336F 1 ; *** HELP MEM Command - output help *** 00336F 1 20 0A 3E HLPMEM: jsr OUTSTR 003372 1 0D 0A 54 68 .byte CR,LF,"The MEM command takes one parameter",CR,LF,LF 003376 1 65 20 4D 45 00337A 1 4D 20 63 6F 00339A 1 20 20 20 4D .byte " MEM ",CR,LF,LF 00339E 1 45 4D 20 3C 0033A2 1 66 72 6F 6D 0033AA 1 54 68 65 20 .byte "The command displays the address",CR,LF 0033AE 1 63 6F 6D 6D 0033B2 1 61 6E 64 20 0033D3 1 61 6E 64 20 .byte "and current contents of that address.",CR,LF,LF 0033D7 1 63 75 72 72 0033DB 1 65 6E 74 20 0033FB 1 50 72 65 73 .byte "Pressing the U key will move 'up' to",CR,LF 0033FF 1 73 69 6E 67 003403 1 20 74 68 65 003421 1 74 68 65 20 .byte "the next address, pressing V will move",CR,LF 003425 1 6E 65 78 74 003429 1 20 61 64 64 003449 1 27 64 6F 77 .byte "'down' to the previous address.",CR,LF,LF 00344D 1 6E 27 20 74 003451 1 6F 20 74 68 00346B 1 54 68 65 20 .byte "The contents can be changed by typing a hex value.",CR,LF,LF 00346F 1 63 6F 6E 74 003473 1 65 6E 74 73 0034A0 1 50 72 65 73 .byt "Pressing any other key will exit.",CR,LF,LF 0034A4 1 73 69 6E 67 0034A8 1 20 61 6E 79 0034C4 1 EA nop 0034C5 1 60 rts 0034C6 1 0034C6 1 ; *** HELP MESSAGES Command - output help *** 0034C6 1 20 0A 3E HLPMES: jsr OUTSTR 0034C9 1 0D 0A 54 68 .byte CR,LF,"The MESSAGES command takes one parameter",CR,LF,LF 0034CD 1 65 20 4D 45 0034D1 1 53 53 41 47 0034F6 1 20 20 20 4D .byte " MESSAGES ()",CR,LF,LF 0034FA 1 45 53 53 41 0034FE 1 47 45 53 20 00350F 1 54 68 65 20 .byte "The parameter sets the MESSAGES state",CR,LF 003513 1 70 61 72 61 003517 1 6D 65 74 65 003536 1 74 6F 20 65 .byte "to either ON or OFF.",CR,LF,LF 00353A 1 69 74 68 65 00353E 1 72 20 4F 4E 00354D 1 57 68 65 6E .byte "When ON, during RAM testing all",CR,LF 003551 1 20 4F 4E 2C 003555 1 20 64 75 72 00356E 1 6D 65 73 73 .byte "messages will be output, when OFF only",CR,LF 003572 1 61 67 65 73 003576 1 20 77 69 6C 003596 1 66 61 69 6C .byte "failure messages will be output.",CR,LF,LF 00359A 1 75 72 65 20 00359E 1 6D 65 73 73 0035B9 1 49 66 20 6E .byte "If no parameter is given then the",CR,LF 0035BD 1 6F 20 70 61 0035C1 1 72 61 6D 65 0035DC 1 63 75 72 72 .byte "current MESSAGES state is output.",CR,LF,LF 0035E0 1 65 6E 74 20 0035E4 1 4D 45 53 53 003600 1 54 68 65 20 .byte "The default value is OFF.",CR,LF,LF 003604 1 64 65 66 61 003608 1 75 6C 74 20 00361C 1 EA nop 00361D 1 60 rts 00361E 1 00361E 1 ; *** HELP RANDOM Command - output help *** 00361E 1 20 0A 3E HLPRND: jsr OUTSTR 003621 1 0D 0A 54 68 .byte CR,LF,"The RANDOM command takes no parameters",CR,LF,LF 003625 1 65 20 52 41 003629 1 4E 44 4F 4D 00364C 1 54 68 65 20 .byte "The command performs a RAM test using",CR,LF 003650 1 63 6F 6D 6D 003654 1 61 6E 64 20 003673 1 72 61 6E 64 .byte "random values.",CR,LF,LF 003677 1 6F 6D 20 76 00367B 1 61 6C 75 65 003684 1 41 20 73 65 .byte "A sequence of pseudo random values is",CR,LF 003688 1 71 75 65 6E 00368C 1 63 65 20 6F 0036AB 1 77 72 69 74 .byte "written to the Address/Block range.",CR,LF,LF 0036AF 1 74 65 6E 20 0036B3 1 74 6F 20 74 0036D1 1 54 68 65 20 .byte "The RAM is then read from the beginning",CR,LF 0036D5 1 52 41 4D 20 0036D9 1 69 73 20 74 0036FA 1 61 6E 64 20 .byte "and compared with the same pseudo",CR,LF 0036FE 1 63 6F 6D 70 003702 1 61 72 65 64 00371D 1 72 61 6E 64 .byte "random sequence.",CR,LF 003721 1 6F 6D 20 73 003725 1 65 71 75 65 00372F 1 49 66 20 61 .byte "If a difference is found then a fault",CR,LF 003733 1 20 64 69 66 003737 1 66 65 72 65 003756 1 68 61 73 20 .byte "has been detected.",CR,LF,LF 00375A 1 62 65 65 6E 00375E 1 20 64 65 74 00376B 1 54 68 65 20 .byte "The process is repeated with the same",CR,LF 00376F 1 70 72 6F 63 003773 1 65 73 73 20 003792 1 70 73 65 75 .byte "pseudo random sequence but inverted.",CR,LF,LF 003796 1 64 6F 20 72 00379A 1 61 6E 64 6F 0037B9 1 EA nop 0037BA 1 60 rts 0037BB 1 0037BB 1 ; *** HELP SEED Command - output help *** 0037BB 1 20 0A 3E HLPSED: jsr OUTSTR 0037BE 1 0D 0A 54 68 .byte CR,LF,"The SEED command takes one parameter",CR,LF,LF 0037C2 1 65 20 53 45 0037C6 1 45 44 20 63 0037E7 1 20 20 20 53 .byte " SEED ()",CR,LF,LF 0037EB 1 45 45 44 20 0037EF 1 28 3C 73 65 0037FA 1 3C 73 65 65 .byte " will be used to seed the pseudo",CR,LF 0037FE 1 64 3E 20 77 003802 1 69 6C 6C 20 003822 1 72 61 6E 64 .byte "random number generator used by the",CR,LF 003826 1 6F 6D 20 6E 00382A 1 75 6D 62 65 003847 1 52 41 4E 44 .byte "RANDOM command.",CR,LF,LF 00384B 1 4F 4D 20 63 00384F 1 6F 6D 6D 61 003859 1 49 66 20 6E .byte "If no parameter is given then the",CR,LF 00385D 1 6F 20 70 61 003861 1 72 61 6D 65 00387C 1 63 75 72 72 .byte "current value is output.",CR,LF,LF 003880 1 65 6E 74 20 003884 1 20 76 61 6C 003898 1 EA nop 003899 1 60 rts 00389A 1 00389A 1 ; *** HELP TEST Command - output help *** 00389A 1 20 0A 3E HLPTST: jsr OUTSTR 00389D 1 0D 0A 54 68 .byte CR,LF,"The TEST command takes no parameters",CR,LF,LF 0038A1 1 65 20 54 45 0038A5 1 53 54 20 63 0038C6 1 54 68 65 20 .byte "The command carries out a RAM test by",CR,LF 0038CA 1 63 6F 6D 6D 0038CE 1 61 6E 64 20 0038ED 1 77 72 69 74 .byte "writing the value of MASK to each RAM",CR,LF 0038F1 1 69 6E 67 20 0038F5 1 74 68 65 20 003914 1 6C 6F 63 61 .byte "location in turn and reading the value",CR,LF 003918 1 74 69 6F 6E 00391C 1 20 69 6E 20 00393C 1 62 61 63 6B .byte "back.",CR,LF 003940 1 2E 0D 0A 003943 1 54 68 65 20 .byte "The same location is then tested again",CR,LF 003947 1 73 61 6D 65 00394B 1 20 6C 6F 63 00396B 1 75 73 69 6E .byte "using the inverted value of MASK before",CR,LF 00396F 1 67 20 74 68 003973 1 65 20 69 6E 003994 1 6D 6F 76 69 .byte "moving on to the next location in the",CR,LF 003998 1 6E 67 20 6F 00399C 1 6E 20 74 6F 0039BB 1 41 64 64 72 .byte "Address/Block range.",CR,LF,LF 0039BF 1 65 73 73 2F 0039C3 1 42 6C 6F 63 0039D2 1 49 66 20 61 .byte "If a difference is found then a fault",CR,LF 0039D6 1 20 64 69 66 0039DA 1 66 65 72 65 0039F9 1 68 61 73 20 .byte "has been detected.",CR,LF,LF 0039FD 1 62 65 65 6E 003A01 1 20 64 65 74 003A0E 1 EA nop 003A0F 1 60 rts 003A10 1 003A10 1 ; *** MASK Command - set/display TEST mask *** 003A10 1 ; takes one parameters: , if no parameter entered then the current mask is output 003A10 1 20 CF 3E MASK: jsr RDIBUF ; read next character from input buffer ignoring leading spaces 003A13 1 C9 0D cmp #CR 003A15 1 D0 13 bne getmsk ; yes - get parameter 003A17 1 20 0A 3E jsr OUTSTR ; no - output current mask 003A1A 1 4D 61 73 6B .byte "Mask: " 003A1E 1 3A 20 003A20 1 EA nop 003A21 1 A5 92 lda mask ; load mask (byte) 003A23 1 20 4C 3F jsr OUTBYT ; output 003A26 1 20 ED FF jsr OSCRLF 003A29 1 60 rts ; and return 003A2A 1 A2 92 getmsk: ldx #mask ; point X at mask 003A2C 1 20 A3 3E jsr HXPARA ; get value 003A2F 1 D0 52 bne maskok ; yes 003A31 1 20 0A 3E jsr OUTSTR ; no - output error message 003A34 1 4D 75 73 74 .byte "Must be a hex value in the range 0 to $FF",CR,LF 003A38 1 20 62 65 20 003A3C 1 61 20 68 65 003A5F 1 EA nop 003A60 1 60 rts 003A61 1 20 0A 3E nomask: jsr OUTSTR ; output error message 003A64 1 4E 6F 20 76 .byte "No valid hex value entered ?",CR,LF 003A68 1 61 6C 69 64 003A6C 1 20 68 65 78 003A82 1 EA nop 003A83 1 20 ED 3E maskok: jsr ENDTST ; check for end of input buffer 003A86 1 60 rts ; and return 003A87 1 003A87 1 ; *** MEM Command - read/modify memory *** 003A87 1 ; takes one parameter: address 003A87 1 A2 8C MEM: ldx #from ; point X at address 003A89 1 20 9D 3E jsr PARAM ; get address from input buffer 003A8C 1 20 ED 3E jsr ENDTST ; test for end of input 003A8F 1 20 ED FF wraddr: jsr OSCRLF ; output CR LF 003A92 1 20 3B 3F jsr OUTWRD ; output address 003A95 1 CA dex ; backup X to point at from address 003A96 1 CA dex 003A97 1 A1 00 wrdata: lda ($00,x) ; read data from memory location 003A99 1 85 88 sta temp ; save it 003A9B 1 20 4C 3F jsr OUTBYT ; output byte 003A9E 1 20 E3 FF jsr OSRDCH ; read input channel 003AA1 1 A8 tay 003AA2 1 20 D7 3E jsr HEXKEY ; hex key pressed ? 003AA5 1 B0 15 bcs updown ; no - try up and down 003AA7 1 A0 04 ldy #$04 003AA9 1 06 88 shift: asl temp ; shift old byte one digit left 003AAB 1 88 dey 003AAC 1 D0 FB bne shift 003AAE 1 05 88 ora temp ; OR new digit in 003AB0 1 81 00 sta ($00,x) ; alter memory location contents 003AB2 1 A9 7F lda #DEL ; move cursor over old byte 003AB4 1 20 F4 FF jsr OSWRCH ; with two deletes 003AB7 1 20 F4 FF jsr OSWRCH 003ABA 1 D0 DB bne wrdata ; write out new data 003ABC 1 C0 55 updown: cpy #'U' ; up key 'U' pressed ? 003ABE 1 D0 08 bne down 003AC0 1 E6 8C inc from ; increment address 003AC2 1 D0 CB bne wraddr ; then rewrite it 003AC4 1 E6 8D inc from+1 003AC6 1 B0 C7 bcs wraddr 003AC8 1 C0 56 down: cpy #'V' ; down key 'V' pressed ? 003ACA 1 D0 0A bne crlf ; some other key ? - output CR LF and return 003ACC 1 A5 8C lda from ; decrement address 003ACE 1 D0 02 bne nodec 003AD0 1 C6 8D dec from+1 003AD2 1 C6 8C nodec: dec from 003AD4 1 B0 B9 bcs wraddr ; always branch to rewrite address 003AD6 1 4C ED FF crlf: jmp OSCRLF ; output CR LF and return 003AD9 1 003AD9 1 ; *** MESSAGES Command - set/unset messages *** 003AD9 1 ; takes one parameter: , if not specified current state is displayed 003AD9 1 ; if messages are ON then faults (if any) are output individually 003AD9 1 ; if messages are OFF then only a total number of faults (per cycle) are output 003AD9 1 20 CF 3E MESAGE: jsr RDIBUF ; ignore leading spaces 003ADC 1 B9 00 01 lda buffer,y ; is there a parameter ? 003ADF 1 C9 0D cmp #CR 003AE1 1 F0 08 beq outmes ; no - output current MESSAGES state 003AE3 1 20 4B 3E jsr ONOFF ; yes - get ON/OFF parameter 003AE6 1 30 27 bmi mesrtn ; if negative there was an error in the parameter 003AE8 1 85 8B sta mesage ; save result 003AEA 1 60 rts ; and return 003AEB 1 20 0A 3E outmes: jsr OUTSTR ; output current MESSAGES state 003AEE 1 4D 65 73 73 .byte "Messages: " 003AF2 1 61 67 65 73 003AF6 1 3A 20 003AF8 1 EA nop 003AF9 1 A5 8B lda mesage ; output current MESSAGES state 003AFB 1 F0 09 beq mesoff ; if 0 MESSAGES are OFF 003AFD 1 20 0A 3E jsr OUTSTR ; else MESSAGES are ON 003B00 1 4F 4E 0D 0A .byte "ON",CR,LF 003B04 1 EA nop 003B05 1 60 rts ; and return 003B06 1 20 0A 3E mesoff: jsr OUTSTR ; output 'OFF' 003B09 1 4F 46 46 0D .byte "OFF",CR,LF 003B0D 1 0A 003B0E 1 EA nop 003B0F 1 60 mesrtn: rts ; and return 003B10 1 003B10 1 ; *** RANDOM Command - test memory with random values *** 003B10 1 ; takes no parameters 003B10 1 A2 00 RANDOM: ldx #$00 ; set cycle counter to 1 003B12 1 86 96 stx cyccnt+1 003B14 1 E8 inx ; X = 1 003B15 1 86 95 stx cyccnt 003B17 1 A5 8A nxtrcy: lda cycle ; is cycling ON ? 003B19 1 F0 1C beq norcyc ; no - branch 003B1B 1 20 0A 3E jsr OUTSTR ; yes - output message 003B1E 1 0D 0A 54 65 .byte CR,LF,"Test Cycle: " 003B22 1 73 74 20 43 003B26 1 79 63 6C 65 003B2C 1 EA nop 003B2D 1 A2 95 ldx #cyccnt ; the cycle number 003B2F 1 20 3B 3F jsr OUTWRD 003B32 1 A2 95 ldx #cyccnt ; and increment cycle count for next time 003B34 1 20 0F 3F jsr INCCMP 003B37 1 20 0A 3E norcyc: jsr OUTSTR ; output pass number 003B3A 1 0D 0A 50 61 .byte CR,LF,"Pass 1: " 003B3E 1 73 73 20 31 003B42 1 3A 20 003B44 1 EA nop 003B45 1 84 9A sty invert ; set inverting off 003B47 1 20 6A 3B jsr RNDLOC ; test RAM 003B4A 1 20 0A 3E jsr OUTSTR ; output pass number 003B4D 1 0D 0A 50 61 .byte CR,LF,"Pass 2: " 003B51 1 73 73 20 32 003B55 1 3A 20 003B57 1 EA nop 003B58 1 A2 FF ldx #$FF ; set inverting on 003B5A 1 20 6A 3B jsr RNDLOC ; test RAM 003B5D 1 A5 8A lda cycle ; are we cycling ? 003B5F 1 F0 05 beq rndrtn ; no - finished 003B61 1 20 61 3D jsr CHKKBD ; yes - check if space-bar has been pressed ? 003B64 1 F0 B1 beq nxtrcy ; yes- continue cycling 003B66 1 20 ED FF rndrtn: jsr OSCRLF ; a final CRLF 003B69 1 60 rts ; no - return 003B6A 1 003B6A 1 ; *** Test Memory Range using Random Sequence *** 003B6A 1 20 DA 3D RNDLOC: jsr INIPTR ; reset pointers 003B6D 1 20 20 3F wrrnd: jsr WRDINC ; and increment from pointer 003B70 1 20 FA 3D jsr GETRND ; get next pseudo random sequence value 003B73 1 45 9A eor invert ; invert using invert mask 003B75 1 91 8C sta (from),y ; and write to RAM 003B77 1 20 30 3F jsr WRDCMP ; and compare from and to pointers 003B7A 1 D0 F1 bne wrrnd ; if not the end of the address range continue at next location 003B7C 1 20 DA 3D jsr INIPTR ; reset pointers 003B7F 1 A2 8C cmprnd: ldx #from ; point X at from pointer 003B81 1 20 20 3F jsr WRDINC ; increment from pointer 003B84 1 20 FA 3D jsr GETRND ; get next pseudo random sequence value 003B87 1 45 9A eor invert ; invert using invert mask 003B89 1 85 9B sta wrpatn ; write test pattern to RAM 003B8B 1 B1 8C lda (from),y ; and read back 003B8D 1 85 9C sta rdpatn ; save the result 003B8F 1 C5 9B cmp wrpatn ; and compare 003B91 1 F0 3E beq incptr ; if no fault found branch 003B93 1 A2 93 ldx #faults ; fault found - point X at the faults counter 003B95 1 20 20 3F jsr WRDINC ; and increment the count 003B98 1 A5 8B lda mesage ; are messages ON ? 003B9A 1 F0 35 beq incptr ; no - carry on testing at next location 003B9C 1 20 0A 3E jsr OUTSTR ; yes - output fault message 003B9F 1 0D 0A 46 61 .byte CR,LF,"Fault at: " 003BA3 1 75 6C 74 20 003BA7 1 61 74 3A 20 003BAB 1 EA nop 003BAC 1 A2 8C ldx #from ; point X at from pointer 003BAE 1 20 3B 3F jsr OUTWRD ; with the address 003BB1 1 20 0A 3E jsr OUTSTR ; yes - output fault message 003BB4 1 57 72 6F 74 .byte "Wrote: " 003BB8 1 65 3A 20 003BBB 1 EA nop 003BBC 1 A5 9B lda wrpatn ; retrieve written value 003BBE 1 20 4C 3F jsr OUTBYT ; and output 003BC1 1 20 0A 3E jsr OUTSTR ; and the read value 003BC4 1 20 52 65 61 .byte " Read: " 003BC8 1 64 3A 20 003BCB 1 EA nop 003BCC 1 A5 9C lda rdpatn ; retrieve read value 003BCE 1 20 4C 3F jsr OUTBYT ; and output 003BD1 1 A2 8C incptr: ldx #from ; point X at from pointer 003BD3 1 20 30 3F jsr WRDCMP ; compare from and to pointers 003BD6 1 D0 A7 bne cmprnd ; if not at end continue at next location 003BD8 1 A5 93 lda faults ; end of cycle were there faults ? 003BDA 1 D0 0D bne rfmess ; yes - output message 003BDC 1 A5 94 lda faults+1 003BDE 1 D0 09 bne rfmess ; yes - output message 003BE0 1 20 0A 3E jsr OUTSTR ; no - output OK message 003BE3 1 4F 4B .byte "OK" 003BE5 1 EA nop 003BE6 1 4C 06 3C jmp rcytst 003BE9 1 A5 8B rfmess: lda mesage ; output a CRLF if messages are ON 003BEB 1 F0 03 beq rncrlf 003BED 1 20 ED FF jsr OSCRLF 003BF0 1 20 0A 3E rncrlf: jsr OUTSTR ; output total faults message 003BF3 1 46 61 75 6C .byte "Faults found: " 003BF7 1 74 73 20 66 003BFB 1 6F 75 6E 64 003C01 1 A2 93 ldx #faults ; point X at faults count 003C03 1 20 3B 3F jsr OUTWRD ; and output 003C06 1 60 rcytst: rts ; else return 003C07 1 003C07 1 ; *** SEED Command - set/display random number generator seed *** 003C07 1 ; takes one parameters: , if no parameter entered then the current seed is output 003C07 1 20 CF 3E SEED: jsr RDIBUF ; read next character from input buffer ignoring leading spaces 003C0A 1 C9 0D cmp #CR 003C0C 1 D0 13 bne getsed ; yes - get parameter 003C0E 1 20 0A 3E jsr OUTSTR ; no - output current seed 003C11 1 53 65 65 64 .byte "Seed: " 003C15 1 3A 20 003C17 1 EA nop 003C18 1 A5 86 lda seed ; load seed (byte) 003C1A 1 20 4C 3F jsr OUTBYT ; output 003C1D 1 20 ED FF jsr OSCRLF 003C20 1 60 rts ; and return 003C21 1 A2 86 getsed: ldx #seed ; point X at seed 003C23 1 20 A3 3E jsr HXPARA ; get value 003C26 1 D0 52 bne seedok ; yes 003C28 1 20 0A 3E jsr OUTSTR ; no - output error message 003C2B 1 4D 75 73 74 .byte "Must be a hex value in the range 0 to $FF",CR,LF 003C2F 1 20 62 65 20 003C33 1 61 20 68 65 003C56 1 EA nop 003C57 1 60 rts 003C58 1 20 0A 3E noseed: jsr OUTSTR ; output error message 003C5B 1 4E 6F 20 76 .byte "No valid hex value entered ?",CR,LF 003C5F 1 61 6C 69 64 003C63 1 20 68 65 78 003C79 1 EA nop 003C7A 1 20 ED 3E seedok: jsr ENDTST ; check for end of input buffer 003C7D 1 60 rts ; and return 003C7E 1 003C7E 1 ; *** TEST Command - Basic RAM Test *** 003C7E 1 ; tests each location in turn with test mask and test mask inverted 003C7E 1 A2 00 TEST: ldx #$00 ; set cycle counter to 1 003C80 1 86 96 stx cyccnt+1 003C82 1 E8 inx 003C83 1 86 95 stx cyccnt 003C85 1 A5 8A nxttcy: lda cycle ; is cycling ON ? 003C87 1 F0 1A beq notcyc 003C89 1 20 0A 3E jsr OUTSTR ; yes - output message 003C8C 1 54 65 73 74 .byte "Test Cycle: " 003C90 1 20 43 79 63 003C94 1 6C 65 3A 20 003C98 1 EA nop 003C99 1 A2 95 ldx #cyccnt ; the cycle number 003C9B 1 20 3B 3F jsr OUTWRD 003C9E 1 A2 95 ldx #cyccnt ; and increment cycle count for next time 003CA0 1 20 0F 3F jsr INCCMP 003CA3 1 20 DA 3D notcyc: jsr INIPTR ; reset pointers 003CA6 1 A2 8C nxtloc: ldx #from ; point X at from pointer 003CA8 1 20 20 3F jsr WRDINC ; and increment 003CAB 1 A5 92 lda mask ; get test mask 003CAD 1 20 FB 3C jsr TSTLOC ; test RAM location 003CB0 1 D0 07 bne fault ; if fault skip second test 003CB2 1 A5 92 lda mask ; no fault so 003CB4 1 49 FF eor #$FF ; invert mask 003CB6 1 20 FB 3C jsr TSTLOC ; and test again 003CB9 1 A2 8C fault: ldx #from ; point X at from pointer 003CBB 1 20 30 3F jsr WRDCMP ; compare with to, have we reached the end ? 003CBE 1 D0 E6 bne nxtloc ; no - round to next location 003CC0 1 A5 93 lda faults ; yes - if there were faults output the total 003CC2 1 D0 0D bne tfmess 003CC4 1 A5 94 lda faults+1 003CC6 1 D0 09 bne tfmess 003CC8 1 20 0A 3E jsr OUTSTR ; else output OK message 003CCB 1 4F 4B .byte "OK" 003CCD 1 EA nop 003CCE 1 4C EE 3C jmp tcytst 003CD1 1 A5 8B tfmess: lda mesage ; output a CRLF if messages are ON 003CD3 1 F0 03 beq tncrlf 003CD5 1 20 ED FF jsr OSCRLF 003CD8 1 20 0A 3E tncrlf: jsr OUTSTR ; output total faults message 003CDB 1 46 61 75 6C .byte "Faults found: " 003CDF 1 74 73 20 66 003CE3 1 6F 75 6E 64 003CE9 1 A2 93 ldx #faults ; point X at faults count 003CEB 1 20 3B 3F jsr OUTWRD ; and output 003CEE 1 20 ED FF tcytst: jsr OSCRLF ; add a final CRLF 003CF1 1 A5 8A lda cycle ; are we cycling ? 003CF3 1 F0 05 beq tstend ; no - finish 003CF5 1 20 61 3D jsr CHKKBD ; yes - check if space-bar has been pressed ? 003CF8 1 F0 8B beq nxttcy ; no - continue cycling 003CFA 1 60 tstend: rts ; yes - return 003CFB 1 003CFB 1 ; *** Test Memory Location with Test Pattern in A *** 003CFB 1 85 9B TSTLOC: sta wrpatn ; save test pattern 003CFD 1 91 8C sta (from),y ; write test pattern to RAM 003CFF 1 B1 8C lda (from),y ; and read back 003D01 1 85 9C sta rdpatn ; save the result 003D03 1 C5 9B cmp wrpatn ; and compare 003D05 1 08 php ; save result for return 003D06 1 F0 3E beq tstrtn ; a match - so no fault, carry on testing 003D08 1 A2 93 ldx #faults ; doesn't match - point X at the faults counter 003D0A 1 20 20 3F jsr WRDINC ; and increment 003D0D 1 A5 8B lda mesage ; are messages on ? 003D0F 1 F0 35 beq tstrtn ; no - carry on testing 003D11 1 20 0A 3E jsr OUTSTR ; yes - output fault message 003D14 1 0D 0A 46 61 .byte CR,LF,"Fault at: " 003D18 1 75 6C 74 20 003D1C 1 61 74 3A 20 003D20 1 EA nop 003D21 1 A2 8C ldx #from ; point X at from pointer 003D23 1 20 3B 3F jsr OUTWRD ; with the address 003D26 1 20 0A 3E jsr OUTSTR ; yes - output fault message 003D29 1 57 72 6F 74 .byte "Wrote: " 003D2D 1 65 3A 20 003D30 1 EA nop 003D31 1 A5 9B lda wrpatn ; retrieve written pattern 003D33 1 20 4C 3F jsr OUTBYT ; and output 003D36 1 20 0A 3E jsr OUTSTR ; and the read value 003D39 1 20 52 65 61 .byte " Read: " 003D3D 1 64 3A 20 003D40 1 EA nop 003D41 1 A5 9C lda rdpatn ; retrieve read value 003D43 1 20 4C 3F jsr OUTBYT ; and output 003D46 1 28 tstrtn: plp ; retrieve test result 003D47 1 60 rts ; and return 003D48 1 003D48 1 ; *** OS Command *** 003D48 1 A0 00 OSCOM: ldy #$00 ; move command in buffer down one to overwrite '*' 003D4A 1 B9 01 01 movcom: lda buffer+1,y ; get command from input buffer 003D4D 1 99 00 01 sta buffer,y ; put back in input buffer 003D50 1 C9 0D cmp #CR ; until CR found 003D52 1 F0 0A beq calcom ; finished 003D54 1 C8 iny ; else increment pointer 003D55 1 C0 3F cpy #$3F ; check for end of buffer (64 characters) 003D57 1 D0 F1 bne movcom ; and move rest of command 003D59 1 A9 0D lda #CR ; end of buffer reached 003D5B 1 99 00 01 sta buffer,y ; put a CR at end of buffer and 003D5E 1 4C F7 FF calcom: jmp OSCLI ; pass to OS and return 003D61 1 003D61 1 ; ****** ROUTINES USED BY COMMANDS ***** 003D61 1 003D61 1 003D61 1 ; *** Check to see if the Space-bar has been Pressed *** 003D61 1 A2 00 CHKKBD: ldx #$00 003D63 1 AD 21 0E kscan: lda keybrd ; read keyboard 003D66 1 C9 20 cmp #SPACE ; has space-bar been pressed ? 003D68 1 F0 04 beq kwait ; yes - branch 003D6A 1 CA dex ; no - but check 256 times to ensure capture 003D6B 1 D0 F6 bne kscan 003D6D 1 60 rts ; return with Z = 1 (no key-pressed) 003D6E 1 AD 21 0E kwait: lda keybrd ; yes 003D71 1 10 FB bpl kwait ; wait for the key to be released 003D73 1 60 rts ; and return with Z = 0 (key-pressed) 003D74 1 003D74 1 ; *** Check Block of RAM has been Defined *** 003D74 1 A5 80 CHKBLK: lda frombl ; read from block 003D76 1 10 2C bpl chkrtn ; if negative not defined 003D78 1 20 0A 3E jsr OUTSTR ; output message 003D7B 1 4E 6F 20 42 .byte "No Block or Address has been defined ?",CR,LF 003D7F 1 6C 6F 63 6B 003D83 1 20 6F 72 20 003DA3 1 EA nop 003DA4 1 60 chkrtn: rts ; and return 003DA5 1 003DA5 1 ; *** Get Block Value from Input Buffer *** 003DA5 1 20 A3 3E GETBLK: jsr HXPARA ; get 2-digit hex parameter from input buffer 003DA8 1 B5 00 lda $00,X ; get value entered 003DAA 1 C9 40 cmp #$40 ; and check less than $40 003DAC 1 90 2B bcc getrtn ; yes - return 003DAE 1 20 0A 3E jsr OUTSTR ; no - output error message 003DB1 1 42 6C 6F 63 .byte "Block value must be between 0 and $3F",CR,LF 003DB5 1 6B 20 76 61 003DB9 1 6C 75 65 20 003DD8 1 EA nop 003DD9 1 60 getrtn: rts ; and return 003DDA 1 003DDA 1 ; *** Initialise Memory Pointers *** 003DDA 1 A0 00 INIPTR: ldy #$00 003DDC 1 84 93 sty faults ; reset faults counter 003DDE 1 84 94 sty faults+1 003DE0 1 A5 82 lda fromad ; copy from address to from pointer 003DE2 1 85 8C sta from 003DE4 1 A5 83 lda fromad+1 003DE6 1 85 8D sta from+1 003DE8 1 A5 84 lda toad ; copy to address to to pointer 003DEA 1 85 8E sta to 003DEC 1 A5 85 lda toad+1 003DEE 1 85 8F sta to+1 003DF0 1 A2 8C ldx #from 003DF2 1 20 27 3F jsr WRDDEC ; backup from pointer by 1 003DF5 1 A5 86 lda seed ; initialise the random number generator 003DF7 1 85 89 sta random 003DF9 1 60 rts 003DFA 1 003DFA 1 ; *** Get a Random Number *** 003DFA 1 ; generates a 255 8-bit sequence 003DFA 1 A5 89 GETRND: lda random ; load current value 003DFC 1 F0 05 beq doeor 003DFE 1 0A asl 003DFF 1 F0 04 beq noeor 003E01 1 90 02 bcc noeor 003E03 1 49 1D doeor: eor #$1D 003E05 1 85 89 noeor: sta random ; update value 003E07 1 F0 F1 beq GETRND ; if result is zero skip (makes a 255 sequence) 003E09 1 60 rts ; and return 003E0A 1 003E0A 1 ; *** Output a String of Characters *** 003E0A 1 68 OUTSTR: pla ; retrieve return PC (-1) LSB 003E0B 1 85 97 sta pc 003E0D 1 68 pla 003E0E 1 85 98 sta pc+1 ; and MSB 003E10 1 A0 00 outnxt: ldy #$00 ; Y = 0 003E12 1 A2 97 ldx #pc ; point x at pc 003E14 1 20 0F 3F jsr INCCMP ; increment pointer 003E17 1 B1 97 lda (pc),y ; get character from string 003E19 1 30 06 bmi eos ; end of string ? 003E1B 1 20 F4 FF jsr OSWRCH ; output character 003E1E 1 4C 10 3E jmp outnxt ; next character 003E21 1 6C 97 00 eos: jmp (pc) ; continue execution after string 003E24 1 003E24 1 003E24 1 20 ED FF cancel: jsr OSCRLF 003E27 1 ; *** Get Command From Buffer *** 003E27 1 A9 3E COMIN: lda #'>' ; display prompt 003E29 1 20 F4 FF jsr OSWRCH 003E2C 1 A2 FF buffin: ldx #$FF 003E2E 1 E8 nxtchr: inx ; increment buffer pointer 003E2F 1 E0 40 cpx #$40 ; buffer full ? (64 bytes) 003E31 1 B0 0B bcs bufful 003E33 1 20 E6 FF readch: jsr OSECHO ; read character from input channel and echo 003E36 1 C9 18 cmp #CAN ; cancel ? 003E38 1 F0 EA beq cancel ; yes - start again 003E3A 1 C9 7F cmp #DEL ; delete ? 003E3C 1 D0 05 bne nodel ; no - branch 003E3E 1 CA bufful: dex ; backup buffer pointer 003E3F 1 10 F2 bpl readch ; and read another character 003E41 1 30 E9 bmi buffin ; start of line - start again 003E43 1 9D 00 01 nodel: sta buffer,x ; put character in buffer 003E46 1 C9 0D cmp #CR ; CR ? 003E48 1 D0 E4 bne nxtchr ; no - read next character 003E4A 1 60 rts ; yes - return 003E4B 1 003E4B 1 ; *** Read ON/OFF Parameter from Input Buffer *** 003E4B 1 20 CF 3E ONOFF: jsr RDIBUF ; ignore leading spaces 003E4E 1 B9 00 01 lda buffer,y ; get next character from buffer 003E51 1 C9 0D cmp #CR ; is there a parameter ? 003E53 1 F0 26 beq ooerr ; no - return error 003E55 1 C9 4F cmp #'O' ; yes - is it an 'O' ? 003E57 1 D0 22 bne ooerr ; no - return error 003E59 1 C8 iny ; yes - increment buffer pointer 003E5A 1 B9 00 01 lda buffer,y ; and get next character from buffer 003E5D 1 C9 4E cmp #'N' ; is it an 'N' ? 003E5F 1 D0 0B bne cmpf ; no - try 'F' 003E61 1 C8 iny ; yes - check for terminating CR 003E62 1 B9 00 01 lda buffer,y ; increment buffer pointer and get next character from buffer 003E65 1 C9 0D cmp #CR 003E67 1 D0 12 bne ooerr ; no - return error 003E69 1 A9 01 lda #$01 ; yes - 'ON' 003E6B 1 60 rts ; return with A = 1 003E6C 1 C9 46 cmpf: cmp #'F' ; test for first F 003E6E 1 D0 0B bne ooerr ; no - return error 003E70 1 C8 iny ; yes - increment buffer pointer 003E71 1 B9 00 01 lda buffer,y ; and get next character from buffer 003E74 1 C9 46 cmp #'F' ; test for second F 003E76 1 D0 03 bne ooerr ; no - return error 003E78 1 A9 00 lda #$00 ; yes - 'OFF' 003E7A 1 60 rts ; return with A = 0 003E7B 1 20 0A 3E ooerr: jsr OUTSTR ; output error message 003E7E 1 4F 6E 6C 79 .byte "Only ON or OFF is valid ?",CR,LF 003E82 1 20 4F 4E 20 003E86 1 6F 72 20 4F 003E99 1 EA nop 003E9A 1 A9 FF lda #$FF ; return with A = $FF 003E9C 1 60 rts 003E9D 1 003E9D 1 ; *** Read Parameter from Input Buffer *** 003E9D 1 20 A3 3E PARAM: jsr HXPARA ; get hex parameter from input buffer 003EA0 1 F0 52 beq synerr ; if not hex - syntax error 003EA2 1 60 rts ; hex - return 003EA3 1 003EA3 1 ; *** Get (up to) 4-digit Hex Parameter from Input Buffer and Store at X *** 003EA3 1 A9 00 HXPARA: lda #$00 ; set parameter to 0 003EA5 1 95 00 sta $00,x 003EA7 1 95 01 sta $01,x 003EA9 1 85 99 sta para ; clear parameter found flag 003EAB 1 20 CF 3E jsr RDIBUF ; ignore leading spaces 003EAE 1 B9 00 01 rdnxch: lda buffer,y ; read character from input buffer 003EB1 1 20 D7 3E jsr HEXKEY ; is it hex ? 003EB4 1 B0 15 bcs delim ; branch if not hex (delimiter character ?) 003EB6 1 0A asl a ; shift up a digit 003EB7 1 0A asl a 003EB8 1 0A asl a 003EB9 1 0A asl a 003EBA 1 84 99 sty para ; temporarily save the input buffer pointer and set parameter flag 003EBC 1 A0 04 ldy #$04 003EBE 1 0A shfdig: asl a ; shift X, X+1 and A left one digit (4-bits) 003EBF 1 36 00 rol $00,x 003EC1 1 36 01 rol $01,x 003EC3 1 88 dey 003EC4 1 D0 F8 bne shfdig 003EC6 1 A4 99 ldy para ; retrieve the input buffer pointer 003EC8 1 C8 iny ; increment buffer pointer 003EC9 1 D0 E3 bne rdnxch ; always branch to read next character 003ECB 1 A5 99 delim: lda para ; sets Z if no parameter was found 003ECD 1 60 rts ; and return 003ECE 1 003ECE 1 C8 space: iny 003ECF 1 ; *** Read the Yth Character From the Input Buffer *** 003ECF 1 B9 00 01 RDIBUF: lda buffer,y 003ED2 1 C9 20 cmp #SPACE ; ignoring spaces 003ED4 1 F0 F8 beq space 003ED6 1 60 rts ; and return 003ED7 1 003ED7 1 ; *** Test Key Value In A For Hex *** 003ED7 1 C9 30 HEXKEY: cmp #'0' ; > '0' ? 003ED9 1 90 10 bcc nothex ; return invalid hex 003EDB 1 C9 3A cmp #':' ; < '9' ? 003EDD 1 90 08 bcc hex ; yes - valid hex 003EDF 1 E9 07 sbc #$07 ; convert 'A' to 'F' 003EE1 1 90 08 bcc nothex ; if < 'A' then not hex 003EE3 1 C9 40 cmp #'@' ; > 'F' ? 003EE5 1 B0 03 bcs hexrtn ; return with C = 1, invalid hex digit 003EE7 1 29 0F hex: and #$0F ; valid hex digit, convert to ASCII 003EE9 1 18 clc ; (unnecessarily set) C = 0 003EEA 1 60 hexrtn: rts ; and return, valid hex digit 003EEB 1 38 nothex: sec ; C = 1 003EEC 1 60 rtn: rts ; and return, invalid hex digit 003EED 1 003EED 1 ; *** Test For End Of Input Buffer *** 003EED 1 20 CF 3E ENDTST: jsr RDIBUF ; read character from input buffer 003EF0 1 C9 0D cmp #CR ; CR ? 003EF2 1 F0 F8 beq rtn ; yes - return, end found 003EF4 1 20 0A 3E synerr: jsr OUTSTR ; no - output 'Syntax Error ?' error 003EF7 1 53 79 6E 74 .byte "Syntax Error ? (2)",CR,LF 003EFB 1 61 78 20 45 003EFF 1 72 72 6F 72 003F0B 1 EA nop 003F0C 1 4C 28 28 jmp RESTRT ; abort command 003F0F 1 003F0F 1 ; *** Increment the 16-bit Word at X,X+1 and Compare with X+2,3 *** 003F0F 1 F6 00 INCCMP: inc $00,x ; increment LSB 003F11 1 D0 02 bne do_cmp ; carry ? 003F13 1 F6 01 inc $01,x ; increment MSB 003F15 1 B5 00 do_cmp: lda $00,x ; compare LSB 003F17 1 D5 02 cmp $02,x 003F19 1 D0 04 bne notequ ; if not equal return 003F1B 1 B5 01 lda $01,x ; otherwise compare MSB 003F1D 1 D5 03 cmp $03,x 003F1F 1 60 notequ: rts ; and return 003F20 1 003F20 1 ; *** Increment the 16-bit Word at X,X+1 *** 003F20 1 F6 00 WRDINC: inc $00,x ; increment LSB 003F22 1 D0 02 bne incrtn ; carry ? 003F24 1 F6 01 inc $01,x ; increment MSB 003F26 1 60 incrtn: rts ; and return 003F27 1 003F27 1 ; *** Decrement the 16-bit Word at X,X+1 *** 003F27 1 B5 00 WRDDEC: lda $00,x ; is the LSB zero ? 003F29 1 D0 02 bne decrtn 003F2B 1 D6 01 dec $01,x ; yes - decrement MSB 003F2D 1 D6 00 decrtn: dec $00,x ; decrement LSB 003F2F 1 60 rts ; and return 003F30 1 003F30 1 ; *** Compare the 16-bit Words at X,X+1 with X+2,3 *** 003F30 1 B5 00 WRDCMP: lda $00,x ; compare LSB 003F32 1 D5 02 cmp $02,x 003F34 1 D0 04 bne ncmp ; if not equal return 003F36 1 B5 01 lda $01,x ; otherwise compare MSB 003F38 1 D5 03 cmp $03,x 003F3A 1 60 ncmp: rts ; and return 003F3B 1 003F3B 1 ; *** Output the Word at X+1, X *** 003F3B 1 B5 01 OUTWRD: lda $01,x ; first byte 003F3D 1 20 4C 3F jsr OUTBYT ; output the second byte (at X+1) 003F40 1 E8 inx ; increment the pointer to the next word 003F41 1 E8 inx 003F42 1 B5 FE lda $FE,x ; output the first byte (now at X-2) 003F44 1 20 4C 3F jsr OUTBYT 003F47 1 A9 20 outspc: lda #SPACE ; followed by a space 003F49 1 4C F4 FF jmp OSWRCH ; and return 003F4C 1 003F4C 1 ; *** Output the Byte in A In Hex *** 003F4C 1 48 OUTBYT: pha ; save A 003F4D 1 4A lsr a ; start with the upper nibble 003F4E 1 4A lsr a ; shift to the lower nibble position 003F4F 1 4A lsr a 003F50 1 4A lsr a 003F51 1 20 55 3F jsr OUTDIG ; and output 003F54 1 68 pla ; retrieve A and output the lower nibble 003F55 1 003F55 1 ; *** Output the Hex Digit in A *** 003F55 1 29 0F OUTDIG: and #$0F ; mask off the upper nibble 003F57 1 C9 0A cmp #$0A ; is it A-F ? 003F59 1 90 02 bcc ascii ; no 003F5B 1 69 06 adc #$06 ; yes - add offset to 'A' 003F5D 1 69 30 ascii: adc #'0' ; convert to ASCII 003F5F 1 4C F4 FF jmp OSWRCH ; output character and return 003F62 1 003F62 1 ; ****** DEBUG CODE ****** 003F62 1 .if DEBUG = 'Y' ; Breakpoint Handler for DEBUG 003F62 1 003F62 1 BRKPNT: cld ; Breakpoint Routine Entry 003F62 1 sta brk_a ; save A, X and Y 003F62 1 stx brk_x 003F62 1 sty brk_y 003F62 1 pla ; retrieve status register 003F62 1 sta brk_sr ; and save 003F62 1 pla ; retrieve PC and save 003F62 1 sta brkpcl 003F62 1 pla 003F62 1 sta brkpch 003F62 1 jsr OUTSTR ; output pc = program counter value 003F62 1 .byte "BREAK at PC=" 003F62 1 lda brkpch 003F62 1 jsr OUTBYT 003F62 1 lda brkpcl 003F62 1 jsr OUTBYT 003F62 1 jsr OUTSTR ; output CRLF A = accumulator value 003F62 1 .byte " A=" 003F62 1 lda brk_a 003F62 1 jsr OUTBYT 003F62 1 jsr OUTSTR ; output X = X register value 003F62 1 .byte " X=" 003F62 1 lda brk_x 003F62 1 jsr OUTBYT 003F62 1 jsr OUTSTR ; output Y = Y register value 003F62 1 .byte " Y=" 003F62 1 lda brk_y 003F62 1 jsr OUTBYT 003F62 1 jsr OUTSTR ; output PS = status register value 003F62 1 .byte " PS=" 003F62 1 lda brk_sr 003F62 1 jsr OUTBYT 003F62 1 jsr OSCRLF ; and a final CR LF 003F62 1 jmp RESTRT ; re-enter command line interpreter 003F62 1 .endif 003F62 1