; ; assembler to check out the 8MHz CPU ; port equ 0ffh ; switches and lights ramrom equ 0feh ; RAM/ROM enable ; adat equ 0 ; data, port A bdat equ adat+1 ; data, port B acon equ adat+2 ; control, port A bcon equ adat+3 ; control, port B ; org 0 ; start: di ld sp,0f000h ;put SP in RAM ; ;************************************** ;* * ;* initialize the SIO/2 at 9600 N81 * ;* * ;************************************** ; ld c,acon ; set up (C) for init. ld b,9 ; send 9 bytes ld hl,iport ; channel init. bytes call ichan ld c,bcon ; set up (C) for init. ld b,9 ; send 9 bytes ld hl,iport ; channel init.bytes call ichan jp smon ; start the monitor ; iport: db 18h,4,0c4h,3,0c1h,5,68h,1,0 ; ichan: ld de,0d000h ; stall ich1: inc de ld a,d or e jr nz,ich1 outi ; send a byte jp nz,ichan ret ; ; *************************************** ; **** SOFTIM: Z80 SOFTWARE TIMER **** ; **** WRITTEN BY: DAN TERPSTRA **** ; ***** CHEMISTRY DEPARTMENT ***** ; ** FLORIDA STATE UNIVERSITY ** ; ***************************** ; ; The execution time of this routine is given by: ; T = (N+2)*40 ; where T is the time in t-states, and N is the 3 byte ; (positive integer) delay quantity obtained from memory ; locations LODELA, HIDELA. To calculate the time in ; seconds, multiply the number of t-states by the time of ; one clock cycle (e.g. 4 MHz = 250 ns/cycle). This ; timing assumes memory that operates with no wait ; states. The minimum time of execution for a 4 MHz Z80 ; is 30 usec for N = 1 (including the CALL and RET ; sequence), increasing in steps of 10 usec to a maximum ; of over 160 sec. N = 0 is undefined, and N = ; FFFFFF(HEX) is the maximum time period. There is NO ; software jitter in this timing loop. ; ; ;main: ; ld hl,(lodela) ;low order count word ; ld a,(hidela) ;high order count byte ; call softim ;time it ; ...continue with program... ; ret ; ; SOFTIM SUBROUTINE ; ; entry conditions: ; a, hl = 24 bit positive count ; exit conditions: ; a = b = hl = 0 ; modifies: ; a, b, hl ; softim: inc a ;at least one pass ld b,a ;through outer loop ld a,0 ;dummy instructions jp softm2 ;to kill time softm1: jr softm2 ;delay 16 T states softm2: nop softm3: dec hl ;decrement low order ld a,l or h ;hl = 0? jp nz,softm1 ;no, look again dec b ;b = zero? jr nz,softm3 ;no, repeat outer loop ret ;yes, return ; ; storage locations for 24-bit time delay word ;lodela: ds 2 ;low order 16 bits ;hidela: ds 1 ;high order 8 bits ; ;**************************** ;* * ;* tenth second delay * ;* * ;**************************** stall: ld hl,(lwp1s) ld a,(ubp1s) call softim ret ; lwp1s: dw 270eh ; lower word of .1 sec. delay ubp1s: db 0 ; upper byte of .1 sec. delay ; ;********************************************** ;* * ;* S. D. Systems Z-80 Monitor for the SBC-200 * ;* * ;********************************************** ; smon: ld hl,0ff60h ld (0ffe6h),hl xor a ld (0ffc0h),a ld (0fffah),a ld a,1 ld (0ffc6h),a init0: ld sp,0ffc0h call crlf ; CR/LF ld c,'.' call print ; print call inandpr ; input & display cp '.' jr z,init0 push bc call space ; space call e784 pop bc ld a,c ld hl,init0 ; set return to push hl ; command loop ld hl,(0ffd2h) ld de,(0ffd0h) ld iy,0ffc0h ; ; At this point, the command arguments can be found in ; de (#1), hl (#2), 0ffd4 (#3), 0ffd6 (#4), 0ffd8 (#5), ; etc., with the arg. count in 0ffc7. ; ; Is it a 'B' -- Breakpoint? ; cp 'B' jr nz,tryG ; no, try 'G' brkpt: push de ld a,(0ffc0h) bit 0,a jr z,brkpt1 ld de,(0ffc4h) ld hl,0ffc1h ld bc,003 ldir xor a ld (0ffc0h),a brkpt1: ld a,(0ffc7h) and a pop hl jr z,brkpt2 brkpt1a: ld (0ffc4h),hl push hl ld de,0ffc1h ld bc,3 push bc ldir ld hl,brkpt3 pop bc pop de ldir ld a,1 ld (0ffc0h),a brkpt2: ret ; brkpt3: jp e591 ; ; Is it a 'G' -- Go? ; tryG: cp 'G' jr nz,tryR ; no, try 'R' ld a,(0ffc7h) and a jr z,go1 ld (0fffeh),de pop af go1: ld a,1 ld (0ffc9h),a jp e5d2 ; ; Is it an 'R' -- Read? ; tryR: cp 'R' jr nz,tryW ; no, try 'W' ld c,0 jp dio ; ; Is it a 'W' -- Write? ; tryW: cp 'W' jr nz,tryZ ; no, try 'Z' ld c,1 ; dio: ld a,(0ffc7h) cp 5 jp nz,inerr dio2: ld a,l out (selr),a dio3: ld a,(0ffd6h) out (sect),a ld h,d ld l,e ld a,(0ffd8h) ld b,a xor a cp c jp z,dio4 call dw jp dio5 dio4: call dr dio5: ld a,(0ffd8h) dec a jp z,init0 ld (0ffd8h),a ld a,(0ffd6h) inc a ld (0ffd6h),a cp maxsect jp c,dio3 ld a,1 ld (0ffd6h),a ld a,l bit 2,l jp nz,dio6 set 2,l jp dio2 dio6: res 2,l ld a,(0ffd4h) inc a ld (0ffd4h),a jp dio2 ; ; Is it a 'Z' -- Format (IBM 3740)? ; tryZ: cp 'Z' jr nz,tryQ ; no, try 'Q' ld a,(0ffc7h) dec a jp nz,inerr ld a,e ld (42h),a xor a ld (44h),a inc a ld (43h),a call 0f018h z1: in a,(63h) or 'P' out (63h),a call 0f033h call e125 jr z,z2 res 4,a out (63h),a call 0f033h z2: call e12a jr nz,z1 jp 0f018h ; e125: in a,(63h) bit 5,a ret ; e12a: ld a,(44h) inc a ld (44h),a ld b,a ld a,(0f040h) cp b ret ; ; Is it a 'Q' -- ? ; tryQ: cp 'Q' jr nz,tryM ld a,e ld (42h),a q1: xor a ld (44h),a q2: ld a,1 ld (43h),a ld a,(0f03fh) ld b,a call e125 jr z,q3 sla b q3: ld a,b ld (45h),a ld hl,100h ld (40h),hl call 0f02dh call e57c call e12a jr nz,q2 ld c,'P' call print jr q1 ; ; Is it an 'M' -- Move memory? ; tryM: cp 'M' jr nz,tryC ; no, try 'C' call e589 ld b,h ld c,l ex de,hl ld de,(0ffd4h) or a sbc hl,de jr nc,m1 ld hl,(0ffd4h) add hl,bc dec hl ld d,h ld e,l ld hl,(0ffd2h) lddr jr m2 ; m1: ld hl,(0ffd0h) ldir m2: ret ; ; Is it a 'C' -- Boot CP/M? ; tryC: cp 'C' jp z,0f003h ; yes, jump to boot ; ; Is it an 'H' -- Hex arithmetic? ; tryH: cp 'H' jr nz,tryX ; no, try 'X' push hl add hl,de ld c,'+' call print call prnthl call space pop hl ex de,hl or a sbc hl,de ld c,'-' call print call prnthl jp init0 ; ; Is it an 'X' -- Display registers? ; tryX: cp 'X' jr nz,tryI ; no, try 'I' xor a cp e call nz,prhead ld a,(0ffc7h) cp 2 jr nz,regs1 ld a,(0ffd2h) ld (0ffc6h),a regs1: jp e646 ; ; Is it an 'I' -- Input? ; tryI: cp 'I' jr nz,tryO ; no, try 'O' res 0,(iy+0ah) ld a,(0ffd0h) ld c,a ld b,1 ld a,(0ffc7h) cp 2 jr c,inp1 ld a,(0ffd2h) ld b,a or a jr nz,inp1 set 0,(iy+0ah) inp1: ld a,c call prntasp in a,(c) call prntasp call e57c push bc call crlf pop bc bit 0,(iy+0ah) jr nz,inp1 djnz inp1 ret ; ; Is it an 'O' -- Output? ; tryO: cp 'O' jr nz,tryF ; no, try 'F' res 0,(iy+0ah) ld a,(0ffd0h) ld c,a ld a,(0ffd2h) ld d,a ld b,1 ld a,(0ffc7h) cp 3 jr c,out1 ld a,(0ffd4h) ld b,a or a jr nz,out1 set 0,(iy+0ah) out1: out (c),d call e57c bit 0,(iy+0ah) jr nz,out1 djnz out1 ret ; ; Is it an 'F' -- Fill? ; tryF: cp 'F' jr nz,tryL ; no, try 'L' ld a,(0ffd4h) push hl call e589 pop hl fill1: ld (de),a push hl or a sbc hl,de pop hl inc de jr nz,fill1 ret ; ; Is it an 'L' -- Locate string? ; tryL: cp 'L' jr nz,tryV ; no, try 'V' call e589 ld a,(0ffc7h) sub 3 jp c,inerr ld b,a inc a ld (0ffc7h),a ld hl,0ffd5h ld de,0ffd6h loc1: ld a,(de) ld (hl),a inc hl inc de inc de djnz loc1 loc4: ld a,(0ffc7h) ld b,a ld hl,(0ffd0h) ld de,0ffd4h loc2: ld a,(de) cp (hl) jr nz,loc3 inc hl inc de djnz loc2 ld hl,(0ffd0h) call prnthl call crlf call e57c loc3: ld hl,(0ffd2h) ld de,(0ffd0h) or a sbc hl,de ret z inc de ld (0ffd0h),de jr loc4 ; ; Is it a 'V' -- Verify memory? ; tryV: cp 'V' jr nz,tryT ; no, try 'T' call e589 push hl pop bc ex de,hl ld de,(0ffd4h) v1: ld a,(de) cpi inc de jr nz,v2 ret po jr v1 ; v2: push af push bc push de dec hl call prnthl ld a,(hl) inc hl call prntasp pop de push de push hl ex de,hl dec hl call prnthl ld a,(hl) call prnta call crlf pop hl pop de pop bc pop af ret po call e57c jr v1 ; ; Is it a 'T' -- Test memory? ; tryT: cp 'T' jr nz,tryD ; no, try 'D' ex de,hl inc de ld b,0 t1: ld hl,(0ffd0h) t2: ld a,l xor h xor b ld (hl),a inc hl push hl or a sbc hl,de pop hl jr nz,t2 ld hl,(0ffd0h) t3: ld a,l xor h xor b cp (hl) call nz,e318 inc hl push hl or a sbc hl,de pop hl jr nz,t3 inc b call e57c ld c,'P' call print jr t1 ; e318: push af call prnthl pop af call prntasp ld a,(hl) call prntasp jp crlf ; ; Is it a 'D' -- Dump memory? ; tryD: cp 'D' jp nz,tryE ; no, try 'E' res 0,(iy+0ah) ex de,hl ld a,(0ffc7h) cp 2 jr nc,d2 d1: ld de,0ffh push hl add hl,de ld (0ffd2h),hl pop hl d2: call crlf push hl pop bc push hl ld hl,(0ffd2h) or a sbc hl,bc jp c,inerr ld bc,0fh or a sbc hl,bc ld b,10h jr z,d3 jp nc,d3a ld a,l add a,b ld b,a d3: set 0,(iy+0ah) d3a: pop hl push bc call prnthl pop bc call e666 call e57c bit 0,(iy+0ah) jr z,d2 d4: call status jr z,d4 call input cp '.' ret z cp ' ' jr nz,d4 res 0,(iy+0ah) call crlf jr d1 ; ; Is it an 'E' -- Examine memory? ; tryE: cp 'E' jp nz,tryP ; no, try 'P' ex de,hl e1: call prnthl ld a,(hl) call prnta ld c,'-' call print push hl call e784 pop hl ld a,(0ffc8h) cp '.' ret z ld a,(0ffc7h) and 3 jr z,e3c1 ld a,(0ffd0h) ld (hl),a inc hl ld a,(0ffc8h) cp 0dh jr z,e1 e2: dec hl jr e1 ; e3c1: ld a,(0ffc8h) cp '^' jr z,e2 inc hl jr e1 ; ; Is it a 'P' -- Examine port? ; tryP: cp 'P' jr nz,tryU ; no, try 'U' ld a,(0ffd0h) ld c,a p1: ld a,c call prntasp in a,(c) call prntasp push bc call e784 pop bc ld a,(0ffc8h) cp '.' ret z ld h,a ld a,(0ffc7h) and a jr z,e3fb ld a,(0ffd0h) out (c),a ld a,'^' cp h jr z,p1 p2: inc c jr p1 ; e3fb: ld a,'^' cp h jr nz,p2 dec c jr p1 ; ; Is it a 'U' -- Relocate to RAM ; tryU: cp 'U' jr nz,tryY ; no, try 'Y' ; ; relocate ROM based part of ; this thing to RAM ; ld hl,0 ld de,8000h ld bc,1000h ldir jp higher+8000h ; ; turn on RAM, clear it, and move ; myself back to 0000h. ; higher: ld a,0ffh ; toggle RAM/ROM out (ramrom),a ld hl,0 hghr1: ld a,0 ld (hl),a inc hl ld a,h cp 80h jr nz,hghr1 ; ld hl,8000h ld de,0 ld bc,1000h ldir ; jp smon ; ; Is it a 'Y' -- Download a .HEX file ; tryY: cp 'Y' jp nz,tryS ; dwnhx: ld hl,bgnmsg call pstrng call crlf doline: call rgetch cp ':' jp nz,doline call getbyte ; count byte ld a,c cp 0 ; zero count is end jp z,finish ld b,c push af call getbyte ; addr msb pop af ld h,c add a,c push af call getbyte ; addr lsb pop af ld l,c add a,c push af call getbyte ; record type pop af add a,c datlp: push af call getbyte ; data byte pop af ld (hl),c inc hl add a,c djnz datlp push af call getbyte ; checksum byte pop af add a,c jp nz,err jp doline ; ; eoj is here ; finish: call crlf call prnthl ld hl,good call pstrng jp init0 good: db 'Good load!',3 bdcksm: db 'Bad checksum.',3 bdchar: db 'Non-hex char.',3 bgnmsg: db 'Start download.',3 err: call crlf ld hl,bdcksm call pstrng jp init0 err1: call crlf ld hl,bdchar call pstrng jp init0 ; ; character i/o routines ; rgetch: call status jp z,rgetch in a,(adat) and 7fh push bc ld c,a call print ld a,c pop bc ret ; getbyte: call chrcnv rla rla rla rla ld c,a call chrcnv or c ld c,a ret ; chrcnv: call rgetch cp '0' jp c,err1 cp ':' jp c,num cp 'A' jp c,err1 cp 'G' jp nc,err1 sub 7 ; look at e728? ; num: sub 30h ret ; ; Is it an 'S' -- Single step? ; tryS: cp 'S' jr z,onestep ; yes, do it inerr: ld c,'?' ; command not call print ; recognized jp init0 ; error ; ; Do single step ; onestep: pop af call prhead ld a,(0ffc7h) and a jr z,s1 ex de,hl ld (0fffeh),hl s1: ld a,(0ffd2h) and a jr nz,s2 inc a s2: ld (0ffc9h),a xor a ld (0ffc7h),a call brkpt ld de,(0fffeh) ld a,(de) cp '@' jr c,s3 cp 0c0h jp c,e511 s3: and 3 ld b,a ld a,(de) rra rra and 1fh push bc ld bc,e558 add a,c ld l,a ld h,b pop bc ld a,(hl) inc b s4: djnz e479 and 3 jp z,e4fc push af ld a,(de) ld hl,(0fff4h) cp 0e9h jp z,e5c5 cp 0c3h jr z,e4d3 cp 0cdh jr z,e4d3 cp 0c9h jr z,e4ca cp 10h jr nz,e47f ld hl,0fff9h dec (hl) jr nz,e4bc inc (hl) s5: jp e532 ; e479: srl a srl a jr s4 ; e47f: cp 18h jr z,e4bc cp 80h jr nc,e491 xor ' ' ld b,a and 'g' jr nz,s5 ld a,b jr e49e ; e491: and 0c7h cp 0c2h jr z,e49d and 0c3h cp 0c0h jr nz,e4e0 e49d: ld a,(de) e49e: and '0' ld hl,e577 e4a3: inc hl sub 10h jr nc,e4a3 ld a,(0fffch) and (hl) ld a,(de) jr z,e4b0 cpl e4b0: bit 3,a jr nz,s5 pop af push af cp 2 jr c,e4ca jr nz,e4d3 e4bc: inc de ld a,(de) inc de ld l,a rla ld h,0 jr nc,e4c6 dec h e4c6: add hl,de jr e4f9 ; e4c9: dec de e4ca: ld hl,(0ffe6h) ld a,(hl) inc hl ld h,(hl) ld l,a jr e537 ; e4d3: ld a,(de) bit 2,a inc de ld a,(de) ld l,a inc de ld a,(de) ld h,a jr nz,e537 jr e4f9 ; e4e0: ld a,(de) and 0c7h cp 0c7h ld a,(de) jr nz,e4ef and '8' ld l,a ld h,0 jr e537 ; e4ef: cp 0fbh jr nz,e532 cpl ld (0fffah),a ex de,hl inc hl e4f9: jp e5c5 ; e4fc: ld a,(de) inc de cp 0edh jr nz,e515 ld b,3 ld a,(de) and 0f7h cp 'E' jr z,e4c9 and 0c7h cp 'C' jr z,e533 e511: ld b,1 jr e533 ; e515: cp 0ddh ld hl,(0ffeah) jr z,e51f ld hl,(0ffe8h) e51f: ld a,(de) cp 0e9h jr z,e4f9 ld hl,e553 ld bc,5 cpir jr nz,e53d inc b e52f: inc b e530: inc b push bc e532: pop bc e533: ex de,hl e534: inc hl djnz e534 e537: call brkpt1a jp e5d2 ; e53d: and 0feh cp '4' jr z,e52f ld a,(de) and 7 cp 6 jr z,e52f ld a,(de) and 0f8h cp 'p' jr z,e52f jr e530 ; e553: ld hl,2a22h ld (hl),0cbh e558: ld e,l ld h,l ld d,l ld h,l ld e,(hl) ld h,l ld d,(hl) ld h,l ld a,(hl) ld h,l halt ; e563: ld h,l ld a,(hl) ld h,l halt ; e567: ld h,l push af ld h,a or l ld l,a or l ld h,a or l ld h,e ld (hl),l ld h,a ld (hl),l ld h,e ld (hl),l ld h,a ld (hl),l e577: ld h,e ld b,b ld bc,8004h e57c: call status ret z call input cp '.' ret nz jp init0 ; e589: or a sbc hl,de jp c,inerr inc hl ret ; e591: ld (0ffe6h),sp ld sp,0 push af push af or a ld a,i push af di push bc push de push hl exx ex af,af' push af push bc push de push hl ld a,(0fffah) and 4 ld (0fffah),a exx ex af,af' push ix push iy ld hl,0ffc1h ld de,(0ffc4h) ld bc,3 ldir ld hl,(0ffc4h) e5c5: ld a,80h ld (0ffc0h),a ld (0fffeh),hl ld sp,0ffc0h jr e604 ; e5d2: ld sp,(0ffe6h) ld hl,(0fffeh) push hl ld hl,(0fffch) push hl ld (0ffe4h),sp ld sp,0ffe8h pop iy pop ix exx ex af,af' pop hl pop de pop bc pop af exx ex af,af' pop hl pop de pop bc pop af ld i,a ld sp,(0ffe4h) jp pe,e601 pop af di ret ; e601: pop af ei ret ; e604: call e646 ld a,(0ffc0h) ld b,a xor a ld (0ffc0h),a ld hl,0ffc9h dec (hl) jr z,e61c call status jr nz,e61c jr e63f ; e61c: call inandpr cp '.' jp z,init0 cp 0dh jr z,e63d cp ' ' jr nz,e61c xor a cp (hl) ld (hl),0 jr nz,e61c call crlf call prhead ld a,0bh jp s2 ; e63d: ld (hl),1 e63f: call crlf ld a,(hl) jp s2 ; e646: ld hl,(0fffeh) call prnthl ld a,(0ffc6h) rra ld b,1 jr nc,e656 ld b,0ch e656: ld hl,0fffdh e659: ld a,(hl) call prnta dec hl ld a,(hl) call prntasp dec hl djnz e659 ret ; e666: push bc push hl e668: ld a,(hl) call prntasp inc hl djnz e668 call space call space pop hl pop bc e677: ld a,(hl) and 7fh ld c,a cp ' ' jr c,e683 cp '{' jr c,e685 e683: ld c,'.' e685: call print inc hl djnz e677 ret ; headx: db ' PC AF I IF BC DE HL A' db 27h,'F',27h,' B',27h,'C',27h,' D' db 27h,'E',27h,' H',27h,'L',27h db ' IX IY SP',0dh,0ah,3 ; ; get serial port status ; status: in a,(acon) ; status and 1 ; (A)=0, not ready ret z ; (A)<>0, ready ld a,0ffh ret ; ; load a character ; input: call status ; input jp z,input in a,(adat) and 7fh cp 60h ; take care of a->f ret c and 5fh ; map to upper case ret ; ; send a character ; print: in a,(acon) ; check tx empty bit 2,a ; bit in D2 jp z,print ; zero means not empty, wait ; ld a,c ; get character to print out (adat),a ; send it out ret ; prntasp: push bc ; print (A) and a space call prnta call space pop bc ret ; crlf: ld c,0dh ; CR/LF call print ld c,0ah jp print ; space: ld c,' ' ; SPACE jp print ; prhead: ld hl,headx ; register header pstrng: ld a,(hl) ; print string that cp 3 ; (HL) points to ret z ld c,a call print inc hl jp pstrng ; prnta: push af rrca rrca rrca rrca call cnv4pr pop af cnv4pr: and 0fh add a,90h daa adc a,'@' daa ld c,a jp print ; e728: sub '0' cp 0ah ret m sub 7 ret ; e730: cp '0' jp c,e746 cp ':' jp c,e744 cp '@' jp c,e746 cp 'G' jp nc,e746 e744: xor a ; a=0 ret ; e746: xor a ; a=1 inc a ret ; e749: cp ' ' ret z cp '^' jp z,e759 cp '.' jp z,init0 cp 0dh ret nz e759: push bc call crlf pop bc xor a ret ; e760: ld hl,0 ld b,l e764: call inandpr inc b call e749 ret z call e730 ret nz ld a,c call e728 add hl,hl add hl,hl add hl,hl add hl,hl add a,l ld l,a jp e764 ; inandpr: call input ld c,a jp print ; e784: xor a ld hl,0ffd0h push hl pop ix ld (hl),a ld bc,9 ld de,0ffd1h ldir ld (0ffc7h),a e797: call e760 jp nz,inerr ld a,c ld (0ffc8h),a cp ' ' jr z,e7a7 dec b ret z e7a7: ld (ix+0),l ld (ix+1),h ld a,(0ffc7h) inc a ld (0ffc7h),a inc ix inc ix ld a,c cp ' ' jr z,e797 ret ; prnthl: ld a,h call prnta ld a,l jp prntasp ; ; diskette interface ; cr equ 0dh lf equ 0ah maxsect equ 8 ; ; disk commands ; seek equ 11h ;seek wtrak equ 0f4h ;write track restore equ 1 ;restore sectrd0 equ 82h ;read sector side zero sectrd1 equ 8ah ;read sector side one sectwr0 equ 0a2h ;write sector side zero sectwr1 equ 0aah ;write sector side one ; cmd equ 4 ;command register track equ cmd + 1 ;track register sect equ cmd + 2 ;sector register dal equ cmd + 3 ;data port selr equ 0ffh ;status/select register wait equ selr ; DRQ/IRQ bits ; ; I/O from/to 0ffh is defined as: ; ; input -> I D output -> D D S S S ; R R T E I E E ; Q Q P N D L L ; - - - - - - - ; 1 0 4 3 2 1 0 ; ; disk write ; dw: ld a,(0ffd4h) call seekr ;position the head ; wrsec: ld h,d ld l,e ld a,(0ffd6h) out (sect),a ld a,(0ffd2h) bit 2,a jr nz,sid1 ld a,sectwr0 jr continu sid1: ld a,sectwr1 continu: di ld c,dal out (cmd),a nxtby: in a,(wait) bit 0,a jp nz,wod ; bit 1,a jp nz,donesect jp nxtby ; wod: outi jp nxtby ; ; disk read ; dr: ld a,(0ffd4h) ;go to track call seekr xor a ;reset retry indicator ld (rtry),a retry: ld h,d ld l,e ld a,(0ffd6h) ;set sector out (sect),a ld c,dal ld a,(0ffd2h) bit 2,a jr z,side0 ld a,sectrd1 ;read side one jr startrd side0: ld a,sectrd0 ;read side zero startrd: di ;no outside interference out (cmd),a ;do sector read nextbyte: in a,(wait) ;wait for operation complete and 1 jr nz,rid in a,(wait) and 2 jr nz,donesect jr nextbyte rid: nop ini ;read data jr nextbyte ;get next byte ; donesect: ei ;can now be bothered again ld d,h ;copy back buffer addr. ld e,l in a,(cmd) ;get status ld (fdcst),a ;save away or a ;error? jr nz,failed ;process error case ; ld a,(rtry) ;see if any retries performed or a call prnta ret ;no, successful i/o ld hl,rtmsg ;warn about retries call pstrng ; ret jp init0 ; ; process error accordingly ; failed: ld a,(rtry) ;increment retry inc a ld (rtry),a cp 10 jp c,retry ; ; 10 retries failed, report fatal error ; push hl ;preserve hl ld hl,msg8 call pstrng ld a,(fdcst) call determerr ;print appropriate error msg. ; ld hl,msg4 call pstrng ld a,(0ffd2h) and 4 rra rra call prnta ld hl,msg5 call pstrng pop hl ld a,(0ffd4h) ;track push hl call prnta ;print track number ld hl,msg6 call pstrng ld a,(0ffd6h) ;sector call prnta ;print sector number ld hl,msg7 call pstrng ld a,(fdcst) ;get status call prnta ;print status ; ; ask user for help to decide what to do next ; errin: ld hl,msg9 call pstrng call rgetch cp '.' jp z,abort ;exit option cp 'R' ;retry? jr nz,errin ; retry read jp dr ;read sector again ; determerr: push hl ld b,a and 80h jr z,dte1 ld hl,msg10 call pstrng ;drive not ready jr exitd dte1: ld a,b and 40h jr z,dte2 ld hl,msg11 call pstrng ;write protect jr exitd dte2: ld a,b and 20h jr z,dte3 ld hl,msg12 call pstrng ;write fault jr exitd dte3: ld a,b and 10h jr z,dte4 ld hl,msg13 call pstrng ;record not found jr exitd dte4: ld a,b and 8 jr z,dte5 ld hl,msg14 call pstrng ;CRC error jr exitd dte5: ld a,b and 4 jr z,dte6 ld hl,msg15 ;lost data call pstrng jr exitd dte6: ld a,b and 2 jr z,exitd ld hl,msg16 ;data request call pstrng exitd: pop hl ret ; abort: ld hl,abtmsg call pstrng jp init0 ; seekr: ld b,a xor a ld (rtry),a skr1: ld a,b out (dal),a ld a,seek out (cmd),a skr2: in a,(wait) bit 1,a jr z,skr2 in a,(cmd) and 10h ret z ld a,(rtry) inc a ld (rtry),a cp 20h jr nc,skr1 ld hl,skmsg call pstrng jp init0 ; rtry: db 0 fdcst: db 0 side: db 0 sectno: db 0 trkn: db 0 ; ; messages ; msg4: db cr,lf,'side= ',3 msg5: db ', track= ',3 msg6: db ', sector= ',3 msg7: db ', status= ',3 msg8: db cr,lf,lf,'fatal read verify error detected: ',3 msg9: db cr,lf,lf,'option ("." to Exit or R to Retry)?',3 msg10: db 'drive not ready',3 msg11: db 'disk is write protected',3 msg12: db 'write fault',3 msg13: db 'record not found',3 msg14: db 'CRC error',3 msg15: db 'lost data',3 msg16: db 'data request',3 abtmsg: db cr,lf,'Disk Read Aborted.',3 rtmsg: db cr,lf,'Good Sector, with retries.',3 skmsg: db cr,lf,'Seek failed.',3 end