home *** CD-ROM | disk | FTP | other *** search
- ;
- ;
- ;************************************************
- ;* EXTENDED SUBMIT FOR *
- ;* CP/M AND MP/M *
- ;************************************************
- ;
- ; REVISED 12/22/81 :added code to so supersub would work under mp/m
- ; and cp/m. George Gary
- ;
- ; 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 --
- ;
- NPAR EQU 10 ;NUMBER OF ALLOWABLE PARAMETERS
- SUBDRV EQU 1 ;MAKE 0 FOR DFLT, 1,2,3,ETC FOR A,B,C
- QUIET EQU FALSE ;SET TO TRUE TO ELIMATE SIGN-ON MSG
- CPBASE EQU 0 ;SET TO 4200H FOR HEATH CP/M
- ;
- ;
- ;
- ;************************************************************
- ;
- ; CP/M DEFINITIONS
- ;
- FPCHAR EQU 2 ;PRINT CHAR FUNCTION
- PRINTF EQU 9 ;PRINT STRING FUNCTION
- RDBUF EQU 10 ;READ CONSOLE BUFFER
- 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
- ;
- BDOS EQU CPBASE+5
- ;
- FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK
- 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
- ;
- CR EQU 13 ;CARRIAGE RETURN
- LF EQU 10 ;LINE FEED
- TAB EQU 9
- ;
- ; START OF PROGRAM CODE
- ;
- ORG TPA
- ;
- ; GET THE BALL ROLLING
- ;
- SUBMIT: LXI H,0 ;SAVE STACK IN CASE
- DAD SP ; ONLY HELP REQUESTED
- SHLD SPSAVE ;(NOT OTHERWISE USED)
- LXI SP,STACK
- CALL START
- ;
- ; SIGN ON MESSAGE
- ;
- IF NOT QUIET
- DB 'SuperSUB V1.1'
- ENDIF
- ;
- DB CR,LF,'$' ;NEWLINE EVEN IF QUIET
- ;
- START:
- POP D ;RETRIEVE STRING POINTER
- MVI C,PRINTF
- LDA FCB+1 ;ANYTHING ON CMD LINE?
- CPI ' '
- JZ HELP ;NO, GO PRINT HELP
- CALL BDOS ;PRINT THE SIGN-ON
- CALL INITVAR ;INITIALIZE THE VARIABLE AREA
- CALL GETPAR ;GET COMMAND LINE PARAMETERS
- 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
- LXI D,SUBTYP ;IT'S NOT BLANK SO MAKE
- MVI B,3 ; SURE IT'S ALREADY
- CALL COMPAR ; "SUB"
- JNZ NOTFND ;IF NOT, IT'S AN ERROR
- RET
- ;
- ; 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: 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 '/' ;NO, CHECK OPTION
- JNZ GLP0 ;NOT KEYBOARD INP, READ FILE
- INX H ;POINT PAST '/'
- 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
- ;
- ; 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 '/' ;'/' OPTION TELLS
- JZ LINE ;JUMP IF NOT
- LXI D,FCB ;WE ARE, OPEN IT
- MVI C,OPENF
- CALL BDOS
- INR A ;IF 0FFH RETURNED,
- JZ NOTFND ; THEN FILE NOT FOUND
- 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
- 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
- ;
- ; 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
- POP H ;CURRENT LINE'S LENGTH POINTER
- MOV M,C ;STORE LENGTH AWAY
- RET ;ALL DONE READING SUB FILE
- ;
- ; GET NEXT BYTE FROM INPUT FILE
- ;
- GNB: PUSH H ;DON'T ALTER ANYBODY
- PUSH D
- PUSH B
- LDA OPTION ;INPUT FROM .SUB FILE?
- CPI '/' ;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
- 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
- CPI ';' ;LOGICAL END-OF-LINE?
- JNZ NSEMI ;JUMP IF NOT
- MVI A,CR ;YES, TRANSLATE IT
- RET
- NSEMI: 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: CALL ISMPM ;ADDED BY GAG TO CHECK FOR MP/M OPERATING SYSTEM
- 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
- ;
- ; 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 '$' ;PARAMETER SPECIFIER?
- JNZ STOBYT ;IF NOT, JUST WRITE CHAR
- LDA OPTION ;CHECK OPTION: '$' DOESN'T
- CPI '/' ; COUNT IN '/' MODE
- MVI A,'$' ;(RESTORE THE '$')
- JZ STOBYT
- CALL LKAHED ;PEEK AT NEXT CHAR
- JC PARERR ;LINE ENDING MEANS PARAM ERR
- CPI '$' ;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
- 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: 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
- ;
- ERRMSG: DB ' error on line number: $'
- ;
- ; PROMPT FOR COMMAND LINE INPUT
- ;
- PROMPT: DB CR,LF,'*$'
- ;
- ; 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
- RET
-
- ;THIS ROUTINE CHECKS FOR MP/M OPERATING SYSTEM. IF IT'S CP/M THEN IT RETURNS
- ;IF ITS MP/M IT FINDS THE CONSOLE NO FROM THE SYSTEM AND INSERTS IT IN THE
- ;SECOND CHARACTER POSITION OF THE FILE TYPE IN THE FCB FOR THE SUBMIT FILE
- ;AND SETS A FLAG IN THE MP/M SYSTEM TO TELL IT THERE'S A SUBMIT FILE TO
- ;EXECUTE WHEN THE NEXT WARM BOOT OCCURRS. GAG
-
- ISMPM: PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- MVI C,0CH ;GET VERSION NUMBER IN HL
- CALL 005H
- XRA A
- CMP H ;IS IT CP/M?
- JZ RSET ;ZERO MEANS CP/M. DON'T NEED ANYTHING ELSE
- MPM: MVI C,9AH ;GET SYSTEM DATA ADDRESS IN HL
- CALL 005H
- LXI D,80H
- DAD D ;ADD 128 TO IT TO FIND SUBMIT FLAGS
- PUSH H ;SAVE POINTER TO SUBMIT FLAGS
- MVI C,99H ;GET CONSOLE NUMBER IN A
- CALL 005H
- MVI D,0
- MOV E,A ;DE = A
- ADI 30H ;PUT ASCII OF CONSOLE NO IN FCB
- LXI H,CONSOL ;SECOND LETTER IN FILE TYPE IN FCB
- MOV M,A ;PUT ASCII OF CONSOLE NO IN FCB
- POP H ;RESTORE POINTER TO SUBMIT FLAGS
- DAD D ;CONSOLE SUBMIT FLAG = PTR + CON NO.
- MVI M,0FFH ;SET CON SUBMIT FLAG TO TRUE
- RSET: POP H ;RETURN TO MAIN PROGRAM
- POP D
- POP B
- POP PSW
- 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 SUPERSUB:',CR,LF
- DB CR,LF,'SUPERSUB<CR> :print this HELP message'
- DB CR,LF,'SUPERSUB /<CR> :go into interactive mode'
- DB CR,LF,'SUPERSUB /<cmd lines> :use SUMMARY mode'
- DB CR,LF,'SUPERSUB <FILE> <PARMS> :as in standard SUBMIT.COM'
- DB CR,LF
- DB CR,LF,'In "/" (interactive) mode, SUPERSUB 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>SUPERSUB /STAT;DIR'
- DB CR,LF,'specifies two commands on the same input line.',CR,LF
- DB CR,LF,'Submitted jobs may be nested...SUPERSUB 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 $
- ;
- TXTPTR: DW 0 ;FREE MEMORY POINTER
- TBLPTR: DW 0 ;POINTER TO PARM TABLE
- 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
- OPTION: DB 0 ;'/' 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 SUBDRV ;DRIVE SPECIFIER
- DB '$'
- CONSOL: DB '$' ; IF MPM THEN PUT ASCII OF CONSOLE NO HERE.
- DB '$ '
- SUBTYP: DB 'SUB'
- DW 0,0,0,0 ;INITIALIZE REST OF FCB
- DW 0,0,0,0
- DW 0,0
- ;
- ; STACK AREA
- ;
- DS 200 ;WHY NOT?
- STACK EQU $
- FREMEM EQU $
- ;
- END SUBMIT
-