TITLE 'SUPRBDOS Disk Operating System' ; ;****************************************************************************** ;* * ;* 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 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 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 ;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