home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-25 | 74.1 KB | 2,485 lines |
- TITLE 'P2 DISK OPERATING SYSTEM'
- .Z80
- ASEG
- ;
- ;******************************************************************************
- ;* *
- ;* P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.1 *
- ;* *
- ;* COPYRIGHT (C) 1985 BY: H.A.J. TEN BRUGGE *
- ;* ALL RIGHTS RESERVED MOLENSTRAAT 33 *
- ;* NL-7491 BD DELDEN *
- ;* THE NETHERLANDS *
- ;* TEL:..31-5407-1980 *
- ;* P2DOS WAS WRITTEN BY HERMAN 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. *
- ;* *
- ;* THIS IS MOD 0.1 TO THE RELEASE VERSION OF P2DOS *
- ;* *
- ;******************************************************************************
- ;
- RAMLOW EQU 00000H ; START ADDRESS MEMORY
- ;
- INCLUDE DOS.LIB
- BASE EQU (MSIZE-7)*1024
- P2DOS EQU BASE+0800H ; START ADDRESS P2DOS
- P2BIOS EQU P2DOS+0E00H ; START ADDRESS P2BIOS
- ;
- PAGE 84 ; 84 LINES/PAGE
- ;
- ; P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.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)
- ; FILE R/O (T1)
- ; SYSTEM FILE (T2)
- ; 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.
- ; - 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
- ;
- ORG 0100H
- .PHASE P2DOS
- ; 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
- ;
- 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
- JR EXIT ; AND RETURN IT TO CALLER
- DCIO0: CALL CONST ; GET CONSOLE STATUS
- OR A ; 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,BACKCPACE
- ;
- 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 ; DIPLAY 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 FISRT 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,D ; 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 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 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 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
- 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
- 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
- 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 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
- 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 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 ; 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 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 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 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
- 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
- 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 EMTY 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)
- 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
- 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 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
- 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 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,(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 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 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 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: 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
- DEFB '*END*' ; JUST A REMINDER
- DEFS 40H,2AH ; FOR ALL THE SPACE THAT'S LEFT
- DEFB '48 BYTES RESERVE'
- DEFB 'D TO ACCOMODATE '
- DEFB 'THE ZCPR-2 STACK'
- ;
- .DEPHASE
- END ; END PROGRAM