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
/
BEEHIVE
/
OS
/
P2DOSV3.ARC
/
P2DOS.MAC
< prev
next >
Wrap
Text File
|
1991-08-11
|
78KB
|
2,531 lines
TITLE 'P2 DISK OPERATING SYSTEM'
;
;******************************************************************************
;* *
;* P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 2.1 *
;* *
;* COPYRIGHT (C) 1985 BY H.A.J. TEN BRUGGE *
;* ALL RIGHTS RESERVED *
;* *
;* P2DOS WAS WRITTEN BY H.A.J. TEN BRUGGE, WHO ASSUMES NO RESPONSIBILITY *
;* OR LIABILITY FOR ITS USE. P2DOS IS RELEASED TO THE PUBLIC DOMAIN FOR *
;* NON-COMMERCIAL USE ONLY. *
;* *
;* THE PULBLIC IS ENCOURAGED TO FREELY COPY AND USE THIS PROGRAM FOR *
;* NON-COMMERCIAL PURPOSES. ANY COMMERCIAL USE OF P2DOS IS PROHIBITED *
;* UNLESS APPROVED BY THE AUTHOR, H.A.J. TEN BRUGGE, IN WRITING. *
;* MY ADDRESS IS : *
;* H.A.J. TEN BRUGGE, *
;* MOLENSTRAAT 33, *
;* 7491 BD DELDEN *
;* PHONE NUMBER : 05407-61980 *
;* *
;* THIS IS MOD 2.1 TO THE RELEASE VERSION OF P2DOS *
;* *
;******************************************************************************
;
RAMLOW EQU 00000H ; START ADDRESS MEMORY
;
P2DOS EQU $ ; START ADDRESS P2DOS
P2BIOS EQU P2DOS+00E00H ; START ADDRESS P2BIOS
;
PAGE 44 ; 44 LINES/PAGE
;
; P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 2.1
;
;
;
; NEW FEATURES OF P2DOS ARE:
; - TEST CONSOLE STATUS AFTER 256 CHARACTERS OUTPUT. THIS MAKES IT POSSIBLE TO
; EXIT A PROGRAM, AFTER YOU HIT ACCIDENTALY A KEY, BY TYPING ^S FOLLOWED BY ^C.
; - ERROR ROUTINES GIVE MORE INFORMATION.
; P2DOS ERROR ON D: BAD SECTOR
; SELECT
; FILE R/O
; R/O
; FUNCTION =XXX (FILE =FILENAME.TYP)
; AS YOU CAN SEE THE ERROR IS DISPLAYED WITH THE P2DOS FUNCTION CALL.
; THE OPTION 'FILE =FILENAME.TYP' IS ONLY DISPLAYED IF THE P2DOS FUNCTION
; USES A FILENAME. AFTER ALL ERRORS A WARM BOOT IS DONE.
; - PUBLIC FILES ARE SUPPORTED. YOU CAN ACCESS A PUBLIC FILE FROM ANY USER NUMBER.
; THIS MAKES IT POSSIBLE TO PUT FOR EXAMPLE ALL '.COM' IN A SPECIAL USER NUMBER
; AND MAKE ALL THOSE FILES PUBLIC. YOU CAN ACCESS ALL THE FILES FROM ANY USER
; USER NUMBER ON THE SAME DISK.
; A PUBLIC FILE IS A FILE WITH BIT F2 (BIT 7 FROM FILENAME LETTER 2) SET TO ONE.
; PUBLIC FILES CAN ONLY BE REFERENCED BY THERE EXACT NAME AND NOT BY WILD CARD
; CHARACTERS.
; - SEARCH PATH IS IMPLEMENTED JUST AS IN ZCPR2 TO FIND FILES ON OTHER DRIVES AND
; IN OTHER USER AREAS. THE FILES MUST BE SYSTEM FILES AND MUST BE REFERENCED
; BY THERE EXACT NAME AS IN PUBLIC FILE NAMES ABOVE.
; - AUTOMATIC DATE AND TIME STAMP IS IMPLEMENTED. THE CREATION DATE AND TIME IS
; SET WHEN THE FUNCTION MAKE IS EXECUTED. THE UPDATE DATE AND TIME IS SET AS
; THE FILE IS CLOSED. TO LET THIS FEATURE WORK YOU NEED TO HAVE A REAL TIME
; CLOCK AND THE CORRECT P2BIOS DRIVER ROUTINE. YOU ALSO HAVE TO INITIALISE YOUR
; DIRECTORY FOR TIME STAMPS.
; - FILE R/O ERROR MESSAGE OCCURS IF ONE OF THE FOLLOWING FILE TYPES IS ACTIVE:
; PUBLIC FILE (F2) AND YOU ARE NOT IN THE SAME USER AREA AS THE PUBLIC FILE IS
; FILE R/O (T1)
; SYSTEM FILE (T2) AND YOU DID USE A QUESTION MARK
; THIS MEANS THAT A SYSTEM FILE OR PUBLIC FILE CANNOT BE ERASED ACCIDENTALY.
; - NEW FUNCTION GET TIME (200) IS IMPLEMENTED TO GET THE CORRECT DATE AND TIME.
; ENTRY DE IS ADDRESS TO PUT TIME. THE DATE AND TIME RECORD HAS THE FOLLOWING
; LAYOUT:
; DATE: DEFS 2 DATE = 1 (SU 01-JAN-1978)
; DATE = 65535 (SU 05-JUN-2157)
; HOUR: DEFS 1 HOUR IN BCD
; MINUTE: DEFS 1 MINUTE IN BCD
; SECOND: DEFS 1 SECOND IN BCD
; FUNCTION WORKS ONLY IF CORRECT P2BIOS FUNCTION CALL IS INSTALLED.
; - NEW FUNCTION SET TIME (201) IS IMPLEMENTED TO SET THE CORRECT DATE AND TIME.
; ENTRY DE IS ADDRESS NEW TIME. THE DATE AND TIME LAYOUT IS AS ABOVE.
; FUNCTION WORKS ONLY IF CORRECT P2BIOS FUNCTION CALL IS INSTALLED.
; - ARCHIEVE BIT HAS BEEN IMPLEMENTED. THIS BIT MUST BE SET BY THE USER (OR
; AN ARCHIEVE PROGRAM). THE BIT IS RESET WHEN THE FILE IS MODIFIED.
; - DISK SIZE CAN BE AS LARGE AS 65536*16K=1 048 576 K BYTE=1 G BYTE.
; - FILE SIZE CAN BE AS LARGE AS 32*64*16K=32 768K BYTE=32 M BYTE.
;
;
; YOU CAN ENABLE/DISABLE THE FUNCTIONS MENTIONED ABOVE WITH THE FOLLOWING DATA AND
; ADDRESSES.
; - ENABLE PATH NAME BY PUTTING ADDRESS OF PATH IN P2DOS+11H. IF THIS VALUE IS 0000H
; NO PATH IS USED. THIS ADDRESS IS NORMALLY SET TO 0040H.
; - ENABLE P2DOS TIME AND DATE STAMPING BY PUTTING THE CORRECT P2BIOS ADDRESS AT
; P2DOS+13H. THIS ADDRESS IS NORMALY SET TO THE P2BIOS CONSOLE STATUS FUNCTION.
; - YOU CAN ENABLE THE 256 CHARACTER DELAY FUNCTION BY SETTING BIT 0 OF ADDRESS
; P2DOS+15H. THIS BIT IS NORMALLY SET TO 1.
; - YOU CAN ENABLE PUBLIC FILES BY SETTING BIT 1 OF ADDRESS P2DOS+15H TO 1. THIS
; BIT IS NORMALLY SET TO 1.
;
;
;
; ENTRY ADDRESSES P2BIOS
;
; FUNC NAME INPUT PARAMETERS RETURNED VALUES
; 0 BOOT NONE NONE
; 1 WBOOT NONE NONE
; 2 CONST NONE A=0FFH IF READY
; A=000H IF NOT READY
; 3 CONIN NONE A=CONSOLE CHARACTER
; 4 CONOUT C=CONSOLE CHARACTER NONE
; 5 LIST C=LIST CHARACTER NONE
; 6 PUNCH C=PUNCH CHARACTER NONE
; 7 READER NONE A=READER CHARACTER
; 8 HOME NONE NONE
; 9 SELDSK C=DRIVE NUMBER (0..15) HL=DISK PARAMETER HEADER ADDRESS
; E=INIT SELECT FLAG HL=0000H IF INVALID DRIVE
; 10 SETTRK BC=TRACK NUMBER NONE
; 11 SETSEC BC=SECTOR NUMBER NONE
; 12 SETDMA BC=DMA ADDRESS NONE
; 13 READ NONE A=00H IF NO ERROR
; A=01H IF ERROR
; 14 WRITE C=0 WRITE DATA A=00H IF NO ERROR
; C=1 WRITE DIRECTORY A=01H IF ERROR
; C=2 WRITE NEW DATA
; 15 LISTST NONE A=000H IF READY
; A=0FFH IF NOT READY
; 16 SECTRN BC=LOGICAL SECTOR HL=PHYSICAL SECTOR NUMBER
; NUMBER
; DE=TRANSLATION TABEL
; ADDRESS
; XX TIME C=000H GET TIME HL=POINTER TO TIME TABLE
; C=0FFH UPDATE CLOCK HL+0:DATE LSB SINCE 1,1,1978
; HL=POINTER TO TIME HL+1:DATE MSB
; TABLE HL+2:HOURS (BCD)
; HL+3:MINUTES (BCD)
; HL+4:SECONDS (BCD)
;
BOOT EQU P2BIOS+00000H ; P2 SYSTEM COLD BOOT
WBOOT EQU P2BIOS+00003H ; P2 SYSTEM WARM BOOT
CONST EQU P2BIOS+00006H ; P2 SYSTEM CONSOLE STATUS
CONIN EQU P2BIOS+00009H ; P2 SYSTEM CONSOLE INPUT
CONOUT EQU P2BIOS+0000CH ; P2 SYSTEM CONSOLE OUTPUT
LIST EQU P2BIOS+0000FH ; P2 SYSTEM LIST OUTPUT
PUNCH EQU P2BIOS+00012H ; P2 SYSTEM PUNCH OUTPUT
READER EQU P2BIOS+00015H ; P2 SYSTEM READER INPUT
HOME EQU P2BIOS+00018H ; P2 SYSTEM HOME DISK
SELDSK EQU P2BIOS+0001BH ; P2 SYSTEM SELECT DISK
SETTRK EQU P2BIOS+0001EH ; P2 SYSTEM SELECT TRACK
SETSEC EQU P2BIOS+00021H ; P2 SYSTEM SELECT SECTOR
SETDMA EQU P2BIOS+00024H ; P2 SYSTEM SET DMA ADDRESS
READ EQU P2BIOS+00027H ; P2 SYSTEM READ 128 BYTES
WRITE EQU P2BIOS+0002AH ; P2 SYSTEM WRITE 128 BYTES
LISTST EQU P2BIOS+0002DH ; P2 SYSTEM LIST STATUS
SECTRN EQU P2BIOS+00030H ; P2 SYSTEM SECTOR TRANSLATION
TIME EQU P2BIOS+00006H ; P2 SYSTEM GET/SET TIME
; MUST BE CHANGED IF ROUTINE PRESENT
;
; INTERNAL DEFINITIONS
;
CONTC EQU 003H ; KEY TO GENERATE WARM BOOT
CONTE EQU 005H ; BREAK LINE
CONTH EQU 008H ; BACKSPACE
TAB EQU 009H ; TAB
LF EQU 00AH ; LINE FEED
CR EQU 00DH ; CARRIAGE RETURN
CONTP EQU 010H ; SET/RESET PRINT FLAG
CONTR EQU 012H ; REPEAT LINE
CONTS EQU 013H ; STOP CONSOLE OUTPUT
CONTU EQU 015H ; DELETE LINE
CONTX EQU 018H ; DELETE LINE (BACKSPACES)
DRVSEP EQU 03AH ; DRIVE SEPERATOR (:)
RUBOUT EQU 07FH ; DELETE LAST CHAR
;
MAXCMD EQU 40 ; NUMBER OF VALID P2DOS COMMANDS
;
; START PROGRAM
;
VERS: DEFB 000H ; VERSION NUMBER NOT IMPLEMENTED
DEFB 000H
DEFB 000H
DEFB 000H
DEFB 000H
DEFB 000H
;
; START P2DOS
;
START: JP ENTRY ; JUMP TO ENTRY POINT P2DOS
;
; ERROR MESSAGES P2DOS
;
STBDSC: DEFW BADSEC ; BAD SECTOR MESSAGE
STSEL: DEFW SELERR ; SELECT ERROR
STRO: DEFW RDONLY ; DRIVE READ ONLY
SFILRO: DEFW FILRO ; FILE READ ONLY
;
; EXTERNAL PATH NAME
;
PATH: DEFW RAMLOW+00040H ; PATHNAME FOR OPEN FILE COMMAND
;
; TIME ADDRESS P2BIOS
;
TIMEAD: DEFW TIME ; TIME ROUTINE ADDRESS FOR TIME
; AND DATE STAMPS
;
; FLAGS FOR SPECIALS
; BIT 0: PUBLIC FILE ENABLE(1)/DISABLE(0)
; BIT 1: DELAY 256 CHARACTERS ACTIVE(1)/DISABLE(0)
;
FLAGS: DEFB 0FFH ; FLAG BITE
;
; ENTRY POINT P2DOS COMMANDS
;
ENTRY: LD A,C ; GET FUNCTION NUMBER
LD (FUNCT),A ; SAVE IT FOR LATER USE
LD HL,0 ; SET HL TO ZERO
LD (PEXIT),HL ; CLEAR EXIT CODE
XOR A ; CLEAR A
LD (FLDRV),A ; RESET DRIVE SELECT DONE FLAG
LD (RDWR),A ; RESET READ/WRITE FLAG
LD (SPSAVE),SP ; SAVE STACK POINTER
LD SP,P2DOSS ; GET INTERNAL STACK POINTER
PUSH IX ; SAVE INDEX REGISTER
PUSH DE ; SAVE PARAMETER REGISTER
POP IX ; GET IT BACK IN IX
LD HL,P2EXIT ; GET EXIT ADDRESS P2DOS
PUSH HL ; SAVE IT ON STACK TO RETURN FROM P2DOS
LD A,C ; GET FUNCTION CODE
CP 200 ; TEST GET TIME
JP Z,GETTIM ; YES THEN GET TIME
CP 201 ; TEST SET TIME
JP Z,SETTIM ; YES THEN SET TIME
CP MAXCMD+1 ; TEST GREATER THEN MAXCMD
RET NC ; IF SO RETURN TO CALLER AND DO NOTHING
LD HL,CTABLE ; LOAD TABLE
LD B,0 ; PREPARE 16 BIT ADD
ADD HL,BC ; ADD
ADD HL,BC ; ADD TWICE TO GET WORD VALUE
LD A,(HL) ; GET LSB
INC HL ; POINTER TO MSB
LD H,(HL) ; GET MSB
LD L,A ; SAVE LSB IN L
JP (HL) ; JUMP TO ROUTINE
;
; COMMAND TABLE
;
;
; FUNC NAME INPUT PARAMETERS RETURNED VALUES
; 0 BOOT NONE NONE
; 1 CONSOLE INPUT NONE A=CHARACTER
; 2 CONSOLE OUTPUT E=CHARACTER A=00H
; 3 READER INPUT NONE A=CHARACTER
; 4 PUNCH OUTPUT E=CHARACTER A=00H
; 5 LIST OUTPUT E=CHARACTER A=00H
; 6 DIRECT CONSOLE I/O E=0FFH A=INPUT CHARACTER
; A=00H IF NO CHARACTER PRESENT
; E=0FEH A=CONSOLE STATUS
; E=000H..0FDH A=00H
; 7 GET I/O BYTE NONE A=I/O BYTE (RAMLOW+03H)
; 8 SET I/O BYTE E=I/O BYTE A=00H
; 9 PRINT STRING DE=ADDRESS STRING A=00H
; 10 READ CONSOLE BUFFER DE=ADDRESS BUFFER A=00H
; 11 GET CONSOLE STATUS NONE A=00H IF NO CHARACTER PRESENT
; A=01H IF CHARACTER PRESENT
; 12 RETURN VERSION NUMBER NONE A=VERSION NUMBER (022H)
; 13 RESET DISK SYSTEM NONE A=00H NO $*.* FILE
; A=FFH $*.* FILE PRESENT
; 14 SELECT DISK E=DISK NUMBER A=00H
; 15 OPEN FILE DE=ADDRESS FCB A=DIRECTORY CODE
; 16 CLOSE FILE DE=ADDRESS FCB A=DIRECTORY CODE
; 17 SEARCH FOR FIRST DE=ADDRESS FCB A=DIRECTORY CODE
; 18 SEARCH FOR NEXT DE=ADDRESS FCB A=DIRECTORY CODE
; 19 DELETE FILE DE=ADDRESS FCB A=ERROR CODE
; 20 READ SEQUENTIAL DE=ADDRESS FCB A=READ/WRITE CODE
; 21 WRITE SEQUENTIAL DE=ADDRESS FCB A=READ/WRITE CODE
; 22 MAKE FILE DE=ADDRESS FCB A=DIRECTORY CODE
; 23 RENAME FILE DE=ADDRESS FCB A=ERROR CODE
; 24 RETURN LOGIN VECTOR NONE HL=LOGIN VECTOR
; 25 RETURN CURRENT DISK NONE A=CURRENT DISK
; 26 SET DMA ADDRESS DE=DMA ADDRESS A=00H
; 27 GET ALLOCATION ADDRESS NONE HL=ADDRESS ALLOCATION VECTOR
; 28 WRITE PROTECT DISK NONE A=00H
; 29 GET R/O VECTOR NONE HL=R/O VECTOR
; 30 SET FILE ATTRIBUTES DE=ADDRESS FCB A=ERROR CODE
; 31 GET ADDRESS DPB NONE HL=ADDRESS DPB
; 32 SET/GET USER CODE E=0FFH A=USER NUMBER
; E=USER NUMBER A=00H
; 33 READ RANDOM DE=ADDRESS FCB A=READ/WRITE CODE
; 34 WRITE RANDOM DE=ADDRESS FCB A=READ/WRITE CODE
; 35 COMPUTE FILE SIZE DE=ADDRESS FCB A=ERROR CODE
; 36 SET RANDOM RECORD DE=ADDRESS FCB A=00H
; 37 RESET MULTIPLE DRIVE DE=MASK A=00H
; 38 NOT IMPLEMENTED NONE A=00H
; 39 NOT IMPLEMENTED NONE A=00H
; 40 WRITE RANDOM WITH DE=ADDRESS FCB A=READ/WRITE CODE
; ZERO FILL
; 200 GET TIME DE=ADDRESS TO PUT TIME A=00H
; 201 SET TIME DE=ADDRESS TIME A=00H
;
; DIRECTORY CODE : A=00H,01H,02H,03H IF NO ERROR
; A=0FFH IF ERROR
; ERROR CODE : A=00H IF NO ERROR
; A=0FFH IF ERROR
; READ/WRITE CODE: A=00H IF NO ERROR
; A=01H READ => END OF FILE
; WRITE => DIRECTORY FULL
; A=02H DISK FULL
; A=03H CLOSE ERROR DURING RANDOM RECORD READ/WRITE
; A=04H READ EMPTY RECORD DURING RANDOM RECORD READ
; A=05H DIRECTORY FULL ERROR DURING RANDOM RECORD WRITE
; A=06H RANDOM RECORD TOO LARGE DURING RANDOM RECORD READ/WRITE
;
CTABLE: DEFW WBOOT ; WARM BOOT
DEFW RDCON ; CONSOLE INPUT
DEFW BWRCON ; CONSOLE OUTPUT
DEFW RDRDR ; READER INPUT
DEFW WPUNCH ; PUNCH OUTPUT
DEFW WLIST ; LIST OUTPUT
DEFW DCIO ; DIRECT CONSOLE I/O
DEFW GIOST ; GET I/O BYTE
DEFW SIOST ; SET I/O BYTE
DEFW MESS ; PRINT STRING
DEFW RDBUF ; READ CONSOLE BUFFER
DEFW TSTCS ; GET CONSOLE STATUS
DEFW CMND12 ; RETURN VERSION NUMBER
DEFW CMND13 ; RESET DISK SYSTEM
DEFW CMND14 ; SELECT DISK
DEFW CMND15 ; OPEN FILE
DEFW CMND16 ; CLOSE FILE
DEFW CMND17 ; SEARCH FOR FIRST
DEFW CMND18 ; SEARCH FOR NEXT
DEFW CMND19 ; DELETE FILE
DEFW CMND20 ; READ SEQUENTIAL
DEFW CMND21 ; WRITE SEQUENTIAL
DEFW CMND22 ; MAKE FILE
DEFW CMND23 ; RENAME FILE
DEFW CMND24 ; RETURN LOGIN VECTOR
DEFW CMND25 ; RETURN CURRENT DISK
DEFW CMND26 ; SET DMA ADDRESS
DEFW CMND27 ; GET ADDRESS ALLOCATION VECTOR
DEFW CMND28 ; WRITE PROTECT DISK
DEFW CMND29 ; GET R/O VECTOR
DEFW CMND30 ; SET FILE ATTRIBUTES
DEFW CMND31 ; GET ADDRESS DISK PARAMETER HEADER(DPH)
DEFW CMND32 ; GET/SET USER CODE
DEFW CMND33 ; READ RANDOM
DEFW CMND34 ; WRITE RANDOM
DEFW CMND35 ; COMPUTE FILE SIZE
DEFW CMND36 ; SET RANDOM RECORD
DEFW CMND37 ; RESET MULTIPLE DRIVE
DEFW DUMMY ; NOT IMPLEMENTED
DEFW DUMMY ; NOT IMPLEMENTED
DEFW CMND40 ; WRITE RANDOM WITH ZERO FILL
;
; I/O ROUTINES
;
; P2DOS CONSOLE INPUT
;
; READ CHARACTER FROM CONSOLE AND ECHO
; IF CHAR=CR,LF,TAB,CONTH OR >=SPACE
;
RDCON: CALL GETCH ; GET CHARACTER
CALL TSTCH ; TEST IF CR,LF,TAB,CONTH OR >=SPACE
JR C,EXIT ; NO THEN EXIT
CALL WRCON ; ECHO CHARACTER
EXIT: LD (PEXIT),A ; RETURN CHARACTER
DUMMY: RET ; AND EXIT P2DOS
;
; P2DOS WRITE CONSOLE
;
BWRCON: LD A,E ; COPY CHARAKTER
JR WRCON ; AND OUTPUT IT
;
; READ READER
;
RDRDR: CALL READER ; GET CHARACTER FROM READER
JR EXIT ; AND RETURN IT TO CALLER
;
; WRITE PUNCH
;
WPUNCH: LD C,E ; COPY CHARACTER
JP PUNCH ; AND OUTPUT IT TO PUNCH DEVICE
;
; WRITE LIST
;
WLIST: LD C,E ; COPY CHARACTER
JP LIST ; AND OUTPUT IT TO LIST DEVICE
;
; DIRECT CONSOLE INPUT/OUTPUT
;
DCIO: LD C,E ; COPY CHARACTER
INC E ; TEST IF 0FFH
JR Z,DCIO0 ; YES DO INPUT
INC E ; TEST IF 0FEH
JP NZ,CONOUT ; NO THEN OUTPUT CHARACTER
CALL CONST ; GET CONSOLE STATUS
AND 1 ; TEST IT
JR EXIT ; AND RETURN IT TO CALLER
DCIO0: CALL CONST ; GET CONSOLE STATUS
AND 1 ; TEST IT
RET Z ; EXIT IF NO CHARACTER PRESENT
CALL CONIN ; GET CHARACTER
JR EXIT ; AND RETURN IT TO CALLER
;
; GET I/O STATUS BYTE
;
GIOST: LD A,(RAMLOW+00003H) ; GET I/O BYTE FROM RAM
JR EXIT ; AND RETURN IT TO CALLER
;
; SET I/O STATUS BYTE
;
SIOST: LD A,E ; COPY I/O BYTE
LD (RAMLOW+00003H),A ; AND SAVE IT IN RAM
RET ; EXIT TO CALLER
;
; TEST CONSOLE STATUS
;
TSTCS: CALL GCONST ; GET CONSOLE STATUS
JR EXIT ; AND RETURN IT TO CALLER
;
; OUTPUT CHAR (CONTROL CHAR = ^CHAR)
;
OUTCH: CALL TSTCH ; TEST IT CR,LF,TAB,CONTH OR >=SPACE
JR NC,WRCON ; YES THEN JUMP
PUSH AF ; SAVE CHARACTER
LD A,'^' ; LOAD A WITH '^'
CALL WRCON ; OUTPUT IT
POP AF ; GET CHARACTER BACK
PUSH AF ; SAVE IT AGAIN
ADD A,'A'-1 ; ADD OFFSET
CALL WRCON ; OUTPUT IT
POP AF ; GET CHARACTER
RET ; RETURN TO CALLER
;
; ECHO CR,LF
;
CROUT: LD A,CR ; A=CARRIAGE RETURN
CALL WRCON ; OUTPUT IT
LD A,LF ; A=LINE FEED
; FALL THROUGH TO OUTPUT ROUTINE
;
; WRITE CHARACTER ON CONSOLE
;
WRCON: CP TAB ; TEST IF TAB
JR NZ,WRCON1 ; NO THEN JUMP
WRCON0: LD A,' ' ; EXPAND TAB WITH SPACES
CALL WRCON ; WRITE SPACE
LD A,(TABCNT) ; GET TAB COUNT
AND 7 ; TEST IF DONE
JR NZ,WRCON0 ; NO THEN REPEAT
LD A,TAB ; RETURN TAB
RET ; RETURN TO CALLER
WRCON1: PUSH AF ; SAVE CHARACTER
CALL GCONST ; TEST STATUS AND CONTS/CONTC
POP AF ; GET CHARACTER BACK
PUSH AF ; SAVE IT AGAIN
LD C,A ; COPY IT
CALL CONOUT ; OUTPUT IT
POP AF ; GET CHARACTER BACK
PUSH AF ; SAVE IT AGAIN
LD C,A ; COPY IT
LD A,(FCONTP) ; GET PRINTER ECHO FLAG
OR A ; TEST IT
CALL NZ,LIST ; NON ZERO => OUTPUT CHAR TO PRINTER
LD A,(FLAGS) ; GET FLAG BYTE
BIT 1,A ; TEST DELAY 256 BYTES ACTIVE
JR Z,WRCON2 ; NO THEN EXIT
LD HL,DELAY ; GET DELAY COUNTER
XOR A ; A=0
OR (HL) ; TEST COUNTER=0
JR Z,WRCON2 ; YES THEN EXIT
DEC (HL) ; ELSE DECREMENT COUNTER
WRCON2: POP AF ; RESTORE CHARACTER
; FALL THROUGH TO COUNT ROUTINE
;
; COUNT CHARAKTERS IN LINE
;
COUNTC: LD HL,TABCNT ; GET POINTER TO TAB COUNTER
CP RUBOUT ; TEST IF CHARACTER = RUBOUT
RET Z ; YES NO UPDATE TAB COUNTER
INC (HL) ; INCREMENT TAB COUNTER
CP ' ' ; TEST IF CHAR >= ' '
RET NC ; YES, NORMAL CHARACTER THEN EXIT
DEC (HL) ; CONTROL CHARACTER, DECREMENT TAB COUNT
CP CONTH ; TEST BACKSPACE
JR NZ,COUNT0 ; NO BACKSPACE THEN JUMP
DEC (HL) ; DECREMENT TAB COUNTER
RET ; AND EXIT
COUNT0: CP CR ; TEST CARRIAGE RETURN
JR NZ,COUNT1 ; NO THEN JUMP
LD (HL),0 ; RESET TAB COUNT
RET ; AND EXIT
COUNT1: CP TAB ; TEST TAB CHARACTER
RET NZ ; NO THEN EXIT
PUSH AF ; SAVE CHARACTER
LD A,(HL) ; GET TAB COUNT
ADD A,8 ; ADVANCE IT 8 POSITION
AND 0F8H ; SET IT TO NEXT TAB POSITION
LD (HL),A ; SAVE IT
POP AF ; RESTORE CHARACTER
RET ; AND EXIT
;
; GET CHARAKTER FROM CONSOLE
;
GETCH: LD HL,LASTCH ; GET POINTER TO LAST INPUT CHARACTER
LD A,(HL) ; GET CHARACTER
LD (HL),0 ; RESET LAST CHARACTER
OR A ; TEST IF CHARACTER PRESENT
RET NZ ; RETURN IF SO
JP CONIN ; ELSE GET CHARACTER
;
; GET CONSOLE STATUS
;
GCONST: LD A,(DELAY) ; GET 256 BYTES DELAY
OR A ; TEST IT
JR NZ,GCONS0 ; NON ZERO, DELAY STIL ACTIVE OR DISABLED
CALL CONST ; GET CONSOLE STATUS
AND 1 ; TEST IT
JR NZ,GCONS1 ; NON ZERO THEN GET CHARACTER
GCONS0: LD A,(LASTCH) ; GET LAST CHARACTER
OR A ; TEST IT
JR NZ,GCONS3 ; NON ZERO THEN CHARACTER PRESENT
CALL CONST ; GET CONSOLE STATUS
AND 1 ; TEST IT
RET Z ; RETURN IF NO CHARACTER PRESENT
GCONS1: CALL CONIN ; GET CHARACTER
CP CONTS ; TEST STOP CHARACTER
JR NZ,GCONS2 ; NOT THEN EXIT CHARACTER
CALL CONIN ; GET NEXT CHARACTER
CP CONTC ; TEST IF USER WANTS TO EXIT
JP Z,RAMLOW+00000H ; YES THEN WARM BOOT
JR GCONST ; TEST AGAIN
GCONS2: LD (LASTCH),A ; SAVE CHARACTER
LD A,0FFH ; SET DELAY COUNTER
LD (DELAY),A ; AND SAVE IT
GCONS3: LD A,1 ; CHARACTER PRESENT CODE
RET ; RETURN TO CALLER
;
; TEST CHARACTER
; EXIT CARRY=0: CR,LF,TAB,CONTH OR >=SPACE
; CARRY=1: ALL OTHER CHARACTERS
;
TSTCH: CP CR ; TEST CARRIAGE RETURN
RET Z ; RETURN IF SO
CP LF ; TEST LINE FEED
RET Z ; RETURN IF SO
CP TAB ; TEST TAB
RET Z ; RETURN IF SO
CP CONTH ; TEST BACKSPACE
RET Z ; RETURN IF SO
CP ' ' ; TEST >=SPACE
RET ; RETURN TO CALLER
;
; WRITE BACKSPACE,SPACE,BACKSPACE
;
WCONTH: CALL WCONT0 ; WRITE BACKSPACE
LD C,' ' ; LOAD SPACE
CALL CONOUT ; AND OUTPUT IT
WCONT0: LD C,CONTH ; LOAD BACKSPACE
JP CONOUT ; AND OUTPUT IT
;
; OUTPUT MESSAGE
;
MESS: LD A,(DE) ; GET BYTE FROM BUFFER
CP '$' ; TEST LAST BYTE
RET Z ; YES, THEN RETURN TO CALLER
INC DE ; POINT TO NEXT BYTE
PUSH DE ; SAVE POINTER
CALL WRCON ; OUTPUT CHARACTER
POP DE ; RESTORE POINTER
JR MESS ; AND TEST AGAIN
;
; AGAIN PRINTS #,CR,LF AND ADVANCES TO TABCX1
;
AGAIN: LD A,'#' ; LOAD '#'
CALL WRCON ; OUTPUT IT
AGAIN0: CALL CROUT ; OUTPUT CARRIAGE RETURN/LINE FEED
AGAIN1: LD HL,TABCNT ; GET TAB COUNT POINTER
LD A,(TABCX1) ; GET POSITION FIRST CHARACTER LINE
CP (HL) ; CHECK IT
RET Z ; RETURN IF ON SAME POSITION
LD A,' ' ; LOAD SPACE
CALL WRCON ; OUTPUT IT
JR AGAIN1 ; AND TEST AGAIN
;
; DELETE CHAR
; ENTRY : HL=START BUFFER-1
; B =CHARACTER COUNTER (ALWAYS>0)
;
DELCH: DEC B ; DECREMENT CHARACTER COUNTER
LD A,(TABCNT) ; GET TAB COUNTER
PUSH AF ; SAVE IT
PUSH BC ; SAVE CHARACTER COUNTER
LD A,(TABCX1) ; GET POSITION FIRST CHARACTER LINE
LD (TABCNT),A ; SAVE IT IN TAB COUNTER
DELCH0: LD A,B ; COPY CHARACTER COUNTER
OR A ; TEST IF 0
JR Z,DELCH2 ; YES THEN JUMP
DEC B ; DECREMENT IT
INC HL ; INCREMENT BUFFER POINTER
LD A,(HL) ; GET CHARACTER FROM BUFFER
PUSH HL ; SAVE BUFFER POINTER
CALL TSTCH ; TEST IF CR,LF,TAB,CONTH OR >=SP
JR NC,DELCH1 ; YES THEN JUMP
RRA ; ELSE MUST BE CONTROL CHARACTER
CALL COUNTC ; COUNT CONTROL CHARACTER TWICE
DELCH1: CALL COUNTC ; COUNT CHARACTER
POP HL ; GET BUFFER POINTER
JR DELCH0 ; AND TEST AGAIN
DELCH2: POP BC ; RESTORE CHARACTER COUNTER
POP AF ; AND TAB COUNTER
PUSH HL ; SAVE BUFFER POINTER
PUSH BC ; AND CHARACTER COUNTER
LD HL,TABCNT ; GET TAB COUNTER POINTER
SUB (HL) ; CALCULATE DIFFERENCE
DELCH3: DEC A ; DECREMENT IT
CP 8 ; COMPARE WITH 8
JR NC,DELCH4 ; JUMP IF >=8
PUSH AF ; SAVE DIFFERENCE
CALL WCONTH ; REMOVE CHARACTER END LINE
POP AF ; RESTORE COUNTER
JR DELCH3 ; REMOVE MORE CHARACTERS
DELCH4: POP BC ; RESTORE CHARACTER COUNTER
POP HL ; RESTORE BUFFER POINTER
RET ; AND RETURN TO CALLER
;
; READ BUFFER
;
RDBUF: LD A,(TABCNT) ; GET CURRENT POSITION CURSOR
LD (TABCX1),A ; SAVE IT
RDBUF0: PUSH IX ; SAVE START ADDRESS BUFFER
POP HL ; GET IT IN HL
LD C,(HL) ; GET MAXIMUM LINE LENGHT
INC HL ; INCREMENT TO LINE LENGHT POSITION
LD B,0 ; CLEAR LINE LENGHT COUNTER
PUSH HL ; SAVE START LINE - 1
RDBUF1: PUSH HL ; SAVE REGISTERS
PUSH BC
RDBUF2: CALL GETCH ; GET CHARACTER
POP BC ; RESTORE REGISTERS
POP HL
AND 07FH ; MASK CHARACTER
CP CONTE ; TEST IF CONTE
JR NZ,RDBUF3 ; NOT THEN JUMP
PUSH HL ; SAVE REGISTERS
PUSH BC
CALL AGAIN0 ; MOVE CURSOR TO NEXT LINE
JR RDBUF2 ; AND GET NEXT CHAR
RDBUF3: CP CONTH ; TEST BACKSPACE
JR NZ,RDBUF4 ; NOT THEN JUMP
LD A,B ; TEST IF DELETING CHAR FROM EMPTY LINE
OR A
JR Z,RDBUF1 ; YES THEN GET NEXT CHAR
POP HL ; GET START LINE
PUSH HL ; AND SAVE IT AGAIN
CALL DELCH ; DELETE CHARACTER
JR RDBUF1 ; GET NEXT CHARACTER
RDBUF4: CP CONTP ; TEST PRINT ENABLE/DISABLE
JR NZ,RDBUF6 ; NOT THEN JUMP
LD A,(FCONTP) ; COMPLEMENT PRINT FLAG
CPL
LD (FCONTP),A
RDBUF5: JR RDBUF1 ; AND GET NEXT CHARACTER
RDBUF6: CP CONTR ; TEST REPEAT LINE
JR NZ,RDBUFA ; NOT THEN JUMP
PUSH BC ; SAVE REGISTERS
CALL AGAIN ; MOVE CURSOR TO NEXT LINE
POP BC ; RESTORE REGISTERS
POP HL ; GET START LINE
PUSH HL ; SAVE IT AGAIN
PUSH BC ; SAVE LINE COUNTER/MAXIMUM LINE LENGHT
RDBUF7: LD A,B ; TEST LAST CHARACTER ECHOED
OR A
JR Z,RDBUF8 ; YES THEN JUMP
INC HL ; INCREMENT POINTER
LD A,(HL) ; GET CHARACTER
DEC B ; DECREMENT LINE COUNTER
PUSH HL ; SAVE REGISTERS
PUSH BC
CALL OUTCH ; OUTPUT CHARACTER
POP BC ; RESTORE REGISTERS
POP HL
JR RDBUF7 ; AND TEST END LINE
RDBUF8: POP BC ; RESTORE LINE COUNTER/MAXIMUM LINE LENGHT
RDBUF9: JR RDBUF5 ; AND GET NEXT CHAR
RDBUFA: CP CONTU ; TEST DELETE LINE
JR NZ,RDBUFC ; NOT THEN JUMP
POP HL ; GET START LINE
CALL AGAIN ; MOVE CURSOR TO NEXT LINE
RDBUFB: JR RDBUF ; AND START ROUTINE AGAIN
RDBUFC: CP CONTX ; TEST DELETE LINE
JR NZ,RDBUFE ; NOT THEN JUMP
RDBUFD: POP HL ; GET START LINE
LD A,B ; TEST IF LAST CHARACTER DELETED
OR A
JR Z,RDBUFB ; YES START ROUTINE AGAIN
PUSH HL ; SAVE POINTER
CALL DELCH ; DELETE LAST CHARACTER LINE
JR RDBUFD ; TEST LAST CHARACTER DELETED
RDBUFE: CP RUBOUT ; TEST DELETE LAST CHARACTER
JR NZ,RDBUFF ; NOT THEN JUMP
LD A,B ; TEST FIRST CHARACTER LINE
OR A
JR Z,RDBUF9 ; YES, DO NOT DELETE
LD A,(HL) ; GET LAST CHARACTER
DEC HL ; DECREMENT POINTER LINE
DEC B ; DECREMENT LINE COUNTER
JR RDBUFG ; ECHO LAST CHARACTER
RDBUFF: CP CR ; TEST CARRIAGE RETURN
JR Z,RDBUFI ; YES, THEN EXIT
CP LF ; TEST LINE FEED
JR Z,RDBUFI ; YES THEN EXIT
INC HL ; INCREMENT POINTER
LD (HL),A ; AND SAVE CHARACTER
INC B ; INCREMENT LINE COUNTER
RDBUFG: PUSH HL ; SAVE REGISTERS
PUSH BC
CALL OUTCH ; ECHO CHARACTER
POP BC ; RESTORE REGISTERS
POP HL
CP CONTC ; TEST WARM BOOT
LD A,B ; GET LINE COUNT
JR NZ,RDBUFH ; NO WARM BOOT THEN JUMP
CP 1 ; TEST CONTC IS FIRST CHARACTER LINE
JP Z,RAMLOW+00000H ; YES THEN EXECUTE WARM BOOT
RDBUFH: CP C ; TEST LINE LENGHT=MAXIMUM LINE LENGHT
JR NZ,RDBUF9 ; NOT THEN GET NEXT CHARACTER
RDBUFI: POP HL ; GET START LINE - 1
LD (HL),B ; SAVE LINE COUNTER
LD A,CR ; LOAD CARRIAGE RETURN
JP WRCON ; AND ECHO IT
;
;******************************************************************************
;* *
;* DISK FUNCTIONS *
;* *
;******************************************************************************
;
; RETURN VERSION NUMBER
;
CMND12: LD A,22H ; SET VERSION NUMBER
JR CMD25A ; AND EXIT
;
; RESET DISK SYSTEM
;
CMND13: LD HL,0 ; LOAD ZERO
LD (LOGIN),HL ; ALL DRIVES LOGED OUT
LD (DSKRO),HL ; ALL DRIVES READ/WRITE
LD HL,RAMLOW+00080H ; SET UP DMA ADDRESS
LD (DMA),HL ; AND SAVE IT
CALL STDMA ; DO P2BIOS CALL
XOR A ; SET DEFAULT DRIVE = 'A'
LD (DEFDRV),A ; SAVE IT
CALL SELDK ; SELECT DRIVE 'A'
LD A,(SUBFLG) ; GET SUBMIT FLAG
JR CMD25A ; EXIT
;
; SEARCH FOR FILE
;
CMND17: CALL SELDRV ; SELECT DRIVE FROM FCB
LD A,(IX+0) ; GET DRIVE NUMBER FROM FCB
SUB '?' ; TEST IF '?'
JR Z,CMD17B ; IF SO ALL ENTRIES MATCH
LD A,(IX+14) ; GET SYSTEM BYTE
CP '?' ; TEST IF '?'
JR Z,CMD17A ; YES, JUMP
LD (IX+14),0 ; LOAD SYSTEM BYTE WITH ZERO
CMD17A: LD A,15 ; TEST FIRST 15 ITEMS IN FCB
CMD17B: CALL SEARCH ; DO SEARCH
CMD17C: LD HL,(DIRBUF) ; COPY DIRECTORY BUFFER
LD DE,(DMA) ; TO DMA ADDRESS
LD BC,128 ; DIRECTORY=128 BYTES
LDIR
RET ; EXIT
;
; SEARCH FOR NEXT OCCURENCE FILE
;
CMND18: LD IX,(DCOPY) ; GET LAST FCB USED BY SEARCH
CALL SELDRV ; SELEXT DRIVE FROM FCB
CALL SEARCN ; SEARCH NEXT FILE MATCH
JR CMD17C ; AND COPY DIRECTORY TO DMA ADDRESS
;
; DELETE FILE
;
CMND19: CALL SELDRV ; SELECT DRIVE FROM FCB
CALL DELETE ; DELETE FILE
CMD19A: LD A,(SEAREX) ; GET EXIT BYTE 00=FILE FOUND,0FFH NOT
JR CMD25A ; AND EXIT
;
; RENAME FILE
;
CMND23: CALL SELDRV ; SELECT DRIVE FROM FCB
CALL RENAM ; RENAME FILE
JR CMD19A ; AND EXIT
;
; RETURN LOGIN VECTOR
;
CMND24: LD HL,(LOGIN) ; GET LOGIN VECTOR
CMD24A: LD (PEXIT),HL ; SAVE IT
RET ; AND EXIT
;
; RETURN CURRENT DRIVE
;
CMND25: LD A,(DEFDRV) ; GET CURRENT DRIVE
CMD25A: JP EXIT ; AND EXIT
;
; RETURN ALV VECTOR
;
CMND27: LD HL,(ALV) ; GET ALLOCATION VECTOR
JR CMD24A ; AND EXIT
;
; RETURN DISK R/O VECTOR
;
CMND29: LD HL,(DSKRO) ; GET DISK R/O VECTOR
JR CMD24A ; AND EXIT
;
; CHANGE STATUS
;
CMND30: CALL SELDRV ; SELECT DRIVE FROM FCB
CALL CSTAT ; CHANGE STATUS
JR CMD19A ; AND EXIT
;
; RETURN DRIVE TABEL
;
CMND31: LD HL,(IXP) ; GET DRIVE TABLE
JR CMD24A ; AND EXIT
;
; SET/GET USER CODE
;
CMND32: LD A,E ; GET USER CODE
INC A ; TEST IF 0FFH
LD A,(USER) ; GET OLD USER CODE
JR Z,CMD25A ; IF 0FFH THEN EXIT
LD A,E ; GET NEW USER CODE
AND 01FH ; MASK IT
LD (USER),A ; SAVE IT
RET ; AND EXIT
;
; COMPUTE FILE SIZE COMMAND
;
CMND35: CALL SELDRV ; SELECT DRIVE FROM FCB
CALL FILSZ ; COMPUTE FILE SIZE
JR CMD19A ; AND EXIT
;
; SET RANDOM RECORD COUNT
;
CMND36: LD HL,32 ; SET POINTER TO NEXT RECORD
CALL CALRRC ; CALCULATE RANDOM RECORD COUNT
LDRRC: LD (IX+33),D ; AND SAVE RANDOM RECORD COUNT
LD (IX+34),C
LD (IX+35),B
RET ; AND EXIT
;
; RESET MULTIPLE LOGIN DRIVE
;
CMND37: LD A,E ; GET MASK LSB
CPL ; COMPLEMENT IT
LD E,A
LD A,D ; GET MASK MSB
CPL ; COMPLEMENT IT
LD D,A
LD HL,(LOGIN) ; GET LOGIN VECTOR
LD A,E ; MASK LOGIN VECTOR
AND L ; LSB
LD L,A
LD A,D ; MASK LOGIN VECTOR
AND H ; MSB
LD H,A
LD (LOGIN),HL ; SAVE LOGIN VECTOR
EX DE,HL ; USE LOGIN VECTOR AS MASK
LD HL,(DSKRO) ; GET DRIVE R/O VECTOR
LD A,E ; MASK DRIVE R/O VECTOR
AND L ; LSB
LD L,A
LD A,D ; MASK DRIVE R/O VECTOR
AND H ; LSB
LD H,A
LD (DSKRO),HL ; SAVE DRIVE R/O VECTOR
RET ; AND EXIT
;
;******************************************************************************
;* *
;* ERROR ROUTINES *
;* *
;******************************************************************************
;
; BAD SECTOR ERROR
;
BADSEC: LD DE,MBADSC ; LOAD BAD SECTOR MESSAGE
JR DERROR ; AND DISPLAY ERROR
;
; SELECT ERROR
;
SELERR: LD DE,MSEL ; LOAD SELECT ERROR MESSAGE
JR DERROR ; AND DIPLAY ERROR
;
; FILE READ ONLY ERROR
;
FILRO: LD DE,MFILRO ; LOAD FILE R/O MESSAGE
LD A,0FFH ; SET FILE R/O MESSAGE FLAG
JR ERROR ; AND DISPLAY ERROR
;
; DRIVE READ ONLY ERROR
;
RDONLY: LD DE,MRO ; LOAD DRIVE R/O MESSAGE
DERROR: XOR A ; SET NO FILE R/O MESSAGE
;
; DISPLAY ERROR MESSAGE
;
; P2DOS ERROR ON D: ERROR MESSAGE
; FUNCTION = NN [FILE = FILENAME.TYP]
;
ERROR: LD C,A ; SAVE FILE R/O MESSAGE FLAG
PUSH BC
PUSH DE ; SAVE ERROR MESSAGE POINTER
CALL CROUT ; DISPLAY CR/LF
LD A,(DEFDRV) ; GET CURRENT DRIVE
ADD A,'A' ; MAKE ASCII
LD (MDRIVE),A ; SAVE IT
LD DE,MBERR ; LOAD MESSAGE "P2DOS ERROR ON D:"
CALL MESS ; DISPLAY MESSAGE
POP DE ; GET ERROR MESSAGE POINTER
CALL MESS ; DISPLAY MESSAGE
CALL CROUT ; DISPLAY CR/LF
LD DE,MBFUNC ; LOAD MESSAGE "FUNCTION ="
CALL MESS ; DISPLAY MESSAGE
LD A,(FUNCT) ; GET FUNCTION NUMBER
PUSH AF ; SAVE IT
LD BC,100 ; DISPLAY NUMBER / 100
CALL NUM
LD C,10 ; DISPLAY NUMBER / 10
CALL NUM
LD BC,101H ; ALWAYS DISPLAY NUMBER / 1
CALL NUM
POP AF ; GET FUNCTION NUMBER
POP BC ; GET FILE R/O FLAG
CP 15 ; TEST IF FCB USED IN COMMAND
JR C,ERROR3
CP 24
JR C,ERROR1
CP 30
JR Z,ERROR1
CP 33
JR C,ERROR3
CP 37
JR C,ERROR1
CP 40
JR NZ,ERROR3
ERROR1: PUSH IX ; YES THEN DISPLAY "FILE ="
SUB 19 ; TEST DELETE FILE FUNCTION
JR NZ,ERROR2 ; NOT THEN JUMP
OR C ; TEST FILE R/O FLAG
JR Z,ERROR2 ; NO FILE R/O THEN JUMP
CALL CALDIR ; GET FCB FROM DIRECTORY BUFFER
EX (SP),HL ; SAVE IT
ERROR2: LD DE,MFILE ; GET MESSAGE " FILE ="
CALL MESS ; DISPLAY MESSAGE
POP HL ; GET POINTER FCB
LD B,8 ; DISPLAY FIRST 8 CHARACTERS
CALL FILENM
LD A,'.' ; LOAD '.'
PUSH HL ; SAVE FCB POINTER
CALL WRCON ; ECHO IT
POP HL ; RESTORE FCB POINTER
LD B,3 ; DISPLAY LAST 3 CHARACTERS
CALL FILENM
ERROR3: CALL GCONST ; TEST IF CHARACTER PRESENT
OR A
JR Z,ERROR4 ; NO THEN JUMP
CALL GETCH ; GET CHARACTER
JR ERROR3 ; AND TEST AGAIN
ERROR4: CALL GETCH ; GET CHARACTER
JP RAMLOW+00000H ; AND DO WARM BOOT
;
; DISPLAY NUMBER
;
NUM: LD D,-1 ; LOAD NUMBER -1
NUM1: INC D ; INCREMENT NUMBER
SUB C ; DIVIDE BY C
JR NC,NUM1 ; NOT FINISHED THEN LOOP
ADD A,C ; RESTORE LAST VALUE
PUSH AF ; SAVE IT
LD A,D ; TEST IF "0"
OR B ; AND IF LEADING ZERO
JR Z,NUM2 ; YES, THEN EXIT
LD B,A ; SET NO LEADING ZERO
LD A,D ; GET NUMBER
ADD A,'0' ; MAKE ASCII
PUSH BC ; SAVE REGISTERS
CALL WRCON ; ECHO NUMBER
POP BC ; RESTORE REGISTERS
NUM2: POP AF ; RESTORE NUMBER
RET ; AND EXIT
;
; DISPLAY FILNAME.TYP
;
FILENM: INC HL ; INCREMENT POINTER FCB
LD A,(HL) ; GET CHARACTER FROM FCB
AND 07FH ; MASK IT
PUSH HL ; SAVE REGISTERS
PUSH BC
CALL WRCON ; ECHO CHARACTER
POP BC ; RESTORE REGISTERS
POP HL
DJNZ FILENM ; REPEAT B TIMES
RET ; AND EXIT
;
; ERROR MESSAGES
;
MBADSC: DEFM 'Bad sector$'
;
MSEL: DEFM 'Select$'
;
MFILRO: DEFM 'File '
;
MRO: DEFM 'R/O$'
;
MBERR: DEFM 'P2DOS error on '
MDRIVE: DEFB 0
DEFB DRVSEP
DEFM ' $'
;
MBFUNC: DEFM 'Function =$'
;
MFILE: DEFM ' File =$'
;
; SELECT DISK FROM FCB
;
SELDRV: LD A,0FFH ; SET DISK SELECT DONE FLAG
LD (FLDRV),A
LD A,(DEFDRV) ; GET CURRENT DRIVE
LD (DRIVE),A ; SAVE IT IN MEMORY
LD E,A ; SAVE IT IN REGISTER E
LD A,(IX+0) ; GET DRIVE FROM FCB
LD (FCB0),A ; SAVE IT
CP '?' ; TEST IF '?'
JR Z,CMND14 ; YES, THEN SELECT DRIVE FROM REGISTER E
AND 01FH ; MASK DRIVE
LD A,E ; TEST IF ZERO
JR Z,SELDR0 ; SELECT DRIVE FROM REGISTER E
LD A,(IX+0) ; GET DRIVE FROM FCB
DEC A ; DECREMENT DRIVE
SELDR0: CALL SELDK ; SELECT DRIVE
LD A,(IX+0) ; GET DRIVE FROM FCB
AND 0E0H ; REMOVE DRIVE BITS
LD B,A ; SAVE REGISTER
LD A,(USER) ; GET USER NUMBER
OR B ; INSERT USER NUMBER IN FCB
LD (IX+0),A
RET ; AND EXIT
;
; 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 LENGHT 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 RESTORE 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 EXTEND MASK
AND (IX+12) ; MASK WITH EXTEND
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 WITH 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 FIRST 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
JP SETWPD ; SET WRITE PROTECT DISK
CHKDR1: LD (HL),A ; UPDATE CHECKSUM
RET ; AND EXIT
;
; READ SECTOR FROM DRIVE
;
READR: CALL READ ; P2BIOS CALL READ SECTOR
JR WRITE0 ; TEST EXIT CODE
;
; WRITE SECTOR ON DRIVE
;
WRITER: CALL WRITE ; P2BIOS CALL WRITE SECTOR
WRITE0: OR A ; TEST EXIT CODE
RET Z ; EXIT IF OK
LD HL,(STBDSC) ; LOAD BAD SECTOR MESSAGE POINTER
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 LENGHT 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
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
LD A,(SEARPU) ; TEST IF PUBLIC FILE
LD B,A ; SAVE IT
LD A,(SEARQU) ; TEST IF QUESTION MARK USED IN FILE NAME
OR B ; A=PUBLIC FILE OR QUESTION MARK USED
CHKFR0: LD DE,2 ; OFFSET TO PUBLIC FILE BIT
ADD HL,DE ; ADD OFFSET
OR A ; TEST QUESTION MARK USED
JR Z,CHKFR1 ; NO THEN DON'T TEST PUBLIC FILE BIT
BIT 7,(HL) ; TEST PUBLIC FILE
JR NZ,CHKFR2 ; YES THEN ERROR
CHKFR1: LD E,7 ; OFFSET TO FILE R/O BIT
ADD HL,DE ; ADD OFFSET
BIT 7,(HL) ; TEST FILE R/O
JR NZ,CHKFR2 ; YES THEN ERROR
OR A ; TEST QUESTION MARK USED
RET Z ; NO THEN DON'T TEST SYSTEM FILE BIT
INC HL ; INCREMENT TO SYSTEM FILE
BIT 7,(HL) ; TEST SYSTEM FILE
RET Z ; NO SYSTEM FILE THEN OK
CHKFR2: 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 LENGHT-1 IN BC
OR A ; CLEAR CARRY
SBC HL,BC ; TEST HL>=LENGHT 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: 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
;
; SEARCH NEXT FILE NAME
;
SEARCN: XOR A ; CHECK CHECKSUM DIRECTORY
CALL RDDIR ; GET FCB FROM DIRECTORY
CALL TSTFCT ; TEST IF PAST LAST ENTRY
JP 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
RES 7,(IX+8) ; RESET PUBLIC/SYSTEM 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
XOR '?' ; TEST IF QUESTION MARK
AND 07FH ; MASK IT
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
SET 7,(IX+8) ; SET PUBLIC/SYSTEM FILE FLAG
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 EXTEND NUMBER
LD A,(DE) ; GET BYTE FROM FCB
JR Z,SEARC7 ; JUMP IF EXTEND 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 EXTENDS
LD B,A ; SAVE IT
LD A,(NEXTND) ; GET EXTEND MASK
CPL ; COMPLEMENT IT
AND 01FH ; MASK IT
AND B ; MASK EXTENDS
POP BC ; RESTORE 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 WRFCB ; 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
PUSH IX ; SAVE FCB ENTRY
POP HL ; GET IT IN HL
LD DE,16 ; OFFSET TO NEW NAME
ADD HL,DE ; ADD OFFSET
EX DE,HL ; COPY HL=>DE
CALL CALDIR ; GET DIRECTORY ENTRY
LD B,11 ; SET UP LOOP COUNTER
RENAM1: INC HL ; INCREMENT DIRECTORY POINTER
INC DE ; INCREMENT FCB POINTER
LD A,(DE) ; GET CHARACTER FROM FCB
AND 07FH ; MASK IT
CP '?' ; TEST IF QUESTION MARK
JR Z,RENAM2 ; YES THEN DO NOT CHANGE CHARACTER ON DISK
LD C,A ; SAVE IT IN C
LD A,(HL) ; GET CHARACTER FROM DIRECTORY
AND 080H ; MASK STATUS BIT
OR C ; OR WITH NEW CHARACTER
LD (HL),A ; SAVE IN DIRECTORY
RENAM2: DJNZ RENAM1 ; LOOP UNTIL DONE
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
PUSH IX ; SAVE FCB ENTRY
POP DE ; GET IT IN HL
CALL CALDIR ; GET DIRECTORY ENTRY
LD B,11 ; SET UP LOOP COUNTER
CSTAT1: INC HL ; INCREMENT DIRECTORY POINTER
INC DE ; INCREMENT FCB POINTER
LD A,(DE) ; GET STATUS BIT FROM FCB
AND 080H ; MASK IT
LD C,A ; SAVE IT IN C
LD A,(HL) ; GET CHARACTER FROM DIRECTORY
AND 07FH ; MASK IT
OR C ; OR WITH NEW STATUS BIT
LD (HL),A ; SAVE IN DIRECTORY
DJNZ CSTAT1 ; LOOP UNTIL DONE
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 LENGHT
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 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
SET 7,(IX+8) ; SET PUBLIC/SYSTEM FILE FLAG
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+8) ; GET PUBLIC/SYSTEM FILE BIT
PUSH AF ; SAVE IT
LD A,(IX+12) ; GET EXTEND 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 EXTEND NUMBER
LD C,(IX+15) ; GET NEXT RECORD NUMBER
POP AF ; GET OLD EXTEND NUMBER
LD (IX+12),A ; SAVE IT
CP B ; COMPARE OLD AND NEW EXTEND NUMBER
JR Z,OPENF1 ; SAME THEN JUMP
LD C,0 ; SET NEXT RECORD COUNT TO 0
JR NC,OPENF1 ; OLD EXTEND >= NEW EXTEND THEN JUMP
LD C,80H ; SET NEXT RECORD COUNT TO MAXIMUM
OPENF1: LD (IX+15),C ; SAVE NEXT RECORD COUNT
POP AF ; GET PUBLIC/SYSTEM FILE BIT
RL (IX+8) ; REMOVE MSB FROM IX+8
RLA ; SET NEW MSB IN CARRY
RR (IX+8) ; SAVE CARRY IN IX+8
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 EXTEND NUMBER
ADD HL,DE ; HL CONTAINS POINTER TO EXTEND NUMBER
LD A,(IX+12) ; GET EXTEND NUMBER FCB
CP (HL) ; COMPARE WITH EXTEND NUMBER DIRECTORY
JR C,CLOSE3 ; FCB < DIRECTORY THEN JUMP
LD (HL),A ; SAVE EXTEND 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 ; EXTENDS 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: LD E,5 ; SET LAST UPDATE DATE/TIME
CALL STIME ; UPDATE TIME
CALL CALDIR ; GET DIRECTORY ENTRY
LD BC,11 ; POINT TO ARCHIEVE BYTE
ADD HL,BC
RES 7,(HL) ; RESET ARCHIEVE BIT
RES 7,(IX+11) ; RESET BIT IN FCB
JP WRFCB ; 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 UP TO FCB+31
INC HL ; INCREMENT POINTER
DJNZ MAKE0 ; AND CLEAR ALL BYTES
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
RES 7,(IX+8) ; RESET PUBLIC/SYSTEM FILE BIT
RES 7,(IX+11) ; RESET ARCHIEVE BIT IF PRESENT
CALL CALDIR ; GET DIRECTORY ENTRY
PUSH IX ; SAVE FCB ENTRY
POP DE ; GET IT IN DE
EX DE,HL ; EXCHANGE FCB AND DIRECTORY ENTRY
LD BC,32 ; NUMBER OF BYTES TO MOVE
LDIR ; MOVE BYTES
CALL WRFCB ; WRITE FCB ON DISK
SET 7,(IX+14) ; SET FCB/FILE NOT MODIFIED
RET ; AND RETURN TO CALLER
;
; OPEN NEXT EXTEND
;
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 EXTEND
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 EXTEND IF WRITE
CALL TSTFCT ; TEST IF SUCCESFULL
JR NZ,OPENX6 ; YES THEN EXIT
JR OPENX3 ; NO THEN ERROR
OPENX2: CALL CALNEX ; CALCULATE NEXT EXTEND
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 EXTEND
; EXIT: CARRY=1 => OVERFLOW DETECTED
; ZERO =1 => SEARCH NEXT EXTEND
; ZERO =0 => NEXT EXTEND PRESENT (CLOSE)
;
CALNEX: LD B,(IX+12) ; GET EXTEND 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 EXTEND NUMBER
LD A,B ; GET EXTEND 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 EXTEND)
JR CALNX1 ; AND SAVE EXTEND NUMBER AND FCB+14
CALNX0: LD A,(NEXTND) ; GET NEXT EXTEND MASK
AND B ; TEST IF SAME EXTEND (CLOSE)
CALNX1: LD (IX+12),B ; SAVE EXTEND 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 EXTEND
JR NC,READS1 ; YES THEN OPEN NEXT EXTEND
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 EXTEND
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
BIT 7,(IX+9) ; TEST IF FILE R/O
JP NZ,CHKFR2 ; YES THEN FILE R/O MESSAGE
BIT 7,(IX+8) ; TEST IF PUBLIC OR SYSTEM FILE
JP NZ,CHKFR2 ; YES THEN FILE R/O MESSAGE
LD A,(IX+32) ; GET RECORD COUNT
CP 080H ; TEST IF END THIS EXTEND
JR C,WRITS0 ; YES THEN OPEN NEXT EXTEND
CALL OPENEX ; OPEN NEXT EXTEND
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 EXTEND
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,(NMASK) ; GET SECTOR MASK
AND (IX+32) ; MASK WITH RECORD COUNTER
JR Z,WRITSX ; ZERO THEN OK (AT START NEW RECORD)
LD C,0 ; ELSE CLEAR NEW BLOCK FLAG
WRITSX: 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 EXTEND
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 EXTEND NUMBER
CP (IX+12) ; COMPARE WITH FCB
JR NZ,LDFCB0 ; NOT EQUAL THEN OPEN NEXT EXTEND
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 EXTEND
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 EXTEND 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 NEW 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 EXTEND NUMBER
ADD HL,DE ; GET POINTER TO EXTEND BYTE
LD D,A ; SAVE FIRST BYTE
LD A,(HL) ; GET EXTEND 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
;
; 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)
;
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
;
; 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: DEFB 0 ; TAB COUNTER
TABCX1: DEFB 0 ; TEMPORARY TAB COUNTER (USED BY RDBUF)
FCONTP: DEFB 0 ; LIST ENABLE FLAG (CONTROL P)
LASTCH: DEFB 0 ; LAST CHARACTER
DELAY: DEFB 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: DEFB 0 ; NUMBER OF BLOCKS
NMASK: DEFB 0 ; MASK NUMBER OF BLOCKS
NEXTND: DEFB 0 ; EXTEND MASK
MAXLEN: DEFW 0 ; MAXIMUM BLOCK NUMBER-1
NFILES: DEFW 0 ; MAXIMUM NUMBER OF FILES-1
NDIR0: DEFB 0 ; FIRST TWO ENTRIES ALV BUFFER
NDIR1: DEFB 0
NCHECK: DEFW 0 ; NUMBER OF CHECKSUM ENTRIES
NFTRK: DEFW 0 ; FIRST TRACK NUMBER
;
DSKRO: DEFW 0 ; DISK R/O VECTOR
LOGIN: DEFW 0 ; LOGIN VECTOR
DMA: DEFW 080H ; DMA ADDRESS
;
FUNCT: DEFB 0 ; FUNCTION NUMBER
PEXIT: DEFW 0 ; EXIT CODE
FLDRV: DEFB 0 ; DRIVE SELECT USED FLAG
RDWR: DEFB 0 ; READ/WRITE FLAG
;
FCB0: DEFB 0 ; FCB BYTE 0
USER: DEFB 0 ; USER NUMBER
DRIVE: DEFB 0 ; DRIVE NUMBER
DEFDRV: DEFB 0 ; DEFAULT DRIVE NUMBER
RECDIR: DEFW 0 ; RECORD DIRECTORY (CHECKSUM)
FILCNT: DEFW 0 ; FILE COUNTER
SECPNT: DEFB 0 ; SECTOR POINTER
SUBFLG: DEFB 0 ; SUBMIT FLAG (RESET DISK COMMAND)
;
DCOPY: DEFW 0 ; COPY ADDRESS FCB
SEAREX: DEFB 0 ; EXIT CODE SEARCH
SEARNB: DEFB 0 ; SEARCH NUMBER OF BYTES
SEARQU: DEFB 0 ; SEARCH QUESTION MARK USED
SEARPU: DEFB 0 ; SEARCH PUBLIC FILE
;
SPSAVE: DEFW 0 ; STACK POINTER LOCATION
DEFS 64 ; 64 BYTES STACK
P2DOSS: ; P2DOS STACK
;
END ; END PROGRAM