mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
6.9 KiB
284 lines
6.9 KiB
;
|
|
;==================================================================================================
|
|
; CH376 NATIVE MASS STORAGE DRIVER
|
|
;==================================================================================================
|
|
;
|
|
|
|
#include "./ch376-native/scsi-drv.s"
|
|
|
|
; find and mount all Mass Storage USB devices
|
|
CHSCSI_INIT .EQU _chscsi_init
|
|
|
|
; DRIVER FUNCTION TABLE
|
|
;
|
|
_ch_scsi_fntbl
|
|
CH_SCSI_FNTBL:
|
|
.DW CH_SCSI_STATUS
|
|
.DW CH_SCSI_RESET
|
|
.DW CH_SCSI_SEEK
|
|
.DW CH_SCSI_READ
|
|
.DW CH_SCSI_WRITE
|
|
.DW CH_SCSI_VERIFY
|
|
.DW CH_SCSI_FORMAT
|
|
.DW CH_SCSI_DEVICE
|
|
.DW CH_SCSI_MEDIA
|
|
.DW CH_SCSI_DEFMED
|
|
.DW CH_SCSI_CAP
|
|
.DW CH_SCSI_GEOM
|
|
#IF (($ - CH_SCSI_FNTBL) != (DIO_FNCNT * 2))
|
|
.ECHO "*** INVALID CH_SCSI_FNTBL FUNCTION TABLE ***\n"
|
|
#ENDIF
|
|
|
|
CH_SCSI_STATUS:
|
|
; LD A, (IY)
|
|
XOR A
|
|
RET
|
|
|
|
CH_SCSI_RESET:
|
|
; LD A, (IY)
|
|
XOR A
|
|
RET
|
|
|
|
; ### Function 0x12 -- Disk Seek (DIOSEEK)
|
|
;
|
|
; Inputs:
|
|
; IY: device config pointer
|
|
; DEHL: Sector Address
|
|
;
|
|
; Outputs:
|
|
; A: Status
|
|
;
|
|
; This function will set the desired sector to be used for the next I/O
|
|
; operation. The returned Status (A) is a standard HBIOS result code.
|
|
;
|
|
; The double-word Sector Address (DEHL) can represent either a Logical
|
|
; Block Address (LBA) or a Cylinder/Head/Sector (CHS). Bit 7 of D is
|
|
; set (1) for LBA mode and cleared (0) for CHS mode.
|
|
;
|
|
; For LBA mode operation, the high bit is set and the rest of the
|
|
; double-word is then treated as the logical sector address.
|
|
;
|
|
; For CHS mode operation, the Sector Address (DEHL) registers are
|
|
; interpreted as: D=Head, E=Sector, and HL=Track. All values (including
|
|
; sector) are 0 relative.
|
|
;
|
|
CH_SCSI_SEEK:
|
|
BIT 7,D ; CHECK FOR LBA FLAG
|
|
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
|
|
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
|
|
EX DE, HL
|
|
|
|
push IY
|
|
CALL _chnative_seek
|
|
RET
|
|
;
|
|
; ### Function 0x13 -- Disk Read (DIOREAD)
|
|
;
|
|
; Inputs
|
|
; IY: device config pointer
|
|
; D: Buffer Bank ID
|
|
; E: Sector Count
|
|
; HL: Buffer Address
|
|
;
|
|
; Outputs
|
|
; A: Status
|
|
; E: Sectors Read
|
|
;
|
|
; Read Sector Count (E) sectors into the buffer located in Buffer Bank ID (D)
|
|
; at Buffer Address (HL) starting at the Current Sector. The returned
|
|
; Status (A) is a standard HBIOS result code.
|
|
;
|
|
CH_SCSI_READ:
|
|
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR
|
|
|
|
; call scsi_read(IY, HL);
|
|
; HL = HL + 512
|
|
push hl
|
|
push iy
|
|
call _scsi_read
|
|
ld a, l
|
|
pop iy
|
|
pop hl
|
|
ld bc, 512
|
|
add hl, bc
|
|
ret
|
|
;
|
|
; ### Function 0x14 -- Disk Write (DIOWRITE)
|
|
;
|
|
; Inputs
|
|
; IY: device config pointer
|
|
; D: Buffer Bank ID
|
|
; E: Sector Count
|
|
; HL: Buffer Address
|
|
;
|
|
; Outputs
|
|
; A: Status
|
|
; E: Sectors Written
|
|
;
|
|
; Write Sector Count (E) sectors from the buffer located in Buffer Bank ID (D)
|
|
; at Buffer Address (HL) starting at the Current Sector. The returned
|
|
; Status (A) is a standard HBIOS result code.
|
|
;
|
|
CH_SCSI_WRITE:
|
|
CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR
|
|
|
|
; call scsi_write(IY, HL);
|
|
; HL = HL + 512
|
|
push hl
|
|
push iy
|
|
call _scsi_write
|
|
ld a, l
|
|
pop iy
|
|
pop hl
|
|
ld bc, 512
|
|
add hl, bc
|
|
ret
|
|
|
|
CH_SCSI_VERIFY:
|
|
CH_SCSI_FORMAT:
|
|
LD A, $FF
|
|
OR A
|
|
RET
|
|
;
|
|
; ### Function 0x17 -- Disk Device (DIODEVICE)
|
|
;
|
|
; Inputs
|
|
; IY: device config pointer
|
|
;
|
|
; Outputs
|
|
; A: Status
|
|
; C: Device Attributes
|
|
; D: Device Type (DIODEV_USB)
|
|
; E: Device Number (1)
|
|
; H: Device Unit Mode (0)
|
|
; L: Device I/O Base Address
|
|
;
|
|
; Reports device information. The Status (A) is a standard
|
|
; HBIOS result code.
|
|
;
|
|
; The Device Attribute (C):
|
|
;
|
|
; | **Bits** | **Definition** |
|
|
; |---------:|--------------------------------------------------|
|
|
; | 7 | Floppy |
|
|
; | 6 | Removable |
|
|
; | 5 | High Capacity (>8 MB) |
|
|
;
|
|
; Low Capacity Devices??
|
|
;
|
|
; | **Bits** | **Definition** |
|
|
; |---------:|--------------------------------------------------|
|
|
; | 4-3 | Form Factor: 0=8", 1=5.25", 2=3.5", 3=Other |
|
|
; | 2 | Sides: 0=SS, 1=DS |
|
|
; | 1-0 | Density: 0=SD, 1=DD, 2=HD, 3=ED |
|
|
;
|
|
; High Capacity Devices
|
|
;
|
|
; | **Bits** | **Definition** |
|
|
; |---------:|--------------------------------------------------|
|
|
; | 4 | LBA Capable |
|
|
; | 3-0 | Media Type: 0=Hard Disk, 1=CF, 2=SD, 3=USB, |
|
|
; | | 4=ROM, 5=RAM, 6=RAMF, 7=FLASH, 8=CD-ROM, |
|
|
; | | 9=Cartridge, 10=usb-scsi, 11=usb-ufi |
|
|
;
|
|
CH_SCSI_DEVICE:
|
|
LD C, %00111010 ; TODO?
|
|
LD D, DIODEV_USB
|
|
LD E, (iy+16) ;???? device_config_storage.drive_index
|
|
LD H, 0
|
|
LD L, 0
|
|
XOR A
|
|
RET
|
|
;
|
|
; ### Function 0x18 -- Disk Media (DIOMEDIA)
|
|
;
|
|
; Inputs
|
|
; IY: device config pointer
|
|
; E: Flags
|
|
;
|
|
; Outputs
|
|
; A: Status
|
|
; E: Media ID
|
|
;
|
|
; Report the Media ID (E) for the for media. If bit 0 of Flags (E) is set,
|
|
; then media discovery or verification will be performed. The Status
|
|
; (A) is a standard HBIOS result code. If there is no media in device,
|
|
; function will return an error status.
|
|
;
|
|
CH_SCSI_MEDIA:
|
|
LD E, MID_HD ;todo verify device still active?
|
|
XOR A
|
|
RET
|
|
|
|
CH_SCSI_DEFMED:
|
|
LD A, $FF
|
|
OR A
|
|
RET
|
|
;
|
|
; ### Function 0x1A -- Disk Capacity (DIOCAPACITY)
|
|
;
|
|
; Inputs
|
|
; IY: device config pointer
|
|
;
|
|
; Outputs
|
|
; A: Status
|
|
; DEHL: Sector Count
|
|
; BC: Block Size
|
|
;
|
|
;
|
|
; Report the current media capacity information.
|
|
;
|
|
;
|
|
CH_SCSI_CAP:
|
|
push ix
|
|
ld ix, -8 ; reserve 8 bytes for
|
|
add ix, sp ; scsi_read_capacity_result
|
|
ld sp, ix
|
|
|
|
push ix
|
|
push iy
|
|
call _scsi_read_capacity
|
|
pop iy
|
|
pop ix
|
|
|
|
ld d, (ix) ; response.number_of_blocks[0]
|
|
ld e, (ix+1) ; response.number_of_blocks[1]
|
|
ld h, (ix+2) ; response.number_of_blocks[2]
|
|
ld l, (ix+3) ; response.number_of_blocks[3]
|
|
ld b, (ix+6) ; response.block_size[2]
|
|
ld c, (ix+7) ; response.block_size[3]
|
|
|
|
ld ix, 8
|
|
add ix, sp
|
|
ld sp, ix
|
|
pop ix
|
|
|
|
xor a ; todo determine a drive status
|
|
ret
|
|
;
|
|
; ### Function 0x1B -- Disk Geometry (DIOGEOMETRY)
|
|
;
|
|
; Inputs
|
|
; IY: device config pointer
|
|
;
|
|
; Outputs
|
|
; A: Status
|
|
; D: Heads
|
|
; E: Sectors
|
|
; HL: Cylinder Count
|
|
; BC: Block Size
|
|
;
|
|
; Report the simulated geometry for the media. The Status (A) is a
|
|
; standard HBIOS result code. If the media is unknown, an error will be returned.
|
|
;
|
|
; ** Does not appear to be used??
|
|
;
|
|
CH_SCSI_GEOM:
|
|
; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS
|
|
; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE
|
|
CALL CH_SCSI_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC
|
|
LD L,H ; DIVIDE BY 256 FOR # TRACKS
|
|
LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL
|
|
LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT
|
|
LD E,16 ; SECTORS / TRACK = 16
|
|
RET ; DONE, A STILL HAS CHUSB_CAP STATUS
|
|
|