|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 19968 (0x4e00)
Types: TextFile
Names: »BIOSKRNL.Z80«
└─⟦7303e23ba⟧ Bits:30003507 JET80 System diskette
└─⟦this⟧ »BIOSKRNL.Z80«
└─⟦a844860b7⟧ Bits:30002858 CP/M Plus (tm) Version 3.0 for JET80
└─⟦this⟧ »BIOSKRNL.Z80«
└─⟦c10cc8855⟧ Bits:30002859 CP/M Plus med Hit & Dit filoverførsel for JET80
└─⟦this⟧ »BIOSKRNL.Z80«
TITLE 'BIOSKRNL.Z80 ROOT TO BIOS. CP/M 3.0'
;****************************************************************
;* THE TOTAL SYSTEM CONSISTS OF: *
;* BIOSKRNL.Z80 ROOT *
;* BOOT.Z80 BOOT-MODULE *
;* CHARIO.Z80 CHARACTER-I/O-MODULE *
;* DRIVES.ASM DISK-DEFINITON-MODULE (WDRIVES/FDRIVES) *
;* EXTMEM.Z80 EXTERNEL MEMORY-MODULE *
;* SCB.REL SYSTEM VARIABLES *
;* IOS.Z80 PORT ADDRESSES *
;****************************************************************
; LATEST CHANGE: 1984-06-20. PSW.
; BIOSREVISION D.
.Z80
PAGE 42
; EXTERNAL VARIABELS
EXTRN @COVEC,@CIVEC,@AOVEC ; I/O REDIRECTION VECTORS
EXTRN @AIVEC,@LOVEC ; - " -
EXTRN @MXTPA ; MAX TPA IN USER BANK
EXTRN @BNKBF ; COMMON 128 BYTE BUFFER
; INIT
EXTRN ?PATCH,?INIT ;
EXTRN ?LDCCP,?RLCCP ; LOAD & RELOAD CCP
; USER DEFINED CHARACTER I/O ROUTINS
EXTRN ?CI,?CO,?CIST,?COST ;
EXTRN ?CINIT,INISTM ;
EXTRN @CTBL ;
; DISK
EXTRN @DTBL ; POINTER TABLE
ENTRY @ADRV,@RDRV,@TRK,@SECT ; DISKPARAMETERS
ENTRY @DMA,@DBNK,@CNT ; - " -
; MEMORY MODULE
ENTRY @CBNK,BNKMSK ; CURRENT BANK
ENTRY ?PMSG ; WRITES MESSAGES
; EXTERNAL LABLES TO BIOS-CALLS
ENTRY ?BOOT,?WBOOT,?CONST,?CONIN,?CONO,?LIST,?AUXO,?AUXI
ENTRY ?HOME,?SLDSK,?STTRK,?STSEC,?STDMA,?READ,?WRITE
ENTRY ?LISTS,?SCTRN
ENTRY ?CONOS,?AUXIS,?AUXOS,?DVTBL,?DEVIN,?DRTBL
ENTRY ?MLTIO,?FLUSH,?MOV,?TIM,?BNKSL,?STBNK,?XMOV
; EXTERNAL LABLE TO USERFUNCTION
EXTRN ?USERF
; INTERRUPT-VECTORS
ENTRY SIO1IV,SIO2IV,DMAIRV,CTCIRV,PIOIRV
ENTRY INTVECT
; INTERRUPT-DRIVEN ROUTINES
EXTRN KBDIRQ,CLKIRQ,PIOGAI,PIOGBI,UNKINT
PAGE
TRUE EQU -1
FALSE EQU NOT TRUE
BIOSRV EQU 8426H ; BIOS-REVISION.
BOTFLG EQU 0C000H ; BOOT-FLAGG
DMA EQU 18H ; DMA.
; DMA-COMMANDS
DMRSET EQU 0C3H ; SOFTWARE RESET
DMENAB EQU 087H ; ENABLE DMA
DMDISA EQU 083H ; DISABLE DMA
BNKMUX EQU 1BH ; BANK-DMA-MULTIPLEXER
DMBK11 EQU 00000000B ; BANK1 --> BANK1
DMBK00 EQU 00001000B ; BANK0 --> BANK0
DMBK10 EQU 00010000B ; BANK1 --> BANK0
DMBK01 EQU 00011000B ; BANK0 --> BANK1
BANK1 EQU 00000000B ; BANK1 (64K FOR CPU)
BANK0 EQU 00100000B ; BANK0 (48K FOR CPU)
CR EQU 13
LF EQU 10
BELL EQU 7
CTLQ EQU 'Q'-'@'
CTLS EQU 'S'-'@'
MB$XONXOFF EQU 00010000B ; XON/XOFF PROTOCOLL ON.
JPOP EQU 0C3H ; Z80 JUMP INSTRUCTION
CCP EQU 100H ; LOAD ADDRESS FOR CCP
PAGE
CSEG
;**********************************************************
;* BIOS: JUMP VECTORS *
;**********************************************************
?BOOT: JP BOOT ;
?WBOOT: JP WBOOT ;
?CONST: JP CONST ;
?CONIN: JP CONIN ;
?CONO: JP CONOUT ;
?LIST: JP LIST ;
?AUXO: JP AUXOUT ;
?AUXI: JP AUXIN ;
?HOME: JP HOME ;
?SLDSK: JP SELDSK ;
?STTRK: JP SETTRK ;
?STSEC: JP SETSEC ;
?STDMA: JP SETDMA ;
?READ: JP READ ;
?WRITE: JP WRITE ;
?LISTS: JP LISTST ;
?SCTRN: JP SECTRN ;
?CONOS: JP CONOST ;
?AUXIS: JP AUXIST ;
?AUXOS: JP AUXOST ;
?DVTBL: JP DEVTBL ;
?DEVIN: JP ?CINIT ; IN CHARIO.Z80
?DRTBL: JP GETDRV ;
?MLTIO: JP MULTIO ;
?FLUSH: JP FLUSH ;
?MOV: JP ?MOVE ;
?TIM: JP RETURN ; NOT INSTALLED
?BNKSL: JP BNKSEL ;
?STBNK: JP SETBNK ;
?XMOV: JP ?XMOVE ;
JP ?USERF ; IN EXTMEM.Z80
JP RETURN ;
JP RETURN ;
NOP ; GIVE CORRECT START FOR INT.VECTORS.
PAGE
;**********************************************************
;* INTERRUPT VECTORS *
;**********************************************************
INTVECT EQU $ ; INTERRUPT VECTOR ADDRESS
PIOIRV EQU $ ; PIO BASE INTERRUPT VECTOR
DEFW PIOGAI ; GRAPHIC SCREEN READY
DEFW PIOGBI ; GRAPHIC KEY BOARD
CTCIRV EQU $ ; CTC BASE INTERRUPT VEKTOR
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW CLKIRQ ; (10 Hz TICK)
SIO1IV EQU $ ; SIO1 BASE INTERRUPT VECTOR
DEFW KBDIRQ ; KEYBOARD INT.
DEFW KBDIRQ ;
DEFW KBDIRQ ;
DEFW KBDIRQ ;
DEFW KBDIRQ ;
DEFW KBDIRQ ;
DEFW KBDIRQ ;
DEFW KBDIRQ ;
SIO2IV EQU $ ; SIO2 BASE INTERRUPT VECTOR
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DMAIRV EQU $ ; DMA BASE INTERRUPT VECTOR
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
PAGE
; BOOT
DSEG ;; CODE IN BANK0
BOOT: DI ;;
LD SP,BOOT$STACK
CALL ?PATCH ;; PATCH IO-PART FROM LOADER.
LD C,0 ;; INIT ALL 16 CHARACTER DEVICES
C$INIT$LOOP:
PUSH BC
CALL ?CINIT ;; INIT CHARACTER DEV.
POP BC
INC C
LD A,C
CP 16
JR NZ,C$INIT$LOOP
CALL ?INIT ;; INIT THE OTHERS
LD A,(BOTFLG) ;; SHALL A: BE WINCHESTER ?
AND A
JR Z,GOON ;; NO...JUMP.
LD HL,(@DTBL+4) ;; GET C:
LD DE,(@DTBL+2) ;; B:
LD BC,(@DTBL) ;; A:
LD (@DTBL),DE ;; B: --> A:
LD (@DTBL+2),HL ;; C: --> B:
LD (@DTBL+4),BC ;; A: --> C:
; GO ON INIT 16 DISK UNITS.
GOON: LD BC,16*256+0 ;; B=NUMBERS. C= LOG. DRIVE
LD HL,@DTBL ;; DRIVE-TABLE
D$IN$LOOP:
PUSH BC ;; SAVE NO. & DRIVE
LD E,(HL)
INC HL
LD D,(HL) ;; DE=ADDRESS TO DPH
INC HL
LD A,E ;; DOES DRIVE EXIST?
OR D
JR Z,D$IN$NEXT ;; NO...JUMP.
PUSH HL ;; SAVE HL
EX DE,HL
DEC HL
DEC HL
LD A,(HL) ;; A=CONTROLLER RELATIVE ADDRESS
LD (@RDRV),A
LD A,C ;; LOGICAL ADDRESS.
LD (@ADRV),A
DEC HL
LD D,(HL)
DEC HL
LD E,(HL) ;; DE=INIT ADDRESS
EX DE,HL ;;
CALL IPCHL ;; JUMP TO INIT.
POP HL ;; HL=DPH POINTER
D$IN$NEXT:
POP BC ;; B=NUMBERS. C=DRIVE
INC C ;; NEXT DRIVE #
DJNZ D$IN$LOOP ;; NEXT DPH-POINTER.
JP BOOT$1
CSEG ; BANK 1.
BOOT$1:
CALL SET$JUMPS ; SET JUMPVECTORS
CALL ?LDCCP ; READ CCP.COM FROM DISK
JP CCP ;
; WBOOT
WBOOT:
LD SP,BOOT$STACK
CALL SET$JUMPS ; INIT PAGE ZERO
CALL ?RLCCP ; REREAD CCP.COM
JP CCP ;
SET$JUMPS:
LD A,1 ; SELECT BANK 1
CALL ?BNKSL
LD A,JPOP ; Z80 JP OPCODE
LD HL,?WBOOT ; WARM BOOT ENTRY POINT
LD (0),A ; BIOS WARM START ENTRY
LD (1),HL
LD HL,(@MXTPA) ; BDOS ENTRY POINT
LD (5),A
LD (6),HL
RETURN: RET ;
DS 64
BOOT$STACK EQU $
; DEVTBL -- RETURNS THE ADDRESS TO CHARACTER DEVICE TABLE
DEVTBL: LD HL,@CTBL
RET
; GETDRV -- RETURNS THE ADDRESS TO DRIVE TABLE
GETDRV: LD HL,@DTBL
RET
PAGE
;**********************************************************
;* CHARACTER I/O- ROUTINES *
;**********************************************************
; CONOUT -- CONSOLE OUTPUT. SENDS CHAR IN (C) TO ALL
; CHOOSEN DEVICES.
CONOUT: LD HL,(@COVEC) ; GET CONSOLE OUTPUT BIT VECTOR
JR OUT$SCAN
; AUXOUT -- AUXILLIARY OUTPUT. SENS CHAR IN (C) TO ALL
; CHOOSEN DEVICES.
AUXOUT: LD HL,(@AOVEC) ; GET AUX OUTPUT BIT VECTOR
JR OUT$SCAN
; LIST -- LIST OUTPUT. SENDS CHAR IN (C) TO ALL
; CHOOSEN DEVICES.
LIST: LD HL,(@LOVEC) ; GET LIST OUTPUT BIT VECTOR
; AND DO OUT$SCAN
OUT$SCAN:
LD B,0 ; START WITH DEVICE 0.
CO$NEXT:
ADD HL,HL ; SHIFT NEXT BIT BIT
JR NC,NO$OUT$DEV ; JUMP IF NO CARRY
PUSH HL ; SAVE THE VECTOR AND
PUSH BC ; COUNTER AND CHAR.
CO$OUT$RDY:
CALL COSTER
OR A ; READY ?
JR Z,CO$OUT$RDY ; NO...JUMP
POP BC ; B=COUNTER C=CHAR
PUSH BC ; SAVE
CALL ?CO ; SEND CHAR IF DEVICE IS CHOOSEN
POP BC ; B=COUNTER C=CHAR
POP HL ; BIT VECTOR
NO$OUT$DEV:
INC B ; NEXT DEVICE #
LD A,H ; TEST IF ANY DEVICES LEFT
OR L
JR NZ,CO$NEXT ; YES...JUMP
RET
; CONOST -- CONSOLE OUTPUT STATUS. RETURNS TRUE IF ALL
; CHOOSEN CONSOLE OUTPUT DEVICES ARE READY.
CONOST: LD HL,(@COVEC) ; GET CONSOLE OUTPUT BIT VECTOR
JR OST$SCAN
; AUXOST -- AUXILIARY OUTPUT STATUS. RETURNS TRUE IF ALL
; CHOOSEN AUX OUTPUT DEVICES ARE READY.
AUXOST: LD HL,(@AOVEC) ; GET AUX OUTPUT BIT VECTOR
JR OST$SCAN
; LISTST -- LIST OUTPUT STATUS. RETURNS TRUE IF ALL
; CHOOSEN LIST OUTPUT DEVICES ARE READY.
LISTST: LD HL,(@LOVEC) ; GET LIST OUTPUT BIT VECTOR.
OST$SCAN:
LD B,0 ; START WITH DEVICE 0
COS$NEXT:
ADD HL,HL ; SHIFT OUT NEXT BIT
PUSH HL ; SAVE THE VECTOR
PUSH BC ; B=COUNTER C=CHAR
LD A,-1 ; SET DEVICE READY
CALL C,COSTER ; GET STATUS IF DEVICE CHOOSEN
POP BC ; B=COUNTER C=CHAR
POP HL ; HL=VECTOR
OR A ; TEST IF DEVICE READY.
RET Z ; IF ALL NOT READY, RETURN FALSE.
INC B ; NEXT DEVICE
LD A,H ; CHECK IF MORE CHOOSEN DEVICES
OR L
JR NZ,COS$NEXT ; YES...JUMP
OR 0FFH ; ALL CHOOSEN DEVICES READY
RET ; RETURN TRUE
; CHECK IF OUTPUT DEVICE READY (XON/XOFF SUPPORT).
COSTER: LD L,B ; CHANGE DEVICE # TO 16 BITS
LD H,0 ; HL=DEV#
PUSH HL ;
ADD HL,HL ; OFFSET IN DEVICE-TABLE
ADD HL,HL
ADD HL,HL ; HL=HL*8
LD DE,@CTBL+6 ; DE= MODE BYTE FØR DEV 0
ADD HL,DE ; HL=RÆTT MODE BYTE
LD A,(HL) ; GET MODE BYTE
AND MB$XONXOFF ; XON/XOFF PROTOCOLL?
POP HL ; HL=DEVICE #
JP Z,?COST ; NO XON/XOFF...JUMP
LD DE,XOFFLIST
ADD HL,DE ; HL=PLACE IN XOFFLIST
LD C,0 ; FLAGSTATUS FOR ^C, ^S, ^Q ONLY
CALL CISTL
LD A,(HL)
CALL NZ,CIL
CP CTLQ
JR NZ,NOT$Q
LD A,-1 ; SET READY-FLAG
NOT$Q: CP CTLS ; CTL-S?
JR NZ,NOT$S ; NO...JUMP
LD A,0 ; CLEAR FLAG
NOT$S: LD (HL),A ; SAVE FLAG
CALL COST1 ; GET OUTPUT STATUS
AND (HL) ; AND MASK WITH XON/XOFF FLAG
RET ; AND RETURN IT AS STATUS
CISTL: PUSH BC ; GET INPUT STATUS WITH (BC) & (HL)
PUSH HL
CALL ?CIST
POP HL
POP BC
OR A
RET
COST1: PUSH BC ; GET OUTPUT STATUS, SAVE (BC) & (HL)
PUSH HL
CALL ?COST
POP HL
POP BC
OR A
RET
CIL: PUSH BC ; GET INPUT AND SAVE (BC) & (HL)
PUSH HL
CALL ?CI
POP HL
POP BC
RET
; CONST -- CONSOLE INPUT STATUS. RETURNS TRUE IF ANY CHOOSEN
; CONSOLE INPUT DEVICE HAS A CHAR AVAILABLE.
CONST: LD HL,(@CIVEC) ; GET CONSOLE INPUT BIT VECTOR
JR IST$SCAN
; AUXIST -- AUXILIARY INPUT STATUS. RETURNS TRUE IF ANY CHOOSEN
; AUX INPUT DEVICE HAS A CHAR AVAILABLE.
AUXIST: LD HL,(@AIVEC) ; GET AUX INPUT BIT VECTOR
IST$SCAN:
LD BC,0 ; START WITH DEVICE 0
; CREG = 0 = FLAG, STATUS CALL ONLY
CIS$NEXT:
XOR A ; SET DEVICE NOT READY
ADD HL,HL ; SHIFT OUT ONE BIT
CALL C,CISTL ; CHECK STATUS ON THIS DEVICE
OR A ; IF ANY READY RETURN TRUE.
RET NZ
INC B ; NEXT DEVICE #
LD A,H ; CHECK IF ANY MORE DEV.
OR L
JR NZ,CIS$NEXT
XOR A ; ALL CHOOSEN NOT READY. FALSE
RET
; CONIN -- CONSOLE INPUT. RETURNS CHAR FROM FIRST READY
; CONSOLE DEVICE.
CONIN: LD HL,(@CIVEC) ; GET CONSOLE BIT VECTOR
JR IN$SCAN
; AUXIN -- AUXILIARY INPUT. RETURNS CHAR FROM FIRST READY
; AUX INPUT DEVICE.
AUXIN: LD HL,(@AIVEC) ; GET AUX BIT VECTOR
IN$SCAN:
PUSH HL ; SAVE BIT VECTOR
LD B,0 ; START WITH DEVICE 0
LD C,-1 ; CREG = FF = STATUS CALL FOR INPUT
CI$NEXT:
XOR A ; SET NO CHAR
ADD HL,HL ; SHIFT OUT ONE BIT
CALL C,CISTL ; CHECK IF DEVICE HAS A CHAR
OR A ; CHAR?
JR NZ,CI$RDY ; YES...JUMP
INC B ; TEST NEXT DEVICE
LD A,H
OR L
JR NZ,CI$NEXT ;
POP HL ; HL=BIT VECTOR
JR IN$SCAN ; LOOP UNTIL GOT A CHAR
CI$RDY: POP HL ; HL=BIT VECTOR
JP ?CI ; GET INPUT FROM DEVICE # IN B.
PAGE
;**********************************************************
;* SUBROUTINES *
;**********************************************************
IPCHL: JP (HL) ; VECTOR-CALL
?PMSG: ; WRITES MESSAGE @(HL) DETERM.
; WITH DEFB 0.
LD A,(HL) ; GET NEXT BYTE
OR A ; IS IT 0 ?
RET Z ; YES...RETURN
PUSH HL ; SAVE REGISTERS
PUSH DE
PUSH BC
LD C,A ; CHAR IN (C)
CALL ?CONO ; WRITE
POP BC
POP DE
POP HL
INC HL ; HL-->NEXT BYTE
JR ?PMSG ; START OVER AGAIN
; ?MOVE -- BLOCKMOVE MEMORY --> MEMORY
; IN: HL = TO ADDRESS
; DE = FROM ADDRES
; BC = COUNTER.
; OUT: HL & DE POINTING TO THE NEXT BYTES
; THAT FOLLOWS THE MOVE.
?MOVE: LD A,B ; IS IT ZERO-MOVE?
OR C
RET Z ; YES...QUIT
LD A,(BNKFLG) ; IS ?XMOVE INVOLVED?
AND A
JR NZ,MOVE1 ; YES...JUMP
EX DE,HL ; EXCHANGE ADDRESSES TO FIT
LDIR ; THIS INSTRUCTION.
EX DE,HL ; GET THEM BACK.
RET
MOVE1: XOR A ; ZERO ?XMOVE-FLAG
LD (BNKFLG),A
LD (SRCADR),DE ; SET SOURCE-ADDRESS IN DMA-TABLE
LD (DSTADR),HL ; SET DEST-ADDRESS IN DMA-TABLE
ADD HL,BC ; HL= END-DEST-ADDRESS.
PUSH HL ; SAVED.
EX DE,HL ;
ADD HL,BC ; HL= END-SOURCE-ADDRESS
PUSH HL ; SAVED.
DEC BC ; REDUCE BLOCK LENGTH WITH 1
LD (LENGTH),BC ; CHECK FOR THE DMA COMMAND
LD A,B
OR C
LD A,11001101B ; IF NOT ONE BYTE SET BURST MODE
JR NZ,MOVE2
LD A,10001101B ; ELSE SET BYTE MODE.
MOVE2: LD (MODE),A ; SAVE THE MODE
LD HL,(DSTBNK) ;
LD A,H ; DEST-BANK IN A.
RLA ; SHIFT OUT LEFT
OR L ; ADD ON SOURCE-BANK.
AND 00000011B ; MASK ANY FAULTS.
LD L,A ;
LD H,0 ; PUT THE CODE I HL
LD DE,BNKTBL ; OFFSET IN THE TABLE
ADD HL,DE ; POINT TO THE RIGHT BYTE
LD A,(HL) ; GET IT.
LD HL,BNKMSK ; ADD ON BANKMASK
OR (HL)
LD HL,DMATBL ; POINT TO THE DMA-TABLE.
DI ; SHUT UP FOR A MOMENT.
OUT (BNKMUX),A ; START THE DMA
CALL INISTM
LD A,B ;
OR C
JR Z,MOVE4
MOVE3: IN A,(DMA) ; READ STATUS
AND 00100000B ; IS IT READY?
JR NZ,MOVE3
MOVE4: LD A,DMDISA ; DISABLE DMA
OUT (DMA),A
EI ; SPEAK AGAIN
POP DE ; GET THE PARAMETERS BACK
POP HL
LD BC,0 ; COUNTER=0
RET
; ?XMOVE -- SETS CORRECT BANKS FOR DATA TRANSFERES.
; IN: B = TO-BANK
; C = FROM-BANK
; OUT: NONE.
;
?XMOVE:
LD A,TRUE
LD (BNKFLG),A ; MARK ?XMOVE
LD (DSTBNK),BC ; GIVES (C) IN TO-BANK
; AND (B) IN FROM-BANK.
RET
; BNKSEL -- BANKSELECT.
; IN: A = MEMORY BANK.
;
BNKSEL: LD (@CBNK),A ; SAVE CURRENT BANK
AND 1 ; MASK
PUSH HL ; SAVE
LD HL,BNKMSK ;
LD A,BANK0 ; START WITH BANK 0.
JR Z,BNK1 ; BANK0 ? YES...JUMP
LD A,BANK1 ; SET BANK 1.
BNK1: DI ; NOTHING CRAZY MAY HAPPEN NOW
LD (HL),A
OUT (BNKMUX),A ; SEND TO BANK SELECT PORT
POP HL
EI ; IT WORKED.
RET
PAGE
DSEG ;; BANK 0.
;***********************************************************
;* DISK-DRIVE-ROUTINES *
;***********************************************************
; SELDSK -- SELECT DISK DRIVE. DOES THE LOGIN-PROCEDURE FOR
; THE DRIVE IF IT IS THE FIRST TIME SELECT.
; IN: C = SELECTED DRIVE.
; E = BIT0 IS 0 IF NOT SELECTED BEFORE
; OUT: HL = 0 IF SELECTED DRIVE DOES NOT EXIST
; HL = @DPH IF SELECTED DRIVE EXISTS
SELDSK: LD A,C
LD (@ADRV),A ;; SAVE #
LD L,C ;; CREATE INDEX
LD H,0
ADD HL,HL ;; HL=2*DRIVE #TO OFFSET
LD BC,@DTBL ;; POINT TO DRIVE-TABLE-HEAD
ADD HL,BC ;; HL=CORRECT VECTOR IN @DTBL
LD A,(HL) ;; GET DPH-POINTER
INC HL
LD H,(HL)
LD L,A ;; HL=DPH-POINTER
OR H ;; SET Z-FLAG AND
RET Z ;; RETURN IF NO DRIVE
LD A,E
AND 1 ;; FIRST SELECT?
RET NZ ;; NO...RETURN
PUSH HL ;; SAVE DPH-POINTER
EX DE,HL
LD HL,-2 ;; GET (DPH-2)
ADD HL,DE
LD A,(HL)
LD (@RDRV),A ;; SAVE THE CONTROLLER RELATIVE DRIVE#
LD HL,-6 ;; GET THE LOGIN-VECTOR
ADD HL,DE
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
CALL IPCHL ;; DO LOGIN
POP HL ;; HL=DPH-POINTER
RET
PAGE
; HOME -- HOME SELECTED DRIVE. DO SETTRK (0).
HOME: LD BC,0 ;; TRACK=0
; SETTRK -- SET TRACK ADDRESS.
; IN: BC = TRACK ADDRESS
; OUT: @TRK = TRACK ADDRESS
SETTRK: LD (@TRK),BC ;; SAVE TRACK ADDRESS
RET
; SETSEC -- SET SECTOR ADDRESS.
; IN: BC = SECTOR ADDRESS
; OUT: @SECT = SECTOR ADDRESS
SETSEC: LD (@SECT),BC ;; SAVE SECTOR ADDRESS
RET
; SETDMA -- SET DIRECT MEMORY ACCESS DISK ADDRESS.
; IN: BD = DMA ADDRESS
; OUT: @DMA = DMA ADDRESS
; @DBNK = @CBNK
SETDMA: LD (@DMA),BC ;; SET GLOBAL DMA ADDRESS
LD A,(@CBNK) ;; DEFAULT DMA BANK IS CURRENT BANK
;; GET CURRENT BANK & DO SETBNK
; SETBNK -- SET DISK I/O MEMORY BANK.
; IN: A = DISK BANK #
; OUT: @DBNK = DISK BANK #
SETBNK:
LD (@DBNK),A ;; SET DISK DMA BANK
RET
; SECTRN -- SECTOR TRANSLATE. TRANSLATE LOGICAL SECTOR NUMBER TO
; PHYSICAL SECTOR NUMBER.
; IN: BC = LOGICAL SECTOR #
; DE = POINTING TO TRANS TABLE
; (0 IF NONE)
; OUT: HL = PHYSICAL SECTOR #.
SECTRN: LD L,C ;;
LD H,B ;; HL=CP/M SECTOR # (RELATIVE 0)
INC HL ;; HL= -"- (RELATIVE 1)
LD A,D ;; IS DE=0
OR E
RET Z ;; YES...RETURN, NO TRANS TABLE
DEC HL ;; HL= CP/M SECTOR # (RELATIVE 0)
ADD HL,DE ;; HL=INDEX IN TRANS TABLE
LD L,(HL) ;; TRANSLATE TO SECTOR # FROM TABLE
LD H,0 ;; 8 BITS VALUE
RET
; READ -- READS PHYSICAL SECTOR FROM SELECTED DISK.
; IN: NONE
; OUT: A = 0 NO ERROR.
; A = 1 IF ERROR.
; A = 0FFH IF MEDIA CHANGE.
READ: LD DE,-8 ;; INDEX OFFSET TO READ-ROUTINE
PUSH DE ;; ON THE STACK
JR RW$COMMON ;; READ-WRITE-GEMENSAM.
; WRITE -- WRITES PHYSICAL SECTOR ON SELECTED DISK.
; IN: C = DEBLOCKING-CODE
; OUT: A = 0 NO ERRORS.
; A = 1 PHYSICAL ERROR.
; A = 2 DISK READ-ONLY
; A = 0FFH IF MEDIA CHANGE.
WRITE: LD DE,-10 ;; INDEX OFFSET TO WRITE-ROUTINE
PUSH DE ;; ON THE STACK
RW$COMMON:
LD HL,(@ADRV) ;; GET DRIVE #
LD H,0
ADD HL,HL ;; HL=2*DRIVE#
LD DE,@DTBL
ADD HL,DE
LD A,(HL)
INC HL
LD H,(HL)
LD L,A ;; HL=DPH
POP DE ;; DE=READ/WRITE
PUSH HL ;; SAVE DPH-ADDRESS
ADD HL,DE ;; HL=READ/WRITE IN DPH
LD A,(HL)
INC HL
LD H,(HL)
LD L,A ;; HL=READ/WRITE-VECTOR
POP DE ;; DE=DPH
DEC DE
DEC DE
LD A,(DE)
LD (@RDRV),A ;; A=CONTROLLER RELATIVE DRIVE#
INC DE ;; BACK TO DPH
INC DE
JP (HL) ;; DO THE ROUTINE IN EXTMEM.Z80
; MULTIO -- SET MULTIPLE SECTOR COUNT.
; IN: A = SECTOR COUNT.
; OUT: @CNT = MULTIPLE SECTOR COUNT
MULTIO: LD (@CNT),A ;; SAVE THE COUNTER.
RET
; FLUSH --
; NOT INSTALLED.
FLUSH: XOR A ;; RETURN NO ERRORS.
RET
PAGE
;********************************************************
;* VARIABLES *
;********************************************************
CSEG ; MUST BE IN BANK1
@ADRV: DEFS 1 ; SELECTED DISK DRIVE #
@RDRV: DEFS 1 ; CONTROLLER RELATIVE DISK DRIVE#
@TRK: DEFS 2 ; TRACK #
@SECT: DEFS 2 ; SECTOR #
@DMA: DEFS 2 ; DMA ADDRESS
@CNT: DEFB 0 ; RECORD COUNT FOR MULTISECTOR I/O
@DBNK: DEFB 0 ; BANK FOR DMA OPERATIONS
@CBNK: DEFB 0 ; BANK FOR PROCESSOR OPERATIONS
BNKMSK: DEFB BANK0 ; MASK FOR PROC-/DMA-OPERATIONS.
BNKFLG: DEFB 0 ; FLAG FOR ?XMOV
DSTBNK: DEFS 1 ; DEST-BANK FOR ?XMOVE-?MOVE
SRCBNK: DEFS 1 ; SOURCE-BANK FOR ?XMOVE-?MOVE
BNKTBL: DEFB DMBK00 ; BANK0 --> BANK0
DEFB DMBK10 ; BANK1 --> BANK0
DEFB DMBK01 ; BANK0 --> BANK1
DEFB DMBK11 ; BANK1 --> BANK1
DMATBL: DEFB 17,DMA ; 17 BYTES TO DMA
DEFB DMDISA ; DISABLE DMA
DEFB 01111101B ; CR1A: BLOCKLENGTH LOW o. HI FOLLOWS,
; PORT A START ADDRESS LOW o. HI
; FOLLOWS A->B, TRANSFER.
SRCADR: DEFS 2 ; SORCE-ADDRESS (PORT A)
LENGTH: DEFS 2 ; BLOCKLENGTH - 1.
DEFB 00010100B ; CR1B: PORT ADDR. INC. PORT A-MEMORY.
DEFB 00010000B ; CR1B: PORT ADDR. INC. PORT B-MEMORY
MODE: DEFS 1 ; CR2B: BURST/BYTE-MODE
DSTADR: DEFS 2 ; DEST-ADDRESS (PORT B)
DEFB 10000010B ; CR2A: STOP END-OF-BLOCK
DEFB 11001111B ; CR2D: LOAD STARTADRESSES FOR BOTH
; PORTS AND ZERO THE COUNTER.
DEFB 10001011B ; CR2D: ZERO STATUS-BITS
DEFB 10110011B ; CR2D: FORCE READY.
DEFB DMENAB ; ENABLE DMA
DEFB 10111111B ; CR2D: SET NEXT READ STATUS.
DEFB 0 ; TABLE END.
XOFFLIST: DEFB -1,-1,-1,-1,-1,-1,-1,-1
DEFB -1,-1,-1,-1,-1,-1,-1,-1
END
«eof»