|
|
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: 38656 (0x9700)
Types: TextFile
Names: »BIOS.ASM«
└─⟦0d02879d3⟧ Bits:30004605 COMPAS Pascal version 3.03
└─⟦this⟧ »BIOS.ASM«
; CBIOS
;
; COPYRIGHT (C) 1980, 1983 METANIC ApS
;
; THIS IS THE CBIOS (Custom Basic Input Output System)
; USED WITH CP/M 2.2 ON THE MICRO COMPUTER 'MPS 2001'. THIS
; FILE CONTAINS ALL THE HARDWARE DEPENDENT ROUTINES USED
; BY A RUNNING CP/M 2.0 SYSTEM.
;
;
;
PSECT ABS
ORG 000H
;
; CONSTANTS
;
; CP/M DEPENDENT CONSTANTS
MSIZE EQU 60 ; CP/M VERSION MEMORY SIZE
; IN KILOBYTES
;BIAS EQU .RES.(MSIZE-20)*1024 ; ADDRESS CORRECTION FOR
; SYSTEM > 20K
;CCP EQU 3400H+BIAS ; BASE ADDRESS OF CCP
;BDOS EQU CCP+806H ; BASE ADDRESS OF BDOS
;BIOS EQU CCP+1600H ; BASE ADDRESS OF BIOS
CDISK EQU 0004H ; ADDRESS OF CP/M VARIABLE
; HOLDING THE CURRENT
; DISK NO, 0=A,..,15=P
;NSECTS EQU (BIOS-CCP)/128 ; NUMBER OF SECTORS TO
; READ IN DURING A WARM
; START
;NSECT1 EQU (BIOS-CCP)/512 ; NUMBER OF SECTORS TO
CHARGE EQU 5400H ; READ IN DURING RESET
BLOWST EQU 0F000H
; DEBUGGER ADDRESS
ERROR EQU 0038H
; HARDWARE DEPENDENT CONSTANTS
;
;
;
;
; PORT NUMBERS OF THE KEYBOARD
KBPIOC EQU 09DH ; PIO CHANNEL A CONTROL
KBPIOD EQU 09CH ; PIO CHANNEL A DATA
KB89A EQU 0F9H ; 8910 ADDRESS REG.
KB89D EQU 0FAH ; 8910 DATA PORT
;
; PORT NUMBERS FOR PIO AND CENTRONIC PRINTER
PIOBC EQU 9FH ; 03H DISABLES SYNC INTERRUPT
; 83H ENABLES SYNC INTERRUPT
PIOBD EQU 9EH ; BIT 0 INPUT HORIZONTAL SYNC
; BIT 1 OUTPUT CENTRONIC STROBE
; BIT 2 INPUT
; BIT 3 INPUT
; BIT 4 INPUT
; BIT 5 INPUT INTERRUPT LYSPEN
; BIT 6 INPUT ENABLE LYSPEN
; BIT 7 INPUT VERTICAL SYNC
;
; PORT NUMBERS FOR CENTRONICS COMPATIBLE PRINTER
;
LPSP EQU PIOBD
LPDP EQU 0F8H
STROBE EQU 1
EMPTY EQU 10H
BUSY EQU 08
;
;
;
; PORT NUMBERS OF THE CRT
CRTREG EQU 088H ; CRTC REGISTER SELECTOR
CRTDAT EQU 089H ; CRTC DATA PORT
; PORT NUMBERS OF THE FLOPPY DISK CONTROLLER
FDCTC EQU 0C7H ; TERMINAL COUNT PORT
FDCST EQU 0C0H ; MAIN STATUS PORT
FDCDT EQU 0C1H ; DATA PORT
FDCDMA EQU 0C4H ; DMA PORT
FDCMON EQU 0CAH ; MOTOR ON
FDCMOF EQU 0C8H ; MOTOR OFF
;
; PORT NUMBERS FOR THE DART AND THE BAUD RATE GENERATOR
;
BAUD0 EQU 8CH ; RATE GENERATOR FOR SERIAL CHANNEL
BAUD1 EQU 8DH ; RATE GENERATOR FOR TAPE RECORDER
BAUD2 EQU 8EH ; 4800 Hz GENERATOR FOR TAPE RECORDER
BAUDC EQU 8FH ; CONTROL REGISTER
DARTAD EQU 94H ; SERIAL CHANNEL DATA
DARTAC EQU 95H ; SERIAL CHANNEL CONTROL
DARTBD EQU 96H ; TAPE RECORDER DATA
DARTBC EQU 97H ; TAPE RECORDER CONTROL
;
; PORT NUMBERS FOR THE CTC
;
CTC0 EQU 98H
CTC1 EQU 99H
CTC2 EQU 9AH
CTC3 EQU 9BH
;
; PORT NUMBERS OF MEMORY CONTROL
;
RAMBAW EQU 0FFH ; BIT 0 - BANK 0 O.S.V.
; OPENS FOR WRITE ONLY
RAMBAR EQU 0FEH ; OPENS FOR READ ONLY
; BIT = 1 -- BANK OPEN
VIDBAN EQU 0FDH ; OPENS FOR READ AND
; WRITE.
; BIT 0 - ROM BANK 0
; BIT 1 - ROM BANK 1
; BIT 2 - ROM BANK 2
; BIT 3 - ROM BANK 3
; BIT 0-3 READ ONLY
; BIT 4 - RED BANK MAIN
; BIT 5 - GREEN BANK
; BIT 6 - BLUE BANK
; BIT 7 - FLASH
; BIT = 1 -- BANK OPEN
SYSBAN EQU 0FCH ; BIT 7 OPEN AND CLOSE
; ROM BANK READ ONLY
; BIT 7 = 0 OPENS
CH80 EQU 0FBH ; BIT 4 = 1 SET 80
; CHARACTERS/LINE
PIXHO EQU 640 ; PIXELS HORIZONTALLY
PIXVE EQU 240 ; PIXELS VERTICALLY
LINLE EQU PIXHO/8 ; LINE LENGTH IN CHARS
; IF NOT PROPORTIONAL SPACING
MAXLINESPACE EQU 36 ; MAX LINESPACE
MAXSPACEW EQU 8 ; MAX SPACEWIDTH
MAXCHARDIST EQU 16 ; MAX CHARDIST
MASKLEN EQU (7+MAXCHARDIST+MAXSPACEW+15+7)/8
ESC EQU 1BH
CR EQU 0DH
LF EQU 0AH
CURUP EQU 0BH
CURRIG EQU 0CH
CURLEF EQU 08H
CURHOM EQU 1EH
; TIME CONSTANTS
SRT EQU 0EH ; STEP RATE TIME.
; CAN BE 1,2,3..16 MS
HUT EQU 15 ; HEAD UNLOAD TIME
; CAN BE 0,16,32..240 MS
HLT EQU 13 ; HEAD LOAD TIME
; CAN BE 2,4,6..256 MS
; DMA/NON-DMA SELECTION CONSTANT
ND EQU 1 ; NON-DMA (0=DMA)
; DISK FORMAT CONSTANTS
EOT EQU 0AH ; NO. OF THE LAST SECTOR
; ON EACH TRACK
GPL EQU 07 ; GAP LENGTH CONSTANT
DTL EQU 00 ; BYTES PER SECTOR
N EQU 02 ; SECTOR LENGTH INDICATOR
;
; CP/M TO HOST DISK CONSTANTS
;
BLKSIZ EQU 1024 ; CP/M ALLOCATION SIZE
HSTSIZ EQU 512 ; HOST DISK SECTOR SIZE
HSTSPT EQU 10 ; HOST DISK SECTORS/TRK
HSTBLK EQU HSTSIZ/128 ; CP/M SECTS/HOST BUFFER
CPMSPT EQU HSTBLK*HSTSPT ; CP/M SECTORS/TRACK
SECMSK EQU HSTBLK-1 ; SECTOR MASK
;
; BDOS CONSTANTS ON ENTRY TO WRITE
;
WRALL EQU 0 ; WRITE TO ALLOCATED
WRDIR EQU 1 ; WRITE TO DIRECTORY
WRUAL EQU 2 ; WRITE TO UNALLOCATED
; DELAY CONSTANT USED IN COMMAND AND READRESULT
DELAYCNT EQU 40H
; MAXIMUM NUMBER OF RE-READS/RE-WRITES
MAXREPEATS EQU 10
;
; RAM AREA FILLED WITH DATA AFTER RESET
;
;
; ORIGIN
;
ORG 0000H ; START ADDRESS IN ROM
STARTC:
LD SP,DIRBF+50 ; SET STAK. CP/M NOT RUNNING
LD A,0FFH
STA3: DEC A
JR NZ,STA3
LD (SYBAN),A
LD (RAMRD),A ; SET BANK VARIABLES
LD (RAMWR),A
LD (VIDROM),A
LD (INSAVE),A
LD HL,BLOWUP
LD DE,BLOWST
LD BC,ASCTAB-BLOWUP
LDIR
CALL INTINI
CALL CRTINI
CALL CTCINI
CALL PIOINI
CALL DARINI
LD A,(SNR)
LD (SNR1),A
LD A,(SNR+2)
LD (SNR1+1),A
LD A,(SNR+3)
LD (SNR1+2),A
START1: LD HL,FUNCST
LD DE,FBUF
LD BC,FUNCS1-FUNCST
LDIR
LD HL,MSGC ; SAY HELLO
CALL OUTTX
STAR5: EI ; START INTERRUPT
CALL CONIN ; READ KEYBOARD
; DI
CP 27
JP Z,CONFIG
CP 0DH
JR NZ,STAR5
LD C,A ; C := A
CALL CONOUT ; ECCO
STAR6: LD C,0AH ; SEND LF
CALL CONOUT
CPM:
STAR10: CALL READRESULT ; CLEAR 765
LD A,01
OUT (RAMBAW),A ; OPEN RAM FOR WRITE
LD (RAMWR),A
XOR A
LD (CDISK),A
LD (HSTACT),A
LD (UNACNT),A
LD (SEKDSK),A
STAR11: CALL MOTORS
LD HL,SPECIO+OFFSET
CALL COMMAND
CALL STAR12
JR STAR15
STAR12: XOR A
LD (HSTDSK),A
LD (SEEKTR+OFFSET),A
LD (SEEKNO+OFFSET),A
LD (RECANO+OFFSET),A
LD (RDTR+OFFSET),A
LD (RDTR+OFFSET+1),A
LD (RDNO+OFFSET),A
CALL HOME
XOR A
LD (DISKNO),A
LD (HSTTRK),A
LD (HSTTRK+1),A
RET
STAR15: LD BC,100H ; READ CP/M INTO 100H
LD A,10
LD (RDEOT+OFFSET),A
DI
CALL RTRACK ; READ TRACK ZERO
EI
OR A
JR NZ,STAR17 ; NOT METANIC OR HH
LD DE,HSTBUF ; CHECK FORMAT ROUTINE
LD HL,STAR30
LD BC,STAR40-STAR30
LDIR
LD HL,100H ;
CALL HSTBUF ; (STAR30)
LD A,B
CP 0C3H ; METANIC FORMAT?
JR Z,READ96
LD HL,100H+512
CALL HSTBUF ; (STAR30)
LD A,B
CP 0C3H ; HH FORMAT
JP Z,READ97
LD HL,TEXT6
CALL OUTTX
JP START1
STAR17:
LD A,02 ; MOVE HEAD TO TRACK 1
LD (SEEKTR+OFFSET),A
LD HL,SEEKCO+OFFSET
CALL COMMAND
CALL ENDSEEK ;
LD A,01 ; UPDATE VARIABLES
LD (RDTR+OFFSET),A
LD A,09
LD (RDEOT+OFFSET),A
LD BC,100H ; READ CP/M INTO 100H
DI
CALL RTRAC1
EI
OR A
JP NZ,STAR10
LD HL,STAR30
LD DE,HSTBUF
LD BC,STAR40-STAR30
LDIR
LD HL,100H ; CHECK FOR SYSTEM
CALL HSTBUF ; (STAR30)
LD A,B
CP 0C3H
JP Z,READ98 ; SYSTEM OK. PROCEED
LD HL,TEXT6 ; NO SYSTEM. TELL USER
CALL OUTTX ; AND GO BACK.
JP START1
READ96: INC HL ; FIND START OF CCP
INC HL
CALL HSTBUF ; (STAR30)
LD A,B
SUB 03
LD (CCPSTO+1),A
LD B,A
CALL CPMSIZ
XOR A
LD (CCPSTO),A
LD A,1 ; READ TRACK 1
LD (RDTR+OFFSET),A
LD (RDTR+1+OFFSET),A
LD A,4
LD (RDNO+OFFSET),A
LD BC,100H+512*10
DI
CALL RTRACK ; READ REST
EI
LD HL,100H+512*11 ; SECTOR 12 AND SECTOR 13
CALL HSTBUF ; FIRST INITIALIZATION
LD A,B ; PROGRAM
OR A
CALL Z,INIT1
LD HL,STAR40
LD DE,HSTBUF
LD BC,STAR50-STAR40
LDIR
LD HL,100H
LD DE,(CCPSTO)
LD BC,512*11
CALL HSTBUF ; (STAR40)
XOR A
LD (DISKFO+OFFSET),A
LD HL,DPBLK0+OFFSET
LD (DPBAS0+OFFSET+10),HL
LD DE,DIRBF
LD HL,STAR30
LD BC,STAR40-STAR30
LDIR
LD HL,100H+512*19
CALL DIRBF
LD A,B
OR A
JP NZ,GOCPMC
LD HL,STAR40
LD DE,DIRBF
LD BC,STAR50-STAR40
LDIR
LD HL,100H+512*19 ; MOVE INIT.SECTOR
LD DE,HSTBUF
LD BC,512
CALL DIRBF
LD A,(HSTBUF+3) ; TEST FOR DISK FORMAT
OR A
JR NZ,INI1
LD HL,HSTBUF+11H
LD DE,DISKFO+1+OFFSET
LD BC,7
LDIR
LD HL,DISKFO+1+OFFSET
LD B,3
LD C,0 ; DISK NO
R0: INC C
PUSH BC
R1: LD A,(HL)
INC HL
OR A
JR Z,R1A ; NOTHING TO MOVE
PUSH HL ; SAVE ADDRESS IN DISKFO
LD HL,DPBLK0+OFFSET
LD DE,DPBLK1-DPBLK0
R2: ADD HL,DE ; CALCULATE ADDRESS
DEC A
JR NZ,R2
PUSH HL ; SAVE ADDRESS DPBLK?
LD HL,DPBAS0+OFFSET
LD DE,DPBAS1-DPBAS0
LD B,C
R3: ADD HL,DE
DEC C
JR NZ,R3
LD C,B
LD DE,10
ADD HL,DE
POP DE ; RECOVER ADDRESS DPBLK?
LD A,E
LD (HL),A
INC HL
LD A,D
LD (HL),A
POP HL ; RECOVER ADDRESS IN DISKFO
R1A: POP BC ; RECOVER COUNTER
DJNZ R0
INI1: LD A,(HSTBUF+20H)
OR A
JR NZ,INI2
LD BC,(HSTBUF+21H)
LD A,00110100B
OUT (BAUDC),A
LD A,C
OUT (BAUD0),A
LD A,B
OUT (BAUD0),A
INI2:
LD A,(HSTBUF+1)
CP 40
JR NZ,INI2A
LD HL,TX7
CALL OUTTX
JR INI3
INI2A: CP 80
JR NZ,INI3
LD HL,TX8
CALL OUTTX
INI3:
LD A,(HSTBUF+2)
OR A
JR NZ,INI5
LD HL,HSTBUF+80
LD DE,FBUF
LD BC,80H
LDIR
INI5:
LD HL,INI8
PUSH HL
LD A,(HSTBUF+6)
CP 'N'
JR NZ,INI6
JR INISER
INI6: CP 'U'
JR NZ,INI7
JR INISER
INI7: CP 'L'
JR NZ,INI7A
JR INISER
INI7A: POP HL
INI8:
LD HL,INI10
PUSH HL
LD A,(HSTBUF+7)
CP 'O'
JR NZ,INI9
JR INISER
INI9: CP 'S'
JR NZ,INI9A
JR INISER
INI9A: POP HL
INI10: LD HL,INI12
PUSH HL
LD A,(HSTBUF+8)
CP '0'
JR NZ,INI11
JR INISER
INI11: CP '1'
JR NZ,INI11A
JR INISER
INI11A: POP HL
INI12: LD A,(HSTBUF+9)
CP 0
JR Z,INI12A
CP 1
JR Z,INI12A
JR INI13
INI12A: LD (PRINTE),A
LD A,(HSTBUF+10)
OR A
JR NZ,INI13
LD A,(HSTBUF+11)
LD (MODE),A
INI13:
LD A,(HSTBUF+4) ; TEST FOR START PROGRAM
OR A
JR NZ,INI14
LD A,(HSTBUF+80+80H)
INC A
LD C,A
LD B,0
LD HL,(CCPSTO)
LD DE,7
ADD HL,DE
EX DE,HL
LD HL,HSTBUF+80+80H
DI
LD A,01
OUT (RAMBAW),A
LD (RAMWR),A
LDIR
XOR A
LD (DE),A
INI14:
LD A,(HSTBUF+5)
LD (TASTBU),A
JP GOCPMC
INISER: PUSH AF
LD C,27
CALL CONOUT
LD C,'b'
CALL CONOUT
POP AF
LD C,A
CALL CONOUT
RET
TX7: DEFB 27,'4',0
TX8: DEFB 27,'8',0
READ97: ; HH FORMAT
INC HL
INC HL
CALL HSTBUF ; STAR30
LD A,B
SUB 03
LD (CCPSTO+1),A
LD B,A
CALL CPMSIZ
XOR A
LD (CCPSTO),A
LD A,02
LD (SEEKTR+OFFSET),A
LD HL,SEEKCO+OFFSET
CALL COMMAND
CALL ENDSEEK
LD A,01
LD (RDTR+OFFSET),A
LD BC,100H+512*10
DI
CALL RTRACK
EI
LD HL,STAR40
LD DE,HSTBUF
LD BC,STAR50-STAR40
LDIR
LD HL,100H+512
LD DE,(CCPSTO)
LD BC,512*11
CALL HSTBUF ; STAR40
LD A,1
LD (DISKFO+OFFSET),A
LD HL,DPBLK1+OFFSET
LD (DPBAS0+OFFSET+10),HL
JP GOCPMC
READ98: INC HL ; FIND SIZE OF SYSTEM
INC HL
CALL HSTBUF ; (STAR30)
LD A,B ; HIGH BYTE IN B
SUB 3 ; REMOVE OFFSET
LD (CCPSTO+1),A ; STORE FOR LATER
LD B,A
CALL CPMSIZ ; TELL THE USER THE SYSTEM SIZE
XOR A ; SET LOW BYTE OF SYSTEM
LD (CCPSTO),A
LD A,04 ; MAKE READY FOR READING 2. TRACK
LD (RDNO+OFFSET),A ; SIDE 1
LD A,01 ; TRACK 1
LD (RDTR+OFFSET),A
LD (RDTR+OFFSET+1),A ; HEAD 1
LD BC,100H+512*9 ; NEXT MEMORY POSITION
DI
CALL RTRAC1 ; READ REST (2 SECTORS ONLY VALID)
EI
OR A
JP NZ,ERROR
LD HL,STAR50 ; MAKE READY TO MOVE INTO POSITION
LD DE,HSTBUF
LD BC,STAR70-STAR50
LDIR ; BLOW THE ROUTINE INTO HSTBUF
CALL HSTBUF ; CALL STAR50
LD A,02 ; SET DISK FORMAT
LD (DISKFO+OFFSET),A
LD HL,DPBLK2+OFFSET
LD (DPBAS0+OFFSET+10),HL
JP GOCPMC ; START CP/M
STAR30: DI
LD A,80H
OUT (SYSBAN),A ; CLOSE ROM
LD A,01
OUT (RAMBAR),A ; OPEN RAM FOR READ
LD A,(HL)
LD B,A
XOR A
OUT (RAMBAR),A ; CLOSE RAM
OUT (SYSBAN),A ; OPEN ROM
EI
RET
STAR40:
LD A,80H ; CLOSE ROM
OUT (SYSBAN),A
LD A,01
OUT (RAMBAR),A ; OPEN RAM FOR READ AND
OUT (RAMBAW),A
LDIR
XOR A
OUT (RAMBAR),A ; CLOSE RAM
OUT (RAMBAW),A
OUT (SYSBAN),A ; OPEN ROM
RET
STAR50:
LD A,80H ; CLOSE SYSTEM BANK
OUT (SYSBAN),A
LD A,01 ; OPEN RAM FOR READ
OUT (RAMBAR),A ; AND WRITE
OUT (RAMBAW),A
XOR A ; COUNTER
LD DE,(CCPSTO) ; START OF CCP
STAR55: LD HL,STAR60-STAR50+HSTBUF ; SKEW TABLE
LD B,0 ; BC := A
LD C,A
ADD HL,BC ; START OF TABLE+ACTUAL ENTRY
PUSH AF ; SAVE AF
LD A,(HL) ; GET ACTUAL SECTOR
LD B,A ; MOVE TO B
POP AF ; RECOVER AF
LD HL,100H-512 ; OFFSET FOR HL
PUSH DE ; SAVE DE
LD DE,512 ; SIZE OF SECTOR
STAR57: ADD HL,DE ; CALCULATE ADDRESS
DJNZ STAR57 ; UNTIL B := 0
POP DE ; DESTINATION ADDRESS
LD BC,512 ; SIZE OF SECTOR
LDIR ; MOVE
INC A ; MAKE READY FOR NEXT SECTOR
CP 09H ; LAST ON SIDE 0
JR NZ,STAR55 ; NO
LD HL,100H+512*9 ; MOVE FIRST SECTOR ON SIDE 1
LD BC,512 ; SIZE
LDIR
LD HL,100H+512*11 ; MOVE SECOND SECTOR
LD BC,512 ; SIZE
LDIR
XOR A ; OPEN SYSTEM AND CLOSE
OUT (RAMBAW),A
OUT (RAMBAR),A
OUT (SYSBAN),A
RET
STAR60:
STAR70:
CPMSIZ: PUSH BC
LD C,0DH
CALL CONOUT
LD C,0AH
CALL CONOUT
POP BC
LD A,B
RRCA ; /2
RRCA ; /4
ADD A,07 ; CALCULATE CP/M SIZE
LD B,0
CPMS10: SUB 10
JR C,CPMS20
INC B
JR CPMS10
CPMS20: PUSH AF
LD A,B
ADD A,30H
LD C,A
CALL CONOUT
POP AF
ADD A,3AH
LD C,A
CALL CONOUT
LD HL,MSGC3
JP OUTTX
RTRAC1: LD HL,READ9
PUSH HL
LD H,B
LD L,C
LD BC,512*9 ; NO OF BYTES
JR STAR19
RTRACK: LD HL,READ9
PUSH HL
LD H,B
LD L,C
LD BC,512*10 ; NO OF BYTES
STAR19: LD D,0A0H
EXX
LD HL,READTR+OFFSET
CALL COMMAND ; READ TRACK ZERO
EXX
STAR20:
IN A,(FDCST)
AND D
JP P,STAR20
RET PO
IN A,(FDCDT)
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JP NZ,STAR20
RET
READ9: OUT (FDCTC),A
CALL READRESULT ; READ OK
LD HL,RESULT
LD A,(HL)
CP 7
JP NZ,STAR11
INC HL
LD B,2
LD A,(HL)
AND 11111000B
READ95: INC HL
OR (HL)
DJNZ READ95
RET Z ; READ OK
LD A,0FFH
RET
OUTTX: LD A,(HL)
OR A
RET Z
LD C,A
PUSH HL
CALL CONOUT
POP HL
INC HL
JR OUTTX
CONFIG:
EI
CALL READRESULT
CALL MOTORS
LD HL,SPECIO+OFFSET
CALL COMMAND
CALL STAR12
LD A,1
LD (HSTTRK),A
LD (HEADNO+OFFSET),A
LD A,10
LD (SECTOR),A
LD A,46H
LD (IOCMD+OFFSET),A
XOR A
LD (HSTDSK),A
CALL IOSEC
OR A
JR Z,CONF01
LD HL,TX6
CALL OUTTX
LD HL,TX6A
CALL OUTTX
JP START1
TX6: DEFB 0DH,0AH,27,'I'
DEFM 'INITIALISERINGSSEKTOR KAN IKKE '
DEFB 0
TX6A: DEFM 'LÆSES!'
DEFB 27,'i'
DEFB 0DH,0AH,0
CONF01: LD A,(HSTBUF+2)
OR A
JR NZ,CONF02
LD HL,HSTBUF+80
LD DE,FBUF
LD BC,80H
LDIR
CONF02: LD HL,MSGC1
CALL OUTTX
CALL CONIN
LD C,A
PUSH AF
CALL CONOUT
POP AF
CP 31H ; TEST FOR DISK FORMAT
JP Z,CONF10
CP 32H ; TEST FOR TIME SET
JP Z,CONF20
CP 33H
JP Z,CONF30 ; SET SERIAL CHANNEL
CP 34H
JP Z,CONF40
CP 35H ; SET FUNCTION KEYS
JP Z,FUNTA
CP 36H
JP Z,AUTOST ; AUTOSTART PROGRAM
CP 37H
JP Z,TASBUF
CP 38H
JP Z,VALGPR
CP 39H
JP Z,SLETIN ; CLEAR INISECTOR
CP 0DH
JP Z,CONF05
JR CONF01
CONF05:
LD HL,MSGC2
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
AND 01011111B
CP 'J'
JR Z,CONF06
CP 'N'
JR NZ,CONF05
CONF03: LD C,27
CALL CONOUT
LD C,'*'
CALL CONOUT
JP START1
CONF06: XOR A
LD (HSTBUF),A ; INIT.SECTOR ACTIVE
CALL MOTORS
LD HL,SPECIO+OFFSET
CALL COMMAND
CALL STAR12
LD A,1
LD (HSTTRK),A
LD (HEADNO+OFFSET),A
LD A,10
LD (SECTOR),A
LD A,45H
LD (IOCMD+OFFSET),A
XOR A
LD (HSTDSK),A
CALL IOSEC
OR A
JR Z,CONF03
LD HL,TX6
CALL OUTTX
LD HL,TX3
CALL OUTTX
JP START1
TX3:
DEFM 'SKRIVES!'
DEFB 27,'i',0DH,0AH
DEFB 0
CONF10: LD HL,TEXT3
CALL OUTTX
CALL CONIN ; GET FORMAT
PUSH AF ; SAVE FORMAT
LD C,A
CALL CONOUT ; TELL THE USER
POP AF ; RECOVER FORMAT
AND 00000011B
DEC A ; NOW 0 := METANIC
; 1 := 40 TRACK SINGLE
; 2 := 40 TRACK DUAL
PUSH AF ; SAVE FORMAT
LD HL,TEXT4
CALL OUTTX
CALL CONIN ; GET DISK NO
PUSH AF ; SAVE DISK NO
LD C,A
CALL CONOUT ; TELL THE USER
POP AF ; RECOVER DISK NO
AND 00000011B ;
LD C,A ; C := DISK NO
LD HL,DISKFO+OFFSET
LD E,A
LD D,0
ADD HL,DE
POP AF ; RECOVER FORMAT
LD (HL),A ; SAVE IN TABLE
LD B,A ; B := FORMAT
LD A,C
LD HL,DPBAS0+OFFSET
LD DE,DPBAS1-DPBAS0
OR A
CONF14: JR Z,CONF12
ADD HL,DE
DEC A
JR CONF14
CONF12: LD DE,10
ADD HL,DE
PUSH HL
LD HL,DPBLK0+OFFSET
LD DE,DPBLK1-DPBLK0
LD A,B
OR A
CONF18: JR Z,CONF16
ADD HL,DE
DEC A
JR CONF18
CONF16: EX DE,HL
POP HL
LD A,E
LD (HL),A
INC HL
LD A,D
LD (HL),A
LD HL,TEXT5
CALL OUTTX
CALL CONIN
AND 01011111B
CP 01001010B
JR Z,CONF10
XOR A
LD (HSTBUF+3),A ; DISK FORMAT TABLE ACTIVE
LD HL,DISKFO+OFFSET
LD DE,HSTBUF+10H
LD BC,8
LDIR
JP CONF01
CONF20: LD HL,TX1 ; SET TIME
CALL OUTTX
LD HL,TIMBUF+OFFSET
LD B,12
XOR A
CONF21: LD (HL),A
INC HL
DJNZ CONF21
LD HL,TIMBUF+OFFSET
LD B,12
CONF22: PUSH HL ; SAVE TIMBUF
PUSH BC ; SAVE B
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
CP 0DH
JR Z,CONF24
CP '-'
JR Z,CONF23
CP 30H
JR C,CONF29
CP 3AH
JR NC,CONF29
CONF23: POP BC
POP HL
LD (HL),A
INC HL
DJNZ CONF22
PUSH HL
PUSH BC
CONF24: POP BC
POP HL
LD HL,TIMBUF+OFFSET
CALL CONF25
LD (HOUR),A
LD HL,TIMBUF+3+OFFSET
CALL CONF25
LD (MINUTE),A
LD HL,TIMBUF+6+OFFSET
CALL CONF25
LD (SECOND),A
CON24: LD HL,TX2
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
AND 01011111B
CP 'J'
JR Z,CONF28
CP 'N'
JR Z,CON28
JR CON24
CONF28: LD A,0FFH
LD (VISF),A
JP CONF01
CON28: XOR A
LD (VISF),A
JP CONF01
CONF25: LD A,(HL)
SUB 30H
OR A
LD B,A
JR Z,CONF27
LD A,0
CONF26: ADD A,10
DJNZ CONF26
LD B,A
CONF27: INC HL
LD A,(HL)
SUB 30H
ADD A,B
RET
CONF29: POP BC
POP HL
JP CONF20
TX1: DEFB 27,'*'
DEFB 0DH,0AH,0AH
DEFM 'Angiv tiden på formen: TT-MM-SS'
DEFB 0DH,0AH
DEFM 'afslut med RETURN'
DEFB 0DH,0AH
DEFM '? '
DEFB 0
TX2: DEFB 0DH,0AH,0AH
DEFM 'Skal tiden vises (J/N) ? '
DEFB 0
CONF30: LD HL,TX4 ; SET SERIAL CHANNEL
CALL OUTTX
CONF31: CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
CP 32H
JP C,CONF39
CP 3AH
JP NC,CONF39
SUB 30H
ADD A,A
LD HL,BAUDTA
LD C,A
LD B,0
ADD HL,BC
LD A,00110100B
OUT (BAUDC),A
LD A,(HL)
LD C,A
OUT (BAUD0),A
INC HL
LD A,(HL)
LD B,A
OUT (BAUD0),A
XOR A
LD (HSTBUF+20H),A
LD (HSTBUF+21H),BC ; SAVE FOR INIT.SECTOR
CONF33: LD HL,TXI6
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
AND 01011111B
CP 'N'
JR Z,CONF35
CP 'J'
JR NZ,CONF33
CONF34: LD HL,TXI7
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
AND 01011111B
CP 'L'
JR Z,CONF35
CP 'U'
JR NZ,CONF34
CONF35: PUSH AF
LD C,27
CALL CONOUT
LD C,'b'
CALL CONOUT
POP AF
LD (HSTBUF+6),A ; I, U OR L
LD C,A
CALL CONOUT
CONF36: LD HL,TXI8
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
AND 01011111B
CP 'S'
JR Z,CONF37
CP 'O'
JR NZ,CONF36
CONF37: PUSH AF
LD C,27
CALL CONOUT
LD C,'b'
CALL CONOUT
POP AF
LD (HSTBUF+7),A ; S OR O
LD C,A
CALL CONOUT
CON37: LD HL,TXI9
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
CP '0'
JR Z,CONF38
CP '1'
JR NZ,CON37
CONF38: PUSH AF
LD C,27
CALL CONOUT
LD C,'b'
CALL CONOUT
POP AF
LD (HSTBUF+8),A ; 0 OR 1
LD C,A
CALL CONOUT
JP CONF01
CONF39: LD HL,TX5
CALL OUTTX
JP CONF31
TX4: DEFB 27,'*'
DEFB 0DH,0AH
DEFM 'Der kan vælges mellem følgende'
DEFB 0DH,0AH
DEFM 'baudrate for seriekanalen:'
DEFB 0DH,0AH,0AH
DEFM '2. 19.200 BAUD'
DEFB 0DH,0AH
DEFM '3. 9.600 "'
DEFB 0DH,0AH
DEFM '4. 4.800 "'
DEFB 0DH,0AH
DEFM '5. 2.400 "'
DEFB 0DH,0AH
DEFM '6. 1.200 "'
DEFB 0DH,0AH
DEFM '7. 600 "'
DEFB 0DH,0AH
DEFM '8. 300 "'
DEFB 0DH,0AH
DEFM '9. 110 "'
TX5: DEFB 0DH,0AH,0AH
DEFM 'Hvilken ( 2 - 9 ) ønskes ? '
DEFB 0
TXI6: DEFB 27,'*',0AH,0AH
DEFM 'Skal der være paritet (J/N) ? '
DEFB 0
TXI7: DEFB 0DH,0AH,0AH
DEFM 'Lige eller ulige (L/U) ? '
DEFB 0
TXI8: DEFB 0DH,0AH,0AH
DEFM 'Skal der være 7 eller 8 databit (S/O) ? '
DEFB 0
TXI9: DEFB 0DH,0AH,0AH
DEFM 'Skal "BUSY" linien være aktiv høj eller lav (1/0) ? '
DEFB 0
CONF40: LD HL,TX9 ; SET SCREEN
CALL OUTTX
CALL CONIN
PUSH AF
LD C,A
CALL CONOUT
POP AF
CP 34H
JR NZ,CONF42
LD A,40
LD (HSTBUF+1),A
JP CONF01
CONF42: CP 38H
JR NZ,CONF40
LD A,80
LD (HSTBUF+1),A
JP CONF01
TX9: DEFB 27,'*'
DEFB 0DH,0AH
DEFM 'Skal skærmen arbejde med 40'
DEFB 0DH,0AH
DEFM 'eller 80 tegn i bredden ? '
DEFB 0DH,0AH
DEFM 'Angiv 4 eller 8: '
DEFB 0
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE DELAY
;
; PARAMETRE IND: A = ANTAL PERIODER A 5 MS, DER SKAL
; VENTES
; PARAMETRE UD : INGEN
;
; BRUGER AF
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY: PUSH DE ; STAK DE
DELAY1: LD E,30 ; REPEAT E := 30
DELAY2: LD D,22 ; REPEAT D := 22
DELAY3: DEC D ; REPEAT D := D-1
JR NZ,DELAY3 ; UNTIL D := 0
; (NU ER DER GAAET
; 166,5 MS)
DEC E ; E := E-1
JR NZ,DELAY2 ; UNTIL E = 0
; (NU ER DER GAAET 5 MS)
DEC A
JR NZ,DELAY1
POP DE
RET
MSGC:
DEFB 0DH,0AH
DEFM 'BUTLER operativsystem v. '
SNR: DEFM '1.30'
DEFB 0DH,0AH,0AH
DEFM 'Indsæt en CP/M systemdisk i det øverste'
DEFB 0DH,0AH
DEFM 'diskdrev og tryk på "RETURN"'
DEFB 0
MSGC1: DEFB 27,'*',0AH,0AH
DEFM 'Konfigurerings mode'
DEFB 0DH,0AH,0AH
DEFM '* 1. Diskformater'
DEFB 0DH,0AH
DEFM ' 2. Indstilling af ur'
DEFB 0DH,0AH
DEFM '* 3. Indstilling af seriekanal'
DEFB 0DH,0AH
DEFM '* 4. Antal tegn på skærmen'
DEFB 0DH,0AH
DEFM '* 5. Streng til funktionstaster'
DEFB 0DH,0AH
DEFM '* 6. Autostart'
DEFB 0DH,0AH
DEFM '* 7. Tastaturbuffer'
DEFB 0DH,0AH
DEFM '* 8. Valg af printer'
DEFB 0DH,0AH
DEFM '* 9. Slet initialiseringssektor'
DEFB 0DH,0AH,0AH
DEFM 'Tryk "RETURN" for normal opstart'
DEFB 0DH,0AH,0AH
DEFM 'Hvilken funktion skal udføres? '
DEFB 0
MSGC2: DEFB 0DH,0AH,0AH
DEFM 'Skal de med "*" mærkede muligheder'
DEFB 0DH,0AH
DEFM 'udskrives på disken (J/N) ? '
DEFB 0
MSGC3: DEFM ' K CP/M system'
DEFB 0DH,0AH,0AH,00
TEXT3: DEFB 27,'*',0AH
DEFM 'Der kan vælges mellem følgende formater:'
DEFB 0DH,0AH,0AH
DEFM '1. Dobbeltsidet 80 spor'
DEFB 0DH,0AH,0AH
DEFM '2. Enkeltsidet 40 spor'
DEFB 0DH,0AH,0AH
DEFM '3. Dobbeltsidet 40 spor'
DEFB 0DH,0AH,0AH
DEFM 'Hvilket format ( 1 - 3 ) ? '
DEFB 0
TEXT4: DEFB 0DH,0AH,0AH
DEFM 'Hvilket diskdrev ( 0 - 3 ) ? '
DEFB 0
TEXT5: DEFB 0DH,0AH,0AH
DEFM 'Flere (J/-) ? '
DEFB 0
TEXT6: DEFB 0AH
DEFM 'Drev 0 (A:) indeholder ikke en CP/M systemdisk!'
DEFB 0DH,0AH,0
; EJECT
TITLE JUMP VECTOR AND TABLES
;
; THE JUMP VECTOR WHICH ESTABLISHES THE CONNECTION
; BETWEEN BDOS AND CBIOS
;
JTAB: JP BOOT ; COLD START
WBOOTE: JP WBOOT ; WARM START
JP CONST ; RETURN CONSOLE STATUS
JP CONIN ; CONSOLE CHARACTER IN
JP CONOUT ; CONSOLE CHARACTER OUT
JP LIST ; LIST CHARACTER OUT
JP PUNCH ; PUNCH CHARACTER OUT
JP READER ; READER CHARACTER IN
JP HOME ; MOVE DISK HEAD TO HOME
; POSITION
JP SELDSK ; SELECT DISK
JP SETTRK ; SET TRACK NO
JP SETSEC ; SET SECTOR NO
JP SETDMA ; SET DMA ADDRESS
JP READ ; READ DISK
JP WRITE ; WRITE DISK
JP LISTST ; RETURN LIST STATUS
JP SECTRAN ; SECTOR TRANSLATE
JVEC0:
;
; SECTOR TRANSLATE VECTOR
;
TR1:
TR0: DEFB 1,04,07,0AH ; SECTORS 1-4
DEFB 03,06,09,02 ; SECTORS 5-8
DEFB 05,08 ; SECTORS 9-10
RCSYFO:
TR2: DEFB 1,3,5,7
DEFB 9,2,4,6
DEFB 8
; EJECT
; TITLE BOOT, WBOOT
;
; BOOT - COLD START AFTER SYSTEM LOAD
;
BOOT: ; SIMPLEST CASE IS TO JUST
; PERFORM PARAMETER
LD SP,DIRBF+50
LD HL,SPECIO+OFFSET
CALL COMMAND ; COMMAND(SPECIFY)
LD A,01
OUT (RAMBAW),A ; OPEN RAM FOR WRITE
LD (RAMWR),A
XOR A
LD (CDISK),A
LD (HSTACT),A ; HOST BUFFER INACTIVE
LD (UNACNT),A ; CLEAR UNALLOC COUNT
LD HL,000H
CALL OUTRFRSH ; OUTRFRSH(0)
; CALL OUTCUR
JP GOCPMW ; INIT AND GO TO CP/M
;
; WBOOT - WARM START, THAT IS, RELOAD THE CCP AND BDOS
;
WBOOT: ; SIMPLEST CASE IS TO READ
; THE DISK UNTIL ALL
; SECTORS HAVE BEEN READ
LD SP,DIRBF+50 ; SET UP STACK - CP/M IS
; NOT RUNNING, SO DIRBUF
; IS FREE
XOR A
LD (HSTACT),A
LD (UNACNT),A
LD HL,SPECIO+OFFSET
CALL COMMAND ; COMMAND(SPECIFY)
LD C,0 ; SELECT DISK 0
CALL SELDSK
CALL HOME
;
; NOW, READ IN THE CP/M SYSTEM. IT STARTS AT TRACK 00,
; SECTOR 2 (SECTOR 1 CONTAINS THE COLD START LOADER).
; THE LENGTH IS 'NSECTS' BLOCKS.
;
; WHEN THE READ-IN STARTS, DISK 0 IS SELECTED AND
; RECALIBRATED (SET TO TRACK 0)
;
DI
LD A,1 ; OPEN RAM FOR WRITE
OUT (RAMBAW),A
LD (RAMWR),A
CALL MOTORS
CALL STAR12
LD A,10
LD (RDEOT+OFFSET),A
LD BC,(CCPSTO)
DI
CALL RTRACK
EI
OR A
JR NZ,WBOO10 ; NOT METANIC OR HH
LD DE,HSTBUF ; CHECK FORMAT ROUTINE
LD HL,STAR30
LD BC,STAR40-STAR30
LDIR
LD HL,(CCPSTO) ;
CALL HSTBUF ; (STAR30)
LD A,B
CP 0C3H ; METANIC FORMAT?
JP Z,WBOO20 ; YES
LD DE,512
ADD HL,DE
CALL HSTBUF ; (STAR30)
LD A,B
CP 0C3H ; HH FORMAT
JP Z,WBOO30
LD HL,TEXT6
CALL OUTTX
JP START1
WBOO10:
XOR A
LD (HSTDSK),A
LD (SEEKNO+OFFSET),A
LD (HEADNO+OFFSET),A
INC A
LD (HSTTRK),A
INC A
LD (SEEKTR+OFFSET),A
LD (DISKFO+OFFSET),A
LD A,09H ; NO OF LAST SECTOR
LD (IOEOT+OFFSET),A
LD A,46H
LD (IOCMD+OFFSET),A
LD B,0BH ; NO OF SECTORS
LD C,0 ; SECTOR COUNTER
LD DE,(CCPSTO)
WBOO15: PUSH BC
PUSH DE
LD HL,RCSYFO
LD B,0
ADD HL,BC
LD A,(HL)
LD (SECTOR),A
CALL IOSEC
OR A
POP DE
POP BC
JR NZ,WBOO15
PUSH BC
LD HL,HSTBUF
LD BC,512
LDIR
POP BC
DEC B
JR Z,RCFUS
INC C
LD A,C
CP 09H
JR C,WBOO15
LD C,0
LD A,1
LD (HEADNO+OFFSET),A
JP WBOO15
RCFUS: LD HL,STAR30
LD DE,HSTBUF
LD BC,STAR40-STAR30
LDIR
LD HL,(CCPSTO)
CALL TESTSY
JP GOCPMW
WBOO20:
CALL TESTSY ; METANIC FORMAT
WBOO21: XOR A
LD (HSTDSK),A
LD (SEEKTR+OFFSET),A
LD (SEEKNO+OFFSET),A
LD (DISKFO+OFFSET),A
INC A
LD (HSTTRK),A
LD (SECTOR),A
LD (HEADNO+OFFSET),A
LD A,46H
LD (IOCMD+OFFSET),A
CALL IOSEC
LD HL,(CCPSTO)
LD DE,10*512
ADD HL,DE
EX DE,HL
LD HL,HSTBUF
LD BC,512
LDIR
JP GOCPMW
WBOO30: CALL TESTSY
LD A,1
LD (DISKFO+OFFSET),A
PUSH HL
LD HL,STAR40
LD DE,HSTBUF
LD BC,STAR50-STAR40
LDIR
POP HL
LD DE,(CCPSTO) ; MOVE CP/M IN PLACE
LD BC,512*9
CALL HSTBUF
PUSH DE
XOR A
LD (HSTDSK),A
LD (HEADNO+OFFSET),A
LD (SEEKNO+OFFSET),A
INC A
LD (SECTOR),A
LD (HSTTRK),A
INC A
LD (SEEKTR+OFFSET),A
LD A,10
LD (IOEOT+OFFSET),A
LD A,46H
LD (IOCMD+OFFSET),A
CALL IOSEC
POP DE
LD HL,HSTBUF
LD BC,512
LDIR
PUSH DE
LD A,2
LD (SECTOR),A
CALL IOSEC
POP DE
LD HL,HSTBUF
LD BC,512
LDIR
JP GOCPMW
TESTSY: INC HL
INC HL
CALL HSTBUF
LD A,B
SUB 3
LD HL,CCPSTO+1
CP (HL)
RET Z
LD HL,TXTSY
CALL OUTTX
TESY10: CALL CONIN
CP 0DH
JR NZ,TESY10
LD C,0DH
CALL CONOUT
LD C,0AH
CALL CONOUT
JP WBOOT
TXTSY: DEFB 0DH,0AH,0AH,27,'I'
DEFM 'CP/M systemet har forkert størrelse!'
DEFB 0DH,0AH,0AH
DEFB 27,'i'
DEFM 'Indsæt ny disk og tryk på RETURN '
DEFB 0
;
; THE WHOLE CP/M SYSTEM HAS BEEN LOADED. NOW, SET UP
; THE PARAMETERS THAT CP/M REQUIRES AND JUMP TO CCP
;
; THIS ENTRY POINT IS USED BY THE COLD START, TOO.
;
GOCPMC: CALL GOCPM
CALL GOCPM1
JP GOCPM2
GOCPMW: CALL GOCPM
JP GOCPM2
GOCPM:
LD A,01 ; OPEN RAM FOR WRITE
OUT (RAMBAW),A
LD (RAMWR),A
LD B,11H
LD HL,(CCPSTORE)
LD DE,1600H
ADD HL,DE
LD A,0CDH
LD DE,XJTAB+OFFSET
GOCP10: LD (HL),A
INC HL
LD (HL),E
INC HL
LD (HL),D
INC HL
DJNZ GOCP10
LD A,0C3H ; (0H..2H) := JP GOTOCCP
LD (0),A
LD DE,1603H
LD HL,(CCPSTO)
ADD HL,DE
LD (1),HL
LD HL,(CCPSTO)
LD DE,806H
ADD HL,DE
LD (5),A ; (5H..7H) := JP BDOS
LD (6),HL
LD BC,80H ; SET_DMA(80H)
CALL SETDMA ; (* DEFAULT VALUE *)
RET
GOCPM1:
LD HL,STAR30
LD DE,HSTBUF
LD BC,STAR40-STAR30
LDIR
LD HL,100H+512*13
CALL HSTBUF
LD A,B
OR A
CALL Z,INIT1
RET
GOCPM2:
LD HL,GOCP30
LD DE,HSTBUF
LD BC,GOCP40-GOCP30
LDIR
JP HSTBUF
INIT1: PUSH HL
LD HL,GOCP80
LD DE,HSTBUF
LD BC,GOCP90-GOCP80
LDIR
POP HL
JP HSTBUF
GOCP80: DI
LD A,1
OUT (RAMBAR),A
LD (RAMRD),A
LD A,80H
OUT (SYSBAN),A
LD (SYBAN),A
JP (HL)
GOCP90:
GOCP30: DI
LD A,1
OUT (RAMBAR),A
LD (RAMRD),A
LD A,80H
OUT (SYSBAN),A
LD (SYBAN),A
LD A,(CDISK)
LD C,A
LD HL,(CCPSTORE)
EI
JP (HL)
GOCP40:
; EJECT
; TITLE SELDSK
;
; SELECT A DISK FOR SUBSEQUENT TRANSFERS
; THE DISK NUMBER IS INPUT IN C (0...)
; THE ADDRESS OF THE DISK PARAMETER BLOCK FOR THE DISK
; IS RETURNED IN HL; 0 IS RETURNED IF THE DISK DOES
; NOT EXIST.
;
SELDSK:
PUSH BC
CALL MOTORS
POP BC
LD A,C
CP 04
JR C,SELD2
SELD1:
LD HL,0
RET
SELD2:
LD A,C
LD (RECANO+OFFSET),A
LD (SEKDSK),A
LD BC,DPBAS1-DPBAS0
LD HL,DPBAS0+OFFSET
OR A
SELD4: RET Z
ADD HL,BC
DEC A
JR SELD4
;
CONST:
LD A,(KBFLAG)
OR A
RET
;
; READ A CHARACTER FROM THE KEYBOARD
; RETURN A = CHARACTER WITH THE PARITY BIT RESET
;
CONIN:
LD A,(KBFLAG)
OR A
JR Z,CONIN
DI
LD A,(KBFLAG)
DEC A
LD (KBFLAG),A
LD C,A
LD B,0
LD A,(KBBUF)
JR Z,CONIAB
LD HL,KBBUF+1
LD DE,KBBUF
LDIR
CONIAB: AND 7FH
EI
RET
CONI05:
CONI21:
LD A,(KEYSAVE)
LD C,A
LD DE,(KEYSAVE+1)
LD A,C ; GET COLUMN
OR 11000001B
CALL TESTLI ; TEST FOR 1 LINE
JP NZ,FAKE ; TWO OR MORE DOWN
LD A,C
AND 00000001B
JR NZ,CONI22
LD HL,ASCTAB ; CHARACTER TABLE
JR CONI25
CONI22: LD HL,ASCTA1
CONI25: LD B,05
LD A,C
RRA ; MOVE INTO POSITION
CONI30: RRA
JR NC,CONI40
PUSH BC
LD BC,16
ADD HL,BC ; UPDATE HL
POP BC
DJNZ CONI30
JR FAKE ; NO LINE DOWN
CONI40:
LD A,E
CALL TESTLI
JR NZ,FAKE
LD A,D
CALL TESTLI
JR NZ,FAKE ; MORE THAN 1 LINE
LD A,E
CP 0FFH
JR Z,CONI45
LD A,D
CP 0FFH
JR NZ,FAKE
CONI45: LD A,D
LD B,8
CONI50: RLA
JR NC,CONI70
INC HL
DJNZ CONI50
LD A,E
LD B,8
CONI60: RLA
JR NC,CONI70
INC HL
DJNZ CONI60
JR FAKE
CONI70:
LD A,(HL) ; GET CHARACTER
CP 80H
JR NC,FUNCTA
LD B,A ; SAVE IN B
LD A,C ; GET COLUMN
RLA ; MOVE LEFT
JR C,CONI90 ; CONTROL DOWN ?
LD A,B
AND 00011111B
LD B,A
JR CONI95
CONI90: LD A,C
RLA
RLA
JR C,CONI95
LD A,B
CP 41H ; TEST FOR ALPHA LOCK
JR C,CONI95
CP 7EH
JR NC,CONI95
RES 5,B
CONI95:
LD A,(TASTBU)
OR A
JR Z,CONI97
LD A,(KBFLAG)
CP 80
RET Z
LD HL,KBBUF
LD E,A
LD D,0
ADD HL,DE
LD A,B
LD (HL),A
LD A,E
INC A
LD (KBFLAG),A
FAKE:
RET
CONI97: LD A,B
LD (KBBUF),A
LD A,1
LD (KBFLAG),A
RET
TESTLI: CPL
LD B,A
NEG
AND B
SUB B
RET
FUNCTA: CP 90H
JR C,FUNC10
JR NZ,FUNC20
LD A,(OLINE)
CPL
LD (OLINE),A
RET
FUNC10: AND 00000111B ; REMOVE BIT 4-7
LD B,A ; STORE IN B
LD A,C
RLA
JR C,FUNC15
SET 3,B
FUNC15:
LD HL,FBUF-1
LD A,B
OR A
JR Z,FUNC18
FUNC17:
INC HL
LD A,(HL)
CP 80H
JR C,FUNC17
DEC B
JR NZ,FUNC17
FUNC18: INC HL
LD A,(HL)
CP 80H
RET Z ; ZERO STRING
LD B,A
LD A,(KBFLAG)
CP 80
RET Z
PUSH HL
LD E,A
LD D,0
LD HL,KBBUF
ADD HL,DE
LD A,B
LD (HL),A
LD A,E
INC A
LD (KBFLAG),A
POP HL
LD A,B
CP 80H
RET NC
JR FUNC18
FUNC20: CP 91H
JR NZ,FUNC30
LD A,(ULINE)
CPL
LD (ULINE),A
RET
FUNC30: CP 92H
JR NZ,FUNC40
LD A,(INVERT)
CPL
LD (INVERT),A
RET
FUNC40: CP 98H
JR NZ,FUNC50
LD C,27
CALL CONOUT
LD C,'H'
CALL CONOUT
LD A,(MODE)
LD C,A
CALL CONOUT
RET
FUNC50: RET
;
; OUTPUT A CHARACTER TO THE LIST DEVICE
; THE CHARACTER IS INPUT IN C
;
LIST: CALL LISTST
OR A
JR Z,LIST
LD A,C
OUT (LPDP),A
IN A,(LPSP)
RES STROBE,A
OUT (LPSP),A
SET STROBE,A
OUT (LPSP),A
LD A,C
RET
;
;
; RETURN LIST STATUS IN A (0 - NOT READY; 0FFH - READY)
;
LISTST: IN A,(LPSP)
AND EMPTY+BUSY
LD A,0FFH
RET Z
INC A
RET
;
;
; PUNCH A CHARACTER INPUT IN REGISTER C
;
PUNCH:
LD A,(BUSYLI)
AND 00100000B
LD B,A
PUNC10:
LD A,00010000B
OUT (DARTAC),A
IN A,(DARTAC)
AND 00100000B
CP B
JR NZ,PUNC10
PUNC20:
IN A,(DARTAC)
AND 00000100B
JR Z,PUNC20
LD A,C
OUT (DARTAD),A
RET
;
; READ A CHARACTER FROM THE READER TO REGISTER A WITH
; THE PARITY BIT RESET. CTRL-Z INDICATES EOF.
;
READER:
LD A,(BUSYLI)
AND 00001000B
LD B,A
READE2:
LD A,00010000B
OUT (DARTAC),A
IN A,(DARTAC)
AND 00001000B
CP B
JR NZ,READE2
READE3: IN A,(DARTAC)
AND 00000001B
JR Z,READE3
IN A,(DARTAD)
AND 7FH
RET
; EJECT
; TITLE DISK HANDLER
;
; DISK HANDLER
;
;
; RECALIBRATE THE CURRENT DISK
;
HOME:
CALL MOTORS
LD HL,RECALIBRATE+OFFSET ; COMMAND(RECALIBRATE)
CALL COMMAND
CALL ENDSEEK
LD HL,RECALIBRATE+OFFSET
CALL COMMAND
CALL ENDSEEK
RET
;
; SELECT A TRACK FOR SUBSEQUENT TRANSFERS
; THE TRACK NUMBER IS INPUT IN BC (0...)
;
SETTRK:
LD H,B
LD L,C
LD (SEKTR),HL
RET
;
; SELECT A SECTOR FOR SUBSEQUENT TRANSFERS.
; THE SECTOR NUMBER IS INPUT IN BC (RANGE AS THE RETURN
; VALUE FROM SECTRAN).
;
SETSEC:
LD A,C
LD (SEKSEC),A
RET
;
; TRANSLATE A LOGICAL SECTOR NUMBER TO A PHYSICAL
; SECTOR NUMBER. THE LOGICAL SECTOR NUMBER (0...) IS
; INPUT IN BC AND DE POINTS OUT THE TRANSLATE TABLE TO
; BE USED.
; THE RESULTANT PHYSICAL SECTOR NUMBER IS RETURNED IN HL.
;
SECTRAN:
LD H,B
LD L,C
RET
;
; SET THE DMA ADDRESS FOR SUBSEQUENT TRANSFERS.
; THE DMA ADDRESS IS INPUT IN BC.
;
SETDMA:
LD (DMAADR),BC ; DMA_ADDRESS := BC
RET
;
; READ OR WRITE A SECTOR ACCORDING TO THE PREVIOUSLY GIVEN
; SPECIFICATIONS (DISK, TRACK, SECTOR, DMA ADDRESS).
; RETURN A = 0 IF SUCCES, = 1 IF FAILURE.
;
; EJECT
; TITLE READ/WRITE
READ: XOR A
LD (UNACNT),A
LD A,1
LD (READOP),A ; READ OPERATION
LD (RSFLAG),A ; MUST READ DATA
LD A,WRUAL
LD (WRTYPE),A ; TREAT AS UNALLOC
JP RWOPER
WRITE: XOR A ; 0 TO ACCUMULATOR
LD (READOP),A ; NOT A READ OPERATION
LD A,C ; WRITE TYPE IN C
LD (WRTYPE),A
CP WRUAL ; WRITE UNALLOCATED?
JP NZ,CHKUNA ; CHECK FOR UNALLOC
;
; WRITE TO UNALLOCATED, SET PARAMETERS
;
LD A,BLKSIZ/128 ; NEXT UNALLOC RECS
LD (UNACNT),A
LD A,(SEKDSK) ; DISK TO SEEK
LD (UNADSK),A ; UNADSK = SEKDSK
LD HL,(SEKTR) ;
LD (UNATRK),HL
LD A,(SEKSEC)
LD (UNASEC),A ; UNASEC = SEKSEC
;
; CHECK FOR WRITE TO UNALLOCATED SECTOR
;
CHKUNA: LD A,(UNACNT) ; ANY UNALLOC REMAIN
OR A
JP Z,ALLOC ; SKIP IF NOT
;
; MORE UNALLOCATED RECORDS REMAIN
;
DEC A ; UNACNT = UNACNT-1
LD (UNACNT),A
LD A,(SEKDSK) ; SAME DISK?
LD HL,UNADSK
CP (HL) ; SEKDSK = UNADSK
JP NZ,ALLOC ; SKIP IF NOT
;
; DISKS ARE THE SAME
;
LD HL,UNATRK
CALL SEKTRKCMP ; SEKTRK = UNATRK
JP NZ,ALLOC
;
; TRACKS ARE THE SAME
;
LD A,(SEKSEC) ; SAME SECTOR
LD HL,UNASEC
CP (HL) ; SEKSEC = UNASEC
JP NZ,ALLOC ; SKIP IF NOT
;
; MATCH, MOVE TO NEXT SECTOR FOR FUTURE REF
;
INC (HL) ; UNASEC = UNASEC+1
LD A,(HL) ; END OF TRACK?
CP CPMSPT ; COUNT CP/M SECTORS
JP C,NOOVF ; SKIP IF NO OVERFLOW
;
; OVERFLOW TO NEXT TRACK
;
LD (HL),0 ; UNASEC = 0
LD HL,(UNATRK)
INC HL
LD (UNATRK),HL ; UNATRK = UNATRK+1
;
; MATCH FOUND, MARK AS UNNECESSARY READ
;
NOOVF: XOR A ; 0 TO ACCUMULATOR
LD (RSFLAG),A ; RSFLAG = 0
JP RWOPER ; TO PERFORM THE WRITE
;
; NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ
;
ALLOC: XOR A ; 0 TO ACCUM
LD (UNACNT),A ; UNACNT = 0
INC A ; 1 TO ACCUM
LD (RSFLAG),A ; RSFLAG = 1
;
; ENTER HERE TO PERFORM THE READ/WRITE
;
RWOPER: XOR A ; ZERO TO ACCUM
LD (ERFLAG),A ; NO ERRORS (YET)
LD A,(SEKSEC) ; COMPUTE HOST SECTOR
OR A
RRA
OR A
RRA
LD (SEKHST),A ; HOST SECTOR TO SEEK
;
; ACTIVE HOST SECTOR
;
LD HL,HSTACT ; HOST ACTIVE FLAG
LD A,(HL)
LD (HL),1 ; ALWAYS BECOMES 1
OR A ; WAS IT ALREADY?
JP Z,FILHST
;
; HOST BUFFER ACTIVE, SAME AS SEEK BUFFER
;
LD A,(SEKDSK)
LD HL,HSTDSK ; SAME DISK?
CP (HL) ; SEKDSK = HSTDSK
JP NZ,NOMATCH
;
; SAME DISK, SAME TRACK?
;
LD HL,HSTTRK
CALL SEKTRKCMP ; SEKTRK = HSTTRK?
JP NZ,NOMATCH
;
; SAME DISK, SAME TRACK, SAME BUFFER?
;
LD A,(SEKHST)
LD HL,HSTSEC ; SEKHST = HSTSEC
CP (HL)
JP Z,MATCH ; SKIP IF MATCH
;
; PROPER DISK, BUT NOT CORRECT SECTOR
;
NOMATCH: LD A,(HSTWRT) ; HOST WRITTEN
OR A
CALL NZ,WRITEHST ; CLEAR HOST BUFFER
;
; MAY HAVE TO FILL THE HOST BUFFER
;
FILHST: LD A,(SEKDSK)
LD (HSTDSK),A
LD HL,(SEKTR)
LD (HSTTRK),HL
LD A,(SEKHST)
LD (HSTSEC),A
LD A,(RSFLAG) ; NEED TO READ?
OR A
CALL NZ,READHST ; YES, IF 1
XOR A ; 0 TO ACCUM
LD (HSTWRT),A
;
; COPY DATA TO OR FROM BUFFER
;
MATCH: LD A,(SEKSEC) ; MASK BUFFER NUMBER
AND SECMSK ; LEAST SIGNIF BITS
LD L,A ; READY TO SHIFT
LD H,0 ; DOUBLE COUNT
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
;
; HL HAS RELATIVE HOST BUFFER ADDRESS
LD DE,HSTBUF
ADD HL,DE ; HL = HOST ADDRESS
EX DE,HL ; NOW IN DE
LD HL,RWMO10
PUSH HL
LD HL,(DMAADR) ; GET/PUT CP/M DATA
LD C,128 ; LENGTH OF MOVE
LD A,(READOP) ; WHICH WAY?
OR A
JP NZ,RWMOVE+OFFSET ; SKIP IF READ
;
; WRITE OPERATION, MARK AND SWITCH DIRECTION
;
LD A,1
LD (HSTWRT),A ; HSTWRT = 1
EX DE,HL ; SOURCE/DEST SWAP
JP RWMOVE+OFFSET
;
; C INITIALLY 128, DE IS SOURCE, HL IS DEST
;
;RWMOVE:
; LD A,(DE) ; SOURCE CHARACTER
; INC DE
; LD (HL),A ; TO DEST
; INC HL
; DEC C ; LOOP 128 TIMES
; JP NZ,RWMOVE
;
; DATA HAS BEEN MOVED TO/FROM HOST BUFFER
;
RWMO10: LD A,(WRTYPE) ; WRITE TYPE
CP WRDIR ; TO DIRECTORY?
LD A,(ERFLAG) ; IN CASE OF ERRORS
RET NZ ; NO FURTHER PROCESSING
;
; CLEAR HOST BUFFER FOR DIRECTORY WRITE
;
OR A ; ERRORS
RET NZ ; SKIP IF SO
XOR A ; 0 TO ACCUM
LD (HSTWRT),A ; BUFFER WRITTEN
CALL WRITEHST
LD A,(ERFLAG)
RET
;
; UTILITY SUBROUTINE FOR 16-BIT COMPARE
;
SEKTRKCMP:
EX DE,HL
LD HL,SEKTR
LD A,(DE) ; LOW BYTE COMPARE
CP (HL) ; SAME
RET NZ ; RETURN IF NOT
;
; LOW BYTES EQUAL, TEST HIGH IS
;
INC DE
INC HL
LD A,(DE)
CP (HL) ; SETS FLAGS
RET
;
INCLUDE BIOS2.ASM
INCLUDE BIOS1.ASM
INCLUDE BLOWUP.ASM
INCLUDE BLOWU1.ASM
; INCLUDE CHARGE.ASM
INCLUDE COMARE.ASM
«eof»