|
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 - 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»