.Z80 ;*************************************************************** ;File: GIDEBIOS.MAC ;Purp: BIOS extension to support the RehDesign GIDE adapter ; on the Davidge DSB 4/6 single-board computer w/v1.3 BIOS ;Auth: John D. Baker ; ; Revsion History: ; ; 9 March 1996 (JDB) ; Revised disk selection/mapping code to account for non- ; sequential hard disk usage. ; ; 18 January 1996 (JDB) ; More code tightening and tweaking. Re-wrote clock driver ; to use RLD instructions. Relocated some data areas above ; clock driver entry point. ; ; 15 January 1996 (JDB) ; Major rewrite. First public release. ; ; 12 January 1996 (JDB) ; Created. ; msize equ 62 ;cp/m version memory size in kilobytes kfrac equ 0 ;number of pages in excess of "msize" ssize equ msize*4+kfrac-10 ;size of this cp/m system in pages ; ; "bias" is address offset from 3400h for memory systems larger ; than 16k (referred to as "b" throughout the text) ; bias equ (ssize-80)*256 ccp equ 3400h+bias ;base of ccp bdos equ ccp+806h ;base of bdos bios equ ccp+1600h ;base of bios cdisk equ 0004h ;current disk number 0=a,...,15=p iobyte equ 0003h ;intel i/o byte ; hstsiz equ 512 ;host sector size nsecs equ (bios-ccp)/128 ;number of sectors for warm boot nhsecs equ nsecs/4 ;number of host sectors wbtdrv equ 'A' ;warmboot from this drive ; BDOSV equ 0005 WBOOTE equ 0000 ;jump here for warm boot ; ; bdos constants on entry to write (passed in C) ; wrall equ 0 ;write to allocated wrdir equ 1 ;write to directory wrual equ 2 ;write to unallocated ; ; ; Definition of used I/O addresses: GIDE equ 20h ; base address of GIDE board RTC equ GIDE+5 ; 72421 register access port ZDTIME equ 0FFF5h ;entry point for CardZ180 OEM ZDDOS clock IdeDOR equ GIDE+6 ; Digital Output Register IdeDat equ GIDE+8 ; Data Register IdeErr equ GIDE+9 ; Error Register IdeWrPc equ IdeErr ; Write Precomp REgister IdeSCnt equ GIDE+0Ah ; Sector Count IdeSNum equ GIDE+0Bh ; Sector Number IdeCLo equ GIDE+0Ch ; Cylinder Low IdeCHi equ GIDE+0Dh ; Cylinder High IdeSDH equ GIDE+0Eh ; Drive and Head IdeCmd equ GIDE+0Fh ; Command IdeStat equ IdeCmd ; Status ; Commands for IDE hard disk drives: CmdRd equ 20h ; Read Sector CmdWr equ 30h ; Write Sector CmdInit equ 91h ; Initialize Drive Params ; TPA equ 0100h ;start here FBTOP equ bios + 0F16h ;top of davidge floppy-disk BIOS systop equ ZDTIME ;don't go higher than this xtrspc equ ZDTIME+3 ;unless it's here HDBIOS equ 0F720h ;this is where our stuff loads if (HDBIOS - FBTOP) gt 07fffh .printx " *** MSIZE too large! *** " endif prntstr equ 9 ;CP/M print string ASEG org TPA ;duh! ld (oldstack),sp ;save stack pointer ld sp,biosstk ;set up local stack ; ld de,signmsg ;point at signon message ld c,prntstr ;print string in C call BDOSV ;sign on ; ld a,bios/256 ;check for size ld hl,(WBOOTE+1) ;get Warm boot sub h ;compare jr c,toosmall ;exit if running bios is too high ; ld hl,(szchain) ;get command length ld h,0 ;0 in H ex de,hl ;in DE ld hl,(szfixed) ;get code length add hl,de ;make size of code to move ; ld b,h ld c,l ;BC has length of code ld hl,BiosCode ;source in HL ld de,Fboot ;destination in DE ldir ;move the code ; jp Fboot ;finish up here. ; toosmall: ld de,tsmlmsg ;point at too small message ld c,prntstr ;print string in C call bdosv ;print message ld sp,(oldstack) ;get old stack pointer back ret ;and exit ; ; ; put length of fixed code here to allow easier patching of ; user's CCP chain command: szfixed: defw ourcmd-Fboot ;size of executable szchain: defb cmdlen+1 ;length of chain command ; signmsg: defb 0dh,'RehDesign GIDE: 62k BIOS for Davidge DSB 4/6' defb 0dh,0ah,' -- John D. Baker, 9 March 1996' defb 0dh,0ah,'$' ; tsmlmsg: defb 0dh,0ah,0ah,'*** No space for GIDE BIOS!!' defb ' Memory size must be 62K or less. ***' defb 0d,0ah,'$' BiosCode: .phase HDBIOS ; Define a replacement set of BIOS jump vectors which point to ; our custom functions or back to the standard BIOS functions, ; as appropriate. Fboot: jp Hboot ;cold boot Fwboot: jp Hwboot ;warm boot Fconst: jp Fconst ;console status Fconin: jp Fconin ;console input Fconot: jp Fconot ;console output Flist: jp Flist ;list output Fpunch: jp Fpunch ;punch output Freader: jp Freader ;reader input Fhome: jp Hhome ;home disk drive Fseldsk: jp Hseldsk ;select drive Fsettrk: jp Hsettrk ;set track Fsetsec: jp Hsetsec ;set sector Fsetdma: jp Hsetdma ;set dma address Fread: jp Hread ;read sector Fwrite: jp Hwrite ;write sector Flistst: jp Flistst ;list status Fsectrn: jp Hsectrn ;sector translate szjptab equ $-Fboot ;size of jump table ;*************************************************************** ;Function: Hboot ;Purpose: Placeholder to locate fixed options ;Entry: None ;Exit: None ;Uses: None Hboot: jp Hbtcode ;jump over ;*************************************************************** ;Some fixed data options. ; ; ;selary -- array of select values for mapping the disk number ; passed to SELDSK to either the floppy-disk bios or the ; hard disk bios--selecting which disk to use. ; ; 00-0F = Vendor's CBIOS disk handlers ; 80-8F = Hard disk extension BIOS (SASI/SCSI) ; A0-AF = Hard disk extension BIOS (IDE) ; FF = invalid drive ; selary: defb 0 ;A: = first floppy defb 1 ;B: = second floppy defb 2 ;C: defb 3 ;D: defb 0a0h ;E: = first IDE disk (head 0) defb 0a1h ;F: defb 0a2h ;G: defb 0a3h ;H: defb 0a4h ;I: defb 0ffh ;J: = no such disk defb 0ffh ;K: defb 0ffh ;L: defb 0ffh ;M: defb 0ffh ;N: defb 0ffh ;O: defb 0ffh ;P: ; ; wbtdsk -- disk number 0-F to use for warm boots ; wbtdsk: defb wbtdrv-'A' ;warm boot disk number 0-F ; ; szwrmbt -- number of CPM sectors to read on warm boot ; szwrmbt: defw nsecs ;*************************************************************** ;Function: Hhome ;Purpose: Home current disk ;Entry: None ;Exit: Disk homed ;Uses: AF, HL Hhome: call chkhrd ;is it our disk? jr z,Fhome ;no, jump to FBIOS ; xor a ;0 in A ld hl,hstact ; HL points to host active or (hl) ;set flags ret z ;return if host is not active inc hl ;bump to hstwrt xor a ;0 in A or (hl) ;set flagz ret nz ;return if pending write dec hl ;bump back down to hstact ld (hl),a ; else clear host active flag ret ;and done ;*************************************************************** ;Function: Hsettrk ;Purpose: Set logical track number for disk I/O ;Entry: BC = logical sector number ;Exit: track set up ;Used: All Hsettrk: call chkhrd ;is it our disk? jr z,Fsettrk ;no, jump to Fbios ; ld (sektrk),bc ;save it ret ;and done ;*************************************************************** ;Function: Hsetsec ;Purpose: Set logical sector number for disk I/O ;Entry: BC = logical sector number ;Exit: sector set up ;Used: All Hsetsec: call chkhrd ;is it our disk? jr z,Fsetsec ;not our disk. Jump to FBIOS ; ld (SEKSEC),bc ;save sector to seek ret ;*************************************************************** ;Function: Hsetdma ;Purpose: Set transfer address for disk I/O ;Entry: BC = dma address ;Exit: DMA address set up ;Used: All Hsetdma: ld (dmaadr),bc ;set it here jr Fsetdma ;and let FBIOS set it as well. ;*************************************************************** ;Function: Hsectrn ;Purpose: Do logical->physical sector translation ;Entry: BC = logical sector number, DE points to xlate table ;Exit: HL = physical sector number ;Uses: All Hsectrn: call chkhrd ;is it our disk? jr z,Fsectrn ;not our disk, jump to FBIOS ; ld l,c ;L=C ld h,b ;H=B (no translation) ret ;and we're done ;*************************************************************** ;Function: Hwrite ;Purpose: Write logical CP/M sector ;Entry: disk, track, sector, DMA, etc. set up ;Exit: sector transferred to disk..sort of ;Uses: All Hwrite: call chkhrd ;is it our disk? jr z,Fwrite ;no, jump to FBIOS ; XOR A ;0 in A LD (READOP),A ;indicate a write operation (READOP) LD A,C ;get the write type in A LD (wrtype),A ;store at WRTYP CP wrual ;is it write to unallocated? JR NZ,chkuna ;no, jump over (to chkuna) ; LD HL,SEKDSK ;point to SEKDSK LD DE,UNADSK ;set pointer to UNADSK LD BC,005H ;count of data to move LDIR ;copy SEKDSK --> UNADSK LD A,(HDBLM) ;get BLM INC A ;bump up by 1 LD (UNACNT),A ;set up unacnt chkuna: LD HL,UNACNT ;point at unacnt XOR A ;0 in A CP (HL) ;any more unallocated sectors? JR Z,alloc1 ;JRIF no more (alloc1) DEC (HL) ;--unacnt LD HL,SEKDSK ;HL points to SEKDSK LD DE,UNADSK ;point to unadsk disk data LD BC,005H ;count of data to move/compare CALL strcmp ;compare with SEKDSK JR NZ,alloc0 ;JRIF not same disk (alloc0) ; LD HL,(UNASEC) ;get unasec INC HL ;bump up 1 LD (UNASEC),HL ;put it back LD DE,(DPBHD) ;get cp/m sec/trk or a ;clear carry sbc hl,de ;check for overflow JR C,noovf0 ;JRIF no overflow ; ld hl,0000 ;overflow, 0 in HL LD (UNASEC),HL ;reset unasec to 0 LD HL,(UNATRK) ;get UNATRK INC HL ;bump to next track LD (UNATRK),HL ;and put it back noovf0: XOR A ;0 in A JR noovf1 ; and do a write ;*************************************************************** ;Function: Hread ;Purpose: Read logical CP/M sector ;Entry: disk, track, sector, DMA, etc. set up ;Exit: sector transferred to memory ;Uses: All Hread: call chkhrd ;is it our disk? jp z,Fread ;no, jump to FBIOS ; LD A,wrual ;treat as write to unallocated LD (wrtype),A ;store at WRTYPE LD (READOP),A ;indicate a read (READOP) alloc0: XOR A ;0 in A LD (UNACNT),A ;clear unacnt alloc1: INC A ;bump to 1 noovf1: LD (RSFLAG),A ;flag a rd(!0) or wr(0) (rsflag) LD (OLDSTACK),SP ;save old stack pointer LD SP,BIOSSTK ;set up local stack pointer rwoper: ; calculate host sector... ; ld a,(SecShf) ;get sector shift ld b,a ;into B or a ;check for 0 ld hl,(SEKSEC) ;get sector jr z,rwoper1 ;jrif 0 (don't shift) rwoper0: or a ;clear carry rr h ;shift sector right H:0->carry rr l ;shift sector right carry->L:7 djnz rwoper0 ;until found rwoper1: ld (SEKHST),HL ;store host sector to seek ; XOR A ;0 in A LD (erflag),A ;no errors (yet) LD HL,HSTACT ;point at hstact OR (HL) ;OR in the host active flag LD (HL),1 ;always becomes 1 JR Z,filhst ;JRIF was not already 1 (filhst) ; LD HL,SEKHST ;HL points to SEKHST LD DE,HSTSEC ;DE points HSTSEC LD BC,5 ;length to move/compare in BC call strcmp ;compare JR Z,match ;jrif same buffer, disk, track ;nomatch: LD A,(HSTWRT) ;match, host written? OR A ; CALL NZ,WRITEHST ;flush pending write filhst: LD HL,SEKHST ;point at SEKHST LD DE,HSTSEC ;point to HSTSEC stuff LD BC,5 ;count of data to move LDIR ;set up HSTDSK LD A,(RSFLAG) ;GET RSFLAG OR A ;Need to read? CALL NZ,READHST ;readhst XOR A ;0 in A LD (HSTWRT),A ;no pending write match: LD HL,(SecMsk) ;get mask value in L LD A,(SEKSEC) ;get SEKSEC AND L ;mask with L (A has sector offset) LD BC,00080H ;sector size in BC LD HL,HSTBUF ;buffer base in HL? RRA ;A /= 2 (transfer A:0 to Carry) LD D,A ;in D (make high byte of offset) LD E,B ;0 in E RR E ;E /= 2 (rotate Carry into E:7) ADD HL,DE ;make address of CP/M sector in HL LD DE,(DMAADR) ;get DMA address in DE LD A,(READOP) ;get READOP OR A ;is this a READ? JR NZ,rwmove ;yes, skip EX DE,HL ;no, swap pointers INC A ; LD (HSTWRT),A ;hstwrt = 1 rwmove: LDIR ;move data to/from host buffer LD A,(wrtype) ;get WRTYPE DEC A ;bump down LD A,(erflag) ;get erflag? LD SP,(OLDSTACK) ;restore the stack RET NZ ;return if WRTYPE was wrall or wrual OR A ;was wrdir, errors? RET NZ ; return if errors LD (HSTWRT),A ;no errors, mark buffer written ;and fall through to writehst sector... ;*************************************************************** ;Function: WriteHst ;Purpose: Do physical write to IDE drive ;Entry: hstdsk, hsttrk, hstdsk set up ;Exit: sector in hstbuf written to disk ;Used: all Writehst: call tfsetup ;set up Task File ld a,CmdWr ;get a write command out (IdeCmd),a ;send it to Task File call WaitDrq ;wait for data otir otir ;write 512 bytes jr chkerr ;check for/report errors ;*************************************************************** ;Function: ReadHst ;Purpose: Do physical read of IDE drive ;Entry: hstdsk, hsttrk, hstdsk set up ;Exit: sector read into hstbuf ;Used: all Readhst: call tfsetup ;set up Task File ld a,CmdRd ;get a read command out (IdeCmd),a ;send to task file call WaitDrq ;wait for data inir inir ;read 512 bytes chkerr: in a,(IdeStat) ;get status and 1 ;check error bit ld (erflag),a ;save as error flag ret ;return error/no error ;*************************************************************** ;Function: Hwboot ;Purpose: perform initializations and re-load CP/M ;Entry: zero page set up ;Exit: initializations done, current disk in C ;Used: All Hwboot: ld hl,0000 ;0000 in HL ld (unacnt),hl ;clr unalloc cnt, hst buf inactive ld hl,hstbuf ;get address of host buffer ld (adrhst),hl ;and put it here jp Fwboot ;and continue here. ;*************************************************************** ;Function: Hseldsk ;Purpose: Select disk drive ;Entry: Disk number 0-F in C ;Exit: Address of DPH in HL or 0000 if error ;Used: All Hseldsk: ld a,c ;get disk cp 0fh+1 ;compare against max disk + 1 jr nc,errsel ;jump if out of range ; call makesel ;get disk select data ; inc a ;if FF, now 00 jr z,errsel ;no such disk dec a ;restore to previous ; rlca ;preserve bit 7 rrca ;into Carry jr c,oursel ;if bit 7 set, it's our disk ; ld c,a ;belongs to Vendor's CBIOS, put back in C xor a ;0 in A ld (ourdsk),a ;let our HBIOS segment know jp Fseldsk ;and let Fbios handle it ; oursel: ld (ourdsk),a ;flag as our disk ld l,a ;and put in L ld a,c ;get disk number again ld (sekdsk),a ;save disk number add hl,hl ;*2 add hl,hl ;*4 add hl,hl ;*8 add hl,hl ;*16 ld h,0 ;make sure H=0 ld de,hdpbase ;get base of hard disk dph's add hl,de ;make pointer to DPH for drive ret ;and go back errsel: ld hl,0000 ;0 in HL ld a,(cdisk) ;get current disk sub c ;same as selected? ret nz ;wasn't same ld (cdisk),a ;else force drive A current ret ;and return with error makesel: ld b,0 ;0 in B ld hl,selary ;base of select array in HL add hl,bc ;make pointer to select data ld a,(hl) ;get the select data ret ;*************************************************************** ;Function: TFsetup ;Purpose: send host parms to IDE Task File registers ;Entry: hstdsk, hsttrk, hstsec set up ;Exit: Task file registers set up. HL points to hstbuf, ; BC has count, data port address tfsetup: in a,(IdeStat) ;get status rla ;BSY bit to Carry jr c,tfsetup ;loop until not BUSY ; ld a,1 ;1-sector transfer out (IdeSCnt),a ;tell IDE drive ld a,(hstsec) ;get host sector number inc a ;bump up to 1 out (IdeSNum),a ;send to Task File ld hl,(hsttrk) ;get host track ld a,l ;get low order byte out (IdeCLo),a ;send to Task File ld a,h ;get high-order byte out (IdeCHi),a ;send to task file ld a,(hstdsk) ;get host disk number ld c,a ;put in c call makesel ;get the select data in A and 0fh ;mask low mybble ld c,a ;in C ld b,0 ;0 in B ld hl,sdhbase ;point to base of SDH byte array add hl,bc ;form pointer in HL ld a,(hl) ;get the sdh byte out (IdeSDH),a ;send to drive! ; ld hl,(ADRHST) ;HL points to host buffer ld bc,IdeDat ;BC has count, port ret ;and go back ;*************************************************************** ;Function: chkhrd ;Purpose: check if disk operation is for hard disk or floppy ;Entry: "ourdisk" is set for hard disk, clear for floppy ;Exit: Z set if floppy operation, clear if hard disk ;Uses: AF chkhrd: ld a,(ourdsk) ;is it our disk? or a ;set flagz ret ;and done ;*************************************************************** ;Function: WaitDrq ;Purpose: Wait until data available or ready for data ;Entry: None ;Exit: None ;Uses: AF WaitDrq: in a,(IdeCmd) bit 3,a jr z,WaitDrq ret ;*************************************************************** ;Function: strcmp ;Purpose: Compare two strings [(SEK|UNA|HST)TRK] ;Entry: HL, DE have addresses of strings, BC = length ;Exit: Z set if strings are the same, clear if different ; P/V flag clear if entire string checked ;Uses: AF, BC, DE, HL strcmp: LD A,(DE) ;get a byte from (DE) CPI ;compare A-(HL++), BC-- RET NZ ;return if no match RET PO ;return if string exhausted INC DE ;else bump to next source byte JR strcmp ;and repeat comparison ;*************************************************************** ;The clock driver conforms to the ZS/ZDDOS/DateStamper standard. ;On entry: ; DE = address of 6-byte BCD string of the form: ; YY MM DD HH MM SS ; C = 0 for read, 1 for set ; ;On exit: ; E = previous contents of (DE+5) [old seconds] ; HL = entry value of DE + 5 [ptr to new seconds] ; A = 1 if success, FF if error. ; ; *** NOTE *** ; This particular instance of the clock driver is for the Davidge ; DSB 4000 BIOS v1.3 and the CardZ180 OEM version of ZDDOS. ; For use with standard (generic) ZDDOS, some re-arrangement ; may be required. ; ; It is more probable that the clock driver could be stashed in ; some extra space in the NZCOM VBIOS segment (NZBIO) once the ; VBIOS segment is loaded. ; ClkDrv: ex de,hl ;time pointer to HL dec c ;check read or set jr z,RTCset ;C->0 if was set command RTCread: call RTCwait ; check for RTC non-busy RTCrd1: ld e,(hl) ; save byte (last will be old seconds) in a,(c) ; read tens digit rld ; rotate into [HL]:0-3 dec b ; bump to units in a,(c) ; read units digit rld ; and rotate units in... inc hl ; bump pointers dec b jp p,RTCrd1 ; repeat until seconds done RTCexit: dec hl ; reset HL to new seconds ld b,0Dh xor a out (c),a ; reset Hold bit inc a ; return success in A ret ; Set date & time of RTC according to buffer given by (DE) RTCset: call RTCinit ; Init the clock on a set, just in case... RTCst1: ld e,(hl) ; save byte (last will be seconds) rld ; get tens into A out (c),a ; write tens to RTC dec b ; bump to units rld ; get units to A out (c),a ; write units to RTC rld ; and restore (HL) inc hl ; bump pointers dec b jp p,RTCst1 ; repeat until seconds done jr RTCexit ; and done ; Init the RTC for normal operation. ; If the RTC is battery backed, this is needed only for ; the first time the RTC is powered up! RTCinit: ld bc,0F00h+RTC ; access Ctl-Reg. F ld a,5 out (c),a ; RTC Ctl-F: 24h mode, Reset dec a out (c),a ; release Reset ;and fall through to wait routine... ; Prepare for R/W access to the RTC. The hold bit is set, ; and the busy flag checked to see if accesses are allowed. ; Also set up time register pointer in B. RTCwait: ld bc,0D00h+RTC ; access Ctl-D ld a,1 out (c),a ; set Hold bit in a,(c) bit 1,a ; check Busy flag jr z,RTCntbsy ; not busy: set up B and return xor a out (c),a ; reset Hold bit jr RTCwait ; go try again RTCntbsy: ld b,0Bh ; point at year tens register ret ;*************************************************************** ;Fixed data area ; SDHBASE: defb 0a0h ;SDH byte for first logical disk... defb 0a1h defb 0a2h defb 0a3h defb 0a4h ;five of them, for now. HDPBASE: HDPH0: defw 0000 ;XLT0 defw 0000 defw 0000, 0000 ;scratch defw DIRBUF defw DPBHD defw CSV0 defw ALV0 HDPH1: defw 0000 ;XLT1 defw 0000 defw 0000, 0000 ;scratch defw DIRBUF defw DPBHD defw CSV1 defw ALV1 HDPH2: defw 0000 ;XLT2 defw 0000 defw 0000, 0000 ;scratch defw DIRBUF defw DPBHD defw CSV2 defw ALV2 HDPH3: defw 0000 ;XLT3 defw 0000 defw 0000, 0000 ;scratch defw DIRBUF defw DPBHD defw CSV3 defw ALV3 HDPH4: defw 0000 ;XLT4 defw 0000 defw 0000, 0000 ;scratch defw DIRBUF defw DPBHD defw CSV4 defw ALV4 ; Host Parameters for Conner CP-342 IDE drive... SecMsk: defb 3 ;512/128 - 1 Secshf: defb 2 ;log_2(512/128) ;A proposed Disk Parameter Block for 8MB drives with 8K blocks DPBHD: defw 68 ;17*4 CP/M Sec/trk defb 6 ;64 recs/block HDBLM: defb 63 ;ditto defb 3 ;extent mask defw 3ffh ;1024 blocks defw 3ffh ;1024 directory entries defb 0f0h ;4 blocks of directory defb 0 ; defw 0 ;no scratch defw 2 ;2 tracks offset ;*************************************************************** ;RAM Variables and unitialized data ; HSTBUF: HbtCode: ld hl,Hwboot ;get address of warm boot code ld (Hboot+1),hl ;cut off access to this code ; ld hl,ClkDrv ;get address of clock driver ld (ZDTIME+1),HL ;and stick it here ld a,0C3h ;get a jump instruction ld (ZDTIME),A ;and put it here ; ld hl,0000 ;0 in HL ld (unacnt),hl ;clr unalloc cnt, hstbuf inactive ld hl,hstbuf ;get address of host buffer ld (adrhst),hl ;and initialize it here ;fall through to patch in our jump table ;*************************************************************** ;Function: SWPJTAB ;Purpose: Swap stock BIOS jump table with ours ;Entry: Standard CP/M v2.2 BIOS jump table ;Exit: Jump tables swapped. ;Uses: All swpjtab: ld hl,(WBOOTE+1) ;get Warm boot ld l,0 ;point at start ld de,Fboot ;point at our jump table ld b,szjptab ;size in B swpjtlp: ld a,(hl) ;get stock byte push af ;save it ld a,(de) ;get our byte ld (hl),a ;put it where stock was pop af ;get stock byte back ld (de),a ;put it where ours was inc hl ;bump stock pointer inc de ;bump our pointer djnz swpjtlp ;until all bytes done ;and fall through to chain code... ;*************************************************************** ;code to stuff CCP command buffer with chain command ; ld a,(BDOSV+2) ;get BDOS base page sub 8 ;back up to CCP base ld d,a ;in D ld e,7 ;point at command buffer ld a,(ourcmd) ;get length ld c,a ;in C ld b,0 ;0 in B inc bc ;bump up one, make byte count ld hl,ourcmd ;point at our command ldir ;put our command in buffer ; ex de,hl ;get CCP space in HL ld (hl),0 ;force terminator ; ld l,0 ;0 in HL (point to CCP) ld sp,0080h ;set default stack pointer ld a,(cdisk) ;get the current disk ld c,a ;put in C jp (hl) ;and jump to CCP ; ourcmd: defb cmdlen defb 'NZCOM' cmdlen equ $-ourcmd defb 0 ;end of command szhcbt equ $-Hbtcode if (hstsiz-szhcbt) gt 07fffh .printx " *** Cold boot code too large! *** " endif defs hstsiz-szhcbt ;space to host buffer size ; ourdsk: defs 1 ;flag if disk operation is for us. ; DO NOT CHANGE THE ORDER OF THESE DATA AREAS!!! hstsec: defs 2 ;host sector hstdsk: defs 1 ;host disk hsttrk: defs 2 ;host track sekhst: defs 2 ;host sector to seek sekdsk: defs 1 ;disk to seek sektrk: defs 2 ;track to seek seksec: defs 2 ;sector to seek unadsk: defs 1 ;unallocated disk unatrk: defs 2 ;unallocated track unasec: defs 2 ;unallocated sector unacnt: defs 1 ;unallocated sector count hstact: defs 1 ;host active flag hstwrt: defs 1 ;host written flag erflag: defs 1 ;error reporting flag rsflag: defs 1 ;read sector flag ; locate these above ZDTIME to get more space... readop equ xtrspc ;1 if this is a read (FFF8) wrtype equ readop+1 ;type of write operation (FFF9) dmaadr equ wrtype+1 ;last dma address (FFFA) adrhst equ dmaadr+2 ;address of host buffer (FFFC) oldstack equ adrhst+2 ;old stack pointer (FFFE) DIRBUF: defs 128 CSV0: ALV0: defs 128 CSV1: ALV1: defs 128 CSV2: ALV2: defs 128 CSV3: ALV3: defs 128 CSV4: ALV4: defs 128 ; defs 24 biosstk: .dephase ;end of HDBIOS extension if (biosstk gt systop) or (biosstk lt Fboot) .PRINTX " *** Origin of HDBIOS too high! *** " endif end