home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
BDOS
/
SUPRDOS2.LBR
/
DOS2.MZC
/
DOS2.MAC
Wrap
Text File
|
2000-06-30
|
44KB
|
1,498 lines
;
; SELECT DISK
;
CMND14: LD A,E ; COPY DRIVE NUMBER
;
; SELECT DISK
;
SELDK: AND 0FH ; MASK DRIVE NUMBER
LD B,A ; SAVE COUNTER
LD DE,(LOGIN) ; GET LOGIN VECTOR
OR A ; TEST DRIVE 'A'
JR Z,SELDK1 ; YES THEN JUMP
SELDK0: RR D ; SHIFT LOGIN VECTOR
RR E ; UNTIL BIT 0 REGISTER E
DJNZ SELDK0 ; IS CURRENT DRIVE
SELDK1: LD HL,DEFDRV ; GET POINTER LAST DRIVE
BIT 0,E ; TEST IF DRIVE LOGGED IN
JR Z,SELDK2 ; NO, LOGIN DRIVE
CP (HL) ; TEST SAME DRIVE
RET Z ; YES THEN EXIT
SELDK2: LD (HL),A ; SAVE NEW CURRENT DRIVE
PUSH DE ; SAVE DRIVE LOGGED IN FLAG
LD C,A ; COPY DRIVE NUMBER
CALL SELDSK ; DO P2BIOS SELECT
LD A,H ; TEST IF ERROR
OR L
JR Z,SELDK3 ; YES, ILLEGAL DRIVE NUMBER
LD E,(HL) ; GET LSB TRANSLATION VECTOR
INC HL ; INCREMENT POINTER
LD D,(HL) ; GET MSB TRANSLATION VECTOR
INC HL ; INCREMENT POINTER
LD (TRANS),DE ; SAVE TRANSLATION VECTOR
LD (TEMP0),HL ; SAVE ADDRESS TEMP0
INC HL ; INCREMENT TO NEXT ADDRESS
INC HL
LD (TEMP1),HL ; SAVE ADDRESS TEMP1
INC HL ; INCREMENT TO NEXT ADDRESS
INC HL
LD (TEMP2),HL ; SAVE ADDRESS TEMP2
INC HL ; INCREMENT TO NEXT ADDRESS
INC HL
LD DE,DIRBUF ; LOAD DIRBUF POINTER
LD BC,8 ; COPY 8 BYTES
LDIR
LD HL,(IXP) ; GET DRIVE PARAMETER ADDRESS
LD C,15 ; COPY 15 BYTES
LDIR
POP DE ; GET DRIVE LOGGED IN FLAG
BIT 0,E ; TEST IT
RET NZ ; DRIVE LOGGED IN SO RETURN
LD HL,(LOGIN) ; GET LOGIN VECTOR
CALL SDRVB ; SET DRIVE BIT IN LOGIN VECTOR
LD (LOGIN),HL ; SAVE LOGIN VECTOR
JR INITDR ; AND SETUP DRIVE TABLES
SELDK3: LD HL,(STSEL) ; LOAD ERROR MESSAGE ADDRESS
JP (HL) ; AND DISPLAY ERROR
;
; INIT DRIVE
; CLEAR ALV BIT BUFFER AFTER DRIVE RESET
;
INITDR: LD DE,(MAXLEN) ; GET LENGTH ALV BUFFER-1 (BITS)
LD A,3 ; DIVIDE BY 8
INITD0: SRL D ; TO GET BYTES
RR E
DEC A
JR NZ,INITD0
INC DE ; INCREMENT, SO ALL BITS ARE CLEARED
LD HL,(ALV) ; GET POINTER ALV BUFFER
PUSH HL
INITD1: LD (HL),0 ; CLEAR 8 BITS
INC HL ; INCREMENT POINTER
DEC DE ; DECREMENT COUNTER
LD A,D ; TEST IF COUNTER ZERO
OR E
JR NZ,INITD1 ; NOT THEN JUMP
POP HL ; GET ALV POINTER
LD DE,(NDIR0) ; GET FIRST TWO BYTES ALV BUFFER
LD (HL),E ; SAVE LSB
INC HL ; INCREMENT POINTER
LD (HL),D ; SAVE MSB
LD HL,(TEMP0) ; CLEAR NUMBER OF FILES
XOR A ; ON THIS DRIVE
LD (HL),A ; CLEAR LSB
INC HL ; INCREMENT POINTER
LD (HL),A ; CLEAR MSB
LD (SUBFLG),A ; CLEAR SUBMIT FLAG (RESET DISK COMMAND)
CALL SETFCT ; SET FILE COUNT
INITD2: LD A,0FFH ; UPDATE DIRECTORY CHECKSUM
CALL RDDIR ; READ FCB'S FROM DIRECTORY
CALL TSTFCT ; TEST LAST FCB
RET Z ; YES THEN EXIT
CALL CALDIR ; CALCULATE ENTRY POINT FCB
LD A,(HL) ; GET FIRST BYTE FCB
CP 0E5H ; TEST EMPTY DIRECTORY ENTRY
JR Z,INITD2 ; YES THEN GET NEXT FCB
CP 021H ; TEST TIME STAMP
JR Z,INITD2 ; YES THEN GET NEXT FCB
LD A,(USER) ; GET USER NUMBER
CP (HL) ; TEST IF USER IS SAME
JR NZ,INITD3 ; NO THEN JUMP
INC HL ; POINT TO FILE NAME
LD A,(HL) ; GET FIRST CHAR FILENAME
SUB '$' ; TEST IF '$'
JR NZ,INITD3 ; NOT THEN JUMP
DEC A ; LOAD A WITH 0FFH
LD (SUBFLG),A ; SAVE IT IN SUBFLG
INITD3: LD C,1 ; SET BIT IN ALV BUFFER
CALL FILLBB ; SET BITS FROM FCB IN ALV BUFFER
CALL SETLF ; UPDATE LAST FILE COUNT
JR INITD2 ; AND GET NEXT FCB
;
; SET DRIVE BIT IN HL
;
SDRVB: EX DE,HL ; COPY HL=>DE
LD HL,1 ; GET MASK DRIVE "A"
LD A,(DEFDRV) ; GET CURRENT DRIVE
OR A ; TEST IF DRIVE "A"
JR Z,SDRVB1 ; YES THEN DONE
SDRVB0: ADD HL,HL ; GET NEXT MASK
DEC A ; DECREMENT DRIVE COUNTER
JR NZ,SDRVB0 ; AND TEST IF DONE
SDRVB1: LD A,D ; HL=HL OR DE
OR H
LD H,A
LD A,E
OR L
LD L,A
RET ; EXIT
;
; CALCULATE SECTOR/TRACK DIRECTORY
;
STDIR: LD HL,(FILCNT) ; GET FCB COUNTER DIRECTORY
SRL H ; DIVIDE BY 4
RR L ; (4 FCB'S / SECTOR)
SRL H
RR L
LD (RECDIR),HL ; SAVE VALUE (USED BY CHECKSUM)
EX DE,HL ; COPY IT TO DE
LD HL,0 ; CLEAR HL
;
; CALCULATE SECTOR/TRACK
; ENTRY: HL,DE=SECTOR NUMBER (128 BYTE SECTOR)
; RESULT SET TRACK =HL,DE / MAXSEC
; SET SECTOR =HL,DE MOD MAXSEC
;
CALST: LD BC,(MAXSEC) ; GET SECTORS/TRACK
LD A,17 ; SET UP LOOP COUNTER
CALST0: OR A ; TEST HL>=BC
SBC HL,BC
CCF
JR C,CALST1 ; YES THEN JUMP
ADD HL,BC ; NO THEN RETORE HL
OR A ; AND CLEAR CARRY
CALST1: RL E ; SHIFT RESULT IN DE
RL D
DEC A ; TEST LAST BIT DONE
JR Z,CALST2 ; YES THEN EXIT
RL L ; SHIFT NEXT BIT IN HL
RL H
JR CALST0 ; CONTINUE
CALST2: PUSH HL ; SAVE SECTOR NUMBER
LD HL,(NFTRK) ; GET FIRST TRACK
ADD HL,DE ; ADD TRACK NUMBER
LD B,H ; COPY IT TO BC
LD C,L
CALL SETTRK ; P2BIOS CALL SET TRACK
POP BC ; RESTORE SECTOR NUMBER
LD DE,(TRANS) ; GET TRANSLATION TABLE ADDRESS
CALL SECTRN ; P2BIOS CALL SECTOR TRANSLATION
LD B,H ; COPY RESULT TO BC
LD C,L
JP SETSEC ; P2BIOS CALL SET SECTOR
;
; GET DISK MAP BLOCK NUMBER FROM FCB
; EXIT HL=ADDRESS FCB
; DE=DM
; BC=OFFSET IN DM
;
GETDM: LD C,(IX+32) ; GET NEXT RECORD
LD A,(NBLOCK) ; GET NUMBER OF BLOCKS
LD B,A ; SAVE IT
GETDM0: SRL C ; SHIFT NEXT RECORD
DJNZ GETDM0 ; NUMBER OF BLOCKS TIMES
GETDM1: CPL ; COMPLEMENT NUMBER OF BLOCKS
ADD A,9 ; ADD 9
LD B,A ; B=8-NUMBER OF BLOCKS
LD A,(NEXTND) ; GET EXTENT MASK
AND (IX+12) ; MASK WITH EXTENT
RRCA ; ROTATE ONE RIGHT
GETDM2: RLCA ; ROTATE ONE LEFT
DJNZ GETDM2 ; 8-NUMBER OF BLOCKS TIMES
GETDM3: ADD A,C ; ADD THE TWO VALUES TO GET ENTRY FCB
GETDM4: PUSH IX ; GET FCB ADDRESS
POP HL
LD C,16 ; ADD OFFSET 16 TO POINT TO DM
ADD HL,BC
LD C,A ; ADD ENTRY FCB
ADD HL,BC
LD A,(MAXLEN+1) ; TEST 8 BITS/16 BITS FCB ENTRY
OR A
JR NZ,GETDM5 ; 16 BITS => JUMP
LD E,(HL) ; GET 8 BIT VALUE
LD D,0 ; MAKE MSB ZERO
RET ; AND EXIT
GETDM5: ADD HL,BC ; ADD TWICE (16 BIT VALUES)
LD E,(HL) ; GET LSB
INC HL ; INCREMENT POINTER
LD D,(HL) ; GET MSB
DEC HL ; DECREMENT POINTER
RET ; AND EXIT
;
; CALCULATE SECTOR NUMBER
; ENTRY: DE=BLOCK NUMBER FROM FCB
;
CALSEC: LD HL,0 ; CLEAR MSB SECTOR NUMBER
LD A,(NBLOCK) ; GET LOOP COUNTER
LD B,A ; SAVE IT IN B
CALSC0: SLA E ; SHIFT L,D,E
RL D
RL L
DJNZ CALSC0 ; B TIMES
CALSC1: LD A,(NMASK) ; GET SECTOR MASK
AND (IX+32) ; AND WHIT NEXT RECORD
OR E ; SET UP LSB SECTOR NUMBER
LD E,A
RET ; AND EXIT
;
; CALCULATE DIRBUF ENTRY POINT
;
CALDIR: LD HL,(DIRBUF) ; GET START ADDRESS DIRBUF
LD A,(SECPNT) ; GET SECTOR POINTER
ADD A,L ; ADD L=L+A
LD L,A
RET NC ; NO CARRY EXIT
INC H ; INCREMENT H
RET ; AND EXIT
;
; INIT FILE COUNT
;
SETFCT: LD HL,-1 ; SET UP FILE COUNT
LD (FILCNT),HL ; SAVE IT
RET ; AND EXIT
;
; TEST FILE COUNT
;
TSTFCT: LD HL,(FILCNT) ; TEST FILE COUNT=0FFFFH
LD A,H ; GET MSB
AND L ; AND LSB
INC A ; TEST IF RESULT=0FFH
RET ; AND EXIT
;
; SET LAST FILE
;
SETLF: CALL TSTLF ; TEST LAST FILE
RET C ; NO THEN EXIT
INC DE ; INCREMENT LAST FILE
LD (HL),D ; SAVE IT IN TEMP0
DEC HL
LD (HL),E
RET ; AND EXIT
;
; TEST LAST FILE
;
TSTLF: LD HL,(TEMP0) ; GET POINTER TO LAST FILE
LD DE,(FILCNT) ; GET FILE COUNTER
LD A,E ; SUBTRACT DE-(HL)
SUB (HL)
INC HL
LD A,D
SBC A,(HL)
RET ; EXIT
;
; GET NEXT FCB FROM DRIVE
; ENTRY A=0 CHECK CHECKSUM, A=0FFH UPDATE CHECKSUM
;
RDDIR: LD C,A ; SAVE CHECKSUM FLAG
LD HL,(FILCNT) ; GET FILE COUNTER
INC HL ; INCREMENT IT
LD (FILCNT),HL ; AND SAVE IT
LD DE,(NFILES) ; GET MAXIMUM NUMBER OF FILES
OR A ; CLEAR CARRY
SBC HL,DE ; TEST IF LAST FILE
ADD HL,DE
JR Z,RDDIR0 ; NO JUMP
JR NC,SETFCT ; YES SET FILE COUNT TO 0FFFFH
RDDIR0: LD A,L ; GET FILE COUNT LSB
ADD A,A ; *32
ADD A,A
ADD A,A
ADD A,A
ADD A,A
AND 060H ; MASK IT
LD (SECPNT),A ; SAVE IT FOR LATER USE
RET NZ ; RETURN IF NOT FISRT FCB SECTOR
PUSH BC ; SAVE CHECKSUM FLAG
CALL STDIR ; CALCULATE SECTOR/TRACK DIRECTORY
CALL READDR ; READ SECTOR DIRECTORY
POP BC ; RESTORE CHECKSUM FLAG
;
; UPDATE/CHECK CHECKSUM DIRECTORY
; ENTRY C=0 CHECK CHECKSUM, C=0FFH UPDATE CHECKSUM
;
CHKDIR: LD HL,(NCHECK) ; GET NUMBER OF CHECKED RECORDS
LD DE,(RECDIR) ; GET CURRENT RECORD
OR A ; CLEAR CARRY
SBC HL,DE ; TEST CURRENT RECORD
RET Z ; EXIT IF ZERO
RET C ; EXIT IF GREATER THEN NCHECK
LD HL,(DIRBUF) ; GET DIRBUF
LD B,128 ; SET UP COUNTER
XOR A ; CLEAR CHECKSUM
CHKDR0: ADD A,(HL) ; ADD CHECKSUM
INC HL ; INCREMENT POINTER
DJNZ CHKDR0 ; 128 TIMES
LD HL,(CSV) ; GET POINTER CHECKSUM DIRECTORY
ADD HL,DE ; ADD CURRENT RECORD
INC C ; TEST CHECKSUM FLAG
JR Z,CHKDR1 ; 0FFH=> UPDATE CHECKSUM
CP (HL) ; TEST CHECKSUM
RET Z ; EXIT IF OK
;Automatic disk logging--instead of setting read/only flag when disk is
;changed, a disk changed flag is set. The disk is reset when the SEARCH
;routine is called.
; JP SETWPD
LD A,TRUE ; set disk changed flag
LD (DIFF),A
JP SETFN ; set number of files
CHKDR1: LD (HL),A ; UPDATE CHECKSUM
RET ; AND EXIT
;
; READ SECTOR FROM DRIVE
;
;
;Readr and Writer modified to give separate error messages--B.H.
READR: CALL READ ; P2BIOS CALL READ SECTOR
LD HL,(SRDERR)
JR WRITE0
;
; WRITE SECTOR ON DRIVE
;
WRITER: CALL WRITE ; P2BIOS CALL WRITE SECTOR
LD HL,(SWRTER)
WRITE0: OR A ; TEST EXIT CODE
RET Z ; EXIT IF OK
LD A,1
LD (RETFLG),A
JP (HL) ; P2DOS ERROR ON D: BAD SECTOR
;
; READ DIRECTORY FROM DRIVE
;
READDR: CALL DMADIR ; SET UP DMA DIRECTORY
CALL READR ; READ RECORD
JR STDMA ; SET UP DMA USER
;
; WRITE DIRECTORY ON DRIVE
;
WRITDR: LD C,0FFH ; UPDATE CHECKSUM DIRECTORY
CALL CHKDIR
CALL DMADIR ; SET UP DMA DIRECTORY
LD C,1 ; WRITE DIRECTORY FLAG
CALL WRITER ; WRITE RECORD
JR STDMA ; SET UP DMA USER
;
; SET DMA ADDRESS COMMAND
;
CMND26: LD (DMA),DE ; SAVE DMA ADDRESS
;
; SET DMA ADDRESS
;
STDMA: LD BC,(DMA) ; GET DMA ADDRESS
JR DMADR0 ; AND DO P2BIOS CALL
;
; SET DMA ADDRESS DIRECTORY
;
DMADIR: LD BC,(DIRBUF) ; GET DMA ADDRESS DIRECTORY
DMADR0: JP SETDMA ; P2BIOS CALL SET DMA
;
; GET BIT FROM ALV BUFFER
; ENTRY DE=BLOCK NUMBER
; EXIT A =BIT IN LSB
; B =BITNUMBER IN A
; HL=POINTER IN ALV BUFFER
;
GETBIT: LD A,E ; GET BIT NUMBER
AND 7 ; MASK IT
INC A ; ADD 1
LD B,A ; SAVE IT
LD C,A ; TWICE
SRL D ; GET BYTE NUMBER
RR E ; DE=DE/8
SRL D
RR E
SRL D
RR E
LD HL,(ALV) ; GET START ADDRESS ALV BUFFER
ADD HL,DE ; ADD BYTE NUMBER
LD A,(HL) ; GET 8 BITS
GETBT0: RLCA ; GET CORRECT BIT
DJNZ GETBT0
LD B,C ; RESTORE BIT NUMBER
RET ; AND RETURN TO CALLER
;
; SET/RESET BIT IN ALV BUFFER
; ENTRY DE=BLOCK NUMBER
; C =0 RESET BIT, C=1 SET BIT
;
SETBIT: PUSH BC ; SAVE SET/RESET BIT
CALL GETBIT ; GET BIT
AND 0FEH ; MASK IT
POP DE ; GET SET/RESET BIT
OR E ; SET/RESET BIT
SETBT0: RRCA ; ROTATE BIT IN CORRECT POSITION
DJNZ SETBT0
LD (HL),A ; SAVE 8 BITS
RET ; AND RETURN TO CALLER
;
; FILL BIT BUFFER FROM FCB IN DIRBUF
; ENTRY C=0 RESET BIT, C=1 SET BIT
;
FILLBB: CALL CALDIR ; GET DIRECTORY ENTRY
LD DE,16 ; GET OFFSET DM BLOCK
ADD HL,DE ; ADD OFFSET
LD B,E ; GET BLOCK COUNTER
FILLB0: LD E,(HL) ; GET LSB BLOCK NUMBER
INC HL ; INCREMENT POINTER
LD D,0 ; RESET MSB BLOCK NUMBER
LD A,(MAXLEN+1) ; TEST >256 BLOCKS PRESENT
OR A
JR Z,FILLB1 ; NO THEN JUMP
DEC B ; DECREMENT BLOCK COUNTER
LD D,(HL) ; GET CORRECT MSB
INC HL ; INCREMENT POINTER
FILLB1: LD A,D ; TEST BLOCK NUMBER
OR E
JR Z,FILLB2 ; ZERO THEN GET NEXT BLOCK
PUSH HL ; SAVE POINTER
PUSH BC ; SAVE COUNTER AND SET/RESET BIT
LD HL,(MAXLEN) ; GET MAXIMUM LENGTH ALV BUFFER
OR A ; RESET CARRY
SBC HL,DE ; TEST DE<=MAXLEN ALV BUFFER
CALL NC,SETBIT ; YES THEN INSERT BIT
POP BC ; GET COUNTER AND SET/RESET BIT
POP HL ; GET POINTER
FILLB2: DJNZ FILLB0 ; REPEAT FOR ALL DM ENTRIES
RET ; AND RETURN TO CALLER
;
; SET WRITE PROTECT DISK COMMAND
;
CMND28:
;
; SET WRITE PROTECT DISK
;
SETWPD: LD HL,(DSKRO) ; GET DISK R/O VECTOR
CALL SDRVB ; INCLUDE DRIVE BIT
LD (DSKRO),HL ; SAVE DISK R/O BIT
SETFN: LD DE,(NFILES) ; GET MAXIMUM NUMBER OF FILES-1
INC DE ; INCREMENT IT
LD HL,(TEMP0) ; GET POINTER TO DISK PARAMETER BLOCK
LD (HL),E ; AND SAVE NUMBER OF FILES
INC HL
LD (HL),D
RET ; AND RETURN TO CALLER
;
; CHECK FILE R/O BIT
;
CHKFRO: CALL CALDIR ; GET DIRECTORY ENTRY
CHKFR0: LD DE,2 ; OFFSET TO PUBLIC FILE BIT
ADD HL,DE ; ADD OFFSET
BIT 7,(HL) ; TEST PUBLIC FILE
JR NZ,CHKFR1 ; YES THEN ERROR
LD E,7 ; OFFSET TO FILE R/O BIT
ADD HL,DE ; ADD OFFSET
BIT 7,(HL) ; TEST FILE R/O
JR NZ,CHKFR1 ; YES THEN ERROR
;system files should not be r/o for CP/M compatibility-B.H.
; INC HL ; INCREMENT TO SYSTEM FILE
; BIT 7,(HL) ; TEST SYSTEM FILE
RET Z ; NO SYSTEM FILE THEN OK
CHKFR1: LD HL,(SFILRO) ; GET POINTER TO FILE R/O MESSAGE
JP (HL) ; DISPLAY MESSAGE
;
; CHECK DRIVE READ ONLY
;
CHKRO: LD HL,(DSKRO) ; GET DRIVE R/O VECTOR
CALL SDRVB ; SET DRIVE BIT
SBC HL,DE ; TEST EXTRA BIT ADDED
RET NZ ; YES THEN DRIVE NOT R/O
LD HL,(STRO) ; GET POINTER TO DRIVE R/O MESSAGE
JP (HL) ; DISPLAY MESSAGE
;
; GET FREE BLOCK FROM ALV BUFFER
; ENTRY DE=OLD BLOCK NUMBER
; EXIT DE=NEW BLOCK NUMBER (0 IF NO FREE BLOCK)
; HL COUNTS UP,DE COUNTS DOWN
;
GETFRE: LD H,D ; COPY OLD BLOCK TO HL
LD L,E
GETFR0: LD A,D ; TEST DOWN COUNTER IS ZERO
OR E
JR Z,GETFR1 ; YES THEN JUMP
DEC DE ; DECREMEMT DOWN COUNTER
PUSH HL ; SAVE UP/DOWN COUNTER
PUSH DE
CALL GETBIT ; GET BIT FROM ALV BUFFER
RRA ; TEST IF ZERO
JR NC,GETFR3 ; YES THEN FOUND EMPTY BLOCK
POP DE ; GET UP/DOWN COUNTER
POP HL
GETFR1: LD BC,(MAXLEN) ; GET MAXIMUM ALV LENGTH-1 IN BC
OR A ; CLEAR CARRY
SBC HL,BC ; TEST HL>=LENGTH ALV-1
ADD HL,BC ; RESTORE HL (FLAGS ARE NOT AFFECTED)
JR NC,GETFR2 ; END BUFFER THEN JUMP
INC HL ; INCREMENT UP COUNTER
PUSH DE ; SAVE DOWN/UP COUNTER
PUSH HL
EX DE,HL ; SAVE UP COUNTER IN DE
CALL GETBIT ; GET BIT FROM ALV BUFFER
RRA ; TEST IF ZERO
JR NC,GETFR3 ; YES THEN FOUND EMPTY BLOCK
POP HL ; GET DOWN/UP COUNTER
POP DE
JR GETFR0 ; AND TEST NEXT BLOCK
GETFR2: LD A,D ; TEST IF LAST BLOCK TESTED
OR E
JR NZ,GETFR0 ; NO THEN TEST NEXT BLOCK
RET ; EXIT (DE=0)
GETFR3: SCF ; SET BLOCK NUMBER USED
RLA ; SAVE BIT
CALL SETBT0 ; PUT BIT IN ALV BUFFER
POP DE ; GET CORRECT COUNTER
POP HL ; RESTORE STACK POINTER
RET ; EXIT (DE=BLOCK NUMBER)
;
; SEARCH FOR FILE NAME
; ENTRY: A : NUMBER OF BYTES TO SEARCH FOR
;
SEARCH: PUSH AF
LD HL,DIFF ;Reset disk if it has changed
XOR A
CP (HL)
JR Z,S1
CALL CLRDSK
S1: POP AF
LD (SEARNB),A ; SAVE NUMBER OF BYTES
LD A,0FFH ; SET EXIT CODE TO 0FFH (NOT FOUND)
LD (SEAREX),A
LD (DCOPY),IX ; COPY FCB POINTER TO RAM (SEARCH NEXT)
CALL SETFCT ; INITIATE FILE COUNTER
;Mod 0.1 had a bug in which the directory of a changed disk would not be
;read. Adding CALL HOME forces a directory read--B.H.
;
CALL HOME
;
; SEARCH NEXT FILE NAME
;
SEARCN: XOR A ; CHECK CHECKSUM DIRECTORY
CALL RDDIR ; GET FCB FROM DIRECTORY
CALL TSTFCT ; TEST IF PAST LAST ENTRY
JR Z,SEARC8 ; YES THEN JUMP
LD DE,(DCOPY) ; GET FCB POINTER
LD A,(DE) ; GET FIRST BYTE
CP 0E5H ; TEST IF SEARCHING EMPTY DIRECTORY
JR Z,SEARC1 ; YES THEN JUMP
PUSH DE ; SAVE FCB POINTER
CALL TSTLF ; TEST LAST FILE ON THIS DRIVE
POP DE ; RESTORE FCB POINTER
JR NC,SEARC8 ; YES THEN JUMP
SEARC1: CALL CALDIR ; GET ENTRY IN DIRECTORY
LD A,(HL) ; GET FIRST BYTE DIRECTORY ENTRY
CP 021H ; TEST TIME STAMP
JR Z,SEARCN ; YES THEN GET NEXT DIRECTORY ENTRY
LD A,(SEARNB) ; GET NUMBER OF BYTES TO SEARCH FOR
LD B,A ; SAVE IT IN COUNTER
XOR A ; CLEAR ACCU
LD (SEARQU),A ; CLEAR QUESTION MARK DETECTED FLAG
LD (SEARPU),A ; CLEAR PUBLIC FILE FLAG
LD C,A ; CLEAR COUNTER
SEARC2: LD A,B ; TEST IF COUNTER IS ZERO
OR A
JR Z,SEARC9 ; YES THEN JUMP
LD A,(DE) ; GET BYTE FROM FCB
SUB '?' ; TEST IF QUESTION MARK
JR Z,SEARC6 ; YES THEN JUMP
LD A,C ; GET FCB COUNTER
OR A ; TEST FIRST BYTE
JR NZ,SEARC3 ; NO THEN JUMP
LD A,(FLAGS) ; GET FLAG BYTE
BIT 0,A ; TEST PUBLIC FILE ENABLE
JR Z,SEARC3 ; NO THEN JUMP
INC HL ; GET POINTER TO PUBLIC BIT
INC HL
BIT 7,(HL) ; TEST PUBLIC BIT DIRECTORY
DEC HL ; RESTORE POINTER
DEC HL
JR Z,SEARC3 ; NO PUBLIC FILE THEN JUMP
LD A,(DE) ; GET FIRST BYTE FCB
CP 0E5H ; TEST IF SEARCHING EMPTY DIRECTORY
JR Z,SEARC3 ; YES THEN JUMP
XOR (HL) ; TEST FCB=DIRECTORY ENTRY
AND 07FH ; MASK IT
JR Z,SEARC5 ; YES THEN JUMP
AND 0E0H ; MASK USER NUMBER
JR NZ,SEARC3 ; NOT THE SAME THEN JUMP
DEC A ; A=0FFH
LD (SEARPU),A ; SET PUBLIC FILE FOUND
JR SEARC5 ; JUMP FOUND
SEARC3: LD A,C ; GET FCB COUNTER
CP 13 ; TEST IF USER CODE
JR Z,SEARC5 ; YES THEN NO TEST
CP 12 ; TEST IF EXTENT NUMBER
LD A,(DE) ; GET BYTE FROM FCB
JR Z,SEARC7 ; JUMP IF EXTENT NUMBER
XOR (HL) ; TEST BYTE FCB=BYTE DIRECTORY ENTRY
AND 07FH ; MASK IT
SEARC4: JR NZ,SEARCN ; NOT THE SAME THEN GET NEXT ENTRY
SEARC5: INC DE ; INCREMENT POINTER FCB
INC HL ; INCREMENT POINTER DIRECTORY ENTRY
INC C ; INCREMENT COUNTER
DEC B ; DECREMENT COUNTER
JR SEARC2 ; TEST NEXT BYTE
SEARC6: DEC A ; SET QUESTION MARK FOUND FLAG
LD (SEARQU),A
JR SEARC5 ; JUMP FOUND
SEARC7: PUSH BC ; SAVE COUNTERS
XOR (HL) ; TEST EXTENTS
LD B,A ; SAVE IT
LD A,(NEXTND) ; GET EXTENT MASK
CPL ; COMPLEMENT IT
AND 01FH ; MASK IT
AND B ; MASK EXTENTS
POP BC ; RETORE COUNTERS
JR SEARC4 ; AND TEST RESULT
SEARC8: CALL SETFCT ; ERROR SET FILE COUNTER
LD A,0FFH ; AND SET EXIT CODE
LD (PEXIT),A
RET ; RETURN TO CALLER
SEARC9: LD A,(SEARQU) ; GET QUESTION MARK FOUND FLAG
LD B,A ; SAVE IT
LD A,(SEARPU) ; GET PUBLIC FILE FLAG
AND B ; TEST IF PUBLIC FILE AND QUESTION MARK
JR NZ,SEARC4 ; YES THEN SEARCH FOR NEXT ENTRY
CALL SETLF ; UPDATE LAST FILE COUNT (EMPTY FCB)
LD A,(FILCNT) ; GET FILE COUNTER
AND 3 ; MASK IT
LD (PEXIT),A ; AND SET EXIT CODE
XOR A ; CLEAR EXIT CODE SEARCH
LD (SEAREX),A
RET ; AND RETURN TO CALLER
;
;DELETE FILE
;
DELETE: CALL CHKRO ; CHECK DISK R/O
LD A,12 ; NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
DEL0: CALL TSTFCT ; TEST IF FILE FOUND
RET Z ; NOT THEN EXIT
CALL CHKFRO ; CHECK FILE R/O
CALL CALDIR ; GET ENTRY POINT DIRECTORY
LD (HL),0E5H ; REMOVE FILE
LD C,0 ; REMOVE BITS ALV BUFFER
CALL FILLBB
CALL WRFCB1 ; WRITE DIRECTORY BUFFER ON DISK
CALL SEARCN ; SEARCH NEXT ENTRY
JR DEL0 ; AND TEST IT
;
; RENAME FILE
;
RENAM: CALL CHKRO ; CHECK DISK R/O
LD A,12 ; NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
RENAM0: CALL TSTFCT ; TEST IF FILE FOUND
RET Z ; NOT THEN EXIT
CALL CHKFRO ; CHECK FILE R/O
LD BC,12*256+16 ; COPY FCB+16 TO DIRECTORY+0 12 TIMES
CALL WRFCB ; AND WRITE DIRECTORY ON DISK
CALL SEARCN ; SEARCH NEXT FILE
JR RENAM0 ; AND TEST IT
;
; CHANGE STATUS FILE
;
CSTAT: CALL CHKRO ; CHECK DISK R/O
LD A,12 ; NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
CSTAT0: CALL TSTFCT ; TEST IF FILE FOUND
RET Z ; NOT THEN EXIT
LD BC,12*256+0 ; COPY FCB+0 TO DIRECTORY+0 12 TIMES
CALL WRFCB ; AND WRITE DIRECTORY TO DISK
CALL SEARCN ; SEARCH NEXT FILE
JR CSTAT0 ; AND TEST IT
;
; COMPUTE FILE SIZE
;
FILSZ: LD BC,0 ; RESET FILE SIZE LENGTH
LD D,C
CALL LDRRC ; SAVE IT IN FCB+33,34,35
LD A,12 ; NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
FILSZ0: CALL TSTFCT ; TEST IF FILE FOUND
RET Z ; NOT THEN EXIT
CALL CALDIR ; GET DIRECTORY ENTRY
EX DE,HL ; COPY TO DE
LD HL,15 ; OFFSET TO NEXT RECORD
CALL CALRRC ; CALCULATE RANDOM RECORD COUNT
LD A,D ; TEST LSB < (IX+33)
SUB (IX+33)
LD A,C ; TEST ISB < (IX+34)
SBC A,(IX+34)
LD A,B ; TEST MSB < (IX+35)
SBC A,(IX+35)
CALL NC,LDRRC ; WRITE NEW MAXIMUM
CALL SEARCN ; SEARCH NEXT FILE
JR FILSZ0 ; AND TEST IT
;
; WRITE FCB ON DISK
;
WRFCB: CALL CALDIR ; GET DIRECTORY ENTRY
PUSH HL ; SAVE POINTER
LD A,(HL) ; GET USER CODE
EX DE,HL ; COPY TO DE
PUSH IX ; SAVE FCB ENTRY
POP HL ; GET IT IN HL
PUSH BC ; SAVE BC
LD B,0 ; RESET B FOR ADD
ADD HL,BC ; ADD OFFSET FCB
POP BC ; RESTORE BC
LD C,B ; GET NUMBER OF BYTES TO MOVE
LD B,0 ; RESET B FOR LDIR
LDIR ; MOVE BYTES
POP HL ; GET POINTER USER CODE
LD (HL),A ; RESTORE IT
WRFCB1: CALL STDIR ; CALCULATE SECTOR/TRACK DIRECTORY
JP WRITDR ; WRITE DIRECTORY ON DISK
;
; FIND FILE
;
FINDF: LD A,15 ; NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
CALL TSTFCT ; TEST IF FILE PRESENT
RET NZ ; YES THEN EXIT
LD A,(RDWR) ; TEST IF WRITE FUNCTION
OR A
RET NZ ; YES THEN EXIT
LD A,(SEARQU) ; TEST IF QUESTION MARK USED
OR A
RET NZ ; YES THEN EXIT
LD HL,(PATH) ; GET PATH ADDRESS
LD A,H ; TEST IF ZERO (NO PATH)
OR L
RET Z ; YES THEN EXIT
FINDF0: LD A,(HL) ; GET FIRST ENTRY PATH NAME
INC HL ; INCREMENT POINTER
OR A ; TEST IF LAST ENTRY
JP Z,SEARC8 ; YES THEN ERROR EXIT
AND 07FH ; MASK DRIVE NUMBER
CP '$' ; TEST IF CURRENT DRIVE
JR NZ,FINDF1 ; NO THEN JUMP
LD A,(DRIVE) ; GET CURRENT DRIVE
INC A ; INCREMENT DRIVE NUMBER
FINDF1: DEC A ; DECREMENT DRIVE NUMBER
PUSH HL ; SAVE PATH POINTER
CALL SELDK ; SELECT DRIVE
POP HL ; RESTORE PATH POINTER
LD A,(HL) ; GET USER NUMBER
INC HL ; ADVANCE POINTER
AND 07FH ; MASK USER NUMBER
CP '$' ; TEST IF CURRENT USER
JR NZ,FINDF2 ; NO THEN JUMP
LD A,(USER) ; GET CURRENT USER
FINDF2: AND 01FH ; MASK USER NUMBER
LD B,A ; SAVE IT
LD A,(IX+0) ; GET FCB BYTE 0
AND 0E0H ; REMOVE USER NUMBER
OR B ; ADD NEW USER NUMBER
LD (IX+0),A ; AND SAVE IT
PUSH HL ; SAVE PATH POINTER
LD A,15 ; SET NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
CALL TSTFCT ; TEST IF FILE PRESENT
POP HL ; RESTORE PATH POINTER
JR Z,FINDF0 ; NO THEN TEST NEXT PATH ENTRY
PUSH HL ; SAVE PATH POINTER
CALL CALDIR ; GET DIRECTORY ENTRY
LD DE,10 ; ADD OFFSET SYSTEM BIT
ADD HL,DE
BIT 7,(HL) ; TEST SYSTEM FILE
POP HL ; RESTORE PATH POINTER
JR Z,FINDF0 ; NO SYSTEM FILE THEN TEST NEXT PATH
; ENTRY
LD A,(DEFDRV) ; GET CURRENT DRIVE
INC A ; INCREMENT DRIVE NUMBER
LD (FCB0),A ; SAVE IT IN EXIT FCB0
RET ; AND RETURN TO CALLER
;
; OPEN FILE COMMAND
;
CMND15:
CALL SELDRV ; SELECT DRIVE FROM FCB
LD (IX+14),0 ; CLEAR FCB+14
;
; OPEN FILE
;
OPENF: CALL FINDF ; FIND FILE (USE PATH NAME)
CALL TSTFCT ; TEST FILE FOUND
RET Z ; NO THEN EXIT
OPENF0: LD A,(IX+12) ; GET EXTENT NUMBER FROM FCB
PUSH AF ; SAVE IT
CALL CALDIR ; GET DIRECTORY ENTRY
PUSH IX ; SAVE FCB ENTRY
POP DE ; GET IN IN DE
LD BC,32 ; NUMBER OF BYTES TO MOVE
LDIR ; MOVE DIRECTORY TO FCB
SET 7,(IX+14) ; SET FCB/FILE NOT MODIFIED
LD B,(IX+12) ; GET EXTENT NUMBER
LD C,(IX+15) ; GET NEXT RECORD NUMBER
POP AF ; GET OLD EXTENT NUMBER
LD (IX+12),A ; SAVE IT
CP B ; COMPARE OLD AND NEW EXTENT NUMBER
JR Z,OPENF1 ; SAME THEN JUMP
LD C,0 ; SET NEXT RECORD COUNT TO 0
JR NC,OPENF1 ; OLD EXTENT >= NEW EXTENT THEN JUMP
LD C,80H ; SET NEXT RECORD COUNT TO MAXIMUM
OPENF1: LD (IX+15),C ; SAVE NEXT RECORD COUNT
RET ; AND RETURN TO CALLER
;
; CLOSE FILE COMMAND
;
CMND16: CALL SELDRV ; SELECT DRIVE FROM FCB
;
; CLOSE FILE
;
CLOSE: BIT 7,(IX+14) ; TEST FCB/FILE MODIFIED
RET NZ ; NOT THEN NO CLOSE REQUIRED
CALL CHKRO ; TEST DISK R/O
LD A,15 ; NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH FILE
CALL TSTFCT ; TEST FILE PRESENT
RET Z ; NO THEN EXIT
CALL CHKFRO ; CHECK FILE R/O
CALL CALDIR ; GET DIRECTORY ENTRY
LD BC,16 ; OFFSET TO DM BLOCK
ADD HL,BC ; ADD OFFSET
EX DE,HL ; SAVE HL IN DE
PUSH IX ; SAVE FCB POINTER
POP HL ; GET IT IN HL
ADD HL,BC ; ADD OFFSET
LD A,(MAXLEN+1) ; TEST NUMBER OF BLOCK >= 256
OR A
JR Z,CLOSE0 ; NO THEN JUMP
DEC B ; SET FLAG
CLOSE0: CALL COPYDM ; COPY AND TEST BLOCKS
EX DE,HL ; EXCHANGE COPY DIRECTION
CALL COPYDM ; COPY AND TEST BLOCKS
EX DE,HL ; EXCHANGE COPY DIRECTION
JR NZ,CLOSE4 ; BLOCK NOT THE SAME THEN ERROR
INC HL ; INCREMENT POINTER FCB
INC DE ; INCREMENT POINTER DIRECTORY
BIT 0,B ; TEST NUMBER OF BLOCK >= 256
JR Z,CLOSE1 ; NO THEN JUMP
INC HL ; INCREMENT POINTER FCB
INC DE ; INCREMENT POINTER DIRECTORY
DEC C ; DECREMENT COUNTER
CLOSE1: DEC C ; DECREMENT COUNTER
JR NZ,CLOSE0 ; NOT READY THEN JUMP
LD HL,-20 ; ADD -20 TO GET EXTENT NUMBER
ADD HL,DE ; HL CONTAINS POINTER TO EXTENT NUMBER
LD A,(IX+12) ; GET EXTENT NUMBER FCB
CP (HL) ; COMPARE WITH EXTENT NUMBER DIRECTORY
JR C,CLOSE3 ; FCB < DIRECTORY THEN JUMP
LD (HL),A ; SAVE EXTENT NUMBER IN DIRECTORY
INC HL ; GET POINTER TO NEXT RECORD
INC HL
INC HL
LD A,(IX+15) ; GET NEXT RECORD FCB
;
; THESE LINES HAVE TO BE REMOVED TO LET SUBMIT WORK CORRECTLY
;
; JR NZ,CLOSE2 ; EXTENTS NOT EQUAL THEN JUMP
; CP (HL) ; TEST FCB < DIRECTORY
; JR C,CLOSE3 ; IF SO THEN JUMP
;
CLOSE2: LD (HL),A ; SAVE NEXT RECORD IN DIRECTORY
CLOSE3:
IF DOTIME
LD E,5 ; SET LAST UPDATE DATE/TIME
CALL STIME ; UPDATE TIME
ENDIF
JP WRFCB1 ; WRITE FCB ON DISK
CLOSE4: LD A,0FFH ; FLAG ERROR
LD (PEXIT),A
RET ; AND RETURN TO CALLER
;
; COPY AND TEST DISK MAP
; ENTRY : HL : POINTER TO FIRST FCB
; DE : POINTER TO SECOND FCB
; B : 000H LESS THEN 256 BLOCKS
; 0FFH MORE OR EQUAL TO 256 BLOCKS
; EXIT : ZERO : 1 BLOCKS ARE THE SAME
; 0 BLOCKS ARE NOT THE SAME
;
COPYDM: LD A,(HL) ; GET BYTE FIRST FCB
BIT 0,B ; TEST NUMBER OF BLOCKS >=256
JR Z,COPYD0 ; NO THEN JUMP
INC HL ; INCREMENT POINTER
OR (HL) ; TEST BYTE =0
DEC HL ; DECREMENT POINTER
COPYD0: OR A ; TEST BLOCK NUMBER IS ZERO
JR NZ,COPYD1 ; NO THEN COMPARE BLOCKS
LD A,(DE) ; COPY BLOCK FROM OTHER FCB IN EMPTY
; LOCATION
LD (HL),A
BIT 0,B ; TEST NUMBER OF BLOCKS >=256
RET Z ; NO THEN EXIT
INC HL ; INCREMENT TO MSB BLOCK NUMBERS
INC DE
LD A,(DE) ; COPY BLOCK FROM OTHER FCB IN EMPTY
; LOCATION
LD (HL),A
JR COPYD2 ; JUMP TRICK TO SAVE SPACE
COPYD1: LD A,(DE) ; GET BLOCK NUMBER FIRST FCB
SUB (HL) ; TEST IF THE SAME
RET NZ ; NOT THEN RETURN
OR B ; TEST IF >=256 BLOCKS
RET Z ; NO THEN RETURN
INC HL ; INCREMENT TO MSB BLOCK NUMBERS
INC DE
COPYD2: LD A,(DE) ; GET BLOCK NUMBER FIRST FCB
SUB (HL) ; TEST IF THE SAME
DEC HL ; DECREMENT BLOCK FCB POINTERS
DEC DE
RET ; AND EXIT TO CALLER
;
; MAKE FILE COMMAND
;
CMND22: CALL SELDRV ; SELECT DRIVE FROM FCB
LD (IX+14),0 ; CLEAR FCB+14
;
; MAKE FILE
;
MAKE:
CALL CHKRO ; CHECK DRIVE R/O
LD A,(IX+0) ; GET FIRST BYTE FCB
PUSH AF ; SAVE IT
LD (IX+0),0E5H ; SET FIRST BYTE TO EMPTY FILE
LD A,1 ; SEARCH FOR 1 BYTE
CALL SEARCH ; SEARCH EMPTY FILE
POP AF ; GET FIRST BYTE FCB
LD (IX+0),A ; RESTORE IT
CALL TSTFCT ; TEST EMPTY FILE FOUND
RET Z ; NO THEN RETURN ERROR
XOR A ; CLEAR FCB+13
LD (IX+13),A
PUSH IX ; SAVE FCB POINTER
POP HL ; GET IT BACK IN HL
LD DE,15 ; PREPARE OFFSET
ADD HL,DE ; ADD IT
LD B,17 ; SET LOOP COUNTER
MAKE0: LD (HL),A ; CLEAR FCB+15 UNP TO FCB+31
INC HL ; INCREMENT POINTER
DJNZ MAKE0 ; AND CLEAR ALL BYTES
CALL CALDIR ; GET DIRECTORY ENTRY
LD A,(IX+0) ; GET FIRST BYTE FCB
LD (HL),A ; SAVE IT IN DIRECTORY (WRITE FCB
; NEEDS THIS)
IF DOTIME
LD E,1 ; SET CREATION DATE/TIME
CALL STIME ; UPDATE TIME IN DIRECTORY
LD E,5 ; SET LAST UPDATE DATE/TIME
CALL STIME ; UPDATE TIME IN DIRECTORY
ENDIF
;
LD BC,32*256+0 ; COPY FCB+0 TO DIRECTOTY+0 32 TIMES
CALL WRFCB ; WRITE FCB ON DISK
SET 7,(IX+14) ; SET FCB/FILE NOT MODIFIED
RET ; AND RETURN TO CALLER
;
; OPEN NEXT EXTENT
;
OPENEX: BIT 7,(IX+14) ; TEST IF FCB/FILE MODIFIED (WRITE)
JR NZ,OPENX2 ; NOT THEN JUMP
CALL CLOSE ; CLOSE CURRENT FCB
LD A,(PEXIT) ; GET EXIT CODE
INC A ; TEST IF ERROR
RET Z ; YES THEN EXIT
CALL CALNEX ; CALCULATE NEXT EXTENT
JR C,OPENX3 ; ERROR THEN JUMP
JR NZ,OPENX5 ; FCB PRESENT FROM CLOSE THEN JUMP
OPENX0: LD A,15 ; SEARCH FIRST 15 BYTES
CALL SEARCH ; SEARCH FOR FILE
OPENX1: CALL TSTFCT ; TEST IF FILE FOUND
JR NZ,OPENX5 ; YES THEN JUMP
LD A,(RDWR) ; TEST READ/WRITE FLAG
OR A ; TEST IF READ
JR Z,OPENX3 ; YES THEN ERROR
CALL MAKE ; MAKE NEW EXTENT IF WRITE
CALL TSTFCT ; TEST IF SUCCESFULL
JR NZ,OPENX6 ; YES THEN EXIT
JR OPENX3 ; NO THEN ERROR
OPENX2: CALL CALNEX ; CALCULATE NEXT EXTENT
JR C,OPENX3 ; ERROR THEN JUMP
BIT 7,(IX+10) ; TEST SYSTEM FILE BIT
JR Z,OPENX0 ; NO SYSTEM FILE THEN JUMP
CALL FINDF ; SEARCH PATH FOR FILE
JR OPENX1 ; USE SAME ROUTINE
OPENX3: SET 7,(IX+14) ; SET FCB/FILE NOT MODIFIED
LD A,0FFH ; SET EXIT CODE
OPENX4: LD (PEXIT),A
RET ; AND RETURN TO CALLER
OPENX5: CALL OPENF0 ; OPEN FILE
OPENX6: XOR A ; AND CLEAR EXIT CODE
JR OPENX4 ; USE SAME ROUTINE
;
; CALCULATE NEXT EXTENT
; EXIT: CARRY=1 => OVERFLOW DETECTED
; ZERO =1 => SEARCH NEXT EXTENT
; ZERO =0 => NEXT EXTENT PRESENT (CLOSE)
;
CALNEX: LD B,(IX+12) ; GET EXTENT NUMBER
LD C,(IX+14) ; GET FCB+14
BIT 6,C ; TEST ERROR BIT RANDOM RECORD
SCF ; SET ERROR FLAG
RET NZ ; NON ZERO THEN ERROR EXIT
INC B ; INCREMENT EXTENT NUMBER
LD A,B ; GET EXTENT NUMBER
AND 01FH ; MASK IT
LD B,A ; SAVE IT IN B
JR NZ,CALNX0 ; NON ZERO THEN JUMP
INC C ; INCREMENT FCB+14
LD A,C ; GET IT IN A
AND 03FH ; MASK IT
LD C,A ; SAVE IT IN C
SCF ; SET ERROR FLAG
RET Z ; AND RETURN IF FILE OVERFLOW
XOR A ; CLEAR ZERO FLAG (NOT SAME EXTENT)
JR CALNX1 ; AND SAVE EXTENT NUMBER AND FCB+14
CALNX0: LD A,(NEXTND) ; GET NEXT EXTENT MASK
AND B ; TEST IF SAME EXTENT (CLOSE)
CALNX1: LD (IX+12),B ; SAVE EXTENT NUMBER
LD (IX+14),C ; SAVE FCB+14
RET ; AND RETURN TO CALLER
;
; READ RANDOM RECORD COMMAND
;
CMND33: CALL SELDRV ; SELECT DRIVE FROM FCB
;
; READ RANDOM SECTOR
;
RDRAN: XOR A ; SET READ/WRITE FLAG
CALL LDFCB ; LOAD RANDOM RECORD IN FCB
JR Z,READS ; NO ERROR THEN READ SECTOR
RET ; RETURN ERROR
;
; READ SEQUENTIAL
;
CMND20: CALL SELDRV ; SELECT DRIVE FROM FCB
;
; READ SECTOR
;
READS: XOR A ; SET READ/WRITE FLAG
LD (RDWR),A ; SAVE IT
LD A,(IX+32) ; GET RECORD COUNTER
CP 080H ; TEST IF LAST RECORD THIS EXTENT
JR NC,READS1 ; YES THEN OPEN NEXT EXTENT
CP (IX+15) ; TEST IF GREATER THEN CURRENT RECORD
JR C,READS2 ; NO THEN GET RECORD
READS0: LD A,1 ; SET END OF FILE FLAG
LD (PEXIT),A ; SAVE IT
RET ; AND RETURN TO CALLER
READS1: CALL OPENEX ; OPEN NEXT EXTENT
LD A,(PEXIT) ; GET EXIT CODE
OR A
JR NZ,READS0 ; YES THEN END OF FILE
LD (IX+32),0 ; CLEAR RECORD COUNTER
READS2: CALL GETDM ; GET BLOCK NUMBER FROM DM IN FCB
LD A,D ; TEST BLOCK NUMBER = 0
OR E
JR Z,READS0 ; YES THEN END FILE
CALL CALSEC ; CALCULATE SECTOR NUMBER (128 BYTES)
CALL CALST ; CALCULATE SECTOR/TRACK NUMBER
CALL READR ; READ DATA
LD A,(FUNCT) ; GET FUNCTION NUMBER
CP 20 ; TEST IF READ SEQUENTIAL
RET NZ ; NO THEN RETURN
INC (IX+32) ; INCREMENT NEXT RECORD COUNTER
RET ; AND RETURN TO CALLER
;
; WRITE RANDOM SECTOR WITH ZERO FILL COMMAND
;
CMND40: CALL SELDRV ; SELECT DRIVE FROM FCB
;
; WRITE RANDOM SECTOR WITH ZERO FILL
;
WRRANZ: LD A,0FFH ; SET READ/WRITE FLAG
CALL LDFCB ; LOAD FCB FROM RANDOM RECORD
JR Z,WRITES ; NO ERROR THEN WRITE RECORD
RET ; RETURN ERROR
;
; WRITE RANDOM RECORD COMMAND
;
CMND34: CALL SELDRV ; SELECT DRIVE FROM FCB
;
; WRITE RANDOM SECTOR
;
WRRAN: LD A,0FFH ; SET READ/WRITE FLAG
CALL LDFCB ; LOAD FCB FROM RANDOM RECORD
JR Z,WRITES ; NO ERROR THEN WRITE RECORD
RET ; RETURN ERROR
;
; WRITE SEQUENTIAL
;
CMND21: CALL SELDRV ; SELECT DRIVE FROM FCB
;
; WRITE SECTOR
;
WRITES: LD A,0FFH ; SET READ/WRITE FLAG
LD (RDWR),A ; AND SAVE IT
CALL CHKRO ; CHECK DISK R/O
PUSH IX ; SAVE FCB POINTER
POP HL ; GET IT BACK IN HL
CALL CHKFR0 ; CHECK FILE R/O
LD A,(IX+32) ; GET RECORD COUNT
CP 080H ; TEST IF END THIS EXTENT
JR C,WRITS0 ; YES THEN OPEN NEXT EXTENT
CALL OPENEX ; OPEN NEXT EXTENT
LD A,(PEXIT) ; GET ERROR CODE
OR A
JP NZ,WRITS9 ; ERROR THEN DIRECTORY FULL ERROR
LD (IX+32),0 ; CLEAR RECORD COUNTER
WRITS0: CALL GETDM ; GET BLOCK NUMBER FROM FCB
LD A,D ; TEST IF BLOCK NUMBER = 0
OR E
JR NZ,WRITS5 ; NO THEN WRITE SECTOR
PUSH HL ; SAVE POINTER TO BLOCK NUMBER
LD A,C ; TEST FIRST BLOCK NUMBER IN EXTENT
OR A
JR Z,WRITS1 ; YES THEN JUMP
DEC A ; DECREMENT POINTER TO BLOCK NUMBER
CALL GETDM4 ; GET PREVIOUS BLOCKNUMBER
WRITS1: CALL GETFRE ; GET NEAREST FREE BLOCK
POP HL ; GET POINTER TO BLOCK NUMBER
LD A,D ; TEST IF BLOCKNUMBER = 0
OR E
JR Z,WRITS8 ; YES THEN DISK FULL ERROR
RES 7,(IX+14) ; RESET FCB/FILE MODIFIED
LD (HL),E ; SAVE BLOCKNUMBER
LD A,(MAXLEN+1) ; GET NUMBER OF BLOCKS
OR A ; TEST IF <256
JR Z,WRITS2 ; YES THEN JUMP
INC HL ; INCREMENT TO MSB BLOCK NUMBER
LD (HL),D ; SAVE MSB BLOCK NUMBER
WRITS2: LD C,2 ; SET WRITE NEW BLOCK FLAG
LD A,(FUNCT) ; GET FUNCTION NUMBER
SUB 40 ; TEST IF WRITE RR WITH ZERO FILL
JR NZ,WRITS6 ; NO THEN JUMP
PUSH DE ; SAVE BLOCKNUMBER
LD HL,DIRBUF ; USE DIRECTORY BUFFER FOR ZERO FILL
LD B,128 ; 128 BYTES TO CLEAR
WRITS3: LD (HL),A ; CLEAR DIRECTORY BUFFER
INC HL ; INCREMENT POINTER
DJNZ WRITS3 ; CLEAR ALL BYTES
CALL CALSEC ; CALCULATE SECTOR NUMBER (128 BYTES)
LD A,(NMASK) ; GET SECTOR MASK
LD B,A ; COPY IT
INC B ; INCREMENT IT TO GET NUMBER OF WRITES
CPL ; COMPLEMENT SECTOR MASK
AND E ; MASK SECTOR NUMBER
LD E,A ; AND SAVE IT
LD C,2 ; SET WRITE NEW BLOCK FLAG
WRITS4: PUSH HL ; SAVE REGISTERS
PUSH DE
PUSH BC
CALL CALST ; CALCULATE SECTOR/TRACK
CALL DMADIR ; SET DMA DIRECTORY BUFFER
POP BC ; GET WRITE NEW BLOCK FLAG
PUSH BC ; SAVE IT AGAIN
CALL WRITER ; WRITE RECORD ON DISK
POP BC ; RESTORE REGISTERS
POP DE
POP HL
LD C,0 ; CLEAR WRITE NEW BLOCK FLAG
INC E ; INCREMENT SECTOR NUMBER
DJNZ WRITS4 ; WRITE ALL BLOCKS
CALL STDMA ; SET USER DMA ADDRESS
POP DE ; GET BLOCK NUMBER
WRITS5: LD C,0 ; CLEAR WRITE NEW BLOCK FLAG
WRITS6: RES 7,(IX+14) ; RESET FCB/FILE MODIFIED FLAG
PUSH BC ; SAVE IT
CALL CALSEC ; CALCULATE SECTOR NUMBER (128 BYTES)
CALL CALST ; CALCULATE SECTOR/TRACK
POP BC ; GET WRITE NEW BLOCK FLAG
CALL WRITER ; WRITE RECORD ON DISK
LD A,(IX+32) ; GET RECORD COUNTER
CP (IX+15) ; COMPARE WITH NEXT RECORD
JR C,WRITS7 ; IF LESS THEN JUMP
INC A ; INCREMENT RECORD COUNT
LD (IX+15),A ; SAVE IT ON NEXT RECORD POSITION
RES 7,(IX+14) ; RESET FCB/FILE MODIFIED FLAG
WRITS7: LD A,(FUNCT) ; GET FUNCTION NUMBER
CP 21 ; TEST WRITE SEQUENTIAL
RET NZ ; NOT THEN RETURN
INC (IX+32) ; INCREMENT RECORD COUNT
RET ; AND RETURN TO CALLER
WRITS8: LD A,2 ; SET DISK FULL ERROR
LD (PEXIT),A
RET ; AND RETURN TO CALLER
WRITS9: LD A,1 ; SET DIRECTORY FULL FLAG
LD (PEXIT),A
RET ; AND RETURN TO CALLER
;
; LOAD FCB FOR RANDOM READ/WRITE
; EXIT : ZERO FLAG : 1 NO ERROR
; 0 ERROR OCCURED
;
LDFCB: LD (RDWR),A ; SAVE READ/WRITE FLAG
LD A,(IX+33) ; GET FIRST BYTE RANDOM RECORD
LD D,A ; SAVE IT IN D
RES 7,D ; RESET MSB TO GET NEXT RECORD
RLA ; SHIFT MSB IN CARRY
LD A,(IX+34) ; LOAD NEXT BYTE RANDOM RECORD
RLA ; SHIFT CARRY
PUSH AF ; SAVE IT
AND 01FH ; MASK NEXT EXTENT
LD C,A ; SAVE IT IN C
POP AF ; GET BYTE
RLA ; SHIFT 4 TIMES
RLA
RLA
RLA
AND 0FH ; MASK IT
LD B,A ; SAVE FCB+14
LD A,(IX+35) ; GET NEXT BYTE RANDOM RECORD
LD E,6 ; SET RANDOM RECORD TO LARGE FLAG
CP 4 ; TEST RANDOM RECORD TO LARGE
JR NC,LDFCB8 ; YES THEN ERROR
RLCA ; SHIFT 4 TIMES
RLCA
RLCA
RLCA
ADD A,B ; ADD BYTE
LD B,A ; SAVE FCB+14 IN B
LD (IX+32),D ; SET NEXT RECORD COUNT
LD D,(IX+14) ; GET FCB+14
BIT 6,D ; TEST ERROR RANDOM RECORD
JR NZ,LDFCB0 ; YES THEN JUMP
LD A,C ; GET NEW EXTENT NUMBER
CP (IX+12) ; COMPARE WITH FCB
JR NZ,LDFCB0 ; NOT EQUAL THEN OPEN NEXT EXTENT
LD A,B ; GET NEW FCB+14
XOR (IX+14) ; COMPARE WITH FCB+14
AND 03FH ; MASK IT
JR Z,LDFCB6 ; EQUAL THEN RETURN
LDFCB0: BIT 7,D ; TEST FCB MODIFIED (WRITE)
JR NZ,LDFCB1 ; NO THEN JUMP
PUSH DE ; SAVE REGISTERS
PUSH BC
CALL CLOSE ; CLOSE EXTENT
POP BC ; RESTORE REGISTERS
POP DE
LD E,3 ; SET CLOSE ERROR
LD A,(PEXIT) ; GET EXIT CODE
INC A
JR Z,LDFCB7 ; ERROR THEN EXIT
LDFCB1: LD (IX+12),C ; SAVE NEW EXTENT NUMBER
LD (IX+14),B ; SAVE NEW FCB+14
BIT 7,D ; TEST FCB MODIFIED (PREVIOUS FCB)
JR NZ,LDFCB3 ; NO THEN JUMP
LDFCB2: LD A,15 ; SET NUMBER OF BYTES TO SEARCH FOR
CALL SEARCH ; SEARCH NEXT FCB
JR LDFCB4 ; JUMP
LDFCB3: BIT 7,(IX+10) ; TEST IF SYSTEM FILE
JR Z,LDFCB2 ; NO USE SEARCH
CALL FINDF ; OPEN FILE (USE PATH NAME)
LDFCB4: LD A,(PEXIT) ; GET ERROR CODE
INC A
JR NZ,LDFCB5 ; NO ERROR THEN EXIT
LD A,(RDWR) ; GET READ/WRITE FLAG
LD E,4 ; SET READ EMPTY RECORD
INC A
JR NZ,LDFCB7 ; READ THEN ERROR
CALL MAKE ; MAKE MEW FCB
LD E,5 ; SET MAKE ERROR
LD A,(PEXIT) ; GET ERROR CODE
INC A
JR Z,LDFCB7 ; ERROR THEN EXIT
JR LDFCB6 ; NO ERROR EXIT (ZERO SET)
LDFCB5: CALL OPENF0 ; OPEN FILE
LDFCB6: XOR A ; SET ZERO FLAG AND CLEAR ERROR CODE
LD (PEXIT),A
RET ; AND RETURN TO CALLER
LDFCB7: LD (IX+14),0C0H ; SET RANDOM RECORD ERROR
LDFCB8: LD A,E ; GET ERROR CODE
LD (PEXIT),A ; AND SAVE IT
SET 7,(IX+14) ; SET FCB/FILE NOT MODIFIED
OR A ; CLEAR ZERO FLAG
RET ; AND RETURN TO CALLER
;
; CALCULATE RANDOM RECORD
; ENTRY HL=OFFSET IN FCB
; DE=FCB POINTER
; EXIT D=LSB RANDOM RECORD
; C=ISB RANDOM RECORD
; B=MSB RANDOM RECORD
;
CALRRC: ADD HL,DE ; POINTER TO FCB+15 OR FCB+32
LD A,(HL) ; GET BYTE
LD HL,12 ; OFFSET TO EXTENT NUMBER
ADD HL,DE ; GET POINTER TO EXTENT BYTE
LD D,A ; SAVE FIRST BYTE
LD A,(HL) ; GET EXTENT BYTE
AND 01FH ; MASK IT
RL D ; SHIFT MSB IN CARRY
ADC A,0 ; ADD CARRY
RRA ; SHIFT 1 TIME (16 BITS)
RR D
LD C,A ; SAVE ISB
INC HL ; INCREMENT TO FCB+14
INC HL
LD A,(HL) ; GET FCB+14
RRCA ; SHIFT 4 TIMES
RRCA
RRCA
RRCA
PUSH AF ; SAVE IT
AND 03H ; MASK MSB
LD B,A ; SAVE IT
POP AF ; GET LSB
AND 0F0H ; MASK IT
ADD A,C ; ADD WITH ISB
LD C,A ; SAVE ISB
RET NC ; NO CARRY THEN RETURN
INC B ; INCREMENT MSB
RET ; AND RETURN TO CALLER
;
CLRDSK: LD HL,0 ; Disk reset routine
LD (LOGIN),HL
CALL INITDR
XOR A ;Clear disk changed flag
LD (DIFF),A
LD A,(SUBFLG)
JP CMD25A
;
; SET TIME AND DATE
; ENTRY: E : 1 : SET CREATION TIME/DATE
; 5 : SET LAST UPDATE TIME/DATE
; TIME RETURN POINTER IN HL
; HL+0 : LOW BYTE DATE SINCE JAN,1,1978
; HL+1 : HIGH BYTE DATE SINCE JAN,1,1978
; HL+2 : HOURS (BCD)
; HL+3 : MINUTES (BCD)
; HL+4 : SECONDS (BCD) (NOT USED IN TIME STAMP)
;
IF DOTIME
STIME: LD HL,(DIRBUF) ; GET DIRECTORY ENTRY
LD BC,060H ; OFFSET ENTRY POINT TIME/DATE STAMP
ADD HL,BC ; ADD OFFSET
LD A,(HL) ; GET BYTE
SUB 021H ; TEST IF TIME STAMP PRESENT
RET NZ ; NO THEN RETURN
LD D,A ; CLEAR D
ADD HL,DE ; ADD ENTRY (UPDATE/CREATE)
LD A,(SECPNT) ; GET SECTOR POINTER
RRCA ; SHIFT 2 TIMES
RRCA
LD E,A ; SAVE IT
RRCA ; SHIFT 2 TIMES
RRCA
ADD A,E ; ADD IT (A=0,10,20)
LD E,A ; SAVE IN E
ADD HL,DE ; ADD OFFSET
PUSH HL ; SAVE RESULT
LD C,0 ; RETURN POINTER IN HL
; C=FF MEANS SET DATE POINTED TO BY HL
CALL BTIME ; RETURN POINTER IN HL
POP DE ; GET POINTER
LD BC,4 ; SET 4 BYTES
LDIR ; COPY 4 BYTES
RET ; AND RETURN TO CALLER
;
; GET TIME
;
GETTIM: PUSH DE ; SAVE ADDRESS TO PUT TIME
LD C,0 ; GET TIME ADDRESS
CALL BTIME ; EXECUTE P2BIOS CALL
POP DE ; RESTORE ADDRESS TO PUT TIME
LD BC,5 ; 5 BYTES TO MOVE
LDIR ; STORE THE TIME
RET ; AND RETURN TO CALLER
;
; SET TIME
;
SETTIM: EX DE,HL ; GET ADDRESS TIME IN HL
LD C,0FFH ; SET TIME ADDRESS
; AND FALL THROUGH TO P2BIOS CALL
;
; EXECUTE P2BIOS TIME ROUTINE
;
BTIME: PUSH HL ; SAVE VALUE IN HL
LD HL,(TIMEAD) ; GET ADDRESS TIME ROUTINE
EX (SP),HL ; PUT ADDRESS ON STACK AND RESTORE HL
RET ; EXECUTE TIME ROUTINE
;
ENDIF
;
; P2DOS EXIT ROUTINE
;
P2EXIT: LD A,(FLDRV) ; TEST DRIVE SELECT USED FLAG
OR A
JR Z,P2EXT0 ; NO THEN EXIT
LD A,(FCB0) ; GET FCB BYTE 0
LD (IX+0),A ; SAVE IT
LD A,(DRIVE) ; GET OLD DRIVE NUMBER
CALL SELDK ; SELECT DISK
P2EXT0: PUSH IX ; SAVE IX
POP DE ; RESTORE DE
POP IX ; RESTORE IX
LD SP,(SPSAVE) ; GET OLD SP
LD HL,(PEXIT) ; GET EXIT CODE
LD A,(FUNCT) ; GET FUNCTION CODE
LD C,A ; RESTORE C
LD A,L ; COPY FUNCTION CODE
LD B,H
RET ; AND RETURN TO CALLER
;
; RAM AREA
;
TABCNT: DB 0 ; TAB COUNTER
TABCX1: DB 0 ; TEMPORARY TAB COUNTER (USED BY RDBUF)
FCONTP: DB 0 ; LIST ENABLE FLAG (CONTROL P)
LASTCH: DB 0 ; LAST CHARACTER
DELAY: DB 0FFH ; DELAY COUNTER
;
TRANS: DEFW 0 ; TRANSLATION VECTOR
TEMP0: DEFW 0 ; NUMBER OF FILES ON DRIVE
TEMP1: DEFW 0 ; NOT USED
TEMP2: DEFW 0 ; NOT USED
DIRBUF: DEFW 0 ; DIRECTORY BUFFER
IXP: DEFW 0 ; DISK PARAMETER BLOCK
CSV: DEFW 0 ; CHECK SUM POINTER
ALV: DEFW 0 ; ALLOCATION VECTOR POINTER
;
MAXSEC: DEFW 0 ; MAXIMUM NUMBER OF SECTORS/TRACK
NBLOCK: DB 0 ; NUMBER OF BLOCKS
NMASK: DB 0 ; MASK NUMBER OF BLOCKS
NEXTND: DB 0 ; EXTENT MASK
MAXLEN: DEFW 0 ; MAXIMUM BLOCK NUMBER-1
NFILES: DEFW 0 ; MAXIMUM NUMBER OF FILES-1
NDIR0: DB 0 ; FIRST TWO ENTRIES ALV BUFFER
NDIR1: DB 0
NCHECK: DEFW 0 ; NUMBER OF CHECKSUM ENTRUIES
NFTRK: DEFW 0 ; FIRST TRACK NUMBER
;
DSKRO: DEFW 0 ; DISK R/O VECTOR
LOGIN: DEFW 0 ; LOGIN VECTOR
DMA: DEFW 080H ; DMA ADDRESS
;
FUNCT: DB 0 ; FUNCTION NUMBER
PEXIT: DEFW 0 ; EXIT CODE
FLDRV: DB 0 ; DRIVE SELECT USED FLAG
RDWR: DB 0 ; READ/WRITE FLAG
;
FCB0: DB 0 ; FCB BYTE 0
USER: DB 0 ; USER NUMBER
DRIVE: DB 0 ; DRIVE NUMBER
DEFDRV: DB 0 ; DEFAULT DRIVE NUMBER
RECDIR: DEFW 0 ; RECORD DIRECTORY (CHECKSUM)
FILCNT: DEFW 0 ; FILE COUNTER
SECPNT: DB 0 ; SECTOR POINTER
SUBFLG: DB 0 ; SUBMIT FLAG (RESET DISK COMMAND)
;
DCOPY: DEFW 0 ; COPY ADDRESS FCB
SEAREX: DB 0 ; EXIT CODE SEARCH
SEARNB: DB 0 ; SEARCH NUMBER OF BYTES
SEARQU: DB 0 ; SEARCH QUESTION MARK USED
SEARPU: DB 0 ; SEARCH PUBLIC FILE
;next two flags added by B.H.
DIFF: DB 0 ; disk changed flag
RETFLG: DB 0 ; allows recovery from read/write errors
;
SPSAVE: DEFW 0 ; STACK POINTER LOCATION
DEFS 62 ; 62 BYTE STACK
P2DOSS: ; P2DOS STACK
DOSSTOP EQU $
;
IF Z80MR
IF ((DOSSTOP-DOSSTRT).GT.3584)
*Bdos too large
ENDIF
ELSE
IF ((DOSSTOP-DOSSTRT) GT 3584)
*Bdos too large!!*
ENDIF
ENDIF
;
P-DOSSTRT).GT.3584)
*Bdos too large
ENDIF
ELSE
IF ((