title 'Root module of loader BIOS for CP/M 3.0' ; version 1.0 3-30-83 ; this is the root module provided by digital research ; modified for use with cpmldr by Edwin E. Smith ; Tarbell Electronics true equ -1 false equ not true banked equ false ; Copyright (C), 1982 ; Digital Research, Inc ; P.O. Box 579 ; Pacific Grove, CA 93950 ; This is the invariant portion of the modular BIOS and is ; distributed as source for informational purposes only. ; All desired modifications should be performed by ; adding or changing externally defined modules. ; This allows producing "standard" I/O modules that ; can be combined to support a particular system ; configuration. maclib z80 ;use z80 library ; user defined character I/O routines extrn ?co,?cost ; each take device in extrn ?cinit ; (re)initialize device in ; disk communication data items extrn @dtbl ; table of pointers to XDPHs public @adrv,@rdrv,@trk,@sect ; parameters for disk I/O public @dma,@cnt ; '' '' '' '' ; general utility routines public ?pmsg ; print message ; External names for BIOS entry points public ?boot,?cono public ?home,?sldsk,?sttrk,?stsec,?stdma,?read public ?sctrn public ?conos public ?mltio ; BIOS Jump vector. ; All BIOS routines are invoked by calling these ; entry points. ?boot: jmp boot ; initial entry on cold start ?wboot: jmp empret ; reentry on program exit, warm start ?const: jmp empret ; return console input status ?conin: jmp empret ; return console input character ?cono: jmp conout ; send console output character ?list: jmp empret ; send list output character ?auxo: jmp empret ; send auxilliary output character ?auxi: jmp empret ; return auxilliary input character ?home: jmp home ; set disks to logical home ?sldsk: jmp seldsk ; select disk drive, return disk parameter info ?sttrk: jmp settrk ; set disk track ?stsec: jmp setsec ; set disk sector ?stdma: jmp setdma ; set disk I/O memory address ?read: jmp read ; read physical block(s) ?write: jmp empret ; write physical block(s) ?lists: jmp empret ; return list device status ?sctrn: jmp sectrn ; translate logical to physical sector ?conos: jmp conost ; return console output status ?auxis: jmp empret ; return aux input status ?auxos: jmp empret ; return aux output status ?dvtbl: jmp empret ; return address of device def table ?devin: jmp empret ; change baud rate of device ?drtbl: jmp empret ; return address of disk drive table ?mltio: jmp multio ; set multiple record count for disk I/O ?flush: jmp empret ; flush BIOS maintained disk caching ?mov: jmp ?move ; block move memory to memory ?tim: jmp empret ; Signal Time and Date operation ?bnksl: jmp empret ; select bank for code execution and default DMA ?stbnk: jmp empret ; select different bank for disk I/O DMA operations. ?xmov: jmp empret ; set source and destination banks for one operation jmp 0 ; reserved for future expansion jmp 0 ; reserved for future expansion jmp 0 ; reserved for future expansion empret xra a ret ; block move routine bc is byte count ; de is source and hl is destination ?move xchg ;swap source and destination ldir ;do the move xchg ;swap back ret ; BOOT ; Initial entry point for system startup. boot: mvi c,0 ; initialize device 0 console call ?cinit lxi b,0*256+0 lxi h,@dtbl ; init logical disk drive 0 mov e,m inx h mov d,m inx h ; grab @drv entry xchg ; XDPH address in dcx h dcx h mov a,m sta @RDRV ; get relative drive code mov a,c sta @ADRV ; get absolute drive code dcx h ; point to init pointer mov d,m dcx h mov e,m ; get init pointer xchg call ipchl ; call init routine ret ;return to cpmldr ; Console Output. Send character in ; to all selected devices conout: mvi b,0 ;device 0 jmp ?co ; CONOST ; Console Output Status. Return true if ; all selected console output devices ; are ready. conost: mvi b,0 ;device 0 jmp ?cost ; Utility Subroutines ipchl: ; vectored CALL point pchl ?pmsg: ; print message @ up to a null ; saves & push b push d pmsg$loop: mov a,m ora a jz pmsg$exit mov c,a push h call ?cono pop h inx h jmp pmsg$loop pmsg$exit: pop d pop b ret ; Disk I/O interface routines ; SELDSK ; Select Disk Drive. Drive code in . ; Invoke login procedure for drive ; if this is first select. Return ; address of disk parameter header ; in seldsk: mov a,c sta @adrv ; save drive select code mov l,c mvi h,0 dad h ; create index from drive code lxi b,@dtbl dad b ; get pointer to dispatch table mov a,m inx h mov h,m mov l,a ; point at disk descriptor ora h rz ; if no entry in table, no disk mov a,e ani 1 jnz not$first$select ; examine login bit push h xchg ; put pointer in stack & lxi h,-2 dad d mov a,m sta @RDRV ; get relative drive lxi h,-6 dad d ; find LOGIN addr mov a,m inx h mov h,m mov l,a ; get address of LOGIN routine call ipchl ; call LOGIN pop h ; recover DPH pointer not$first$select: ret ; HOME ; Home selected drive. Treated as SETTRK(0). home: lxi b,0 ; same as set track zero ; SETTRK ; Set Track. Saves track address from ; in @TRK for further operations. settrk: mov l,c mov h,b shld @trk ret ;SETSEC ; Set Sector. Saves sector number from ; in @sect for further operations. setsec: mov l,c mov h,b shld @sect ret ; SETDMA ; Set Disk Memory Address. Saves DMA address ; from in @DMA and sets @DBNK to @CBNK ; so that further disk operations take place ; in current bank. setdma: mov l,c mov h,b shld @dma ret ; SECTRN ; Sector Translate. Indexes skew table in ; with sector in . Returns physical sector ; in . If no skew table (=0) then ; returns physical=logical. sectrn: mov l,c mov h,b mov a,d ora e rz xchg dad b mov l,m mvi h,0 ret ; READ ; Read physical record from currently selected drive. ; Finds address of proper read routine from ; extended disk parameter header (XDPH). read: lhld @adrv mvi h,0 dad h ; get drive code and double it lxi d,@dtbl dad d ; make address of table entry mov a,m inx h mov h,m mov l,a ; fetch table entry push h ; save address of table lxi d,-8 dad d ; point to read routine address mov a,m inx h mov h,m mov l,a ;get address of routine pop d ;recover address of table dcx d dcx d ; point to relative drive ldax d sta @rdrv ; get relative drive code and post it inx d inx d ; point to DPH again pchl ;leap to driver ; MULTIO ; Set multiple sector count. Saves passed count in ; @CNT multio: sta @cnt ret ; disk communication data items @adrv ds 1 ; currently selected disk drive @rdrv ds 1 ; controller relative disk drive @trk ds 2 ; current track number @sect ds 2 ; current sector number @dma ds 2 ; current DMA address @cnt db 0 ; record count for multisector transfer end