|
|
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: 54528 (0xd500)
Types: TextFile
Names: »BIOSKRNL.Z82«
└─⟦8181fe295⟧ Bits:30005924 PolyPascal-80 V3.10 arbejdsdiskette 2
└─⟦this⟧ »BIOSKRNL.Z82«
└─⟦ee7c759f6⟧ Bits:30005973 System backup med COMPAS-80 V3.01, dBase II og WordStar
└─⟦this⟧ »BIOSKRNL.Z82«
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.Z80 DISK-DEFINITON-MODULE *
;* EXTMEM.Z80 EXTERNEL MEMORY-MODULE *
;* SCB.REL SYSTEM VARIABLES *
;* IOS.Z80 PORT ADDRESSES *
;**********************************************************
; LATEST CHANGE: 1984-02-29. PSW.
; BIOSREVISION C.
TRUE EQU -1
FALSE EQU NOT TRUE
BIOSRV EQU 8408H ; BIOS-REVISION.
BOTFLG EQU 0C000H ; BOOT-FLAGG
.Z80
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
; 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,UNKINT
PAGE
CSEG
;**********************************************************
;* BIOS: JUMP VECTORS *
;**********************************************************
.PHASE 0F700H
?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 UNKINT
DEFW UNKINT ; PIO PORT B
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 UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
DEFW UNKINT ;
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
;
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 NOE
LD (HL),A
OUT (BNKMUX),A ; SEND TO BANK SELECT PORT
POP HL
EI ; IT WORKED.
RET
PAGE
;********************************************************
;* VARIABLES *
;********************************************************
.DEPHASE
.PHASE 0F96FH
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
;***************** BOOT **********************************
;
CSEG ; BANK1
; ?LDCCP -- IS CALLED FROM BIOSKRNL.Z80 TO LOAD CCP FROM
; THE FILE CCP.COM. IT WILL BE STORED IN A BUFFER
; AREA IN BANK1 AND WHEN ?RLCCP IS CALLED IT WILL
; BE RELOADED TO BANK1 FOR EXECUTION.
; NOTE: WHEN ?RLCCP IS CALLED BANK1 IS ACTIVE.
?LDCCP: XOR A
LD (CCP$FCB+15),A
LD HL,0
LD (FCB$NR),HL
LD DE,CCP$FCB ; OPEN FILE 'CCP.COM'
LD C,15
CALL BDOS
INC A ; FILE OPEN?
JR NZ,CCPOPEN ; YES...JUMP
CCPERR: LD HL,ERRCCP
LD A,0 ; SET BANK0
CALL ?BNKSL
CALL ?PMSG ; WRITE ERROR MESSAGE
LD A,1
CALL ?BNKSL
LD C,1 ; GET CONSOLE INPUT
CALL BDOS
LD HL,CRLF
CALL ?PMSG ; NEW LINE.
JR ?LDCCP ; TRY AGAIN.
; LOAD CCP FROM 'CCP.COM'
CCPOPEN:
LD DE,26 ; UP TO 26 SECT. READ
LD C,44 ; MULTI-SECTOR-COUNT
CALL BDOS
LD DE,BASE1 ; ADDRESS IN BANK1.
LD C,26
CALL BDOS ; SET DMA ADDRESS
LD DE,CCP$FCB
LD C,20
CALL BDOS ; READ RECORDS.
CP 1 ; ANY ERRORS?
JR NZ,CCPERR ; YES...JUMP
CCPOP3: LD B,0 ; DEST.-BANK
LD C,1 ; SOURCE-BANK
CALL ?XMOV
LD DE,BASE1 ; SOURCE-ADDRESS
LD HL,BASE0 ; DEST.-ADDRESS
JR RLOOP1
; ?RLCCP -- RELOADS CCP FROM BANK0 0000H - 0DFFH TO
; BANK1 0100H -
; ?LDCCP USES THE MAIN PART OF THIS ROUTINE
; TO MOVE CCP FROM BANK1 TO BANK0 ON COLDBOOT.
?RLCCP: LD B,1 ; DEST.-BANK
LD C,0 ; SOURCE-BANK
CALL ?XMOV
LD DE,BASE0 ; SOURCE-ADDRESS
LD HL,BASE1 ; DEST.-ADDRESS
RLOOP1: LD BC,13*256 ; COUNT
CALL ?MOV
LD A,1 ; SET BANK1
JP ?BNKSL
CCP$FCB:
DEFB 1 ; DRIVE A
DEFB 'CCP COM'
DEFB 0 ; EX
DEFB 0 ; S1
DEFB 0 ; S2
DEFB 0 ; RC
DEFW 0,0,0,0 ; D0 --
DEFW 0,0,0,0 ; --DN
FCB$NR: DB 0
DB 0,0,0
CRLF: DEFB CR,LF,0
;**************** CHARIO **********************************************
;
TITLE 'CHARIO.Z80 I/O-HANDLER'
;**********************************************************
;* THIS MODULE TAKES CARE OF ALL CHAR I/O FUNCTIONS FOR *
;* CP/M 3.0 . *
;* A TABLE OF DEVICE-NAMES IS DEFINED TOGEATHER WITH A *
;* DEVICE-HANDLER-TABLE WITH ADDRESSES AND ROUTINES. *
;* THE INTERRUPT-DRIVEN KEYBOARD ROUTINE IS HERE. *
;* *
;* THE GLOBAL SUBROUTINE 'INISTM' IS ALSO IN THIS MODULE. *
;**********************************************************
; LATEST CHANGE: 1984-02-29. PSW.
; BIOSREVISION C.
.Z80
; SPECIAL CHARACTERS AND CONSTANS:
EOF EQU 1AH ; CP/M END OF FILE CHAR (^Z)
CTRLC EQU 'C'-'@'
FALSE EQU 0
TRUE EQU NOT FALSE
MB$INPUT EQU 00000001B ; DEVICE HANDLES INPUT
MB$OUTPUT EQU 00000010B ; DEVICE HANDLES OUTPUT
MB$IN$OUT EQU MB$INPUT+MB$OUTPUT
MB$SOFTBAUD EQU 00000100B ; SOFTWARE SELECTABLE BAUD RATE
MB$SERIAL EQU 00001000B ; DEVICE USES PROTOCOL
MB$XON$XOFF EQU 00010000B ; XON/XOFF PROTOCOL ON
; PORT-ADDRESSES WITH COMMANDS.
SIO1AD EQU 0 ; MODEM/PRINTER - DATA
SIO1AC EQU SIO1AD+1 ; MODEM/PRINTER - CONTROL/STATUS
SIO1BD EQU SIO1AD+2 ; V24,TERMINAL - DATA
SIO1BC EQU SIO1AD+3 ; V24,TERMINAL - CONTROL/STATUS
SIO2AD EQU 4 ; RS422/NETWORK - DATA
SIO2AC EQU SIO2AD+1 ; RS422/NETWORK - CONTROL/STATUS
SIO2BD EQU SIO2AD+2 ;
SIO2BC EQU SIO2AD+3 ;
; SUPPORTED WITH 1,228,800 Hz
CTC0 EQU 8 ; CTC CHAN 0 - BAUDRATE SIO1A/TIMER
CTC1 EQU CTC0+1 ; CTC CHAN 1 - BAUDRATE SIO1B/TIMER
CTC2 EQU CTC0+2 ; CTC CHAN 2 - TIMER TO CTC3 (HALVED)
CTC3 EQU CTC0+3 ; CTC CHAN 3 - REALTIMECLOCK/COUNTER
PIOAD EQU 0CH ; PIO A DATA - CENTRONICS DATA
PIOAC EQU PIOAD+1 ; PIO A CONTROL (WRITE ONLY)
PIOBD EQU PIOAD+2 ; PIO B DATA - CENTRONICS CTRL
; + MODEM CTRL
; BIT0 CEN. *BUSY
; BIT1 CEN. *PAPER EMPTY
; BIT2 CEN. *SELECT
; BIT3 CEN. *FAULT
; BIT4 CEN. *STROBE
; BIT5 CEN. *ACK
; BIT6 MODEM RING INDICATOR
; BIT7 MODEM *DSR
PIOBC EQU PIOAD+3 ; PIO B CONTROL (WRITE ONLY)
SWITCH EQU 1CH ; READABLE SWITCH
; BIT5: CONSOLE BAUDRATE
; xx0xxxxx 9600 BAUD
; xx1xxxxx 19200 BAUD
; BIT6: CONSOLE HANDSHAKE
; x0xxxxxx NO HANDSHAKE
; x1xxxxxx HANSHAKE
; ENTRY ?CINIT,?CI,?CO,?CIST,?COST
; ENTRY @CTBL
; ENTRY INISTM
; ENTRY KBDIRQ,UNKINT
; ENTRY C0BAUD,C1BAUD,SI1ATBL
; EXTRN SIO1IV,CTCIRV
; EXTRN @FX,@MXTPA
; EXTRN ?PMSG
PAGE
CSEG ; BANK0
;**********************************************************
;* NAME TABLE OF THE DEVICES IN THE SYSTEM. *
;**********************************************************
@CTBL:
DEFB 'CRT ' ; DEVICE 0, CRT OR CONSOLE
DEFB MB$IN$OUT+MB$SERIAL+MB$SOFTBAUD
C0BAUD: DEFB 14 ; 9600 BAUD. WILL BE PATCHED.
DEFB 'LPT ' ; DEVICE 1, SERIAL LINE PRINTER
DEFB MB$IN$OUT+MB$SERIAL+MB$SOFTBAUD
C1BAUD: DEFB 14 ; 9600 BAUD. WILL BE PATCHED.
DEFB 'CEN ' ; DEVICE 2, CENTRONICS PARALLEL
DEFB MB$OUTPUT ; OUTPUT ONLY.
DEFB 0 ; NO BAUDRATE
CTBLEND EQU $
DB 0 ; END TABLE
MAX$DEVICES EQU (CTBLEND-@CTBL)/8
BDTBL:
DEFB -1,0 ; 0: NONE
DEFB -1,0 ; 1: 50
DEFB 0,0C4H ; 2: 75
DEFB 174,0C4H ; 3: 110
DEFB 143,0C4H ; 4: 134.5
DEFB 0,84H ; 5: 150
DEFB 128,84H ; 6: 300
DEFB 64,84H ; 7: 600
DEFB 32,84H ; 8: 1200
DEFB -1,0 ; 9: 1800
DEFB 16,84H ;10: 2400
DEFB -1,0 ;11: 3600
DEFB 8,84H ;12: 4800
DEFB -1,0 ;13: 7200
DEFB 4,84H ;14: 9600
DEFB 2,84H ;15: 19200
DEFB 1,84H ;16: 38400
DEFB 1,44H ;17: 76800
BTLKUP:
AND 0FH ; MASK MAX 15.
RLA ; *2 FOR TABLE-LOOKUP
LD E,A ; INDEX TABLE FOR CTC CONSTANS.
LD D,0 ; (IF CTC CONST.=0FFH, NO BAUD RATE
LD HL,BDTBL
ADD HL,DE
LD A,(HL)
CP -1
RET Z ; CANNOT SET THIS BAUD RATE
INC HL ; GET SIO BYTE.
LD B,(HL)
RET
PAGE
; INISTM -- WRITES A NUMBER OF BYTE TO ONE OR MORE PORTS.
; IN: HL = TABLE-ADDRESS.
; TABLEVIEW (BYTE BY BYTE):
; NO OF BYTES, PORT#, BYTE1,...,
; NO OF BYTES, PORT#, BYTE1,...,
; 0 (DETERMINATOR).
INISTM: LD A,(HL) ; LOAD BYTE
OR A ; IS IT ZERO?
RET Z ; YES...TERMINATE
LD B,A ; NO...THEN IT IS A BYTE COUNTER.
INC HL ; NEXT BYTE, WHICH IS THE PORT#
LD C,(HL) ; STORED IN C.
INC HL ; POINT TO DATA BYTE1
OTIR ; SEND (B) BYTES TO PORT (C)
JR INISTM ; GO ON.
PAGE
;********************************************************
;* *
;* CONSOLE AND LIST DEVICE I/O *
;* *
;********************************************************
; ?CINIT --
; IN: C = LOGICAL UNIT #
;
; IF THERE IS A PHYSICAL UNIT IN @CTBL FOR THIS LOGICAL UNIT,
; IT WILL BE INITILIZED WITH WITH BAUD RATE BYTE IN THE TABLE.
?CINIT:
LD B,C
INC B ; MAKE DEVICE # (RELATIVE 1)
DJNZ INIT1 ; TEST IF DEV# IS 0
; INIT DEVICE 0 ; CRT
LD HL,SIO1IV ; SET SIOVECTOR
LD A,L
LD (SIOVEC),A
LD HL,CTCIRV ; SET CTCVECTOR
LD A,L
LD (CTCVEC),A
IN A,(SWITCH) ; READ SWITCH
AND 00100000B ; BIT5 BAUDRATE
JR Z,INIT01
LD A,15 ; 19200 BAUD
LD (C0BAUD),A
INIT01: IN A,(SWITCH)
AND 01000000B ; BIT6 HANDSHAKE
JR Z,INIT02
LD A,11100001B ; Rx 8 BITS, AUTO ENABL., Rx ENABLE
LD (HANDSH),A
INIT02: LD A,(C0BAUD)
CALL BTLKUP
RET Z
LD (BAUDB),A
LD A,B
LD (CLKB),A
LD HL,SI1BTBL ; POINT TO INIT.TABLE
INSIO: CALL INISTM ; SEND TO THE PORT.
DEC C ; POINT TO THE DATA PORT
IN A,(C) ; CLEAR THE INPUT
IN A,(C) ; OF THE SIO.
RET ; READY
INIT1: DJNZ INIT2 ; JUMP IF NOT DEV #1.
; INIT DEV #1. ; LPT
LD A,(C1BAUD) ; GET CHAR DEVICE 1 BAUD BYTE.
; CALC BAUD RATE BYTES
INIT1B: CALL BTLKUP ; CHECK IN BAUD TABLE
RET Z ; NOT COORECT...RETURN
LD (BAUDA),A ; SET CTC COUNTER CONSTANT
LD A,B ; GET SIO CONSTANT
LD (CLKA),A ; SET IT
LD HL,SI1ATBL ; POINT TO THE INIT. TABLE
JR INSIO ; DO
INIT2: DJNZ INIT3 ; JUMP IF NOT DEV #2
; INIT DEVICE #2 ; CEN
LD HL,PIOTBL ; POINT TO THE INIT. TABLE
CALL INISTM ; DO
INIT3: RET ; NO MORE DEVICES.
PAGE
; ?CI:
; CHAR INPUT FROM DEVICE # IN REGISTER (B).
?CI:
INC B ; DEVICE # (RELATIVE 1)
DJNZ CI1 ; JUMP IF NOT DEVICE #0
; CONIN -- CONSOLE CHAR INPUT. DEVICE #0.
; IN: NONE.
; OUT: A = CHAR (PARITY BIT = 0).
; AF,DE,HL,BC WILL BE CHANGED.
;CONIN:
TTYIN:
LD HL,RNGCNT ; POINT TO THE RING BUFFER COUNTER.
XOR A ; ZERO
CONIN1: OR (HL) ; GET IT.
JR Z,CONIN1 ; LOOP FOR CHAR.
DI
DEC (HL) ; COUNT DOWN
LD DE,(RNGOUT) ; GET THE OUTPUT-POINTER
LD A,(DE) ; A=OUTPUT CHAR (PARITY RESET).
AND 07FH ; CLEAR BIT 7
CP 03H ; CTRL C?
JR Z,CONIN2 ; YES...JUMP
CP 11H ; CTRL Q?
JR Z,CONIN2 ; YES...JUMP
CP 13H ; CTRL S?
JR NZ,CONIN3 ; NO...JUMP
CONIN2: INC HL ; HL=^C-COUNTER
DEC (HL)
CONIN3: AND A ; CLEAR CARRY BIT
LD HL,RNGEND ; INC RING BUFFER-OUTPUT-POINTER
SBC HL,DE ; IS THE BUFFEREND?
INC DE ; (INC)
JR NZ,CONIN4 ; NO...JUMP
LD DE,RNGBEG ; SET BUFFER START
CONIN4: LD (RNGOUT),DE ; SAVE THE POINTER.
EI
RET
CI1: DJNZ CI2 ; JUMP IF NOT DEVICE 1
; AUXIN -- GIVES INPUT FROM SIO1 A.
;
; IN: NONE
; OUT: A = CHAR.
;AUXIN:
MODIN: CALL MODIST ; CHAR IN SIO BUFFER?
JR Z,MODIN ; NO...WAIT
IN A,(SIO1AD) ; READ CHAR
RET
CI2:
; CENTRONICS IS DEVICE 2, OUTPUT ONLY.
LD A,EOF ; END-OF-FILE-TOKEN.
RET
PAGE
; ?CO -- SEND A CHARACTER TO A CHOOSEN DEVICE.
; IN: B = DEVICE #
; C = CHAR.
?CO:
INC B ; MAKE DEVICE # (RELATIVE 1)
DJNZ CO1 ; JUMP IF NOT DEVICE 0
; CONOUT -- SIO1B OUTPUT ROUTINE.
;
; IN: C = CHAR --> SIO1B
; OUT: A = WRITTEN CHAR.
;CONOUT:
TTYOUT:
CALL CNOST ; TEST OUTPUT STATUS
JR Z,TTYOUT ; WAIT FOR READY
LD A,C
OUT (SIO1BD),A
RET
CO1: DJNZ CO2 ; JUMP IF NOT DEVICE 1
; AUXOUT -- SIO1A OUTPUT ROUTINE.
; IN: C = CHAR --> SIO1A
; OUT: A = WRITTEN CHAR
;AUXOUT:
MODOUT:
CALL MODOST ; TEST OUTPUT STATUS
JR Z,MODOUT ; WAIT FOR READY.
LD A,C
OUT (SIO1AD),A
RET
CO2: DJNZ CO3 ; JUMP IF NOT DEVICE 2
; LISTC -- CENTRONICS PARALLEL OUTPUT ROUTINE.
; IN: C = CHAR --> PIOA
; OUT: A = WRITTEN CHAR.
LISTC: LD A,10H ; STROBE HIGH
OUT (PIOBD),A
LISTC1: CALL LSTTST ; TESTA OUTPUT STATUS
JR Z,LISTC1 ; VÆNTA TILLS KLAR.
LD A,C
OUT (PIOAD),A
LD A,0H ; STROBE
OUT (PIOBD),A
LD A,10H ; STROBE HIGH
OUT (PIOBD),A
CO3: RET
PAGE
; ?CIST -- CHAR INPUT STATUS FROM CHOOSEN DEVICE.
; IN: B = DEVICE #
?CIST:
INC B ; MAKE DEVICE # (RELATIVE 1)
DJNZ CIS1 ; JUMP IF NOT DEVICE 0.
; CONST -- CONSOLE INPUT STATUS CHECK.
; IN: NONE
; OUT: A = 0, Z = 1 IF NO CHAR AVAIL.
; A = 0FFH, Z = 0 AT LEAST ONE CHAR AVAIL.
;CONST:
XCONST:
LD A,(RNGCNT) ; ANY CHAR IN THE BUFFER?
OR A
RET Z ; NO...RETURN
OR 0FFH ; YES...SET FLAG
RET
CIS1: DJNZ CIS2 ; JUMP IF NOT DEVICE 1.
; AUXIST -- AUXILIARY INPUT STATUS.
; IN: NONE
; OUT: A = 0, Z = 1 IF NOT READY
; A = 0FFH, Z = 0 IF CHAR AVAIL.
;AUXIST:
MODIST:
IN A,(SIO1AC) ; READY STATUS.
AND 00000001B ; MASK Rx CHAR AVAILABLE
RET Z ; NOT READY...RETURN
OR 0FFH ; MARK CHAR AVAIL
RET
CIS2:
; DEVICE 2 THE LAST ONE IN THE LIST. CENTRONICS DOES NOT
; HANDLE INPUT. RETURNS NOT READY.
XOR A ; NOT READY
RET
PAGE
; ?COST -- CHARACTER OUTPUT STATUS FROM CHOOSEN DEVICE.
; IN: B = DEVICE #.
?COST:
INC B ; MAKE DEVICE # (RELATIVE 1)
DJNZ COS1 ; JUMP IF NOT DEVICE 0.
; CNOST: -- CONSOLE OUTPUT STATUS CHECK.
; IN: NONE
; OUT: A = 0, Z = 1 IF NOT READY
; A = 0FFH, Z = 0 IF READY FOR OUTPUT
CNOST:
IN A,(SIO1BC) ; READ STATUS.
AND 00000100B ; MASK Tx BUFFER EMPTY
RET Z ; NOT READY...RETURN
OR 0FFH ; SET FLAG FOR READY OUTPUT.
RET
COS1: DJNZ COS2 ; JUMP IF NOT DEVICE 1.
; AUXOST -- AUXILIARY OUTPUT STATUS.
; IN: NONE
; OUT: A = 0, Z = 1 IF NOT READY
; A = 0FFH, Z = 0 IF READY FOR OUTPUT.
;AUXOST:
MODOST:
IN A,(SIO1AC) ; READ STATUS
AND 00000100B ; MASK Tx BUFFER EMPTY
RET Z ; NOT READY...RETURN
OR 0FFH ; SET FLAG FOR READY OUTPUT.
RET
COS2: DJNZ COS3 ; JUMP IF NOT DEVICE 2.
; LSTTST -- PARALLEL PORT TEST IF READY.
; IN: NONE
; OUT: A = 0, Z = 1 IF NOT READY
; A = 0FFH, Z = 0 IF READY FOR OUTPUT.
LSTTST:
IN A,(PIOBD) ; READ ACK AND BUSY.
AND 00100001B
CP 00100000B ; READY AND NOT BUSY
LD A,0FFH
JR Z,LSTT1 ; YES...JUMP
LD A,0 ; SET NOT READY
LSTT1: AND A
RET
COS3: XOR A ; NOT READY. CAUSE NO
RET ; MORE DEVICES.
PAGE
; KBDIRQ -- CONSOLE KEYBOARD INTERRUPT SERVICE ROUTIN.
; USES LOCAL STACK IN ORDER NOT TO INTERFERE WITH THE
; USER PROGRAM STACK.
KBDIRQ:
LD (USRSK2),SP ; OWN STACK
LD SP,OWNSK2
PUSH AF ; SAVE REGISTERS.
PUSH DE
PUSH HL
LD HL,RNGCNT ; HL --> NO OF CHAR IN BUFFER
LD A,(HL) ; A = NO OF CHAR IN BUFFERT
CP RNGEND-RNGBEG ; IS BUFFER FULL?
IN A,(SIO1BD) ; A = CHAR (CLR INTERRUPT)
JR Z,KBDIR3 ; YES...JUST JUMP AND QUIT
INC (HL) ; INC CHAR-COUNTER
AND 07FH ; MASK PARITY
CP 13H ; CTRL S?
JR Z,KBDIR4 ; YES...JUMP
JP NC,KBDIR1 ; CAN'T BE ^Q,^C...JUMP
CP 11H ; CTRL Q?
JR Z,KBDIR4 ; YES...JUMP
CP 3 ; CTRL C?
JP NZ,KBDIR1 ; NO...JUMP
LD (HL),1 ; ZERO BUFFER
INC HL
LD (HL),1
LD HL,RNGBEG
LD (RNGIN),HL
LD (RNGOUT),HL
JR KBDIR1
KBDIR4: INC HL ; HL --> ^C-COUTER
INC (HL) ; INC
LD HL,(RNGOUT)
EX DE,HL
LD HL,RNGBEG
AND A
SBC HL,DE
DEC DE
JR NZ,KBDIR7
LD DE,RNGEND
KBDIR7: LD (DE),A ; SAVE ^Q/S AT BUFFERSTART
LD (RNGOUT),DE
JR KBDIR3
KBDIR1: LD HL,(RNGIN) ; HL --> INPUT
LD (HL),A ; SPAR INPUT CHAR IN BUFFER.
AND A ; CLEAR CARRY BIT
EX DE,HL ; SAVE INPUT POINTER IN DE.
LD HL,RNGEND ; HL=BUFFEREND FOR TEST
SBC HL,DE ; POINTER AT END?
INC DE ; INC
JP NZ,KBDIR2 ; NO...JUMP
LD DE,RNGBEG ; SET POINTER TO BUFFERSTART
KBDIR2: LD (RNGIN),DE ; SAVE THE PEKAREN.
KBDIR3: POP HL ; USER REGS. BACK
POP DE
POP AF
LD SP,(USRSK2) ; AND USER STACK.
UNKINT:
EI ; BACK FROM INTERRUPT.
RETI
PAGE
;**********************************************************
;* OTHER TABLES *
;**********************************************************
; NOTE: THE SIO1-TABLES ARE PATCHES FROM THE LOADER IN
; BOOT.Z80-MODULE.
; IT VERY IMPORTANT THAT SIZE AND ORDER IN THIS
; TABLES NOT ARE ALTERED.
SI1ATBL: ; MODEM/AUX/PRINTER.
DEFB 3,CTC0 ; 3 BYTES TO CTC CHAN 0
DEFB 01000101B ; CTC0: INT. DIS, COUNTER MODE,
; NEG. EDGE, TIME CONST. FOLLOWS,
; COUNTING CONT.
BAUDA: DEFB 4 ; GIVES 307200 Hz TO SIO1A
CTCVEC: DEFS 1 ; CTCINTERRUPTVECTOR.
DEFB 9,SIO1AC ; 9 BYTES TO SIO1 A/MODEM
DEFB 18H ; RESET CHANNEL.
DEFB 14H ; WR 4:
CLKA: DEFB 10000100B ; x32 CLOCK, 1 STOP BIT, NO PARITY.
DEFB 13H ; WR 3:
DEFB 11100001B ; Rx 8 BITS, AUTO ENABL., Rx ENABLE.
DEFB 15H ; WR 5:
DEFB 11101010B ; DTR, Tx 8 BITS, Tx ENABLE, *RTS LOW.
DEFB 01 ; WR 1:
DEFB 00000000B ; NO INTERRUPTS, UNMODIFIED INTERRUPT
; VECTOR (BOTH CHANNELS).
DEFB 0 ; END TABLE.
SI1BTBL:
DEFB 2,CTC1 ; 2 BYTES TO CTC CHAN 1
DEFB 01000101B ; CTC1: INT. DIS, COUNTER MODE,
; NEG. EDGE, TIME CONST. FOLLOWS,
; COUNTING CONT.
BAUDB: DEFB 4 ; GIVES 307200 Hz TO SIO1B.
DEFB 11,SIO1BC ; 11 BYTES TO SIO1 B/TERMINAL
DEFB 18H ; RESET CHANNEL
DEFB 12H ; WR 2:
SIOVEC: DEFS 1 ; INTERRUPTVECTOR
DEFB 14H ; WR 4:
CLKB: DEFB 10000100B ; x32 CLOCK, 1 STOP BIT, NO PARITY
DEFB 13H ; WR 3:
HANDSH: DEFB 11000001B ; Rx 8 BITS, Rx ENABLE.
DEFB 15H ; WR 5:
DEFB 11101010B ; DTR, Tx 8 BITS, Tx ENABLE, *RTS LOW
DEFB 01 ; WR 1:
DEFB 00011000B ; INT ON ALL Rx CHAR (PARITY DOES NOT
; AFFECT VECTOR)
DEFB 0 ; END TABLE.
PAGE
; PIO PORT A INIT TABLE
PIOTBL: DEFB 2,PIOAC ; 2 BYTES TO PIO A CTLR-REG.
DEFB 00001111B ; SELECT MODE 0 OPERATION
DEFB 00000011B ; INTERUPT DISABLE.
; PIO PORT B INIT TABLE
DEFB 4,PIOBC ; 4 BYTES TO PIO B CTRL-REG.
DEFB 11001111B ; SELECT MODE 3 OPERATION
DEFB 11101111B ; BIT4=OUTPUT ALL OTHERS INPUTS
DEFB 00110111B ; INTERRUPT CONTROL WORD = DISABLED
DEFB 00000001B ; MASK WORD, ONLY MONITOR BIT 0.
; REAL TIME CLOCK INITIALIZATION TABLE
DEFB 2,CTC2 ; 2 BYTES TO CTC CHAN 2
DEFB 01000101B ; CTC2: INT. DIS, COUNTER MODE,
; NEG. EDGE, TIME CONST. FOLLOWS,
; COUNTING CONT.
DEFB 0 ; GIVES 4800 Hz TO CTC3.
DEFB 2,CTC3 ; 2 BYTES TO CTC CHAN 3.
DEFB 11000101B ; INT. ENABLED, COUNTER MODE
; NEG. EDGE, TIME CONST. FOLLOWS,
; COUNTING CONT.
DEFB 240 ; GIVES 20 Hz, WHICH IS DIVIDED
; BY 2 (HARDWARE).
; INERRUPT 10 times/second.
DEFB 0 ; END TABLE.
PAGE
USRSK2: DEFS 2 ; USER STACK SAVED HERE
DEFS 10H ; LOCAL STACK.
OWNSK2 EQU $
RNGCNT: DEFB 0 ; NO OF CHAR IN BUFFER
DEFB 0 ; NO OF ^C IN BUFFER
RNGIN: DEFW RNGBEG ; POINTS TO INPUT PLACE
RNGOUT: DEFW RNGBEG ; POINTS TO OUTPUT PLACE
; IF EQU BUFFER IS EMPTY.
RNGBEG: DEFS 82 ; KEYBOARD RING BUFFER.
RNGEND EQU $-1
;
;*******************************************************************
TITLE 'FDRIVES.Z80 TABLES FOR DISKETTES'
;*********************************************************
;* *
;* DEFINITION MODULE FOR THE FLOPPIES IN THE SYSTEM *
;* *
;*********************************************************
; LATEST CHANGE: 1984-02-29. PSW
; BIOSREVISION C.
.Z80
TRUE EQU 0FFH
FALSE EQU 0
;******************************************************************
; What kind of floppy system do You want ?
VERIFY EQU TRUE ; Verify after write.
M8 EQU TRUE ; A: 8" 2x77x8x1024, 256 ent. UNIT0
; B: 8" 2x77x8x1024, 256 ent. UNIT1
; C: 5" 2x80x5x1024, 128 ent. UNIT0
; D: 8" 1x77x26x128, 64 ent. UNIT1
M5 EQU FALSE ; A: 5" 2x77x8x1024, 256 ent. UNIT0
; B: 5" 2x77x8x1024, 256 ent. UNIT1
; C: 8" 2x77x8x1024, 256 ent. UNIT0
; D: 8" 1x77x26x128, 64 ent. UNIT0
M596D EQU FALSE ; A: 5" 2x80x5x1024, 128 ent. UNIT0
; B: 5" 2x80x5x1024, 128 ent. UNIT1
; C: 8" 2x77x8x1024, 256 ent. UNIT0
; D: 8" 1x77x26x128, 64 ent. UNIT0
M548D EQU FALSE ; A: 5" 2x40x5x1024, 128 ent. UNIT0
; B: 5" 2x40x5x1024, 128 ent. UNIT1
; C: 8" 2x77x8x1024, 256 ent. UNIT0
; D: 8" 1x77x26x128, 64 ent. UNIT0
M548S EQU FALSE ; A: 5" 1x40x5x1024, 64 ent. UNIT0
; B: 5" 1x40x5x1024, 64 ent. UNIT1
; C: 8" 2x77x8x1024, 256 ent. UNIT0
; D: 8" 1x77x26x128, 64 ent. UNIT0
; MARK CORRECT FLOPPY SYSTEM WITH TRUE. NOTE ONLY ONE TRUE.
;******************************************************************
PAGE
RATE0 EQU 00000000B ; 3ms/6ms
RATE1 EQU 00000001B ; 6ms/12ms
RATE2 EQU 00000010B ; 10ms/20ms
RATE3 EQU 00000011B ; 15ms/30ms
DOUBLS EQU 0FFH ; DOUBLE SIDED
SINGLS EQU 0 ; SINGLE SIDED
UNIT0 EQU 00000000B ; FYSISK ENHET 0
UNIT1 EQU 00000001B ; FYSISK ENHET 1
UNIT2 EQU 00000010B ; FYSISK ENHET 2
UNIT3 EQU 00000011B ; FYSISK ENHET 3
INCH5 EQU 00001000B ; 5"-FLOPPY
INCH8 EQU 11010100B ; 8"-FLOPPY
DOUBLD EQU 00000000B ; DOUBLE DENSITY
SINGLD EQU 00100000B ; SINGLE DENSITY
COMMON EQU 0C0H ; COMMON AREA▶8a◀
IF M8
SIGN EQU '8'
ELSE
SIGN EQU '5'
ENDIF
; EXTRN FDREAD,FDWRIT,FDLGIN,FDINIT
; ENTRY @DTBL,?TITEL
; ENTRY @COMMO
CSEG
@DTBL: DEFW FLA,FLB,FLC,FLD
DEFW 0,0,0,0
DEFW 0,0,0,0
DEFW 0,0,0,0
@COMMO: DEFB COMMON
PAGE
CSEG
; DPB for 8" 2x77x8x1024, 256 entries.
F8D: DEFW 64 ; Number of logical sect/track
DEFB 4,0FH ; BLOCK SKIFT and MASK
DEFB 0 ; EXTENT MASK
DEFW 607 ; MAX BLOCKNUMBER
DEFW 256-1 ; 256 DIR. ENTRIES
DEFB 0F0H,0 ; ALLOC VECTOR TO DIR
DEFW 256/4 ; CHECKSUMMA SIZE
DEFW 2 ; NUMBER OF OFFSET TRACKS
DEFB 0 ; PHYS. SECTOR SIZE
DEFB 0 ; PHYS. SECTOR SHIFT-MASK
DEFB 0 ; Floppy
DEFB 8 ; No. of log.sec./phys. sec.
DEFB 22 ; Read time out
DEFB 19 ; Write time out
DEFB 0FFH ; Double sided
DEFB VERIFY ; Verify after write
DEFB RATE0 ; Step rate
DEFB INCH8+DOUBLD ; Boot select
DEFB 0,0,0,0,0,0 ; Dummies
; DPB for 8" 1x77x26x128, 64 entries. (IBM)
F8S: DEFW 26 ; No. of logical sectors/track.
DEFB 3,7 ; BLOCK SKIFT AND MASK
DEFB 0 ; EXTENT MASK
DEFW 242 ; MAX BLOCKNUMBER
DEFW 64-1 ; 64 DIR. ENTRIES
DEFB 0C0H,0 ; ALLOC VECTOR TO DIR
DEFW 64/4 ; CHECKSUM SIZE
DEFW 2 ; OFFSET TRACK
DEFB 0 ; PHYS.SECTOR SIZE
DEFB 0 ; PHYS. SECTOR SHIFT-MASK
DEFB 0 ; Floppy
DEFB 1 ; No. of logical sectors/phys. sector.
DEFB 22 ; Read time out
DEFB 19 ; Write time out
DEFB 0 ; Single sided
DEFB VERIFY ; Verify after write
DEFB RATE0 ; Step rate
DEFB INCH8+SINGLD ; Boot select
DEFB 0,0,0,0,0,0 ; Dummies
PAGE
; DPB for 5.25" 2x77x8x1024, 256 entries.
F5MAX: DEFW 64 ; No. of logical sectors/track.
DEFB 4,0FH ; BLOCK SKIFT AND MASK
DEFB 0 ; EXTENT MASK
DEFW 607 ; MAX BLOCKNUMBER
DEFW 256-1 ; 256 DIR. ENTRIES
DEFB 0F0H,0 ; ALLOC VECTOR TO DIR
DEFW 256/4 ; CHECKSUM SIZE
DEFW 2 ; OFFSET TRACKS
DEFB 0 ; PHYS. SECTOR SIZE
DEFB 0 ; PHYS. SECTOR SHIFT-MASK
DEFB 0 ; Floppy
DEFB 8 ; No. of logical sectors/phys. sector.
DEFB 22 ; Read time out
DEFB 19 ; Write time out
DEFB 0FFH ; Double sided
DEFB VERIFY ; Verify after write
DEFB RATE0 ; Step rate
DEFB INCH5+DOUBLD+11000000B ; Boot select
DEFB 0,0,0,0,0,0 ; Dummies
; DPB for 5.25" 2x80x5x1024, 128 entries.
F596D: DEFW 40 ; No. of logical sectors/track.
DEFB 4,0FH ; BLOCK SKIFT AND MASK
DEFB 0 ; EXTENT MASK
DEFW 394 ; MAX BLOCKNUMBER
DEFW 128-1 ; 128 DIR. ENTRIES
DEFB 0C0H,0 ; ALLOC VECTOR TO DIR
DEFW 128/4 ; CHECKSUM SIZE
DEFW 2 ; OFFSET TRACKS
DEFB 0 ; PHYS. SECTOR SIZE
DEFB 0 ; PHYS. SECTOR SHIFT-MASK
DEFB 0 ; Floppy
DEFB 8 ; No. of logical sectors/phys. sector.
DEFB 22 ; Read time out
DEFB 19 ; Write time out
DEFB 0FFH ; Double sided
DEFB VERIFY ; Verify after write
DEFB RATE0 ; Step rate
DEFB INCH5+DOUBLD ; Boot select
DEFB 0,0,0,0,0,0 ; Dummies
PAGE
; DPB for 5.25" 2x40x5x1024, 128 entries.
F548D: DEFW 40 ; No. of logical sectors/track.
DEFB 4,0FH ; BLOCK SKIFT AND MASK
DEFB 1 ; EXTENT MASK
DEFW 194 ; MAX BLOCKNUMBER
DEFW 128-1 ; 128 DIR. ENTRIES
DEFB 0C0H,0 ; ALLOC VECTOR TO DIR
DEFW 128/4 ; CHECKSUM SIZE
DEFW 2 ; OFFSET TRACKS
DEFB 0 ; PHYS: SECTOR SIZE
DEFB 0 ; PHYS. SECTOR SHIFT-MASK
DEFB 0 ; Floppy
DEFB 8 ; No. of logical sectors/phys. sector
DEFB 22 ; Read time out
DEFB 19 ; Write time out
DEFB 0FFH ; Double sided
DEFB VERIFY ; Verify after write
DEFB RATE0 ; Step rate
DEFB INCH5+DOUBLD ; Boot select
DEFB 0,0,0,0,0,0 ; Dummies
; DPB for 5.25" 1x40x5x1024, 64 entries.
F548S: DEFW 40 ; No. of logical sectors/track.
DEFB 3,7 ; BLOCK SKIFT AND MASK
DEFB 0 ; EXTENT MASK
DEFW 189 ; MAX BLOCKNUMBER
DEFW 64-1 ; 64 DIR. ENTRIES
DEFB 0C0H,0 ; ALLOC VECTOR TILL DIR
DEFW 64/4 ; CHECKSUM SIZE
DEFW 2 ; OFFSET TRACKS
DEFB 0 ; PHYS. SECTOR SIZE
DEFB 0 ; PHYS. SECTOR SHIFT-MASK
DEFB 0 ; Floppy
DEFB 8 ; No. of logical sector/phys. sector
DEFB 22 ; Read time out
DEFB 19 ; Write time out
DEFB 0 ; Single sided
DEFB VERIFY ; Verify after write
DEFB RATE0 ; Step rate
DEFB INCH5+DOUBLD ; Boot select
DEFB 0,0,0,0,0,0 ; Dummies
PAGE
?TITEL: DEFB '80. '
DEFB SIGN,'"-floppy-version. '
IF M8
DEFB '2x1.2 MBytes.'
ENDIF
IF M5
DEFB '2x1.2 MBytes.'
ENDIF
IF M596D
DEFB '2x800 KBytes.'
ENDIF
IF M548D
DEFB '2x400 KBytes.'
ENDIF
IF M548S
DEFB '2x200 KBytes.'
ENDIF
DEFB 13,10,0
TRANS: DEFB 1,7,13,19,25▶8a◀ DEFB 5,11,17,23
DEFB 3,9,15,21
DEFB 2,8,14,20,26
DEFB 6,12,18,24
DEFB 4,10,16,22
title 'System Control Block Definition for CP/M3 BIOS'
; public @civec, @covec, @aivec, @aovec, @lovec, @bnkbf
; public @crdma, @crdsk, @vinfo, @resel, @fx, @usrcd
; public @mltio, @ermde, @erdsk, @media, @bflgs
; public @date, @hour, @min, @sec, ?erjmp, @mxtpa
scb$base equ 0F69CH ; Base of the SCB
@CIVEC equ scb$base+22h ; Console Input Redirection
; Vector (word, r/w)
@COVEC equ scb$base+24h ; Console Output Redirection
; Vector (word, r/w)
@AIVEC equ scb$base+26h ; Auxiliary Input Redirection
; Vector (word, r/w)
@AOVEC equ scb$base+28h ; Auxiliary Output Redirection
; Vector (word, r/w)
@LOVEC equ scb$base+2Ah ; List Output Redirection
; Vector (word, r/w)
@BNKBF equ scb$base+35h ; Address of 128 Byte Buffer
; for Banked BIOS (word, r/o)
@CRDMA equ scb$base+3Ch ; Current DMA Address
; (word, r/o)
@CRDSK equ scb$base+3Eh ; Current Disk (byte, r/o)
@VINFO equ scb$base+3Fh ; BDOS Variable "INFO"
; (word, r/o)
@RESEL equ scb$base+41h ; FCB Flag (byte, r/o)
@FX equ scb$base+43h ; BDOS Function for Error
; Messages (byte, r/o)
@USRCD equ scb$base+44h ; Current User Code (byte, r/o)
@MLTIO equ scb$base+4Ah ; Current Multi-Sector Count
; (byte,r/w)
@ERMDE equ scb$base+4Bh ; BDOS Error Mode (byte, r/o)
@ERDSK equ scb$base+51h ; BDOS Error Disk (byte,r/o)
@MEDIA equ scb$base+54h ; Set by BIOS to indicate
; open door (byte,r/w)
@BFLGS equ scb$base+57h ; BDOS Message Size Flag (byte,r/o)
@DATE equ scb$base+58h ; Date in Days Since 1 Jan 78
; (word, r/w)
@HOUR equ scb$base+5Ah ; Hour in BCD (byte, r/w)
@MIN equ scb$base+5Bh ; Minute in BCD (byte, r/w)
@SEC equ scb$base+5Ch ; Second in BCD (byte, r/w)
?ERJMP equ scb$base+5Fh ; BDOS Error Message Jump
; (word, r/w)
@MXTPA equ scb$base+62h ; Top of User TPA
; (address at 6,7)(word, r/o)
;
.DEPHASE
;
.PHASE 0A700H
; BOOT
; DSEG ;; CODE IN BANK0
BOOT: 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
;
; 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
;***************************************************************
;
TITLE 'BOOT.Z80'
;***********************************************************
;* THIS MODULE PATCHES THE IO-PARAMETERS FROM THE LOADER *
;* TO THE SCB.ASM AND CHARIO.Z80. *
;* IT ALSO LOADS CCP.COM ON COLDBOOT TO A RESERVED AREA *
;* IN BANK0 0000H - 0DFFH, FROM WHERE IT WILL BE RELOADED *
;* TO BANK1 ADDRESS 0100H ON WARMBOOT. *
;***********************************************************
; LATEST CHANGE: 1984-02-29. PSW.
; BIOSREVSION C.
.Z80
FALSE EQU 0
TRUE EQU NOT FALSE
CR EQU 13
LF EQU 10
BDOS EQU 5 ; HOPP-VEKTOR TO CP/M
BASE1 EQU 100H ; CCP I BANK 1
BASE0 EQU 000H ; CCP I BANK 0.
CIVC EQU 20H ; IN LOADER
COVC EQU 22H
LOVC EQU 24H
AIVC EQU 26H
AOVC EQU 28H
C0BD EQU 2AH ; BAUD DEV#0
C1BD EQU 2BH ; BAUD DEV#1
S1STRT EQU 30H ; SIO TABLES
SILEN EQU 23H ; LENGTH
; EXTRN INTVECT,?PMSG
; EXTRN ?BNKSL,?MOV,?XMOV
; EXTRN @COVEC,@CIVEC,@LOVEC,@AOVEC,@AIVEC
; EXTRN C0BAUD,C1BAUD,SI1ATBL
; ENTRY ?INIT,?PATCH,?LDCCP,?RLCCP
; EXTRN ?TITEL
PAGE
; DSEG ;; BANK 0.
; ?PATCH -- THIS ROUTINE PATCHES THE IO-PARAMETERS
; FROM THE LOADER.
?PATCH: LD HL,(CIVC) ;; CONSOLE INPUT VECTOR
LD (@CIVEC),HL
LD HL,(COVC) ;; CONSOLE OUTPUT VECTOR
LD (@COVEC),HL
LD HL,(LOVC) ;; LIST OUTPUT VECTOR
LD (@LOVEC),HL
LD HL,(AIVC) ;; AUX INPUT VECTOR
LD (@AIVEC),HL
LD HL,(AOVC) ;; AUX OUTPUT VECTOR
LD (@AOVEC),HL
LD A,(C0BD) ;; BAUD DEV#0
LD (C0BAUD),A
LD A,(C1BD) ;; BAUD DEV#1
LD (C1BAUD),A
LD HL,S1STRT ;; MOVE SIO TABLES
LD DE,SI1ATBL
LD BC,SILEN
LDIR
RET
; ?INIT -- SET UP INTERRUP VECTOR ENABLE INTERRUPT AND
; WRITE A PART OF SIGNON MESSAGE.
?INIT: LD HL,INTVECT
LD A,H ;; LADDA INTERRUPT VEKTOR PAGE
LD I,A ;; I Z80 REGISTER I.
LD HL,SIGNON ;; SKRIV 1/2 RAD 1 SIGNON.
CALL ?PMSG
LD HL,?TITEL ;; SKRIV 1/2 RAD 1 SIGNON.
CALL ?PMSG ;; FINNS I DRIVES.Z80
EI ;; SLÅ PÅ INTERRUPTS
RET
;
;**************************** BOOT ********************************
; DSEG
; MESSAGES IN BANK0.
ERRCCP: DEFB 'CCP.COM-error. Press <RET> to retry',0
SIGNON: DEFB CR,LF
DEFB 'CP/M Plus Version 3.0 - JET-',0
;
; DSEG
IF M8
; Define 8" 2x77x8x1024, 256 entries. UNIT A:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH8+UNIT0+DOUBLD
; $FDXSL
DEFB 0 ;
FLA: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAG
DEFW F8D ; ADDRESS T. DPB
DEFW 0FFFEH ; CHECKSUM VECTOR SET BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR SET BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM SETUP
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK
; Define 8" 2x77x8x1024, 256 entries. UNIT B:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH8+UNIT1+DOUBLD
; $FDXSL
DEFB 0 ;
FLB: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAG
DEFW F8D ; ADDRESS T. DPB
DEFW 0FFFEH ; CHECKSUM VECTOR SET BY GENCPM▶8a◀ DEFW 0FFFEH ; ALLOC VECTOR SET BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM SETUP
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK
ENDIF
PAGE
IF M5
; Define 5.25" 2x77x8x1024, 256 entries. UNIT A:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT0+DOUBLD+11000000B
; $FDXSL 2 MHz 8" Mode
DEFB 0 ;
FLA: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAGG
DEFW F5MAX ; ADDRESS TO DPB
DEFW 0FFFEH ; CHECKSUM VECTOR GEN BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR GEN BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM CALC
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK.
; Define 5.25" 2x77x8x1024, 256 entries. UNIT B:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT1+DOUBLD+11000000B
; $FDXSL 2 MHz 8" Mode
DEFB 0 ;
FLB: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAGG
DEFW F5MAX ; ADDRESS TO DPB
DEFW 0FFFEH ; CHECKSUM VECTOR GEN BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR GEN BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM CALC
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK.
ENDIF
PAGE
IF M596D
; Define 5.25" 2x80x5x1024, 128 entries. UNIT A:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT0+DOUBLD
; $FDXSL
DEFB 0 ;
FLA: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAGG
DEFW F596D ; ADDRESS TO DPB
DEFW 0FFFEH ; CHECKSUM VECTOR GEN BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR GEN BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM CALC
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK.
; Define 5.25" 2x80x5x1024, 128 entries. UNIT B:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT1+DOUBLD
; $FDXSL
DEFB 0 ;
FLB: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAGG
DEFW F596D ; ADDRESS TO DPB
DEFW 0FFFEH ; CHECKSUM VECTOR GEN BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR GEN BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM CALC
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK.
ENDIF
PAGE
IF M548D
; Define 5.25" 2x40x5x1024, 128 entries. UNIT A:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT0+DOUBLD
; $FDXSL
DEFB 0 ;
FLA: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAG
DEFW F548D ; ADDRESS T. DPB
DEFW 0FFFEH ; CHECKSUM VECTOR SET BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR SET BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM SETUP
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK
; Define 5.25" 2x40x5x1024, 128 entries. UNIT B:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT1+DOUBLD
; $FDXSL
DEFB 0 ;
FLB: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAG
DEFW F548D ; ADDRESS T. DPB
DEFW 0FFFEH ; CHECKSUM VECTOR SET BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR SET BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM SETUP
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK
ENDIF
PAGE
IF M548S
; Define 5.25" 1x40x5x1024, 64 entries. UNIT A:
DEFW FDWRIT▶8a◀ DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT0+DOUBLD
; $FDXSL
DEFB 0 ;
FLA: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAG
DEFW F548S ; ADDRESS T. DPB
DEFW 0FFFEH ; CHECKSUM VECTOR SET BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR SET BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM SETUP
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK
; Define 5.25" 1x40x5x1024, 64 entries. UNIT B:
DEFW FDWRIT▶8a◀ DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
DEFB INCH5+UNIT1+DOUBLD
; $FDXSL
DEFB 0 ;
FLB: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAG
DEFW F548S ; ADDRESS T. DPB
DEFW 0FFFEH ; CHECKSUM VECTOR SET BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR SET BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM SETUP
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK
ENDIF
PAGE
; Define UNIT C:
; If M8 it is 5.25" 2x80x5x1024, 128 entries
; else 8" 2x77x8x1024, 256 entries.
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
IF M8
DEFB INCH5+UNIT0+DOUBLD ; $FDXSL
ELSE
DEFB INCH8+UNIT0+DOUBLD
ENDIF
DEFB 0 ;
FLC: DEFW 0 ; NO TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAGG
IF M8
DEFW F596D ; ADDRESS TO DPB
ELSE
DEFW F8D
ENDIF
DEFW 0FFFEH ; CHECKSUM VECTOR GEN BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR GEN BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM CALC
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK.
; Define 8" 1x77x26x128, 64 entries (IBM). UNIT D:
DEFW FDWRIT
DEFW FDREAD
DEFW FDLGIN
DEFW FDINIT
IF M8
DEFB INCH8+UNIT1+SINGLD ; $FDXSL
ELSE
DEFB INCH8+UNIT0+SINGLD
ENDIF
DEFB 0 ;
FLD: DEFW TRANS ; TRANS TABLE
DEFB 0,0,0,0,0,0,0,0,0
DEFB 0 ; MEDIAFLAGG
DEFW F8S ; ADDRESS TO DPB
DEFW 0FFFEH ; CHECKSUM VECTOR GEN. BY GENCPM
DEFW 0FFFEH ; ALLOC VECTOR GEN. BY GENCPM
DEFW 0FFFEH,0FFFEH ; LET GENCPM CALC
DEFW 0FFFEH ; DIRBCB, DTABCB, HASH
DEFB 0 ; HASH BANK.
PAGE
;
;
«eof»