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.
 
 
 
 
 
 

303 lines
5.4 KiB

;
;==================================================================================================
; HDSK DISK DRIVER
;==================================================================================================
;
; IO PORT ADDRESSES
;
HDSK_IO .EQU $FD
;
HDSK_CMDNONE .EQU 0
HDSK_CMDRESET .EQU 1
HDSK_CMDREAD .EQU 2
HDSK_CMDWRITE .EQU 3
HDSK_CMDPARAM .EQU 4
;
; STATUS
;
HDSKRC_OK .EQU 0
;
;
;
HDSK_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F
JR Z,HDSK_READ
DEC A
JR Z,HDSK_WRITE
DEC A
JR Z,HDSK_STATUS
DEC A
JR Z,HDSK_MEDIA
DEC A
JR Z,HDSK_CAP
DEC A
JR Z,HDSK_GEOM
CALL PANIC
;
; HDSK_MEDIA
;
HDSK_MEDIA:
LD A,C ; GET THE DEVICE/UNIT
AND $0F ; ISOLATE UNIT
CP HDSKCNT ; NUM UNITS
LD A,MID_HD ; ASSUME WE ARE OK
RET C ; RETURN
XOR A ; NO MEDIA
RET ; AND RETURN
;
;
;
HDSK_INIT:
PRTS("HDSK: UNITS=$")
LD A,HDSKCNT
CALL PRTDECB
;
XOR A
DEC A ; INITIAL STATUS IS NOT READY $FF
LD (HDSK_STAT),A ; SAVE IT
XOR A ; INIT SUCCEEDED
RET ; RETURN
;
;
;
HDSK_STATUS:
LD A,(HDSK_STAT) ; LOAD STATUS
OR A ; SET FLAGS
RET
;
; GET DISK CAPACITY
; RETURN HL:DE=BLOCK COUNT, BC=BLOCK SIZE
; SLICE C/H/S = 65/16/16 OR 16,640 TOTAL SECTORS
; ASSUME 8 SLICES, SO 65 X 8 = 520 CYLS OR 16,640 * 8 = 133,120 TOTAL SECTORS
;
HDSK_CAP:
LD HL,133120 >> 16 ; BLOCK COUNT MSW
LD DE,133120 & $FFFF ; BLOCK COUNT LSW
LD BC,512 ; 512 BYTE SECTOR
XOR A ; SIGNAL SUCCESS
RET
;
; GET GEOMETRY
; RETURN HL:DE=CYLINDERS, B=HEADS, C=SECTORS
;
HDSK_GEOM:
LD HL,0 ; CYLINDER COUNT MSW
LD DE,520 ; CYLINDER COUNT LSW
LD B,16 ; HEADS / CYLINDER
LD C,16 ; SECTORS / TRACK
XOR A ; SIGNAL SUCCESS
RET
;
;
;
HDSK_READ:
LD A,HDSK_CMDREAD
JR HDSK_RW
;
;
;
HDSK_WRITE:
LD A,HDSK_CMDWRITE
JR HDSK_RW
;
;
;
HDSK_RW:
LD (HDSK_CMD),A
; CLEAR RESULTS
XOR A ; A = 0
LD (HDSK_RC),A ; CLEAR RETURN CODE
; INIT IF NEEDED
LD A,(HDSK_STAT) ; GET CURRENT STATUS
OR A ; SET FLAGS
CALL NZ,HDSK_RESET ; RESET IF NOT READY
; SET DEVICE
LD A,(HSTDSK)
AND $0F
LD (HDSK_DEVICE),A
; INCOMING TRK:SEC ACTUALLY REPRESENTS 32 BIT LBA
; MAP TRK:SEC TO HDSK DRIVER AS TTSS:SS
LD A,(HSTTRK) ; LSB OF TRACK
LD (HDSK_TRK + 1),A ; MAPS TO MSB OF HDSK TRK
LD A,(HSTSEC + 1) ; MSB OF SECTOR
LD (HDSK_TRK),A ; MAPS TO LSB OF HDSK TRK
LD A,(HSTSEC) ; LSB OF SECTOR
LD (HDSK_SEC),A ; MAPS TO LSB OF HDSK SEC
; SET TRANSFER ADDRESS
LD BC,(DIOBUF)
LD (HDSK_DMA),BC
; EXECUTE COMMAND
LD B,7 ; SIZE OF PARAMETER BLOCK
LD HL,HDSK_PARMBLK ; START ADDRESS OF PARAMETER BLOCK
HDSK_RW1:
LD A,(HL) ; GET BYTE OF PARAMETER BLOCK
OUT ($FD),A ; SEND IT TO PORT
INC HL ; POINT TO NEXT BYTE
DJNZ HDSK_RW1
IN A,($FD) ; GET RESULT CODE
LD (HDSK_RC),A
OR A
JR Z,HDSK_OK
JR HDSK_ERR
HDSK_ERR:
XOR A
DEC A ; A=$FF TO SIGNAL ERROR
LD (HDSK_STAT),A ; SAVE IT
#IF (HDSKTRACE >= 1)
PUSH AF
CALL HDSK_PRT
POP AF
#ENDIF
RET
HDSK_OK:
#IF (HDSKTRACE >= 2)
CALL HDSK_PRT
#ENDIF
XOR A
RET
;
;
;
HDSK_RESET:
LD B,32
LD A,HDSK_CMDRESET
HDSK_RESET1:
OUT ($FD),A
DJNZ HDSK_RESET1
XOR A ; STATUS = OK
LD (HDSK_STAT),A ; SAVE IT
#IF (HDSKTRACE >= 2)
CALL NEWLINE
LD DE,HDSKSTR_PREFIX
CALL WRITESTR
CALL PC_SPACE
LD DE,HDSKSTR_RESET
CALL WRITESTR
#ENDIF
RET
;
;
;
HDSK_PRT:
CALL NEWLINE
LD DE,HDSKSTR_PREFIX
CALL WRITESTR
CALL PC_SPACE
LD DE,HDSKSTR_CMD
CALL WRITESTR
LD A,(HDSK_CMD)
CALL PRTHEXBYTE
CALL PC_SPACE
CALL PC_LBKT
LD A,(HDSK_CMD)
LD DE,HDSKSTR_NONE
CP HDSK_CMDNONE
JP Z,HDSK_PRTCMD
LD DE,HDSKSTR_RESET
CP HDSK_CMDRESET
JP Z,HDSK_PRTCMD
LD DE,HDSKSTR_READ
CP HDSK_CMDREAD
JP Z,HDSK_PRTCMD
LD DE,HDSKSTR_WRITE
CP HDSK_CMDWRITE
JP Z,HDSK_PRTCMD
LD DE,HDSKSTR_PARAM
CP HDSK_CMDPARAM
JP Z,HDSK_PRTCMD
LD DE,HDSKSTR_UNKCMD
HDSK_PRTCMD:
CALL WRITESTR
CALL PC_RBKT
LD A,(HDSK_CMD)
CP HDSK_CMDREAD
JR Z,HDSK_PRTRW
CP HDSK_CMDWRITE
JR Z,HDSK_PRTRW
RET
HDSK_PRTRW:
CALL PC_SPACE
LD A,(HDSK_DEVICE)
CALL PRTHEXBYTE
CALL PC_SPACE
LD BC,(HDSK_TRK)
CALL PRTHEXWORD
CALL PC_SPACE
LD A,(HDSK_SEC)
CALL PRTHEXBYTE
CALL PC_SPACE
LD BC,(HDSK_DMA)
CALL PRTHEXWORD
CALL PC_SPACE
LD DE,HDSKSTR_ARROW
CALL WRITESTR
CALL PC_SPACE
LD DE,HDSKSTR_RC
CALL WRITESTR
LD A,(HDSK_RC)
CALL PRTHEXBYTE
CALL PC_SPACE
CALL PC_LBKT
LD A,(HDSK_RC)
LD DE,HDSKSTR_RCOK
CP HDSKRC_OK
JP Z,HDSK_PRTRC
LD DE,HDSKSTR_RCUNK
HDSK_PRTRC:
CALL WRITESTR
CALL PC_RBKT
RET
;
;
;
HDSKSTR_PREFIX .TEXT "HDSK:$"
HDSKSTR_CMD .TEXT "CMD=$"
HDSKSTR_RC .TEXT "RC=$"
HDSKSTR_ARROW .TEXT "-->$"
HDSKSTR_NONE .TEXT "NONE$"
HDSKSTR_RESET .TEXT "RESET$"
HDSKSTR_READ .TEXT "READ$"
HDSKSTR_WRITE .TEXT "WRITE$"
HDSKSTR_PARAM .TEXT "PARAM$"
HDSKSTR_UNKCMD .TEXT "UNKCMD$"
HDSKSTR_RCOK .TEXT "OK$"
HDSKSTR_RCUNK .TEXT "UNKNOWN ERROR$"
;
;==================================================================================================
; HDSK DISK DRIVER - DATA
;==================================================================================================
;
HDSK_STAT .DB 0
HDSK_RC .DB 0
;
HDSK_PARMBLK:
HDSK_CMD .DB 0 ; COMMAND (HDSK_READ, HDSK_WRITE, ...)
HDSK_DEVICE .DB 0 ; 0..7, HARD DISK UNIT
HDSK_SEC .DB 0 ; 0..255 SECTOR
HDSK_TRK .DW 0 ; 0..2047 TRACK
HDSK_DMA .DW 0 ; DEFINES WHERE RESULT IS PLACED IN MEMORY