home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol041
/
fdcbios.z80
< prev
next >
Wrap
Text File
|
1984-04-29
|
15KB
|
747 lines
LIST NOCOND,NOGEN
;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
; modifications by Mike Goetz and Hank Kee - 9/2/81
;
; corrected PIP A:=B:filename.ext on Persci 277/299
; Persci's must be configured as A: and B:
; and/or C: and D: since they have but one
; arm to access two drives
; modified sign-on message to properly generate size
; from MEMSIZE definition during assembly
; corrected current drive assignment on warm boot
; inclusion of LIST serial driver for CCS 8250 (30 CPS)
; option to support LA34/LA36
;
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
PERSCISW: EQU 1 ;ONE IF PERSCI DRIVE
LARGESW: EQU 1 OR PERSCISW ;ONE IF MAXI DRIVE
NUMDRIVES: EQU 2 ;ONE TO FOUR (MUST BE SAME TYPE)
BIGIOSW: EQU 1 ;ZERO IF NO LIST, NO PUNCH
;
MEMSIZE: EQU 64
SERIAL: EQU 1 ;SERIAL PRINTER OPTION W/8250
MEMSTAT: EQU MEMSIZE-9 ;2400 HEX OFFSET
BEGINADR: EQU MEMSTAT*1024 ;THIS IS THE START OF CPM
MEMUNITS: EQU MEMSIZE-(MEMSIZE/10*10)
MEMTENTH: EQU MEMSIZE/10
;
ORG 1600H+BEGINADR
;
; CROMEMCO 4FDC I/O ASSIGNMENTS
;
CSTATPORT: EQU 00H ;3P + S, 4FDC, TU-UART, OR SCC
CDATAPORT: EQU 01H
IMODEPORT: EQU 02H ;(3P + S DOESNT HAVE THESE)
IMASKPORT: EQU 03H
PARLPORT: EQU 04H ;NOT USED
;
STATPORT: EQU 30H ;4FDC OR CCS 2422 BOARD
TRAKPORT: EQU 31H
SECTPORT: EQU 32H
DATAPORT: EQU 33H
FLAGPORT: EQU 34H
;
BANKPORT: EQU 40H ;MEMORY BANKING PORT
;
; 1771/179X EQUATES
;
HEADLOAD: EQU 08H
VERIFY: EQU 04H
;
IF BIGIOSW = 1
;
; OTHER DEFINITIONS (OPTIONAL)
;
BAUDRATE: EQU 01H ;110 BAUD FOR READER ?
RSTATPORT: EQU 10H
RBAUDPORT: EQU RSTATPORT ;TU-UART BOARD FOR PAPER TAPE
RDATAPORT: EQU RSTATPORT+1
PSTATPORT: EQU 10H
PBAUDPORT: EQU PSTATPORT ;PAPER TAPE PUNCH ALSO
PDATAPORT: EQU PSTATPORT+1
LSTATPORT: EQU 54H ;PARALLEL PRINTER POARD
LDATAPORT: EQU LSTATPORT
ENDIF
TRUE: EQU -1
FALSE: EQU 0
NULLS: EQU 6 ; NUMBER OF NULLS AFTER LF
LF: EQU 0AH ; LINE FEED
SDATA: EQU 20H ; DATA PORT
SINTEN: EQU 21H ; INTERRUPT REGISTER
SIDENT: EQU 22H ; INTERRUPT IDENTIFICATION
SLCTRL: EQU 23H ; LINE CONTROL REGISTER
SMDMCT: EQU 24H ; MODEM CONTROL REGISTER
SLSTAT: EQU 25H ; LINE STATUS REGISTER
SMDMST: EQU 26H ; MODEM STATUS REGISTER
SSTATP: EQU 25H ; SERIAL PRINTER STATUS PORT (INPUT)
STBE: EQU 20H ; SERIAL PRINTER TBE BIT
;
; CPM ENTRY POINTS
CPMB: EQU 00H+BEGINADR
BDOS: EQU 806H+BEGINADR
;
; JUMP VECTOR
JP CBOOT
EBOOT:
JP WBOOT
JP CONSTAT
JP CONIN
JP CONOUT
JP LIST
JP PUNCH
JP READER
JP HOME
JP SELDSK
JP SETTRK
JP SETSEC
JP SETDMA
JP READ
JP WRITE
JP LISTAT
JP SECTRAN
;
; CP/M 2.2 DISK CONTROL BLOCKS
;
DPBASE:
DW XLT0,0000
DW 0000,0000
DW DIRBUF,DPB0
DW CSV0,ALV0
;
IF NUMDRIVES > 1
DW XLT0,0000
DW 0000,0000
DW DIRBUF,DPB0
DW CSV1,ALV1
ENDIF
;
IF NUMDRIVES > 2
DW XLT0,0000
DW 0000,0000
DW DIRBUF,DPB0
DW CSV2,ALV2
ENDIF
;
IF NUMDRIVES > 3
DW XLT0,0000
DW 0000,0000
DW DIRBUF,DPB0
DW CSV3,ALV3
ENDIF
;
DPB0:
;
; disk parameter block, common to all disks
; this implements a "standard" CP/M directory
; with 64 entries, and 1K blocks.
;
DW 18+LARGESW*8 ;sectors per track
DB 3 ;block shift factor
DB 7 ;block mask
DB 0 ;null mask
DW 81+LARGESW*161 ;disk size-1
DW 63 ;directory max
DB 192 ;alloc 0
DB 0 ;alloc 1
DW 16 ;check size
DW 3-LARGESW ;track offset
;
XLT0:
;
; sector translate vector
;
IF LARGESW EQ 0
DB 1,6,11,16 ;sectors 1,2,3,4
DB 3,8,13,18 ;sectors 5,6,7,8
DB 5,10,15,2 ;sectors 9,10,11,12
DB 7,12,17,4 ;sectors 13,14,15,16
DB 9,14 ;sectors 17,18
ENDIF
;
;
IF LARGESW EQ 1
DB 1,7,13,19 ;sectors 1,2,3,4
DB 25,5,11,17 ;sectors 5,6,7,8
DB 23,3,9,15 ;sectors 9,10,11,12
DB 21,2,8,14 ;sectors 13,14,15,16
DB 20,26,6,12 ;sectors 17,18,19,20
DB 18,24,4,10 ;sectors 21,22,23,24
DB 16,22 ;sectors 25,26
ENDIF
;
;
SIGNON:
DEFB 26,13,10,10
DEFB MEMTENTH+30H
DEFB MEMUNITS+30H
DEFB 'k CP/M version 2.2'
DEFB 13,10,0
;
SELDSK: ;
LD HL,0
LD A,C ;C CONTAINS REQUESTED DRIVE NO.
CP NUMDRIVES
RET NC ;IGNORE IF TOO HIGH
LD (DKNUMB),A
LD L,C ;L=disk number 0,1,2,3
ADD HL,HL ;*2
ADD HL,HL ;*4
ADD HL,HL ;*8
ADD HL,HL ;*16 (size of each header)
LD DE,DPBASE
ADD HL,DE ;HL=.dpbase(diskno*16)
RET
;
SECTRAN: ;TRANSLATE SECTOR IN C USING TABLE AT DE
LD B,0
EX DE,HL ;TABLE ADDR TO HL
ADD HL,BC ;GET ADDRESS
LD L,(HL) ;GET BYTE
LD H,0 ;ANSWER IN HL
RET
;
SETSEC:
LD A,C ;JUST SAVE SECTOR NUMBER
LD (DKSECT),A
RET
;
SETDMA:
LD (DKDMA),BC ;JUST SAVE I/O ADDRESS
RET
;
;
; ERROR CHECKING READ AND WRITE RTNS FOR
; CROMEMCO CBIOS
;
READ:
CALL CLEAR
RETRYREAD:
CALL READ4FDC ;READ SECTOR
RET Z ;SUCCESSFUL READ. RETURN
CALL ERROR ;INCREMENT RETRYCOUNT
JR NZ,RETRYREAD ;RETRY 20 TIMES
OR 01H ;CP/M CONVENTION FOR PERMANENT ERROR
RET
;
CLEAR:
XOR A
LD (TRKERCNT),A ;ZERO OUT TRACK ERROR COUNTER
LD (RETRYCOUNT),A ;ZERO OUT CRC ERROR COUNTER
RET
;
WRITE:
CALL CLEAR
RETRYWRITE:
CALL WRIT4FDC ;WRITE SECTOR
RET Z ;SUCCESSFUL WRITE. RETURN
CALL ERROR ;INCREMENT RETRYCOUNT
JR NZ,RETRYWRITE ;RETRY 20 TIMES
OR 01H ;CP/M CONVENTION FOR PERMANENT ERROR
RET
;
ERROR:
PUSH HL
AND 10H ;CHECK FOR NRF
JR NZ,TRACKERROR
LD HL,RETRYCOUNT
INC (HL) ;INCREMENT RETRYCOUNT
LD A,(HL)
POP HL
SUB 20 ;20 TRIES?
RET
;
TRACKERROR:
LD HL,TRKERCNT
INC (HL) ;INCREMENT NO OF TRACK ERRORS
LD A,(HL)
SUB 10D ;ALLOW ONLY 10 TRACK ERRORS
POP HL
RET Z ;IF >10, RETURN A FAILURE
PUSH BC
CALL HOME ;HOME THE HEAD
LD A,(DKTRACK)
LD C,A ;GET TRACK IN C
CALL SETTRK ;RESEEK TO CORRECT TRACK
POP BC
OR 0FFH ;RETRY
RET
;
; RESTORE THE DISK TO TRACK ZERO
;
HOME:
SUB A,A ;ZERO OUT TRACK COUNTER
LD (DKTRACK),A
CALL DISKSELECT ;NOW SELECT THE DISK
OUT FLAGPORT,A
LD A,02H+HEADLOAD+VERIFY ;USE SLOW STEPPING SPEED FOR ALL DISKS
OUT STATPORT,A
RSTI:
IN A,FLAGPORT ;NOW CHECK STATUS
RRA
JR NC,RSTI ;LOOP BACK UNTIL DONE
JP SEEKTEST
;
; HERE, ACTUALLY DO THE READ OPERATION
;
READ4FDC:
PUSH BC
PUSH HL ;FIRST, SAVE REGS
PUSH DE
LD E,88H ;READ COMMAND (VALID FOR 1771, 179X)
CALL INIT4FDC
RDI1:
IN A,FLAGPORT ;NOW CHECK FLAGS
RRA
JR C,RDI3 ;IF PREMATURELY DONE, STOP
INI
JR NZ,RDI1 ;READ ANOTHER BYTE INTO CORE UNTIL DONE
RDI2:
IN A,FLAGPORT ;CHECK FLAGS
RRA
JR NC,RDI2 ;LOOP UNTIL READY
RDI3:
IN A,STATPORT ;NOW CHECK STATUS
AND A,9CH
RDWREND:
EI
POP DE ;RESTORE REGS
POP HL
POP BC
RET
;
; ACTUALLY DO WRITE OPERATION
;
WRIT4FDC:
PUSH BC
PUSH HL ;SAVE REGS
PUSH DE
LD E,0A8H ;WRITE COMMAND (VALID FOR 1771, 179X)
CALL INIT4FDC
WRI1:
IN A,FLAGPORT ;CHECK FLAGS
RRA
JR C,WRI3 ;IF PREMATURELY DONE, STOP
OUTI
JR NZ,WRI1 ;WRITE DATA FROM MEMORY TIL DONE
WRI2:
IN A,FLAGPORT ;CHECK FLAGS
RRA
JR NC,WRI2 ;LOOP TIL DONE WITH WHOLE OPERATION
WRI3:
IN A,STATPORT ;NOW CHECK ERROR STATUS
AND A,0FCH
JR RDWREND
;
; SET THE TRACK, AND MOVE DISK ARM THERE
;
SETTRK:
LD A,C
LD (DKTRACK),A ;STORE THE TRACK NUMBER
SUB A,A
CALL DISKSELECT ;NOW SELECT THE DISK
OUT FLAGPORT,A
LD A,C
OUT DATAPORT,A ;TELL 1771 ABOUT TRACK WANTED
LD A,(DKSECT)
OUT SECTPORT,A ;TELL IT ABOUT SECTOR WANTED
PUSH HL
PUSH DE
LD HL,LOGINTAB ;NOW, SEE WHERE DISK ARM IS NOW
LD A,(DKNUMB)
LD E,A ;LOOK UP IN TABLE
LD D,0
ADD HL,DE ;GET BYTE
LD A,(HL)
OUT TRAKPORT,A ;TELL 1771 WHERE ARM IS NOW
LD A,(HL)
SUB A,C
POP DE ;NOW CAN RESTORE THE REGS
POP HL
RET Z ;IF ALREADY AT THAT TRACK, QUIT
LD A,12H-LARGESW*2+HEADLOAD+VERIFY
OUT STATPORT,A ;PERFORM THE SEEK THAT IS NEEDED
SKI:
IN A,FLAGPORT ;CHECK FLAGS
RRA
JR NC,SKI ;LOOP UNITL OPERATION DONE
SEEKTEST:
IN A,STATPORT ;NOW CHECK ERROR STATUS
AND A,98H
RET NZ ;ZERO IS ALL OK
PUSH DE
LD D,0 ;UPDATE TRACK TABLE
LD A,(DKNUMB)
LD E,A ;WITH NEW POSITION
;
IF PERSCISW = 1
CALL ADDSHIFT ;PERSCI DRIVES HAVE ONLY ONE ARM
LD A,E
XOR 1
LD E,A
CALL ADDSHIFT
POP DE
RET
ENDIF
;
ADDSHIFT: ;IF NOT PERSCI, FALL THRU HERE
PUSH HL
LD HL,LOGINTAB ;GET CORRECT ADDRESS OF DISK
ADD HL,DE
LD A,(DKTRACK) ;AND GET CURRENT TRACK NUMBER
LD (HL),A
SUB A,A ;PUT IT IN
POP HL
IF PERSCISW = 0
POP DE ;AND MISC CLEANUP
ENDIF
RET
;
; INITIALIZE THE 4FDC, BY SELECTING THE DISK AND
; TURNING ON THE DISK MOTORS, AND INITIALIZE THE
; REGISTERS FOR THE I/O OPERATION
;
INIT4FDC:
LD A,80H ;FIRST, SELECT THE DISK
CALL DISKSELECT
LD HL,(DKDMA) ;INITIALIZE HL AND BC REGS FOR I/O
LD BC,8000H+DATAPORT ;80H IS 128 BYTE SECTORS
LD D,A ;SAVE THE A REG
DI ;DISABLE INTERRUPTS
LD A,(DKSECT)
OUT SECTPORT,A ;SET THE SECTOR WANTED
IN A,FLAGPORT
CPL ;SEE IF HEAD IS LOADED
AND A,20H
JR Z,IN0
LD A,04 ;THIS IS THE HEAD LOAD BIT
IN0:
ADD A,E ;ADD HEAD LOAD BIT TO COMMAND
LD E,A
LD A,D ;RESTORE THE A REG
OUT FLAGPORT,A
LD A,E
OUT STATPORT,A ;OUTPUT THE COMMAND
RET
;
; FIGURE OUT WHICH DISK TO SELECT AND PUT BIT THERE
;
DISKSELECT:
PUSH BC ;FIRST, SAVE THIS, ITS NEEDED
LD C,A
LD A,(DKNUMB) ;GET DISK NUMBER 0-3
LD B,A
INC B ;ADD ONE
SUB A,A
SCF ;SET A BIT IN TO BE SHIFTED
SHIFTBIT:
RLA ;NOW, ROTATE BITS OVER
DJNZ SHIFTBIT
LD B,A ;SAVE THE NEW VALUE
XOR A
OR A,20H+LARGESW*10H ;CONDITION 4FDC FOR MOTOR ON AND MAXI
OR A,B
OR A,C ;OR IN DRIVE SELECT AND COMMAND WANTED
POP BC
RET
;
; GETS CONTROL ON A WARM START
;
WBOOT:
LD A,01H ;FIRST, RESTORE DEFAULT BANKING
OUT BANKPORT,A
;
LD SP,80H
LD A,(DKNUMB)
LD (CURRDRIVE),A ;STORE SELECTED DRIVE
;
STARTBOOT:
LD C,0
CALL SELDSK ;SELECT DRIVE A TO REBOOT
CALL HOME
LD HL,CPMB-128 ;WILL INCREMENT BY 128 LATER
LD (DKDMA),HL
LD BC,44*256+1 ;SECTOR COUNT, FIRST SECTOR-1
RDSEC:
LD A,C ;C IS SECTOR NUMBER
CP 18+LARGESW*8
JR Z,NXTTRK
LD DE,128 ;INCREMENT DMA ADDRESS
LD HL,(DKDMA)
ADD HL,DE
LD (DKDMA),HL ;STORE DMA ADDRESS
INC C ;INCREMENT SECTOR NUMBER
CALL SETSEC
CALL READ ;READ THE DATA
JR NZ,WBOOT ;ON READ FAILURE TRY AGAIN
DJNZ RDSEC
JR BOOT ;READ CCP AND BDOS;
NXTTRK:
LD A,(DKTRACK)
CP 2-LARGESW
JR Z,BOOT ;STOP AT TRACK 2
LD C,A
INC C ;SEEK NEXT TRACK IF NOT
CALL SETTRK
LD C,0
JR RDSEC
;
;
CBOOT: ;AFTER COLD BOOT
LD SP,80H ;INITIALIZE STACK FOR ROUTINE
LD HL,SIGNON
CALL PRMSG ;PRINT MESSAGE
BOOT: ;GETS CONTROL AFTER COLD OR WARM BOOT
DI
LD A,0C3H ;SET UP PARAMETERS ON PAGE 0
LD (0),A
LD HL,EBOOT
LD (1),HL
LD (7*8+1),HL
LD (5),A
LD HL,BDOS
LD (6),HL
;
; CROMEMCO INITIALIZATION HERE (READER, LIST NOT NEEDED)
; NOTE .. THE CONSOLE TUART IS INITIALIZED BY RDOS
;
IF BIGIOSW = 1
LD A,BAUDRATE
OUT PBAUDPORT,A
ENDIF
;
IF SERIAL = 1
CALL L2INIT
ENDIF
;
LD BC,80H ;SET DEFAULT DMA ADDR
CALL SETDMA
;
LD A,(CURRDRIVE) ;RESELECT THE DRIVE THAT WAS ACTIVE
LD C,A ; BEFORE THE WARM START
EI
JP CPMB
;
;
ERRMSG:
DEFB 13,10,'?? ERROR ??',13,10,0
;
PRMSG: ;PRINT MESSAGE AT H,L UNTIL 0
LD A,(HL)
OR A ;ZERO?
RET Z
LD C,A ;GO PRINT CHAR
CALL CONOUT
INC HL ;GET NEXT CHAR
JR PRMSG
;
;
;HARDWARE UART CONSOLE ROUTINES
;
CONSTAT:
IN A,CSTATPORT ;CHECK CONSOLE STATUS
AND 40H
RET Z ;ZERO MEANS NO INPUT BYTE READY
LD A,0FFH
RET ;FF MEANS INPUT
;
CONIN:
CALL CONSTAT ;CHECK STATUS TIL GOT A BYTE
JR Z,CONIN
IN A,CDATAPORT ;READ THE BYTE AND KILL OFF 80H
AND 7FH
;
; THE FOLLOWING CODE REPLACES THE DEL KEY WITH A CTRL-U,
; SO THAT DEL MEANS LINE DELETE. USE BACKSPACE TO DELETE
; A SINGLE CHARACTER.
;
; CP 127 ; DEL
; RET NZ
; SUB 127-21 ; CTRL-U
RET
;
; CONSOLE OUTPUT ROUTINE
;
CONOUT:
IN A,CSTATPORT ;FIRST, LOOP UNITL TRANSMITTER BUFFER
AND 80H ;IS EMPTY
JR Z,CONOUT
LD A,C ;NOW, OUTPUT CHARACTER TO CONSOLE
OUT CDATAPORT,A
RET
;
; LIST STATUS CHECK FOR CP/M 2.2
;
LISTAT:
IF BIGIOSW = 1
IN A,LSTATPORT ;IF LIST TRANSMITTER IS BUSY,
CPL ;THEN RETURN WITH ZERO
AND 20H
RET Z
OR A,0FFH ;LIST TRANSMITTER BUFFER IS EMPTY
RET
ENDIF
;
LIST:
IF BIGIOSW = 1 AND SERIAL = 0
CALL LISTAT ;CHECK IF PRINTER BUSY
JR Z,LIST
LD A,C ;NOW OUTPUT CHARACTER
SET 7,A
OUT LDATAPORT,A ;WITH HIGH STROBE
RES 7,A
OUT LDATAPORT,A ;NOW LOW STROBE
SET 7,A
OUT LDATAPORT,A ;NOW HIGH STROBE AGAIN
RET
ENDIF
;
IF SERIAL = 1
LD A,C
JP L2OUT
ENDIF
;
PUNCH:
IF BIGIOSW = 1
IN A,PSTATPORT ;CHECK IF PUNCH BUFFER EMPTY
AND 80H
JR Z,PUNCH ;LOOP UNTIL READY
LD A,C
OUT PDATAPORT,A ;OUTPUT CHARACTER
RET
ENDIF
;
READER:
IF BIGIOSW = 1
IN A,RSTATPORT ;SEE IF READER BUFFER FULL
AND 40H
JR Z,READER ;LOOP UNTIL FULL
IN A,RDATAPORT ;AND READ IT
RET
ENDIF
;
IF BIGIOSW NE 1
XOR A,A ;DUMMY ROUTINE FOR LIST,PUNCH,READER
RET
ENDIF
; Serial Printer Initialization Routine
L2INIT: LD A,0FH ; SETUP THE 8250
OUT SMDMCT,A
LD A,83H ; SET DIVISOR REGISTER ACCESS
OUT SLCTRL,A
LD A,80H ; SET THE DIVISOR TO 384=300 BAUD
OUT SDATA,A
LD A,01H ;
OUT SINTEN,A
LD A,03H ; SET DATA REGISTER ACCESS
OUT SLCTRL,A
LD A,0H ; DISABLE INTERRUPT
OUT SINTEN,A
OUT SLSTAT,A ; RESET ERROR FLAGS
RET
; Get Serial Printer Output Status
; Upon Exit: A = -1 (FFH) and Z-flag is reset if ready for char.
; A = 0 and Z-flag is set if not ready for character
L2RDY: IN A,SSTATP ; GET LIST-OUT STATUS
AND STBE ; CHECK PRINTER TBE FLAG
RET Z ; PRINTER NOT READY FOR CHARACTER
LD A,-1 ; PRINTER READY FOR CHARACTER
RET
; Serial Printer Output Routine
; Upon Entry: A contains the character to be output
L2OUT: PUSH AF ; SAVE CHARACTER FOR A MOMENT
L2OT30: CALL L2RDY ; GET LIST-OUT STATUS
JR Z,L2OT30 ; ZERO MEANS PRINTER BUSY
POP AF ; RESTORE CHARACTER
OUT SDATA,A ; OUTPUT THE CHARACTER
CP LF ; CHECK FOR END OF LINE
RET NZ ; RETURN IF NOT LINE FEED CHARACTER
LD A,NULLS+1 ; IF LF, GET NUMBER OF NULLS
L2RTN: DEC A ; CHECK FOR 0 NULLS AT TOP OF LOOP
RET Z ; RETURN IF ALL NULLS OUTPUT
PUSH AF ; SAVE NULLS COUNTER
SUB A ; PRINT A SINGLE NULL
CALL L2OUT ; CHARACTER (RECURSIVE)
POP AF ; RESTORE NULLS COUNTER
JR L2RTN ; LOOP TO PRINT NEXT NULL
;
DKNUMB: EQU 4 ;THIS IS WHERE THE DISK NUMBER IS
; ;KEPT IN NORMAL CP/M
CURRDRIVE:
DB 0 ;THE SAVE AREA FOR THE DEFAULT DRIVE
LOGINTAB:
DB 2-LARGESW,0,0,0 ;FOUR DRIVES MAX
DKSECT:
DB 0 ;SECTOR NUMBER
DKTRACK:
DB 0 ;TRACK NUMBER
DKDMA:
DW 0 ;DMA ADDRESS
TRKERCNT:
DB 0 ;NUMBER OF TRACK ERRORS
RETRYCOUNT:
DB 0 ;NUMBER OF READ ERRORS
;
; FROM HERE ON, THE AREAS ARE INITIALIZED BY CP/M AS NEEDED
;
DIRBUF:
DS 128 ;SAVE AREA FOR DISK DIRECTORY OPERATIONS
;
;
ALV0:
DS 32
;
IF NUMDRIVES > 1
ALV1:
DS 32
ENDIF
;
IF NUMDRIVES > 2
ALV2:
DS 32
ENDIF
;
IF NUMDRIVES > 3
ALV3:
DS 32
ENDIF
;
CSV0:
DS 16
;
IF NUMDRIVES > 1
CSV1:
DS 16
ENDIF
;
IF NUMDRIVES > 2
CSV2:
DS 16
ENDIF
;
IF NUMDRIVES > 3
CSV3:
DS 16
ENDIF
;
; Note: The last assembled byte of this module MUST NOT be a Define
; Storage (DS or DEFS) pseudo-op to assure proper operation with CDOSGEN
END