|
|
@ -45,14 +45,17 @@ |
|
|
|
|
|
|
|
|
maclib cpm3.lib |
|
|
maclib cpm3.lib |
|
|
|
|
|
|
|
|
|
|
|
; HBIOS related definitons |
|
|
|
|
|
|
|
|
|
|
|
include hbios.z80 |
|
|
|
|
|
|
|
|
; common control characters |
|
|
; common control characters |
|
|
|
|
|
|
|
|
cr equ 13 |
|
|
cr equ 13 |
|
|
lf equ 10 |
|
|
lf equ 10 |
|
|
bell equ 7 |
|
|
bell equ 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Extended Disk Parameter Headers (XPDHs) |
|
|
|
|
|
|
|
|
; Extended Disk Parameter Headers (XDPHs) |
|
|
|
|
|
|
|
|
; All DPH entries below are generic. They are updated during |
|
|
; All DPH entries below are generic. They are updated during |
|
|
; boot to point to available HBIOS disk unit/slices dynamically. |
|
|
; boot to point to available HBIOS disk unit/slices dynamically. |
|
|
@ -370,7 +373,7 @@ dsk$init: |
|
|
|
|
|
|
|
|
dsk$init1: |
|
|
dsk$init1: |
|
|
; Get bank count of RAM/ROM disk |
|
|
; Get bank count of RAM/ROM disk |
|
|
ld b,0FAh ; HBIOS Peek Function |
|
|
|
|
|
|
|
|
ld b,BF_SYSPEEK ; HBIOS Peek Function |
|
|
ld a,(@hbbio) ; HBIOS bank id |
|
|
ld a,(@hbbio) ; HBIOS bank id |
|
|
ld d,a ; ... goes in D |
|
|
ld d,a ; ... goes in D |
|
|
rst 08 ; Call HBIOS, value in E |
|
|
rst 08 ; Call HBIOS, value in E |
|
|
@ -446,7 +449,6 @@ dsk$login: |
|
|
;ret ; we have nothing to do in |
|
|
;ret ; we have nothing to do in |
|
|
; simple single density only environment. |
|
|
; simple single density only environment. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;ld a,'L' |
|
|
;ld a,'L' |
|
|
;call cout |
|
|
;call cout |
|
|
|
|
|
|
|
|
@ -461,193 +463,37 @@ dsk$login: |
|
|
inc a ; 0FFh -> 000h |
|
|
inc a ; 0FFh -> 000h |
|
|
jp z,err_ret ; bail out on no disk mapped here |
|
|
jp z,err_ret ; bail out on no disk mapped here |
|
|
|
|
|
|
|
|
;call media ; update DPH for media |
|
|
|
|
|
;ret |
|
|
|
|
|
|
|
|
|
|
|
media: |
|
|
media: |
|
|
; Set retry address |
|
|
; Set retry address |
|
|
ld hl,media |
|
|
ld hl,media |
|
|
ld (retry$adr),hl |
|
|
ld (retry$adr),hl |
|
|
|
|
|
|
|
|
; Sense media to determine media format |
|
|
; Sense media to determine media format |
|
|
ld a,(unit) ; get disk unit |
|
|
|
|
|
ld c,a ; put in C |
|
|
|
|
|
ld b,18h ; HBIOS Media function |
|
|
|
|
|
ld e,1 ; Enable media check/discovery |
|
|
|
|
|
|
|
|
ld b,BF_EXTSLICE ; HBIOS func: SLICE |
|
|
|
|
|
ld a,(unit) ; passing boot unit |
|
|
|
|
|
ld d,a |
|
|
|
|
|
ld a,(slice) ; and slice |
|
|
|
|
|
ld e,a |
|
|
call 0FFF0H ; HBIOS call |
|
|
call 0FFF0H ; HBIOS call |
|
|
jp nz,err_diskio ; handle error |
|
|
|
|
|
ld a,e ; resultant media id to accum |
|
|
|
|
|
ld (medid),a ; save media id |
|
|
|
|
|
or a ; set flags, 0 is no media |
|
|
|
|
|
jp z,err_nodisk ; handle no media error |
|
|
|
|
|
|
|
|
|
|
|
; Initialize slice start LBA & sectors per slice |
|
|
|
|
|
ld hl,0 ; assume slice starts |
|
|
|
|
|
ld (lba),hl ; ... at LBA offset |
|
|
|
|
|
set 7,h ; ... of zero |
|
|
|
|
|
ld (lba+2),hl ; ... w/ LBA access |
|
|
|
|
|
|
|
|
|
|
|
; Check device type |
|
|
|
|
|
ld a,(unit) ; get disk unit |
|
|
|
|
|
ld c,a ; put in C |
|
|
|
|
|
ld b,17h ; HBIOS func: report device info |
|
|
|
|
|
call 0FFF0h ; get unit info, device type in D |
|
|
|
|
|
ld a,d ; device type -> A |
|
|
|
|
|
cp 01h ; floppy? |
|
|
|
|
|
jr nz,media1 ; if not, do LBA I/O |
|
|
|
|
|
ld hl,lba+3 ; point to high order byte |
|
|
|
|
|
res 7,(hl) ; switch from LBA -> CHS |
|
|
|
|
|
|
|
|
|
|
|
media1: |
|
|
|
|
|
ld hl,16640 ; assume legacy value for |
|
|
|
|
|
ld (sps),hl ; ... sectors per slice |
|
|
|
|
|
|
|
|
|
|
|
; If not hard disk, skip partition & slice stuff |
|
|
|
|
|
ld a,(medid) ; get media id |
|
|
|
|
|
cp 4 ; hard disk? |
|
|
|
|
|
jp nz,media9 ; if not, jump ahead |
|
|
|
|
|
|
|
|
|
|
|
; Read MBR |
|
|
|
|
|
ld de,8000h ; LBA address zero |
|
|
|
|
|
ld hl,0 ; ... to read first sector |
|
|
|
|
|
ld bc,mbrsec ; read into MBR buffer |
|
|
|
|
|
ld (dma),bc ; save |
|
|
|
|
|
ld a,(0FFE0h) ; get current HBIOS bank |
|
|
|
|
|
ld (bank),a ; set DMA bank |
|
|
|
|
|
ld a,(unit) ; get bootunit |
|
|
|
|
|
ld c,a ; put in C |
|
|
|
|
|
ld b,013h ; HBIOS func: disk read |
|
|
|
|
|
call dsk$io ; do it |
|
|
|
|
|
ret nz ; abort on error |
|
|
|
|
|
|
|
|
|
|
|
; Check signature |
|
|
|
|
|
ld hl,(mbrsec+1FEh) ; get signature |
|
|
|
|
|
ld a,l ; first byte |
|
|
|
|
|
cp 055h ; should be $55 |
|
|
|
|
|
jr nz,media5 ; if not, no part table |
|
|
|
|
|
ld a,h ; second byte |
|
|
|
|
|
cp 0AAh ; should be $AA |
|
|
|
|
|
jr nz,media5 ; if not, no part table |
|
|
|
|
|
|
|
|
|
|
|
; Search part table for CP/M entry (type 0x2E) |
|
|
|
|
|
ld b,4 ; four entries in part table |
|
|
|
|
|
ld hl,mbrsec+1BEh+4 ; offset of first part type |
|
|
|
|
|
media3: |
|
|
|
|
|
ld a,(hl) ; get part type |
|
|
|
|
|
cp 2Eh ; CP/M partition? |
|
|
|
|
|
jr z,media4 ; cool, grab the LBA offset |
|
|
|
|
|
ld de,16 ; part table entry size |
|
|
|
|
|
add hl,de ; bump to next part type |
|
|
|
|
|
djnz media3 ; loop thru table |
|
|
|
|
|
jr media5 ; too bad, no CP/M partition |
|
|
|
|
|
|
|
|
|
|
|
media4: |
|
|
|
|
|
; Capture the starting LBA of the CP/M partition we found |
|
|
|
|
|
ld de,4 ; LBA is 4 bytes after part type |
|
|
|
|
|
add hl,de ; point to it |
|
|
|
|
|
ld de,lba ; loc to store lba offset |
|
|
|
|
|
ld bc,4 ; 4 bytes (32 bits) |
|
|
|
|
|
ldir ; copy it |
|
|
|
|
|
|
|
|
|
|
|
; Check that requested slice is "inside" partition. |
|
|
|
|
|
; Slice size is exactly 16,384 sectors (8mb), so we can just |
|
|
|
|
|
; right shift partition sector count by 14 bits |
|
|
|
|
|
ld e,(hl) ; HL points to first byte |
|
|
|
|
|
inc hl ; ... of 32 bit partition |
|
|
|
|
|
ld d,(hl) ; ... sector count, |
|
|
|
|
|
inc hl ; ... load sector count |
|
|
|
|
|
push de ; ... into DE:HL |
|
|
|
|
|
ld e,(hl) ; ... |
|
|
|
|
|
inc hl ; ... |
|
|
|
|
|
ld d,(hl) ; ... |
|
|
|
|
|
pop hl ; ... DE:HL = part size in sectors |
|
|
|
|
|
ld b,2 ; DE = DE:HL >> 2 (tricky!) |
|
|
|
|
|
call rl32 ; DE = slicecnt |
|
|
|
|
|
ex de,hl ; HL = slicecnt |
|
|
|
|
|
ld a,(slice) ; get target slice |
|
|
|
|
|
ld c,a ; put in C |
|
|
|
|
|
ld b,0 ; BC := requested slice # |
|
|
|
|
|
scf ; set carry! |
|
|
|
|
|
sbc hl,bc ; max slices - slice - 1 |
|
|
|
|
|
jp c,err_noslice ; slice too high, error exit |
|
|
|
|
|
|
|
|
|
|
|
; For now, it is implied that a slice within a partition |
|
|
|
|
|
; table will be in the "new" disk format. So, we now |
|
|
|
|
|
; adjust the sectors per slice and media id. |
|
|
|
|
|
|
|
|
|
|
|
; Use new slice format sectors per slice value |
|
|
|
|
|
ld hl,16384 ; new sectors per slice |
|
|
|
|
|
ld (sps),hl ; save it |
|
|
|
|
|
|
|
|
|
|
|
; Update media id for new hard disk format |
|
|
|
|
|
ld a,10 ; new media id |
|
|
|
|
|
ld (medid),a ; save it |
|
|
|
|
|
|
|
|
|
|
|
media5: |
|
|
|
|
|
; Adjust LBA offset based on target slice |
|
|
|
|
|
ld a,(slice) ; get slice, A is loop cnt |
|
|
|
|
|
ld hl,(lba) ; set DE:HL |
|
|
|
|
|
ld de,(lba+2) ; ... to starting LBA |
|
|
|
|
|
ld bc,(sps) ; sectors per slice |
|
|
|
|
|
res 7,d ; clear lba mode bit |
|
|
|
|
|
boot6: |
|
|
|
|
|
or a ; set flags to check loop cntr |
|
|
|
|
|
jr z,boot8 ; done if counter exhausted |
|
|
|
|
|
add hl,bc ; add one slice to low word |
|
|
|
|
|
jr nc,boot7 ; check for carry |
|
|
|
|
|
inc de ; if so, bump high word |
|
|
|
|
|
boot7: |
|
|
|
|
|
dec a ; dec loop downcounter |
|
|
|
|
|
jr boot6 ; and loop |
|
|
|
|
|
boot8: |
|
|
|
|
|
|
|
|
|
|
|
; LBA offset of desired slice is now in DE:HL. |
|
|
|
|
|
; Need to check if the slice is beyond capacity of media. |
|
|
|
|
|
; If lba_off + sps >= dsk_cap, error! |
|
|
|
|
|
|
|
|
|
|
|
; Save lba_off |
|
|
|
|
|
push de ; msw |
|
|
|
|
|
push hl ; lsw |
|
|
|
|
|
|
|
|
|
|
|
; Add sps to compute lba_req |
|
|
|
|
|
ld bc,(sps) ; sectors per slice |
|
|
|
|
|
add hl,bc ; add one slice to low word |
|
|
|
|
|
jr nc,dsk_mbr9 ; check for carry |
|
|
|
|
|
inc de ; if so, bump high word |
|
|
|
|
|
dsk_mbr9: |
|
|
|
|
|
; Save cap_req |
|
|
|
|
|
ld (cap_req),hl ; lsw |
|
|
|
|
|
ld (cap_req+2),de ; msw |
|
|
|
|
|
|
|
|
|
|
|
; Get dsk_cap (de:hl) |
|
|
|
|
|
ld b,1Ah ; hbios disk capacity func |
|
|
|
|
|
ld a,(unit) ; disk unit number |
|
|
|
|
|
ld c,a ; ... into c |
|
|
|
|
|
rst 08 ; hbios call (de:hl = capacity) |
|
|
|
|
|
|
|
|
|
|
|
; Save dsk_cap (de:hl) |
|
|
|
|
|
push de ; save dsk_cap (msw) |
|
|
|
|
|
push hl ; save dsk_cap (lsw) |
|
|
|
|
|
|
|
|
|
|
|
; Check dsk_cap >= cap_req, cf set on overflow |
|
|
|
|
|
; No need save actual result |
|
|
|
|
|
or a ; clear carry for sbc |
|
|
|
|
|
pop hl ; dsk_cap lsw |
|
|
|
|
|
ld de,(cap_req) ; cap_req lsw |
|
|
|
|
|
sbc hl,de ; dsk_cap - lba_req (lsw) |
|
|
|
|
|
pop hl ; dsk_cap msw |
|
|
|
|
|
ld de,(cap_req+2) ; cap_req msw |
|
|
|
|
|
sbc hl,de ; dsk_cap - lba_req (msw) |
|
|
|
|
|
|
|
|
|
|
|
; Restore lba_off |
|
|
|
|
|
pop hl ; lsw |
|
|
|
|
|
pop de ; msw |
|
|
|
|
|
|
|
|
|
|
|
; Abort on overflow with error! |
|
|
|
|
|
jp c,err_noslice ; slice too high, error exit |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Check errors from the Function |
|
|
|
|
|
cp ERR_NOUNIT ; compare to no unit error |
|
|
|
|
|
jp z,err_nodisk ; handle no disk err |
|
|
|
|
|
cp ERR_NOMEDIA ; no media in the device |
|
|
|
|
|
jp z,err_nodisk ; handle the error |
|
|
|
|
|
cp ERR_RANGE ; slice is invalid |
|
|
|
|
|
jp z,err_noslice ; bad slice, handle err |
|
|
|
|
|
or a ; any other error |
|
|
|
|
|
jp nz,err_diskio ; handle as general IO error |
|
|
|
|
|
|
|
|
|
|
|
; Capture the Result |
|
|
|
|
|
ld a,c ; resultant media id to accum |
|
|
|
|
|
ld (medid),a ; save media id |
|
|
; Finalize slice lba |
|
|
; Finalize slice lba |
|
|
|
|
|
BIT 7,B ; Is the floppy Disk Attribute Set |
|
|
|
|
|
jr nz,media8 ; if it is Floppy; Skip Setting LBA |
|
|
set 7,d ; set LBA access flag |
|
|
set 7,d ; set LBA access flag |
|
|
|
|
|
media8: |
|
|
ld (lba),hl ; save new lba, low word |
|
|
ld (lba),hl ; save new lba, low word |
|
|
ld (lba+2),de ; save new lba, high word |
|
|
ld (lba+2),de ; save new lba, high word |
|
|
|
|
|
|
|
|
@ -698,12 +544,12 @@ media10: |
|
|
; if necessary, then return an error code in <A> |
|
|
; if necessary, then return an error code in <A> |
|
|
|
|
|
|
|
|
dsk$read: |
|
|
dsk$read: |
|
|
ld a,13h ; HBIOS disk read function |
|
|
|
|
|
|
|
|
ld a,BF_DIOREAD ; HBIOS disk read function |
|
|
ld (func),a ; save it |
|
|
ld (func),a ; save it |
|
|
jr dsk$rw ; common disk read/write code |
|
|
jr dsk$rw ; common disk read/write code |
|
|
|
|
|
|
|
|
dsk$write: |
|
|
dsk$write: |
|
|
ld a,14h ; HBIOS disk write function |
|
|
|
|
|
|
|
|
ld a,BF_DIOWRITE ; HBIOS disk write function |
|
|
ld (func),a ; save it |
|
|
ld (func),a ; save it |
|
|
jr dsk$rw ; common disk read/write code |
|
|
jr dsk$rw ; common disk read/write code |
|
|
|
|
|
|
|
|
@ -791,7 +637,7 @@ dsk$io: |
|
|
|
|
|
|
|
|
; Seek to requested sector in DE:HL |
|
|
; Seek to requested sector in DE:HL |
|
|
push bc ; save func & unit |
|
|
push bc ; save func & unit |
|
|
ld b,012h ; HBIOS func: seek |
|
|
|
|
|
|
|
|
ld b,BF_DIOSEEK ; HBIOS func: seek |
|
|
call 0FFF0h ; do it |
|
|
call 0FFF0h ; do it |
|
|
pop bc ; recover func & unit |
|
|
pop bc ; recover func & unit |
|
|
jp nz,err_diskio ; handle error |
|
|
jp nz,err_diskio ; handle error |
|
|
@ -872,7 +718,7 @@ err_perm: |
|
|
call prt_err |
|
|
call prt_err |
|
|
jr err_ret |
|
|
jr err_ret |
|
|
err_diskio: |
|
|
err_diskio: |
|
|
cp -10 ; HBIOS read only error |
|
|
|
|
|
|
|
|
cp ERR_READONLY ; HBIOS read only error |
|
|
jr z,err_rdonly ; if so, handle special |
|
|
jr z,err_rdonly ; if so, handle special |
|
|
ld a,(@ermde) ; get error mode |
|
|
ld a,(@ermde) ; get error mode |
|
|
cp 0FFh ; FFh means suppress |
|
|
cp 0FFh ; FFh means suppress |
|
|
@ -916,9 +762,6 @@ medid db 0 ; working media id value |
|
|
unit db 0 ; working disk unit num |
|
|
unit db 0 ; working disk unit num |
|
|
slice db 0 ; working slice num |
|
|
slice db 0 ; working slice num |
|
|
lba dw 0,0 ; working lba |
|
|
lba dw 0,0 ; working lba |
|
|
sps dw 0 ; sectors per slice |
|
|
|
|
|
cap_req dw 0,0 ; lba cap required for slice |
|
|
|
|
|
mbrsec ds 512 ; MBR sector buffer |
|
|
|
|
|
dma dw 0 ; current DMA address |
|
|
dma dw 0 ; current DMA address |
|
|
bank db 0 ; HBIOS DMA bank |
|
|
bank db 0 ; HBIOS DMA bank |
|
|
func db 0 ; HBIOS function |
|
|
func db 0 ; HBIOS function |
|
|
|