home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol058
/
cios.sqc
/
CIOS.SRC
Wrap
Text File
|
1985-02-09
|
20KB
|
699 lines
; LOGICAL I/O SYSTEM FOR CP/M
; MISCELLANEOUS EQUATES
CPM EQU 5 ; CPM ENTRY POINT
BIOS EQU 0 ; BIOS ENTRY POINT
FCB EQU 5CH ; TRANSIENT FCB
TBUF EQU 80H ; TRANSIENT BUFFER
; FCB FORMAT
FFET EQU 0 ; ENTRY TYPE
FFFN EQU 1 ; FILE NAME
FFFT EQU 9 ; FILE TYPE
FFEX EQU 12 ; FILE EXTENT
FFRC EQU 15 ; RECORD COUNT
FFDM EQU 16 ; ALLOCATION MAP
FFNR EQU 32 ; NEXT RECORD
FFBA EQU 33 ; NEXT BYTE
FFDV EQU 35 ; DEVICE ADDRESS
FFBUF EQU 36 ; BUFFER
; GET CHARACTER (W/OUT ECHO) FROM CONSOLE
; OUTPUTS: A = CHARACTER
FGTCH:
LHLD 1 ; GET BIOS
LXI D,6 ; ADDRESS
DAD D ; FOR
LXI D,FGTC01 ; CONSOLE
PUSH D ; CALL
PCHL ; BIOS
FGTC01:
ANI 7FH ; CLEAR PARITY
MOV B,A
LDA CANCEL ; TEST FOR CANCEL
CMP B
JZ FGTC06
MOV A,B
CPI ESCAPE ; TEST FOR ESCAPE
CZ FGTC03
LDA FLOWER
CMP B ; ADJUST
JP FGTC02 ; LOWER
CPI '{' ; CASE
JP FGTC02
MOV A,B
ANI 5FH
MOV B,A
FGTC02:
MVI A,60H
STA FLOWER
MOV A,B
RET
FGTC03:
CALL FGTCH ; ESCAPE
CPI '[' ; SEQUENCE
CZ FGTCH ; PROCESSOR
LXI H,TRANSLATE
MOV B,A
FGTC04:
MOV A,M ; SCAN TRANSLATE
INX H ; TABLE USING
ORA A ; SECOND CHARACTER
JZ FGTC05 ; OF SEQUENCE
CMP B
JZ FGTC05
INX H
JMP FGTC04
FGTC05:
MOV B,M ; SUBSTITUTE VALUE
RET ; FROM TABLE
FGTC06:
WRTLN FGSURE
CALL FGTCH
CPI 'Y'
JZ BOOT
JMP FGTCH
FLOWER: DB 60H
FGSURE: DB 13,10,'Are you sure(y/n)? ','$'
; GET CHARACTER (W/ECHO) FROM CONSOLE
; OUTPUTS: A = CHARACTER
FRDCH:
CALL FGTCH
CPI 20H
JP FRDC01
CPI 0DH
JZ FRDC01
ORI 20H
FRDC01:
CALL FWTCH
RET
; READ LINE FROM CONSOLE
; INPUT: HL = @(BUFFER)
; A = S(BUFFER)
; OUTPUT: BUFFER WITH GOODIES
FRDLN:
DCX H ; POINT
DCX H ; TO MAX
PUSH H ; SIZE
PUSH H
MOV M,A ; SAVE SIZE
INX H ; POINT TO
INX H ; BUFFER
FFRD01: ; AND
MVI M,' ' ; CLEAR
INX H ; THE
DCR A ; BUFFER
JNZ FFRD01
POP D
MVI C,10 ; READ
CALL CPM ; CONSOLE
POP H ; ADJUST
MOV B,M ; LOWER
INX H ; CASE
INX H
FFRD02:
MOV A,M
CPI 'a'
JM FFRD03
CPI '{'
JP FFRD03
ANI 5FH
MOV M,A
FFRD03:
INX H
DCR B
JNZ FFRD02
RET
; WRITE CHARACTER TO CONSOLE
; INPUTS: A = CHARACTER
FWTCH:
PUSH PSW
CPI 13 ; CHECK FOR CR
JNZ FWTCH1
LDA CRLF
FWTCH1:
CPI 10 ; CHECK FOR LF
JNZ FWTCH2
LDA CRLF+1
FWTCH2:
MOV E,A
MVI C,2
CALL CPM
POP PSW
RET
; WRITE LINE TO CONSOLE
; INPUTS: HL=@(LINE)
; LINE TERMINATED BY '$'
FWRTLN:
MOV A,M
CPI DOLLAR
RZ
PUSH H
CALL FWTCH
POP H
INX H
JMP FWRTLN
; GOTOXY CURSOR CONTROL FOR CRT
; INPUT: A = ROW
; B = COLUMN
GOTOXY:
STA FTEMP
LDA MEMAP ; TEST FOR
ORA A ; MEMORY MAPPED
LDA FTEMP
JNZ MGTXY ; TERMINAL
MOV C,A
LDA CR ; TEST FOR
CPI 0 ; ANSI OPTION
JZ GTXY06
MOV A,B
LHLD XBND1 ; IF COL<XBND1
CMP L ; THEN
JP GTXY01
ADD H ; COL:=COL+XINC1
JMP GTXY02
GTXY01: ; ELSE
LHLD XBND2 ; IF COL<XBND2
CMP L ; THEN
JP GTXY02
ADD H ; COL:=COL+XINC2
GTXY02:
MOV E,A
MOV A,C
LHLD YBND1 ; IF ROW<YBND1
CMP L ; THEN
JP GTXY03
ADD H ; ROW:=ROW+YINC1
JMP GTXY04
GTXY03:
LHLD YBND2 ; IF ROW<YBND2
CMP L ; THEN
JP GTXY04
ADD H ; ROW:=ROW+YINC2
GTXY04:
MOV D,A
LDA CR ; IF COL_ROW THEN
CPI 2
JNZ GTXY05
MOV H,D ; D XCHG E
MOV D,E
MOV E,H
GTXY05:
XCHG
SHLD GTXYL1
WRITE PRFX ; WRITE(PRFX)
WRITE CMMD ; WRITE(CMMD)
WRITE GTXYL1 ; WRITE(ROW/COL)
WRITE GTXYL1+1 ; WRITE(COL/ROW)
RET
GTXY06: ; ANSI GOTOXY OPTION
PUSH B ; SAVE COORDINATES
MOV E,C ; CONVERT
MVI D,0 ; ROW
LXI H,GTXYL2+2
MVI A,2
CALL INT$TO$STR
POP B ; CONVERT
MOV E,B ; COLUMN
MVI D,0
LXI H,GTXYL2+5
MVI A,2
CALL INT$TO$STR
WRTLN GTXYL2 ; WRITE(ROW,COL)
RET
GTXYL1: DB ' '
GTXYL2: DB 27H,'[00;00H','$'
; SCREEN CLEAR PROCEDURES
CLR$SCR:
XRA A
CALL CLEOS ; CLEAR THE SCREEN
GTXY 0,0 ; GOTOXY(0,0);
MOVI COLUMN,0
MOVI ROW,0
RET ; END
CLEOS:
STA CLROW
MVI B,0 ; GOTOXY(0,A);
CALL GOTOXY
MCPI CLESL,DOLLAR ; CHECK FOR CLEAR
JZ CLES02 ; FUNCTION AVAILABLE
WRTLN CLESL ; CLEAR TO END OF SCREEN
CALL CLWAIT
RET
*
* CLEAR WITH SPACES
*
CLES02:
MVI A,DOLLAR ; ADJUST FOR
XPUT CLSPC-1,MXCOL ; LINE LENGTH
DMVI CLESW2,2 ; WORK:=MXROW-2;
DSUB CLESW2,MXROW,CLESW2
CLES03:
WRTLN CLSPC ; CLEAR SCREEN
WRTLN CLESL3 ; GO TO NEXT LINE
NEXT CLES03,CLROW,CLESW2
WRTLN CLSPC ; CLEAR LAST LINE
RET
CLESW2: DW 0
CLESL3: DB 10,'$'
CLEOL:
STA CLROW
MVI B,0 ; GOTOXY(0,A);
CALL GOTOXY
MCPI CLELL,DOLLAR ; CHECK FOR CLEAR
JZ CLEL01 ; FUNCTION AVAILABLE
WRTLN CLELL ; WRITE CLEARTOENDOFLINE
CALL CLWAIT
RET ; END
CLEL01:
MVI A,DOLLAR ; ADJUST FOR
XPUT CLSPC-1,MXCOL ; LINE LENGTH
WRTLN CLSPC ; CLEAR LINE
RET
CLROW: DW 0
CLSPC: DB ' '
DB ' '
DB ' '
DB ' '
DB ' '
DB '$'
; WAIT FOR SCREEN TO SETTLE
CLWAIT:
MOVE CLWTW1,NULL$COUNT
RZ ; EXIT IF NO DELAY NEEDED
CLWT01:
WRTLN CLWTL1 ; DELAY FOR CLEAR
MDEC CLWTW1
JNZ CLWT01
RET
CLWTL1: DB 0,0,0,0,'$'
CLWTW1: DB 0
; FCB BUILDER
; PREPARES FCB FOR I/O
; INPUTS: DE = @(FCB)
; HL = @(FCB$NAME)
FFCB:
CALL FCMPR ; COMPRESS
CALL FADDR ; GET ADDRS
DCX H ; GET
MOV B,M ; SIZE
PUSH B ; AND
INX H ; SAVE
XCHG
SHLD FTEMP ; SAVE HL
MVI A,36 ; AND
FFCB01:
MVI M,0 ; CLEAR
INX H ; ENTIRE
DCR A ; FCB
JNZ FFCB01
PUSH D ; GET CURRENT
MVI C,25 ; DEVICE
CALL CPM ; SPECIFICATION
LHLD FPFDV ; RETRIEVE HL
MOV M,A ; AND SAVE
POP D ; RETRIEVE
PUSH D ; D AND
LDAX D ; GET DEVICE
MOV B,A ; SPEC
INX D ; POINT TO ':'
LDAX D ; GET ':'
CPI ':' ; TEST FOR
JNZ FFCB02 ; DEVICE SPEC
MOV A,B ; NORMALIZE
MVI B,'A' ; DEVICE
SUB B ; SPEC
MOV M,A ; AND SAVE
INX D ; BYPASS D:
POP B
POP B ; ADJUST
DCR B ; SIZE
DCR B
PUSH B
PUSH D
FFCB02:
LHLD FPFCB ; POINT
INX H ; TO ID
PUSH H ; AND SAVE
MVI A,11
FFCB03:
MVI M,' ' ; CLEAR
INX H ; ID
DCR A ; TO
JNZ FFCB03 ; SPACES
POP H ; RETRIEVE
POP D ; HL, DE
POP B ; AND BC
FFCB04:
LDAX D ; GET NAME
CPI '.' ; AND TEST
JZ FFCB06 ; FOR TYPE
CPI '0' ; ELSE TEST
JM FFCB05 ; FOR DONE
CPI '['
JP FFCB05
MOV M,A ; ELSE
INX H ; MOVE
FFCB05:
INX D ; CHARACTER
DCR B ; TO
JNZ FFCB04 ; FCB
RET
FFCB06:
PUSH D ; POINT
LHLD FTEMP ; TO
LXI D,FFFT ; TYPE
DAD D ; FIELD
POP D ; IN
JMP FFCB05 ; FCB
FCMPR:
PUSH D
MOV D,H
MOV E,L
DCX H
PUSH H
MOV B,M
MVI C,0
INX H
FCMP01:
MOV A,M
CPI '.'
JM FCMP02
CPI '['
JP FCMP02
STAX D
INX D
INR C
FCMP02:
INX H
DCR B
JNZ FCMP01
POP H
MOV M,C
INX H
POP D
RET
; CREATE A DISK FILE
; USED FOR OUTPUT FILES ONLY
; INPUT: DE = @(FCB)
; OUTPUT: CARRY = ERROR
FREWRT:
MVI A,22 ; SET UP
STA FTEMP ; FOR CREATE
CALL FINIT
PUSH PSW
LHLD FPFBUF ; INITIALIZE
CALL FSVFBA ; POINTER
CALL FBCLR ; CLEAR BUFFER
POP PSW
RET
; OPEN A DISK FILE
; INPUT: DE = @(FCB)
; OUTPUT: CARRY = ERROR
FRESET:
MVI A,15 ; SET UP
STA FTEMP ; FOR OPEN
CALL FINIT
PUSH PSW
LHLD FPFBUF ; INITIALIZE
LXI D,128 ; POINTER
DAD D
CALL FSVFBA
POP PSW
RET
; CLOSE A DISK FILE
; INPUT: DE = @(FCB)
; OUTPUT: CARRY = ERROR
FCLOS:
CALL FADDR
LHLD FPFBUF ; WRITE
XCHG ; LAST
LHLD FXFBA ; RECORD
CALL FCPHL
CNZ FWRT02
MVI A,16 ; SET
STA FTEMP ; UP
LHLD FPFCB ; FOR
XCHG ; CLOSE
JMP FINIT
; DELETE A DISK FILE
; INPUT: DE = @(FCB)
; OUTPUT: CARRY = 0
FDELE:
MVI A,19 ; SET UP
STA FTEMP ; FOR DELETE
CALL FINIT
XRA A ; CLEAR CARRY
RET
; DISK INITIALIZATION
; INPUT: DE = @(FCB)
; FTEMP = COMMAND
; OUTPUT: CARRY = ERROR
FINIT:
CALL FADDR ; GET FCB ADDRS
CALL FSW ; SELECT DEVICE
LHLD FPFCB ; RETRIEVE
XCHG ; DE
LDA FTEMP ; GET COMMAND
MOV C,A ; CREATE/OPEN/CLOSE
CALL CPM ; OR DELETE FILE
PUSH PSW ; SAVE ERRORS
CALL FSW ; DEVICE
POP PSW ; RETRIEVE AND
CPI 0FFH ; TEST FOR
JZ FINT01 ; ERROR
XRA A ; NO
RET
FINT01:
STC ; SET
RET ; CARRY
; WRITE BYTE TO DISK BLOCK
; INPUT: DE = @(FCB)
; A = BYTE
; OUTPUT: CARRY = ERROR
FWRIT:
STA FTEMP ; SAVE BYTE
CALL FADDR ; GET FCB ADDRS
FWRT01:
LHLD FPFBUF
LXI D,128
DAD D
XCHG ; BUFFER END ADDR IN DE
LHLD FXFBA ; CURRENT ADDR IN HL
CALL FCPHL ; TEST FOR END OF BUFFER
JZ FWRT02 ; YES THEN WRITE
LDA FTEMP ; STORE DATA
MOV M,A ; BYTE IN BUFFER
INX H ; BUMP BUFFER POINTER
CALL FSVFBA ; AND SAVE IT
ORA A
RET
FWRT02:
CALL FSW ; SET DRIVE
LHLD FPFCB
XCHG
MVI C,21 ; WRITE
CALL CPM ; RECORD
PUSH PSW ; SAVE ERRORS
CALL FSW ; RESET DRIVE
POP PSW ; RETRIEVE AND
CPI 0 ; TEST FOR
JNZ FWRTER ; ERROR
LHLD FPFBUF ; RESET POINTER
CALL FSVFBA ; AND SAVE IT
CALL FBCLR ; CLEAR BUFFER
JMP FWRT01 ; CONTINUE
FWRTER:
STC ; FLAG ERROR
RET
; READ BYTE FROM DISK
; INPUT: DE = @(FCB)
; OUTPUT: A = BYTE
; CARRY = ERROR
FREAD:
CALL FADDR ; GET FCB ADDRS
FRD01:
LHLD FPFBUF
LXI D,128
DAD D
XCHG ; BUFFER END ADDR IN DE
LHLD FXFBA ; CURRENT PONTER IN HL
CALL FCPHL ; TEST FOR END OF BUFFER
JZ FRD02 ; YES SO GO READ
MOV A,M ; GET BYTE
INX H ; BUMP POINTER
CALL FSVFBA ; AND SAVE IT
ORA A ; RESET FLAG
RET
FRD02:
CALL FSW ; SET DRIVE
LHLD FPFCB
XCHG
MVI C,20 ; READ
CALL CPM ; BLOCK
PUSH PSW ; SAVE ERRORS
CALL FSW ; RESET DRIVE
POP PSW ; RETRIEVE AND
CPI 0 ; TEST FOR
JNZ FRDER ; ERROR
LHLD FPFBUF ; RESET
CALL FSVFBA ; POINTER
JMP FRD01
FRDER:
STC ; FLAG ERROR
RET
; DRIVE SWITCH PROCEDURE
FSW:
PUSH H
PUSH D
LHLD FPFBUF ; SET
XCHG ; DMA
MVI C,26
CALL CPM
MVI C,25 ; GET CURRENT
CALL CPM ; DRIVE NUMBER
MOV B,A
LHLD FPFDV
MOV E,M ; EXCHANGE
MOV M,B ; NUMBER
MVI C,14 ; TELL
CALL CPM ; CPM
POP D
POP H
RET
; FCB ADDRESS COMPUTER
; INPUT: DE = @(FCB)
FADDR:
PUSH H
PUSH D
XCHG
SHLD FPFCB
LXI D,FFBA
DAD D
SHLD FPFBA
MOV E,M
INX H
MOV D,M
XCHG
SHLD FXFBA
LHLD FPFCB
LXI D,FFDV
DAD D
SHLD FPFDV
LHLD FPFCB
LXI D,FFBUF
DAD D
SHLD FPFBUF
POP D
POP H
RET
; SAVE FBA PROCEDURE
; INPUT: HL = POINTER
FSVFBA:
SHLD FXFBA
XCHG
LHLD FPFBA
MOV M,E
INX H
MOV M,D
RET
; CLEAR OUTPUT BUFFER
FBCLR:
LHLD FPFBUF
MVI A,128
FSVF01:
MVI M,1AH
INX H
DCR A
JNZ FSVF01
RET
; DOUBLE PRECISION COMPARE
; INPUT: HL AND DE
; OUTPUT: EQUAL/NOT EQUAL
FCPHL:
MOV A,H
CMP D
RNZ
MOV A,L
CMP E
RET
; DATA STORAGE
FTEMP: DS 2
FPFCB: DS 2
FPFBA: DS 2
FXFBA: DS 2
FPFDV: DS 2
FPFBUF: DS 2
DS 32*2
STACK: DS 0