title 'semidisk handler routines' true equ -1 false equ 0 banked equ true .Z80 entry sinit,slogin,sread,swrite external @trk,@sect,@dma,@ermde external ?pmsg,?pderr,?wboot if banked external @cbnk,@dbnk,?bank endif dseg data equ 80H ; semidisk origin byte equ data+1 trk equ data+2 sect equ data+3 sinit: ; check for board set xor a ; clear a out (trk),a ; track 0 out (sect),a ; sector 0 out (byte),a ; byte 0 in a,(data) ; get first test byte cp 80h ; test value jr nz,clx ; jump to clear board instructions ld a,10h out (byte),a in a,(data) ; second test byte cp 80h ret z ; return if board set clx: ; clear semidisk xor a ; clear a out (byte),a ; start byte count ld d,80h ; parity fill data ld e,a ; initial track call settr ; 2 parity tracks call settr ld d,0e5h ; directory fill data call settr call settr ret settr: ; set track to value in d ld a,e out (trk),a ; set track number inc e ; increment track number xor a ; clear sector counter ld b,10h ; count+sector port sectlp: out (sect),a ; set sector inc a ; increment sector number ld h,b ; store b ld bc,8000h+data ; count+data port bytelp: out (c),d ; enter data djnz bytelp ld b,h ; recover b for outer loop djnz sectlp ret slogin: ret ; no action here sread: call setup if banked jp rl ; jump to common memory else rlu: in d,(c) ld (hl),d add a,d inc hl djnz rlu endif srx: call parity in d,(c) sub d ret z ; normal exit ld a,(@ermde) ; error mode inc a ; if (@ermde==0ffh get zero) jr z,herror ; if error messages are not being sent call ?pderr jp ?wboot herror: inc a ; error indicator = 1 ret swrite: call setup if banked jp wl ; jump to common memory else wlu: add a,(hl) outi jr nz,wlu endif swx: call parity out (c),a xor a ; clear a ret setup: ; setup parameters for read & write ld a,(@trk) out (trk),a ld a,(@sect) out (sect),a ld bc,8000h+data ; count in b, data port in c ld hl,(@dma) xor a ; clear a out (byte),a if banked ld a,(@dbnk) ; bank for read or write endif ret parity: ; get parity word if not banked ld d,a ; keep a endif ld a,(@trk) ; get track ld e,a ; & store in e and 80h ; keep bit 7 rlca ; & move it to bit 1 out (trk),a ; Use it as track number ld a,e ; get track again and 78h ; 01111000 binary rrca ; right shift 3 times rrca rrca out (sect),a ; semidisk sector 0-15 ld a,e ; get track again and 7 ; 00000111 binary rlca ; left shift 4 bits rlca rlca rlca ld e,a ; hold in e ld a,(@sect) ; get sector add a,e ; form byte number out (byte),a ; and pass to semidisk ld a,d ; restore a ret if banked cseg ; read & write in common rl: call ?bank xor a rl1: in d,(c) ; read in byte ld (hl),d ; store in memory add a,d ; add to accumulator for parity inc hl ; inc memory pointer djnz rl1 ; loop until b=0 ld d,a ; keep a ld a,(@cbnk) ; restore bank call ?bank jp srx ; return to banked memory wl: call ?bank xor a wl1: add a,(hl) ; add to accumulator from memory outi ; copy memory to port, inc registers jr nz,wl1 ; loop until b=0 ld d,a ; keep a ld a,(@cbnk) ; restore bank call ?bank jp swx ; return to banked memory endif end