title 'LDRBIOS for CP/M 3.0' .z80 cr equ 13 lf equ 10 ntry equ 4 ; number of retries for disk read external adrv,dskdef ; drive & disk tables origin equ 0E000H djboot equ origin ;Disk Jockey 2D cold boot djcin equ origin+3h ;Disk Jockey 2D character input routine djcout equ origin+6h ;Disk Jockey 2D character output routine djhome equ origin+9h ;Disk Jockey 2D track zero seek djtrk equ origin+0ch ;Disk Jockey 2D track seek routine djsec equ origin+0fh ;Disk Jockey 2D set sector routine djdma equ origin+12h ;Disk Jockey 2D set DMA address djread equ origin+15h ;Disk Jockey 2D read routine djwrit equ origin+18h ;Disk Jockey 2D write routine djsel equ origin+1bh ;Disk Jockey 2D select drive routine djtsta equ origin+21h ;Disk Jockey 2D terminal status routine djstat equ origin+27h ;Disk Jockey 2D status routine djerr equ origin+2ah ;Disk Jockey 2D error, flash led djden equ origin+2dh ;Disk Jockey 2D set density routine djside equ origin+30h ;Disk Jockey 2D set side routine djleav equ origin+222h ;leave routine in dj rom djprep equ origin+233h ;prep routine in dj rom ; BIOS Jump vector. ?boot: jp boot ; initial entry on cold start ?wboot: jp wboot ; reentry on program exit, warm start ?const: jp const ; return console input status ?conin: jp conin ; return console input character ?cono: jp conout ; send console output character ?list: jp list ; send list output character ?auxo: jp auxout ; send auxilliary output character ?auxi: jp auxin ; return auxilliary input character ?home: jp home ; set disks to logical home ?sldsk: jp seldsk ; select disk drive, return disk parameter info ?sttrk: jp settrk ; set disk track ?stsec: jp setsec ; set disk sector ?stdma: jp setdma ; set disk I/O memory address ?read: jp read ; read physical block(s) ?write: jp write ; write physical block(s) ?lists: jp listst ; return list device status ?sctrn: jp sectrn ; translate logical to physical sector ?conos: jp conost ; return console output status ?auxis: jp auxist ; return aux input status ?auxos: jp auxost ; return aux output status ?dvtbl: jp devtbl ; return address of device def table ?devin: jp cinit ; change baud rate of device ?drtbl: jp getdrv ; return address of disk drive table ?mltio: jp multio ; set multiple record count for disk I/O ?flush: jp flush ; flush BIOS maintained disk caching ?mov: jp move ; block move memory to memory ?tim: jp time ; Signal Time and Date operation ?bnksl: jp bnksel ; select bank for code execution and default DMA ?stbnk: jp setbnk ; select different bank for disk I/O DMA operations. ?xmov: jp xmove ; set source and destination banks for one operation jp fe ; reserved for future expansion jp fe ; reserved for future expansion jp fe ; reserved for future expansion wboot: ; jump vector locations not used const: conin: list: auxout: auxin: write: listst: conost: auxist: auxost: devtbl: cinit: getdrv: multio: flush: time: bnksel: setbnk: xmove: fe: ld hl,msg1 ; error halt call ?pmsg halt msg1: db cr,lf,'CPMLDR failure: unimplemented bios call',cr,lf,0 boot: ld a,1 ; reset output board out (0e1h),a ld a,0 out (0e1h),a ; get disk type - assume reads of a non-zero track have already taken place ; so a dummy read is not necessary - adjust disk tables and set double ; sided indicator call djstat ; get status word ld (dsx),a ; store for double sided indicator rrca ; move right and 16h ; 2 * sec.lng.code + 16 * side.code ld hl,dskdef ; get table of disk table addresses ld b,0 ld c,a add hl,bc ; hl points to address of skew table ld de,adrv ; de points to head of dph ldi ; copy two bytes ldi ld bc,6 add hl,bc ; address of pointer to dpb ld bc,10 ex de,hl add hl,bc ; pointer to dpb in dph ex de,hl ldi ; copy two bytes ldi ret home: call djhome ret seldsk: ld hl,adrv ret settrk: ld b,c ld c,0 ld a,(dsx) ; get status word and 20h ; get bit 5 jr z,ss ; jump if single sided srl b ; divide by 2 rl c ; remainder to c ss: call djside ld c,b call djtrk jr c,lmsg3 ret setsec: call djsec jr c,lmsg3 ret setdma: xor a call djdma and a jr nz,lmsg3 ret lmsg3: ld hl,msg3 call ?pmsg halt msg3: db cr,lf,'CPMLDR failure: disk parameter error',cr,lf,0 read: ld b,ntry ; number of tries cycr: push bc call djread pop bc ld a,0 ret nc djnz cycr ld hl,msg4 call ?pmsg halt msg4: db cr,lf,'CPMLDR error: disk read error',cr,lf,0 sectrn: ex de,hl add hl,bc ld l,(hl) ld h,0 ret conout: in a,(0e1h) ; get status and 1 jr nz,conout ; wait for buffer to clear ld a,c and 7fh ; blank parity out (0e0h),a ; output character ret move: ex de,hl ; we are passed source in DE and dest in HL ldir ; use Z80 block move instruction ex de,hl ; need next addresses in same regs ret ?pmsg: ; print message @ up to a null ld a,(hl) or a ret z ld c,a push hl call ?cono pop hl inc hl jr ?pmsg dsx: ds 1 ; indicator for double sided disks end