home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
utilitys
/
dos1a.arc
/
DOS1A.MAC
< prev
Wrap
Text File
|
1990-07-21
|
37KB
|
1,182 lines
TITLE 'SUPRBDOS Disk Operating System'
;
; Implement full XON - XOFF protocol for console I/O
;
; Michael Stapleton 29/5/1987
;
;******************************************************************************
;* *
;* P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.2 *
;* No more control-C to change disks! *
;* 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.2 TO THE RELEASE VERSION OF P2DOS *
;* *
;******************************************************************************
;* MOD 0.2 Revisions
;* Renamed to SUPRBDOS
;* By Benjamin Ho
;* 626 Emerson St.
;* Evanston, IL 60201
;* Background:
;*
;* P2DOS MOD 0.1 was not a major improvement on the standard CP/M BDOS.
;* While it added Public files, slightly more informative error messages, and
;* time stamping support, it did not fix the major annoyances of the CP/M BDOS,
;* namely the necessity of logging in new disks with Control-C, mystifying
;* error messages, and a delete key that looked like it didn't delete.
;*
;* P2DOS MOD 0.2 is a major enhancement which liberates the CP/M user from all
;* these annoyances. It is compatible with all CP/M software except those
;* that modify the BDOS. Fortunately, that type of program is extremely rare.
;*
;* P2DOS MOD 0.2 may be used with ZCPR3 to provide an extremely powerful
;* 100% CP/M 2.2 compatible operating system. The resulting system is not
;* subject to Digital Research's licensing agreement. The only restriction
;* is that it may be used for non-commerical use only, as stated by the
;* authors of ZCPR3 and P2DOS.
;*
;* Enjoy!
;* 9/2/86-
;* Added automatic login of changed disks--no more Control-C
;* when changing disks!
;* Removed P2DOS tie to ZCPR2. Can now be used with ZCPR3 or
;* (ugh!) normal CP/M.
;* Improved error messages:
;* Disk Error on X: Read Error
;* Write Error
;* Non-existent drive
;* File is Read-Only
;* Fixed delete key--now works like backspace. No echoing characters
;* Allowed functions 13 and 37 to recognize changes between single and
;* double sided disks on machines which normally require a warm
;* boot when "sidedness" is changed. Bios modification is needed
;* to support this feature
;* Fixed directory read bug. Function 37 bug which plagued
;* library utility program NULU 1.5 is fixed.
;* Choice of assembly by M80 and compatibles or public domain ZASM
;* System files are read/write, as in CP/M. Changed from P2DOS
;* mod 0.1 in which system files were R/O
;* Deleted P2DOS search path so the more flexible
;* ZCR3 search path could be used
;* File split into 3 sections for easy of editing.
;******************************************************************************
RAMLOW EQU 00000H ; START ADDRESS MEMORY
DOSSTRT EQU $
P2BIOS EQU DOSSTRT+0E00H
;
;
; 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 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 THEIR 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 TABLE
; 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
;
; added definition for XON character
;
XON EQU 011H ; DEFINE ASCII XON CHARACTER
;
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
;
P2DOS:
;
VERS: DB 000H ; VERSION NUMBER NOT IMPLEMENTED
DB 000H
DB 000H
DB 000H
DB 000H
DB 000H
;
; START P2DOS
;
START: JP ENTRY ; JUMP TO ENTRY POINT P2DOS
;
; ERROR MESSAGES P2DOS
;
;Bad sector message changed to read/write messages-B.H.
;STBDSC: DEFW BADSEC ; BAD SECTOR MESSAGE
STSEL: DEFW SELERR ; SELECT ERROR
STRO: DEFW RDONLY ; DRIVE READ ONLY
SFILRO: DEFW FILRO ; FILE READ ONLY
SRDERR: DEFW RDERR ; Read error message
SWRTER: DEFW WRTERR ; Write error message
;
; EXTERNAL PATH NAME
;
;PATH: DEFW RAMLOW+00040H ; PATHNAME FOR OPEN FILE COMMAND
;Path not supported--B.H.
PATH: DEFW RAMLOW+0000H
;
; TIME ADDRESS P2BIOS
;
IF DOTIME
TIMEAD: DEFW TIME ; TIME ROUTINE ADDRESS FOR TIME
; AND DATE STAMPS
ELSE
TIMEAD: DEFW CONST
ENDIF
;
; FLAGS FOR SPECIALS
; BIT 0: PUBLIC FILE ENABLE(1)/DISABLE(0)
; BIT 1: DELAY 256 CHARACTERS ACTIVE(1)/DISABLE(0)
;
FLAGS: DB 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
;
IF DOTIME
CP 200 ; TEST GET TIME
JP Z,GETTIM ; YES THEN GET TIME
CP 201 ; TEST SET TIME
JP Z,SETTIM ; YES THEN SET TIME
ENDIF
;
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
; 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 CHARACTER
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 CHARACTERS IN LINE
;
COUNTC: LD HL,TABCNT ; GET POINTER TO TAB COUNTER
;Part of delete key fix--B.H.
; 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
CP RUBOUT
JR NZ,COUNT0
DEC (HL)
RET
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 CHARACTER 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
;
; added label "GCNS1A" here for not XON character loop
;
GCNS1A: CALL CONIN ; GET NEXT CHARACTER
CP CONTC ; TEST IF USER WANTS TO EXIT
JP Z,RAMLOW+00000H ; YES THEN WARM BOOT
;
; code added to test for XON - if yes then start output else wait for XON
;
CP XON ; SEE IF START CHARACTER
JR NZ,GCNS1A ; LOOP IF NOT
;
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
;Added next two lines as a part of delete key fix--B.H.
RET Z ; RETURN IF SO
CP RUBOUT
RET Z
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 LENGTH
INC HL ; INCREMENT TO LINE LENGTH POSITION
LD B,0 ; CLEAR LINE LENGTH 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
DOBACK: 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 LENGTH
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/MAX LINE LENGTH
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
JR DOBACK ; Part of delete key fix
;Remove code for echoing deleted character--B.H.
; 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 LENGTH=MAXIMUM LINE LENGTH
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:
IF RESDSK
;detect change between single and double sided disks if this function is
;supported.--B.H.
CALL SETDSK
ENDIF
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 TABLE
;
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
;
DBL: EXX
IF RESDSK
CALL SETDSK
ENDIF
CALL CLRDSK
EXX
RET
;
;******************************************************************************
;* *
;* ERROR ROUTINES *
;* *
;******************************************************************************
;
; Bad sector error message replaced by read/write error messages--B.H.
; 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
;
; Read Error Message--B.H.
;
RDERR: LD DE,MRDERR
JR DERROR
;
; Write Error Message--B.H.
WRTERR: LD DE,MWRTER
JR DERROR
;
; 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
;P2DOS had a bug which did not allow the user to ignore a read/write error
;by hitting a key other than Control-C. This is the fix.--B.H.
PUSH AF ; Save it
LD A,(RETFLG) ; Get RETFLG
OR A
JR Z,ERROR5
POP AF
CP CONTC
RET NZ
ERROR5: JP RAMLOW+00000H ; AND DO WARM BOOT
;
; DISPLAY NUMBER
;
NUM: LD D,0FFH ; 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
; Made more meaningful-B.H.
;
;Bad sector message replaced by read/write error messages
;MBADSC: DB 'Bad sector$'
;
MSEL: DB 'Non-existent drive$'
;
MFILRO: DB 'File is '
;
MRO: DB 'Read-Only$'
;
MBERR: DB 'Disk error on '
MDRIVE: DB 0
DB DRVSEP
DB ' $'
;
MBFUNC: DB 'Function = $'
;
MFILE: DB '; File = $'
;
MRDERR: DB 'Read error$'
;
MWRTER: DB 'Write error$'
;
; 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