|
DataMuseum.dkPresents historical artifacts from the history of: Jet Computer Jet80 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Jet Computer Jet80 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 29056 (0x7180) Types: TextFile Names: »BIOSKRNL.Z80«
└─⟦21f5a1bd4⟧ Bits:30003500 CP/M Plus (tm) Version 3.0 BIOS Revision F └─ ⟦this⟧ »BIOSKRNL.Z80« └─⟦67f37b9ce⟧ Bits:30003503 JET80/W20FT systemdisk └─ ⟦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 defintion module ; ; Fdrives.Asm for floppy systems ; ; Wdrives.Asm for winchester systems ; ; Extmem.Rel External memory module ; ; ExtmemF.Rel for floppy systems ; ; ExtmemA.Rel for winchester Adaptec ; ; ExtmemX.Rel for winchester Xebec ; ; Cntrlr.Rel Controller commands for Adaptec ; ; Scb.Asm System variables ; ;------------------------------------------------------------; ; Latest update: 1985-11-15. PSW ; Bios revision: F .Z80 True Equ -1 False Equ Not True BotFlg Equ 0C000h ; Boot flag address NetWork Equ False WrkStn Equ False Page 66 ; External variables: Extrn @CoVec,@CiVec,@AoVec ; I/O REDIRECTION VECTORS Extrn @AiVec,@LoVec ; - " - Extrn @MxTpa ; MAX TPA IN USER BANK Extrn @BnkBf ; COMMON 128 BYTE BUFFER Extrn Bank0Call ; Init Extrn ?Patch,?Init ; Extrn ?LdCcp,?RlCcp ; LOAD & RELOAD CCP ; User defined character I/O routines: 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,MuxByte ; CURRENT BANK Entry DmaFlg Entry ?PMsg ; WRITES MESSAGES ; Global 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 ; Global lable to userfunction: Extrn ?UserF ; Interrupt vectors: Entry Sio1Iv,CtcIrv Entry PioIrv Entry IntVect ; Interrupt driven routines: Extrn KbdIrq,UnkInt,LptIrq,ClkIrq If Not WrkStn Extrn PioGaI,PioGbI Endif Extrn KbdErRq,LptErRq,SetLptBuff Page ; Port address: ; Dma-COMMANDS DmRSet Equ 0C3h ; SOFTWARE RESET DmEnab Equ 087h ; ENABLE Dma DmDisa Equ 083h ; DISABLE Dma If Not WrkStn Dma Equ 18h ; 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) Else Dma Equ 0F0h ; Dma BnkMux Equ 0F4h ; Bank-Dma-MULTIPLEXER DmBk11 Equ 00000100b ; Bank1 --> Bank1 DmBk00 Equ 00000000b ; Bank0 --> Bank0 DmBk10 Equ 00000110b ; Bank1 --> Bank0 DmBk01 Equ 00000010b ; Bank0 --> Bank1 Bank1 Equ 00100000b ; Bank1 (64K FOR CPU) Bank0 Equ 00100001b ; Bank0 (48K FOR CPU) Endif CtlQ Equ 'Q'-'@' CtlS Equ 'S'-'@' MbXonXoff 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 If Not WrkStn Dw PioGaI ; GRAPHIC SCREEN READY Dw PioGbI ; GRAPHIC KEY BOARD Else Dw UnkInt ; Dw UnkInt ; Endif CtcIrv Equ $ ; CTC BASE INTERRUPT VEKTOR Dw UnkInt ; Dw UnkInt ; Dw UnkInt ; Dw ClkIrq ; (10 Hz TICK) Sio1Iv Equ $ ; SIO1 BASE INTERRUPT VECTOR Dw KbdIrq ; KEYBOARD INT. Dw KbdIrq ; Dw KbdIrq ; Dw KbdErRq ; Dw LptIrq ; Dw LptIrq ; Dw LptIrq ; Dw LptErRq ; Db 'This area is used as stack by CCP but You ' Db 'can use it for interrupt vectors when' Db ' CCP not in ram ' Boot$Stack Equ $ Page ;------------------------------------------------------------; ; Boot -- Cold start init. routunes. ; ;------------------------------------------------------------; Dseg ;; Code in Bank0. Boot: Di ;; Ld Sp,Boot$Stack ;; Call ?Patch ;; Patch loader parameters Ld Bc,16*256+0 ;; B=Counter, C=Dev#. C_Init_Loop: ;; Push Bc ;; Call ?CInit ;; Init char. dev. Pop Bc ;; Inc C ;; Djnz C_Init_Loop ;; Call ?Init ;; Init the rest. If Not NetWork Ld A,(BotFlg) ;; Winchester boot? 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: Endif ; Go on init 16 logical disk units. GoOn: Ld Bc,16*256+0 ;; B=Counter, C=Log. drive# Ld Hl,@DTbl ;; drive table. D_In_Loop: ;; Push Bc ;; save # and drive. Ld E,(Hl) ;; get DPH-vector Inc Hl ;; Ld D,(Hl) ;; in De. Inc Hl ;; Ld A,E ;; does drive exist ? Or D ;; Jr Z,D_In_Next ;; No...next Push Hl ;; save vector pointer Ex De,Hl ;; Dec Hl ;; .media byte Dec Hl ;; .controller rel. address Ld A,(Hl) ;; get it Ld (@RDrv),A ;; and save it Ld A,C ;; And save Ld (@ADrv),A ;; logical drive#. Dec Hl ;; Get init-vector Ld D,(Hl) ;; Dec Hl ;; Ld E,(Hl) ;; into De. Ex De,Hl ;; Call IPcHl ;; execute init. Pop Hl ;; Restore vector pointer. D_In_Next: ;; Pop Bc ;; Restore counter, drive Inc C ;; Next drive Djnz D_In_Loop ;; Loop... Jp Boot$1 ;; Take the last part in Bank1. Cseg ; Bank 1. Boot$1: Call SetJumps ; Set jump vectors Call ?LdCcp ; Read Ccp.Com from disk Jp Ccp ; ;------------------------------------------------------------; ; WBoot -- Warm boot routine. ; ;------------------------------------------------------------; WBoot: Ld Sp,Boot$Stack ; Ld Hl,0 ; Ld C,5 ; Reset Lpt interrupt buffer Call ?UserF ; Ld C,2 ; Call ?UserF ; Flush floppy/winchester buffers Call SetJumps ; Init page zero Call ?RlCcp ; Reread Ccp.Com Jp Ccp ; SetJumps: Ld A,1 ; Select Bank1 Call ?BnkSl ; Ld A,JpOp ; Z80 Jp opcode Ld Hl,?WBoot ; Warm Boot entry point Ld (0),A ; Ld (1),Hl ; Ld Hl,(@MxTpa) ; Bdos entry point Ld (5),A ; Ld (6),Hl ; Return: Ret ; ;------------------------------------------------------------; ; 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 a charcter in (C) to all ; ; choosen devices. ; ;------------------------------------------------------------; ConOut: Ld Hl,ConOutB0 ; Jp Bank0Call ; Dseg ConOutB0: ;; Ld Hl,(@CoVec) ;; Get console oputput bit vector Jr OutScan ;; Cseg ;------------------------------------------------------------; ; AuxOut -- Auxilliary output. Sends a character in (C) to ; ; all choosen devices. ; ;------------------------------------------------------------; AuxOut: Ld Hl,AuxOutB0 ; Jp Bank0Call ; Dseg AuxOutB0: ;; Ld Hl,(@AoVec) ;; Get aux output bit vector Jr OutScan ;; Cseg ;------------------------------------------------------------; ; List -- List output. Sends a character in (C) to all ; ; choosen devices. ; ;------------------------------------------------------------; List: Ld Hl,ListB0 ; Jp Bank0Call ; Dseg ListB0: ;; Ld Hl,(@LoVec) ;; Get list output bit vector ;; and do OutScan OutScan: ;; Ld B,0 ;; Start with device 0. CoNext: Add Hl,Hl ;; Shift next device bit Jr NC,NoOutDev ;; Jump...if not set Push Hl ;; Save bit vector Push Bc ;; device and char. CoOutRdy: ;; Call Coster ;; Or A ;; Ready ? ? Jr Z,CoOutRdy ;; No...jump Pop Bc ;; B=device# C=Char Push Bc ;; save Call ?Co ;; Send char Pop Bc ;; Restore Pop Hl ;; NoOutDev: ;; Inc B ;; Next device# Ld A,H ;; Any bits left in bit vector Or L ;; Jr Nz,CoNext ;; Yes...loop Ret ;; Cseg ;------------------------------------------------------------; ; ConoSt -- Console output status. Returns true if all ; ; choosen console output devices are ready. ; ;------------------------------------------------------------; ConoSt: ; Ld Hl,ConoStB0 ; Jp Bank0Call ; Dseg ConoStB0: ;; Ld Hl,(@CoVec) ;; Get console output bit vector Jr OStScan ;; Cseg ;------------------------------------------------------------; ; AuxOSt -- Auxiliary output status. Returns true if all ; ; choosen aux output devices are ready. ; ;------------------------------------------------------------; AuxOSt: ; Ld Hl,AuxOStB0 ; Jp Bank0Call ; Dseg AuxOStB0: ;; Ld Hl,(@AoVec) ;; Get aux output bit vector Jr OStScan ;; Cseg ;------------------------------------------------------------; ; ListSt -- List output status. Returns true if all choosen ; ; list output devices are ready. ; ;------------------------------------------------------------; ListSt: ; Ld Hl,LstStoStB0 ; Jp Bank0Call ; Dseg LstStoStB0: ;; Ld Hl,(@LoVec) ;; Get list output bit vector. OStScan: ;; Ld B,0 ;; Start with device #0. CosNext: ;; Add Hl,Hl ;; Shift next device bit Push Hl ;; save bit vector Push Bc ;; B=dev#, C=Char. Ld A,-1 ;; Set dev. ready Call C,Coster ;; Get status if choosen Pop Bc ;; Restore Pop Hl ;; Or A ;; Ready ? Ret Z ;; No...Return false. Inc B ;; Next device Ld A,H ;; Any more devs. ? Or L ;; Jr Nz,CosNext ;; Yes...loop 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 MbXonXoff ;; 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,NotQ ;; Ld A,-1 ;; SET READY-FLAG NotQ: Cp CtlS ;; CTL-S? Jr Nz,NotS ;; NO...JUMP Xor A ;; CLEAR FLAG NotS: 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 ;; Cseg ;------------------------------------------------------------; ; ConSt -- Console input status. Returns true if any choosen ; ; console input device has a character available. ; ;------------------------------------------------------------; ConSt: ; Ld Hl,ConStB0 ; Jp Bank0Call ; Dseg ConStB0: ;; Ld Hl,(@CiVec) ;; Get console input bit vector Jr IstScan ;; Cseg ;------------------------------------------------------------; ; AuxISt -- Auxialiary input status. Returns true if any ; ; Choosen aux input device has a character avail. ; ;------------------------------------------------------------; AuxISt: ; Ld Hl,AuxIStB0 ; Jp Bank0Call ; Dseg AuxIStB0: ;; Ld Hl,(@AiVec) ;; Get aux input bit vector IstScan: ;; Ld Bc,0 ;; START WITH DEVICE 0 ;; CREG = 0 = FLAG, STATUS Call ONLY CisNext: ;; 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,CisNext ;; Xor A ;; ALL CHOOSEN NOT READY. FALSE Ret ;; Cseg ;------------------------------------------------------------; ; ConIn -- Console input. Returns a character from first ; ; ready console device. ; ;------------------------------------------------------------; ConIn: ; Ld Hl,ConInB0 ; Jp Bank0Call ; Dseg ConInB0: ;; Ld Hl,(@CiVec) ;; Get console input bit vector Call InScan ;; And 7FH ;; strip off parity bit. Ret ;; Cseg ;------------------------------------------------------------; ; AuxIn -- Auxialiary input. Returns a character from first ; ; ready aux input device. ; ;------------------------------------------------------------; AuxIn: ; Ld Hl,AuxInB0 ; Jp Bank0Call ; Dseg AuxInB0: ;; Ld Hl,(@AiVec) ;; Get aux input bit vector InScan: ;; Push Hl ;; SAVE BIT VECTOR Ld B,0 ;; START WITH DEVICE 0 Ld C,-1 ;; CREG = FF = STATUS Call FOR INPUT CiNext: ;; 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,CiRdy ;; YES...JUMP Inc B ;; TEST NEXT DEVICE Ld A,H ;; Or L ;; Jr Nz,CiNext ;; Pop Hl ;; Hl=BIT VECTOR Jr InScan ;; LOOP UNTIL GOT A CHAR CiRdy: Pop Hl ;; Hl=BIT VECTOR Jp ?Ci ;; GET INPUT FROM DEVICE # IN B. Page Cseg ;------------------------------------------------------------; ; Subroutines ; ;------------------------------------------------------------; IPcHl: Jp (Hl) ; VECTOR-Call ?PMsg: ; Prints a message @(Hl) terminated ; with Db 0. Ld A,(Hl) ; Get next char 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 ; print it Pop Bc ; Restore Pop De ; Pop Hl ; Inc Hl ; Next byte Jr ?PMsg ; Loop... ;------------------------------------------------------------; ; ?Move -- Blockmove: Memory to memory. ; ; ; ; At entry: Hl = Destination address. ; ; De = Source address. ; ; Bc = Counter. ; ; At exit: Hl & De pointing to the next bytes ; ; that follows the move. ; ;------------------------------------------------------------; ?Move: Ld A,B ; Is it a zero-move ? Or C ; Ret Z ; Yes...quit Ld A,(BnkFlg) ; Is ?XMove involved ? And A ; Jr Nz,Move1 ; Yes... Ex De,Hl ; Exchange addresses to fit Ldir ; this instruction Ex De,Hl ; and get them back. Ret ; Move1: Di ; Shut up for a moment Call WaitDma ; Wait for Dma Xor A ; Zero ?XMove-flag Ld (BnkFlg),A ; Ld (SrcAdr),De ; Set source address in Dmatable Ld (DstAdr),Hl ; Set destination address in Dmatable Add Hl,Bc ; Hl= End dest.address Push Hl ; Saved. Ex De,Hl ; Add Hl,Bc ; Hl= End sourceaddress Push Hl ; saved. Dec Bc ; Reduce blocklength with 1 Ld (Length),Bc ; Check for the Dma command Ld A,B ; Or C ; Ld A,11001101b ; If not 1 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 garbidge. Ld L,A ; Will give index Ld H,0 ; in table. 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 Dmatable. Out (BnkMux),A ; Start dma Ld (MuxByte),A ; Push Bc ; Save counter Call IniStm ; Pop Bc ; Restore counter Ld A,B ; Or C ; Jr Z,Move4 ; Move3: In A,(Dma) ; Read status And 00100000b ; ready ? Jr Nz,Move3 ; No... Move4: Ld A,DmDisa ; Disable Dma Out (Dma),A ; Xor A ; Free Dma Ld (DmaFlg),A Ei ; Speak again Pop De ; Restore parameters Pop Hl ; Ld Bc,0 ; COUNTER=0 Ret ; ;------------------------------------------------------------; ; WaitDma -- Wait until Dma is free, then mark it busy. ; ;------------------------------------------------------------; WaitDma: ; Ld A,(DmaFlg) ; And A ; Jr Nz,WaitDma ; Inc A ; Ld (DmaFlg),A ; Ret ; ;------------------------------------------------------------; ; ?XMove -- Sets correct banks for data transferes. ; ; ; ; At entry: B = Destination bank. ; ; C = Source bank. ; ;------------------------------------------------------------; ?XMove: ; Ld A,True ; Ld (BnkFlg),A ; Mark ?XMove Ld (DstBnk),Bc ; Gives (C) in dest.bank ; and (B) in source bank. Ret ; ;------------------------------------------------------------; ; BnkSel -- Select bank. ; ; ; ; At entry: A = Memory Bank. ; ;------------------------------------------------------------; BnkSel: ; Di ; Nothing crazy may happen now Ld (@CBnk),A ; Save current bank And 1 ; mask Ld A,Bank0 ; Start with Bank0. Jr Z,Bnk1 ; Bank0 ? Yes... Ld A,Bank1 ; Else set Bank1. Bnk1: ; Ld (BnkMsk),A ; Out (BnkMux),A ; Send it to Bank select port. Ld (MuxByte),A ; Ei ; It worked. Ret ; Page ;------------------------------------------------------------; ; Disk Drive Routines ; ;------------------------------------------------------------; Dseg ;; Bank 0. ;------------------------------------------------------------; ; SelDsk -- Select disk drive. Executes the login procedure ; ; for the drive if it is the first time select. ; ; ; ; At entry: C = Selected drive. ; ; E = Bit0 reset if not slected before. ; ; At exit: Hl = 0 if drives does not exist. ; ; Hl = @DPH if 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 ;; ;------------------------------------------------------------; ; Home -- Home selected drive. Do SetTrk (0). ; ; ; ; SetTrk -- Set track address. ; ; ; ; At entry: Bc = Track address ; ; At exit: (@Trk) = Track address. ; ;------------------------------------------------------------; Home: Ld Bc,0 ;; Track=0 SetTrk: Ld (@Trk),Bc ;; Save track address Ret ;; ;------------------------------------------------------------; ; SetSec -- Set sector address. ; ; ; ; At entry: Bc = Sector address ; ; At exit: (@Sect) = Sector address. ; ;------------------------------------------------------------; SetSec: Ld (@Sect),Bc ;; Save sector address Ret ;; ;------------------------------------------------------------; ; SetDma -- Set Direct Memory Access disk address. ; ; ; ; At entry: Bc = Dma address ; ; At exit: (@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. ; ; ; ; At entry: A = Disk Bank # ; ; At exit: (@DBnk) = Disk Bank # ; ;------------------------------------------------------------; SetBnk: Ld (@DBnk),A ;; Set Disk Dma Bank Ret ;; ;------------------------------------------------------------; ; SecTrn -- Sector translate. Translate logical sector number; ; to physical sector number. ; ; ; ; At entry: Bc = Logical sector # ; ; De = Pointing to TransTable. (0 if none). ; ; At exit: Hl = Physical sector #. ; ;------------------------------------------------------------; SecTrn: Ld L,C ;; Ld H,B ;; Hl=CP/M sector # (relative 0) Inc Hl ;; Hl= -"- (relative 1) Ld A,D ;; Test De=0 Or E ;; Ret Z ;; Yes...Return, no TransTable Dec Hl ;; Hl= CP/M sector # (relative 0) Add Hl,De ;; Hl=Index in table Ld L,(Hl) ;; Translate to sector # from table Ld H,0 ;; 8 bits value Ret ;; ;------------------------------------------------------------; ; Read -- Reads physical sector from selected disk to current; ; @Dma address. ; ; ; ; At entry: None ; ; At exit: A = 0 Ok. ; ; A = 1 if error. ; ; A =-1 if media change. ; ;------------------------------------------------------------; Read: Ld De,-8 ;; Index offset to Readroutine Push De ;; on the stack Jr RWCommon ;; Read-Write-Common-Routine ;------------------------------------------------------------; ; Write -- Writes physical sector on selected disk from ; ; current @Dma address. ; ; ; ; At entry: C = Deblocking code. ; ; At exit: A = 0 If Ok. ; ; A = 1 Physical error. ; ; A = 2 Disk is R/O. ; ; A =-1 If media change. ; ;------------------------------------------------------------; Write: Ld De,-10 ;; Index offset to Writeroutine Push De ;; on the stack RWCommon: ;; 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. ; ; ; ; At entry: A = Sector count. ; ; At exit: (@Cnt) = Multiple sector count. ; ;------------------------------------------------------------; MultIO: Ld (@Cnt),A ;; Save the counter. Ret ;; ;------------------------------------------------------------; ; Flush -- Flush all disk buffers. ; ;------------------------------------------------------------; Flush: Ld C,2 ;; Call ?UserF ;; Xor A ;; Return no error. Ret ;; Page ;------------------------------------------------------------; ; Variables ; ;------------------------------------------------------------; Cseg ; MUST BE IN Bank1 @ADrv: Db 0 ; SELECTED DISK DRIVE # @RDrv: Db 0 ; CONTROLLER RELATIVE DISK DRIVE# @Trk: Dw 0 ; TRACK # @Sect: Dw 0 ; SECTOR # @Dma: Dw 0 ; Dma ADDRESS @Cnt: Db 0 ; RECORD COUNT FOR MULTISECTOR I/O @DBnk: Db 0 ; Bank FOR Dma OPERATIONS @CBnk: Db 0 ; Bank FOR PROCESSOR OPERATIONS BnkMsk: Db Bank0 ; MASK FOR PROC-/Dma-OPERATIONS. MuxByte: Db 0 ; DmaFlg: Db 0 ; Dma busy flag BnkFlg: Db 0 ; FLAG FOR ?XMov DstBnk: Db 0 ; DEST-Bank FOR ?XMove-?Move SrcBnk: Db 0 ; SOURCE-Bank FOR ?XMove-?Move BnkTbl: Db DmBk00 ; Bank0 --> Bank0 Db DmBk10 ; Bank1 --> Bank0 Db DmBk01 ; Bank0 --> Bank1 Db DmBk11 ; Bank1 --> Bank1 DmaTbl: Db 23,Dma ; 23 Bytes to Dma Db DmDisa ; DISABLE Dma Db DmRset Db DmRset Db DmRset Db DmRset Db DmRset Db DmRset Db 01111101B ; CR1A: BLOCKLENGTH LOW o. HI FOLLOWS, ; PORT A START ADDRESS LOW o. HI ; FOLLOWS A->B, TRANSFER. SrcAdr: Dw 0 ; SORCE-ADDRESS (PORT A) Length: Dw 0 ; BLOCKLENGTH - 1. Db 00010100B ; CR1B: PORT ADDR. Inc. PORT A-MEMORY. Db 00010000B ; CR1B: PORT ADDR. Inc. PORT B-MEMORY Mode: Db 0 ; CR2B: BURST/BYTE-Mode DstAdr: Dw 0 ; DEST-ADDRESS (PORT B) Db 10000010B ; CR2A: STOP END-OF-BLOCK Db 11001111B ; CR2D: LOAD STARTADRESSES FOR BOTH ; PORTS And ZERO THE COUNTER. Db 10001011B ; CR2D: ZERO STATUS-BITS Db 10110011B ; CR2D: FORCE READY. Db DmEnab ; ENABLE Dma Db 10111111B ; CR2D: SET NEXT READ STATUS. Db 0 ; TABLE END. Dseg ;; Bank0 XoffList: Db -1,-1,-1,-1,-1,-1,-1,-1 Db -1,-1,-1,-1,-1,-1,-1,-1 End «eof»