|
@@ -0,0 +1,807 @@
|
|
|
+ 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
|
|
|
+
|