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.
265 lines
5.9 KiB
265 lines
5.9 KiB
;
|
|
;==================================================================================================
|
|
; MD DISK DRIVER (MEMORY DISK)
|
|
;==================================================================================================
|
|
;
|
|
MD_DISPATCH:
|
|
LD A,B ; GET REQUESTED FUNCTION
|
|
AND $0F
|
|
JP Z,MD_READ
|
|
DEC A
|
|
JP Z,MD_WRITE
|
|
DEC A
|
|
JP Z,MD_STATUS
|
|
DEC A
|
|
JP Z,MD_MEDIA
|
|
DEC A
|
|
JP Z,MD_CAP
|
|
DEC A
|
|
JP Z,MD_GEOM
|
|
CALL PANIC
|
|
;
|
|
;
|
|
;
|
|
MD_MEDIA:
|
|
LD A,C ; DEVICE/UNIT IS IN C
|
|
AND $0F ; ISOLATE UNIT NUM
|
|
CP 2 ; CHECK FOR MAX UNIT EXCEEDED
|
|
CALL NC,PANIC ; PANIC IF TOO HIGH
|
|
ADD A,MID_MDROM ; SET CORRECT MEDIA VALUE
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
MD_INIT:
|
|
PRTS("MD: UNITS=2 $")
|
|
PRTS("ROMDISK=$")
|
|
LD HL,ROMSIZE - 128
|
|
CALL PRTDEC
|
|
PRTS("KB RAMDISK=$")
|
|
LD HL,RAMSIZE - 128
|
|
CALL PRTDEC
|
|
PRTS("KB$")
|
|
XOR A ; INIT SUCCEEDED
|
|
RET ; RETURN
|
|
;
|
|
;
|
|
;
|
|
MD_STATUS:
|
|
XOR A ; ALWAYS OK
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
MD_CAP:
|
|
LD A,C ; DEVICE/UNIT IS IN C
|
|
AND $0F ; ISOLATE UNIT NUM
|
|
JR Z,MD_CAP0 ; UNIT 0
|
|
DEC A ; TRY UNIT 1
|
|
JR Z,MD_CAP1 ; UNIT 1
|
|
CALL PANIC ; PANIC ON INVALID UNIT
|
|
MD_CAP0:
|
|
LD HL,(HCB + HCB_ROMBANKS) ; POINT TO ROM BANK COUNT
|
|
JR MD_CAP2
|
|
MD_CAP1:
|
|
LD HL,(HCB + HCB_RAMBANKS) ; POINT TO RAM BANK COUNT
|
|
MD_CAP2:
|
|
LD H,(HL) ; H := # BANKS
|
|
LD E,64 ; # 512 BYTE BLOCKS / BANK
|
|
CALL MULT8 ; HL := TOTAL # 512 BYTE BLOCKS
|
|
LD DE,0 ; NEVER EXCEEDS 64K, ZERO HIGH WORD
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
MD_GEOM:
|
|
; RAM/ROM DISKS ALLOW CHS STYLE ACCESS BY EMULATING
|
|
; A DISK DEVICE WITH 1 HEAD AND 16 SECTORS / TRACK.
|
|
CALL MD_CAP ; HL := CAPACITY IN BLOCKS
|
|
EX DE,HL ; SWAP
|
|
LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT
|
|
LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION
|
|
LD B,4 ; PREPARE TO DIVIDE BY 16
|
|
MD_GEOM1:
|
|
SRL H ; SHIFT H
|
|
RR L ; SHIFT L
|
|
DJNZ MD_GEOM1 ; DO 4 BITS TO DIVIDE BY 16
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
;
|
|
;
|
|
MD_READ:
|
|
CALL MD_IOSETUP ; SETUP FOR MEMORY COPY
|
|
#IF (MDTRACE >= 2)
|
|
LD (MD_SRC),HL
|
|
LD (MD_DST),DE
|
|
LD (MD_LEN),BC
|
|
#ENDIF
|
|
PUSH BC
|
|
LD C,A ; SOURCE BANK
|
|
LD B,BID_BIOS ; DESTINATION BANK IS RAM BANK 1 (HBIOS)
|
|
#IF (MDTRACE >= 2)
|
|
LD (MD_SRCBNK),BC
|
|
CALL MD_PRT
|
|
#ENDIF
|
|
LD A,C ; GET SOURCE BANK
|
|
LD (HB_SRCBNK),A ; SET IT
|
|
LD A,B ; GET DESTINATION BANK
|
|
LD (HB_DSTBNK),A ; SET IT
|
|
POP BC
|
|
CALL BNKCPY ; DO THE INTERBANK COPY
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
MD_WRITE:
|
|
LD A,C ; DEVICE/UNIT IS IN C
|
|
AND $0F ; ISOLATE UNIT NUM
|
|
LD A,1 ; PREPARE TO RETURN FALSE
|
|
RET Z ; RETURN ERROR IF ROM UNIT
|
|
|
|
CALL MD_IOSETUP ; SETUP FOR MEMORY COPY
|
|
EX DE,HL ; SWAP SRC/DEST FOR WRITE
|
|
#IF (MDTRACE >= 2)
|
|
LD (MD_SRC),HL
|
|
LD (MD_DST),DE
|
|
LD (MD_LEN),BC
|
|
#ENDIF
|
|
PUSH BC
|
|
LD C,BID_BIOS ; SOURCE BANK IS RAM BANK 1 (HBIOS)
|
|
LD B,A ; DESTINATION BANK
|
|
#IF (MDTRACE >= 2)
|
|
LD (MD_SRCBNK),BC
|
|
CALL MD_PRT
|
|
#ENDIF
|
|
LD A,C ; GET SOURCE BANK
|
|
LD (HB_SRCBNK),A ; SET IT
|
|
LD A,B ; GET DESTINATION BANK
|
|
LD (HB_DSTBNK),A ; SET IT
|
|
POP BC
|
|
CALL BNKCPY ; DO THE INTERBANK COPY
|
|
XOR A
|
|
RET
|
|
;
|
|
; SETUP FOR MEMORY COPY
|
|
; A=BANK SELECT
|
|
; BC=COPY SIZE
|
|
; DE=DESTINATION
|
|
; HL=SOURCE
|
|
;
|
|
; ASSUMES A "READ" OPERATION. HL AND DE CAN BE SWAPPED
|
|
; AFTERWARDS TO ACHIEVE A WRITE OPERATION
|
|
;
|
|
; ON INPUT, WE HAVE LBA ADDRESSING IN HSTLBAHI:HSTLBALO
|
|
; BUT WE NEVER HAVE MORE THAN $FFFF BLOCKS IN A RAM/ROM DISK,
|
|
; SO THE HIGH WORD (HSTLBAHI) IS IGNORED
|
|
;
|
|
; EACH RAM/ROM BANK IS 32K BY DEFINITION AND EACH SECTOR IS 512
|
|
; BYTES BY DEFINITION. SO, EACH RAM/ROM BANK CONTAINS 64 SECTORS
|
|
; (32,768 / 512 = 64). THEREFORE, YOU CAN THINK OF LBA AS
|
|
; 00000BBB:BBOOOOOO IS WHERE THE 'B' BITS REPRESENT THE BANK NUMBER
|
|
; AND THE 'O' BITS REPRESENT THE SECTOR NUMBER WITHIN THE BANK.
|
|
;
|
|
; TO EXTRACT THE BANK NUMBER, WE CAN LEFT SHIFT TWICE TO GIVE US:
|
|
; 000BBBBB:OOOOOOOO. FROM THIS WE CAN EXTRACT THE MSB
|
|
; TO USE AS THE BANK NUMBER. NOTE THAT THE "RAW" BANK NUMBER MUST THEN
|
|
; BE OFFSET TO THE START OF THE ROM/RAM BANKS.
|
|
; ALSO NOTE THAT THE HIGH BIT OF THE BANK NUMBER REPRESENTS "RAM" SO THIS
|
|
; BIT MUST ALSO BE SET ACCORDING TO THE UNIT BEING ADDRESSED.
|
|
;
|
|
; TO GET THE BYTE OFFSET, WE THEN RIGHT SHIFT THE LSB BY 1 TO GIVE US:
|
|
; 0OOOOOOO AND EXTRACT THE LSB TO REPRESENT THE MSB OF
|
|
; THE BYTE OFFSET. THE LSB OF THE BYTE OFFSET IS ALWAYS 0 SINCE WE ARE
|
|
; DEALING WITH 512 BYTE BOUNDARIES.
|
|
;
|
|
MD_IOSETUP:
|
|
LD HL,(HSTLBALO) ; HL := LOW WORD OF LBA
|
|
; ALIGN BITS TO EXTRACT BANK NUMBER FROM H
|
|
SLA L ; LEFT SHIFT ONE BIT
|
|
RL H ; FULL WORD
|
|
SLA L ; LEFT SHIFT ONE BIT
|
|
RL H ; FULL WORD
|
|
LD C,H ; BANK NUMBER FROM H TO C
|
|
; GET BANK NUM TO A AND SET FLAG Z=ROM, NZ=RAM
|
|
LD A,(HSTDSK) ; DEVICE/UNIT TO A
|
|
AND $01 ; ISOLATE LOW BIT, SET ZF
|
|
LD A,C ; BANK VALUE INTO A
|
|
PUSH AF ; SAVE IT FOR NOW
|
|
; ADJUST L TO HAVE MSB OF OFFSET
|
|
SRL L ; ADJUST L TO BE MSB OF BYTE OFFSET
|
|
LD H,L ; MOVE MSB TO H WHERE IT BELONGS
|
|
LD L,0 ; AND ZERO L SO HL IS NOW BYTE OFFSET
|
|
; LOAD DESTINATION AND COUNT
|
|
LD DE,(DIOBUF) ; DMA ADDRESS IS DESTINATION
|
|
LD BC,512 ; ALWAYS COPY ONE SECTOR
|
|
; FINISH UP
|
|
POP AF ; GET BANK AND FLAGS BACK
|
|
JR Z,MD_IOSETUP2 ; DO ROM DRIVE, ELSE FALL THRU FOR RAM DRIVE
|
|
;
|
|
MD_IOSETUP1: ; RAM
|
|
ADD A,BID_RAMD0
|
|
RET
|
|
;
|
|
MD_IOSETUP2: ; ROM
|
|
ADD A,BID_ROMD0
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
MD_PRT:
|
|
PUSH AF
|
|
PUSH BC
|
|
PUSH DE
|
|
PUSH HL
|
|
|
|
CALL NEWLINE
|
|
|
|
LD DE,MDSTR_PREFIX
|
|
CALL WRITESTR
|
|
|
|
CALL PC_SPACE
|
|
LD DE,MDSTR_SRC
|
|
CALL WRITESTR
|
|
LD A,(MD_SRCBNK)
|
|
CALL PRTHEXBYTE
|
|
CALL PC_COLON
|
|
LD BC,(MD_SRC)
|
|
CALL PRTHEXWORD
|
|
|
|
CALL PC_SPACE
|
|
LD DE,MDSTR_DST
|
|
CALL WRITESTR
|
|
LD A,(MD_DSTBNK)
|
|
CALL PRTHEXBYTE
|
|
CALL PC_COLON
|
|
LD BC,(MD_DST)
|
|
CALL PRTHEXWORD
|
|
|
|
CALL PC_SPACE
|
|
LD DE,MDSTR_LEN
|
|
CALL WRITESTR
|
|
LD BC,(MD_LEN)
|
|
CALL PRTHEXWORD
|
|
|
|
POP HL
|
|
POP DE
|
|
POP BC
|
|
POP AF
|
|
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
MD_SRCBNK .DB 0
|
|
MD_DSTBNK .DB 0
|
|
MD_SRC .DW 0
|
|
MD_DST .DW 0
|
|
MD_LEN .DW 0
|
|
;
|
|
MDSTR_PREFIX .TEXT "MD:$"
|
|
MDSTR_SRC .TEXT "SRC=$"
|
|
MDSTR_DST .TEXT "DEST=$"
|
|
MDSTR_LEN .TEXT "LEN=$"
|