Browse Source

CPM3 DiskIO routines now use HBIOS EXT_SLICE function during Drive Select

master
Mark Pruden 1 year ago
parent
commit
8e56b270c4
  1. 1
      Doc/ChangeLog.txt
  2. 219
      Source/CPM3/diskio.z80
  3. 2
      Source/ver.inc
  4. 2
      Source/ver.lib

1
Doc/ChangeLog.txt

@ -42,6 +42,7 @@ Version 3.5
- MAP: Added new HBIOS function EXT_SLICE (orginally SYSGET_DIOMED) - MAP: Added new HBIOS function EXT_SLICE (orginally SYSGET_DIOMED)
- MAP: ROMLDR now uses EXT_SLICE to get Slice Sector for boot - MAP: ROMLDR now uses EXT_SLICE to get Slice Sector for boot
- MAP: CBIOS now uses EXT_SLICE during drive selection - MAP: CBIOS now uses EXT_SLICE during drive selection
- MAP: CPM3 Boot Loader, and BIOS (drive select) now use EXT_SLICE
- M?R: Added REBOOT application - M?R: Added REBOOT application
Version 3.4 Version 3.4

219
Source/CPM3/diskio.z80

@ -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

2
Source/ver.inc

@ -2,7 +2,7 @@
#DEFINE RMN 5 #DEFINE RMN 5
#DEFINE RUP 0 #DEFINE RUP 0
#DEFINE RTP 0 #DEFINE RTP 0
#DEFINE BIOSVER "3.5.0-dev.92"
#DEFINE BIOSVER "3.5.0-dev.93"
#define rmj RMJ #define rmj RMJ
#define rmn RMN #define rmn RMN
#define rup RUP #define rup RUP

2
Source/ver.lib

@ -3,5 +3,5 @@ rmn equ 5
rup equ 0 rup equ 0
rtp equ 0 rtp equ 0
biosver macro biosver macro
db "3.5.0-dev.92"
db "3.5.0-dev.93"
endm endm

Loading…
Cancel
Save