title CROMEMCO PROGRAM DEBUGGER name ('DEBUGK') ; Kernel of Cromemco program debugger ; DASMed by W.Cirsovius ; NOTES: ; (1) Routine l021b prints also characters from 80H..FFH ; MSB should be resetted ;; .z80 ;; aseg .phase 0000h CDOS equ 0000h FCB equ 005ch DMA equ 0080h CCP equ 0080h .drv equ 1 .nam equ 8 .ext equ 3 _EX equ 12 _CR equ 32 .conout equ 2 .rdkbd equ 10 .resdsk equ 13 .open equ 15 .close equ 16 .delete equ 19 .rdseq equ 20 .wrseq equ 21 .make equ 22 .setdma equ 26 .usrcod equ 32 DIRlen equ 16 reclng equ 128 IOerr equ 0ffh null equ 00h lf equ 0ah cr equ 0dh eof equ 1ah DEL equ 7fh endtab equ -1 LOMASK equ 00001111b UPPMASK equ 01011111b MSB equ 10000000b NOMSB equ 01111111b MAXBP equ 12 BPLEN equ 8 LINLIST equ 16 ; Default lines for command L BASEBP equ 11000111b ; Base address of breakpoint BPMASK equ NOT BASEBP ; Breakpoint mask BP.Nr equ 6 ; Breakpoint number used here BPcode equ BASEBP + BP.Nr SHL 3 _r.HL equ 6 ; Register number for (HL) l2131 equ 2131h l2625 equ 2625h lffff equ 0ffffh l0001 equ 0001h l0005 equ 0005h l000a equ 000ah l0010 equ 0010h l0080 equ 0080h l0100 equ 0100h l0000: jp l0005 jp l006d l0006: jp l006d jr l006d l000b: db BPcode ; Here: RST 30h - Breakpoint code l000c: db '!' ; ds 2*32 ; ; ^^^^^^^^^ Stack ; l004d: db 0 ; L' l004e: db 0 ; H' l004f: db 0 ; E' l0050: db 0 ; D' l0051: db 0 ; C' l0052: db 0 ; B' l0053: db 0 ; F' l0054: db 0 ; A' l0055: db 0 ; IP l0056: ; I db 0 ; State of interrupt register l0057: dw 0 ; IY l0059: dw 0 ; IX l005b: db 0 ; F l005c: db 0 ; A l005d: db 0 ; C l005e: db 0 ; B l005f: db 0 ; E l0060: db 0 ; D l0061: db 0 ; L l0062: db 0 ; H l0063: ; SP dw 0 ; Top of memory l0065: di ; May be EI l0067 equ $+1 ; PC jp l0100 ; Jump to current breakpoint l0069: dw 0 l006b: dw 0 ; Adress of error routine ; ; ############################## ; ### COLD START OF DEBUGGER ### ; ############################## ; l006d: ld a,i ld (l0056),a ; Save state of interrupt register ld a,0f3h ; DI jp po,l0079 ld a,0fbh ; EI l0079: ld (l0065),a ; Set interrupt ld hl,(l0006) ; Get top of memory ld (l0063),hl ld hl,l0110 ld (l006b),hl ; Init address of error routine ld sp,l004d ld a,(FCB+.drv) cp ' ' ; Test filename given ld hl,l0000 call nz,l0f0d ; Yeap, load file call l0549 ; ; ########################## ; ### MAIN DEBUGGER LOOP ### ; ########################## ; l0099: ld sp,l004d ; Set local stack ld hl,l0110 ld (l006b),hl ; Init address of error routine call l067c ld a,(l000c) ; Get indicator call l01ef ; Put to console call l016b ; Read line from keyboard call l0254 ; Skip blanks ld a,(de) ; Get character and a ; Test end of line jr z,l0099 ; Yeap inc de sub 'A'-1 ; Test range jr c,l0105 cp 'Z'+1-('A'-1) jr nc,l0105 add a,a ; Double index ld hl,l00cf call l024f ; Add byte to word ld a,(hl) ; Fetch address inc hl ld h,(hl) ld l,a call l00ce ; Execute command jr l0099 ; ; Jump thru register ; ENTRY Reg HL holds address ; l00ce: jp (hl) ; ; Command table ; l00cf:: dw l0cd1 ; @: dw l1104 ; A: Assemble dw l0695 ; B: Set or display breakpoints dw l2007 ; C: Trace over calls dw l0def ; D: Dump or display memory dw l0ce0 ; E: Examine input port dw l0eb8 ; F: Specify filename dw l0657 ; G: Go dw l0d78 ; H: Hex arithmetic dw l0eb8 ; I: Input CCP command line dw l0105 ; J: -- dw l0105 ; K: -- dw l17c2 ; L: List in assembler mnemonics dw l0d67 ; M: Move memory dw l10a0 ; N: Reset disk system dw l0cec ; O: Output data to port dw l0105 ; P: -- dw l0db3 ; Q: Query memory dw l0f02 ; R: Read disk file dw l0af0 ; S: Substitute memory dw l200b ; T: Trace dw l10f9 ; U: Set user area dw l0d38 ; V: Verify memory dw l1068 ; W: Write disk file dw l0df5 ; X: Display registers dw l0105 ; Y: -- dw l0dd4 ; Z: Zap memory ; ; Error routine ; l0105: ld hl,(l006b) call l00ce ld hl,l0000 jr l0099 ; ; ; l0110: ld a,'?' call l01ef ; Put to console jp l0236 ; Close console ; ; Keyboard line ; l0118: db 80 ds 1 ds 80+1 ; ; Read line from keyboard ; EXIT Reg DE points to line ; l016b: ld de,l0118 ; Point to keyboard line push de ld c,.rdkbd call CDOS ; Read line call l0236 ; Close console pop de ; Get back line pointer inc de ld a,(de) ; Get length ld b,a inc b inc de push de ; Save start of line ld c,0 ; Init string marker l0180: ld a,(de) ; Get character dec b ; Test end of line jr z,l0192 ; Yeap bit 0,c ; Test string pending call z,l0196 ; Nope, convert to upper case ld (de),a ; Save character inc de cp '''' ; Test string jr nz,l0180 ; Nope inc c ; Indicate it jr l0180 l0192: sub a ld (de),a ; Close line pop de ret ; ; Convert character to upper case ; ENTRY Accu holds character ; EXIT Accu holds character in upper case ; l0196: cp 'a' ; Test range ret c cp 'z'+1 ret nc and UPPMASK ; Convert it ret ; ; ; l019f: call l01d5 ; Put hex word to console push de push hl ld de,(l0069) ld a,d or e jr z,l01b9 call l0232 ; Put blank to console and a sbc hl,de call l01d5 ; Put hex word to console call l024b ; Put apostrophe to console and a l01b9: pop hl pop de ret ; ; ; l01bc: call l01c3 ld a,'.' jr l01ef ; Put to console ; ; ; l01c3: push de ld de,l000a ld c,8ah call l053c ld a,h or l call nz,l01c3 ld a,e pop de jr l01e3 ; Put hex digit to console ; ; Put hex word to console ; l01d5: ld a,h ; Get hi call l01da ; Put hex byte to console ld a,l ; Get low ; ; Put hex byte to console ; l01da: push af rra rra rra rra call l01e3 ; Put hex digit to console pop af ; ; Put hex digit to console ; l01e3: and LOMASK cp 9+1 jr c,l01eb add a,'A'-'0'-10 l01eb: add a,'0' jr l01ef ; Put to console ; ; Put character to console ; ENTRY Accu holds character ; l01ef: push hl push de push bc push af call l01ff ; Put to console ld hl,l0205 inc (hl) ; Update column pop af pop bc pop de pop hl ret ; ; Put character to console ; ENTRY Accu holds character ; l01ff: ld e,a ; Get character ld c,.conout jp CDOS ; Put it ; l0205: db 0 ; Console column ; ; ; l0206: push hl push de push bc ld c,6 ld e,0ffh call l0000 and a jr z,l0214 scf l0214: pop bc pop de pop hl ret pop de pop hl ret ; ; Put string to console ; ENTRY Reg HL points to string ; EXIT Reg C holds number of characters printed ; l021b: ld c,0 ; Clear counter l021d: ld a,(hl) ; Get character and a ; Test end ret z call l01ef ; Put to console inc c ; Update count inc hl and a ; Test end character ret m ; Yeap jr l021d ; ; Put six blanks to console ; l0229: call l022f ; Put two blanks to console call l022f ; Put two more blanks to console ; ; Put two blanks to console ; l022f: call l0232 ; Put blank to console ; ; Put blank to console ; l0232: ld a,' ' jr l01ef ; Put to console ; ; Close console ; l0236: ld a,cr call l01ef ; Put to console ld a,lf call l01ef ; Put to console sub a ld (l0205),a ; Clear console column call l0206 jp c,l0099 ret ; ; Put apostrophe to console ; l024b: ld a,'''' jr l01ef ; Put to console ; ; Add byte to word ; ENTRY Accu holds byte ; Reg HL holds word ; EXIT Reg HL holds sum ; l024f: add a,l ; Add low ld l,a ret nc inc h ; Remember carry ret ; ; Skip blanks ; ENTRY Reg DE points to string ; EXIT Reg DE points to non blank character ; l0254: ld a,(de) ; Get character cp ' ' ; Test string ret nz ; Nope inc de ; Skip it jr l0254 ; ; ; l025b: call l0254 ; Skip blanks ld a,(de) cp ',' ret nz inc de call l0254 ; Skip blanks sub a ret ; ; Skip to end of line ; ENTRY Reg DE points to line ; EXIT Reg DE updated ; l0268: call l0254 ; Skip blanks ld a,(de) and a ; Test end ret z cp cr jp nz,l0105 ret ; ; Compare values ; ENTRY Reg HL holds value 1 ; Reg DE holds value 2 ; EXIT Zero flag set if both values match ; Carry flag set if value 1 less value 2 ; Carry flag reset if value 1 equal or greater value 2 ; l0274: push hl and a sbc hl,de ; Compare pop hl ret ; ; Find item in list ; ENTRY Reg HL points to table ; Reg DE points to string ; EXIT Carry set on match ; Reg B holds number of item in list ; l027a: ld b,MSB+0 ; Clear number jr l0280 ; ; Find item in list ; ENTRY Reg HL points to table ; Reg DE points to string ; EXIT Carry set on match ; Reg B holds number of item in list ; l027e: ld b,0 ; Clear number l0280: ld a,(hl) ; Get from list and a ; Test end of list ret z ; Yeap call l029e ; Test match jr c,l028b ; Yeap inc b ; Update item number jr l0280 l028b: res 7,b ; Clear hi bit ret ; ; ; l028e: ld b,0 l0290: ld a,(hl) and a ret z ld a,(de) cp (hl) jr z,l029b inc hl inc b jr l0290 l029b: scf inc de ret ; ; Test item match ; EXIT Carry set on match ; l029e: push bc jr l02a4 l02a1: push bc res 7,b l02a4: push de l02a5: ld a,(de) ; Get character xor (hl) ; Test match and NOMSB jr nz,l02ba ; Nope bit 7,(hl) ; Test end of item inc hl inc de jr z,l02a5 ; Nope call l02c1 jr nc,l02bd pop af scf ; Set match pop bc ret l02ba: call l02e0 ; Skip item l02bd: pop de and a ; Set no match pop bc ret ; ; ; l02c1: ld a,(de) bit 7,b jr z,l02ca cp 'S' scf ret z l02ca: cp '0' ret c cp '9'+1 ccf ret nc cp 'A' ret c cp 'Z'+1 ccf ret ; ; Position to selected item ; ENTRY Reg HL points to list ; Reg B holds number of item ; EXIT Reg HL points to selected item in list ; l02d8: inc b l02d9: dec b ; Test done ret z ; Nope call l02e0 ; Skip item jr l02d9 ; ; Skip item ; ENTRY Reg HL points to list ; EXIT Reg HL points to next item in list ; l02e0: ld a,(hl) ; Get character and a ; Test total end ret z ; Yeap l02e3: ld a,(hl) ; Get character inc hl and a ; Test end of item ret m ; Yeap jr l02e3 ; ; Get three parameters ; l02e9: call l031d push hl push bc call l025b call l0364 jp c,l0105 call l0268 ; Skip to end of line ex de,hl pop bc pop hl ret call l031d jr l0306 ; ; ; l0303: call l0320 l0306: jp l0268 ; Skip to end of line ; ; ; l0309: call l0364 jp c,l0105 jp l0268 ; Skip to end of line ; ; ?????????????????????????? ; ENTRY Reg HL points to ??? ; l0312: push hl call l0364 jr c,l0319 ex (sp),hl l0319: pop hl jp l0268 ; Skip to end of line l031d: scf jr l0321 ; ; ; l0320: and a l0321: ex af,af' push bc push hl call l0364 jr nc,l0330 ex af,af' jr c,l0339 ex af,af' pop hl jr l0331 l0330: pop af l0331: call l033e jr nc,l033c ex af,af' pop bc ret nc l0339: jp l0105 l033c: pop af ret l033e: call l025b ld a,(de) cp 'S' jr nz,l0347 inc de l0347: push hl push af call l0364 jr c,l035d ld b,h ld c,l pop af pop hl jr z,l035b ld a,c sub l ld c,a ld a,b sbc a,h ld b,a inc bc l035b: and a ret l035d: pop af pop hl jp z,l0105 scf ret ; ; ; l0364: call l0254 ; Skip blanks l0367: call l03d6 ret c call l0396 ret nc push bc push hl call l03d6 jp c,l0105 ex de,hl ex (sp),hl and a sbc hl,de ld hl,lffff pop de ret l0381: jr z,l0394 jr l0393 l0385: jr nz,l0394 jr l0393 l0389: jr z,l0394 l038b: jr c,l0394 jr l0393 l038f: jr z,l0393 l0391: jr nc,l0394 l0393: inc hl l0394: and a ret l0396: push hl ld hl,l03c6 call l028e jr nc,l03c4 ld a,b or a jr z,l03b8 ld a,(de) cp '=' jr nz,l03ad inc de inc b inc b jr l03b8 l03ad: bit 0,b jr z,l03b8 cp '>' jr nz,l03b8 inc de ld b,5 l03b8: ld hl,l03ca ld a,b add a,a call l024f ; Add byte to word ld c,(hl) inc hl ld b,(hl) scf l03c4: pop hl ret l03c6: db '=<>',0 l03ca: dw l0381 dw l038b dw l038f dw l0389 dw l0391 dw l0385 ; ; ; l03d6: call l0444 ret c l03da: call l041b push hl push bc call l0446 pop bc ex de,hl ex (sp),hl jr nc,l03ee pop de ld a,b or c ret z jp l0105 l03ee: ld a,b or c push bc ret nz pop bc l03f3: add hl,de l03f4: pop de jr l03da l03f7: and a sbc hl,de jr l03f4 l03fc: ld b,h ld c,l call l054a nop jr l03f4 l0404: ld c,8ah call l053c jr l03f4 l040b: ld a,h and d ld h,a ld a,l and e ld l,a jr l03f4 l0413: ld a,h or d ld h,a ld a,l or e ld l,a jr l03f4 l041b: push hl ld hl,l042f call l028e ld a,b ld hl,l0436 add a,a call l024f ; Add byte to word ld c,(hl) inc hl ld b,(hl) pop hl ret l042f: dec hl dec l ld hl,(l2625) ld a,h nop l0436: dw l03f3 dw l03f7 dw l03fc dw l0404 dw l040b dw l0413 dw 0 ; ; ; l0444: ld c,1 l0446: call l0501 ; Test (hex)decimal digit jr nc,l0478 ; Yeap ld a,(de) inc de ld hl,(l0069) cp '@' ret z ld hl,(l0067) ; Get address of current breakpoint cp '$' ret z cp '-' jr z,l04b5 cp '~' jr z,l04c2 cp '+' jr z,l0444 cp '^' jr z,l04a5 cp '(' jr z,l04c7 cp '[' jr z,l04db cp '''' jr z,l048e l0475: dec de scf ret l0478: push de l0479: inc de call l0501 ; Test (hex)decimal digit jr nc,l0479 ; Yeap pop de cp '.' jr z,l0489 call l04ea and a ret l0489: call l0515 and a ret l048e: ld hl,l0000 l0491: ld a,(de) cp '''' jr z,l049d and a ret z l0498: ld h,l ld l,a inc de jr l0491 l049d: inc de ld a,(de) cp '''' jr z,l0498 and a ret l04a5: call l0bb9 ; Find register jr nc,l04e7 ; Not found ld a,(hl) ; Get content of register inc hl ld h,(hl) ld l,a and a bit 0,c ret nz ld h,0 ret l04b5: call l0444 dec hl l04b9: jr c,l04e7 ld a,h cpl ld h,a ld a,l cpl ld l,a ret l04c2: call l0444 jr l04b9 l04c7: ld a,b or c jr z,l0475 call l0367 jr c,l04e7 ld a,(de) cp ')' jr nz,l04e7 inc de ld a,(hl) inc hl ld h,(hl) ld l,a ret l04db: call l0367 jr c,l04e7 ld a,(de) cp 5dh jr nz,l04e7 inc de ret l04e7: jp l0105 l04ea: ld hl,l0000 l04ed: call l0501 ; Test (hex)decimal digit jr c,l04fc ; Nope add hl,hl add hl,hl add hl,hl add hl,hl call l024f ; Add byte to word inc de jr l04ed l04fc: cp 'H' ret nz inc de ret ; ; Test (hex)decimal digit ; ENTRY Reg DE points to character ; EXIT Carry set if not a digit ; Accu holds binary digit ; l0501: ld a,(de) cp '0' ret c cp '9'+1 jr c,l0512 cp 'A' ret c cp 'F'+1 ccf ret c sub 'A'-'0'-10 l0512: sub '0' ret ; ; ; l0515: ld hl,l0000 l0518: call l0531 ; Test decimal digit inc de jr c,l052b ; Nope push bc add hl,hl ld b,h ld c,l add hl,hl add hl,hl add hl,bc pop bc call l024f ; Add byte to word jr l0518 l052b: cp '.' ; Verify end of digits ret z jp l0105 ; ; Test decimal digit ; ENTRY Reg DE points to character ; EXIT Carry set if not a digit ; Accu holds binary digit ; l0531: ld a,(de) cp '0' ret c cp '9'+1 ccf ret c sub '0' ret ; ; ENTRY .... ; l053c: and a ld bc,lffff l0540: inc bc sbc hl,de jr nc,l0540 add hl,de ex de,hl push bc pop hl l0549: ret ; ; ; l054a: ld hl,l0000 l054d: add hl,de dec bc ld a,b or c jr nz,l054d ret ; ; Print state of registers ; l0554: call l0592 ; Print flag register call l022f ; Put blanks to console ld hl,l060f ; Point to name of registers ld de,l062f ; Point to control field ld b,NRegLen ; Set length l0562: call l05d8 ; Print normal registers djnz l0562 push hl ; Save pointers push de ld iy,(l0067) ; Get address of current breakpoint call l1852 exx ex af,af' call l0236 ; Close console call l05a5 ; Print alternate flag register call l022f ; Put blanks to console pop de ; Get back pointers pop hl ld b,ARegLen l057f: call l05d8 ; Print alternate registers djnz l057f exx ex af,af' and a jr z,l058f call l0229 ; Put blanks to console call l1838 l058f: jp l0236 ; Close console ; ; Print flag register ; l0592: ld a,(l005b) ; Get state of flag register call l05ae ; Indicate it ld a,(l0065) ; Get state of interrupt cp 0f3h ; Test DI jp z,l0232 ; Yeap, put blank to console ld a,'E' jp l01ef ; Put to console ; ; Print alternate flag register ; l05a5: ld a,(l0053) ; Get state of flag register call l05ae ; Indicate it jp l0232 ; Put blank to console ; ; Indicate state of flag register ; ENTRY Accu holds state ; ; MZ-I-E-C ; l05ae: ld b,a ld a,'S' ; Sxxx.xxxx call l05d0 ld a,'Z' ; xZxx.xxxx call l05d0 rl b ld a,'H' ; xxxH.xxxx call l05d0 rl b ld a,'V' ; xxxx.xVxx call l05d0 ld a,'N' ; xxxx.xxNx call l05d0 ld a,'C' ; xxxx.xxxC jr l05d0 l05d0: rl b ; Get bit jp c,l01ef ; Put state to console if set jp l0232 ; Put blank to console if not ; ; Print register contents ; ENTRY Reg HL points to registers names ; Reg DE points to control array ; l05d8: push bc push de call l021b ; Print name of register ld a,'=' call l01ef ; Put to console ex (sp),hl ; Get array pointer ld e,(hl) ; Fetch address of register inc hl ld d,(hl) inc hl ld a,(hl) ; Get state inc hl push hl and a ; Test byte only jr z,l0604 push af ld a,(de) ; Fetch content of register pair ld l,a inc de ld a,(de) ld h,a pop af dec a ; Test program counter jr z,l05ff ; Nope, print content word call l019f call z,l0229 ; Put blanks to console jr l0608 l05ff: call l01d5 ; Put hex word to console jr l0608 l0604: ld a,(de) call l01da ; Put hex byte to console l0608: call l0232 ; Put blank to console pop de pop hl pop bc ret ; l060f: dc 'A ' dc 'BC ' dc 'DE ' dc 'HL ' dc 'SP' dc 'PC' NRegLen equ 6 ; dc 'A''' dc 'BC''' dc 'DE''' dc 'HL''' dc 'IX' dc 'IY' dc 'I' ARegLen equ 7 db null ; ; Byte 0,1: Address ; Byte 2 : State: ; 0: Register ; 1: Register pair ; 2: Program counter ; l062f: dw l005c ; A db 0 dw l005d ; C db 1 dw l005f ; E db 1 dw l0061 ; L db 1 dw l0063 ; SP db 1 dw l0067 ; PC db 2 ; dw l0054 ; A' db 0 dw l0051 ; C' db 1 dw l004f ; E' db 1 dw l004d ; L' db 1 dw l0059 ; IX db 1 dw l0057 ; IY db 1 dw l0056 ; I db 0 db null ; ; Command G starting_address/breakpoint-1 breakpoint-2 ... breakpoint-n : Go ; l0657:: sub a ld (l20d1),a ; Set normal trace ld (l087a),a call l0364 jr c,l0666 ld (l0067),hl ; Set address of current breakpoint l0666: call l0254 ; Skip blanks ld a,(de) and a jp z,l095d cp '/' ; Test breakpoints follow jp nz,l0105 inc de ld a,2 call l0749 jp l095d ; ; ; l067c: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l0682: ld a,(ix+0) ; Get state and 11110001b ; Reset bits ld (ix+0),a call l0997 ld de,BPLEN add ix,de ; Point to next djnz l0682 ret ; ; Command B: Set or display permanent break points ; Command BX: Delete permanent break points ; Modes: B ; B breakpoint-1 breakpoint-2...breakpoint-n ; BX ; BX addr-1 addr-2 ... l0695:: call l0254 ; Skip blanks ld a,(de) ; Get next character or a ; Test display jr z,l06e4 ; Yeap inc de cp 'X' ; Test delete jr z,l06a8 ; Yeap dec de ld a,1 call l0749 ret ; ; Delete breakpoints ; l06a8: call l0254 ; Skip blanks ld a,(de) and a ; Test delete all jr z,l06bf ; Yeap l06af: call l0364 jp c,l0268 ; Skip to end of line push de call l06c0 pop de call l025b jr l06af ; ; Delete all breakpoints ; l06bf: scf ; Set delete all flag l06c0: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l06c6: push af ; Save flag jr c,l06d4 ; Delete all ld e,(ix+2) ; Get address of breakpoint ld d,(ix+3) call l0274 ; Compare jr nz,l06db ; No match l06d4: ld (ix+0),00000000b; Force passive call l0997 l06db: ld de,BPLEN add ix,de ; Point to next breakpoint pop af ; Get back delete flag djnz l06c6 ret ; ; Display all breakpoints ; l06e4: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l06ea: bit 0,(ix+0) ; Test state jr z,l073d ; Not enabled ld hl,l0745 call l021b ; Tell BP ld a,'R' bit 4,(ix+0) ; Get optional report register flag jr nz,l0700 ld a,' ' l0700: call l01ef ; Put to console call l0232 ; Put blank to console ld l,(ix+2) ; Get memory address of break point ld h,(ix+3) call l019f call l0232 ; Put blank to console ld l,(ix+6) ; Get condition for break point ld h,(ix+7) ld a,h or l jr z,l072c ; Skip if no condition ld a,'{' call l01ef ; Put to console call l021b ; Print condition ld a,'}' call l01ef ; Put to console call l0232 ; Put blank to console l072c: ld a,':' call l01ef ; Put to console ld l,(ix+4) ; Get repeat count of break point ld h,(ix+5) call l01d5 ; Put hex word to console call l0236 ; Close console l073d: ld de,BPLEN add ix,de ; Point to next breakpoint djnz l06ea ret ; l0745: dc 'BP= ' ; ; ??????????????????????????????? ; ENTRY Accu holds count [1 or 2] ; l0749: ld b,a ; Save count call l0254 ; Skip blanks ld a,(de) ; Get character and a ; Test more ret z ; Nope, end cp 'R' ; Test register jr nz,l0757 ; Nope inc de ; Skip it set 4,b ; Set bit l0757: push bc call l0784 ; Find free breakpoint call l0364 jp c,l0105 ld (ix+2),l ; Save address of breakpoint ld (ix+3),h call l07c4 ld (ix+6),l ; Save condition ld (ix+7),h call l079c ld (ix+4),l ; Save repeat count ld (ix+5),h call l025b pop af ld (ix+0),a ; Save state and 00001111b jr l0749 ; ; Find free breakpoint ; EXIT Reg IX points to free one ; l0784: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l078a: ld a,(ix+0) ; Get state and 00001111b ; Test free ret z ; Yeap push bc ld bc,BPLEN add ix,bc ; Point to next pop bc djnz l078a ; Try it jp l0105 ; Error if no breakpoint available ; ; ; l079c: call l0254 ; Skip blanks ld hl,l0001 ld a,(de) cp ':' jr z,l07bc cp '(' ret nz inc de call l0364 jp c,l0105 call l0254 ; Skip blanks ld a,(de) cp ')' jp nz,l0105 inc de ret l07bc: inc de call l0364 jp c,l0105 ret ; ; ; l07c4: call l0254 ; Skip blanks ld a,(de) cp '{' ld hl,l0000 ret nz inc de push de call l0364 jp c,l0105 ld a,(de) cp '}' jp nz,l0105 pop de ld hl,(l0a6c) ld (l0a6e),hl l07e3: ld a,(de) inc de cp '}' jr z,l07ee call l09f0 jr l07e3 l07ee: sub a call l09f0 ld hl,(l0a6e) ret ; ; !!!!!!!!!!!!!!!!!!!!!!!! ; !!! Enter breakpoint !!! ; !!!!!!!!!!!!!!!!!!!!!!!! ; l07f6: ld (l0061),hl ; Save HL register pop hl dec hl ld (l0067),hl ; Set address of current breakpoint ld (l0063),sp ld sp,l0061 ; Ppoint stack to registers push de push bc push af push ix push iy ld a,i nop ld h,a ld l,0 push hl ld a,0f3h ; DI jp po,l081a ld a,0fbh ; EI l081a: ld (l0065),a ; Set state of interrupt ex af,af' push af exx push bc push de push hl call l08b2 ld a,(l20d0) dec a jr z,l0844 call l084c and a jp z,l095d and 83h jp z,l2038 call l0554 ; Print state of registers call l0549 call l067c jp l0099 l0844: ld (l20d0),a ld c,7 jp l0979 ; ; ; l084c: ld a,80h ex af,af' sub a ld (l087a),a ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l0859: ld a,(ix+0) ; Get state and 00000111b ; Mask it jr z,l0871 ld e,(ix+2) ; Get address of breakpoint ld d,(ix+3) ld hl,(l0067) ; Get address of current breakpoint call l0274 ; Compare push bc call z,l087b ; Match pop bc l0871: ld de,BPLEN add ix,de djnz l0859 ex af,af' ret ; l087a: db 0 ; ; ; l087b: ex af,af' res 7,a ex af,af' ld e,(ix+6) ; Get condition of breakpoint ld d,(ix+7) ld a,d or e ld hl,lffff call nz,l0364 ld a,h or l ret z ld e,(ix+4) ; Get repeat count ld d,(ix+5) dec de ; Count down ld a,d or e ; Test done jr z,l08ac ; Yeap ld (ix+4),e ; Update count ld (ix+5),d bit 4,(ix+0) ; Rest register ret z ; Nope ld a,1 ld (l087a),a ret l08ac: ex af,af' or (ix+0) ; BUild new state ex af,af' ret ; ; ; l08b2: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l08b8: bit 5,(ix+0) res 5,(ix+0) jr z,l08d2 ld l,(ix+2) ; Get address of break point ld h,(ix+3) ld a,(l000b) ; Get breakpoint code cp (hl) jr nz,l08d2 ld a,(ix+1) ld (hl),a l08d2: res 3,(ix+0) ld de,BPLEN add ix,de djnz l08b8 ret ; ; ; l08de: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l08e4: ld a,(ix+0) ; Get state of breakpoint and 00000011b jr z,l08f8 ld e,(ix+2) ; Get address of breakpoint ld d,(ix+3) ld hl,(l0067) ; Get address of current breakpoint call l0274 ; Compare ret z ; End if match l08f8: ld de,BPLEN add ix,de djnz l08e4 sub a inc a ret ; ; ; l0902: call l0784 ; Find free breakpoint ld (ix+4),1 ; Init repeat count ld (ix+5),0 ld (ix+2),l ; Set address of breakpoint ld (ix+3),h ld (ix+6),0 ; Clear condition ld (ix+7),0 ld a,(l20d0) and a ld a,0001000b jr nz,l0925 ld a,0000100b l0925: ld (ix+0),a ; Set state ret ; ; ; l0929: ld b,MAXBP ; Set number of breakpoints ld ix,l0a0c ; Point to breakpoints l092f: ld a,(ix+0) ; Get state of breakpoint and c ; Test same jr z,l0955 ; Yeap set 5,(ix+0) ld l,(ix+2) ; Get address of breakpoint ld h,(ix+3) ld a,(hl) ; Get opcode ld (ix+1),a ; save it ld a,(l000b) ; Get breakpoint code ld (hl),a and BPMASK ; Get address of breakpoint ld h,0 ld l,a ld (hl),0c3h inc hl ld de,l07f6 ld (hl),e inc hl ld (hl),d l0955: ld de,BPLEN add ix,de djnz l092f ret ; ; ; l095d: sub a ld (l20d0),a ld a,(l087a) and a call nz,l0554 ; Print state of registers call l08de ld c,7 jr nz,l0979 ld a,1 ld (l20d0),a call l1eed ld c,8 l0979: call l0929 ld sp,l004d ; Point tack to HL' pop hl pop de pop bc pop af exx ex af,af' pop af ld i,a pop iy pop ix pop af pop bc pop de pop hl ld sp,(l0063) jp l0065 ; ; ; l0997: ld a,(ix+0) ; Get state of breakpoint and 00000011b ret nz ld e,(ix+6) ; Get condition ld d,(ix+7) ld a,d or e ret z push bc ld h,d ld l,e sub a ld (ix+6),a ; Clear condition ld (ix+7),a ld bc,lffff cpir l09b5: push de ld de,(l0a6c) call l0274 ; Compare pop de jr nc,l09cb ; HL>=DE call l09d1 l09c3: ld a,(hl) ldi and a jr nz,l09c3 jr l09b5 l09cb: ld (l0a6c),de pop bc ret ; ; ; l09d1: ld iy,l0a0c ; Point to breakpoints push de l09d6: ld e,(iy+6) ld d,(iy+7) call l0274 ; Compare jr z,l09e8 ; Match ld de,BPLEN add iy,de jr l09d6 l09e8: pop de ld (iy+6),e ld (iy+7),d ret ; ; ; l09f0: push de ld hl,(l0a6c) ld de,l0af0 call l0274 ; Compare jr nc,l0a03 ; HL>=DE ld (hl),a inc hl ld (l0a6c),hl pop de ret l0a03: ld hl,(l0a6e) ld (l0a6c),hl jp l0105 ; ; Breakpoint table ; Each entry holds the following settings: ; ; Byte 0 : State of breakpoint ; Byte 1 : Opcode of program ; Bytes 2,3: Address of breakpoint ; Bytes 4,5: Repeat count ; Bytes 6,7: Condition ; ; Definition of state bits: ; ; | | Mask 1 ; | | Mask 2 ; | | Mask 3 ; 7654 3210 ; xxxx xxxB Active ; xxxx xBxx ??? ; xxxx Bxxx ??? ; xxxB xxxx Register ; xxBx xxxx ??? ; l0a0c: ds MAXBP*BPLEN l0a6c: dw l0a70 l0a6e: dw l0a70 l0a70: ds 128 ; ; Command S: Substitute memory ; Command SM starting-addr: Substitute memory ; l0af0: call l0254 ; Skip blanks ld a,(de) ; Get next character inc de cp 'M' ; Test SM jp z,l0c68 ; Yeap dec de call l0bb9 ; Find register jp nc,l0c68 ; Not found call l0268 ; Skip to end of line ld a,b ; Get index cp 1eh ; Test F' jr z,l0b68 cp 1fh ; Test F jr z,l0b58 cp 1dh ; Test IP jp z,l0105 ex de,hl ld hl,l0bd1 ; Point to register table call l02d8 ; Position to selected register l0b19: ld b,c call l021b ; Print register ld a,'=' call l01ef ; Put to console call l0b45 call l0232 ; Put blank to console push de push bc call l016b ; Read line from keyboard call l0254 ; Skip blanks ld a,(de) and a jr z,l0b42 call l0309 ld b,h ld c,l pop af pop hl ld (hl),c bit 0,a ret z inc hl ld (hl),b ret l0b42: pop af pop hl ret ; ; ; l0b45: ld a,(de) bit 0,b jp z,l01da ; Put hex byte to console ld l,a inc de ld a,(de) dec de ld h,a bit 1,b jp z,l01d5 ; Put hex word to console jp l019f ; ; ; l0b58: call l0592 ld a,0f3h ; DI ld (l0065),a ; Set state of interrupt scf call l0b73 ld (l005b),a ; Set state of flag register ret l0b68: call l05a5 and a call l0b73 ld (l0053),a ; Set state of flag register ret ; ; ; l0b73: ex af,af' ld b,0 ; Init count call l0232 ; Put blank to console call l0268 ; Skip to end of line call l016b ; Read line from keyboard l0b7f: call l0254 ; Skip blanks ld a,(de) and a ld a,b ret z push bc ld hl,l0baf call l028e jp nc,l0105 ld a,b cp 8 jr z,l0ba2 pop bc rlca rlca rlca add a,0c0h ld (l0b9f),a l0b9f equ $+1 set 0,b jr l0b7f l0ba2: ex af,af' jp nc,l0105 ex af,af' ld a,0fbh ; EI ld (l0065),a ; Set state of interrupt pop bc jr l0b7f ; l0baf: db 'CNV H ZSE',null ; ; Find register ; ENTRY Reg DE points to register name ; EXI Carry set if register found ; Reg C holds register type [1 is pair] ; Reg HL holds ???? ; l0bb9: ld hl,l0bd1 ; Point to register table call l027a ; Find item in list ret nc ; No match ld a,b add a,b add a,b ld hl,l0c08 call l024f ; Add byte to word ld c,(hl) ; Get register type inc hl ld a,(hl) ; Fetch address of register inc hl ld h,(hl) ld l,a scf ret ; l0bd1: dc 'BC''' ; 0 dc 'DE''' ; 1 dc 'HL''' ; 2 dc 'BC' ; 3 dc 'DE' ; 4 dc 'HL' ; 5 dc 'A''' ; 6 dc 'B''' ; 7 dc 'C''' ; 8 dc 'D''' ; 9 dc 'E''' ; 10 dc 'H''' ; 11 dc 'L''' ; 12 dc 'A' ; 13 dc 'B' ; 14 dc 'C' ; 15 dc 'D' ; 16 dc 'E' ; 17 dc 'H' ; 18 dc 'L' ; 19 dc 'IX' ; 20 dc 'IY' ; 21 dc 'SP' ; 22 dc 'PC' ; 23 dc 'X' ; 24 dc 'Y' ; 25 dc 'S' ; 26 dc 'P' ; 27 dc 'I' ; 28 dc 'IP' ; 29 1dh dc 'F''' ; 30 1eh dc 'F' ; 31 1fh db null ; ; 32 Entries ; ; Byte 0 : State ; Byte 1,2: Address ; l0c08:: db 1 dw l0051 ; BC' db 1 dw l004f ; DE' db 1 dw l004d ; HL' db 1 dw l005d ; BC db 1 dw l005f ; DE db 1 dw l0061 ; HL db 0 dw l0054 ; A' db 0 dw l0052 ; B' db 0 dw l0051 ; C' db 0 dw l0050 ; D' db 0 dw l004f ; E' db 0 dw l004e ; H' db 0 dw l004d ; L' db 0 dw l005c ; A db 0 dw l005e ; B db 0 dw l005d ; C db 0 dw l0060 ; D db 0 dw l005f ; E db 0 dw l0062 ; H db 0 dw l0061 ; L db 1 dw l0059 ; IX db 1 dw l0057 ; IY db 1 dw l0063 ; SP db 3 dw l0067 ; PC db 1 dw l0059 ; X db 1 dw l0057 ; Y db 1 dw l0063 ; S db 3 dw l0067 ; P db 0 dw l0056 ; I db 1 dw l0055 ; IP db 0 dw l0053 ; F' db 0 dw l005b ; F ; ; Execute SM ; l0c68: ld hl,(l0ccf) call l0312 l0c6e: ld (l0ccf),hl call l019f call l0232 ; Put blank to console ld a,(hl) call l01da ; Put hex byte to console call l022f ; Put blanks to console push hl call l016b ; Read line from keyboard pop hl call l0254 ; Skip blanks ld a,(de) and a jr nz,l0c8d inc hl jr l0c6e l0c8d: ld a,(de) cp '.' ret z cp '-' jr z,l0cb0 cp '''' jr z,l0cb9 l0c99: push hl call l0364 ld a,l pop hl jr c,l0cab ld (hl),a ; Store new byte inc hl l0ca3: ld (l0ccf),hl call l025b jr l0c8d l0cab: call l0268 ; Skip to end of line jr l0c6e l0cb0: inc de ld a,(de) dec de and a jr nz,l0c99 dec hl jr l0c6e l0cb9: inc de l0cba: ld a,(de) and a jr z,l0c6e cp '''' jr z,l0cc7 l0cc2: ld (hl),a inc de inc hl jr l0cba l0cc7: inc de ld a,(de) cp '''' jr z,l0cc2 jr l0ca3 ; l0ccf: dw l0100 ; ; Command @: Register ; l0cd1:: call l0268 ; Skip to end of line ld hl,l0cdf ld de,l0069 ld c,1 jp l0b19 ; l0cdf: db 0c0h ; ; Command E data-port: Examine input port ; l0ce0:: call l0309 ; Get port ld c,l in a,(c) ; Input from port call l01da ; Put hex byte to console jp l0236 ; Close console ; ; Command O data-port: Output data to port ; l0cec:: call l0364 ; Get port push hl call l025b call l0309 ; Get byte pop bc out (c),l ret ; ; Parse file ; ENTRY Reg HL points to name of file ; Reg DE holds FCB ; EXIT ????? ; l0cfa: ld a,(hl) ; Get optional drive inc hl ld c,a ld a,(hl) ; Get next inc hl cp ':' ; Verify drive ld a,c jr z,l0d08 ; Yeap dec hl dec hl ld a,'A'-1 l0d08: sub 'A'-1 ; Make binary ld (de),a ; Save drive ld bc,256*.nam+3 ;;l0803 l0d0e: inc de call l0d1e ld (de),a djnz l0d0e ld b,.ext dec c jr nz,l0d0e inc de sub a ld (de),a ret ; ; ; l0d1e: call l0edc ; Test special delimiter bit 0,c jr nc,l0d29 ; Not printable inc hl ret nz jr l0d1e l0d29: jr nz,l0d33 dec c cp '.' jr nz,l0d33 inc hl jr l0d1e l0d33: ld a,' ' ret jr l0d3b ; ; Command V source-addr source-end destination-addr: Verify memory ; Command V source-addr $ swath-width destination-addr: Verify memory ; l0d38:: call l02e9 l0d3b: push bc ld a,(de) ; Get bytes ld b,(hl) cp b ; Compare jr z,l0d5e ; Match ld c,a call l019f call l0232 ; Put blank to console ld a,b call l01da ; Put hex byte to console call l022f ; Put blanks to console ld a,c call l01da ; Put hex byte to console call l0232 ; Put blank to console ex de,hl call l019f ex de,hl call l0236 ; Close console l0d5e: pop bc inc hl ; Bump addresses inc de dec bc ; Count down ld a,b or c jr nz,l0d3b ret ; ; Command M source-addr source-end destination-addr: Move memory ; Command M source-addr S swath-width destination-addr: Move memory ; l0d67:: call l02e9 call l0d6f ; Move jr l0d3b ; ; Move memory ; l0d6f: push hl ; Save regs push de push bc ldir ; Move pop bc pop de pop hl ret ; ; Command H expr: Hex arithmetic ; Command H expr1 expr2: Hex arithmetic ; l0d78:: call l0364 jp c,l0105 call l025b push hl call l0364 push af call l0268 ; Skip to end of line pop af ex de,hl pop hl jr c,l0da7 push hl push de add hl,de ; Build sum call l01d5 ; Put hex word to console call l0232 ; Put blank to console call l01bc ld a,',' call l01ef ; Put to console call l022f ; Put blanks to console pop de pop hl and a sbc hl,de ; Build difference l0da7: call l01d5 ; Put hex word to console call l0232 ; Put blank to console call l01bc jp l0236 ; Close console ; ; Command Q beginning-addr ending-addr string-of-bytes: Query memory ; Command Q beginning-addr S swath-width string-of-bytes: Query memory ; l0db3: call l031d push bc push hl call l0e26 pop hl l0dbc: call l0e17 ; Compare memory jr nz,l0dca ; No match push bc ld bc,l0010 and a call l0e61 pop bc l0dca: inc hl ex (sp),hl dec hl ld a,h or l ex (sp),hl jr nz,l0dbc pop bc ret ; ; Command Z beginning-addr ending-addr string-of-bytes: Zap memory ; Command Z beginning-addr S swath-width string-of-bytes: Zap memory ; l0dd4: call l031d push bc push hl call l0e26 ld a,b pop hl pop bc push hl ex de,hl l0de1: ldi jp po,l0ded dec a jr nz,l0de1 pop hl ldir ret l0ded: pop hl ret ; ; Command D or DM: Display memory ; DR : Display registers ; l0def:: ld a,(de) ; Get next character cp 'R' ; Test register jr nz,l0dfb ; Nope inc de ; Skip to register ; ; Command X: Display registers ; l0df5:: call l0268 ; Skip to end of line jp l0554 ; Print state of registers ; ; ; l0dfb: cp 'M' ; Test DM jp nz,l0e07 inc de ld a,(de) cp 'X' ; Test DMX jr nz,l0e07 inc de l0e07: ld hl,(l0e15) ld bc,l0080 call l0303 scf call l0e61 ret ; l0e15: dw 0100h ; ; Compare memory ; ENTRY Reg HL points to 1st address ; Reg DE points to 2nd address ; Reg B holds length of test ; EXIT Zero flag set on match ; l0e17: push hl push de push bc l0e1a: ld a,(de) ; Get byte cp (hl) ; Compare jr nz,l0e22 ; No match inc de inc hl djnz l0e1a ; Test all l0e22: pop bc pop de pop hl ret ; ; ; l0e26: ld hl,l0118+1 ; Point to keyboard line l0e29: call l025b ld a,(de) cp '''' jr z,l0e3d push hl call l0364 ld a,l pop hl jr c,l0e53 ld (hl),a inc hl jr l0e29 l0e3d: inc de l0e3e: ld a,(de) cp '''' jr z,l0e4b and a jr z,l0e53 l0e46: ld (hl),a inc hl inc de jr l0e3e l0e4b: inc de ld a,(de) cp '''' jr z,l0e46 jr l0e29 l0e53: call l0268 ; Skip to end of line ld de,l0118+1 ; Point to keyboard line and a sbc hl,de ld b,l jp z,l0105 ret ; ; ; l0e61: push bc push de push hl ex af,af' l0e65: call l019f call z,l022f ; Put blanks to console call l0232 ; Put blank to console ld de,0 ; Init count l0e71: ld a,(hl) inc hl call l01da ; Put hex byte to console call l0232 ; Put blank to console dec bc inc e ; Update count ld a,e cp l0010 jr z,l0e89 and 00000011b call z,l0232 ; Put blank to console ld a,b or c jr nz,l0e71 l0e89: call l0232 ; Put blank to console and a sbc hl,de l0e8f: ld a,(hl) call l0eac ; Map non printable character call l01ef ; Put to console inc hl dec e jr nz,l0e8f ex af,af' jr nc,l0ea0 ld (l0e15),hl l0ea0: ex af,af' call l0236 ; Close console ld a,b or c jr nz,l0e65 pop hl pop de pop bc ret ; ; Map non printable character ; ENTRY Accu holds character ; EXIT Accu holds dot if character unprintable ; l0eac: and NOMSB ; Mask hi bit cp DEL ; Test DELete jr z,l0eb5 ; It's not printable cp ' ' ; Test range ret nc l0eb5: ld a,'.' ; Map it ret ; ; Command F: Specify filename ; Command I: Input CCP command line ; l0eb8:: push de ld hl,CCP+1 ; Point to CCP line ld (hl),' ' ; Set blank on first position inc hl l0ebf: ld a,(de) ld (hl),a ; Unpack command line inc hl inc de and a jr nz,l0ebf ld a,l sub CCP+2 ; Calculate length of line ld (CCP),a ; Stre it pop hl ; Get back name pointer ld de,FCB call l0ed6 ; Parse first file ld de,FCB+DIRlen ; The second one l0ed6: call l0ee8 jp l0cfa ; Parse file ; ; Test special delimiter ; ENTRY Reg HL points to character ; EXIT Carry flag set if printable ; l0edc: ld a,(hl) ; Get character cp '.' ; Filter special ret z ; Carry also reset cp '/' ret z cp ' '+1 ; Test printable ccf ret ; ; ; l0ee7: inc hl l0ee8: ld a,(hl) cp '/' jr z,l0efa cp '=' jr z,l0ee7 cp ',' jr z,l0ee7 cp ' ' jr z,l0ee7 ret l0efa: ld a,(hl) cp ' '+1 jr c,l0ee8 inc hl jr l0efa ; ; Command R [displacement]: Read disk file ; l0f02:: call l0364 jr nc,l0f0a ld hl,l0000 l0f0a: call l0268 ; Skip to end of line ; ; Load file given as start parameter into memory ; ENTRY Reg HL holds offset ; l0f0d: push hl ld hl,0 ld (l1065),hl ; Init highest address by this session sub a ld (FCB+_EX),a ; Clear extent ld (FCB+_CR),a ; Clear current record ld de,DMA ld c,.setdma call CDOS ; Set disk buffer ld de,FCB ld c,.open call CDOS ; Open file cp IOerr ; Test success jp z,l0105 ; Nope, error ld hl,FCB+.drv+.nam ld de,l0f60 ld b,.ext call l102c ; Test HEX file pop hl jr z,l0f63 ; Yeap ; ; Load .COM file ; ld de,l0100 add hl,de ; Build start address push hl l0f43: call l0fe6 ; Read record from file jr z,l0f59 ; End of file pop hl ld de,DMA ; Init buffer ld b,reclng ; Set length of buffer l0f4e: ld a,(de) ; Get byte call l0ffb ; Store it inc de inc hl djnz l0f4e ; Go thru buffer push hl jr l0f43 ; Read next l0f59: pop hl call l0549 jp l1034 ; Print load values ; l0f60: db 'HEX' ; ; Load .HEX file ; l0f63: push hl ld a,reclng ld (l0fe5),a ; Force read l0f69: call l0fca ; Read character from file jr z,l0f9f ; End of file cp ':' ; Test start of HEX record jr nz,l0f69 ; Nope, wait for it ld c,0 ; Init checksum call l0fa3 ; Get byte count ld b,a call l0fa3 ; Get address ld h,a call l0fa3 ld l,a ld a,b ; Get byte count and a ; Test end of file jr z,l0f9f ; Yeap call l0fa3 ; Skip record type l0f87: call l0fa3 ; Get data byte pop de push de push hl add hl,de call l0ffb ; Store byte pop hl inc hl djnz l0f87 call l0fa3 ; Get checksum ld a,c and a ; Verify correct one jp nz,l0105 ; Nope, error jr l0f69 l0f9f: pop hl jp l1034 ; Print load values ; ; Read byte from HEX file ; EXIT Accu holds byte ; l0fa3: call l0fb4 ; Get hi nybble rlca rlca rlca rlca ld d,a ; Save it call l0fb4 ; Get low nybble add a,d ; Insert hi part ld d,a add a,c ; Update checksum ld c,a ld a,d ret ; ; Read nybble from HEX file ; EXIT Accu holds nybble ; l0fb4: call l0fca ; Read character from file jr z,l0fc7 ; End of file sub '0' ; Validate range jr c,l0fc7 ; Error cp 9+1 ret c sub 'A'-'0'-10 jr c,l0fc7 cp 15+1 ret c l0fc7: jp l0105 ; ; Read character from HEX file ; EXIT Accu holds character ; Zero flag set on end of file ; l0fca: ld a,(l0fe5) ; Get record pointer cp reclng ; Test buffer read jr nz,l0fd6 ; Nope call l0fe6 ; Read record from file ret z ; End of file sub a l0fd6: inc a ld (l0fe5),a ; Update record pointer push hl add a,DMA-1 ; Build address ld l,a ld h,0 ld a,(hl) ; Get character pop hl cp eof ; Test for end of file ret ; l0fe5: db 0 ; HEX file record pointer ; ; Read record from file ; EXIT Zero flag set on end of file ; l0fe6: push hl push de push bc ld de,FCB ld c,.rdseq call CDOS ; Read record dec a ; Test EOF jr z,l0ff7 ; Yeap jp p,l0105 ; Error l0ff7: pop bc pop de pop hl ret ; ; Store byte into memory ; ENTRY Accu holds byte ; l0ffb: push af push de ld de,l0100 call l0274 ; Compare jp c,l0105 ; HL=DE ld de,(l1065) ; Get highest address by this session call l0274 ; Compare jr c,l101c ; HL