home *** CD-ROM | disk | FTP | other *** search
- * PROGRAM NAME: SUB
- * AUTHOR: RICHARD CONN (From SuperSUB Ver 1.1 by Ron Fowler)
- * VERSION: 2.3
- * DATE: 6 JAN 83
- * PREVIOUS VERSIONS: 2.2 (7 DEC 82), 2.1 (14 NOV 82), 2.0 (11 OCT 82)
- * PREVIOUS VERSIONS: 1.4 (10 OCT 81), 1.3 (7 OCT 81)
- * PREVIOUS VERSIONS: 1.2 (5 OCT 81), 1.1 (3 OCT 81), 1.0 (1 OCT 81)
- * NOTE: FOR USE WITH ZCPR2 VERSION 2.6 AND LATER
- VERS EQU 23
-
- ;
- ;
- ;************************************************
- ;* EXTENDED SUBMIT FOR *
- ;* CP/M *
- ;************************************************
- ;
- ; SUB is derived from Ron's SuperSUB program; it provides a different
- ; format for the command line, a command-search hierarchy like CCPZ, a
- ; resetting of the DMA address, several additional functions, and there are
- ; several other additions/changes. Additionally, ZCPR2-specific enhancements,
- ; such as appending the rest of the multiple command line to the command file
- ; and allowing multiple commands on a single line, are permitted.
- ;
- ; REVISED 09/13/81 (RGF): added control character translation
- ; fixed bug in line number reporting
- ;
- ; VERSION 1.1 by Ron Fowler
- ; 2/18/81 (first written) WESTLAND, MICH.
- ;
- ;
- ; This program is intended as a replacement for the
- ; SUBMIT program provided with CP/M. It provides sev-
- ; eral new facilities:
- ; 1) Nestable SUBMIT runs
- ; 2) Interactive entry of SUBMIT job (no need
- ; to use an editor for simple SUBMIT runs)
- ; 3) Command line entry of small SUBMIT jobs
- ; 4) Ability to enter blank lines in an edited
- ; SUBMIT file
- ; 5) User customization of number of parameters
- ; and drive to send $$$.SUB to
- ;
- ; For full details along with examples, see the ac-
- ; companying documentation file.
- ; --Ron Fowler
- ;
- ;
- ; DEFINE BOOLEANS
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ;
- ;************************************************************
- ;
- ; -- User customizable options --
- ;
- CURIND EQU '$' ;CURRENT USER INDICATOR
-
- FORCE$SUB EQU FALSE ;TRUE IF SUBMITTED FILE MUST BE OF TYPE .SUB
- TIME$CONST EQU 0C000H ;DELAY FOR RINGING BELL
- DFLT$USER EQU 0 ;DEFAULT USER NUMBER TO SEARCH FOR .SUB FILE
- DFLT$DISK EQU 0 ;DEFAULT DISK TO SEARCH FOR .SUB FILE (0=A)
- NPAR EQU 20 ;NUMBER OF ALLOWABLE PARAMETERS
- QUIET EQU FALSE ;SET TO TRUE TO ELIMATE SIGN-ON MSG
- CPBASE EQU 0 ;SET TO 4200H FOR HEATH CP/M
- OPT EQU '/' ;OPTION DELIMITER CHAR
- PDELIM EQU '$' ;PARAMETER DELIMITER
- ;
- ;
- ;
- ;************************************************************
- ;
- ; CP/M DEFINITIONS
- ;
- FGCHAR EQU 1 ;GET CHAR FUNCTION
- FPCHAR EQU 2 ;PRINT CHAR FUNCTION
- DIRIOF EQU 6 ;DIRECT CONSOLE I/O
- PRINTF EQU 9 ;PRINT STRING FUNCTION
- RDBUF EQU 10 ;READ CONSOLE BUFFER
- DETVERS EQU 12 ;GET VERSION NUMBER
- LOGIN EQU 14 ;LOG IN DISK
- OPENF EQU 15 ;OPEN FILE FUNCTION
- CLOSEF EQU 16 ;CLOSE FILE FUNCTION
- DELETF EQU 19 ;DELETE FILE FUNCTION
- READF EQU 20 ;READ RECORD FUNCTION
- WRITEF EQU 21 ;WRITE RECORD FUNCTION
- MAKEF EQU 22 ;MAKE (CREATE) FILE FUNCTION
- GETDSK EQU 25 ;RETURN CURRENT DISK
- SETDMA EQU 26 ;SET DMA ADDRESS
- UCODE EQU 32 ;GET/SET USER CODE
- ;
- UDFLAG EQU CPBASE+4
- BDOS EQU CPBASE+5
- ;
- FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK
- FCBEX EQU 12 ;FCB OFFSET TO EXTENT FIELD
- FCBRC EQU 15 ;FCB OFFSET TO RECORD COUNT
- FCBNR EQU 32 ;FCB OFFSET TO NEXT RECORD
- FN EQU 1 ;FCB OFFSET TO FILE NAME
- FT EQU 9 ;FCB OFFSET TO FILE TYPE
- TBUF EQU CPBASE+80H ;DEFAULT BUFFER
- TPA EQU CPBASE+100H ;TRANSIENT PROGRAM AREA
- ;
- PUTCNT EQU TBUF ;COUNTER FOR OUTPUT CHARS
- ;
- ; DEFINE SOME TEXT CHARACTERS
- ;
- CTRLC EQU 3 ;^C
- BEL EQU 7 ;RING BELL
- CR EQU 13 ;CARRIAGE RETURN
- LF EQU 10 ;LINE FEED
- TAB EQU 9
-
- ORG TPA
- ;
- ; Branch to Start of Program
- ;
- JMP SUBMIT
-
- ;
- ;******************************************************************
- ;
- ; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
- ;
- ; This data block precisely defines the data format for
- ; initial features of a ZCPR2 system which are required for proper
- ; initialization of the ZCPR2-Specific Routines in SYSLIB.
- ;
-
- ;
- ; EXTERNAL PATH DATA
- ;
- EPAVAIL:
- DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
- EPADR:
- DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
-
- ;
- ; INTERNAL PATH DATA
- ;
- INTPATH:
- DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT
- ; DISK = 1 FOR A, '$' FOR CURRENT
- ; USER = NUMBER, '$' FOR CURRENT
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0
- DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT
- DB 0 ; END OF PATH
-
- ;
- ; MULTIPLE COMMAND LINE BUFFER DATA
- ;
- MCAVAIL:
- DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
- MCADR:
- DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
-
- ;
- ; DISK/USER LIMITS
- ;
- MDISK:
- DB 4 ; MAXIMUM NUMBER OF DISKS
- MUSER:
- DB 31 ; MAXIMUM USER NUMBER
-
- ;
- ; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
- ;
- DOK:
- DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
- UOK:
- DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
-
- ;
- ; PRIVILEGED USER DATA
- ;
- PUSER:
- DB 10 ; BEGINNING OF PRIVILEGED USER AREAS
- PPASS:
- DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS
- DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
-
- ;
- ; CURRENT USER/DISK INDICATOR
- ;
- CINDIC:
- DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS)
-
- ;
- ; DMA ADDRESS FOR DISK TRANSFERS
- ;
- DMADR:
- DW 80H ; TBUFF AREA
-
- ;
- ; NAMED DIRECTORY INFORMATION
- ;
- NDRADR:
- DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
- NDNAMES:
- DB 64 ; MAX NUMBER OF DIRECTORY NAMES
- DNFILE:
- DB 'NAMES ' ; NAME OF DISK NAME FILE
- DB 'DIR' ; TYPE OF DISK NAME FILE
-
- ;
- ; REQUIREMENTS FLAGS
- ;
- EPREQD:
- DB 0FFH ; EXTERNAL PATH?
- MCREQD:
- DB 0FFH ; MULTIPLE COMMAND LINE?
- MXREQD:
- DB 0FFH ; MAX USER/DISK?
- UDREQD:
- DB 0FFH ; ALLOW USER/DISK CHANGE?
- PUREQD:
- DB 0FFH ; PRIVILEGED USER?
- CDREQD:
- DB 0FFH ; CURRENT INDIC AND DMA?
- NDREQD:
- DB 0FFH ; NAMED DIRECTORIES?
- Z2CLASS:
- DB 0 ; CLASS 0
- DB 'ZCPR2'
- DS 10 ; RESERVED
-
- ;
- ; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
- ;
- ;******************************************************************
- ;
-
- ;
- ; Start of Program
- ;
- SUBMIT:
- LXI H,0 ;SAVE STACK IN CASE
- DAD SP ; ONLY HELP REQUESTED
- SHLD SPSAVE ;(NOT OTHERWISE USED)
- LXI SP,STACK
- MVI C,SETDMA ;SET DMA ADDRESS
- LXI D,TBUF ;SET DMA TO TBUF
- CALL BDOS
- CALL START
- ;
- ; SIGN ON MESSAGE
- ;
- IF NOT QUIET
- DB 'SUB, Version ',VERS/10+'0','.',(VERS MOD 10)+'0','$'
- ENDIF
- ;
- START:
- POP D ;RETRIEVE STRING POINTER
- MVI C,PRINTF
- CALL BDOS ;PRINT THE SIGN-ON
- LDA FCB+1 ;ANYTHING ON CMD LINE?
- CPI ' '
- JZ HELP ;NO, GO PRINT HELP
- CALL INITVAR ;INITIALIZE THE VARIABLE AREA
- CALL GETPAR ;GET COMMAND LINE PARAMETERS AND EXTRACT OPTION
- CALL ABORT ;PERFORM ABORT IF FLAG SET
- CALL SETUP ;SET UP READ OF SUBMIT FILE
- CALL RDFILE ;READ THE SUBMIT FILE
- CALL WRSET ;SET UP WRITE OF "$$$.SUB"
- CALL WRSUB ;WRITE "$$$.SUB"
- JMP CPBASE ;GO START THE SUBMIT
- ;
- ;
- ; SETUP SETS UP THE FILE CONTROL BLOCK
- ; FOR READING IN THE .SUB TEXT FILE
- ;
- SETUP:
- LXI H,FCB+FT ;LOOK AT FIRST CHAR OF
- MOV A,M ;FILE TYPE. IF IT IS
- CPI ' ' ;BLANK, THEN GO MOVE
- JZ PUTSUB ;"SUB" INTO FT FIELD
-
- IF FORCE$SUB ;FILE TYPE MUST BE OF .SUB
- LXI D,SUBTYP ;FILE TYPE MUST BE .SUB
- MVI B,3 ;3 BYTES
- CALL COMPAR
- JNZ NOTFND ;FILE NOT FOUND IF NO TYPE MATCH
- ENDIF
-
- RET ; IF NOT BLANK, THEN ACCEPT ANY FILE TYPE
- ;
- ; MOVE "SUB" INTO THE FILE TYPE
- ;
- PUTSUB:
- XCHG ;BY CONVENTION, MOVE FROM
- LXI H,SUBTYP ; @HL TO @DE
- MVI B,3
- CALL MOVE
- RET
- ;
- ; MOVE # BYTES IN B REGISTER FROM @HL TO @DE
- ;
- MOVE:
- MOV A,M ;PICK UP
- STAX D ;PUT DOWN
- INX H ;I'M SURE
- INX D ; YOU'VE SEEN THIS
- DCR B ; BEFORE...
- JNZ MOVE ;100 TIMES AT LEAST
- RET ;I KNOW I HAVE!
- ;
- ; GETPAR MOVES THE SUBSTITUTION PARAMETERS SPECIFIED
- ; IN THE COMMAND LINE INTO MEMORY, AND STORES THEIR
- ; ADDRESSES IN THE PARAMETER TABLE. THIS ALLOWS
- ; SUBSTITUTION OF $1, $2, ETC., IN THE SUBMIT COMMANDS
- ; WITH THEIR ACTUAL VALUES SPECIFED IN THE COMMAND
- ; LINE.
- ;
- GETPAR:
- XRA A ;A=0
- STA AFLAG ;TURN OFF ABORT COMMAND
- LXI H,TBUF+1 ;WHERE WE FIND THE COMMAND TAIL
- CALL SCANTO ;SKIP SUBMIT FILE NAME
- STA OPTION ;FIRST CHAR OF CMD LINE IS OPTION
- RC ;LINE ENDED?
- CPI OPT ;NO, CHECK OPTION
- JNZ GLP0 ;NOT KEYBOARD INP, READ FILE
- INX H ;POINT PAST '/'
- MOV A,M ;GET OPTION CHAR
- CPI 'A' ;ABORT COMMAND
- JZ GPARABT
- CPI 'D' ;DO COMMAND
- JZ GPARDO
- CPI 'I' ;INTERACTIVE MODE
- JZ GPARINT ;SKIP TO EOL AND RETURN
- JMP HELP ;HELP OTHERWISE
- GPARABT:
- MVI A,0FFH ;TURN ON ABORT FLAG
- STA AFLAG
- INX H ;GET POSSIBLE BELL OPTION
- MOV A,M
- CPI 'B' ;BELL OPTION
- RNZ
- MVI A,0FFH ; SET BELL FLAG
- STA BELL$FLAG
- RET
- GPARINT:
- XRA A ;TURN OFF COMMAND LINE INPUT
- STA CLFLAG
- RET
- GPARDO:
- INX H ;SKIP TO <SP>
- MOV A,M ;GET CHAR
- CPI ' '+1 ;LOOK FOR <SP> OR LESS
- JNC GPARDO
- SLSCAN:
- SHLD CLPTR ;SAVE CMD LINE PTR
- MOV A,M ;KBD IS SOURCE, GET EOL FLAG
- STA CLFLAG ;SAVE AS EOL FLAG
- CPI ' ' ;ALLOW SPACES AFTER '/'
- RNZ ;GOT NON-BLANK, DONE
- INX H ;ELSE CONTINUE SCAN
- JMP SLSCAN
- GLP0:
- MOV A,M ;INPUT IS FROM A .SUB FILE..THIS
- INX H ; CODE SKIPS OVER THE NAME OF
- ORA A ; THE SUB FILE TO GET TO THE
- RZ ; COMMAND LINE PARAMETERS
- CPI ' '
- JZ GLP
- CPI TAB
- JNZ GLP0
- GLP:
- CALL SCANTO ;PASS UP THE BLANKS
- RC ;CY RETURNED IF END OF CMD LINE
- CALL PUTPAR ;NOW PUT THE PARAMETER INTO MEM
- RC ;CY RETURNED IF END OF CMD LINE
- JMP GLP ;GET THEM ALL
- ;
- ; SCANTO SCANS PAST BLANKS TO THE FIRST NON-BLANK. IF
- ; END OF COMMAND LINE FOUND, RETURNS CARRY SET.
- ;
- SCANTO:
- MOV A,M
- INX H
- ORA A ;SET FLAGS ON ZERO
- STC ;IN CASE ZERO FOUND (END OF CMD LIN)
- RZ
- CPI ' '
- JZ SCANTO ;SCAN PAST BLANKS
- CPI TAB ;DO TABS TOO, JUST FOR
- JZ SCANTO ; GOOD MEASURE
- DCX H ;FOUND CHAR, POINT BACK TO IT
- ORA A ;INSURE CARRY CLEAR
- RET
- ;
- ; PUTPAR PUTS THE PARAMETER POINTED TO BY HL INTO
- ; MEMORY POINTED TO BY "TXTPTR". ALSO STORES THE
- ; ADDRESS OF THE PARAMETER INTO THE PARAMETER TABLE
- ; FOR EASY ACCESS LATER, WHEN WE WRITE $$$.SUB
- ;
- PUTPAR:
- PUSH H ;SAVE POINTER TO PARM
- LHLD TXTPTR ;NEXT FREE MEMORY
- XCHG ; INTO DE
- LHLD TBLPTR ;NEXT FREE AREA OF TABLE
- MOV A,M ;NON-ZERO IN TABLE
- ORA A ; INDICATES TABLE
- JNZ PAROVF ; TABLE OVERFLOW (TOO MANY PARMS)
- MOV M,E ;STORE THE PARM ADRS
- INX H
- MOV M,D
- INX H
- SHLD TBLPTR ;SAVE TABLE PNTR FOR NEXT TIME
- POP H ;GET BACK PARM POINTER
- PUSH D ;SAVE FREE MEM POINTER BECAUSE
- ; WE WILL HAVE TO HAVE IT BACK
- ; LATER TO STORE THE LENGTH
- INX D ;POINT PAST LENGTH STORAGE
- MVI B,0 ;INITIALIZE LENGTH OF PARM
- PPLP:
- MOV A,M ;GET NEXT BYTE OF PARM
- INX H
- ORA A ;TEST FOR END OF CMD LINE
- JZ PP2 ;JUMP IF END
- CPI ' ' ;TEST FOR END OF COMMAND
- JZ PP2
- CPI TAB ;TAB ALSO ENDS COMMAND
- JZ PP2
- STAX D ;PUT PARAMETER BYTE-BY-BYTE
- INX D ;INTO FREE MEMORY
- INR B ;BUMP LENGTH
- JMP PPLP
- PP2:
- XCHG
- SHLD TXTPTR ;NEW FREE MEMORY POINTER
- POP H ;REMEMBER OUR LENGTH POINTER?
- MOV M,B ;STORE THE LENGTH
- XCHG ;HAVE TO RETN HL > CMD LINE
- ORA A ;NOW RETURN END OF LINE FLAG
- STC
- RZ ;RETURN CY IF ZERO (EOL MARK)
- CMC
- RET
- ;
- ;
- ; ABORT CHECKS TO SEE IF THE ABORT FLAG IS SET AND
- ; EXECUTES THE ABORT FUNCTION IF SO
- ;
- ;
- ABORT:
- LDA AFLAG ;GET THE FLAG
- ORA A ;0=NO
- RZ
- LXI D,ABMSG ;PRINT ABORT MESSAGE
- MVI C,PRINTF
- CALL BDOS
- CALL CHARINB ;GET RESPONSE
- CPI 'A' ;ABORT?
- JZ ABORT0 ;RETURN TO CP/M
- CPI CTRLC ;ABORT?
- JNZ ABORT1 ;RETURN TO CP/M
- ABORT0:
- LXI D,SUBFCB ;DELETE SUBMIT FILE
- MVI C,DELETF
- CALL BDOS
- LXI D,ABMSG1 ;PRINT DONE MESSAGE
- MVI C,PRINTF
- CALL BDOS
- JMP CPBASE ;RETURN TO CP/M
- ABORT1:
- LXI D,ABMSG2 ;PRINT CONTINUATION MESSAGE
- MVI C,PRINTF
- CALL BDOS
- JMP CPBASE ; RETURN TO CP/M
- ABMSG:
- DB CR,LF,'Abort SUB File'
- DB CR,LF,'Do you wish to abort execution?'
- DB CR,LF,' Enter A or ^C to Abort or anything else to '
- DB 'continue - $'
- ABMSG1:
- DB 'Execution Aborted$'
- ABMSG2:
- DB 'Continuing Execution$'
- ;
- ; INPUT CHAR FROM CON:; RING BELL EVERY SO OFTEN IF FLAG SET
- ;
- CHARINB:
- LDA BELL$FLAG ; GET FLAG
- ORA A ; 0=NO
- JZ CHARIN
- PUSH H ; SAVE HL
- CHARINB$LOOP:
- LXI H,TIME$CONST ; GET TIME CONSTANT
- CHARINB$LOOP1:
- DCX H ; COUNT DOWN
- MOV A,H
- ORA L
- JNZ CHARINB$LOOP1
- MVI E,0FFH ; REQUEST STATUS
- MVI C,DIRIOF ; DIRECT I/O
- CALL BDOS
- ORA A ; ANY INPUT?
- JNZ CHARINB$DONE
- MVI E,BEL ; RING BELL
- MVI C,2 ; OUTPUT TO CON:
- CALL BDOS
- JMP CHARINB$LOOP
- CHARINB$DONE:
- POP H ; RESTORE HL
- JMP CHARIN1
-
- ;
- ; INPUT CHAR FROM CON:; CAPITALIZE IT AND ECHO <CRLF>
- ;
- CHARIN:
- MVI C,FGCHAR ;GET CHAR
- CALL BDOS
- CHARIN1:
- CALL UCASE ;CAPITALIZE
- PUSH PSW ;SAVE IT
- CALL CRLF ;NEW LINE
- POP PSW ;GET IT
- RET
- ;
- ; RDFILE READS THE .SUB FILE SPECIFIED
- ; IN THE SUBMIT COMMAND INTO MEMORY
- ;
- RDFILE:
- LXI H,0 ;INIT LINE NUMBER
- SHLD LINNUM
- LDA OPTION ;USING A FILE?
- CPI OPT ;OPT OPTION TELLS
- JNZ RDFILE1 ;JUMP IF NOT
- LXI D,RDLMSG ;READING LINE MESSAGE
- MVI C,PRINTF
- CALL BDOS
- JMP LINE
- RDFILE1:
- LXI D,RDFMSG ;READING FILE MESSAGE
- MVI C,PRINTF
- CALL BDOS
-
- * CHECK FOR .SUB FILE IN CURRENT USER/CURRENT DISK
- LXI D,FCB ;WE ARE, OPEN IT
- CALL INITFCB ;INIT FCB
- LXI H,INTPATH ;SET ADDRESS OF PATH
- LDA EPAVAIL ;EXTERNAL PATHS AVAILABLE?
- ORA A ;0=NO
- JZ OSB1 ;USE INTERNAL PATH
- LHLD EPADR ;PT TO EXTERNAL PATH
- OSB1:
- CALL FNDFILE ;SEARCH FOR FILE
- JZ NOTFND ;FILE NOT FOUND
- LXI D,FCB ;PT TO FCB
- MVI C,OPENF ;OPEN FILE
- CALL BDOS
- LINE:
- LHLD LINNUM ;BUMP LINE NUMBER
- INX H
- SHLD LINNUM
- LHLD PREV ;GET PREV PREVIOUS LINE POINTER
- XCHG
- LHLD TXTPTR ;GET CURRENT FREE MEM POINTER
- SHLD PREV ;MAKE IT THE PREV LINE (FOR NXT PASS)
- MOV M,E ;STORE AT BEGIN OF CURRENT LINE,
- INX H ; A POINTER TO THE PREVIOUS
- MOV M,D
- INX H
- PUSH H ;LATER WE WILL PUT LENGTH HERE
- INX H ;SKIP PAST LENGTH
- MVI C,0 ;INITIALIZE LENGTH TO ZERO
- LLP:
- CALL GNB ;GET NEXT BYTE FROM INPUT SOURCE
- JC EOF ;CY SET IF END OF FILE FOUND
- ANI 7FH ;MASK OUT MSB
- CALL UCASE ;CONVERT TO UPPER CASE
- CPI 1AH ;SEE IF CPM END OF FILE INDICATOR
- JZ EOF
- CPI LF ;IGNORE LINEFEEDS
- JZ LLP
- CPI CR ;IF IT'S A CARRIAGE RETURN,
- JZ EOL ; THEN DO END OF LINE
- MOV M,A ;STORE ALL OTHERS INTO MEMORY
- INX H
- CALL SIZE ;MAKE SURE NO MEMORY OVERFLOW
- INR C ;BUMP CHAR COUNT
- JM LENERR ;MAX OF 128 CHARS PER LINE
- JMP LLP ;GO DO NEXT CHAR
- RDFMSG:
- DB CR,LF,'Process SUB File$'
- RDLMSG:
- DB CR,LF,'Input SUB File Command Lines$'
- ;
- ; DO END OF LINE SEQUENCE
- ;
- EOL:
- SHLD TXTPTR ;SAVE FREE MEMORY POINTER
- POP H ;CURRENT LINE'S LENGTH POINTER
- MOV M,C ;STORE LENGTH AWAY
- JMP LINE ;GO DO NEXT LINE
- ;
- ; END OF TEXT FILE
- ;
- EOF:
- SHLD TXTPTR ;SAVE FREE MEMORY POINTER
- PUSH B ;SAVE LINE LENGTH
- CALL ZMCL ;LOAD REST OF MULTIPLE COMMAND LINE
- POP B ;RESTORE LINE LENGTH
- POP H ;CURRENT LINE'S LENGTH POINTER
- MOV M,C ;STORE LENGTH AWAY
- RET ;ALL DONE READING SUB FILE
- ;
- ; COPY MULTIPLE COMMAND LINE INTO MEMORY BUFFER
- ;
- ZMCL:
- LDA MCAVAIL ;ANY MULTIPLE COMMANDS?
- ORA A ;0=NO
- RZ
- LHLD LINNUM ;BUMP LINE NUMBER
- INX H
- SHLD LINNUM
- LHLD PREV ;GET PREV PREVIOUS LINE POINTER
- XCHG
- LHLD TXTPTR ;GET CURRENT FREE MEM POINTER
- SHLD PREV ;MAKE IT THE PREV LINE (FOR NXT PASS)
- MOV M,E ;STORE AT BEGIN OF CURRENT LINE,
- INX H ; A POINTER TO THE PREVIOUS
- MOV M,D
- INX H
- PUSH H ;LATER WE WILL PUT LENGTH HERE
- INX H ;SKIP PAST LENGTH
- MVI C,0 ;INITIALIZE LENGTH TO ZERO
- XCHG ;DE PTS TO NEXT PLACE TO STORE A BYTE
- LHLD MCADR ;GET ADDRESS OF MULTIPLE COMMAND LINE BUFFER
- MOV A,M ;GET LOW
- INX H
- MOV H,M ;GET HIGH
- MOV L,A ;HL PTS TO FIRST BYTE OF MULTIPLE COMMAND LINE
- MOV B,M ;GET FIRST CHAR IN LINE
- MVI M,0 ;CLEAR LINE
- MOV A,B ;CHECK TO SEE IF FIRST CHAR IS A SEMICOLON (CMD SEP)
- CPI ';'
- JNZ ZMCL0
- INX H ;PT TO 2ND CHAR
- MOV A,M ;FIRST WAS A SEMICOLON, SO GET SECOND
- ZMCL0:
- XCHG ;HL PTS TO NEXT BUFFER SPACE, DE PTS TO MC LINE
- JMP ZMCL1A ;A=FIRST CHAR IN MC LINE
- ;
- ; MAJOR LOOP TO STORE MULTIPLE COMMAND LINE
- ;
- ZMCL1:
- LDAX D ;GET NEXT BYTE FROM MULTIPLE COMMAND LINE
- ZMCL1A:
- ORA A ;0=EOL
- JZ ZMCL2
- ANI 7FH ;MASK OUT MSB
- CALL UCASE ;CONVERT TO UPPER CASE
- MOV M,A ;STORE CHAR INTO MEMORY
- INX H ;PT TO NEXT CHAR
- INX D
- CALL SIZE ;MAKE SURE NO MEMORY OVFL
- INR C ;INCR CHAR COUNT
- JM LENERR ;MAX OF 128 CHARS IN LINE
- JMP ZMCL1
- ;
- ; DONE WITH INPUT OF MULTIPLE COMMAND LINE -- SAVE CHAR CNT AND SET PTR
- ;
- ZMCL2:
- SHLD TXTPTR ;SAVE PTR
- POP H ;PT TO CHAR COUNT POSITION
- MOV M,C ;STORE CHAR COUNT
- RET
-
- *
- * FNDFILE -- LOOK FOR FILE ALONG ZCPR2 PATH
- * INPUT PARAMETERS: HL = BASE ADDRESS OF PATH, DE = PTR TO FCB OF FILE
- * OUTPUT PARAMETERS: A=0 AND ZERO FLAG SET IF NOT FOUND, NZ IF FOUND
- *
- FNDFILE:
- SHLD PATH ;SAVE PATH BASE ADDRESS
- MVI C,17 ;SEARCH FOR FIRST
- CALL BENTRY ;LOOK FOR FILE
- INR A ;SET FLAG
- JNZ FF5 ;FOUND IT -- RETURN FOUND FLAG
- XCHG ;HL=FCB PTR
- SHLD FCBPTR ;SAVE IT
- LHLD PATH ;PT TO PATH FOR FAILURE POSSIBILITY
- MVI C,32 ;GET CURRENT USER
- MVI E,0FFH
- CALL BENTRY
- STA TMPUSR ;SAVE IT FOR LATER
- ;
- ; MAIN SEARCH LOOP
- ;
- FF1:
- MOV A,M ;GET DRIVE
- ANI 7FH ;MASK MSB
- ORA A ;0=DONE=COMMAND NOT FOUND
- JNZ FF2 ;NO ERROR ABORT?
- ;
- ; FILE NOT FOUND ERROR
- ;
- XRA A ;ZERO FLAG MEANS NOT FOUND
- RET
- ;
- ; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
- ;
- FF2:
- CPI CURIND ;CURRENT DRIVE SPECIFIED?
- JNZ FF3 ;SKIP DEFAULT DRIVE SELECTION IF SO
- LDA UDFLAG ;GET DEFAULT USER/DISK
- ANI 0FH ;MASK FOR DEFAULT DISK
- INR A ;PREP FOR FOLLOWING DCR A
- FF3:
- DCR A ;ADJUST PATH 1 TO 0 FOR A, ETC
- MOV E,A ;DISK NUMBER IN E
- MVI C,14 ;SELECT DISK FCT
- CALL BENTRY ;SELECT DRIVE
- INX H ;PT TO USER NUMBER
- MOV A,M ;GET USER NUMBER
- ANI 7FH ;MASK OUT MSB
- INX H ;PT TO NEXT ENTRY IN PATH
- PUSH H ;SAVE PTR
- CPI CURIND ;CURRENT USER SPECIFIED?
- JNZ FF4 ;DO NOT SELECT CURRENT USER IF SO
- LDA TMPUSR ;GET ORIGINAL USER NUMBER
- FF4:
- MOV E,A ;SELECT USER
- MVI C,32
- CALL BENTRY
- LHLD FCBPTR ;GET PTR TO FCB
- XCHG ;... IN DE
- MVI C,17 ;SEARCH FOR FIRST
- CALL BENTRY ;LOOK FOR FILE
- POP H ;GET PTR TO NEXT PATH ENTRY
- INR A ;SET FLAG
- JZ FF1 ;CONTINUE PATH SEARCH IF SEARCH FAILED
- ;
- ; FILE FOUND -- PERFORM SYSTEM TEST AND PROCEED IF APPROVED
- ;
- FF5:
- MVI A,0FFH ;SET OK RETURN
- ORA A
- RET
-
- ;
- ; BDOS ROUTINE
- ;
- BENTRY:
- PUSH H ;SAVE REGS
- PUSH D
- PUSH B
- CALL BDOS
- POP B ;GET REGS
- POP D
- POP H
- RET
-
- * BUFFERS
- FCBPTR:
- DS 2 ;POINTER TO FCB FOR FILE SEARCH
- TMPUSR:
- DS 1 ;CURRENT USER NUMBER
- PATH:
- DS 2 ;BASE ADDRESS OF PATH
- ;
- ; INITIALIZE KEY FIELDS OF FCB PTED TO BY DE
- ;
- INITFCB:
- PUSH H ;SAVE HL
- XRA A ;A=0
- STAX D ;SET DEFAULT DRIVE
- LXI H,FCBEX ;PT TO EX FIELD
- DAD D
- MOV M,A ;SET EX FIELD TO ZERO
- LXI H,FCBNR ;PT TO CR FIELD
- DAD D
- MOV M,A ;SET CR FIELD TO ZERO
- POP H ;RESTORE HL
- RET
- ;
- ; GET NEXT BYTE FROM INPUT FILE
- ;
- GNB:
- PUSH H ;DON'T ALTER ANYBODY
- PUSH D
- PUSH B
- LDA OPTION ;INPUT FROM .SUB FILE?
- CPI OPT ;TOLD BY ORIG CMD LINE OPTION
- JNZ NSLASH ;JUMP IF WE ARE
- CALL GNBKBD ;NO, GET A BYTE FROM KBD INPUT
- JMP GNBXIT ;THEN LEAVE
- NSLASH:
- LDA IBP ;GET BUFFER POINTER
- ORA A ;PAST END?
- CM FILL ;WRAPPED AROUND
- JNC GNB1 ;NO END OF FILE
-
- * RESTORE CURRENT USER/DISK IF CHANGED
- LDA UDFLAG ;RESTORE CURRENT DISK
- ANI 0FH ;MASK IN DISK ONLY
- MOV E,A
- MVI C,LOGIN ;BDOS FCT
- CALL BDOS
- LDA DUSER ;RESTORE CURRENT USER
- MOV E,A
- MVI C,UCODE ;BDOS FCT
- CALL BDOS
-
- MVI A,1AH ;FAKE EOF
- GNB1:
- MOV E,A ;PUT IN DE
- MVI D,0
- INR A ;POINT TO NEXT
- STA IBP ;PUT AWAY
- LXI H,TBUF ;NOW OFFSET INTO BUFR
- DAD D
- MOV A,M ;GET CHAR THERE
- GNBXIT:
- POP B ;RESTORE EVERYBODY
- POP D
- POP H
- ORA A ;TURN ON CARRY
- RET
- ;
- ; FILL INPUT BUFFER
- ;
- FILL:
- MVI C,READF
- LXI D,FCB
- CALL BDOS
- ORA A ;GOT GOOD READ?
- MVI A,0 ;(NEW BUF PTR)
- STC
- RNZ ;RETN CY=EOF
- CMC ;NO EOF, NO CY
- RET
- ;
- ; COME HERE TO GET A .SUB CHARACTER WHEN
- ; WE'RE NOT USING A .SUB FILE ("/" OPTION)
- ;
- GNBKBD:
- LDA CLFLAG ;USE CP/M CMD LINE?
- ORA A
- JNZ GNBCL ;THEN GO DO IT
- LDA CLCNT ;NOT, CHECK LOCAL
- ORA A ; CMD LINE CHAR COUNT
- CM CLFILL ;REFILL WHEN IT WRAPS BACK
- JC GKEND ;GOT CARRY (FROM CLFILL), RETURN EOF
- DCR A ;COUNT DOWN
- STA CLCNT
- JP GNBCL ;IF PLUS, BUFFER NOT EMPTY
- MVI A,CR ;OUT OF CHARS, RETURN A CR
- RET
- GKEND:
- MVI A,1AH ;RETURN EOF
- RET
- ;
- ; GET NEXT BYTE OF INPUT FROM CMD LINE @CLPTR
- ;
- GNBCL:
- LHLD CLPTR ;LOAD THE POINTER
- MOV A,M ;GET THE CHAR
- INX H ;BUMP POINTER FOR NEXT TIME
- SHLD CLPTR
- ORA A ;PHYSICAL END-OF-LINE
- RNZ ;THIS ONLY NEEDED WHEN INPUT
- ; SOURCE IS ORIG CPM CMD LINE
- MVI A,1AH ;TRANSLATE THAT TO END OF FILE
- RET
- ;
- ; SUBROUTINE TO RE-FILL THE LOCAL COMMAND LINE
- ;
- CLFILL:
- LXI D,PROMPT ;PRINT A PROMPT
- MVI C,PRINTF ;USE CP/M FUNCT 9
- CALL BDOS
- LXI D,CLBUF ;NOW FILL THE BUFFER
- MVI C,RDBUF
- CALL BDOS
- LDA CLCNT ;RETURN WITH COUNT IN A
- LXI H,CLTEXT ;RESET THE CMD LINE POINTER
- SHLD CLPTR
- ORA A ;SET CY ON LEN NZ
- STC
- RZ
- CMC
- RET
- ;
- ; MAKE SURE NO MEMORY OVERFLOW
- ;
- SIZE:
- LDA BDOS+2 ;HIGHEST PAGE POINTER
- DCR A ;MAKE IT BE UNDER BDOS
- CMP H ;CHECK IT AGAINST CURRENT PAGE
- RNC ;NC=ALL OKAY
- JMP MEMERR ;OTHERWISE ABORT
- ;
- ; SET UP THE $$$.SUB FILE
- ; FOR WRITING
- ;
- WRSET:
- LXI D,WRSUBMSG
- MVI C,PRINTF
- CALL BDOS
- LXI D,SUBFCB
- MVI C,OPENF
- CALL BDOS ;OPEN THE FILE
- INR A ;CHECK CPM RETURN
- JZ NONE1 ;NONE EXISTS ALREADY
- ;
- ; $$$.SUB EXISTS, SO SET
- ; FCB TO APPEND TO IT
- ;
- LDA SUBFCB+FCBRC ;GET RECORD COUNT
- STA SUBFCB+FCBNR ;MAKE NEXT RECORD
- RET
- ;
- ; COME HERE WHEN NO $$$.SUB EXISTS
- ;
- NONE1:
- LXI D,SUBFCB
- MVI C,MAKEF
- CALL BDOS
- INR A
- JZ NOMAKE ;0FFH=CAN'T CREATE FILE
- RET
- ;
- WRSUBMSG:
- DB CR,LF,'Writing SUB Execution File to Disk$'
- ;
- ; WRITE THE "$$$.SUB" FILE
- ;
- WRSUB:
- LHLD PREV ;THIS CODE SCANS BACKWARD
- MOV A,H ; THRU THE FILE STORED IN
- ORA L ; MEMORY TO THE FIRST NON-
- JZ NOTEXT ; NULL LINE. IF NONE IS
- MOV E,M ; FOUND, ABORTS
- INX H
- MOV D,M ;HERE, WE PICK UP PNTR TO PREV LINE
- INX H ;NOW WE POINT TO LENGTH
- XCHG ;WE NEED TO STORE AWAY
- SHLD PREV ; POINTER TO PREV LINE
- XCHG
- MOV A,M ;NOW PICK UP THE LENGTH
- ORA A ;SET Z FLAG ON LENGTH
- JNZ WRNTRY ;GOT LINE W/LENGTH: GO DO IT
- LHLD LINNUM ;NOTHING HERE, FIX LINE NUMBER
- DCX H ;(WORKING BACKWARD NOW)
- SHLD LINNUM
- JMP WRSUB
- WRLOP:
- LHLD PREV ;GET PREV LINE POINTER
- MOV A,H
- ORA L ;IF THERE IS NO PREV LINE
- JZ CLOSE ; THEN WE ARE DONE
- MOV E,M ;ELSE SET UP PREV FOR NEXT
- INX H ; PASS THRU HERE
- MOV D,M
- INX H
- XCHG ;NOW STORE IT AWAY
- SHLD PREV
- XCHG
- WRNTRY:
- CALL PUTLIN ;WRITE THE LINE TO THE FILE
- LHLD LINNUM ;BUMP THE LINE NUMBER
- DCX H ;DOWN (WORKING BACK NOW)
- SHLD LINNUM
- JMP WRLOP
- ;
- ; $$$.SUB IS WRITTEN, CLOSE THE FILE
- ;
- CLOSE:
- LXI D,SUBFCB
- MVI C,CLOSEF
- JMP BDOS
- ;
- ; THIS SUBROUTINE WRITES A LINE
- ; TO THE $$$.SUB FILE BUFFER,
- ; AND FLUSHES THE BUFFER AFTER
- ; THE LINE IS WRITTEN.
- ;
- PUTLIN:
- MOV A,M ;PICK UP LENGTH BYTE
- INX H ;POINT PAST IT
- STA GETCNT ;MAKE A COUNT FOR "GET"
- SHLD GETPTR ;MAKE A POINTER FOR "GET"
- LXI H,TBUF+1 ;TEXT GOES AFTER LENGTH
- SHLD PUTPTR ;MAKE POINTER FOR "PUT"
- XRA A ;INITIALIZE PUT COUNT
- STA PUTCNT
- MOV B,L ;COUNT FOR CLEAR LOOP
- CLR:
- MOV M,A ;ZERO OUT BUFFER LOC
- INX H
- INR B ;COUNT
- JNZ CLR
- ;
- ; THIS LOOP COLLECTS CHARACTERS
- ; FROM THE LINE STORED IN MEMORY
- ; AND WRITES THEM TO THE FILE.
- ; IF THE "$" PARAMETER SPECIFIER
- ; IS ENCOUNTERED, PARAMETER SUB-
- ; STITUTION IS DONE
- ;
- PUTLP:
- CALL GETCHR ;PICK UP A CHARACTER
- JC FLUSH ;CY = NO MORE CHAR IN LINE
- CPI '^' ;CONTROL-CHAR TRANSLATE PREFIX?
- JNZ NOTCX
- CALL GETCHR ;YES, GET THE NEXT
- JC CCERR ;ERROR: EARLY END OF INPUT
- SUI '@' ;MAKE IT A CONTROL-CHAR
- JC CCERR ;ERROR: TOO SMALL
- CPI ' '
- JNC CCERR ;ERROR: TOO LARGE
- NOTCX:
- CPI PDELIM ;PARAMETER SPECIFIER?
- JNZ STOBYT ;IF NOT, JUST WRITE CHAR
- LDA OPTION ;CHECK OPTION: '$' DOESN'T
- CPI OPT ; COUNT IN OPT MODE
- MVI A,PDELIM ;(RESTORE THE '$')
- JZ STOBYT
- CALL LKAHED ;PEEK AT NEXT CHAR
- JC PARERR ;LINE ENDING MEANS PARAM ERR
- CPI PDELIM ;ANOTHER "$"?
- JNZ SUBS ;IF NOT THEN GO DO SUBSTITUTION
- CALL GETCHR ;GET THE 2ND "$" (WE ONLY LOOKED
- ; AHEAD BEFORE)
- STOBYT:
- CALL PUTCHR ;WRITE CHAR TO FILE
- JMP PUTLP
- ;
- ; PARAMETER SUBSTITUTION...LOOKS UP THE
- ; PARAMETER # AFTER THE "$" AND PLUGS IT
- ; IN IF IT EXISTS.
- ;
- SUBS:
- CALL NUMTST ;IT BETTER BE A NUMBER
- JC PARERR ; OTHERWISE PARAM ERROR
- MVI B,0 ;INITIALIZE PARM #
- JMP LPNTRY ;WE JOIN LOOP IN PROGRESS...
- SUBLP:
- CALL LKAHED ;LOOK AT NEXT CHAR
- JC DOSUBS ;IF LINE EMPTY, THEN PLUG IN PARM
- CALL NUMTST ;CHECK FOR NUMERIC
- JC DOSUBS ;DONE IF NOT
- LPNTRY:
- CALL GETCHR ;NOW REMOVE THE CHAR FROM INPUT STREAM
- SUI '0' ;REMOVE ASCII BIAS
- MOV C,A ;SAVE IT
- MOV A,B ;OUR ACCUMULATED COUNT
- ADD A ;MULTIPLY BY TEN
- ADD A
- ADD B
- ADD A
- ADD C ;THEN ADD IN NEW DIGIT
- MOV B,A ;RESTORE COUNT
- JMP SUBLP
- ;
- ; PERFORM THE SUBSTITUTION
- ;
- DOSUBS:
- MOV A,B ;GET PARM #
- DCR A ;MAKE ZERO RELATIVE
- JM PARERR ;OOPS
- CALL LOOKUP ;LOOK IT UP IN PARM TABLE
- JC PARERR ;IT'S NOT THERE
- MOV B,A ;LENGTH IN B
- SUBLP1:
- INR B ;TEST B FOR ZERO
- DCR B
- JZ PUTLP ;DONE
- MOV A,M ;GET CHAR OF REAL PARAMETER
- INX H ;POINT PAST FOR NEXT TIME
- PUSH H ;SAVE REAL PARM POINTER
- CALL PUTCHR ;PUT IT IN THE FILE
- POP H ;GET BACK REAL PARM POINTER
- DCR B ;COUNTDOWN
- JMP SUBLP1
- ;
- ; COME HERE WHEN A LINE IS FINISHED,
- ; AND WE NEED TO WRITE THE BUFFER TO DISK
- ;
- FLUSH:
- LXI D,SUBFCB
- MVI C,WRITEF
- CALL BDOS
- ORA A
- JNZ WRERR ;CPM RETURNED A WRITE ERROR
- RET
- ;
- ; GETCHR GETS ONE CHAR FROM
- ; LINE STORED IN MEMORY
- ;
- GETCHR:
- LXI H,GETCNT
- MOV A,M ;PICK UP COUNT
- DCR A ;REMOVE THIS CHAR
- STC ;PRESET ERROR
- RM ;RETURN CY IF OUT OF CHARS
- MOV M,A ;UPDATE COUNT
- LHLD GETPTR ;CURRENT CHAR POINTER
- MOV A,M ;PICK UP CHAR
- INX H ;BUMP POINTER
- SHLD GETPTR ;PUT IT BACK
- CMC ;TURN CARRY OFF
- RET
- ;
- ; PUTCHR PUTS ONE CHAR TO
- ; THE OUTPUT BUFFER
- ;
- PUTCHR:
- LXI H,PUTCNT
- INR M ;INCREMENT COUNT
- JM LENERR ;LINE WENT TO > 128 CHARS
- LHLD PUTPTR ;GET BUFFER POINTER
- ANI 7FH ;MASK OUT MSB
- MOV M,A ;PUT CHAR THERE
- INX H ;BUMP POINTER
- SHLD PUTPTR ;PUT IT BACK
- RET ;ALL DONE
- ;
- ; LOOK AHEAD ONE CHAR IN
- ; THE INPUT STREAM. SET
- ; CARRY IF NONE LEFT.
- ;
- LKAHED:
- LDA GETCNT
- ORA A ;SEE IF COUNT IS DOWN TO ZERO
- STC ;PRE SET INDICATOR
- RZ
- MOV A,M ;PICK UP CHAR
- CMC ;TURN OFF CARRY FLAG
- RET
- ;
- ; LOOK UP PARAMETER WITH NUMBER IN
- ; A REG. RETURN A=LENGTH OF PARM,
- ; AND HL => PARAMETER
- ;
- LOOKUP:
- CPI NPAR
- JNC PAROVF ;PARM # TOO HIGH
- MOV L,A
- MVI H,0 ;NOW HAVE 16 BIT NUMBER
- DAD H ;DOUBLE FOR WORD OFFSET
- LXI D,TABLE
- DAD D ;DO THE OFFSET
- MOV E,M ;GET ADDRESS OF PARM
- INX H
- MOV D,M
- MOV A,D ;ANYTHING THERE?
- ORA E
- JNZ LKUPOK
- XRA A ;NO, ZERO LENGTH
- RET
- LKUPOK:
- XCHG ;NOW IN DE
- MOV A,M ;PICK UP LENGTH
- INX H ;POINT PAST LENGTH
- RET
- ;
- ; UTILITY COMPARE SUBROUTINE
- ;
- COMPAR:
- LDAX D
- CMP M
- RNZ
- INX H
- INX D
- DCR B
- JNZ COMPAR
- RET
- ;
- ; NUMERIC TEST UTILITY SUBROUTINE
- ;
- NUMTST:
- CPI '0'
- RC
- CPI '9'+1
- CMC
- RET
- ;
- ;DECIMAL OUTPUT ROUTINE
- ;
- DECOUT:
- PUSH B
- PUSH D
- PUSH H
- LXI B,-10
- LXI D,-1
- ;
- DECOU2:
- DAD B
- INX D
- JC DECOU2
- LXI B,10
- DAD B
- XCHG
- MOV A,H
- ORA L
- CNZ DECOUT
- MOV A,E
- ADI '0'
- CALL TYPE
- POP H
- POP D
- POP B
- RET
- ;
- ; PRINT CR, LF ON CONSOLE
- ;
- CRLF:
- MVI A,CR
- CALL TYPE
- MVI A,LF
- ;
- ; PRINT CHAR IN A ON CONSOLE
- ;
- TYPE:
- PUSH H ;SAVE REGS
- PUSH D
- PUSH B
- MOV E,A ;PUT IN E FOR CP/M
- MVI C,FPCHAR
- CALL BDOS ;PRINT IT
- POP B ;RESTORE ALL
- POP D
- POP H
- RET
- ;
- ; CONVERT CHAR IN A TO UPPER CASE
- ;
- UCASE:
- CPI 'a' ;VALIDATE CASE
- RC
- CPI 'z'+1
- RNC
- ANI 5FH ;GOT LC, CONV TO UC
- RET
- ;
- ; ERROR HANDLERS
- ;
- WRERR:
- CALL ERRXIT
- DB 'Disk Full$'
- NOMAKE:
- CALL ERRXIT
- DB 'Directory Full$'
- MEMERR:
- CALL ERRXIT
- DB 'Memory Full$'
- NOTFND:
- CALL ERRXIT
- DB 'SUBMIT File Not Found$'
- PARERR:
- CALL ERRXIT
- DB 'Parameter$'
- PAROVF:
- CALL ERRXIT
- DB 'Too Many Parameters: $'
- LENERR:
- CALL ERRXIT
- DB 'Line too Long: $'
- NOTEXT:
- CALL ERRXIT
- DB 'SUBMIT File Empty$'
- CCERR:
- CALL ERRXIT
- DB 'Control Character$'
- ERRXIT:
- LXI D,SUBERR ;PRINT ERROR HERALD
- MVI C,PRINTF
- CALL BDOS
- POP D
- MVI C,PRINTF
- CALL BDOS
- LXI D,ERRMSG ;PRINT 2ND HALF MSG
- MVI C,PRINTF
- CALL BDOS
- LHLD LINNUM ;TELL LINE NUMBER
- CALL DECOUT
- CALL CRLF
- LXI D,SUBFCB ;DELETE THE $$$.SUB FILE
- MVI C,DELETF
- CALL BDOS
- JMP CPBASE
- ;
- SUBERR:
- DB CR,LF,'SUB Error -- $'
- ERRMSG:
- DB ' error on line number: $'
- ;
- ; PROMPT FOR COMMAND LINE INPUT
- ;
- PROMPT:
- DB CR,LF,'Command Line? $'
- ;
- ; INITIALIZE ALL VARIABLES
- ;
- INITVAR:
- LXI H,VAR
- LXI B,ENDVAR-VAR
- INITLP:
- MVI M,0 ;ZERO ENTIRE VAR AREA
- INX H
- DCX B
- MOV A,B
- ORA C
- JNZ INITLP
- LXI H,TABLE ;INIT PARM TABLE POINTER
- SHLD TBLPTR
- LXI H,0FFFFH ;MARK END OF TABLE
- SHLD ENDTBL
- LXI H,FREMEM ;FREE MEMORY STARTS TXT AREA
- SHLD TXTPTR
- MVI A,80H ;FORCE READ
- STA IBP
- STA CLCNT ;FORCE CONSOLE READ
- ; GET CURRENT USER NUMBER FOR LATER
- MVI E,0FFH ;GET USER CODE
- MVI C,UCODE ;BDOS FCT
- CALL BDOS
- STA DUSER ;DEFAULT USER
- RET
- ;
- ; PRINT HELP WITH PROGRAM OPTIONS
- ;
- HELP:
- LXI D,HLPMSG ;PRINT THE HELP STUFF
- MVI C,PRINTF
- CALL BDOS
- LHLD SPSAVE ;THEN RETURN W/NO WARM-BOOT
- SPHL
- RET
- ;
- HLPMSG:
- DB CR,LF,'How to use SUB --',CR,LF
- DB CR,LF,'SUB<CR> - print this HELP message'
- DB CR,LF,'SUB /A <text> - Abort of SUBMIT File'
- DB CR,LF,'SUB /AB <text> - /A and Ring Bell'
- DB CR,LF,'SUB /D <cmd lines> - use SUMMARY (DO) mode'
- DB CR,LF,'SUB /I<CR> - go into Interactive mode'
- DB CR,LF,'SUB <FILE> <PARMS> - as in standard SUBMIT.COM'
- DB CR,LF
- DB CR,LF,'In "/I" (interactive) mode, SUB will prompt you'
- DB CR,LF,'a line at a time for the SUBMIT job input...logical'
- DB CR,LF,'lines may be combined on the same input line by sep-'
- DB CR,LF,'erating them with semicolons. Example:'
- DB CR,LF,' A>SUB /D STAT;DIR'
- DB CR,LF,'specifies two commands on the same input line.',CR,LF
- DB CR,LF,'Submitted jobs may be nested...SUB does not erase'
- DB CR,LF,'any existing submit job (appends to them instead).'
- DB CR,LF
- DB CR,LF,'To insert a control character into the output, pre-'
- DB CR,LF,'fix it with a "^" (works in any mode).'
- DB CR,LF,'$'
- ;
- ; VARIABLE STORAGE
- ;
- VAR EQU $
- ;
- AFLAG:
- DB 0 ;ABORT FLAG (0=NO)
- TXTPTR:
- DW 0 ;FREE MEMORY POINTER
- TBLPTR:
- DW 0 ;POINTER TO PARM TABLE
- DUSER:
- DB 0 ;DEFAULT USER NUMBER
- LINNUM:
- DW 0 ;CURRENT LINE NUMBER
- PREV:
- DW 0 ;POINTER TO PREV LINE
- GETCNT:
- DB 0 ;COUNTER FOR 'GET'
- GETPTR:
- DW 0 ;POINTER FOR 'GET'
- PUTPTR:
- DW 0 ;POINTER FOR 'PUT'
- IBP:
- DB 0 ;INPUT BUFFER POINTER
- CLPTR:
- DW 0 ;COMMAND LINE POINTER
- CLFLAG:
- DB 0 ;USE CP/M CMD LINE FLAG
- BELL$FLAG:
- DB 0 ;RING BELL ON ABORT FLAG
- OPTION:
- DB 0 ;OPT OPTION FLAG STORE
- TABLE:
- DS NPAR*3 ;PARAMETER TABLE
- ENDTBL:
- DW 0FFFFH ;END OF PARAMETER TABLE
- ;
- ENDVAR EQU $
- ;
- ; COMMAND LINE BUFFER...NOT INITIALIZED
- ;
- CLBUF:
- DB 128 ;BUFFER LENGTH
- CLCNT:
- DB 0 ;CHARACTER COUNTER
- CLTEXT:
- DS 128 ;THE BUFFER ITSELF
- ;
- SPSAVE:
- DW 0 ;STACK POINTER SAVE
- ;
- ;
- ; FCB FOR $$$.SUB
- ;
- SUBFCB:
- DB 1 ;DRIVE SPECIFIER (A SELECTED)
- DB '$$$ '
- SUBTYP:
- DB 'SUB'
- DW 0,0,0,0 ;INITIALIZE REST OF FCB
- DW 0,0,0,0
- DW 0,0,0,0
- ;
- ; STACK AREA
- ;
- DS 200 ;WHY NOT?
- STACK EQU $
- FREMEM EQU $
- ;
- END SUB
-
-