Browse Source

Slice Protection, Issue #366

- Dean Jenkins has motivated me to implement additional protection from using a slice that does not fit within the capacity of the physical disk being used.  You can still assign an unusable slice, but when you try to refer to it, you will immediately get a "no disk" error from the OS.
pull/367/head
Wayne Warthen 2 years ago
parent
commit
93dcfe9610
  1. 90
      Source/CBIOS/cbios.asm
  2. 50
      Source/CPM3/diskio.z80
  3. 2
      Source/ver.inc
  4. 2
      Source/ver.lib

90
Source/CBIOS/cbios.asm

@ -1511,8 +1511,8 @@ DSK_MBR3:
; ;
DSK_MBR4: DSK_MBR4:
; IF BOOT FROM PARTITION, USE NEW SECTORS PER SLICE VALUE ; IF BOOT FROM PARTITION, USE NEW SECTORS PER SLICE VALUE
LD HL,16384 ; NEW SECTORS PER SLICE
LD (SPS),HL ; SAVE IT
LD HL,16384 ; NEW SECTORS PER SLICE
LD (SPS),HL ; SAVE IT
; UPDATE MEDIA ID ; UPDATE MEDIA ID
LD A,MID_HDNEW ; NEW MEDIA ID LD A,MID_HDNEW ; NEW MEDIA ID
@ -1520,20 +1520,79 @@ DSK_MBR4:
; ;
DSK_MBR5: DSK_MBR5:
; ADJUST LBA OFFSET BASED ON TARGET SLICE ; ADJUST LBA OFFSET BASED ON TARGET SLICE
LD A,(SLICE) ; GET SLICE, A IS LOOP CNT
LD HL,(SEKLBA) ; SET DE:HL
LD DE,(SEKLBA+2) ; ... TO STARTING LBA
LD BC,(SPS) ; SECTORS PER SLICE
DSK_MBR6:
OR A ; SET FLAGS TO CHECK LOOP CNTR
JR Z,DSK_MBR8 ; DONE IF COUNTER EXHAUSTED
ADD HL,BC ; ADD ONE SLICE TO LOW WORD
JR NC,DSK_MBR7 ; CHECK FOR CARRY
INC DE ; IF SO, BUMP HIGH WORD
DSK_MBR7:
DEC A ; DEC LOOP DOWNCOUNTER
JR DSK_MBR6 ; AND LOOP
LD A,(SLICE) ; GET SLICE, A IS LOOP CNT
LD HL,(SEKLBA) ; SET DE:HL
LD DE,(SEKLBA+2) ; ... TO STARTING LBA
LD BC,(SPS) ; SECTORS PER SLICE
DSK_MBR6:
OR A ; SET FLAGS TO CHECK LOOP CNTR
JR Z,DSK_MBR8 ; DONE IF COUNTER EXHAUSTED
ADD HL,BC ; ADD ONE SLICE TO LOW WORD
JR NC,DSK_MBR7 ; CHECK FOR CARRY
INC DE ; IF SO, BUMP HIGH WORD
DSK_MBR7:
DEC A ; DEC LOOP DOWNCOUNTER
JR DSK_MBR6 ; AND LOOP
DSK_MBR8: DSK_MBR8:
; 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
;
#IFDEF PLTWBW
; GET DSK_CAP (DE:HL)
LD B,BF_DIOCAP ; HBIOS DISK CAPACITY FUNC
LD A,(SEKUNIT) ; DISK UNIT NUMBER
LD C,A ; ... INTO C
RST 08 ; HBIOS CALL (DE:HL = CAPACITY)
#ENDIF
;
#IFDEF PLTUNA
; GET DSK_CAP (DE:HL)
LD C,$45 ; UBIOS DISK INFO FUNC
LD A,(SEKUNIT) ; DISK UNIT NUMBER
LD B,A ; ... INTO B
RST 08 ; CALL UNA (DE:HL = CAPACITY)
#ENDIF
;
; 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!
JR NC,DSK_MBR10 ; IF NO OVERFLOW, CONTINUE
OR $FF ; SIGNAL ERROR
RET ; DONE
;
DSK_MBR10:
; FINALIZE SLICE LBA
SET 7,D ; SET LBA ACCESS FLAG SET 7,D ; SET LBA ACCESS FLAG
; RESAVE IT ; RESAVE IT
LD (SEKLBA),HL ; LOWORD LD (SEKLBA),HL ; LOWORD
@ -1758,6 +1817,7 @@ CCPBUF .DW 0 ; ADDRESS OF CCP BUF IN BIOS BANK
MEDID .DB 0 ; TEMP STORAGE FOR MEDIA ID MEDID .DB 0 ; TEMP STORAGE FOR MEDIA ID
SLICE .DB 0 ; CURRENT SLICE SLICE .DB 0 ; CURRENT SLICE
SPS .DW 0 ; SECTORS PER SLICE SPS .DW 0 ; SECTORS PER SLICE
CAP_REQ .DW 0,0 ; LBA CAP REQUIRED FOR SLICE
STKSAV .DW 0 ; TEMP SAVED STACK POINTER STKSAV .DW 0 ; TEMP SAVED STACK POINTER
; ;
#IFDEF PLTWBW #IFDEF PLTWBW

50
Source/CPM3/diskio.z80

@ -38,7 +38,7 @@
extrn ?bnkxlt extrn ?bnkxlt
extrn phex8, cout
extrn phex16, phex8, cout, crlf, crlf2
; CP/M 3 Disk definition macros ; CP/M 3 Disk definition macros
@ -600,6 +600,53 @@ boot7:
dec a ; dec loop downcounter dec a ; dec loop downcounter
jr boot6 ; and loop jr boot6 ; and loop
boot8: 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
; Finalize slice lba
set 7,d ; set LBA access flag set 7,d ; set LBA access flag
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
@ -870,6 +917,7 @@ 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 sps dw 0 ; sectors per slice
cap_req dw 0,0 ; lba cap required for slice
mbrsec ds 512 ; MBR sector buffer 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

2
Source/ver.inc

@ -2,7 +2,7 @@
#DEFINE RMN 4 #DEFINE RMN 4
#DEFINE RUP 0 #DEFINE RUP 0
#DEFINE RTP 0 #DEFINE RTP 0
#DEFINE BIOSVER "3.4.0-dev.1"
#DEFINE BIOSVER "3.4.0-dev.2"
#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 4
rup equ 0 rup equ 0
rtp equ 0 rtp equ 0
biosver macro biosver macro
db "3.4.0-dev.1"
db "3.4.0-dev.2"
endm endm

Loading…
Cancel
Save