mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1264 lines
30 KiB
1264 lines
30 KiB
.title "Digital Research CCP, Version 2.2"
|
|
.page 49
|
|
|
|
MON .EQU 1 ;ADD THE CCP MON COMMAND
|
|
USRDSP .EQU 1 ;SHOW THE USER NUMBER
|
|
CHKU0B .EQU 0 ;CHECK FOR TRANSIENTS ON USER 0 TOO
|
|
ENDFIL .EQU 1 ;FILE FULL CCP SIZE
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* C C P - C O N S O L E C O M M A N D P R O C E S S O R
|
|
;*
|
|
;**************************************************************
|
|
;*
|
|
IOBYTE: .EQU 3 ; I/O DEFINITION BYTE.
|
|
TDRIVE: .EQU 4 ; CURRENT DRIVE NAME AND USER NUMBER.
|
|
ENTRY: .EQU 5 ; ENTRY POINT FOR THE CP/M BDOS.
|
|
TFCB: .EQU 5CH ; DEFAULT FILE CONTROL BLOCK.
|
|
TBUFF: .EQU 80H ; I/O BUFFER AND COMMAND LINE STORAGE.
|
|
TBASE: .EQU 100H ; TRANSIANT PROGRAM STORAGE AREA.
|
|
;
|
|
; SET CONTROL CHARACTER .EQUATES.
|
|
;
|
|
CNTRLC: .EQU 03H ; CONTROL-C
|
|
CNTRLE: .EQU 05H ; CONTROL-E
|
|
BS: .EQU 08H ; BACKSPACE
|
|
TAB: .EQU 09H ; TAB
|
|
LF: .EQU 0AH ; LINE FEED
|
|
FF: .EQU 0CH ; FORM FEED
|
|
CR: .EQU 0DH ; CARRIAGE RETURN
|
|
CNTRLP: .EQU 10H ; CONTROL-P
|
|
CNTRLR: .EQU 12H ; CONTROL-R
|
|
CNTRLS: .EQU 13H ; CONTROL-S
|
|
CNTRLU: .EQU 15H ; CONTROL-U
|
|
CNTRLX: .EQU 18H ; CONTROL-X
|
|
CNTRLZ: .EQU 1AH ; CONTROL-Z (END-OF-FILE MARK)
|
|
DEL: .EQU 7FH ; RUBOUT
|
|
;
|
|
; SET ORIGIN FOR CP/M
|
|
;
|
|
|
|
NK .EQU 59 ;SYSTEM SIZE
|
|
BASE .EQU (NK*1024)-5000H
|
|
CCPO .EQU BASE+3400H ;CCP ORIGIN
|
|
BDOSO .EQU BASE+3C00H ;BDOS ORIGIN
|
|
BIOSO .EQU BASE+4A00H ;BIOS ORIGIN
|
|
|
|
.ORG CCPO
|
|
;
|
|
CBASE: JP COMMAND ; EXECUTE COMMAND PROCESSOR (CCP).
|
|
JP CLEARBUF ; ENTRY TO EMPTY INPUT BUFFER BEFORE STARTING CCP.
|
|
|
|
;
|
|
; STANDARD CP/M CCP INPUT BUFFER. FORMAT IS (MAX LENGTH),
|
|
; (ACTUAL LENGTH), (CHAR #1), (CHAR #2), (CHAR #3), ETC.
|
|
;
|
|
INBUFF: .DB 127 ; LENGTH OF INPUT BUFFER.
|
|
; N8VEM - if add any text after this point, change .DB 0 below to length
|
|
; and put a 0 after the text, and delete the same number of zeros after the dig
|
|
; so that inpoint ends up at the same spot
|
|
; INBUFF+1 is cleared on the next warm boot, so only runs once.
|
|
.DB 0 ;CURRENT LENGTH OF CONTENTS.
|
|
|
|
|
|
; .DB 17 ; Autoboot length of string
|
|
; .DB "SUPERSUB AUTOEXEC"
|
|
; .DB 0 ; zero at end
|
|
|
|
|
|
.DB "COPYRIGHT"
|
|
.DB " 1979 (C) BY "
|
|
.DB "DIGITAL RESEARCH "
|
|
.FILL ((INBUFF + 128) - $),055H
|
|
|
|
|
|
INPOINT:.DW INBUFF+2 ; INPUT LINE POINTER
|
|
NAMEPNT:.DW 0 ; INPUT LINE POINTER USED FOR ERROR MESSAGE. POINTS TO
|
|
; ;START OF NAME IN ERROR.
|
|
;
|
|
; ROUTINE TO PRINT (A) ON THE CONSOLE. ALL REGISTERS USED.
|
|
;
|
|
PRINT: LD E,A ; SETUP BDOS CALL.
|
|
LD C,2
|
|
JP ENTRY
|
|
;
|
|
; ROUTINE TO PRINT (A) ON THE CONSOLE AND TO SAVE (BC).
|
|
;
|
|
PRINTB: PUSH BC
|
|
CALL PRINT
|
|
POP BC
|
|
RET
|
|
;
|
|
; ROUTINE TO SEND A CARRIAGE RETURN, LINE FEED COMBINATION
|
|
; TO THE CONSOLE.
|
|
;
|
|
CRLF: LD A,CR
|
|
CALL PRINTB
|
|
LD A,LF
|
|
JP PRINTB
|
|
;
|
|
; ROUTINE TO SEND ONE SPACE TO THE CONSOLE AND SAVE (BC).
|
|
;
|
|
SPACE: LD A,' '
|
|
JP PRINTB
|
|
;
|
|
; ROUTINE TO PRINT CHARACTER STRING POINTED TO BE (BC) ON THE
|
|
; CONSOLE. IT MUST TERMINATE WITH A NULL BYTE.
|
|
;
|
|
PLINE: PUSH BC
|
|
CALL CRLF
|
|
POP HL
|
|
PLINE2: LD A,(HL)
|
|
OR A
|
|
RET Z
|
|
INC HL
|
|
PUSH HL
|
|
CALL PRINT
|
|
POP HL
|
|
JP PLINE2
|
|
;
|
|
; ROUTINE TO RESET THE DISK SYSTEM.
|
|
;
|
|
RESDSK: LD C,13
|
|
JP ENTRY
|
|
;
|
|
; ROUTINE TO SELECT DISK (A).
|
|
;
|
|
DSKSEL: LD E,A
|
|
LD C,14
|
|
JP ENTRY
|
|
;
|
|
; ROUTINE TO CALL BDOS AND SAVE THE RETURN CODE. THE ZERO
|
|
; FLAG IS SET ON A RETURN OF 0FFH.
|
|
;
|
|
ENTRY1: CALL ENTRY
|
|
LD (RTNCODE),A ; SAVE RETURN CODE.
|
|
INC A ; SET ZERO IF 0FFH RETURNED.
|
|
RET
|
|
;
|
|
; ROUTINE TO OPEN A FILE. (DE) MUST POINT TO THE FCB.
|
|
;
|
|
OPEN: LD C,15
|
|
JP ENTRY1
|
|
;
|
|
; ROUTINE TO OPEN FILE AT (FCB).
|
|
;
|
|
OPENFCB:XOR A ; CLEAR THE RECORD NUMBER BYTE AT FCB+32
|
|
LD (FCB+32),A
|
|
LD DE,FCB
|
|
JP OPEN
|
|
;
|
|
; ROUTINE TO CLOSE A FILE. (DE) POINTS TO FCB.
|
|
;
|
|
CLOSE: LD C,16
|
|
JP ENTRY1
|
|
;
|
|
; ROUTINE TO SEARCH FOR THE FIRST FILE WITH AMBIGUEOUS NAME
|
|
; (DE).
|
|
;
|
|
SRCHFST:LD C,17
|
|
JP ENTRY1
|
|
;
|
|
; SEARCH FOR THE NEXT AMBIGEOUS FILE NAME.
|
|
;
|
|
SRCHNXT:LD C,18
|
|
JP ENTRY1
|
|
;
|
|
; SEARCH FOR FILE AT (FCB).
|
|
;
|
|
SRCHFCB:LD DE,FCB
|
|
JP SRCHFST
|
|
;
|
|
; ROUTINE TO DELETE A FILE POINTED TO BY (DE).
|
|
;
|
|
DELETE: LD C,19
|
|
JP ENTRY
|
|
;
|
|
; ROUTINE TO CALL THE BDOS AND SET THE ZERO FLAG IF A ZERO
|
|
; STATUS IS RETURNED.
|
|
;
|
|
ENTRY2: CALL ENTRY
|
|
OR A ; SET ZERO FLAG IF APPROPRIATE.
|
|
RET
|
|
;
|
|
; ROUTINE TO READ THE NEXT RECORD FROM A S.EQUENTIAL FILE.
|
|
; (DE) POINTS TO THE FCB.
|
|
;
|
|
RDREC: LD C,20
|
|
JP ENTRY2
|
|
;
|
|
; ROUTINE TO READ FILE AT (FCB).
|
|
;
|
|
READFCB:LD DE,FCB
|
|
JP RDREC
|
|
;
|
|
; ROUTINE TO WRITE THE NEXT RECORD OF A S.EQUENTIAL FILE.
|
|
; (DE) POINTS TO THE FCB.
|
|
;
|
|
WRTREC: LD C,21
|
|
JP ENTRY2
|
|
;
|
|
; ROUTINE TO CREATE THE FILE POINTED TO BY (DE).
|
|
;
|
|
CREATE: LD C,22
|
|
JP ENTRY1
|
|
;
|
|
; ROUTINE TO RENAME THE FILE POINTED TO BY (DE). NOTE THAT
|
|
; THE NEW NAME STARTS AT (DE+16).
|
|
;
|
|
RENAM: LD C,23
|
|
JP ENTRY
|
|
;
|
|
; GET THE CURRENT USER CODE.
|
|
;
|
|
GETUSR: LD E,0FFH
|
|
;
|
|
; ROUTNE TO GET OR SET THE CURRENT USER CODE.
|
|
; IF (E) IS FF THEN THIS IS A GET, ELSE IT IS A SET.
|
|
;
|
|
GETSETUC:
|
|
LD C,32
|
|
JP ENTRY
|
|
;
|
|
; ROUTINE TO SET THE CURRENT DRIVE BYTE AT (TDRIVE).
|
|
;
|
|
SETCDRV:CALL GETUSR ; GET USER NUMBER
|
|
ADD A,A ; AND SHIFT INTO THE UPPER 4 BITS.
|
|
ADD A,A
|
|
ADD A,A
|
|
ADD A,A
|
|
LD HL,CDRIVE ; NOW ADD IN THE CURRENT DRIVE NUMBER.
|
|
OR (HL)
|
|
LD (TDRIVE),A ; AND SAVE.
|
|
RET
|
|
;
|
|
; MOVE CURRENTLY ACTIVE DRIVE DOWN TO (TDRIVE).
|
|
;
|
|
MOVECD: LD A,(CDRIVE)
|
|
LD (TDRIVE),A
|
|
RET
|
|
;
|
|
; ROUTINE TO CONVERT (A) INTO UPPER CASE ASCII. ONLY LETTERS
|
|
; ARE AFFECTED.
|
|
;
|
|
UPPER: CP 'A' ; CHECK FOR LETTERS IN THE RANGE OF 'A' TO 'Z'.
|
|
RET C
|
|
CP '{'
|
|
RET NC
|
|
AND 5FH ; CONVERT IT IF FOUND.
|
|
RET
|
|
;
|
|
; ROUTINE TO GET A LINE OF INPUT. WE MUST CHECK TO SEE IF THE
|
|
; USER IS IN (BATCH) MODE. IF SO, THEN READ THE INPUT FROM FILE
|
|
; ($$$.SUB). AT THE END, RESET TO CONSOLE INPUT.
|
|
;
|
|
GETINP: LD A,(BATCH) ; IF =0, THEN USE CONSOLE INPUT.
|
|
OR A
|
|
JP Z,GETINP1
|
|
;
|
|
; USE THE SUBMIT FILE ($$$.SUB) WHICH IS PREPARED BY A
|
|
; SUBMIT RUN. IT MUST BE ON DRIVE (A) AND IT WILL BE DELETED
|
|
; IF AND ERROR OCCURES (LIKE EOF).
|
|
;
|
|
LD A,(CDRIVE) ; SELECT DRIVE 0 IF NEED BE.
|
|
OR A
|
|
LD A,0 ; ALWAYS USE DRIVE A FOR SUBMIT.
|
|
CALL NZ,DSKSEL ; SELECT IT IF REQUIRED.
|
|
LD DE,BATCHFCB
|
|
CALL OPEN ; LOOK FOR IT.
|
|
JP Z,GETINP1 ; IF NOT THERE, USE NORMAL INPUT.
|
|
LD A,(BATCHFCB+15) ; GET LAST RECORD NUMBER+1.
|
|
DEC A
|
|
LD (BATCHFCB+32),A
|
|
LD DE,BATCHFCB
|
|
CALL RDREC ; READ LAST RECORD.
|
|
JP NZ,GETINP1 ; QUIT ON END OF FILE.
|
|
;
|
|
; MOVE THIS RECORD INTO INPUT BUFFER.
|
|
;
|
|
LD DE,INBUFF+1
|
|
LD HL,TBUFF ; DATA WAS READ INTO BUFFER HERE.
|
|
LD B,128 ; ALL 128 CHARACTERS MAY BE USED.
|
|
CALL HL2DE ; (HL) TO (DE), (B) BYTES.
|
|
LD HL,BATCHFCB+14
|
|
LD (HL),0 ; ZERO OUT THE 'S2' BYTE.
|
|
INC HL ; AND DECREMENT THE RECORD COUNT.
|
|
DEC (HL)
|
|
LD DE,BATCHFCB ; CLOSE THE BATCH FILE NOW.
|
|
CALL CLOSE
|
|
JP Z,GETINP1 ; QUIT ON AN ERROR.
|
|
LD A,(CDRIVE) ; RE-SELECT PREVIOUS DRIVE IF NEED BE.
|
|
OR A
|
|
CALL NZ,DSKSEL ; DON'T DO NEEDLESS SELECTS.
|
|
;
|
|
; PRINT LINE JUST READ ON CONSOLE.
|
|
;
|
|
LD HL,INBUFF+2
|
|
CALL PLINE2
|
|
CALL CHKCON ; CHECK CONSOLE, QUIT ON A KEY.
|
|
JP Z,GETINP2 ; JUMP IF NO KEY IS PRESSED.
|
|
;
|
|
; TERMINATE THE SUBMIT JOB ON ANY KEYBOARD INPUT. DELETE THIS
|
|
; FILE SUCH THAT IT IS NOT RE-STARTED AND JUMP TO NORMAL KEYBOARD
|
|
; INPUT SECTION.
|
|
;
|
|
CALL DELBATCH ; DELETE THE BATCH FILE.
|
|
JP CMMND1 ; AND RESTART COMMAND INPUT.
|
|
;
|
|
; GET HERE FOR NORMAL KEYBOARD INPUT. DELETE THE SUBMIT FILE
|
|
; INCASE THERE WAS ONE.
|
|
;
|
|
GETINP1:CALL DELBATCH ; DELETE FILE ($$$.SUB).
|
|
CALL SETCDRV ; RESET ACTIVE DISK.
|
|
LD C,10 ; GET LINE FROM CONSOLE DEVICE.
|
|
LD DE,INBUFF
|
|
CALL ENTRY
|
|
CALL MOVECD ; RESET CURRENT DRIVE (AGAIN).
|
|
;
|
|
; CONVERT INPUT LINE TO UPPER CASE.
|
|
;
|
|
GETINP2:LD HL,INBUFF+1
|
|
LD B,(HL) ; (B)=CHARACTER COUNTER.
|
|
GETINP3:INC HL
|
|
LD A,B ; END OF THE LINE?
|
|
OR A
|
|
JP Z,GETINP4
|
|
LD A,(HL) ; CONVERT TO UPPER CASE.
|
|
CALL UPPER
|
|
LD (HL),A
|
|
DEC B ; ADJUST CHARACTER COUNT.
|
|
JP GETINP3
|
|
GETINP4:LD (HL),A ; ADD TRAILING NULL.
|
|
LD HL,INBUFF+2
|
|
LD (INPOINT),HL ; RESET INPUT LINE POINTER.
|
|
RET
|
|
;
|
|
; ROUTINE TO CHECK THE CONSOLE FOR A KEY PRESSED. THE ZERO
|
|
; FLAG IS SET IS NONE, ELSE THE CHARACTER IS RETURNED IN (A).
|
|
;
|
|
CHKCON: LD C,11 ; CHECK CONSOLE.
|
|
CALL ENTRY
|
|
OR A
|
|
RET Z ; RETURN IF NOTHING.
|
|
LD C,1 ; ELSE GET CHARACTER.
|
|
CALL ENTRY
|
|
OR A ; CLEAR ZERO FLAG AND RETURN.
|
|
RET
|
|
;
|
|
; ROUTINE TO GET THE CURRENTLY ACTIVE DRIVE NUMBER.
|
|
;
|
|
GETDSK: LD C,25
|
|
JP ENTRY
|
|
;
|
|
; SET THE STABDARD DMA ADDRESS.
|
|
;
|
|
STDDMA: LD DE,TBUFF
|
|
;
|
|
; ROUTINE TO SET THE DMA ADDRESS TO (DE).
|
|
;
|
|
DMASET: LD C,26
|
|
JP ENTRY
|
|
;
|
|
; DELETE THE BATCH FILE CREATED BY SUBMIT.
|
|
;
|
|
DELBATCH:
|
|
LD HL,BATCH ; IS BATCH ACTIVE?
|
|
LD A,(HL)
|
|
OR A
|
|
RET Z
|
|
LD (HL),0 ; YES, DE-ACTIVATE IT.
|
|
XOR A
|
|
CALL DSKSEL ; SELECT DRIVE 0 FOR SURE.
|
|
LD DE,BATCHFCB ; AND DELETE THIS FILE.
|
|
CALL DELETE
|
|
LD A,(CDRIVE) ; RESET CURRENT DRIVE.
|
|
JP DSKSEL
|
|
;
|
|
; PRINT BACK FILE NAME WITH A '?' TO INDICATE A SYNTAX ERROR.
|
|
;
|
|
SYNERR: CALL CRLF ; END CURRENT LINE.
|
|
LD HL,(NAMEPNT) ; THIS POINTS TO NAME IN ERROR.
|
|
SYNERR1:LD A,(HL) ; PRINT IT UNTIL A SPACE OR NULL IS FOUND.
|
|
CP ' '
|
|
JP Z,SYNERR2
|
|
OR A
|
|
JP Z,SYNERR2
|
|
PUSH HL
|
|
CALL PRINT
|
|
POP HL
|
|
INC HL
|
|
JP SYNERR1
|
|
SYNERR2:LD A,'?' ; ADD TRAILING '?'.
|
|
CALL PRINT
|
|
CALL CRLF
|
|
CALL DELBATCH ; DELETE ANY BATCH FILE.
|
|
JP CMMND1 ; AND RESTART FROM CONSOLE INPUT.
|
|
;
|
|
; CHECK CHARACTER AT (DE) FOR LEGAL COMMAND INPUT. NOTE THAT THE
|
|
; ZERO FLAG IS SET IF THE CHARACTER IS A DELIMITER.
|
|
;
|
|
CHECK: LD A,(DE)
|
|
OR A
|
|
RET Z
|
|
CP ' ' ; CONTROL CHARACTERS ARE NOT LEGAL HERE.
|
|
JP C,SYNERR
|
|
RET Z ; CHECK FOR VALID DELIMITER.
|
|
CP '='
|
|
RET Z
|
|
CP '_'
|
|
RET Z
|
|
CP '.'
|
|
RET Z
|
|
CP ':'
|
|
RET Z
|
|
CP $3B
|
|
RET Z
|
|
CP '<'
|
|
RET Z
|
|
CP '>'
|
|
RET Z
|
|
RET
|
|
;
|
|
; GET THE NEXT NON-BLANK CHARACTER FROM (DE).
|
|
;
|
|
NONBLANK:
|
|
LD A,(DE)
|
|
OR A ; STRING ENDS WITH A NULL.
|
|
RET Z
|
|
CP ' '
|
|
RET NZ
|
|
INC DE
|
|
JP NONBLANK
|
|
;
|
|
; ADD (HL)=(HL)+(A)
|
|
;
|
|
ADDHL: ADD A,L
|
|
LD L,A
|
|
RET NC ; TAKE CARE OF ANY CARRY.
|
|
INC H
|
|
RET
|
|
;
|
|
; CONVERT THE FIRST NAME IN (FCB).
|
|
;
|
|
CONVFST:LD A,0
|
|
;
|
|
; FORMAT A FILE NAME (CONVERT * TO '?', ETC.). ON RETURN,
|
|
; (A)=0 IS AN UNAMBIGEOUS NAME WAS SPECIFIED. ENTER WITH (A) .EQUAL TO
|
|
; THE POSITION WITHIN THE FCB FOR THE NAME (EITHER 0 OR 16).
|
|
;
|
|
CONVERT:LD HL,FCB
|
|
CALL ADDHL
|
|
PUSH HL
|
|
PUSH HL
|
|
XOR A
|
|
LD (CHGDRV),A ; INITIALIZE DRIVE CHANGE FLAG.
|
|
LD HL,(INPOINT) ; SET (HL) AS POINTER INTO INPUT LINE.
|
|
EX DE,HL
|
|
CALL NONBLANK ; GET NEXT NON-BLANK CHARACTER.
|
|
EX DE,HL
|
|
LD (NAMEPNT),HL ; SAVE POINTER HERE FOR ANY ERROR MESSAGE.
|
|
EX DE,HL
|
|
POP HL
|
|
LD A,(DE) ; GET FIRST CHARACTER.
|
|
OR A
|
|
JP Z,CONVRT1
|
|
SBC A,'A'-1 ; MIGHT BE A DRIVE NAME, CONVERT TO BINARY.
|
|
LD B,A ; AND SAVE.
|
|
INC DE ; CHECK NEXT CHARACTER FOR A ':'.
|
|
LD A,(DE)
|
|
CP ':'
|
|
JP Z,CONVRT2
|
|
DEC DE ; NOPE, MOVE POINTER BACK TO THE START OF THE LINE.
|
|
CONVRT1:LD A,(CDRIVE)
|
|
LD (HL),A
|
|
JP CONVRT3
|
|
CONVRT2:LD A,B
|
|
LD (CHGDRV),A ; SET CHANGE IN DRIVES FLAG.
|
|
LD (HL),B
|
|
INC DE
|
|
;
|
|
; CONVERT THE BASIC FILE NAME.
|
|
;
|
|
CONVRT3:LD B,08H
|
|
CONVRT4:CALL CHECK
|
|
JP Z,CONVRT8
|
|
INC HL
|
|
CP '*' ; NOTE THAT AN '*' WILL FILL THE REMAINING
|
|
JP NZ,CONVRT5 ; FIELD WITH '?'.
|
|
LD (HL),'?'
|
|
JP CONVRT6
|
|
CONVRT5:LD (HL),A
|
|
INC DE
|
|
CONVRT6:DEC B
|
|
JP NZ,CONVRT4
|
|
CONVRT7:CALL CHECK ; GET NEXT DELIMITER.
|
|
JP Z,GETEXT
|
|
INC DE
|
|
JP CONVRT7
|
|
CONVRT8:INC HL ; BLANK FILL THE FILE NAME.
|
|
LD (HL),' '
|
|
DEC B
|
|
JP NZ,CONVRT8
|
|
;
|
|
; GET THE EXTENSION AND CONVERT IT.
|
|
;
|
|
GETEXT: LD B,03H
|
|
CP '.'
|
|
JP NZ,GETEXT5
|
|
INC DE
|
|
GETEXT1:CALL CHECK
|
|
JP Z,GETEXT5
|
|
INC HL
|
|
CP '*'
|
|
JP NZ,GETEXT2
|
|
LD (HL),'?'
|
|
JP GETEXT3
|
|
GETEXT2:LD (HL),A
|
|
INC DE
|
|
GETEXT3:DEC B
|
|
JP NZ,GETEXT1
|
|
GETEXT4:CALL CHECK
|
|
JP Z,GETEXT6
|
|
INC DE
|
|
JP GETEXT4
|
|
GETEXT5:INC HL
|
|
LD (HL),' '
|
|
DEC B
|
|
JP NZ,GETEXT5
|
|
GETEXT6:LD B,3
|
|
GETEXT7:INC HL
|
|
LD (HL),0
|
|
DEC B
|
|
JP NZ,GETEXT7
|
|
EX DE,HL
|
|
LD (INPOINT),HL ; SAVE INPUT LINE POINTER.
|
|
POP HL
|
|
;
|
|
; CHECK TO SEE IF THIS IS AN AMBIGEOUS FILE NAME SPECIFICATION.
|
|
; SET THE (A) REGISTER TO NON ZERO IF IT IS.
|
|
;
|
|
LD BC,11 ; SET NAME LENGTH.
|
|
GETEXT8:INC HL
|
|
LD A,(HL)
|
|
CP '?' ; ANY QUESTION MARKS?
|
|
JP NZ,GETEXT9
|
|
INC B ; COUNT THEM.
|
|
GETEXT9:DEC C
|
|
JP NZ,GETEXT8
|
|
LD A,B
|
|
OR A
|
|
RET
|
|
;
|
|
; CP/M COMMAND TABLE. NOTE COMMANDS CAN BE EITHER 3 OR 4 CHARACTERS LONG.
|
|
;
|
|
.IF MON
|
|
NUMCMDS:.EQU 7 ; NUMBER OF COMMANDS
|
|
.ELSE
|
|
NUMCMDS:.EQU 6 ; NUMBER OF COMMANDS
|
|
.ENDIF
|
|
|
|
CMDTBL: .DB "DIR "
|
|
.DB "ERA "
|
|
.DB "TYPE"
|
|
.DB "SAVE"
|
|
.DB "REN "
|
|
.DB "USER"
|
|
.IF MON
|
|
.DB "MON "
|
|
.ENDIF
|
|
|
|
CMDADR: .DW DIRECT
|
|
.DW ERASE
|
|
.DW TYPE
|
|
.DW SAVE
|
|
.DW RENAME
|
|
.DW USER
|
|
.IF MON
|
|
.DW MONITOR
|
|
.ENDIF
|
|
.DW UNKNOWN
|
|
;
|
|
; SEARCH THE COMMAND TABLE FOR A MATCH WITH WHAT HAS JUST
|
|
; BEEN ENTERED. IF A MATCH IS FOUND, THEN WE JUMP TO THE
|
|
; PROPER SECTION. ELSE JUMP TO (UNKNOWN).
|
|
; ON RETURN, THE (C) REGISTER IS SET TO THE COMMAND NUMBER
|
|
; THAT MATCHED (OR NUMCMDS+1 IF NO MATCH).
|
|
;
|
|
SEARCH: LD HL,CMDTBL
|
|
LD C,0
|
|
SEARCH1:LD A,C
|
|
CP NUMCMDS ; THIS COMMANDS EXISTS.
|
|
RET NC
|
|
LD DE,FCB+1 ; CHECK THIS ONE.
|
|
LD B,4 ; MAX COMMAND LENGTH.
|
|
SEARCH2:LD A,(DE)
|
|
CP (HL)
|
|
JP NZ,SEARCH3 ; NOT A MATCH.
|
|
INC DE
|
|
INC HL
|
|
DEC B
|
|
JP NZ,SEARCH2
|
|
LD A,(DE) ; ALLOW A 3 CHARACTER COMMAND TO MATCH.
|
|
CP ' '
|
|
JP NZ,SEARCH4
|
|
LD A,C ; SET RETURN REGISTER FOR THIS COMMAND.
|
|
RET
|
|
SEARCH3:INC HL
|
|
DEC B
|
|
JP NZ,SEARCH3
|
|
SEARCH4:INC C
|
|
JP SEARCH1
|
|
;
|
|
; SET THE INPUT BUFFER TO EMPTY AND THEN START THE COMMAND
|
|
; PROCESSOR (CCP).
|
|
;
|
|
CLEARBUF:
|
|
XOR A
|
|
LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH.
|
|
COMMAND:LD SP,CCPSTACK ; SETUP STACK AREA.
|
|
PUSH BC ; NOTE THAT (C) SHOULD BE .EQUAL TO:
|
|
LD A,C ; (UUUUDDDD) WHERE 'UUUU' IS THE USER NUMBER
|
|
RRA ; AND 'DDDD' IS THE DRIVE NUMBER.
|
|
RRA
|
|
RRA
|
|
RRA
|
|
AND 0FH ; ISOLATE THE USER NUMBER.
|
|
LD E,A
|
|
CALL GETSETUC ; AND SET IT.
|
|
CALL RESDSK ; RESET THE DISK SYSTEM.
|
|
LD (BATCH),A ; CLEAR BATCH MODE FLAG.
|
|
POP BC
|
|
LD A,C
|
|
AND 0FH ; ISOLATE THE DRIVE NUMBER.
|
|
LD (CDRIVE),A ; AND SAVE.
|
|
CALL DSKSEL ; ...AND SELECT.
|
|
LD A,(INBUFF+1)
|
|
OR A ; ANYTHING IN INPUT BUFFER ALREADY?
|
|
JP NZ,CMMND2 ; YES, WE JUST PROCESS IT.
|
|
;
|
|
; ENTRY POINT TO GET A COMMAND LINE FROM THE CONSOLE.
|
|
;
|
|
CMMND1: LD SP,CCPSTACK ; SET STACK STRAIGHT.
|
|
CALL CRLF ; START A NEW LINE ON THE SCREEN.
|
|
CALL GETDSK ; GET CURRENT DRIVE.
|
|
ADD A,'A'
|
|
CALL PRINT ; PRINT CURRENT DRIVE.
|
|
.IF USRDSP
|
|
CALL GETUSR ;GET CURRENT USER NUMBER
|
|
CP 10 ;TWO DIGITS?
|
|
JR C,CMMND3 ;NO
|
|
LD A,'1' ;PRINT LEADING '1'
|
|
CALL PRINT
|
|
CALL GETUSR ;GET CURRENT USER NUMBER
|
|
SUB 10 ;SUBTRACT 10
|
|
CMMND3: ADD A,'0'
|
|
CALL PRINT
|
|
.ENDIF
|
|
LD A,'>'
|
|
CALL PRINT ; AND ADD PROMPT.
|
|
CALL GETINP ; GET LINE FROM USER.
|
|
;
|
|
; PROCESS COMMAND LINE HERE.
|
|
;
|
|
CMMND2: LD DE,TBUFF
|
|
CALL DMASET ; SET STANDARD DMA ADDRESS.
|
|
CALL GETDSK
|
|
LD (CDRIVE),A ; SET CURRENT DRIVE.
|
|
CALL CONVFST ; CONVERT NAME TYPED IN.
|
|
CALL NZ,SYNERR ; WILD CARDS ARE NOT ALLOWED.
|
|
LD A,(CHGDRV) ; IF A CHANGE IN DRIVES WAS INDICATED,
|
|
OR A ; THEN TREAT THIS AS AN UNKNOWN COMMAND
|
|
JP NZ,UNKNOWN ; WHICH GETS EXECUTED.
|
|
CALL SEARCH ; ELSE SEARCH COMMAND TABLE FOR A MATCH.
|
|
;
|
|
; NOTE THAT AN UNKNOWN COMMAND RETURNS
|
|
; WITH (A) POINTING TO THE LAST ADDRESS
|
|
; IN OUR TABLE WHICH IS (UNKNOWN).
|
|
;
|
|
LD HL,CMDADR ; NOW, LOOK THRU OUR ADDRESS TABLE FOR COMMAND (A).
|
|
LD E,A ; SET (DE) TO COMMAND NUMBER.
|
|
LD D,0
|
|
ADD HL,DE
|
|
ADD HL,DE ; (HL)=(CMDADR)+2*(COMMAND NUMBER).
|
|
LD A,(HL) ; NOW PICK OUT THIS ADDRESS.
|
|
INC HL
|
|
LD H,(HL)
|
|
LD L,A
|
|
JP (HL) ; NOW EXECUTE IT.
|
|
;
|
|
; READ ERROR WHILE TYPEING A FILE.
|
|
;
|
|
RDERROR:LD BC,RDERR
|
|
JP PLINE
|
|
RDERR: .DB "Read Error",0
|
|
;
|
|
; REQUIRED FILE WAS NOT LOCATED.
|
|
;
|
|
NONE: LD BC,NOFILE
|
|
JP PLINE
|
|
NOFILE: .DB "No File",0
|
|
;
|
|
; DECODE A COMMAND OF THE FORM 'A>FILENAME NUMBER{ FILENAME}.
|
|
; NOTE THAT A DRIVE SPECIFIER IS NOT ALLOWED ON THE FIRST FILE
|
|
; NAME. ON RETURN, THE NUMBER IS IN REGISTER (A). ANY ERROR
|
|
; CAUSES 'FILENAME?' TO BE PRINTED AND THE COMMAND IS ABORTED.
|
|
;
|
|
DECODE: CALL CONVFST ; CONVERT FILENAME.
|
|
LD A,(CHGDRV) ; DO NOT ALLOW A DRIVE TO BE SPECIFIED.
|
|
OR A
|
|
JP NZ,SYNERR
|
|
LD HL,FCB+1 ; CONVERT NUMBER NOW.
|
|
LD BC,11 ; (B)=SUM REGISTER, (C)=MAX DIGIT COUNT.
|
|
DECODE1:LD A,(HL)
|
|
CP ' ' ; A SPACE TERMINATES THE NUMERAL.
|
|
JP Z,DECODE3
|
|
INC HL
|
|
SUB '0' ; MAKE BINARY FROM ASCII.
|
|
CP 10 ; LEGAL DIGIT?
|
|
JP NC,SYNERR
|
|
LD D,A ; YES, SAVE IT IN (D).
|
|
LD A,B ; COMPUTE (B)=(B)*10 AND CHECK FOR OVERFLOW.
|
|
AND 0E0H
|
|
JP NZ,SYNERR
|
|
LD A,B
|
|
RLCA
|
|
RLCA
|
|
RLCA ; (A)=(B)*8
|
|
ADD A,B ; .......*9
|
|
JP C,SYNERR
|
|
ADD A,B ; .......*10
|
|
JP C,SYNERR
|
|
ADD A,D ; ADD IN NEW DIGIT NOW.
|
|
DECODE2:JP C,SYNERR
|
|
LD B,A ; AND SAVE RESULT.
|
|
DEC C ; ONLY LOOK AT 11 DIGITS.
|
|
JP NZ,DECODE1
|
|
RET
|
|
DECODE3:LD A,(HL) ; SPACES MUST FOLLOW (WHY?).
|
|
CP ' '
|
|
JP NZ,SYNERR
|
|
INC HL
|
|
DECODE4:DEC C
|
|
JP NZ,DECODE3
|
|
LD A,B ; SET (A)=THE NUMERIC VALUE ENTERED.
|
|
RET
|
|
;
|
|
; MOVE 3 BYTES FROM (HL) TO (DE). NOTE THAT THERE IS ONLY
|
|
; ONE REFERENCE TO THIS AT (A2D5H).
|
|
;
|
|
MOVE3: LD B,3
|
|
;
|
|
; MOVE (B) BYTES FROM (HL) TO (DE).
|
|
;
|
|
HL2DE: LD A,(HL)
|
|
LD (DE),A
|
|
INC HL
|
|
INC DE
|
|
DEC B
|
|
JP NZ,HL2DE
|
|
RET
|
|
;
|
|
; COMPUTE (HL)=(TBUFF)+(A)+(C) AND GET THE BYTE THAT'S HERE.
|
|
;
|
|
EXTRACT:LD HL,TBUFF
|
|
ADD A,C
|
|
CALL ADDHL
|
|
LD A,(HL)
|
|
RET
|
|
;
|
|
; CHECK DRIVE SPECIFIED. IF IT MEANS A CHANGE, THEN THE NEW
|
|
; DRIVE WILL BE SELECTED. IN ANY CASE, THE DRIVE BYTE OF THE
|
|
; FCB WILL BE SET TO NULL (MEANS USE CURRENT DRIVE).
|
|
;
|
|
DSELECT:XOR A ; NULL OUT FIRST BYTE OF FCB.
|
|
LD (FCB),A
|
|
LD A,(CHGDRV) ; A DRIVE CHANGE INDICATED?
|
|
OR A
|
|
RET Z
|
|
DEC A ; YES, IS IT THE SAME AS THE CURRENT DRIVE?
|
|
LD HL,CDRIVE
|
|
CP (HL)
|
|
RET Z
|
|
JP DSKSEL ; NO. SELECT IT THEN.
|
|
;
|
|
; CHECK THE DRIVE SELECTION AND RESET IT TO THE PREVIOUS
|
|
; DRIVE IF IT WAS CHANGED FOR THE PRECEEDING COMMAND.
|
|
;
|
|
RESETDR:LD A,(CHGDRV) ; DRIVE CHANGE INDICATED?
|
|
OR A
|
|
RET Z
|
|
DEC A ; YES, WAS IT A DIFFERENT DRIVE?
|
|
LD HL,CDRIVE
|
|
CP (HL)
|
|
RET Z
|
|
LD A,(CDRIVE) ; YES, RE-SELECT OUR OLD DRIVE.
|
|
JP DSKSEL
|
|
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* M O N I T O R C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
.IF MON
|
|
MONITOR:RST 38H
|
|
.ENDIF
|
|
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* D I R E C T O R Y C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
DIRECT: CALL CONVFST ; CONVERT FILE NAME.
|
|
CALL DSELECT ; SELECT INDICATED DRIVE.
|
|
LD HL,FCB+1 ; WAS ANY FILE INDICATED?
|
|
LD A,(HL)
|
|
CP ' '
|
|
JP NZ,DIRECT2
|
|
LD B,11 ; NO. FILL FIELD WITH '?' - SAME AS *.*.
|
|
DIRECT1:LD (HL),'?'
|
|
INC HL
|
|
DEC B
|
|
JP NZ,DIRECT1
|
|
DIRECT2:LD E,0 ; SET INITIAL CURSOR POSITION.
|
|
PUSH DE
|
|
CALL SRCHFCB ; GET FIRST FILE NAME.
|
|
CALL Z,NONE ; NONE FOUND AT ALL?
|
|
DIRECT3:JP Z,DIRECT9 ; TERMINATE IF NO MORE NAMES.
|
|
LD A,(RTNCODE) ; GET FILE'S POSITION IN SEGMENT (0-3).
|
|
RRCA
|
|
RRCA
|
|
RRCA
|
|
AND 60H ; (A)=POSITION*32
|
|
LD C,A
|
|
LD A,10
|
|
CALL EXTRACT ; EXTRACT THE TENTH ENTRY IN FCB.
|
|
RLA ; CHECK SYSTEM FILE STATUS BIT.
|
|
JP C,DIRECT8 ; WE DON'T LIST THEM.
|
|
POP DE
|
|
LD A,E ; BUMP NAME COUNT.
|
|
INC E
|
|
PUSH DE
|
|
AND 03H ; AT END OF LINE?
|
|
PUSH AF
|
|
JP NZ,DIRECT4
|
|
CALL CRLF ; YES, END THIS LINE AND START ANOTHER.
|
|
PUSH BC
|
|
CALL GETDSK ; START LINE WITH ('A:').
|
|
POP BC
|
|
ADD A,'A'
|
|
CALL PRINTB
|
|
LD A,':'
|
|
CALL PRINTB
|
|
JP DIRECT5
|
|
DIRECT4:CALL SPACE ; ADD SEPERATOR BETWEEN FILE NAMES.
|
|
LD A,':'
|
|
CALL PRINTB
|
|
DIRECT5:CALL SPACE
|
|
LD B,1 ; 'EXTRACT' EACH FILE NAME CHARACTER AT A TIME.
|
|
DIRECT6:LD A,B
|
|
CALL EXTRACT
|
|
AND 7FH ; STRIP BIT 7 (STATUS BIT).
|
|
CP ' ' ; ARE WE AT THE END OF THE NAME?
|
|
JP NZ,DRECT65
|
|
POP AF ; YES, DON'T PRINT SPACES AT THE END OF A LINE.
|
|
PUSH AF
|
|
CP 3
|
|
JP NZ,DRECT63
|
|
LD A,9 ; FIRST CHECK FOR NO EXTENSION.
|
|
CALL EXTRACT
|
|
AND 7FH
|
|
CP ' '
|
|
JP Z,DIRECT7 ; DON'T PRINT SPACES.
|
|
DRECT63:LD A,' ' ; ELSE PRINT THEM.
|
|
DRECT65:CALL PRINTB
|
|
INC B ; BUMP TO NEXT CHARACTER PSOITION.
|
|
LD A,B
|
|
CP 12 ; END OF THE NAME?
|
|
JP NC,DIRECT7
|
|
CP 9 ; NOPE, STARTING EXTENSION?
|
|
JP NZ,DIRECT6
|
|
CALL SPACE ; YES, ADD SEPERATING SPACE.
|
|
JP DIRECT6
|
|
DIRECT7:POP AF ; GET THE NEXT FILE NAME.
|
|
DIRECT8:CALL CHKCON ; FIRST CHECK CONSOLE, QUIT ON ANYTHING.
|
|
JP NZ,DIRECT9
|
|
CALL SRCHNXT ; GET NEXT NAME.
|
|
JP DIRECT3 ; AND CONTINUE WITH OUR LIST.
|
|
DIRECT9:POP DE ; RESTORE THE STACK AND RETURN TO COMMAND LEVEL.
|
|
JP GETBACK
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* E R A S E C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
ERASE: CALL CONVFST ; CONVERT FILE NAME.
|
|
CP 11 ; WAS '*.*' ENTERED?
|
|
JP NZ,ERASE1
|
|
LD BC,YESNO ; YES, ASK FOR CONFIRMATION.
|
|
CALL PLINE
|
|
CALL GETINP
|
|
LD HL,INBUFF+1
|
|
DEC (HL) ; MUST BE EXACTLY 'Y'.
|
|
JP NZ,CMMND1
|
|
INC HL
|
|
LD A,(HL)
|
|
CP 'Y'
|
|
JP NZ,CMMND1
|
|
INC HL
|
|
LD (INPOINT),HL ; SAVE INPUT LINE POINTER.
|
|
ERASE1: CALL DSELECT ; SELECT DESIRED DISK.
|
|
LD DE,FCB
|
|
CALL DELETE ; DELETE THE FILE.
|
|
INC A
|
|
CALL Z,NONE ; NOT THERE?
|
|
JP GETBACK ; RETURN TO COMMAND LEVEL NOW.
|
|
YESNO: .DB "All (Y/N)?",0
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* T Y P E C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
TYPE: CALL CONVFST ; CONVERT FILE NAME.
|
|
JP NZ,SYNERR ; WILD CARDS NOT ALLOWED.
|
|
CALL DSELECT ; SELECT INDICATED DRIVE.
|
|
CALL OPENFCB ; OPEN THE FILE.
|
|
JP Z,TYPE5 ; NOT THERE?
|
|
CALL CRLF ; OK, START A NEW LINE ON THE SCREEN.
|
|
LD HL,NBYTES ; INITIALIZE BYTE COUNTER.
|
|
LD (HL),0FFH ; SET TO READ FIRST SECTOR.
|
|
TYPE1: LD HL,NBYTES
|
|
TYPE2: LD A,(HL) ; HAVE WE WRITTEN THE ENTIRE SECTOR?
|
|
CP 128
|
|
JP C,TYPE3
|
|
PUSH HL ; YES, READ IN THE NEXT ONE.
|
|
CALL READFCB
|
|
POP HL
|
|
JP NZ,TYPE4 ; END OR ERROR?
|
|
XOR A ; OK, CLEAR BYTE COUNTER.
|
|
LD (HL),A
|
|
TYPE3: INC (HL) ; COUNT THIS BYTE.
|
|
LD HL,TBUFF ; AND GET THE (A)TH ONE FROM THE BUFFER (TBUFF).
|
|
CALL ADDHL
|
|
LD A,(HL)
|
|
CP CNTRLZ ; END OF FILE MARK?
|
|
JP Z,GETBACK
|
|
CALL PRINT ; NO, PRINT IT.
|
|
CALL CHKCON ; CHECK CONSOLE, QUIT IF ANYTHING READY.
|
|
JP NZ,GETBACK
|
|
JP TYPE1
|
|
;
|
|
; GET HERE ON AN END OF FILE OR READ ERROR.
|
|
;
|
|
TYPE4: DEC A ; READ ERROR?
|
|
JP Z,GETBACK
|
|
CALL RDERROR ; YES, PRINT MESSAGE.
|
|
TYPE5: CALL RESETDR ; AND RESET PROPER DRIVE
|
|
JP SYNERR ; NOW PRINT FILE NAME WITH PROBLEM.
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* S A V E C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
SAVE: CALL DECODE ; GET NUMERIC NUMBER THAT FOLLOWS SAVE.
|
|
PUSH AF ; SAVE NUMBER OF PAGES TO WRITE.
|
|
CALL CONVFST ; CONVERT FILE NAME.
|
|
JP NZ,SYNERR ; WILD CARDS NOT ALLOWED.
|
|
CALL DSELECT ; SELECT SPECIFIED DRIVE.
|
|
LD DE,FCB ; NOW DELETE THIS FILE.
|
|
PUSH DE
|
|
CALL DELETE
|
|
POP DE
|
|
CALL CREATE ; AND CREATE IT AGAIN.
|
|
JP Z,SAVE3 ; CAN'T CREATE?
|
|
XOR A ; CLEAR RECORD NUMBER BYTE.
|
|
LD (FCB+32),A
|
|
POP AF ; CONVERT PAGES TO SECTORS.
|
|
LD L,A
|
|
LD H,0
|
|
ADD HL,HL ; (HL)=NUMBER OF SECTORS TO WRITE.
|
|
LD DE,TBASE ; AND WE START FROM HERE.
|
|
SAVE1: LD A,H ; DONE YET?
|
|
OR L
|
|
JP Z,SAVE2
|
|
DEC HL ; NOPE, COUNT THIS AND COMPUTE THE START
|
|
PUSH HL ; OF THE NEXT 128 BYTE SECTOR.
|
|
LD HL,128
|
|
ADD HL,DE
|
|
PUSH HL ; SAVE IT AND SET THE TRANSFER ADDRESS.
|
|
CALL DMASET
|
|
LD DE,FCB ; WRITE OUT THIS SECTOR NOW.
|
|
CALL WRTREC
|
|
POP DE ; RESET (DE) TO THE START OF THE LAST SECTOR.
|
|
POP HL ; RESTORE SECTOR COUNT.
|
|
JP NZ,SAVE3 ; WRITE ERROR?
|
|
JP SAVE1
|
|
;
|
|
; GET HERE AFTER WRITING ALL OF THE FILE.
|
|
;
|
|
SAVE2: LD DE,FCB ; NOW CLOSE THE FILE.
|
|
CALL CLOSE
|
|
INC A ; DID IT CLOSE OK?
|
|
JP NZ,SAVE4
|
|
;
|
|
; PRINT OUT ERROR MESSAGE (NO SPACE).
|
|
;
|
|
SAVE3: LD BC,NOSPACE
|
|
CALL PLINE
|
|
SAVE4: CALL STDDMA ; RESET THE STANDARD DMA ADDRESS.
|
|
JP GETBACK
|
|
NOSPACE:.DB "No Space",0
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* R E N A M E C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
RENAME: CALL CONVFST ; CONVERT FIRST FILE NAME.
|
|
JP NZ,SYNERR ; WILD CARDS NOT ALLOWED.
|
|
LD A,(CHGDRV) ; REMEMBER ANY CHANGE IN DRIVES SPECIFIED.
|
|
PUSH AF
|
|
CALL DSELECT ; AND SELECT THIS DRIVE.
|
|
CALL SRCHFCB ; IS THIS FILE PRESENT?
|
|
JP NZ,RENAME6 ; YES, PRINT ERROR MESSAGE.
|
|
LD HL,FCB ; YES, MOVE THIS NAME INTO SECOND SLOT.
|
|
LD DE,FCB+16
|
|
LD B,16
|
|
CALL HL2DE
|
|
LD HL,(INPOINT) ; GET INPUT POINTER.
|
|
EX DE,HL
|
|
CALL NONBLANK ; GET NEXT NON BLANK CHARACTER.
|
|
CP '=' ; ONLY ALLOW AN '=' OR '_' SEPERATOR.
|
|
JP Z,RENAME1
|
|
CP '_'
|
|
JP NZ,RENAME5
|
|
RENAME1:EX DE,HL
|
|
INC HL ; OK, SKIP SEPERATOR.
|
|
LD (INPOINT),HL ; SAVE INPUT LINE POINTER.
|
|
CALL CONVFST ; CONVERT THIS SECOND FILE NAME NOW.
|
|
JP NZ,RENAME5 ; AGAIN, NO WILD CARDS.
|
|
POP AF ; IF A DRIVE WAS SPECIFIED, THEN IT
|
|
LD B,A ; MUST BE THE SAME AS BEFORE.
|
|
LD HL,CHGDRV
|
|
LD A,(HL)
|
|
OR A
|
|
JP Z,RENAME2
|
|
CP B
|
|
LD (HL),B
|
|
JP NZ,RENAME5 ; THEY WERE DIFFERENT, ERROR.
|
|
RENAME2:LD (HL),B ; RESET AS PER THE FIRST FILE SPECIFICATION.
|
|
XOR A
|
|
LD (FCB),A ; CLEAR THE DRIVE BYTE OF THE FCB.
|
|
RENAME3:CALL SRCHFCB ; AND GO LOOK FOR SECOND FILE.
|
|
JP Z,RENAME4 ; DOESN'T EXIST?
|
|
LD DE,FCB
|
|
CALL RENAM ; OK, RENAME THE FILE.
|
|
JP GETBACK
|
|
;
|
|
; PROCESS RENAME ERRORS HERE.
|
|
;
|
|
RENAME4:CALL NONE ; FILE NOT THERE.
|
|
JP GETBACK
|
|
RENAME5:CALL RESETDR ; BAD COMMAND FORMAT.
|
|
JP SYNERR
|
|
RENAME6:LD BC,EXISTS ; DESTINATION FILE ALREADY EXISTS.
|
|
CALL PLINE
|
|
JP GETBACK
|
|
EXISTS: .DB "File Exists",0
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* U S E R C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
USER: CALL DECODE ; GET NUMERIC VALUE FOLLOWING COMMAND.
|
|
CP 16 ; LEGAL USER NUMBER?
|
|
JP NC,SYNERR
|
|
LD E,A ; YES BUT IS THERE ANYTHING ELSE?
|
|
LD A,(FCB+1)
|
|
CP ' '
|
|
JP Z,SYNERR ; YES, THAT IS NOT ALLOWED.
|
|
CALL GETSETUC ; OK, SET USER CODE.
|
|
JP GETBACK1
|
|
;
|
|
;**************************************************************
|
|
;*
|
|
;* T R A N S I A N T P R O G R A M C O M M A N D
|
|
;*
|
|
;**************************************************************
|
|
;
|
|
UNKNOWN:LD A,(FCB+1) ; ANYTHING TO EXECUTE?
|
|
CP ' '
|
|
JP NZ,UNKWN1
|
|
LD A,(CHGDRV) ; NOPE, ONLY A DRIVE CHANGE?
|
|
OR A
|
|
JP Z,GETBACK1 ; NEITHER???
|
|
DEC A
|
|
LD (CDRIVE),A ; OK, STORE NEW DRIVE.
|
|
CALL MOVECD ; SET (TDRIVE) ALSO.
|
|
CALL DSKSEL ; AND SELECT THIS DRIVE.
|
|
JP GETBACK1 ; THEN RETURN.
|
|
;
|
|
; HERE A FILE NAME WAS TYPED. PREPARE TO EXECUTE IT.
|
|
;
|
|
UNKWN1: LD DE,FCB+9 ; AN EXTENSION SPECIFIED?
|
|
LD A,(DE)
|
|
CP ' '
|
|
JP NZ,SYNERR ; YES, NOT ALLOWED.
|
|
UNKWN2: PUSH DE
|
|
CALL DSELECT ; SELECT SPECIFIED DRIVE.
|
|
POP DE
|
|
LD HL,COMFILE ; SET THE EXTENSION TO 'COM'. LD HL,COMFILE
|
|
CALL MOVE3 ; MOVE 3 BYTES FROM (HL) TO (DE) TO ADD .COM
|
|
CALL OPENFCB ; AND OPEN THIS FILE.
|
|
.IF CHKU0B
|
|
JP NZ,UNKWNA ; GOT IT
|
|
LD E,0 ; TRY USER 0, THIS DRIVE
|
|
CALL GETSETUC ; OK, SET USER CODE.
|
|
CALL OPENFCB
|
|
JP NZ,UNKWNA ; GOT IT
|
|
LD HL,FCB ; SEE IF ON DRIVE B, USER 0
|
|
LD (HL),2
|
|
CALL OPENFCB
|
|
.ENDIF
|
|
JP Z,UNKWN9 ; NOPE
|
|
;
|
|
; LOAD IN THE PROGRAM.
|
|
;
|
|
UNKWNA: LD HL,TBASE ; STORE THE PROGRAM STARTING HERE.
|
|
UNKWN3: PUSH HL
|
|
EX DE,HL
|
|
CALL DMASET ; SET TRANSFER ADDRESS.
|
|
LD DE,FCB ; AND READ THE NEXT RECORD.
|
|
CALL RDREC
|
|
JP NZ,UNKWN4 ; END OF FILE OR READ ERROR?
|
|
POP HL ; NOPE, BUMP POINTER FOR NEXT SECTOR.
|
|
LD DE,128
|
|
ADD HL,DE
|
|
LD DE,CBASE ; ENOUGH ROOM FOR THE WHOLE FILE?
|
|
LD A,L
|
|
SUB E
|
|
LD A,H
|
|
SBC A,D
|
|
JP NC,UNKWN0 ; NO, IT CAN'T FIT.
|
|
JP UNKWN3
|
|
;
|
|
; GET HERE AFTER FINISHED READING.
|
|
;
|
|
UNKWN4: POP HL
|
|
DEC A ; NORMAL END OF FILE?
|
|
JP NZ,UNKWN0
|
|
CALL RESETDR ; YES, RESET PREVIOUS DRIVE.
|
|
CALL CONVFST ; CONVERT THE FIRST FILE NAME THAT FOLLOWS
|
|
LD HL,CHGDRV ; COMMAND NAME.
|
|
PUSH HL
|
|
LD A,(HL) ; SET DRIVE CODE IN DEFAULT FCB.
|
|
LD (FCB),A
|
|
LD A,16 ; PUT SECOND NAME 16 BYTES LATER.
|
|
CALL CONVERT ; CONVERT SECOND FILE NAME.
|
|
POP HL
|
|
LD A,(HL) ; AND SET THE DRIVE FOR THIS SECOND FILE.
|
|
LD (FCB+16),A
|
|
XOR A ; CLEAR RECORD BYTE IN FCB.
|
|
LD (FCB+32),A
|
|
LD DE,TFCB ; MOVE IT INTO PLACE AT(005CH).
|
|
LD HL,FCB
|
|
LD B,33
|
|
CALL HL2DE
|
|
LD HL,INBUFF+2 ; NOW MOVE THE REMAINDER OF THE INPUT
|
|
UNKWN5: LD A,(HL) ; LINE DOWN TO (0080H). LOOK FOR A NON BLANK.
|
|
OR A ; OR A NULL.
|
|
JP Z,UNKWN6
|
|
CP ' '
|
|
JP Z,UNKWN6
|
|
INC HL
|
|
JP UNKWN5
|
|
;
|
|
; DO THE LINE MOVE NOW. IT ENDS IN A NULL BYTE.
|
|
;
|
|
UNKWN6: LD B,0 ; KEEP A CHARACTER COUNT.
|
|
LD DE,TBUFF+1 ; DATA GETS PUT HERE.
|
|
UNKWN7: LD A,(HL) ; MOVE IT NOW.
|
|
LD (DE),A
|
|
OR A
|
|
JP Z,UNKWN8
|
|
INC B
|
|
INC HL
|
|
INC DE
|
|
JP UNKWN7
|
|
UNKWN8: LD A,B ; NOW STORE THE CHARACTER COUNT.
|
|
LD (TBUFF),A
|
|
CALL CRLF ; CLEAN UP THE SCREEN.
|
|
CALL STDDMA ; SET STANDARD TRANSFER ADDRESS.
|
|
CALL SETCDRV ; RESET CURRENT DRIVE.
|
|
CALL TBASE ; AND EXECUTE THE PROGRAM.
|
|
;
|
|
; TRANSIANT PROGRAMS RETURN HERE (OR REBOOT).
|
|
;
|
|
LD SP,BATCH ; SET STACK FIRST OFF.
|
|
CALL MOVECD ; MOVE CURRENT DRIVE INTO PLACE (TDRIVE).
|
|
CALL DSKSEL ; AND RESELECT IT.
|
|
JP CMMND1 ; BACK TO COMAND MODE.
|
|
;
|
|
; GET HERE IF SOME ERROR OCCURED.
|
|
;
|
|
UNKWN9: CALL RESETDR ; INPROPER FORMAT.
|
|
JP SYNERR
|
|
UNKWN0: LD BC,BADLOAD ; READ ERROR OR WON'T FIT.
|
|
CALL PLINE
|
|
JP GETBACK
|
|
BADLOAD:.DB "Bad Load",0
|
|
COMFILE:.DB "COM" ; COMMAND FILE EXTENSION.
|
|
;
|
|
; GET HERE TO RETURN TO COMMAND LEVEL. WE WILL RESET THE
|
|
; PREVIOUS ACTIVE DRIVE AND THEN EITHER RETURN TO COMMAND
|
|
; LEVEL DIRECTLY OR PRINT ERROR MESSAGE AND THEN RETURN.
|
|
;
|
|
GETBACK:CALL RESETDR ; RESET PREVIOUS DRIVE.
|
|
GETBACK1:
|
|
CALL CONVFST ; CONVERT FIRST NAME IN (FCB).
|
|
LD A,(FCB+1) ; IF THIS WAS JUST A DRIVE CHANGE REQUEST,
|
|
SUB ' ' ; MAKE SURE IT WAS VALID.
|
|
LD HL,CHGDRV
|
|
OR (HL)
|
|
JP NZ,SYNERR
|
|
JP CMMND1 ; OK, RETURN TO COMMAND LEVEL.
|
|
;
|
|
; CCP STACK AREA.
|
|
;
|
|
.DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
CCPSTACK: .EQU $ ;END OF CCP STACK AREA.
|
|
|
|
;
|
|
; BATCH (OR SUBMIT) PROCESSING INFORMATION STORAGE.
|
|
;
|
|
BATCH: .DB 0 ; BATCH MODE FLAG (0=NOT ACTIVE).
|
|
BATCHFCB:.DB 0,"$$$ SUB"
|
|
.DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
;
|
|
; FILE CONTROL BLOCK SETUP BY THE CCP.
|
|
;
|
|
FCB: .DB 0," ",0,0,0,0,0
|
|
.DB " ",0,0,0,0,0
|
|
RTNCODE:.DB 0 ; STATUS RETURNED FROM BDOS CALL.
|
|
CDRIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE.
|
|
CHGDRV: .DB 0 ; CHANGE IN DRIVES FLAG (0=NO CHANGE).
|
|
NBYTES: .DW 0 ; BYTE COUNTER USED BY TYPE.
|
|
|
|
.IF ENDFIL
|
|
.FILL ((CCPO + 0800H) - $),055H
|
|
.ENDIF
|
|
|
|
.END
|
|
|