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.
2940 lines
87 KiB
2940 lines
87 KiB
;__________________________________________________________________________________________________
|
|
;
|
|
; CBIOS FOR SBC
|
|
;
|
|
; BY ANDREW LYNCH, WITH INPUT FROM MANY SOURCES
|
|
; ROMWBW ADAPTATION BY WAYNE WARTHEN
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; TODO:
|
|
; 1) STACK LOCATION DURING BOOT OR WBOOT???
|
|
; 2) REVIEW USE OF DI/EI IN INIT
|
|
;
|
|
FALSE .EQU 0
|
|
TRUE .EQU ~FALSE
|
|
;
|
|
BDOS .EQU 5 ; BDOS FUNC INVOCATION VECTOR
|
|
;
|
|
; DEFINE PLATFORM STRING
|
|
;
|
|
#IFDEF PLTWBW
|
|
#DEFINE PLTSTR "WBW"
|
|
#ENDIF
|
|
#IFDEF PLTUNA
|
|
#DEFINE PLTSTR "UNA"
|
|
#ENDIF
|
|
;
|
|
; RAM DISK INITIALIZATION OPTIONS
|
|
;
|
|
CLR_NEVER .EQU 0 ; NEVER CLEAR RAM DISK
|
|
CLR_AUTO .EQU 1 ; CLEAR RAM DISK IF INVALID DIR ENTRIES
|
|
CLR_ALWAYS .EQU 2 ; ALWAYS CLEAR RAM DISK
|
|
;
|
|
; DISK OPERATION CONSTANTS
|
|
;
|
|
DOP_READ .EQU 0 ; READ OPERATION
|
|
DOP_WRITE .EQU 1 ; WRITE OPERATION
|
|
;
|
|
; DEFAULT IOBYTE VALUE:
|
|
; CON:=TTY: ------00
|
|
; RDR:=PTR: ----01--
|
|
; PUN:=PTP: --01----
|
|
; LST:=LPT: 10------
|
|
; ========
|
|
; 10010100
|
|
;
|
|
DEF_IOBYTE .EQU %10010100 ; DEFAULT IOBYTE VALUE
|
|
;
|
|
; SPECIAL CHARACTER DEVICES IMPLEMENTED INTERNALLY
|
|
;
|
|
DEV_BAT .EQU $FE ; BAT:
|
|
DEV_NUL .EQU $FF ; NUL:
|
|
;
|
|
#INCLUDE "../HBIOS/ver.inc"
|
|
;
|
|
#INCLUDE "config.asm"
|
|
;
|
|
; MEMORY LAYOUT
|
|
;
|
|
IOBYTE .EQU 3 ; LOC IN PAGE 0 OF I/O DEFINITION BYTE
|
|
CDISK .EQU 4 ; LOC IN PAGE 0 OF CURRENT DISK NUMBER 0=A,...,15=P
|
|
;
|
|
CCP_LOC .EQU CPM_LOC
|
|
CCP_SIZ .EQU $800
|
|
;
|
|
BDOS_LOC .EQU CCP_LOC + CCP_SIZ
|
|
BDOS_SIZ .EQU $E00
|
|
;
|
|
CBIOS_LOC .EQU BDOS_LOC + BDOS_SIZ
|
|
CBIOS_END .EQU CPM_END
|
|
;
|
|
MEMTOP .EQU $10000
|
|
;
|
|
#IFDEF PLTWBW
|
|
#INCLUDE "../HBIOS/hbios.inc"
|
|
#ENDIF
|
|
;
|
|
#IFDEF PLTUNA
|
|
#INCLUDE "../UBIOS/ubios.inc"
|
|
#ENDIF
|
|
;
|
|
.ORG CBIOS_LOC ; DEFINED IN STD.ASM
|
|
;
|
|
STACK .EQU CBIOS_END ; USE SLACK SPACE FOR STACK AS NEEDED
|
|
;
|
|
;==================================================================================================
|
|
; CP/M JUMP VECTOR TABLE FOR INDIVIDUAL SUBROUTINES
|
|
;==================================================================================================
|
|
; These jumps are defined in the CP/M-80 v2.2 system guide and comprise
|
|
; the invariant part of the BIOS.
|
|
;
|
|
JP BOOT ; #0 - COLD START
|
|
WBOOTE JP WBOOT ; #1 - WARM START
|
|
JP CONST ; #2 - CONSOLE STATUS
|
|
JP CONIN ; #3 - CONSOLE CHARACTER IN
|
|
JP CONOUT ; #4 - CONSOLE CHARACTER OUT
|
|
JP LIST ; #5 - LIST CHARACTER OUT
|
|
JP PUNCH ; #6 - PUNCH CHARACTER OUT
|
|
JP READER ; #7 - READER CHARACTER IN
|
|
JP HOME ; #8 - MOVE HEAD TO HOME POSITION
|
|
JP SELDSK ; #9 - SELECT DISK
|
|
JP SETTRK ; #10 - SET TRACK NUMBER
|
|
JP SETSEC ; #11 - SET SECTOR NUMBER
|
|
JP SETDMA ; #12 - SET DMA ADDRESS
|
|
JP READ ; #13 - READ DISK
|
|
JP WRITE ; #14 - WRITE DISK
|
|
JP LISTST ; #15 - RETURN LIST STATUS
|
|
JP SECTRN ; #16 - SECTOR TRANSLATE
|
|
;
|
|
;==================================================================================================
|
|
; CBIOS STAMP FOR ROMWBW
|
|
;==================================================================================================
|
|
;
|
|
; RomWBW CBIOS places the following stamp data into page zero
|
|
; at address $40. The address range $40-$4F is reserved by CP/M
|
|
; as a scratch area for CBIOS. This data below is copied there at
|
|
; every warm start. It allows applications to identify RomWBW CBIOS.
|
|
; Additionally, it contains a pointer to additional CBIOS extension
|
|
; data (CBX) specific to RomWBW CBIOS.
|
|
;
|
|
; RomWBW CBIOS page zero stamp starts at $40
|
|
; $40-$41: Marker ('W', ~'W')
|
|
; $42-$43: Version bytes: major/minor, update/patch
|
|
; $44-$45: CBIOS Extension Info address
|
|
;
|
|
STPLOC .EQU $40
|
|
STPIMG: .DB 'W',~'W' ; MARKER
|
|
.DB RMJ << 4 | RMN ; FIRST BYTE OF VERSION INFO
|
|
.DB RUP << 4 | RTP ; SECOND BYTE OF VERSION INFO
|
|
.DW CBX ; ADDRESS OF CBIOS EXT DATA
|
|
STPSIZ .EQU $ - STPIMG
|
|
;
|
|
; The following section contains key information and addresses for the
|
|
; RomWBW CBIOS. A pointer to the start of this section is stored with
|
|
; with the ZPX data in page zero at $44 (see above).
|
|
;
|
|
CBX:
|
|
DEVMAPADR .DW DEVMAP ; DEVICE MAP ADDRESS
|
|
DRVMAPADR .DW 0 ; DRIVE MAP ADDRESS (FILLED IN LATER)
|
|
DPBMAPADR .DW DPBMAP ; DPB MAP ADDRESS
|
|
;
|
|
CBXSIZ .EQU $ - CBX
|
|
.ECHO "CBIOS extension info occupies "
|
|
.ECHO CBXSIZ
|
|
.ECHO " bytes.\n"
|
|
;
|
|
;==================================================================================================
|
|
; CHARACTER DEVICE MAPPING
|
|
;==================================================================================================
|
|
;
|
|
; MAP LOGICAL CHARACTER DEVICES TO PHYSICAL CHARACTER DEVICES
|
|
;
|
|
; IOBYTE (0003H)
|
|
; ==============
|
|
;
|
|
; Device LST: PUN: RDR: CON:
|
|
; Bit positions 7 6 5 4 3 2 1 0
|
|
;
|
|
; Dec Binary
|
|
;
|
|
; 0 00 TTY: TTY: TTY: TTY:
|
|
; 1 01 CRT: PTP: PTR: CRT:
|
|
; 2 10 LPT: UP1: UR1: BAT:
|
|
; 3 11 UL1: UP2: UR2: UC1:
|
|
;
|
|
; TTY: Teletype device (slow speed console)
|
|
; CRT: Cathode ray tube device (high speed console)
|
|
; BAT: Batch processing (input from RDR:, output to LST:)
|
|
; UC1: User-defined console
|
|
; PTR: Paper tape reader (high speed reader)
|
|
; UR1: User-defined reader #1
|
|
; UR2: User-defined reader #2
|
|
; PTP: Paper tape punch (high speed punch)
|
|
; UP1: User-defined punch #1
|
|
; UP2: User-defined punch #2
|
|
; LPT: Line printer
|
|
; UL1: User-defined list device #1
|
|
;
|
|
#IFDEF PLTUNA
|
|
|
|
LD_TTY .EQU 0 ; -> COM0:
|
|
LD_CRT .EQU 0 ; -> CRT:
|
|
LD_BAT .EQU DEV_BAT
|
|
LD_UC1 .EQU 0 ; -> COM1:
|
|
LD_PTR .EQU 0 ; -> COM1:
|
|
LD_UR1 .EQU 0 ; -> COM2:
|
|
LD_UR2 .EQU 0 ; -> COM3:
|
|
LD_PTP .EQU 0 ; -> COM1:
|
|
LD_UP1 .EQU 0 ; -> COM2:
|
|
LD_UP2 .EQU 0 ; -> COM3:
|
|
LD_LPT .EQU 0 ; -> LPT0:
|
|
LD_UL1 .EQU 0 ; -> LPT1:
|
|
|
|
#ELSE
|
|
|
|
LD_TTY .EQU CIODEV_CONSOLE ; -> COM0:
|
|
LD_CRT .EQU CIODEV_CONSOLE ; -> CRT:
|
|
LD_BAT .EQU DEV_BAT
|
|
LD_UC1 .EQU CIODEV_CONSOLE ; -> COM1:
|
|
LD_PTR .EQU CIODEV_CONSOLE ; -> COM1:
|
|
LD_UR1 .EQU CIODEV_CONSOLE ; -> COM2:
|
|
LD_UR2 .EQU CIODEV_CONSOLE ; -> COM3:
|
|
LD_PTP .EQU CIODEV_CONSOLE ; -> COM1:
|
|
LD_UP1 .EQU CIODEV_CONSOLE ; -> COM2:
|
|
LD_UP2 .EQU CIODEV_CONSOLE ; -> COM3:
|
|
LD_LPT .EQU CIODEV_CONSOLE ; -> LPT0:
|
|
LD_UL1 .EQU CIODEV_CONSOLE ; -> LPT1:
|
|
|
|
#ENDIF
|
|
;
|
|
DEVMAP:
|
|
;
|
|
; CONSOLE (CON:)
|
|
.DB LD_TTY ; CON:=TTY: (IOBYTE XXXXXX00)
|
|
.DB LD_CRT ; CON:=CRT: (IOBYTE XXXXXX01)
|
|
.DB LD_BAT ; CON:=BAT: (IOBYTE XXXXXX10)
|
|
.DB LD_UC1 ; CON:=UC1: (IOBYTE XXXXXX11)
|
|
; READER (RDR:)
|
|
.DB LD_TTY ; RDR:=TTY: (IOBYTE XXXX00XX)
|
|
.DB LD_PTR ; RDR:=PTR: (IOBYTE XXXX01XX)
|
|
.DB LD_UR1 ; RDR:=UR1: (IOBYTE XXXX10XX)
|
|
.DB LD_UR2 ; RDR:=UR2: (IOBYTE XXXX11XX)
|
|
; PUNCH (PUN:)
|
|
.DB LD_TTY ; PUN:=TTY: (IOBYTE XX00XXXX)
|
|
.DB LD_PTP ; PUN:=PTP: (IOBYTE XX01XXXX)
|
|
.DB LD_UP1 ; PUN:=UP1: (IOBYTE XX10XXXX)
|
|
.DB LD_UP2 ; PUN:=UP2: (IOBYTE XX11XXXX)
|
|
; LIST (LST:)
|
|
.DB LD_TTY ; LST:=TTY: (IOBYTE 00XXXXXX)
|
|
.DB LD_CRT ; LST:=CRT: (IOBYTE 01XXXXXX)
|
|
.DB LD_LPT ; LST:=LPT: (IOBYTE 10XXXXXX)
|
|
.DB LD_UL1 ; LST:=UL1: (IOBYTE 11XXXXXX)
|
|
;
|
|
;==================================================================================================
|
|
; DRIVE MAPPING TABLE (DRVMAP)
|
|
;==================================================================================================
|
|
;
|
|
; Disk mapping is done using a drive map table (DRVMAP) which is built
|
|
; dynamically at cold boot. See the DRV_INIT routine. This table is
|
|
; made up of entries as documented below. The table is prefixed with one
|
|
; byte indicating the number of entries. The postion of the entry indicates
|
|
; the drive letter, so the first entry is A:, the second entry is B:, etc.
|
|
;
|
|
; UNIT: BIOS DISK UNIT # (BYTE)
|
|
; SLICE: DISK SLICE NUMBER (BYTE)
|
|
; DPH: DPH ADDRESS OF DRIVE (WORD)
|
|
;
|
|
; DRVMAP --+
|
|
; | DRIVE A | DRIVE B | | DRIVE N |
|
|
; +-----V------+-------+-----+--------------------+ +--------------------+
|
|
; | N | UNIT | SLICE | DPH | UNIT | SLICE | DPH | ... | UNIT | SLICE | DPH |
|
|
; +----8+-----8+------8+-+-16+-----8+------8+-+-16+ +-----8+------8+-+-16+
|
|
; | | |
|
|
; +--------------------+ +-> [DPH] +-> [DPH]
|
|
; |
|
|
; V-----+-------+-------+-------+--------+-----+-----+-----+
|
|
; DPH: | XLT | 0000H | 0000H | 0000H | DIRBUF | DPB | CSV | ALV |
|
|
; +---16+-----16+-----16+-----16+------16+-+-16+-+-16+-+-16+
|
|
; (ONE DPH PER DRIVE) | | |
|
|
; | | +----------+
|
|
; | | |
|
|
; +----------------------+ V-------------+ V-------------+
|
|
; | | CSV BUF | | ALV BUF |
|
|
; | +-------------+ +-------------+
|
|
; | (CSZ BYTES) (ASZ BYTES)
|
|
; |
|
|
; +-----+-----+-----V-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
; DPB: | CSZ | ASZ | BLS | SPT | BSH | BLM | EXM | DSM | DRM | AL0 | AL1 | CKS | OFF |
|
|
; +---16+---16+----8+---16+----8+----8+----8+---16+---16+----8+----8+---16+---16+
|
|
; |<--- PREFIX ---->|<------------------- STANDARD CP/M DPB ------------------->|
|
|
;
|
|
;==================================================================================================
|
|
; DPB MAPPING TABLE
|
|
;==================================================================================================
|
|
;
|
|
; MAP MEDIA ID'S TO APPROPRIATE DPB ADDRESSEES
|
|
; THE ENTRIES IN THIS TABLE MUST CONCIDE WITH THE VALUES
|
|
; OF THE MEDIA ID'S (SAME SEQUENCE, NO GAPS)
|
|
;
|
|
.DB DPBCNT
|
|
;
|
|
DPBMAP:
|
|
.DW 0 ; MID_NONE (NO MEDIA)
|
|
.DW DPB_ROM ; MID_MDROM
|
|
.DW DPB_RAM ; MID_MDRAM
|
|
.DW DPB_RF ; MID_RF
|
|
.DW DPB_HD ; MID_HD
|
|
.DW DPB_FD720 ; MID_FD720
|
|
.DW DPB_FD144 ; MID_FD144
|
|
.DW DPB_FD360 ; MID_FD360
|
|
.DW DPB_FD120 ; MID_FD120
|
|
.DW DPB_FD111 ; MID_FD111
|
|
;
|
|
DPBCNT .EQU ($ - DPBMAP) / 2
|
|
;
|
|
;==================================================================================================
|
|
; BIOS FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
BOOT:
|
|
; STANDARD BOOT INVOCATION
|
|
LD SP,STACK ; STACK FOR INITIALIZATION
|
|
|
|
;
|
|
; COPY INITIALIZATION CODE TO RUNNINT LOCATION $8000
|
|
LD HL,BUFPOOL
|
|
LD DE,$8000
|
|
LD BC,CBIOS_END - BUFPOOL
|
|
PUSH HL ; SAVE START ADR FOR BELOW
|
|
PUSH HL ; SAVE START ADR AGAIN FOR BELOW
|
|
PUSH BC ; SAVE LENGTH FOR BELOW
|
|
LDIR ; COPY THE CODE
|
|
;
|
|
; CLEAR BUFFER
|
|
POP BC ; RECOVER LENGTH
|
|
POP HL ; RECOVER START
|
|
POP DE ; RECOVER START AS DEST
|
|
LD (HL),0 ; SET FIRST BYTE TO ZERO
|
|
INC DE ; OFFSET DEST
|
|
DEC BC ; REDUCE LEN BY ONE
|
|
LDIR ; USE LDIR TO FILL
|
|
;
|
|
CALL INIT ; PERFORM COLD BOOD ROUTINE
|
|
CALL RESCPM ; RESET CPM
|
|
CALL AUTOSUB ; PREP AUTO SUBMIT, IF APPROPRIATE
|
|
;
|
|
JR GOCPM ; THEN OFF TO CP/M WE GO...
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
REBOOT:
|
|
; REBOOT FROM ROM, REPLACES BOOT AFTER INIT
|
|
#IFDEF PLTUNA
|
|
DI ; NO INTERRUPTS
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,0 ; ROM BOOT BANK
|
|
CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE)
|
|
#ENDIF
|
|
#IFDEF PLTWBW
|
|
DI ; NO INTERRUPTS
|
|
LD A,0 ; ROM BOOT BANK
|
|
CALL HB_BNKSEL ; SELECT IT INTO LOW MEMORY
|
|
#ENDIF
|
|
;
|
|
; JUMP TO RESTART ADDRESS
|
|
JP 0
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
WBOOT:
|
|
LD SP,STACK ; STACK FOR INITIALIZATION
|
|
;
|
|
#IFDEF PLTUNA
|
|
; RESTORE COMMAND PROCESSOR FROM UNA BIOS CACHE
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_BIOS ; UBIOS_PAGE (SEE PAGES.INC)
|
|
RST 08 ; DO IT
|
|
PUSH DE ; SAVE PREVIOUS BANK
|
|
|
|
LD HL,(CCPBUF) ; ADDRESS OF CCP BUF IN BIOS MEM
|
|
LD DE,CCP_LOC ; ADDRESS IN HI MEM OF CCP
|
|
LD BC,CCP_SIZ ; SIZE OF CCP
|
|
LDIR ; DO IT
|
|
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
POP DE ; RECOVER OPERATING BANK
|
|
RST 08 ; DO IT
|
|
#ELSE
|
|
; RESTORE COMMAND PROCESSOR FROM CACHE IN HB BANK
|
|
LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY
|
|
LD DE,(BNKBIOS) ; D = DEST (USER BANK), E = SRC (BIOS BANK)
|
|
LD HL,CCP_SIZ ; HL = COPY LEN = SIZE OF COMMAND PROCESSOR
|
|
RST 08 ; DO IT
|
|
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
|
|
LD HL,(CCPBUF) ; COPY FROM FIXED LOCATION IN HB BANK
|
|
LD DE,CCP_LOC ; TO CCP LOCATION IN USR BANK
|
|
RST 08 ; DO IT
|
|
#ENDIF
|
|
;
|
|
; SOME APPLICATIONS STEAL THE BDOS SERIAL NUMBER STORAGE
|
|
; AREA (FIRST 6 BYTES OF BDOS) ASSUMING IT WILL BE RESTORED
|
|
; AT WARM BOOT BY RELOADING OF BDOS. WE DON'T WANT TO RELOAD
|
|
; BDOS, SO INSTEAD THE SERIAL NUMBER STORAGE IS FIXED HERE
|
|
; SO THAT THE DRI SERIAL NUMBER VERIFICATION DOES NOT FAIL
|
|
LD HL,BDOS_LOC
|
|
LD BC,6
|
|
XOR A
|
|
CALL FILL
|
|
;
|
|
CALL RESCPM ; RESET CPM
|
|
JR GOCPM ; THEN OFF TO CP/M WE GO...
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
RESCPM:
|
|
;
|
|
LD A,$C3 ; LOAD A WITH 'JP' INSTRUCTION (USED BELOW)
|
|
;
|
|
; CPU RESET / RST 0 / JP 0 -> WARM START CP/M
|
|
LD ($0000),A ; JP OPCODE GOES HERE
|
|
LD HL,WBOOTE ; GET WARM BOOT ENTRY ADDRESS
|
|
LD ($0001),HL ; AND PUT IT AT $0001
|
|
|
|
; ; INT / RST 38 -> INVOKE MONITOR
|
|
; LD ($0038),A
|
|
; LD HL,GOMON
|
|
; LD ($0039),HL
|
|
|
|
; ; INT / RST 38 -> PANIC
|
|
; LD ($0038),A
|
|
; LD HL,PANIC ; PANIC ROUTINE ADDRESS
|
|
; LD ($0039),HL ; POKE IT
|
|
|
|
; CALL 5 -> INVOKE BDOS
|
|
LD ($0005),A ; JP OPCODE AT $0005
|
|
LD HL,BDOS_LOC + 6 ; GET BDOS ENTRY ADDRESS
|
|
LD ($0006),HL ; PUT IT AT $0006
|
|
;
|
|
; INSTALL ROMWBW CBIOS PAGE ZERO STAMP AT $40
|
|
LD HL,STPIMG ; FORM STAMP DATA IMAGE
|
|
LD DE,STPLOC ; TO IT'S LOCATION IN PAGE ZERO
|
|
LD BC,STPSIZ ; SIZE OF BLOCK TO COPY
|
|
LDIR ; DO IT
|
|
;
|
|
; RESET (DE)BLOCKING ALGORITHM
|
|
CALL BLKRES
|
|
;
|
|
; DEFAULT DMA ADDRESS
|
|
LD BC,$80 ; DEFAULT DMA ADDRESS IS $80
|
|
CALL SETDMA ; SET IT
|
|
;
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
GOCPM:
|
|
;
|
|
; ENSURE VALID DISK AND JUMP TO CCP
|
|
LD A,(CDISK) ; GET CURRENT USER/DISK
|
|
AND $0F ; ISOLATE DISK PART
|
|
LD C,A ; SETUP C WITH CURRENT USER/DISK, ASSUME IT IS OK
|
|
CALL DSK_STATUS ; CHECK DISK STATUS
|
|
JR Z,CURDSK ; ZERO MEANS OK
|
|
LD A,(DEFDRIVE) ; CURRENT DRIVE NOT READY, USE DEFAULT
|
|
JR GOCCP ; JUMP TO COMMAND PROCESSOR
|
|
CURDSK:
|
|
LD A,(CDISK) ; GET CURRENT USER/DISK
|
|
GOCCP:
|
|
LD C,A ; SETUP C WITH CURRENT USER/DISK, ASSUME IT IS OK
|
|
JP CCP_LOC ; JUMP TO COMMAND PROCESSOR
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
GOMON:
|
|
CALL PANIC
|
|
;
|
|
; DI
|
|
; IM 1
|
|
;
|
|
; LD SP,STACK
|
|
;
|
|
; ; RELOAD MONITOR INTO RAM (IN CASE IT HAS BEEN OVERWRITTEN)
|
|
; CALL ROMPGZ
|
|
; LD HL,MON_IMG
|
|
; LD DE,MON_LOC
|
|
; LD BC,MON_SIZ
|
|
; LDIR
|
|
; CALL RAMPGZ
|
|
|
|
; ; JUMP TO MONITOR WARM ENTRY
|
|
; JP MON_UART
|
|
;
|
|
;
|
|
;==================================================================================================
|
|
; CHARACTER BIOS FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
CONST:
|
|
; CONSOLE STATUS, RETURN $FF IF CHARACTER READY, $00 IF NOT
|
|
;
|
|
LD B,BF_CIOIST ; B = FUNCTION
|
|
LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE
|
|
JR CONIO
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
CONIN:
|
|
; CONSOLE CHARACTER INTO REGISTER A
|
|
;
|
|
LD B,BF_CIOIN ; B = FUNCTION
|
|
LD HL,CIOIN ; HL = ADDRESS OF COMPLETION ROUTINE
|
|
JR CONIO
|
|
|
|
;__________________________________________________________________________________________________
|
|
CONOUT:
|
|
; CONSOLE CHARACTER OUTPUT FROM REGISTER C
|
|
;
|
|
LD B,BF_CIOOUT ; B = FUNCTION
|
|
POP HL ; NO COMPLETION ROUTINE, SETUP DIRECT RETURN TO CALLER
|
|
LD E,C ; E = CHARACTER TO SEND
|
|
; JR CONIO ; COMMENTED OUT, FALL THROUGH OK
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
CONIO:
|
|
;
|
|
LD A,(IOBYTE) ; GET IOBYTE
|
|
AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR CONSOLE
|
|
;OR $00 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C
|
|
JR CIO_DISP
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
LIST:
|
|
; LIST CHARACTER FROM REGISTER C
|
|
;
|
|
LD B,BF_CIOOUT ; B = FUNCTION
|
|
POP HL ; NO COMPLETION ROUTINE, SETUP DIRECT RETURN TO CALLER
|
|
LD E,C ; E = CHARACTER TO SEND
|
|
JR LISTIO
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
LISTST:
|
|
; RETURN LIST STATUS (0 IF NOT READY, 1 IF READY)
|
|
;
|
|
LD B,BF_CIOOST ; B = FUNCTION
|
|
LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE
|
|
;JR LISTIO ; COMMENTED OUT, FALL THROUGH OK
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
LISTIO:
|
|
;
|
|
LD A,(IOBYTE) ; GET IOBYTE
|
|
RLCA ; SHIFT RELEVANT BITS TO BITS 0-1
|
|
RLCA
|
|
AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR LST:
|
|
OR $0C ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C
|
|
JR CIO_DISP
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
PUNCH:
|
|
; PUNCH CHARACTER FROM REGISTER C
|
|
;
|
|
LD B,BF_CIOOUT ; B = FUNCTION
|
|
POP HL ; NO COMPLETION ROUTINE, SETUP DIRECT RETURN TO CALLER
|
|
LD E,C ; E = CHARACTER TO SEND
|
|
;JR PUNCHIO ; COMMENTED OUT, FALL THROUGH OK
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
PUNCHIO:
|
|
;
|
|
LD A,(IOBYTE) ; GET IOBYTE
|
|
RLCA ; SHIFT RELEVANT BITS TO BITS 0-1
|
|
RLCA
|
|
RLCA
|
|
RLCA
|
|
AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR PUN:
|
|
OR $08 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C
|
|
JR CIO_DISP
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
READER:
|
|
; READ CHARACTER INTO REGISTER A FROM READER DEVICE
|
|
;
|
|
LD B,BF_CIOIN ; B = FUNCTION
|
|
LD HL,CIOIN ; HL = ADDRESS OF COMPLETION ROUTINE
|
|
JR READERIO
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
READERST:
|
|
; RETURN READER STATUS (0 IF NOT READY, 1 IF READY)
|
|
;
|
|
LD B,BF_CIOIST ; B = FUNCTION
|
|
LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE
|
|
; JR READERIO ; COMMENTED OUT, FALL THROUGH OK
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
READERIO:
|
|
;
|
|
LD A,(IOBYTE) ; GET IOBYTE
|
|
RRCA ; SHIFT RELEVANT BITS TO BITS 0-1
|
|
RRCA
|
|
AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR RDR:
|
|
OR $04 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C
|
|
JR CIO_DISP
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
CIOIN:
|
|
; COMPLETION ROUTINE FOR CHARACTER INPUT FUNCTIONS
|
|
;
|
|
LD A,E ; MOVE CHARACTER RETURNED TO A
|
|
RET ; FALL THRU
|
|
;;
|
|
;;__________________________________________________________________________________________________
|
|
;CIOOUT:
|
|
;; COMPLETION ROUTINE FOR CHARACTER OUTPUT FUNCTIONS
|
|
;;
|
|
; RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
CIOST:
|
|
; COMPLETION ROUTINE FOR CHARACTER STATUS FUNCTIONS (IST/OST)
|
|
;
|
|
#IFDEF PLTUNA
|
|
LD A,E
|
|
#ENDIF
|
|
OR A ; SET FLAGS
|
|
RET Z ; NO CHARACTERS WAITING (IST) OR OUTPUT BUF FULL (OST)
|
|
OR $FF ; $FF SIGNALS READY TO READ (IST) OR WRITE (OST)
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; CHARACTER DEVICE INTERFACE
|
|
;==================================================================================================
|
|
;
|
|
; ROUTING FOR CHARACTER DEVICE FUNCTIONS
|
|
; A = INDEX INTO DEVICE MAP BASED ON IOBYTE BIOS REQUEST
|
|
; B = FUNCTION REQUESTED: BF_CIO(IN/OUT/IST/OST)
|
|
; E = CHARACTER (IF APPLICABLE TO FUNCTION)
|
|
; HL = ADDRESS OF COMPLETION ROUTINE
|
|
;
|
|
CIO_DISP:
|
|
PUSH HL ; PUT COMPLETION ROUTINE ON STACK
|
|
|
|
; LOOKUP IOBYTE MAPPED DEVICE CODE
|
|
AND $0F ; ISOLATE INDEX INTO DEVICE MAP
|
|
|
|
LD HL,DEVMAP ; HL = ADDRESS OF DEVICE MAP
|
|
CALL ADDHLA ; ADD OFFSET
|
|
|
|
LD A,(HL) ; LOOKUP DEVICE CODE
|
|
#IFDEF PLTUNA
|
|
LD C,B ; MOVE FUNCTION TO C
|
|
LD B,A ; DEVICE GOES IN B
|
|
#ELSE
|
|
LD C,A ; SAVE IN C FOR BIOS USAGE
|
|
#ENDIF
|
|
|
|
CP DEV_BAT ; CHECK FOR SPECIAL DEVICE (BAT, NUL)
|
|
JR NC,CIO_DISP1 ; HANDLE SPECIAL DEVICE
|
|
RST 08 ; RETURN VIA COMPLETION ROUTINE SET AT START
|
|
RET
|
|
|
|
CIO_DISP1:
|
|
; HANDLE SPECIAL DEVICES
|
|
CP DEV_BAT ; BAT: ?
|
|
JR Z,CIO_BAT ; YES, GO TO BAT DEVICE HANDLER
|
|
CP DEV_NUL ; NUL: ?
|
|
JR Z,CIO_NUL ; YES, GO TO NUL DEVICE HANDLER
|
|
CALL PANIC ; SOMETHING BAD HAPPENED
|
|
;
|
|
; BAT: IS A PSEUDO DEVICE REDIRECTING INPUT TO READER AND OUTPUT TO LIST
|
|
;
|
|
CIO_BAT:
|
|
LD C,E ; PUT CHAR BACK IN C
|
|
LD A,B ; GET REQUESTED FUNCTION
|
|
CP BF_CIOIN ; INPUT?
|
|
JR Z,READER ; -> READER
|
|
CP BF_CIOIST ; INPUT STATUS?
|
|
JR Z,READERST ; -> READER
|
|
CP BF_CIOOUT ; OUTPUT?
|
|
JR Z,LIST ; -> LIST
|
|
CP BF_CIOOST ; OUTPUT STATUS?
|
|
JR Z,LISTST ; -> LIST
|
|
CALL PANIC ; SOMETHING BAD HAPPENED
|
|
;
|
|
; NUL: IS A DUMMY DEVICE THAT DOES NOTHING
|
|
;
|
|
CIO_NUL:
|
|
LD A,B ; FUNCTION
|
|
CP BF_CIOIN
|
|
JR Z,NUL_IN
|
|
CP BF_CIOIST
|
|
JR Z,NUL_IST
|
|
CP BF_CIOOUT
|
|
JR Z,NUL_OUT
|
|
CP BF_CIOOST
|
|
JR Z,NUL_OST
|
|
CALL PANIC
|
|
;
|
|
NUL_IN:
|
|
LD E,$1B ; RETURN EOF
|
|
NUL_OUT:
|
|
RET ; SWALLOW CHARACTER
|
|
;
|
|
NUL_IST:
|
|
NUL_OST:
|
|
OR $FF ; A=$FF & NZ (READY)
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; DISK BIOS FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
SELDSK:
|
|
; SELECT DISK NUMBER FOR SUBSEQUENT DISK OPS
|
|
#IF DSKTRACE
|
|
CALL PRTSELDSK
|
|
#ENDIF
|
|
;
|
|
JP DSK_SELECT
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
HOME:
|
|
; SELECT TRACK 0 (BC = 0) AND FALL THRU TO SETTRK
|
|
#IF DSKTRACE
|
|
CALL PRTHOME
|
|
#ENDIF
|
|
;
|
|
LD A,(HSTWRT) ; CHECK FOR PENDING WRITE
|
|
OR A ; SET FLAGS
|
|
JR NZ,HOMED ; BUFFER IS DIRTY
|
|
LD (HSTACT),A ; CLEAR HOST ACTIVE FLAG
|
|
;
|
|
HOMED:
|
|
LD BC,0
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
SETTRK:
|
|
; SET TRACK GIVEN BY REGISTER BC
|
|
LD (SEKTRK),BC
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
SETSEC:
|
|
; SET SECTOR GIVEN BY REGISTER BC
|
|
LD (SEKSEC),BC
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
SECTRN:
|
|
; SECTOR TRANSLATION FOR SKEW, HARD CODED 1:1, NO SKEW IMPLEMENTED
|
|
LD H,B
|
|
LD L,C
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
SETDMA:
|
|
LD (DMAADR),BC
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
READ:
|
|
LD A,DOP_READ
|
|
JR READWRITE
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
WRITE:
|
|
LD A,C
|
|
LD (WRTYPE),A ; SAVE WRITE TYPE
|
|
LD A,DOP_WRITE
|
|
JR READWRITE
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
READWRITE:
|
|
LD (DSKOP),A ; SET THE ACTIVE DISK OPERATION
|
|
JR BLKRW
|
|
;
|
|
;==================================================================================================
|
|
; BLOCKED READ/WRITE (BLOCK AND BUFFER FOR 512 BYTE SECTOR)
|
|
;==================================================================================================
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; RESET (DE)BLOCKING ALGORITHM - JUST MARK BUFFER INVALID
|
|
; NOTE: BUFFER CONTENTS INVALIDATED, BUT RETAIN ANY PENDING WRITE
|
|
;
|
|
BLKRES:
|
|
XOR A
|
|
LD (HSTACT),A ; BUFFER NO LONGER VALID
|
|
LD (UNACNT),A ; CLEAR UNALLOC COUNT
|
|
|
|
RET
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; FLUSH (DE)BLOCKING ALGORITHM - DO PENDING WRITES
|
|
;
|
|
BLKFLSH:
|
|
; CHECK FOR BUFFER WRITTEN (DIRTY)
|
|
LD A,(HSTWRT) ; GET BUFFER WRITTEN FLAG
|
|
OR A
|
|
RET Z ; NOT DIRTY, RETURN WITH A=0 AND Z SET
|
|
|
|
; CLEAR THE BUFFER WRITTEN FLAG (EVEN IF A WRITE ERROR OCCURS)
|
|
XOR A ; Z = 0
|
|
LD (HSTWRT),A ; SAVE IT
|
|
|
|
; DO THE WRITE AND RETURN RESULT
|
|
JP DSK_WRITE
|
|
|
|
#IF WRTCACHE
|
|
|
|
WRT_ALC .EQU 0 ; WRITE TO ALLOCATED
|
|
WRT_DIR .EQU 1 ; WRITE TO DIRECTORY
|
|
WRT_UNA .EQU 2 ; WRITE TO UNALLOCATED
|
|
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; (DE)BLOCKING READ/WRITE ROUTINE. MANAGES PHYSICAL DISK BUFFER AND CALLS
|
|
; PHYSICAL READ/WRITE ROUTINES APPROPRIATELY.
|
|
;
|
|
BLKRW:
|
|
#IF DSKTRACE
|
|
CALL PRTDSKOP
|
|
#ENDIF
|
|
|
|
; FIX!!! WE ABORT ON FIRST ERROR, DRI SEEMS TO PASS ERROR STATUS TO THE END!!!
|
|
|
|
; IF WRITE OPERATION, GO TO SPECIAL WRITE PROCESSING
|
|
LD A,(DSKOP) ; GET REQUESTED OPERATION
|
|
CP DOP_WRITE ; WRITE
|
|
JR Z,BLKRW1 ; GO TO WRITE PROCESSING
|
|
|
|
; OTHERWISE, CLEAR OUT ANY SEQUENTIAL, UNALLOC WRITE PROCESSING
|
|
; AND GO DIRECTLY TO MAIN I/O
|
|
XOR A ; ZERO TO A
|
|
LD (WRTYPE),A ; SET WRITE TYPE = 0 (WRT_ALC) TO ENSURE READ OCCURS
|
|
LD (UNACNT),A ; SET UNACNT TO ABORT SEQ WRITE PROCESSING
|
|
|
|
JR BLKRW4 ; GO TO I/O
|
|
|
|
BLKRW1:
|
|
; WRITE PROCESSING
|
|
; CHECK FOR FIRST WRITE TO UNALLOCATED BLOCK
|
|
LD A,(WRTYPE) ; GET WRITE TYPE
|
|
CP WRT_UNA ; IS IT WRITE TO UNALLOC?
|
|
JR NZ,BLKRW2 ; NOPE, BYPASS
|
|
|
|
; INITIALIZE START OF SEQUENTIAL WRITING TO UNALLOCATED BLOCK
|
|
; AND THEN TREAT SUBSEQUENT PROCESSING AS A NORMAL WRITE
|
|
CALL UNA_INI ; INITIALIZE SEQUENTIAL WRITE TRACKING
|
|
XOR A ; A = 0 = WRT_ALC
|
|
LD (WRTYPE),A ; NOW TREAT LIKE WRITE TO ALLOCATED
|
|
|
|
BLKRW2:
|
|
; IF WRTYPE = WRT_ALC AND SEQ WRITE, GOTO BLKRW7 (SKIP READ)
|
|
OR A ; NOTE: A WILL ALREADY HAVE THE WRITE TYPE HERE
|
|
JR NZ,BLKRW3 ; NOT TYPE = 0 = WRT_ALC, SO MOVE ON
|
|
|
|
CALL UNA_CHK ; CHECK FOR CONTINUATION OF SEQ WRITES TO UNALLOCATED BLOCK
|
|
JR NZ,BLKRW3 ; NOPE, ABORT
|
|
|
|
; WE MATCHED EVERYTHING, TREAT AS WRITE TO UNALLOCATED BLOCK
|
|
LD A,WRT_UNA ; WRITE TO UNALLOCATED
|
|
LD (WRTYPE),A ; SAVE WRITE TYPE
|
|
|
|
CALL UNA_INC ; INCREMENT SEQUENTIAL WRITE TRACKING
|
|
JR BLKRW4 ; PROCEED TO I/O PROCESSING
|
|
|
|
BLKRW3:
|
|
; NON-SEQUENTIAL WRITE DETECTED, STOP ANY FURTHER CHECKING
|
|
XOR A ; ZERO
|
|
LD (UNACNT),A ; CLEAR UNALLOCATED WRITE COUNT
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; IS A FLUSH NEEDED HERE???
|
|
; FLUSH CURRENT BUFFER CONTENTS IF NEEDED
|
|
;CALL BLKFLSH ; FLUSH PENDING WRITES
|
|
;RET NZ ; ABORT ON ERROR
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
BLKRW4:
|
|
; START OF ACTUAL I/O PROCESSING
|
|
CALL BLK_XLT ; DO THE LOGICAL TO PHYSICAL MAPPING: SEK... -> XLT...
|
|
CALL BLK_CMP ; IS THE DESIRED PHYSICAL BLOCK IN BUFFER?
|
|
JR Z,BLKRW6 ; BLOCK ALREADY IN ACTIVE BUFFER, NO READ REQUIRED
|
|
|
|
; AT THIS POINT, WE KNOW WE NEED TO READ THE TARGET PHYSICAL SECTOR
|
|
; IT MAY ACTUALLY BE A PREREAD FOR A SUBSEQUENT WRITE, BUT THAT IS OK
|
|
|
|
; FIRST, FLUSH CURRENT BUFFER CONTENTS
|
|
CALL BLKFLSH ; FLUSH PENDING WRITES
|
|
RET NZ ; ABORT ON ERROR
|
|
|
|
; IMPLEMENT THE TRANSLATED VALUES
|
|
CALL BLK_SAV ; SAVE XLAT VALUES: XLT... -> HST...
|
|
|
|
; IF WRITE TO UNALLOC BLOCK, BYPASS READ, LEAVES BUFFER UNDEFINED
|
|
LD A,(WRTYPE)
|
|
CP 2
|
|
JR Z,BLKRW6
|
|
|
|
; DO THE ACTUAL READ
|
|
CALL DSK_READ ; READ PHYSICAL SECTOR INTO BUFFER
|
|
JR Z,BLKRW6 ; GOOD READ, CONTINUE
|
|
|
|
; IF READ FAILED, RESET (DE)BLOCKING ALGORITHM AND RETURN ERROR
|
|
PUSH AF ; SAVE ERROR STATUS
|
|
CALL BLKRES ; INVALIDATE (DE)BLOCKING BUFFER
|
|
POP AF ; RECOVER ERROR STATUS
|
|
RET ; ERROR RETURN
|
|
|
|
BLKRW6:
|
|
; CHECK TYPE OF OPERATIONS, IF WRITE, THEN GO TO WRITE PROCESSING
|
|
LD A,(DSKOP) ; GET PENDING OPERATION
|
|
CP DOP_WRITE ; IS IT A WRITE?
|
|
JR Z,BLKRW7 ; YES, GO TO WRITE PROCESSING
|
|
|
|
; THIS IS A READ OPERATION, WE ALREADY DID THE I/O, NOW JUST DEBLOCK AND RETURN
|
|
CALL BLK_DEBLOCK ; EXTRACT DATA FROM BLOCK
|
|
XOR A ; NO ERROR
|
|
RET ; ALL DONE
|
|
|
|
BLKRW7:
|
|
; THIS IS A WRITE OPERATION, INSERT DATA INTO BLOCK
|
|
CALL BLK_BLOCK ; INSERT DATA INTO BLOCK
|
|
|
|
; MARK THE BUFFER AS WRITTEN
|
|
LD A,TRUE ; BUFFER DIRTY = TRUE
|
|
LD (HSTWRT),A ; SAVE IT
|
|
|
|
; CHECK WRITE TYPE, IF WRT_DIR, FORCE THE PHYSICAL WRITE
|
|
LD A,(WRTYPE) ; GET WRITE TYPE
|
|
CP WRT_DIR ; 1 = DIRECTORY WRITE
|
|
JP Z,BLKFLSH ; FLUSH PENDING WRITES AND RETURN STATUS
|
|
|
|
XOR A ; ALL IS WELL, SET RETURN CODE 0
|
|
RET ; RETURN
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; INITIALIZE TRACKING OF SEQUENTIAL WRITES INTO UNALLOCATED BLOCK
|
|
; SETUP UNA... VARIABLES
|
|
;
|
|
UNA_INI:
|
|
; COPY SEKDSK/TRK/SEC TO UNA...
|
|
LD HL,SEK
|
|
LD DE,UNA
|
|
LD BC,UNASIZ
|
|
LDIR
|
|
|
|
; SETUP UNACNT AND UNASPT
|
|
LD HL,(SEKDPH) ; HL POINTS TO DPH
|
|
LD DE,10 ; OFFSET OF DPB ADDRESS IN DPH
|
|
ADD HL,DE ; HL PIONTS TO DPB ENTRY IN DPH
|
|
LD A,(HL) ; DEREFERENCE HL
|
|
INC HL ; ... TO GET
|
|
LD H,(HL) ; ... DPB ADDRESS
|
|
LD L,A ; ... SO HL NOW POINTS TO DPB ADDRESS
|
|
LD C,(HL) ; DEREFERENCE HL
|
|
INC HL ; ... INTO BC SO THAT
|
|
LD B,(HL) ; ... BC NOW HAS SPT
|
|
LD (UNASPT),BC ; SAVE SECTORS PER TRACK
|
|
DEC HL ; BACKUP TO START OF DPB
|
|
DEC HL ; BACKUP ONE BYTE FOR RECORDS PER BLOCK (BYTE IN FRONT OF DPB)
|
|
LD A,(HL) ; GET IT
|
|
LD (UNACNT),A ; SAVE IT
|
|
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; CHECK FOR CONTINUATION OF SEQUENTIAL WRITES TO UNALLOCATED BLOCK
|
|
; SEE IF UNACNT > 0 AND UNA... VARIABLES MATCH SEK... VARIABLES
|
|
;
|
|
UNA_CHK:
|
|
LD A,(UNACNT) ; GET THE COUNTER
|
|
OR A
|
|
JR NZ,UNA_CHK1 ; IF NOT DONE WITH BLOCK, KEEP CHECKING
|
|
|
|
; CNT IS NOW ZERO, EXHAUSTED RECORDS IN ONE BLOCK!
|
|
DEC A ; HACK TO SET NZ
|
|
RET ; RETURN WITH NZ
|
|
|
|
UNA_CHK1:
|
|
; COMPARE UNA... VARIABLES WITH SEK... VARIABLES
|
|
LD HL,SEK
|
|
LD DE,UNA
|
|
LD B,UNASIZ
|
|
JR BLK_CMPLOOP
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; INCREMENT THE SEQUENTIAL WRITE TRACKING VARIABLES
|
|
; TO REFLECT THE NEXT RECORD (TRK/SEC) WE EXPECT
|
|
;
|
|
UNA_INC:
|
|
; DECREMENT THE BLOCK RECORD COUNT
|
|
LD HL,UNACNT
|
|
DEC (HL)
|
|
|
|
; INCREMENT THE SECTOR
|
|
LD DE,(UNASEC)
|
|
INC DE
|
|
LD (UNASEC),DE
|
|
|
|
; CHECK FOR END OF TRACK
|
|
LD HL,(UNASPT)
|
|
XOR A
|
|
SBC HL,DE
|
|
RET NZ
|
|
|
|
; HANDLE END OF TRACK
|
|
LD (UNASEC),HL ; SECTOR BACK TO 0 (NOTE: HL=0 AT THIS POINT)
|
|
LD HL,(UNATRK) ; GET CURRENT TRACK
|
|
INC HL ; BUMP IT
|
|
LD (UNATRK),HL ; SAVE IT
|
|
|
|
RET
|
|
#ELSE
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; (DE)BLOCKING READ/WRITE ROUTINE. MANAGES PHYSICAL DISK BUFFER AND CALLS
|
|
; PHYSICAL READ/WRITE ROUTINES APPROPRIATELY.
|
|
;
|
|
BLKRW:
|
|
#IF DSKTRACE
|
|
CALL PRTDSKOP
|
|
#ENDIF
|
|
|
|
CALL BLK_XLT ; SECTOR XLAT: SEK... -> XLT...
|
|
CALL BLK_CMP ; IN BUFFER?
|
|
JR Z,BLKRW1 ; YES, BYPASS READ
|
|
CALL BLK_SAV ; SAVE XLAT VALUES: XLT... -> HST...
|
|
LD A,FALSE ; ASSUME FAILURE, INVALIDATE BUFFER
|
|
LD (HSTACT),A ; SAVE IT
|
|
CALL DSK_READ ; READ PHYSICAL SECTOR INTO BUFFER
|
|
RET NZ ; BAIL OUT ON ERROR
|
|
|
|
BLKRW1:
|
|
LD A,(DSKOP) ; GET PENDING OPERATION
|
|
CP DOP_WRITE ; IS IT A WRITE?
|
|
JR Z,BLKRW2 ; YES, GO TO WRITE ROUTINE
|
|
|
|
CALL BLK_DEBLOCK ; EXTRACT DATA FROM BLOCK
|
|
XOR A ; NO ERROR
|
|
RET ; ALL DONE
|
|
|
|
BLKRW2:
|
|
CALL BLK_BLOCK ; INSERT DATA INTO BLOCK
|
|
CALL DSK_WRITE ; WRITE PHYSICAL SECTOR FROM BUFFER
|
|
RET NZ ; BAIL OUT ON ERROR
|
|
|
|
LD A,TRUE ; BUFFER IS NOW VALID
|
|
LD (HSTACT),A ; SAVE IT
|
|
|
|
XOR A ; ALL IS WELL, SET RETURN CODE 0
|
|
RET ; RETURN
|
|
#ENDIF
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; TRANSLATE FROM CP/M DSK/TRK/SEC TO PHYSICAL
|
|
; SEK... -> XLT...
|
|
;
|
|
BLK_XLT:
|
|
; FIRST, DO A BYTE COPY OF SEK... TO XLT...
|
|
LD HL,SEK
|
|
LD DE,XLT
|
|
LD BC,XLTSIZ
|
|
LDIR
|
|
|
|
; NOW UPDATE XLTSEC BASED ON (DE)BLOCKING FACTOR (ALWAYS 4:1)
|
|
LD BC,(SEKSEC) ; SECTOR IS FACTORED DOWN (4:1) DUE TO BLOCKING
|
|
SRL B ; 16 BIT RIGHT SHIFT TWICE TO DIVIDE BY 4
|
|
RR C
|
|
SRL B
|
|
RR C
|
|
LD (XLTSEC),BC
|
|
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; SAVE RESULTS OF TRANSLATION: XLT... -> HST...
|
|
; IMPLICITLY SETS HSTACT TO TRUE!
|
|
;
|
|
BLK_SAV:
|
|
LD HL,XLT
|
|
LD DE,HST
|
|
LD BC,XLTSIZ
|
|
LDIR
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; COMPARE RESULTS OF TRANSLATION TO CURRENT BUF (XLT... TO HST...)
|
|
; NOTE THAT HSTACT IS COMPARED TO XLTACT IMPLICITLY! XLTACT IS ALWAYS TRUE, SO
|
|
; HSTACT MUST BE TRUE FOR COMPARE TO SUCCEED.
|
|
;
|
|
BLK_CMP:
|
|
LD HL,XLT
|
|
LD DE,HST
|
|
LD B,XLTSIZ
|
|
BLK_CMPLOOP:
|
|
LD A,(DE)
|
|
CP (HL)
|
|
RET NZ ; BAD COMPARE, RETURN WITH NZ
|
|
INC HL
|
|
INC DE
|
|
DJNZ BLK_CMPLOOP
|
|
RET ; RETURN WITH Z
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; BLOCK DATA - INSERT CPM DMA BUF INTO PROPER PART OF PHYSICAL SECTOR BUFFER
|
|
;
|
|
BLK_BLOCK:
|
|
#IFDEF PLTUNA
|
|
CALL BLK_SETUP
|
|
EX DE,HL
|
|
LD BC,128
|
|
LDIR
|
|
RET
|
|
#ELSE
|
|
LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY
|
|
LD A,(BNKUSER) ; GET USER BANK
|
|
LD E,A ; E = SOURCE (USER BANK)
|
|
LD A,(BNKBIOS) ; GET DEST BANK
|
|
LD D,A ; D = DEST (BIOS BANK)
|
|
LD HL,128 ; HL = COPY LEN = DMA BUFFER SIZE
|
|
RST 08 ; DO IT
|
|
CALL BLK_SETUP ; SETUP SOURCE AND DESTINATION
|
|
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
|
|
EX DE,HL ; SWAP HL/DE FOR BLOCK OPERATION
|
|
RST 08 ; DO IT
|
|
RET
|
|
#ENDIF
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; DEBLOCK DATA - EXTRACT DESIRED CPM DMA BUF FROM PHYSICAL SECTOR BUFFER
|
|
;
|
|
BLK_DEBLOCK:
|
|
#IFDEF PLTUNA
|
|
CALL BLK_SETUP
|
|
LD BC,128
|
|
LDIR
|
|
RET
|
|
#ELSE
|
|
LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY
|
|
LD DE,(BNKBIOS) ; E = SOURCE (BIOS BANK), D = DEST (USER BANK)
|
|
LD HL,128 ; HL = COPY LEN = DMA BUFFER SIZE
|
|
RST 08 ; DO IT
|
|
CALL BLK_SETUP ; SETUP SOURCE AND DESTINATION
|
|
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
|
|
RST 08 ; DO IT
|
|
RET
|
|
#ENDIF
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; SETUP SOURCE AND DESTINATION POINTERS FOR BLOCK COPY OPERATION
|
|
; AT EXIT, HL = ADDRESS OF DESIRED BLOCK IN SECTOR BUFFER, DE = DMA
|
|
;
|
|
BLK_SETUP:
|
|
LD A,(SEKSEC) ; GET LOW BYTE OF SECTOR
|
|
AND 3 ; A = INDEX OF CPM BUF IN SEC BUF
|
|
RRCA ; MULTIPLY BY 64
|
|
RRCA
|
|
LD E,A ; INTO LOW ORDER BYTE OF DESTINATION
|
|
LD D,0 ; HIGH ORDER BYTE IS ZERO
|
|
LD HL,(DSKBUF) ; HL = START OF SEC BUF
|
|
ADD HL,DE ; ADD IN COMPUTED OFFSET
|
|
ADD HL,DE ; HL NOW = INDEX * 128 (SOURCE)
|
|
LD DE,(DMAADR) ; DE = DESTINATION = DMA BUF
|
|
RET
|
|
;
|
|
;==================================================================================================
|
|
; PHYSICAL DISK INTERFACE
|
|
;==================================================================================================
|
|
;
|
|
; LOOKUP DISK INFORMATION BASED ON CPM DRIVE IN C
|
|
; ON RETURN, D=UNIT, E=SLICE, HL=DPH ADDRESS
|
|
;
|
|
DSK_GETINF:
|
|
LD HL,(DRVMAPADR) ; HL := START OF UNA DRIVE MAP
|
|
DEC HL ; POINT TO DRIVE COUNT
|
|
LD A,C ; A := CPM DRIVE
|
|
CP (HL) ; COMPARE TO NUMBER OF DRIVES CONFIGURED
|
|
JR NC,DSK_GETINF1 ; IF OUT OF RANGE, GO TO ERROR RETURN
|
|
INC HL ; POINT TO START OF DRIVE MAP
|
|
;
|
|
RLCA ; MULTIPLY A BY 4
|
|
RLCA ; ... TO USE AS OFFSET INTO DRVMAP
|
|
CALL ADDHLA ; ADD OFFSET
|
|
LD D,(HL) ; D := UNIT
|
|
INC HL ; BUMP TO SLICE
|
|
LD E,(HL) ; E := SLICE
|
|
INC HL ; POINT TO DPH LSB
|
|
LD A,(HL) ; A := DPH LSB
|
|
INC HL ; POINT TO DPH MSB
|
|
LD H,(HL) ; H := DPH MSB
|
|
LD L,A ; L := DPH LSB
|
|
LD A,H ; TEST FOR INVALID DPH
|
|
OR L ; ... BY CHECKING FOR ZERO VALUE
|
|
JR Z,DSK_GETINF1 ; HANDLE ZERO DPH, DRIVE IS INVALID
|
|
XOR A ; SET SUCCESS
|
|
RET
|
|
;
|
|
DSK_GETINF1: ; ERROR RETURN
|
|
XOR A
|
|
LD H,A
|
|
LD L,A
|
|
LD D,A
|
|
LD E,A
|
|
INC A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
DSK_SELECT:
|
|
LD B,E ; SAVE E IN B FOR NOW
|
|
CALL DSK_GETINF ; GET D=UNIT, E=SLICE, HL=DPH ADDRESS
|
|
RET NZ ; RETURN IF INVALID DRIVE (A=1, NZ SET, HL=0)
|
|
PUSH BC ; WE NEED B LATER, SAVE ON STACK
|
|
;
|
|
; SAVE ALL THE NEW STUFF
|
|
LD A,C ; A := CPM DRIVE NO
|
|
LD (SEKDSK),A ; SAVE IT
|
|
LD A,D ; A := UNIT
|
|
LD (SEKUNIT),A ; SAVE UNIT
|
|
LD (SEKDPH),HL ; SAVE DPH ADDRESS
|
|
;
|
|
; UPDATE OFFSET FOR ACTIVE SLICE
|
|
; A TRACK IS ASSUMED TO BE 16 SECTORS
|
|
; THE OFFSET REPRESENTS THE NUMBER OF BLOCKS * 256
|
|
; TO USE AS THE OFFSET
|
|
LD H,65 ; H = TRACKS PER SLICE, E = SLICE NO
|
|
CALL MULT8 ; HL := H * E (TOTAL TRACK OFFSET)
|
|
LD (SEKOFF),HL ; SAVE NEW TRACK OFFSET
|
|
;
|
|
; RESTORE DE TO BC (FOR ACCESS TO DRIVE LOGIN BIT)
|
|
POP BC ; GET ORIGINAL E INTO B
|
|
;
|
|
#IFDEF PLTWBW
|
|
;
|
|
; CHECK IF THIS IS LOGIN, IF NOT, BYPASS MEDIA DETECTION
|
|
; FIX: WHAT IF PREVIOUS MEDIA DETECTION FAILED???
|
|
BIT 0,B ; TEST DRIVE LOGIN BIT
|
|
JR NZ,DSK_SELECT2 ; BYPASS MEDIA DETECTION
|
|
;
|
|
; DETERMINE MEDIA IN DRIVE
|
|
LD A,(SEKUNIT) ; GET UNIT
|
|
LD C,A ; STORE IN C
|
|
LD B,BF_DIOMEDIA ; DRIVER FUNCTION = DISK MEDIA
|
|
LD E,1 ; ENABLE MEDIA CHECK/DISCOVERY
|
|
RST 08 ; DO IT
|
|
LD A,E ; RESULTANT MEDIA ID TO ACCUM
|
|
OR A ; SET FLAGS
|
|
LD HL,0 ; ASSUME FAILURE
|
|
RET Z ; BAIL OUT IF NO MEDIA
|
|
;
|
|
; A HAS MEDIA ID, SET HL TO CORRESPONDING DPBMAP ENTRY
|
|
LD HL,DPBMAP ; HL = DPBMAP
|
|
RLCA ; DPBMAP ENTRIES ARE 2 BYTES EACH
|
|
CALL ADDHLA ; ADD OFFSET TO HL
|
|
;
|
|
; LOOKUP THE ACTUAL DPB ADDRESS NOW
|
|
LD E,(HL) ; DEREFERENCE HL...
|
|
INC HL ; INTO DE...
|
|
LD D,(HL) ; DE = ADDRESS OF DESIRED DPB
|
|
;
|
|
; PLUG DPB INTO THE ACTIVE DPH
|
|
LD HL,(SEKDPH)
|
|
LD BC,10 ; OFFSET OF DPB IN DPH
|
|
ADD HL,BC ; HL := DPH.DPB
|
|
LD (HL),E ; SET LSB OF DPB IN DPH
|
|
INC HL ; BUMP TO MSB
|
|
LD (HL),D ; SET MSB OF DPB IN DPH
|
|
#ENDIF
|
|
;
|
|
DSK_SELECT2:
|
|
LD HL,(SEKDPH) ; HL = DPH ADDRESS FOR CP/M
|
|
XOR A ; FLAG SUCCESS
|
|
RET ; NORMAL RETURN
|
|
;
|
|
;
|
|
;
|
|
DSK_STATUS:
|
|
#IFDEF PLTUNA
|
|
XOR A ; ASSUME OK FOR NOW
|
|
RET ; RETURN
|
|
#ELSE
|
|
; C HAS CPM DRIVE, LOOKUP UNIT AND CHECK FOR INVALID DRIVE
|
|
CALL DSK_GETINF ; B := UNIT
|
|
RET NZ ; INVALID DRIVE ERROR
|
|
|
|
; VALID DRIVE, DISPATCH TO DRIVER
|
|
LD C,D ; C := UNIT
|
|
LD B,BF_DIOSTATUS ; B := FUNCTION: STATUS
|
|
RST 08
|
|
RET
|
|
#ENDIF
|
|
;
|
|
;
|
|
;
|
|
DSK_READ:
|
|
; SET B = FUNCTION: READ
|
|
LD B,BF_DIOREAD
|
|
JR DSK_IO
|
|
;
|
|
;
|
|
;
|
|
DSK_WRITE:
|
|
; SET B = FUNCTION: WRITE
|
|
LD B,BF_DIOWRITE
|
|
JR DSK_IO
|
|
;
|
|
;
|
|
;
|
|
#IFDEF PLTUNA
|
|
|
|
DSK_IO:
|
|
PUSH BC
|
|
LD DE,(HSTTRK) ; GET TRACK INTO HL
|
|
LD B,4 ; PREPARE TO LEFT SHIFT BY 4 BITS
|
|
DSK_IO1:
|
|
SLA E ; SHIFT DE LEFT BY 4 BITS
|
|
RL D
|
|
DJNZ DSK_IO1 ; LOOP TILL ALL BITS DONE
|
|
LD A,(HSTSEC) ; GET THE SECTOR INTO A
|
|
AND $0F ; GET RID OF TOP NIBBLE
|
|
OR E ; COMBINE WITH E
|
|
LD E,A ; BACK IN E
|
|
LD HL,0 ; HL:DE NOW HAS SLICE RELATIVE LBA
|
|
; APPLY OFFSET NOW
|
|
; OFFSET IS EXPRESSED AS NUMBER OF BLOCKS * 256 TO OFFSET!
|
|
LD A,(HSTOFF) ; LSB OF SLICE OFFSET TO A
|
|
ADD A,D ; ADD WITH D
|
|
LD D,A ; PUT IT BACK IN D
|
|
LD A,(HSTOFF+1) ; MSB OF SLICE OFFSET TO A
|
|
CALL ADCHLA ; ADD OFFSET
|
|
POP BC ; RECOVER FUNCTION IN B
|
|
LD A,(HSTUNIT) ; GET THE UNIT VALUE
|
|
LD C,A ; PUT IT IN C
|
|
; DISPATCH TO DRIVER
|
|
PUSH BC
|
|
EX DE,HL ; DE:HL NOW HAS LBA
|
|
LD B,C ; UNIT TO B
|
|
LD C,$41 ; UNA SET LBA
|
|
RST 08 ; CALL UNA
|
|
CALL NZ,PANIC
|
|
POP BC ; RECOVER B=FUNC, C=UNIT
|
|
LD E,C ; UNIT TO E
|
|
LD C,B ; FUNC TO C
|
|
LD B,E ; UNIT TO B
|
|
LD DE,(DSKBUF) ; SET BUFFER ADDRESS
|
|
LD HL,1 ; 1 SECTOR
|
|
; DISPATCH TO UBIOS
|
|
RST 08
|
|
OR A ; SET FLAGS BASED ON RESULT
|
|
RET
|
|
|
|
#ELSE
|
|
|
|
DSK_IO:
|
|
;
|
|
; TRANSLATE CP/M TRACK/SECTOR -> HBIOS TRACK/HEAD/SECTOR
|
|
; NEEDS TO HANDLE FLOPPY SEPARATE FROM HARD DISK
|
|
;
|
|
CHS:
|
|
LD A,(HSTUNIT) ; GET UNIT
|
|
LD C,A ; UNIT -> C
|
|
PUSH BC ; SAVE FUNC/UNIT
|
|
LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO
|
|
RST 08 ; GET UNIT INFO, DEVICE TYPE IN D
|
|
POP BC ; GET FUNC/UNIT BACK TO BC
|
|
LD A,D ; DEVICE TYPE -> A
|
|
AND $F0 ; ISOLATE HIGH BITS
|
|
CP DIODEV_FD ; FLOPPY?
|
|
JR NZ,CHSHD ; IF NOT, DO HD CHS XLAT
|
|
;
|
|
; FLOPPY SPECIFIC TRANSLATION ASSUMES FLOPPY IS DOUBLE-SIDED AND
|
|
; USES LOW ORDER BIT OF TRACK AS HEAD VALUE
|
|
;
|
|
; HBIOS SEEK: HL=CYLINDER, D=HEAD, E=SECTOR
|
|
;
|
|
LD DE,(HSTSEC) ; SECTOR -> DE, HEAD(D) BECOMES ZERO
|
|
LD HL,(HSTTRK) ; TRACK -> HL (LOW BIT HAS HEAD)
|
|
SRL H ; SHIFT HEAD BIT OUT OF HL
|
|
RR L ; ... AND INTO CARRY
|
|
RL D ; CARRY BIT (HEAD) INTO D
|
|
JR CHS2
|
|
;
|
|
; HARD DISK SPECIFIC TRANSLATION
|
|
; ASSUMES 16 HEADS PER CYLINDER AND 16 SECTORS PER TRACK
|
|
;
|
|
CHSHD:
|
|
LD HL,(HSTTRK) ; GET TRACK VALUE
|
|
LD A,L ; LSB OF TRACK TO A
|
|
AND $0F ; ISOLATE HEAD IN LOW 4 BITS
|
|
LD D,A ; STUFF IT IN D
|
|
LD A,(HSTSEC) ; GET SECTOR
|
|
LD E,A ; STUFF IT IN E
|
|
LD A,B ; SAVE B (HBIOS FUNC)
|
|
LD B,4 ; PREPARE TO SHIFT OUT 4 BIT HEAD VALUE
|
|
CHSHD1:
|
|
SRL H ; SHIFT ONE BIT OUT
|
|
RR L ; ... OF HL
|
|
DJNZ CHSHD1 ; DO ALL 4 BITS
|
|
LD B,A ; RESTORE B (HBIOS FUNC)
|
|
; FALL THRU TO CHS2
|
|
;
|
|
; ALL TYPES OF TRANSLATION WIND UP HERE TO
|
|
; MAKE THE ACTUAL HBIOS CALL
|
|
;
|
|
CHS2:
|
|
PUSH DE ; SAVE HEAD/SECTOR + COULD MOVE
|
|
LD DE,(HSTOFF) ; NOW GET SLICE OFFSET | TO CHSHD,
|
|
ADD HL,DE ; ADD IT TO TRACK VALUE | NO SLICES
|
|
POP DE ; RECOVER HEAD/SECTOR + FOR FLOPPY
|
|
;
|
|
; MAKE HBIOS CALL
|
|
; HBIOS FUNC SHOULD STILL BE IN B
|
|
; UNIT SHOULD STILL BE IN C
|
|
;
|
|
PUSH BC ; SAVE INCOMING FUNCTION, DEVICE/UNIT
|
|
LD B,BF_DIOSEEK ; SETUP FOR NEW SEEK CALL
|
|
RST 08 ; DO IT
|
|
POP BC ; RESTORE INCOMING FUNCTION, DEVICE/UNIT
|
|
RET NZ ; ABORT IF SEEK RETURNED AN ERROR W/ ERROR IN A
|
|
LD HL,(DSKBUF) ; GET BUFFER ADDRESS
|
|
LD DE,1 ; TRANSFER ONE SECTOR
|
|
RST 08 ; DO IT
|
|
OR A ; SET FLAGS
|
|
RET ; DONE
|
|
|
|
#ENDIF
|
|
;
|
|
;==================================================================================================
|
|
; UTILITY FUNCTIONS
|
|
;==================================================================================================
|
|
;
|
|
ORG_UTIL .EQU $
|
|
#INCLUDE "util.asm"
|
|
SIZ_UTIL .EQU $ - ORG_UTIL
|
|
.ECHO "UTIL occupies "
|
|
.ECHO SIZ_UTIL
|
|
.ECHO " bytes.\n"
|
|
;
|
|
;==================================================================================================
|
|
; DIAGNOSTICS
|
|
;==================================================================================================
|
|
;
|
|
#IF DSKTRACE
|
|
;__________________________________________________________________________________________________
|
|
PRTSELDSK:
|
|
CALL NEWLINE
|
|
PUSH BC
|
|
PUSH DE
|
|
LD B,E
|
|
LD DE,STR_SELDSK
|
|
CALL WRITESTR
|
|
CALL PC_SPACE
|
|
LD DE,STR_DSK
|
|
LD A,C
|
|
CALL PRTHEXBYTE
|
|
CALL PC_SPACE
|
|
CALL PC_LBKT
|
|
LD A,B
|
|
CALL PRTHEXBYTE
|
|
CALL PC_RBKT
|
|
POP DE
|
|
POP BC
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
PRTHOME:
|
|
CALL NEWLINE
|
|
LD DE,STR_HOME
|
|
CALL WRITESTR
|
|
RET
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
PRTDSKOP:
|
|
CALL NEWLINE
|
|
LD A,(DSKOP)
|
|
LD DE,STR_READ
|
|
CP DOP_READ
|
|
CALL Z,WRITESTR
|
|
LD DE,STR_WRITE
|
|
CP DOP_WRITE
|
|
CALL Z,WRITESTR
|
|
LD A,C
|
|
CALL Z,PRTHEXBYTE
|
|
LD DE,STR_DSK
|
|
CALL WRITESTR
|
|
LD A,(SEKDSK)
|
|
CALL PRTHEXBYTE
|
|
LD DE,STR_TRK
|
|
CALL WRITESTR
|
|
LD BC,(SEKTRK)
|
|
CALL PRTHEXWORD
|
|
LD DE,STR_SEC
|
|
CALL WRITESTR
|
|
LD BC,(SEKSEC)
|
|
CALL PRTHEXWORD
|
|
RET
|
|
;
|
|
STR_SELDSK .DB "SELDSK$"
|
|
STR_HOME .DB "HOME$"
|
|
STR_READ .DB "READ$"
|
|
STR_WRITE .DB "WRITE$"
|
|
STR_DSK .DB " DSK=$"
|
|
STR_TRK .DB " TRK=$"
|
|
STR_SEC .DB " SEC=$"
|
|
;
|
|
#ENDIF
|
|
;
|
|
;==================================================================================================
|
|
; DATA
|
|
;==================================================================================================
|
|
;
|
|
;STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$"
|
|
;STR_STALE .DB "\r\nCBIOS Err: Stale Drive$"
|
|
;
|
|
SECADR .DW 0 ; ADDRESS OF SECTOR IN ROM/RAM PAGE
|
|
DEFDRIVE .DB 0 ; DEFAULT DRIVE
|
|
CCPBUF .DW 0 ; ADDRESS OF CCP BUF IN BIOS BANK
|
|
;
|
|
#IFDEF PLTWBW
|
|
BNKBIOS .DB 0 ; BIOS BANK ID
|
|
BNKUSER .DB 0 ; USER BANK ID
|
|
#ENDIF
|
|
;
|
|
; DOS DISK VARIABLES
|
|
;
|
|
DSKOP .DB 0 ; DISK OPERATION (DOP_READ/DOP_WRITE)
|
|
WRTYPE .DB 0 ; WRITE TYPE (0=NORMAL, 1=DIR (FORCE), 2=FIRST RECORD OF BLOCK)
|
|
DMAADR .DW 0 ; DIRECT MEMORY ADDRESS
|
|
HSTWRT .DB 0 ; TRUE = BUFFER IS DIRTY
|
|
DSKBUF .DW 0 ; ADDRESS OF PHYSICAL SECTOR BUFFER
|
|
;
|
|
; LOGICAL DISK I/O REQUEST PENDING
|
|
;
|
|
SEK:
|
|
SEKDSK .DB 0 ; DISK NUMBER 0-15
|
|
SEKTRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL)
|
|
SEKSEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL)
|
|
SEKUNIT .DB 0 ; DISK UNIT
|
|
SEKDPH .DW 0 ; ADDRESS OF ACTIVE (SELECTED) DPH
|
|
SEKOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE
|
|
SEKACT .DB TRUE ; ALWAYS TRUE!
|
|
;
|
|
; RESULT OF CPM TO PHYSICAL TRANSLATION
|
|
;
|
|
XLT:
|
|
XLTDSK .DB 0
|
|
XLTTRK .DW 0
|
|
XLTSEC .DW 0
|
|
XLTUNIT .DB 0
|
|
XLTDPH .DW 0
|
|
XLTOFF .DW 0
|
|
XLTACT .DB TRUE ; ALWAYS TRUE!
|
|
;
|
|
XLTSIZ .EQU $ - XLT
|
|
;
|
|
; DSK/TRK/SEC IN BUFFER (VALID WHEN HSTACT=TRUE)
|
|
;
|
|
HST:
|
|
HSTDSK .DB 0 ; DISK IN BUFFER
|
|
HSTTRK .DW 0 ; TRACK IN BUFFER
|
|
HSTSEC .DW 0 ; SECTOR IN BUFFER
|
|
HSTUNIT .DB 0 ; DISK UNIT IN BUFFER
|
|
HSTDPH .DW 0 ; CURRENT DPH ADDRESS
|
|
HSTOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR SLICE
|
|
HSTACT .DB 0 ; TRUE = BUFFER HAS VALID DATA
|
|
;
|
|
; SEQUENTIAL WRITE TRACKING FOR (UNA)LLOCATED BLOCK
|
|
;
|
|
UNA:
|
|
UNADSK .DB 0 ; DISK NUMBER 0-15
|
|
UNATRK .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL)
|
|
UNASEC .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL)
|
|
;
|
|
UNASIZ .EQU $ - UNA
|
|
;
|
|
UNACNT .DB 0 ; COUNT DOWN UNALLOCATED RECORDS IN BLOCK
|
|
UNASPT .DW 0 ; SECTORS PER TRACK
|
|
;
|
|
;==================================================================================================
|
|
; DISK CONTROL STRUCTURES (DPB, DPH)
|
|
;==================================================================================================
|
|
;
|
|
CKS_RAM .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA
|
|
ALS_RAM .EQU 24 ; ALS: BLKS / 8 = 192 / 8 = 24 (ASSUMES 512K DISK)
|
|
;
|
|
CKS_ROM .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA
|
|
ALS_ROM .EQU 24 ; ALS: BLKS / 8 = 192 / 8 = 24 (ASSUMES 512K DISK)
|
|
;
|
|
CKS_FD .EQU 64 ; CKS: DIR ENT / 4 = 256 / 4 = 64
|
|
ALS_FD .EQU 128 ; ALS: BLKS / 8 = 1024 / 8 = 128
|
|
;
|
|
CKS_HD .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA
|
|
ALS_HD .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP)
|
|
;
|
|
;
|
|
; DISK PARAMETER BLOCKS
|
|
;
|
|
; BLS BSH BLM EXM (DSM<256) EXM (DSM>255)
|
|
; ---------- --- --- ------------- -------------
|
|
; 1,024 3 7 0 N/A
|
|
; 2,048 4 15 1 0
|
|
; 4,096 5 31 3 1
|
|
; 8,192 6 63 7 3
|
|
; 16,384 7 127 15 7
|
|
;
|
|
; AL0/1: EACH BIT SET ALLOCATES A BLOCK OF DIR ENTRIES. EACH DIR ENTRY
|
|
; IS 32 BYTES. BIT COUNT = (((DRM + 1) * 32) / BLS)
|
|
;
|
|
; CKS = (DIR ENT / 4), ZERO FOR NON-REMOVABLE MEDIA
|
|
;
|
|
; ALS = TOTAL BLKS (DSM + 1) / 8
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; ROM DISK: 64 SECS/TRK (LOGICAL), 128 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256
|
|
; ROM DISK SIZE = TOTAL ROM - 128K RESERVED FOR SYSTEM USE
|
|
;
|
|
; ALS_ROM, EXM, DSM MUST BE FILLED DYNAMICALLY:
|
|
; - ALS_ROM := (BANKS * 2)
|
|
; - EXM := (BANKS <= 16) ? 1 : 0
|
|
; - DSM := (BANKS * 16)
|
|
;
|
|
; DEFAULT VALUES BELOW ARE FOR 512K ROM
|
|
;
|
|
.DW CKS_ROM ; CKS: ZERO FOR NON-REMOVABLE MEDIA
|
|
.DW ALS_ROM ; ALS: BLKS / 8
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_ROM:
|
|
.DW 64 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 1 ; EXM: (BLKS <= 256) ? 1 : 0
|
|
.DW 192 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1
|
|
.DW 255 ; DRM: DIR ENTRIES - 1 = 255
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA
|
|
.DW 0 ; OFF: ROM DISK HAS NO SYSTEM AREA
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; RAM DISK: 64 SECS/TRK, 128 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256
|
|
; RAM DISK SIZE = TOTAL RAM - 128K RESERVED FOR SYSTEM USE
|
|
;
|
|
; ALS_RAM, EXM, DSM MUST BE FILLED DYNAMICALLY:
|
|
; - ALS_RAM := (BANKS * 2)
|
|
; - EXM := (BANKS <= 16) ? 1 : 0
|
|
; - DSM := (BANKS * 16)
|
|
;
|
|
; DEFAULT VALUES BELOW ARE FOR 512K RAM
|
|
;
|
|
.DW CKS_RAM ; CKS: ZERO FOR NON-REMOVABLE MEDIA
|
|
.DW ALS_RAM ; ALS: BLKS / 8
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_RAM:
|
|
.DW 64 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 1 ; EXM: (BLKS <= 256) ? 1 : 0
|
|
.DW 192 - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1
|
|
.DW 255 ; DRM: DIR ENTRIES - 1 = 255
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA
|
|
.DW 0 ; OFF: RESERVED TRACKS = 0 TRK
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; 4MB RAM FLOPPY DRIVE, 32 TRKS, 1024 SECS/TRK, 128 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256
|
|
;
|
|
.DW CKS_HD
|
|
.DW ALS_HD
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_RF:
|
|
.DW 64 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 0 ; EXM: EXTENT MASK
|
|
.DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = (4MB / 2K BLS) - 1 = 2047
|
|
.DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA
|
|
.DW 0 ; OFF: RESERVED TRACKS = 0 TRK
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; GENERIC HARD DISK DRIVE (8MB DATA SPACE + 128K RESERVED SPACE)
|
|
; LOGICAL: 1040 TRKS (16 RESERVED), 64 SECS/TRK, 128 BYTES/SEC
|
|
; PHYSICAL: 65 CYLS (1 RESERVED), 16 HEADS/CYL, 16 SECS/TRK, 512 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 4K, DIRECTORY ENTRIES = 512
|
|
;
|
|
.DW CKS_HD
|
|
.DW ALS_HD
|
|
.DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_HD:
|
|
.DW 64 ; SPT: SECTORS PER TRACK
|
|
.DB 5 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 31 ; BLM: BLOCK MASK
|
|
.DB 1 ; EXM: EXTENT MASK
|
|
.DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 = (8MB / 4K BLS) - 1 = 2047
|
|
.DW 511 ; DRM: DIR ENTRIES - 1 = 512 - 1 = 511
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4
|
|
.DW 16 ; OFF: RESERVED TRACKS = 16 TRKS * (16 TRKS * 16 HEADS * 16 SECS * 512 BYTES) = 128K
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; IBM 720KB 3.5" FLOPPY DRIVE, 80 TRKS, 36 SECS/TRK, 512 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 128
|
|
;
|
|
.DW CKS_FD
|
|
.DW ALS_FD
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_FD720:
|
|
.DW 36 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 0 ; EXM: EXTENT MASK
|
|
.DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350
|
|
.DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127
|
|
.DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4
|
|
.DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; IBM 1.44MB 3.5" FLOPPY DRIVE, 80 TRKS, 72 SECS/TRK, 512 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256
|
|
;
|
|
.DW CKS_FD
|
|
.DW ALS_FD
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_FD144:
|
|
.DW 72 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 0 ; EXM: EXTENT MASK
|
|
.DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710
|
|
.DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4
|
|
.DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; IBM 360KB 5.25" FLOPPY DRIVE, 40 TRKS, 9 SECS/TRK, 512 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 128
|
|
;
|
|
.DW CKS_FD
|
|
.DW ALS_FD
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_FD360:
|
|
.DW 36 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 1 ; EXM: EXTENT MASK
|
|
.DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170
|
|
.DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4
|
|
.DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; IBM 1.20MB 5.25" FLOPPY DRIVE, 80 TRKS, 15 SECS/TRK, 512 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256
|
|
;
|
|
.DW CKS_FD
|
|
.DW ALS_FD
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_FD120:
|
|
.DW 60 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 0 ; EXM: EXTENT MASK
|
|
.DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591
|
|
.DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4
|
|
.DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
; IBM 1.11MB 8" FLOPPY DRIVE, 77 TRKS, 15 SECS/TRK, 512 BYTES/SEC
|
|
; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256
|
|
;
|
|
.DW CKS_FD
|
|
.DW ALS_FD
|
|
.DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128)
|
|
DPB_FD111:
|
|
.DW 60 ; SPT: SECTORS PER TRACK
|
|
.DB 4 ; BSH: BLOCK SHIFT FACTOR
|
|
.DB 15 ; BLM: BLOCK MASK
|
|
.DB 0 ; EXM: EXTENT MASK
|
|
.DW 569 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,155K - 15K OFF) / 2K BLS) - 1 = 569
|
|
.DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255
|
|
.DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE
|
|
.DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE
|
|
.DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4
|
|
.DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K
|
|
;
|
|
#IFDEF PLTUNA
|
|
SECBUF .FILL 512,0 ; PHYSICAL DISK SECTOR BUFFER
|
|
#ENDIF
|
|
;
|
|
;==================================================================================================
|
|
; CBIOS BUFFERS
|
|
;==================================================================================================
|
|
;
|
|
BUFPOOL .EQU $ ; START OF BUFFER POOL
|
|
;
|
|
;==================================================================================================
|
|
; COLD BOOT INITIALIZATION
|
|
;
|
|
; THIS CODE IS PLACED IN THE BDOS BUFFER AREA TO CONSERVE SPACE. SINCE
|
|
; COLD BOOT DOES NO DISK IO, THIS IS SAFE.
|
|
;
|
|
;==================================================================================================
|
|
;
|
|
.ORG $8000 ; INIT CODE RUNS AT $8000
|
|
;
|
|
HEAPEND .EQU CBIOS_END - 64 ; TOP OF HEAP MEM, END OF CBIOS LESS 32 ENTRY STACK
|
|
;
|
|
INIT:
|
|
DI ; NO INTERRUPTS FOR NOW
|
|
|
|
; ADJUST BOOT VECTOR TO REBOOT ROUTINE
|
|
LD HL,REBOOT ; GET REBOOT ADDRESS
|
|
LD (CBIOS_LOC + 1),HL ; STORE IT IN FIRST ENTRY OF CBIOS JUMP TABLE
|
|
|
|
#IFDEF PLTUNA
|
|
; MAKE SURE UNA EXEC PAGE IS ACTIVE
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_USR ; SWITCH BACK TO EXEC BANK
|
|
CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED)
|
|
|
|
; COPY BIOS PAGE ZERO TO USER BANK
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_BIOS ; UBIOS_PAGE (SEE PAGES.INC)
|
|
CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED)
|
|
PUSH DE ; SAVE PREVIOUS BANK
|
|
|
|
LD HL,0 ; FROM ADDRESS 0 (PAGE ZERO)
|
|
LD DE,SECBUF ; USE SECBUF AS BOUNCE BUFFER
|
|
LD BC,256 ; ONE PAGE IS 256 BYTES
|
|
LDIR ; DO IT
|
|
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
POP DE ; RECOVER OPERATING BANK
|
|
CALL $FFFD ; DO IT (RST 08 NOT YET INSTALLED)
|
|
|
|
LD HL,SECBUF ; FROM SECBUF (BUNCE BUFFER)
|
|
LD DE,0 ; TO PAGE ZERO OF OPERATING BANK
|
|
LD BC,256 ; ONE PAGE IS 256 BYTES
|
|
LDIR ; DO IT
|
|
|
|
; INSTALL UNA INVOCATION VECTOR FOR RST 08
|
|
LD A,$C3 ; JP INSTRUCTION
|
|
LD (8),A ; STORE AT 0x0008
|
|
LD HL,($FFFE) ; UNA ENTRY VECTOR
|
|
LD (9),HL ; STORE AT 0x0009
|
|
#ELSE
|
|
; GET CRITICAL BANK ID'S
|
|
LD B,BF_SYSGET ; HBIOS FUNC=GET SYS INFO
|
|
LD C,BF_SYSGET_BNKINFO ; HBIOS SUBFUNC=GET BANK ASSIGNMENTS
|
|
RST 08 ; CALL HBIOS
|
|
LD A,D ; GET HBIOS BANK RETURNED IN D
|
|
LD (BNKBIOS),A ; ... AND SAVE IT
|
|
LD A,E ; GET USER BANK RETURNED IN E
|
|
LD (BNKUSER),A ; ... AND SAVE IT
|
|
|
|
; SOFT RESET HBIOS
|
|
LD B,BF_SYSRESET ; HB FUNC: RESET
|
|
RST 08 ; DO IT
|
|
|
|
; CREATE A TEMP COPY OF THE HBIOS CONFIG BLOCK (HCB)
|
|
; FOR REFERENCE USE DURING INIT
|
|
LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY
|
|
LD DE,(BNKBIOS) ; D = DEST (USER BANK), E = SOURCE (BIOS BANK)
|
|
LD HL,HCB_SIZ ; HL = COPY LEN = SIZE OF HCB
|
|
RST 08 ; DO IT
|
|
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
|
|
LD HL,HCB_LOC ; COPY FROM FIXED LOCATION IN HB BANK
|
|
LD DE,HCB ; TO TEMP LOCATION IN USR BANK
|
|
RST 08 ; DO IT
|
|
|
|
; CAPTURE RAM DRIVE STARTING BANK
|
|
LD A,(HCB + HCB_BIDRAMD0)
|
|
LD (BNKRAMD),A
|
|
#ENDIF
|
|
|
|
; PARAMETER INITIALIZATION
|
|
LD A,DEF_IOBYTE ; LOAD DEFAULT IOBYTE
|
|
LD (IOBYTE),A ; STORE IT
|
|
|
|
; INIT DEFAULT DRIVE TO A: FOR NOW
|
|
XOR A ; ZERO
|
|
LD (DEFDRIVE),A ; STORE IT
|
|
|
|
; CBIOS BANNER
|
|
CALL NEWLINE2 ; FORMATTING
|
|
LD DE,STR_BANNER ; POINT TO BANNER
|
|
CALL WRITESTR ; DISPLAY IT
|
|
|
|
#IFDEF PLTUNA
|
|
; SAVE COMMAND PROCESSOR IMAGE TO MALLOCED CACHE IN UNA BIOS PAGE
|
|
LD C,$F7 ; UNA MALLOC
|
|
LD DE,CCP_SIZ ; SIZE OF CCP
|
|
RST 08 ; DO IT
|
|
CALL NZ,PANIC ; BIG PROBLEM
|
|
LD (CCPBUF),HL ; SAVE THE ADDRESS (IN BIOS MEM)
|
|
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_BIOS ; UBIOS_PAGE (SEE PAGES.INC)
|
|
RST 08 ; DO IT
|
|
PUSH DE ; SAVE PREVIOUS BANK
|
|
|
|
LD HL,CCP_LOC ; ADDRESS IN HI MEM OF CCP
|
|
LD DE,(CCPBUF) ; ADDRESS OF CCP BUF IN BIOS MEM
|
|
LD BC,CCP_SIZ ; SIZE OF CCP
|
|
LDIR ; DO IT
|
|
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
POP DE ; RECOVER OPERATING BANK
|
|
RST 08 ; DO IT
|
|
#ELSE
|
|
; SAVE COMMAND PROCESSOR TO ALLOCATED CACHE IN RAM BANK 1
|
|
LD B,BF_SYSALLOC ; HBIOS FUNC: ALLOCATE HEAP MEMORY
|
|
LD HL,CCP_SIZ ; SIZE TO ALLOC (SIZE OF CCP)
|
|
RST 08 ; DO IT
|
|
CALL NZ,PANIC ; BIG PROBLEM
|
|
LD (CCPBUF),HL ; SAVE THE ADDRESS (IN BIOS MEM)
|
|
LD B,BF_SYSSETCPY ; HBIOS FUNC: SETUP BANK COPY
|
|
LD A,(BNKUSER) ; GET USER BANK
|
|
LD E,A ; E = SOURCE (USER BANK)
|
|
LD A,(BNKBIOS) ; GET BIOS BANK
|
|
LD D,A ; D = DEST (BIOS BANK)
|
|
LD HL,CCP_SIZ ; HL = COPY LEN = SIZE OF COMMAND PROCESSOR
|
|
RST 08 ; DO IT
|
|
LD B,BF_SYSBNKCPY ; HBIOS FUNC: PERFORM BANK COPY
|
|
LD HL,CCP_LOC ; COPY FROM CCP LOCATION IN USR BANK
|
|
LD DE,(CCPBUF) ; TO ALLOCATED LOCATION IN HB BANK
|
|
RST 08 ; DO IT
|
|
#ENDIF
|
|
|
|
; DISK SYSTEM INITIALIZATION
|
|
CALL BLKRES ; RESET DISK (DE)BLOCKING ALGORITHM
|
|
CALL DEV_INIT ; INITIALIZE CHARACTER DEVICE MAP
|
|
CALL MD_INIT ; INITIALIZE MEMORY DISK DRIVER (RAM/ROM)
|
|
CALL DRV_INIT ; INITIALIZE DRIVE MAP
|
|
CALL DPH_INIT ; INITIALIZE DPH TABLE AND BUFFERS
|
|
;
|
|
#IFDEF PLTUNA
|
|
; USE A DEDICATED BUFFER FOR UNA PHYSICAL DISK I/O
|
|
LD HL,SECBUF ; ADDRESS OF PHYSICAL SECTOR BUFFER
|
|
LD (DSKBUF),HL ; SAVE IT IN DSKBUF FOR LATER
|
|
#ELSE
|
|
; ALLOCATE A SINGLE SECTOR DISK BUFFER ON THE HBIOS HEAP
|
|
LD B,BF_SYSALLOC ; BIOS FUNC: ALLOCATE HEAP MEMORY
|
|
LD HL,512 ; 1 SECTOR, 512 BYTES
|
|
RST 08 ; DO IT
|
|
CALL NZ,PANIC ; HANDLE ERROR
|
|
LD (DSKBUF),HL ; RECORD THE BUFFER ADDRESS
|
|
#ENDIF
|
|
;
|
|
; DISPLAY FREE MEMORY
|
|
LD DE,STR_LDR2 ; FORMATTING
|
|
CALL WRITESTR ; AND PRINT IT
|
|
;LD HL,CBIOS_END ; SUBTRACT HIGH WATER
|
|
LD HL,HEAPEND ; SUBTRACT HIGH WATER
|
|
LD DE,(HEAPTOP) ; ... FROM TOP OF CBIOS
|
|
OR A ; ... WITH CF CLEAR
|
|
SBC HL,DE ; ... SO HL GETS BYTES FREE
|
|
CALL PRTDEC ; PRINT IT
|
|
LD DE,STR_MEMFREE ; ADD DESCRIPTION
|
|
CALL WRITESTR ; AND PRINT IT
|
|
;
|
|
LD A,(DEFDRIVE) ; GET DEFAULT DRIVE
|
|
LD (CDISK),A ; ... AND SETUP CDISK
|
|
;
|
|
; OS BANNER
|
|
CALL NEWLINE2 ; FORMATTING
|
|
LD DE,STR_CPM ; DEFAULT TO CP/M LABEL
|
|
LD A,(BDOS_LOC) ; GET FIRST BYTE OF BDOS
|
|
CP 'Z' ; IS IT A 'Z' (FOR ZSDOS)?
|
|
JR NZ,INIT2 ; NOPE, CP/M IS RIGHT
|
|
LD DE,STR_ZSDOS ; SWITCH TO ZSDOS LABEL
|
|
INIT2:
|
|
CALL WRITESTR ; DISPLAY OS LABEL
|
|
LD DE,STR_TPA1 ; TPA PREFIX
|
|
CALL WRITESTR
|
|
LD A,BDOS_LOC / 1024 ; TPA SIZE IS START OF BDOS
|
|
CALL PRTDECB ; PRINT IT
|
|
CALL PC_PERIOD ; DECIMAL POINT
|
|
LD A,0 + (((BDOS_LOC % 1024) * 100) / 1024)
|
|
CALL PRTDECB ; MANTISSA
|
|
LD DE,STR_TPA2 ; AND TPA SUFFIX
|
|
CALL WRITESTR
|
|
CALL NEWLINE ; FORMATTING
|
|
RET ; DONE
|
|
;
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
AUTOSUB:
|
|
;
|
|
; SETUP AUTO SUBMIT COMMAND (IF REQUIRED FILES EXIST)
|
|
LD A,(DEFDRIVE) ; GET DEFAULT DRIVE
|
|
INC A ; CONVERT FROM DRIVE NUM TO FCB DRIVE CODE
|
|
LD (FCB_SUB),A ; SET DRIVE OF SUBMIT.COM FCB
|
|
LD (FCB_PRO),A ; SET DRIVE OF PROFILE.SUB FCB
|
|
;
|
|
LD C,17 ; BDOS FUNCTION: FIND FIRST
|
|
LD DE,FCB_SUB ; CHECK FOR SUBMIT.COM
|
|
CALL BDOS ; INVOKE BDOS TO LOOK FOR FILE
|
|
INC A ; CHECK FOR ERR, $FF --> $00
|
|
RET Z ; ERR, DO NOT ATTEMPT AUTO SUBMIT
|
|
;
|
|
LD C,17 ; BDOS FUNCTION: FIND FIRST
|
|
LD DE,FCB_PRO ; CHECK FOR PROFILE.SUB
|
|
CALL BDOS ; INVOKE BDOS TO LOOK FOR FILE
|
|
INC A ; CHECK FOR ERR, $FF --> $00
|
|
RET Z ; ERR, DO NOT ATTEMPT AUTO SUBMIT
|
|
;
|
|
LD HL,CMD ; ADDRESS OF STARTUP COMMAND
|
|
LD DE,CCP_LOC + 7 ; START OF COMMAND BUFFER IN CCP
|
|
LD BC,CMDLEN ; LENGTH OF AUTOSTART COMMAND
|
|
LDIR ; PATCH COMMAND LINE INTO CCP
|
|
RET ; DONE
|
|
;
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
DEV_INIT:
|
|
;
|
|
#IFDEF PLTWBW
|
|
;
|
|
; PATCH IN CRT: DEVICE
|
|
LD A,(HCB + HCB_CRTDEV) ; GET CONSOLE DEVICE
|
|
CP $FF ; NUL MEANS NO CRT DEVICE
|
|
JR Z,DEV_INIT00 ; IF SO, LEAVE IT ALONE
|
|
LD (DEVMAP + 1),A ; CONSOLE CRT
|
|
LD (DEVMAP + 13),A ; LIST CRT
|
|
;
|
|
; UPDATE IOBYTE IF CRT DEVICE IS ACTIVE
|
|
LD A,(HCB + HCB_CRTDEV) ; GET CRT DEVICE
|
|
LD B,A ; SAVE IN B
|
|
LD A,(HCB + HCB_CONDEV) ; GET CONSOLE DEVICE
|
|
CP B ; COMPARE
|
|
JR NZ,DEV_INIT00 ; IF DIFFERENT (CRT NOT ACTIVE), LEAVE IOBYTE ALONE
|
|
LD A,1 ; IF SAME (CRT ACTIVE), SET IOBYTE FOR CON: = CRT:
|
|
LD (IOBYTE),A ; STORE IN IOBYTE
|
|
;
|
|
DEV_INIT00:
|
|
; LOOP THRU DEVICES ADDING NON-CRT DEVICES TO DEVMAP
|
|
LD B,BF_SYSGET ; HBIOS FUNC: GET SYS INFO
|
|
LD C,BF_SYSGET_CIOCNT ; SUBFUNC: GET CIO UNIT COUNT
|
|
RST 08 ; E := SERIAL UNIT COUNT
|
|
LD B,E ; COUNT TO B
|
|
LD C,0 ; UNIT INDEX
|
|
LD HL,DEV_INIT1 ; POINTER FOR FIRST ENTRY FOUND
|
|
DEV_INIT0:
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
PUSH HL ; SAVE TARGET
|
|
LD B,BF_CIODEVICE ; HBIOS FUNC: GET DEVICE INFO
|
|
RST 08 ; D := DEVICE TYPE, E := PHYSICAL UNIT NUMBER
|
|
POP HL ; RESTORE TARGET
|
|
LD A,D ; DEVICE TYPE TO A
|
|
; FIX: BELOW SHOULD TEST THE "TERMINAL" BIT INSTEAD OF CHECKING DEVICE NUMBER
|
|
CP CIODEV_TERM ; COMPARE TO FIRST VIDEO DEVICE
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
LD A,C ; UNIT INDEX TO ACCUM
|
|
;CALL C,JPHL ; DO IT IF DEVICE TYPE < VDU
|
|
CALL JPHL ; DO FOR ANY CHARACTER DEVICE TYPE
|
|
INC C ; NEXT UNIT
|
|
DJNZ DEV_INIT0 ; LOOP TILL DONE
|
|
RET ; ALL DONE
|
|
;
|
|
DEV_INIT1:
|
|
; PATCH IN COM0: DEVICE ENTRIES, COM0: IS TTY:
|
|
LD (DEVMAP + 0),A ; TTY: @ CON:
|
|
LD (DEVMAP + 4),A ; TTY: @ RDR:
|
|
LD (DEVMAP + 8),A ; TTY: @ PUN:
|
|
LD (DEVMAP + 12),A ; TTY: @ LST:
|
|
LD HL,DEV_INIT2 ; HL := CODE FOR NEXT DEVICE
|
|
RET
|
|
;
|
|
DEV_INIT2:
|
|
; PATCH IN COM1: DEVICE ENTRIES, COM1: IS UC1:, PTR:, PTP:, LPT:
|
|
LD (DEVMAP + 3),A ; UC1: @ CON:
|
|
LD (DEVMAP + 5),A ; PTR: @ RDR:
|
|
LD (DEVMAP + 9),A ; PTP: @ PUN:
|
|
LD (DEVMAP + 14),A ; LPT: @ LST:
|
|
LD HL,DEV_INIT3 ; HL := CODE FOR NEXT DEVICE
|
|
RET
|
|
;
|
|
DEV_INIT3:
|
|
; PATCH IN COM2: DEVICE ENTRIES, COM2: IS UR1:, UP1:, UL1:
|
|
LD (DEVMAP + 6),A ; UR1: @ RDR:
|
|
LD (DEVMAP + 10),A ; UP1: @ PUN:
|
|
LD (DEVMAP + 15),A ; UL1: @ LST:
|
|
LD HL,DEV_INIT4 ; HL := CODE FOR NEXT DEVICE
|
|
RET
|
|
;
|
|
DEV_INIT4:
|
|
; PATCH IN COM3: DEVICE ENTRIES, COM3: IS UR2:, UP2:
|
|
LD (DEVMAP + 7),A ; UR2: @ RDR:
|
|
LD (DEVMAP + 11),A ; UP2: @ PUN:
|
|
LD HL,DEV_INIT5 ; HL := CODE FOR NEXT DEVICE
|
|
RET
|
|
;
|
|
DEV_INIT5:
|
|
RET ; FAILSAFE IN CASE MORE THAN 4 COM DEVICES
|
|
;
|
|
#ENDIF
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
MD_INIT:
|
|
;
|
|
; UDPATE THE RAM/ROM DPB STRUCTURES BASED ON HARDWARE
|
|
;
|
|
#IFDEF PLTWBW
|
|
LD A,(HCB + HCB_ROMBANKS) ; ROM BANK COUNT
|
|
LD IX,DPB_ROM ; ADDRESS OF DPB
|
|
CALL MD_INIT1 ; FIX IT UP
|
|
;
|
|
LD A,(HCB + HCB_RAMBANKS) ; RAM BANK COUNT
|
|
LD IX,DPB_RAM ; ADDRESS OF DPB
|
|
CALL MD_INIT1 ; FIX IT UP
|
|
;
|
|
JR MD_INIT4 ; DONE
|
|
;
|
|
MD_INIT1:
|
|
;
|
|
; PUT USABLE BANK COUNT IN HL
|
|
SUB 4 ; REDUCE BANK COUNT BY RESERVED PAGES
|
|
LD L,A ; PUT IN LSB OF HL
|
|
LD H,0 ; MSB IS ALWAYS ZERO
|
|
;
|
|
; UPDATE ALS FIELD
|
|
LD A,L ; LSB OF PAGE COUNT
|
|
RLCA ; DOUBLE IT
|
|
LD (IX - 3),A ; SAVE IT AS LSB OF ALS
|
|
;
|
|
; UDPATE EXM FIELD
|
|
LD A,L ; LSB OF PAGE COUNT
|
|
CP 16 + 1 ; COMPARE TO EXM THRESHOLD
|
|
LD A,1 ; ASSUME <= 16 BANKS, EXM := 1
|
|
JR C,MD_INIT2
|
|
XOR A ; > 16 BANKS, EXM := 0
|
|
MD_INIT2:
|
|
LD (IX + 4),A ; SAVE EXM VALUE
|
|
;
|
|
; UPDATE DSM FIELD
|
|
LD B,4 ; ROTATE 4 TIMES TO MULTIPLY BY 16
|
|
MD_INIT3:
|
|
SLA L ; SHIFT LSB
|
|
RL H ; SHIFT MSB W/ CARRY
|
|
DJNZ MD_INIT3 ; REPEAT AS NEEDED
|
|
DEC HL ; SUBTRACT 1 FOR PROPER DSM VALUE
|
|
LD (IX+5),L ; SAVE UPDATED
|
|
LD (IX+6),H ; ... DSM VALUE
|
|
RET
|
|
;
|
|
MD_INIT4:
|
|
;
|
|
#ENDIF
|
|
;
|
|
#IFDEF PLTUNA
|
|
;
|
|
; INITIALIZE RAM DISK BY FILLING DIRECTORY WITH 'E5' BYTES
|
|
; FILL FIRST 8K OF RAM DISK TRACK 1 WITH 'E5'
|
|
;
|
|
#IF (CLRRAMDISK != CLR_NEVER)
|
|
DI ; NO INTERRUPTS
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_RAMD0 ; FIRST BANK OF RAM DISK
|
|
CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE)
|
|
|
|
#IF (CLRRAMDISK == CLR_AUTO)
|
|
; CHECK FIRST 32 DIRECTORY ENTRIES. IF ANY START WITH AN INVALID
|
|
; VALUE, INIT THE RAM DISK. VALID ENTRIES ARE E5 (EMPTY ENTRY) OR
|
|
; 0-15 (USER NUMBER).
|
|
LD HL,0
|
|
LD DE,32
|
|
LD B,32
|
|
CLRRAM0:
|
|
LD A,(HL)
|
|
CP $E5
|
|
JR Z,CLRRAM1 ; E5 IS VALID
|
|
CP 16
|
|
JR C,CLRRAM1 ; 0-15 IS ALSO VALID
|
|
JR CLRRAM2 ; INVALID ENTRY! JUMP TO INIT
|
|
CLRRAM1:
|
|
ADD HL,DE ; LOOP FOR 32 ENTRIES
|
|
DJNZ CLRRAM0
|
|
; JR CLRRAM2 ; *DEBUG*
|
|
JR CLRRAM3 ; ALL ENTRIES VALID, BYPASS INIT
|
|
CLRRAM2:
|
|
#ENDIF
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_USR ; SWITCH BACK TO EXEC BANK FOR WRITESTR
|
|
CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE)
|
|
|
|
CALL NEWLINE2 ; FORMATTING
|
|
LD DE,STR_INITRAMDISK ; RAM DISK INIT MESSAGE
|
|
CALL WRITESTR ; DISPLAY IT
|
|
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_RAMD0 ; FIRST BANK OF RAM DISK
|
|
CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE)
|
|
|
|
LD HL,0 ; SOURCE ADR FOR FILL
|
|
LD BC,$2000 ; LENGTH OF FILL IS 8K
|
|
LD A,$E5 ; FILL VALUE
|
|
CALL FILL ; DO IT
|
|
CLRRAM3:
|
|
LD BC,$01FB ; UNA FUNC = SET BANK
|
|
LD DE,BID_USR ; SWITCH BACK TO EXEC BANK
|
|
CALL $FFFD ; DO IT (RST 08 NOT SAFE HERE)
|
|
EI ; RESUME INTERRUPTS
|
|
|
|
#ENDIF
|
|
|
|
#ELSE
|
|
;
|
|
; INITIALIZE RAM DISK BY FILLING DIRECTORY WITH 'E5' BYTES
|
|
; FILL FIRST 8K OF RAM DISK TRACK 1 WITH 'E5'
|
|
;
|
|
#IF (CLRRAMDISK != CLR_NEVER)
|
|
DI ; NO INTERRUPTS
|
|
LD A,(BNKRAMD) ; FIRST BANK OF RAM DISK
|
|
CALL HB_BNKSEL ; SELECT BANK
|
|
|
|
#IF (CLRRAMDISK == CLR_AUTO)
|
|
; CHECK FIRST 32 DIRECTORY ENTRIES. IF ANY START WITH AN INVALID
|
|
; VALUE, INIT THE RAM DISK. VALID ENTRIES ARE E5 (EMPTY ENTRY) OR
|
|
; 0-15 (USER NUMBER).
|
|
LD HL,0
|
|
LD DE,32
|
|
LD B,32
|
|
CLRRAM0:
|
|
LD A,(HL)
|
|
CP $E5
|
|
JR Z,CLRRAM1 ; E5 IS VALID
|
|
CP 16
|
|
JR C,CLRRAM1 ; 0-15 IS ALSO VALID
|
|
JR CLRRAM2 ; INVALID ENTRY! JUMP TO INIT
|
|
CLRRAM1:
|
|
ADD HL,DE ; LOOP FOR 32 ENTRIES
|
|
DJNZ CLRRAM0
|
|
; JR CLRRAM2 ; *DEBUG*
|
|
JR CLRRAM3 ; ALL ENTRIES VALID, BYPASS INIT
|
|
CLRRAM2:
|
|
#ENDIF
|
|
LD A,(BNKUSER) ; SWITCH BACK TO USER BANK
|
|
CALL HB_BNKSEL ; SELECT BANK
|
|
CALL NEWLINE2 ; FORMATTING
|
|
LD DE,STR_INITRAMDISK ; RAM DISK INIT MESSAGE
|
|
CALL WRITESTR ; DISPLAY IT
|
|
LD A,(BNKRAMD) ; SWITCH BACK TO FIRST BANK
|
|
CALL HB_BNKSEL ; SELECT BANK
|
|
LD HL,0 ; SOURCE ADR FOR FILL
|
|
LD BC,$2000 ; LENGTH OF FILL IS 8K
|
|
LD A,$E5 ; FILL VALUE
|
|
CALL FILL ; DO IT
|
|
CLRRAM3:
|
|
LD A,(BNKUSER) ; USR BANK (TPA)
|
|
CALL HB_BNKSEL ; SELECT BANK
|
|
EI ; RESUME INTRRUPTS
|
|
#ENDIF
|
|
;
|
|
#ENDIF
|
|
;
|
|
RET
|
|
;
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
#IFDEF PLTUNA
|
|
;
|
|
DRV_INIT:
|
|
;
|
|
; PERFORM UBIOS SPECIFIC INITIALIZATION
|
|
; BUILD DRVMAP BASED ON AVAILABLE UBIOS DISK DEVICE LIST
|
|
;
|
|
; GET BOOT UNIT/SLICE INFO
|
|
LD BC,$00FC ; UNA FUNC: GET BOOTSTRAP HISTORY
|
|
RST 08 ; CALL UNA
|
|
LD D,L ; SAVE L AS UNIT
|
|
LD E,0 ; SLICE IS ZERO
|
|
LD (BOOTVOL),DE ; D -> UNIT, E -> SLICE
|
|
;
|
|
; SETUP THE DRVMAP STRUCTURE
|
|
LD HL,(HEAPTOP) ; GET CURRENT HEAP TOP
|
|
INC HL ; SKIP 1 BYTE FOR ENTRY COUNT PREFIX
|
|
LD (DRVMAPADR),HL ; SAVE AS DRIVE MAP ADDRESS
|
|
LD (HEAPTOP),HL ; ... AND AS NEW HEAP TOP
|
|
;
|
|
; LOOP THRU DEVICES TO COUNT TOTAL HARD DISK VOLUMES
|
|
LD B,0 ; START WITH UNIT 0
|
|
LD L,0 ; INIT HD VOL COUNT
|
|
;
|
|
DRV_INIT2: ; LOOP THRU ALL UNITS AVAILABLE
|
|
PUSH HL ; SAVE HD VOL COUNT
|
|
LD C,$48 ; UNA FUNC: GET DISK TYPE
|
|
LD L,0 ; PRESET UNIT COUNT TO ZERO
|
|
CALL $FFFD ; CALL UNA, B IS ASSUMED TO BE UNTOUCHED!!!
|
|
LD A,L ; UNIT COUNT TO A
|
|
POP HL ; RESTORE HD VOL COUNT
|
|
OR A ; PAST END?
|
|
JR Z,DRV_INIT4 ; WE ARE DONE, MOVE ON
|
|
CALL DRV_INIT3 ; PROCESS THE UNIT
|
|
INC B ; NEXT UNIT
|
|
JR DRV_INIT2 ; LOOP
|
|
;
|
|
DRV_INIT3:
|
|
LD A,D ; DRIVER TYPE TO A
|
|
CP $40 ; RAM/ROM?
|
|
RET Z ; DO NOT COUNT
|
|
;CP $?? ; FLOPPY?
|
|
;RET Z ; DO NOT COUNT
|
|
INC L ; INCREMENT HARD DISK COUNT
|
|
RET ; DONE
|
|
;
|
|
DRV_INIT4: ; SET SLICES PER VOLUME (HDSPV) BASED ON HARD DISK VOLUME COUNT
|
|
LD A,L ; HARD DISK VOLUME COUNT TO A
|
|
LD E,8 ; ASSUME 8 SLICES PER VOLUME
|
|
DEC A ; DEC ACCUM TO CHECK FOR COUNT = 1
|
|
JR Z,DRV_INIT5 ; YES, SKIP AHEAD TO IMPLEMENT 8 HDSPV
|
|
LD E,4 ; NOW ASSUME 4 SLICES PER VOLUME
|
|
DEC A ; DEC ACCUM TO CHECK FOR COUNT = 2
|
|
JR Z,DRV_INIT5 ; YES, SKIP AHEAD TO IMPLEMENT 4 HDSPV
|
|
LD E,2 ; IN ALL OTHER CASES, WE USE 2 HDSPV
|
|
;
|
|
DRV_INIT5:
|
|
LD A,E ; SLICES PER VOLUME VALUE TO ACCUM
|
|
LD (HDSPV),A ; SAVE IT
|
|
;
|
|
; SETUP TO ENUMERATE DEVICES TO BUILD DRVMAP
|
|
LD B,0 ; START WITH UNIT 0
|
|
;
|
|
DRV_INIT6: ; LOOP THRU ALL UNITS AVAILABLE
|
|
LD C,$48 ; UNA FUNC: GET DISK TYPE
|
|
LD L,0 ; PRESET UNIT COUNT TO ZERO
|
|
CALL $FFFD ; CALL UNA, B IS ASSUMED TO BE UNTOUCHED!!!
|
|
LD A,L ; UNIT COUNT TO A
|
|
OR A ; PAST END?
|
|
RET Z ; WE ARE DONE
|
|
PUSH BC ; SAVE UNIT
|
|
CALL DRV_INIT7 ; PROCESS THE UNIT
|
|
POP BC ; RESTORE UNIT
|
|
INC B ; NEXT UNIT
|
|
JR DRV_INIT6 ; LOOP
|
|
;
|
|
DRV_INIT7: ; PROCESS CURRENT UNIT (SEE UNA PROTOIDS.INC)
|
|
LD A,D ; DRIVE TYPE TO ACCUM
|
|
LD D,B ; UNIT TO D
|
|
LD E,0 ; INIT SLICE INDEX
|
|
LD B,1 ; DEFAULT LOOP COUNTER (1 SLICE)
|
|
CP $40 ; RAM/ROM?
|
|
JR Z,DRV_INIT8 ; SINGLE SLICE, DO IT
|
|
;CP $?? ; FLOPPY?
|
|
;JR Z,DRV_INIT8 ; SINGLE SLICE, DO IT
|
|
LD A,(HDSPV) ; GET SLICES PER VOLUME TO ACCUM
|
|
LD B,A ; MOVE TO B FOR LOOP COUNTER
|
|
;
|
|
DRV_INIT8: ; SLICE CREATION LOOP
|
|
;
|
|
; INC DRVMAP ENTRY COUNT AND CHECK FOR 16 ENTRY MAXIMUM
|
|
LD HL,(DRVMAPADR) ; POINT TO DRIVE MAP
|
|
DEC HL ; BACKUP TO POINT TO ENTRY COUNT
|
|
LD A,(HL) ; CURRENT COUNT TO ACCUM
|
|
CP 16 ; AT MAX?
|
|
RET NC ; IF >= MAX, JUST BAIL OUT
|
|
INC (HL) ; INCREMENT THE ENTRY COUNT
|
|
;
|
|
; ALLOCATE ENTRY AND FILL IN UNIT, SLICE
|
|
LD HL,4 ; 4 BYTES PER ENTRY
|
|
CALL ALLOC ; ALLOCATE SPACE
|
|
;CALL NZ,PANIC ; SHOULD NEVER ERROR HERE
|
|
CALL C,PANIC ; SHOULD NEVER ERROR HERE
|
|
LD (HL),D ; SAVE UNIT IN FIRST BYTE OF DRVMAP ENTRY
|
|
INC HL ; POINT TO NEXT BYTE OF DRVMAP ENTRY
|
|
LD (HL),E ; SAVE SLICE NUM IN SECOND BYTE OF DRVMAP ENTRY
|
|
;
|
|
INC E ; INCREMENT SLICE INDEX
|
|
DJNZ DRV_INIT8 ; LOOP AS NEEDED
|
|
RET ; DONE
|
|
;
|
|
#ELSE
|
|
;
|
|
DRV_INIT:
|
|
;
|
|
; PERFORM HBIOS SPECIFIC INITIALIZATION
|
|
; BUILD DRVMAP BASED ON AVAILABLE HBIOS DISK DEVICE LIST
|
|
;
|
|
; GET BOOT UNIT/SLICE INFO
|
|
LD DE,(HCB + HCB_BOOTVOL) ; BOOT VOLUME (UNIT, SLICE)
|
|
LD (BOOTVOL),DE ; D -> UNIT, E -> SLICE
|
|
;
|
|
; SETUP THE DRVMAP STRUCTURE
|
|
LD HL,(HEAPTOP) ; GET CURRENT HEAP TOP
|
|
INC HL ; SKIP 1 BYTE FOR ENTRY COUNT PREFIX
|
|
LD (DRVMAPADR),HL ; SAVE AS DRVMAP ADDRESS
|
|
LD (HEAPTOP),HL ; AND AS NEW HEAP TOP
|
|
;
|
|
; SETUP TO LOOP THROUGH AVAILABLE DEVICES
|
|
LD B,BF_SYSGET
|
|
LD C,BF_SYSGET_DIOCNT
|
|
RST 08 ; E := DISK UNIT COUNT
|
|
LD B,E ; COUNT TO B
|
|
LD A,B ; COUNT TO A
|
|
OR A ; SET FLAGS
|
|
RET Z ; HANDLE ZERO DEVICES (ALBEIT POORLY)
|
|
;
|
|
; LOOP THRU DEVICES TO COUNT TOTAL HARD DISK VOLUMES
|
|
PUSH BC ; SAVE THE DEVICE COUNT
|
|
LD C,0 ; USE C AS DEVICE LIST INDEX
|
|
LD E,0 ; INIT E FOR HARD DISK VOLUME COUNT
|
|
;
|
|
DRV_INIT2:
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
CALL DRV_INIT3 ; CHECK DRIVE
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
INC C ; NEXT UNIT
|
|
DJNZ DRV_INIT2 ; LOOP
|
|
POP BC ; RESTORE UNIT COUNT IN B
|
|
JR DRV_INIT4 ; CONTINUE
|
|
;
|
|
DRV_INIT3:
|
|
PUSH DE ; SAVE DE (HARD DISK VOLUME COUNTER)
|
|
LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO
|
|
RST 08 ; CALL HBIOS, UNIT TO C
|
|
LD A,D ; DEVICE TYPE TO A
|
|
POP DE ; RESTORE DE
|
|
CP DIODEV_IDE ; HARD DISK DEVICE?
|
|
RET C ; NOPE, RETURN
|
|
INC E ; INCREMENT HARD DISK COUNT
|
|
RET ; AND RETURN
|
|
;
|
|
DRV_INIT4: ; SET SLICES PER VOLUME (HDSPV) BASED ON HARD DISK VOLUME COUNT
|
|
LD A,E ; HARD DISK VOLUME COUNT TO A
|
|
LD E,8 ; ASSUME 8 SLICES PER VOLUME
|
|
DEC A ; DEC ACCUM TO CHECK FOR COUNT = 1
|
|
JR Z,DRV_INIT5 ; YES, SKIP AHEAD TO IMPLEMENT 8 HDSPV
|
|
LD E,4 ; NOW ASSUME 4 SLICES PER VOLUME
|
|
DEC A ; DEC ACCUM TO CHECK FOR COUNT = 2
|
|
JR Z,DRV_INIT5 ; YES, SKIP AHEAD TO IMPLEMENT 4 HDSPV
|
|
LD E,2 ; IN ALL OTHER CASES, WE USE 2 HDSPV
|
|
;
|
|
DRV_INIT5:
|
|
LD A,E ; SLICES PER VOLUME VALUE TO ACCUM
|
|
LD (HDSPV),A ; SAVE IT
|
|
;
|
|
; SETUP TO ENUMERATE DEVICES TO BUILD DRVMAP
|
|
LD B,BF_SYSGET
|
|
LD C,BF_SYSGET_DIOCNT
|
|
RST 08 ; E := DISK UNIT COUNT
|
|
LD B,E ; COUNT TO B
|
|
LD C,0 ; USE C AS DEVICE LIST INDEX
|
|
;
|
|
DRV_INIT6: ; LOOP THRU ALL UNITS AVAILABLE
|
|
PUSH BC ; PRESERVE LOOP CONTROL
|
|
LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO
|
|
RST 08 ; CALL HBIOS, D := DEVICE TYPE
|
|
POP BC ; GET UNIT INDEX BACK IN C
|
|
PUSH BC ; RESAVE LOOP CONTROL
|
|
CALL DRV_INIT7 ; MAKE DRIVE MAP ENTRY(S)
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
INC C ; INCREMENT LIST INDEX
|
|
DJNZ DRV_INIT6 ; LOOP AS NEEDED
|
|
RET ; FINISHED
|
|
;
|
|
DRV_INIT7: ; PROCESS UNIT
|
|
LD E,0 ; INITIALIZE SLICE INDEX
|
|
LD B,1 ; DEFAULT LOOP COUNTER
|
|
LD A,D ; DEVICE TYPE TO ACCUM
|
|
LD D,C ; UNIT NUMBER TO D
|
|
CP DIODEV_IDE ; HARD DISK DEVICE?
|
|
JR C,DRV_INIT8 ; NOPE, LEAVE LOOP COUNT AT 1
|
|
LD A,(HDSPV) ; GET SLICES PER VOLUME TO ACCUM
|
|
LD B,A ; MOVE TO B FOR LOOP COUNTER
|
|
;
|
|
DRV_INIT8: ; SLICE CREATION LOOP
|
|
;
|
|
; INC DRVMAP ENTRY COUNT AND ENFORCE FOR 16 ENTRY MAXIMUM
|
|
LD HL,(DRVMAPADR) ; POINT TO DRIVE MAP
|
|
DEC HL ; BACKUP TO POINT TO ENTRY COUNT
|
|
LD A,(HL) ; CURRENT COUNT TO ACCUM
|
|
CP 16 ; AT MAX?
|
|
RET NC ; IF >= MAX, JUST BAIL OUT
|
|
INC (HL) ; INCREMENT THE ENTRY COUNT
|
|
;
|
|
; ALLOCATE ENTRY AND FILL IN UNIT, SLICE
|
|
LD HL,4 ; 4 BYTES PER ENTRY
|
|
CALL ALLOC ; ALLOCATE SPACE
|
|
CALL C,PANIC ; SHOULD NEVER ERROR HERE
|
|
LD (HL),D ; SAVE UNIT IN FIRST BYTE OF DRVMAP ENTRY
|
|
INC HL ; POINT TO NEXT BYTE OF DRVMAP ENTRY
|
|
LD (HL),E ; SAVE SLICE NUM IN SECOND BYTE OF DRVMAP ENTRY
|
|
;
|
|
INC E ; INCREMENT SLICE INDEX
|
|
DJNZ DRV_INIT8 ; LOOP AS NEEDED
|
|
RET ; DONE
|
|
;
|
|
#ENDIF
|
|
;
|
|
;
|
|
;__________________________________________________________________________________________________
|
|
;
|
|
DPH_INIT:
|
|
;
|
|
; ITERATE THROUGH DRIVE MAP TO BUILD DPH ENTRIES DYNAMICALLY
|
|
;
|
|
CALL NEWLINE2 ; FORMATTING
|
|
LD DE,STR_DPHINIT ; POINT TO MSG
|
|
CALL WRITESTR ; DISPLAY IT
|
|
CALL NEWLINE ; FORMATTING
|
|
;
|
|
; ALLOCATE DPH POOL SPACE BASED ON DRIVE COUNT
|
|
LD HL,(DRVMAPADR) ; LOAD DRIVE MAP POINTER
|
|
DEC HL ; BACKUP TO ENTRY COUNT
|
|
LD A,(HL) ; GET THE ENTRY COUNT
|
|
LD L,A ; PUT DRIVE COUNT
|
|
LD H,0 ; ... INTO HL
|
|
ADD HL,HL ; MULTIPLY
|
|
ADD HL,HL ; ... BY SIZE
|
|
ADD HL,HL ; ... OF DPH (16)
|
|
ADD HL,HL ; ... FOR TOTAL SIZE
|
|
CALL ALLOC ; ALLOCATE THE SPACE
|
|
CALL C,PANIC ; SHOULD NEVER ERROR
|
|
;
|
|
; SET DPHTOP TO START OF ALLOCATED SPACE
|
|
LD (DPHTOP),HL ; ... AND SAVE IN DPHTOP
|
|
;
|
|
; ALLOCATE DIRECTORY BUFFER
|
|
LD HL,128 ; SIZE OF DIRECTORY BUFFER
|
|
CALL ALLOC ; ALLOCATE THE SPACE
|
|
CALL C,PANIC ; SHOULD NEVER ERROR
|
|
LD (DIRBUF),HL ; ... AND SAVE IN DIRBUF
|
|
;
|
|
; SETUP FOR DPH BUILD LOOP
|
|
LD HL,(DRVMAPADR) ; POINT TO DRIVE MAP
|
|
DEC HL ; BACKUP TO ENTRY COUNT
|
|
LD B,(HL) ; LOOP DRVCNT TIMES
|
|
LD C,0 ; DRIVE INDEX
|
|
INC HL ; BUMP TO START OF DRIVE MAP
|
|
;
|
|
DPH_INIT1:
|
|
; DISPLAY DRIVE LETTER
|
|
LD A,C ; LOAD DRIVE INDEX
|
|
ADD A,'A' ; MAKE IT A DISPLAY LETTER
|
|
LD DE,STR_LDR ; LEADER STRING
|
|
CALL WRITESTR ; DISPLAY IT
|
|
CALL COUT ; DISPLAY DRIVE LETTER
|
|
CALL PC_COLON ; DISPLAY COLON
|
|
LD A,'=' ; SEPARATOR
|
|
CALL COUT ; DISPLAY IT
|
|
; SETUP FOR DPH BUILD ROUTINE INCLUDING DPH BLOCK ALLOCATION
|
|
LD D,(HL) ; D := UNIT
|
|
INC HL ; BUMP
|
|
LD E,(HL) ; E := SLICE
|
|
INC HL ; BUMP
|
|
CALL PRTDRV ; PRINT DRIVE INFO
|
|
LD A,D ; A := UNIT
|
|
PUSH HL ; SAVE DRIVE MAP POINTER
|
|
PUSH AF ; SAVE UNIT
|
|
; MATCH AND SAVE DEFAULT DRIVE BASED ON BOOT UNIT/SLICE
|
|
LD HL,BOOTVOL + 1 ; POINT TO BOOT UNIT
|
|
LD A,D ; LOAD CURRENT UNIT
|
|
CP (HL) ; MATCH?
|
|
JR NZ,DPH_INIT1A ; BYPASS IF NOT BOOT UNIT
|
|
DEC HL ; POINT TO BOOT SLICE
|
|
LD A,E ; LOAD CURRENT SLICE
|
|
CP (HL) ; MATCH?
|
|
JR NZ,DPH_INIT1A ; BYPASS IF NOT BOOT SLICE
|
|
LD A,C ; LOAD THE CURRENT DRIVE NUM
|
|
LD (DEFDRIVE),A ; SAVE AS DEFAULT
|
|
DPH_INIT1A:
|
|
POP AF ; RESTORE UNIT
|
|
LD DE,(DPHTOP) ; GET ADDRESS OF NEXT DPH
|
|
PUSH DE ; ... AND SAVE IT
|
|
; INVOKE THE DPH BUILD ROUTINE
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
CALL MAKDPH ; MAKE THE DPH AT DE, UNIT IN A
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
; STORE THE DPH POINTER IN DRIVE MAP
|
|
POP DE ; RESTORE DPH ADDRESS TO DE
|
|
POP HL ; RESTORE DRIVE MAP POINTER TO HL
|
|
JR Z,DPH_INIT2 ; IF MAKDPH OK, CONTINUE
|
|
LD DE,0 ; ... OTHERWISE ZERO OUT THE DPH POINTER
|
|
DPH_INIT2:
|
|
LD (HL),E ; SAVE DPH POINTER
|
|
INC HL ; ... IN
|
|
LD (HL),D ; ... DRIVE MAP
|
|
INC HL ; AND BUMP TO START OF NEXT ENTRY
|
|
; UPDATE DPH ALLOCATION TOP
|
|
LD A,16 ; SIZE OF A DPH ENTRY
|
|
EX DE,HL ; HL := DPH POINTER
|
|
CALL ADDHLA ; CALC NEW DPHTOP
|
|
LD (DPHTOP),HL ; SAVE IT
|
|
; HANDLE THE NEXT DRIVE MAP ENTRY
|
|
EX DE,HL ; HL := NEXT DRIVE MAP ENTRY
|
|
INC C ; NEXT DRIVE
|
|
DJNZ DPH_INIT1 ; LOOP AS NEEDED
|
|
RET ; DONE
|
|
;
|
|
MAKDPH:
|
|
;
|
|
; MAKE A DPH AT ADDRESS IN DE FOR UNIT IN A
|
|
;
|
|
PUSH DE ; SAVE INCOMING DPH ADDRESS
|
|
;
|
|
#IFDEF PLTUNA
|
|
;
|
|
LD B,A ; UNIT NUM TO B
|
|
LD C,$48 ; UNA FUNC: GET DISK TYPE
|
|
CALL $FFFD ; CALL UNA
|
|
LD A,D ; MOVE DISK TYPE TO A
|
|
;
|
|
; DERIVE DPB ADDRESS BASED ON DISK TYPE
|
|
CP $40 ; RAM/ROM DRIVE?
|
|
JR Z,MAKDPH0 ; HANDLE RAM/ROM DRIVE IF SO
|
|
; CP $?? ; FLOPPY DRIVE?
|
|
; JR Z,XXXXX ; HANDLE FLOPPY
|
|
LD DE,DPB_HD ; ASSUME HARD DISK
|
|
JR MAKDPH1 ; CONTINUE
|
|
;
|
|
MAKDPH0: ; HANDLE RAM/ROM
|
|
LD C,$45 ; UNA FUNC: GET DISK INFO
|
|
LD DE,INIBUF ; 512 BYTE BUFFER
|
|
CALL $FFFD ; CALL UNA
|
|
BIT 7,B ; TEST RAM DRIVE BIT
|
|
LD DE,DPB_ROM ; ASSUME ROM
|
|
JR Z,MAKDPH1 ; NOT SET, ROM DRIVE, CONTINUE
|
|
LD DE,DPB_RAM ; OTHERWISE, MUST BE RAM DRIVE
|
|
JR MAKDPH1 ; CONTINUE
|
|
;
|
|
#ELSE
|
|
;
|
|
; DETERMINE APPROPRIATE DPB (UNIT NUMBER IN A)
|
|
; GET DEVICE INFO
|
|
LD C,A ; UNIT NUMBER TO C
|
|
LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO
|
|
RST 08 ; CALL HBIOS, RET W/ DEVICE TYPE IN D, PHYSICAL UNIT IN E
|
|
LD A,D ; DEVICE TYPE TO A
|
|
CP DIODEV_MD ; RAM/ROM DISK?
|
|
JR Z,MAKDPH0 ; HANDLE SPECIAL
|
|
LD DE,DPB_FD144 ; PRELOAD FLOPPY DPB
|
|
CP DIODEV_FD ; FLOPPY?
|
|
JR Z,MAKDPH1 ; IF SO, PROCEED TO DPH CREATION
|
|
LD DE,DPB_RF ; PRELOAD RAM FLOPPY DPB
|
|
CP DIODEV_RF ; RAM FLOPPY?
|
|
JR Z,MAKDPH1 ; IF SO, PROCEED TO DPH CREATION
|
|
; EVERYTHING ELSE IS A HARD DISK
|
|
LD DE,DPB_HD ; PRELOAD HARD DISK DPB
|
|
JR MAKDPH1 ; PROCEED TO DPH CREATION
|
|
;
|
|
MAKDPH0:
|
|
; RAM/ROM DISK DPB DERIVATION
|
|
; TYPE OF MEMORY DISK (RAM/ROM) DETERMINED BY PHYSICAL UNIT NUMBER
|
|
LD A,E ; LOAD PHYSICAL UNIT NUMBER
|
|
LD DE,DPB_ROM ; PRELOAD ROM DISK DPB
|
|
OR A ; UNIT=0 (ROM)?
|
|
JR Z,MAKDPH1 ; IF UNIT=0, IT IS ROM, PROCEED TO DPH CREATION
|
|
LD DE,DPB_RAM ; PRELOAD RAM DISK DPB
|
|
CP $01 ; UNIT=1 (RAM)?
|
|
JR Z,MAKDPH1 ; IF UNIT=0, IT IS ROM, PROCEED TO DPH CREATION
|
|
CALL PANIC ; OTHERWISE UNKNOWN, NOT POSSIBLE, JUST PANIC
|
|
;
|
|
#ENDIF
|
|
;
|
|
MAKDPH1:
|
|
;
|
|
; BUILD THE DPH (DE POINTS TO DPB)
|
|
POP HL ; HL := START OF DPH
|
|
LD A,8 ; SIZE OF DPH RESERVED AREA
|
|
CALL ADDHLA ; LEAVE IT ALONE (ZERO FILLED)
|
|
|
|
LD BC,(DIRBUF) ; ADDRESS OF DIRBUF
|
|
LD (HL),C ; PLUG DIRBUF
|
|
INC HL ; ... INTO DPH
|
|
LD (HL),B ; ... AND BUMP
|
|
INC HL ; ... TO NEXT DPH ENTRY
|
|
|
|
LD (HL),E ; PLUG DPB ADDRESS
|
|
INC HL ; ... INTO DPH
|
|
LD (HL),D ; ... AND BUMP
|
|
INC HL ; ... TO NEXT ENTRY
|
|
DEC DE ; POINT
|
|
DEC DE ; ... TO START
|
|
DEC DE ; ... OF
|
|
DEC DE ; ... DPB
|
|
DEC DE ; ... PREFIX DATA (CKS & ALS BUF SIZES)
|
|
CALL MAKDPH2 ; HANDLE CKS BUF, THEN FALL THRU FOR ALS BUF
|
|
RET NZ ; BAIL OUT ON ERROR
|
|
; FALL THRU FOR ALS BUF
|
|
MAKDPH2:
|
|
PUSH HL ; SAVE DPH PTR
|
|
EX DE,HL ; USE HL AS DPB PTR, DE IS NOW SCRATCH
|
|
LD E,(HL) ; DE := CKS/ALS SIZE
|
|
INC HL ; ... AND BUMP
|
|
LD D,(HL) ; ... PAST
|
|
INC HL ; ... CKS/ALS SIZE
|
|
EX DE,HL ; DPB PTR BACK TO DE, ALLOC SIZE TO HL
|
|
LD A,H ; CHECK TO SEE
|
|
OR L ; ... IF HL (ALLOC SIZE) IS ZERO
|
|
CALL NZ,ALLOC ; ALLOC BC BYTES, ADDRESS RETURNED IN BC
|
|
PUSH HL ; MOVE ALLOC RESULT PTR
|
|
POP BC ; ... TO BC
|
|
POP HL ; RECOVER DPH PTR TO HL
|
|
;JR NZ,ERR_HEAPOVF ; HANDLE POSSIBLE ALLOC OVERFLOW HERE
|
|
JR C,ERR_HEAPOVF ; HANDLE POSSIBLE ALLOC OVERFLOW HERE
|
|
LD (HL),C ; SAVE CKS/ALS BUF
|
|
INC HL ; ... ADDRESS IN
|
|
LD (HL),B ; ... DPH AND BUMP
|
|
INC HL ; ... TO NEXT DPH ENTRY
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; ALLOCATE HL BYTES FROM HEAP
|
|
; RETURN POINTER TO ALLOCATED MEMORY IN HL
|
|
; ON OVERFLOW ERROR, C SET
|
|
;
|
|
ALLOC:
|
|
PUSH DE ; SAVE DE SO WE CAN USE IT FOR WORK REG
|
|
LD DE,(HEAPTOP) ; GET CURRENT HEAP TOP
|
|
PUSH DE ; AND SAVE FOR RETURN VALUE
|
|
ADD HL,DE ; ADD REQUESTED SPACE, HL := NEW HEAP TOP
|
|
JR C,ALLOCX ; TEST FOR CPU MEMORY SPACE OVERFLOW
|
|
;LD DE,(HEAPLIM) ; LOAD DE WITH HEAP LIMIT
|
|
LD DE,HEAPEND ; LOAD DE WITH HEAP LIMIT
|
|
EX DE,HL ; DE=NEW HEAPTOP, HL=HEAPLIM
|
|
SBC HL,DE ; HEAPLIM - HEAPTOP
|
|
JR C,ALLOCX ; C SET ON OVERFLOW ERROR
|
|
; ALLOCATION SUCCEEDED, COMMIT NEW HEAPTOP
|
|
LD (HEAPTOP),DE ; SAVE NEW HEAPTOP
|
|
ALLOCX:
|
|
POP HL ; RETURN VALUE TO HL
|
|
POP DE ; RECOVER DE
|
|
RET
|
|
;
|
|
ERR_HEAPOVF:
|
|
LD DE,STR_HEAPOVF
|
|
JR ERR
|
|
;
|
|
ERR_INVMED:
|
|
LD DE,STR_INVMED
|
|
JR ERR
|
|
;
|
|
ERR:
|
|
CALL WRITESTR
|
|
OR $FF
|
|
RET
|
|
;
|
|
PRTDRV:
|
|
;
|
|
; PRINT THE UNIT/SLICE INFO
|
|
; ON INPUT D HAS UNIT, E HAS SLICE
|
|
; DESTROY NO REGISTERS OTHER THAN A
|
|
;
|
|
#IFDEF PLTUNA
|
|
;
|
|
PUSH BC ; PRESERVE BC
|
|
PUSH DE ; PRESERVE DE
|
|
PUSH HL ; PRESERVE HL
|
|
|
|
LD B,D ; B := UNIT
|
|
LD C,$48 ; UNA FUNC: GET DISK TYPE
|
|
CALL $FFFD ; CALL UNA
|
|
LD A,D ; DISK TYPE TO A
|
|
|
|
CP $40
|
|
JR Z,PRTDRV1 ; IF SO, HANDLE RAM/ROM
|
|
|
|
LD DE,DEVIDE ; IDE STRING
|
|
CP $41 ; IDE?
|
|
JR Z,PRTDRVX ; IF YES, PRINT
|
|
LD DE,DEVPPIDE ; PPIDE STRING
|
|
CP $42 ; PPIDE?
|
|
JR Z,PRTDRVX ; IF YES, PRINT
|
|
LD DE,DEVSD ; SD STRING
|
|
CP $43 ; SD?
|
|
JR Z,PRTDRVX ; IF YES, PRINT
|
|
LD DE,DEVDSD ; DSD STRING
|
|
CP $44 ; DSD?
|
|
JR Z,PRTDRVX ; IF YES, PRINT
|
|
|
|
LD DE,DEVUNK ; OTHERWISE, UNKNOWN
|
|
JR PRTDRVX ; PRINT IT
|
|
|
|
PRTDRV1:
|
|
LD C,$45 ; UNA FUNC: GET DISK INFO
|
|
LD DE,INIBUF ; 512 BYTE BUFFER
|
|
CALL $FFFD ; CALL UNA
|
|
BIT 7,B ; TEST RAM DRIVE BIT
|
|
LD DE,DEVROM ; ASSUME ROM
|
|
JR Z,PRTDRVX ; IF SO, DISPLAY ROM
|
|
LD DE,DEVRAM ; ELSE RAM
|
|
JR Z,PRTDRVX ; DO IT
|
|
|
|
PRTDRVX:
|
|
CALL WRITESTR ; PRINT DEVICE NAME
|
|
POP HL ; RECOVER HL
|
|
POP DE ; RECOVER DE
|
|
POP BC ; RECOVER BC
|
|
LD A,D ; LOAD UNIT
|
|
CALL PRTDECB ; PRINT IT
|
|
CALL PC_COLON ; FORMATTING
|
|
LD A,E ; LOAD SLICE
|
|
CALL PRTDECB ; PRINT IT
|
|
RET
|
|
;
|
|
DEVRAM .DB "RAM$"
|
|
DEVROM .DB "ROM$"
|
|
DEVIDE .DB "IDE$"
|
|
DEVPPIDE .DB "PPIDE$"
|
|
DEVSD .DB "SD$"
|
|
DEVDSD .DB "DSD$"
|
|
DEVUNK .DB "UNK$"
|
|
;
|
|
#ELSE
|
|
;
|
|
PUSH BC ; PRESERVE BC
|
|
PUSH DE ; PRESERVE DE
|
|
PUSH HL ; PRESERVE HL
|
|
LD B,BF_DIODEVICE ; HBIOS FUNC: REPORT DEVICE INFO
|
|
LD C,D ; UNIT TO C
|
|
RST 08 ; CALL HBIOS
|
|
LD A,D ; RESULTANT DEVICE TYPE
|
|
PUSH DE ; NEED TO SAVE UNIT NUMBER (IN E)
|
|
RRCA ; ROTATE DEVICE
|
|
RRCA ; ... BITS
|
|
RRCA ; ... INTO
|
|
RRCA ; ... LOWEST 4 BITS
|
|
AND $0F ; ISOLATE DEVICE BITS
|
|
ADD A,A ; MULTIPLY BY TWO FOR WORD TABLE
|
|
LD HL,DEVTBL ; POINT TO START OF DEVICE NAME TABLE
|
|
CALL ADDHLA ; ADD A TO HL TO POINT TO TABLE ENTRY
|
|
LD A,(HL) ; DEREFERENCE HL TO LOC OF DEVICE NAME STRING
|
|
INC HL ; ...
|
|
LD D,(HL) ; ...
|
|
LD E,A ; ...
|
|
CALL WRITESTR ; PRINT THE DEVICE NMEMONIC
|
|
POP DE ; RECOVER UNIT (IN E)
|
|
LD A,E ; LOAD UNIT
|
|
AND $0F ; ISOLATE UNIT
|
|
CALL PRTDECB ; PRINT IT
|
|
POP HL ; RECOVER HL
|
|
POP DE ; RECOVER DE
|
|
POP BC ; RECOVER BC
|
|
CALL PC_COLON ; FORMATTING
|
|
LD A,E ; LOAD SLICE
|
|
CALL PRTDECB ; PRINT IT
|
|
RET
|
|
;
|
|
DEVTBL: ; DEVICE TABLE
|
|
.DW DEV00, DEV01, DEV02, DEV03
|
|
.DW DEV04, DEV05, DEV06, DEV07
|
|
.DW DEV08, DEV09, DEV10, DEV11
|
|
.DW DEV12, DEV13, DEV14, DEV15
|
|
;
|
|
DEVUNK .DB "???$"
|
|
DEV00 .DB "MD$"
|
|
DEV01 .DB "FD$"
|
|
DEV02 .DB "RAMF$"
|
|
DEV03 .DB "IDE$"
|
|
DEV04 .DB "ATAPI$"
|
|
DEV05 .DB "PPIDE$"
|
|
DEV06 .DB "SD$"
|
|
DEV07 .DB "PRPSD$"
|
|
DEV08 .DB "PPPSD$"
|
|
DEV09 .DB "HDSK$"
|
|
DEV10 .EQU DEVUNK
|
|
DEV11 .EQU DEVUNK
|
|
DEV12 .EQU DEVUNK
|
|
DEV13 .EQU DEVUNK
|
|
DEV14 .EQU DEVUNK
|
|
DEV15 .EQU DEVUNK
|
|
;
|
|
#ENDIF
|
|
;
|
|
DPHTOP .DW 0 ; CURRENT TOP OF DPH POOL
|
|
DIRBUF .DW 0 ; DIR BUF POINTER
|
|
HEAPTOP .DW BUFPOOL ; CURRENT TOP OF HEAP
|
|
BOOTVOL .DW 0 ; BOOT VOLUME, MSB=BOOT UNIT, LSB=BOOT SLICE
|
|
BNKRAMD .DB 0 ; STARTING BANK ID FOR RAM DRIVE
|
|
HDSPV .DB 2 ; SLICES PER VOLUME FOR HARD DISKS (MUST BE >= 1)
|
|
;
|
|
CMD .DB CMDLEN - 2
|
|
.TEXT "SUBMIT PROFILE"
|
|
.DB 0
|
|
CMDLEN .EQU $ - CMD
|
|
;
|
|
FCB_SUB .DB '?' ; DRIVE CODE, 0 = CURRENT DRIVE
|
|
.DB "SUBMIT " ; FILE NAME, 8 CHARS
|
|
.DB "COM" ; FILE TYPE, 3 CHARS
|
|
.FILL 36-($-FCB_SUB),0 ; ZERO FILL REMAINDER OF FCB
|
|
;
|
|
FCB_PRO .DB '?' ; DRIVE CODE, 0 = CURRENT DRIVE
|
|
.DB "PROFILE " ; FILE NAME, 8 CHARS
|
|
.DB "SUB" ; FILE TYPE, 3 CHARS
|
|
.FILL 36-($-FCB_PRO),0 ; ZERO FILL REMAINDER OF FCB
|
|
;
|
|
STR_BANNER .DB "CBIOS v", BIOSVER, " [", PLTSTR, "]$"
|
|
STR_INITRAMDISK .DB "Formatting RAMDISK...$"
|
|
STR_LDR2 .DB "\r\n"
|
|
STR_LDR .DB "\r\n $"
|
|
STR_DPHINIT .DB "Configuring Drives...$"
|
|
STR_HEAPOVF .DB " *** Insufficient Memory ***$"
|
|
STR_INVMED .DB " *** Invalid Device ID ***$"
|
|
STR_MEMFREE .DB " Disk Buffer Bytes Free$"
|
|
STR_CPM .DB "CP/M-80 v2.2$"
|
|
STR_ZSDOS .DB "ZSDOS v1.1$"
|
|
STR_TPA1 .DB ", $"
|
|
STR_TPA2 .DB "K TPA$"
|
|
|
|
#IFDEF PLTUNA
|
|
INIBUF .FILL 512,0 ; LOCATION OF TEMP WORK BUF DURING INIT (512 BYTES)
|
|
#ELSE
|
|
HCB .FILL HCB_SIZ,0 ; LOCATION OF TEMP COPY OF HCB DURING INIT (256 BYTES)
|
|
#ENDIF
|
|
;
|
|
;==================================================================================================
|
|
; END OF COLD BOOT INITIALIZATION
|
|
;==================================================================================================
|
|
;
|
|
.ORG BUFPOOL + ($ - $8000)
|
|
;
|
|
SLACK .EQU (CBIOS_END - $)
|
|
.ECHO "INIT code slack space: "
|
|
.ECHO SLACK
|
|
.ECHO " bytes.\n"
|
|
.FILL SLACK,$00
|
|
;
|
|
HEAPS .EQU (CBIOS_END - BUFPOOL)
|
|
.ECHO "HEAP space: "
|
|
.ECHO HEAPS
|
|
.ECHO " bytes.\n"
|
|
;
|
|
.ECHO "CBIOS total space used: "
|
|
.ECHO $ - CBIOS_LOC
|
|
.ECHO " bytes.\n"
|
|
;
|
|
; PAD OUT AREA RESERVED FOR HBIOS PROXY
|
|
.FILL MEMTOP - $
|
|
;
|
|
.END
|
|
|