home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol067 / sub.asm < prev    next >
Assembly Source File  |  1984-04-29  |  22KB  |  885 lines

  1. ;
  2. ;
  3. ;************************************************
  4. ;*        EXTENDED SUBMIT FOR        *
  5. ;*             CP/M AND MP/M              *
  6. ;************************************************
  7. ;
  8. ; REVISED 12/22/81 :added code to so supersub would work under mp/m
  9. ;                   and cp/m. George Gary
  10. ;
  11. ; REVISED 09/13/81 (RGF): added control character translation
  12. ;              fixed bug in line number reporting
  13. ;
  14. ;    VERSION 1.1         by Ron Fowler
  15. ;    2/18/81 (first written)     WESTLAND, MICH.
  16. ;
  17. ;
  18. ; This program is intended as a replacement for the
  19. ; SUBMIT program provided with CP/M.  It provides sev-
  20. ; eral new facilities:
  21. ;    1) Nestable SUBMIT runs
  22. ;    2) Interactive entry of SUBMIT job (no need
  23. ;       to use an editor for simple SUBMIT runs)
  24. ;    3) Command line entry of small SUBMIT jobs
  25. ;    4) Ability to enter blank lines in an edited
  26. ;       SUBMIT file
  27. ;    5) User customization of number of parameters
  28. ;       and drive to send $$$.SUB to
  29. ;
  30. ; For full details along with examples, see the ac-
  31. ; companying documentation file.
  32. ;            --Ron Fowler
  33. ;
  34. ;
  35. ; DEFINE BOOLEANS
  36. ;
  37. FALSE    EQU    0
  38. TRUE    EQU    NOT FALSE
  39. ;
  40. ;************************************************************
  41. ;
  42. ;        --  User customizable options --
  43. ;
  44. NPAR    EQU    10    ;NUMBER OF ALLOWABLE PARAMETERS
  45. SUBDRV    EQU    1    ;MAKE 0 FOR DFLT, 1,2,3,ETC FOR A,B,C
  46. QUIET    EQU    FALSE    ;SET TO TRUE TO ELIMATE SIGN-ON MSG
  47. CPBASE    EQU    0    ;SET TO 4200H FOR HEATH CP/M
  48. ;
  49. ;
  50. ;
  51. ;************************************************************
  52. ;
  53. ; CP/M DEFINITIONS
  54. ;
  55. FPCHAR    EQU    2    ;PRINT CHAR FUNCTION
  56. PRINTF    EQU    9    ;PRINT STRING FUNCTION
  57. RDBUF    EQU    10    ;READ CONSOLE BUFFER
  58. OPENF    EQU    15    ;OPEN FILE FUNCTION
  59. CLOSEF    EQU    16    ;CLOSE FILE FUNCTION
  60. DELETF    EQU    19    ;DELETE FILE FUNCTION
  61. READF    EQU    20    ;READ RECORD FUNCTION
  62. WRITEF    EQU    21    ;WRITE RECORD FUNCTION
  63. MAKEF    EQU    22    ;MAKE (CREATE) FILE FUNCTION
  64. ;
  65. BDOS    EQU    CPBASE+5
  66. ;
  67. FCB    EQU    5CH    ;DEFAULT FILE CONTROL BLOCK
  68. FCBRC    EQU    15    ;FCB OFFSET TO RECORD COUNT
  69. FCBNR    EQU    32    ;FCB OFFSET TO NEXT RECORD
  70. FN    EQU    1    ;FCB OFFSET TO FILE NAME
  71. FT    EQU    9    ;FCB OFFSET TO FILE TYPE
  72. TBUF    EQU    CPBASE+80H  ;DEFAULT BUFFER
  73. TPA    EQU    CPBASE+100H ;TRANSIENT PROGRAM AREA
  74. ;
  75. PUTCNT    EQU    TBUF    ;COUNTER FOR OUTPUT CHARS
  76. ;
  77. ; DEFINE SOME TEXT CHARACTERS
  78. ;
  79. CR    EQU    13    ;CARRIAGE RETURN
  80. LF    EQU    10    ;LINE FEED
  81. TAB    EQU    9
  82. ;
  83. ; START OF PROGRAM CODE
  84. ;
  85.     ORG    TPA
  86. ;
  87. ;    GET THE BALL ROLLING
  88. ;
  89. SUBMIT: LXI    H,0    ;SAVE STACK IN CASE
  90.     DAD    SP    ;  ONLY HELP REQUESTED
  91.     SHLD    SPSAVE    ;(NOT OTHERWISE USED)
  92.     LXI    SP,STACK
  93.     CALL    START
  94. ;
  95. ; SIGN ON MESSAGE
  96. ;
  97.     IF    NOT QUIET
  98.     DB    'SuperSUB V1.1'
  99.     ENDIF
  100. ;
  101.     DB    CR,LF,'$' ;NEWLINE EVEN IF QUIET
  102. ;
  103. START:    
  104.         POP    D    ;RETRIEVE STRING POINTER
  105.     MVI    C,PRINTF
  106.     LDA    FCB+1    ;ANYTHING ON CMD LINE?
  107.     CPI    ' '
  108.     JZ    HELP    ;NO, GO PRINT HELP
  109.     CALL    BDOS    ;PRINT THE SIGN-ON
  110.     CALL    INITVAR ;INITIALIZE THE VARIABLE AREA
  111.     CALL    GETPAR    ;GET COMMAND LINE PARAMETERS
  112.     CALL    SETUP    ;SET UP READ OF SUBMIT FILE
  113.     CALL    RDFILE    ;READ THE SUBMIT FILE
  114.     CALL    WRSET    ;SET UP WRITE OF "$$$.SUB"
  115.     CALL    WRSUB    ;WRITE "$$$.SUB"
  116.     JMP    CPBASE    ;GO START THE SUBMIT
  117. ;
  118. ;
  119. ; SETUP SETS UP THE FILE CONTROL BLOCK
  120. ; FOR READING IN THE .SUB TEXT FILE
  121. ;
  122. SETUP:    LXI    H,FCB+FT ;LOOK AT FIRST CHAR OF
  123.     MOV    A,M    ;   FILE TYPE.    IF IT IS
  124.     CPI    ' '    ;   BLANK, THEN GO MOVE
  125.     JZ    PUTSUB    ;   "SUB" INTO FT FIELD
  126.     LXI    D,SUBTYP ;IT'S NOT BLANK SO MAKE
  127.     MVI    B,3    ;   SURE IT'S ALREADY
  128.     CALL    COMPAR    ;   "SUB"
  129.     JNZ    NOTFND    ;IF NOT, IT'S AN ERROR
  130.     RET
  131. ;
  132. ; MOVE "SUB" INTO THE FILE TYPE
  133. ;
  134. PUTSUB: XCHG         ;BY CONVENTION, MOVE FROM
  135.     LXI    H,SUBTYP ; @HL TO @DE
  136.     MVI    B,3
  137.     CALL    MOVE
  138.     RET
  139. ;
  140. ; MOVE # BYTES IN B REGISTER FROM @HL TO @DE
  141. ;
  142. MOVE:    MOV    A,M    ;PICK UP
  143.     STAX    D    ;PUT DOWN
  144.     INX    H    ;I'M SURE
  145.     INX    D    ; YOU'VE SEEN THIS
  146.     DCR    B    ; BEFORE...
  147.     JNZ    MOVE    ;100 TIMES AT LEAST
  148.     RET        ;I KNOW I HAVE!
  149. ;
  150. ; GETPAR MOVES THE SUBSTITUTION PARAMETERS SPECIFIED
  151. ; IN THE COMMAND LINE INTO MEMORY, AND STORES THEIR
  152. ; ADDRESSES IN THE PARAMETER TABLE.  THIS ALLOWS
  153. ; SUBSTITUTION OF $1, $2, ETC., IN THE SUBMIT COMMANDS
  154. ; WITH THEIR ACTUAL VALUES SPECIFED IN THE COMMAND
  155. ; LINE.
  156. ;
  157. GETPAR: LXI    H,TBUF+1 ;WHERE WE FIND THE COMMAND TAIL
  158.     CALL    SCANTO     ;SKIP SUBMIT FILE NAME
  159.     STA    OPTION     ;FIRST CHAR OF CMD LINE IS OPTION
  160.     RC         ;LINE ENDED?
  161.     CPI    '/'     ;NO, CHECK OPTION
  162.     JNZ    GLP0     ;NOT KEYBOARD INP, READ FILE
  163.     INX    H     ;POINT PAST '/'
  164. SLSCAN: SHLD    CLPTR     ;SAVE CMD LINE PTR
  165.     MOV    A,M     ;KBD IS SOURCE, GET EOL FLAG
  166.     STA    CLFLAG     ;SAVE AS EOL FLAG
  167.     CPI    ' '     ;ALLOW SPACES AFTER '/'
  168.     RNZ         ;GOT NON-BLANK, DONE
  169.     INX    H     ;ELSE CONTINUE SCAN
  170.     JMP    SLSCAN
  171. GLP0:    MOV    A,M     ;INPUT IS FROM A .SUB FILE..THIS
  172.     INX    H     ;  CODE SKIPS OVER THE NAME OF
  173.     ORA    A     ;  THE SUB FILE TO GET TO THE
  174.     RZ         ;  COMMAND LINE PARAMETERS
  175.     CPI    ' '
  176.     JZ    GLP
  177.     CPI    TAB
  178.     JNZ    GLP0
  179. GLP:    CALL    SCANTO    ;PASS UP THE BLANKS
  180.     RC        ;CY RETURNED IF END OF CMD LINE
  181.     CALL    PUTPAR    ;NOW PUT THE PARAMETER INTO MEM
  182.     RC        ;CY RETURNED IF END OF CMD LINE
  183.     JMP    GLP    ;GET THEM ALL
  184. ;
  185. ; SCANTO SCANS PAST BLANKS TO THE FIRST NON-BLANK. IF
  186. ; END OF COMMAND LINE FOUND, RETURNS CARRY SET.
  187. ;
  188. SCANTO: MOV    A,M
  189.     INX    H
  190.     ORA    A    ;SET FLAGS ON ZERO
  191.     STC        ;IN CASE ZERO FOUND (END OF CMD LIN)
  192.     RZ
  193.     CPI    ' '
  194.     JZ    SCANTO    ;SCAN PAST BLANKS
  195.     CPI    TAB    ;DO TABS TOO, JUST FOR
  196.     JZ    SCANTO    ;  GOOD MEASURE
  197.     DCX    H    ;FOUND CHAR, POINT BACK TO IT
  198.     ORA    A    ;INSURE CARRY CLEAR
  199.     RET
  200. ;
  201. ; PUTPAR PUTS THE PARAMETER POINTED TO BY HL INTO
  202. ; MEMORY POINTED TO BY "TXTPTR".  ALSO STORES THE
  203. ; ADDRESS OF THE PARAMETER INTO THE PARAMETER TABLE
  204. ; FOR EASY ACCESS LATER, WHEN WE WRITE $$$.SUB
  205. ;
  206. PUTPAR: PUSH    H    ;SAVE POINTER TO PARM
  207.     LHLD    TXTPTR    ;NEXT FREE MEMORY
  208.     XCHG        ;  INTO DE
  209.     LHLD    TBLPTR    ;NEXT FREE AREA OF TABLE
  210.     MOV    A,M    ;NON-ZERO IN TABLE
  211.     ORA    A    ; INDICATES TABLE
  212.     JNZ    PAROVF    ; TABLE OVERFLOW (TOO MANY PARMS)
  213.     MOV    M,E    ;STORE THE PARM ADRS
  214.     INX    H
  215.     MOV    M,D
  216.     INX    H
  217.     SHLD    TBLPTR    ;SAVE TABLE PNTR FOR NEXT TIME
  218.     POP    H    ;GET BACK PARM POINTER
  219.     PUSH    D    ;SAVE FREE MEM POINTER BECAUSE
  220.             ;  WE WILL HAVE TO HAVE IT BACK
  221.             ;  LATER TO STORE THE LENGTH
  222.     INX    D    ;POINT PAST LENGTH STORAGE
  223.     MVI    B,0    ;INITIALIZE LENGTH OF PARM
  224. PPLP:    MOV    A,M    ;GET NEXT BYTE OF PARM
  225.     INX    H
  226.     ORA    A    ;TEST FOR END OF CMD LINE
  227.     JZ    PP2    ;JUMP IF END
  228.     CPI    ' '    ;TEST FOR END OF COMMAND
  229.     JZ    PP2
  230.     CPI    TAB    ;TAB ALSO ENDS COMMAND
  231.     JZ    PP2
  232.     STAX    D    ;PUT PARAMETER BYTE-BY-BYTE
  233.     INX    D    ;INTO FREE MEMORY
  234.     INR    B    ;BUMP LENGTH
  235.     JMP    PPLP
  236. PP2:    XCHG
  237.     SHLD    TXTPTR    ;NEW FREE MEMORY POINTER
  238.     POP    H    ;REMEMBER OUR LENGTH POINTER?
  239.     MOV    M,B    ;STORE THE LENGTH
  240.     XCHG        ;HAVE TO RETN HL > CMD LINE
  241.     ORA    A    ;NOW RETURN END OF LINE FLAG
  242.     STC
  243.     RZ        ;RETURN CY IF ZERO (EOL MARK)
  244.     CMC
  245.     RET
  246. ;
  247. ;    RDFILE READS THE .SUB FILE SPECIFIED
  248. ;    IN THE SUBMIT COMMAND INTO MEMORY
  249. ;
  250. RDFILE: LXI    H,0    ;INIT LINE NUMBER
  251.     SHLD    LINNUM
  252.     LDA    OPTION    ;USING A FILE?
  253.     CPI    '/'    ;'/' OPTION TELLS
  254.     JZ    LINE    ;JUMP IF NOT
  255.     LXI    D,FCB    ;WE ARE, OPEN IT
  256.     MVI    C,OPENF
  257.     CALL    BDOS
  258.     INR    A    ;IF 0FFH RETURNED,
  259.     JZ    NOTFND    ;  THEN FILE NOT FOUND
  260. LINE:    LHLD    LINNUM    ;BUMP LINE NUMBER
  261.     INX    H
  262.     SHLD    LINNUM
  263.     LHLD    PREV    ;GET PREV PREVIOUS LINE POINTER
  264.     XCHG
  265.     LHLD    TXTPTR    ;GET CURRENT FREE MEM POINTER
  266.     SHLD    PREV    ;MAKE IT THE PREV LINE (FOR NXT PASS)
  267.     MOV    M,E    ;STORE AT BEGIN OF CURRENT LINE,
  268.     INX    H    ;  A POINTER TO THE PREVIOUS
  269.     MOV    M,D
  270.     INX    H
  271.     PUSH    H    ;LATER WE WILL PUT LENGTH HERE
  272.     INX    H    ;SKIP PAST LENGTH
  273.     MVI    C,0    ;INITIALIZE LENGTH TO ZERO
  274. LLP:    CALL    GNB    ;GET NEXT BYTE FROM INPUT SOURCE
  275.     JC    EOF    ;CY SET IF END OF FILE FOUND
  276.     CALL    UCASE    ;CONVERT TO UPPER CASE
  277.     CPI    1AH    ;SEE IF CPM END OF FILE INDICATOR
  278.     JZ    EOF
  279.     CPI    LF    ;IGNORE LINEFEEDS
  280.     JZ    LLP
  281.     CPI    CR    ;IF IT'S A CARRIAGE RETURN,
  282.     JZ    EOL    ;  THEN DO END OF LINE
  283.     MOV    M,A    ;STORE ALL OTHERS INTO MEMORY
  284.     INX    H
  285.     CALL    SIZE    ;MAKE SURE NO MEMORY OVERFLOW
  286.     INR    C    ;BUMP CHAR COUNT
  287.     JM    LENERR    ;MAX OF 128 CHARS PER LINE
  288.     JMP    LLP    ;GO DO NEXT CHAR
  289. ;
  290. ;    DO END OF LINE SEQUENCE
  291. ;
  292. EOL:    SHLD    TXTPTR    ;SAVE FREE MEMORY POINTER
  293.     POP    H    ;CURRENT LINE'S LENGTH POINTER
  294.     MOV    M,C    ;STORE LENGTH AWAY
  295.     JMP    LINE    ;GO DO NEXT LINE
  296. ;
  297. ;    END OF TEXT FILE
  298. ;
  299. EOF:    SHLD    TXTPTR    ;SAVE FREE MEMORY POINTER
  300.     POP    H    ;CURRENT LINE'S LENGTH POINTER
  301.     MOV    M,C    ;STORE LENGTH AWAY
  302.     RET        ;ALL DONE READING SUB FILE
  303. ;
  304. ;    GET NEXT BYTE FROM INPUT FILE
  305. ;
  306. GNB:    PUSH    H    ;DON'T ALTER ANYBODY
  307.     PUSH    D
  308.     PUSH    B
  309.     LDA    OPTION    ;INPUT FROM .SUB FILE?
  310.     CPI    '/'    ;TOLD BY ORIG CMD LINE OPTION
  311.     JNZ    NSLASH    ;JUMP IF WE ARE
  312.     CALL    GNBKBD    ;NO, GET A BYTE FROM KBD INPUT
  313.     JMP    GNBXIT    ;THEN LEAVE
  314. NSLASH: LDA    IBP    ;GET BUFFER POINTER
  315.     ORA    A    ;PAST END?
  316.     CM    FILL    ;WRAPPED AROUND
  317.     JNC    GNB1    ;NO END OF FILE
  318.     MVI    A,1AH    ;FAKE EOF
  319. GNB1:    MOV    E,A    ;PUT IN DE
  320.     MVI    D,0
  321.     INR    A    ;POINT TO NEXT
  322.     STA    IBP    ;PUT AWAY
  323.     LXI    H,TBUF    ;NOW OFFSET INTO BUFR
  324.     DAD    D
  325.     MOV    A,M    ;GET CHAR THERE
  326. GNBXIT: POP    B    ;RESTORE EVERYBODY
  327.     POP    D
  328.     POP    H
  329.     ORA    A    ;TURN ON CARRY
  330.     RET
  331. ;
  332. ;    FILL INPUT BUFFER
  333. ;
  334. FILL:    MVI    C,READF
  335.     LXI    D,FCB
  336.     CALL    BDOS
  337.     ORA    A    ;GOT GOOD READ?
  338.     MVI    A,0    ;(NEW BUF PTR)
  339.     STC
  340.     RNZ        ;RETN CY=EOF
  341.     CMC        ;NO EOF, NO CY
  342.     RET
  343. ;
  344. ; COME HERE TO GET A .SUB CHARACTER WHEN
  345. ; WE'RE NOT USING A .SUB FILE ("/" OPTION)
  346. ;
  347. GNBKBD: LDA    CLFLAG    ;USE CP/M CMD LINE?
  348.     ORA    A
  349.     JNZ    GNBCL    ;THEN GO DO IT
  350.     LDA    CLCNT    ;NOT, CHECK LOCAL
  351.     ORA    A    ;  CMD LINE CHAR COUNT
  352.     CM    CLFILL    ;REFILL WHEN IT WRAPS BACK
  353.     JC    GKEND    ;GOT CARRY (FROM CLFILL), RETURN EOF
  354.     DCR    A    ;COUNT DOWN
  355.     STA    CLCNT
  356.     JP    GNBCL    ;IF PLUS, BUFFER NOT EMPTY
  357.     MVI    A,CR    ;OUT OF CHARS, RETURN A CR
  358.     RET
  359. GKEND:    MVI    A,1AH    ;RETURN EOF
  360.     RET
  361. ;
  362. ; GET NEXT BYTE OF INPUT FROM CMD LINE @CLPTR
  363. ;
  364. GNBCL:    LHLD    CLPTR    ;LOAD THE POINTER
  365.     MOV    A,M    ;GET THE CHAR
  366.     INX    H    ;BUMP POINTER FOR NEXT TIME
  367.     SHLD    CLPTR
  368.     CPI    ';'    ;LOGICAL END-OF-LINE?
  369.     JNZ    NSEMI    ;JUMP IF NOT
  370.     MVI    A,CR    ;YES, TRANSLATE IT
  371.     RET
  372. NSEMI:    ORA    A    ;PHYSICAL END-OF-LINE
  373.     RNZ        ;THIS ONLY NEEDED WHEN INPUT
  374.             ;  SOURCE IS ORIG CPM CMD LINE
  375.     MVI    A,1AH    ;TRANSLATE THAT TO END OF FILE
  376.     RET
  377. ;
  378. ; SUBROUTINE TO RE-FILL THE LOCAL COMMAND LINE
  379. ;
  380. CLFILL: LXI    D,PROMPT ;PRINT A PROMPT
  381.     MVI    C,PRINTF ;USE CP/M FUNCT 9
  382.     CALL    BDOS
  383.     LXI    D,CLBUF  ;NOW FILL THE BUFFER
  384.     MVI    C,RDBUF
  385.     CALL    BDOS
  386.     LDA    CLCNT     ;RETURN WITH COUNT IN A
  387.     LXI    H,CLTEXT ;RESET THE CMD LINE POINTER
  388.     SHLD    CLPTR
  389.     ORA    A     ;SET CY ON LEN NZ
  390.     STC
  391.     RZ
  392.     CMC
  393.     RET
  394. ;
  395. ;    MAKE SURE NO MEMORY OVERFLOW
  396. ;
  397. SIZE:    LDA    BDOS+2    ;HIGHEST PAGE POINTER
  398.     DCR    A    ;MAKE IT BE UNDER BDOS
  399.     CMP    H    ;CHECK IT AGAINST CURRENT PAGE
  400.     RNC        ;NC=ALL OKAY
  401.     JMP    MEMERR    ;OTHERWISE ABORT
  402. ;
  403. ;    SET UP THE $$$.SUB FILE
  404. ;    FOR WRITING
  405. ;
  406. WRSET:    CALL    ISMPM   ;ADDED BY GAG TO CHECK FOR MP/M OPERATING SYSTEM
  407.         LXI    D,SUBFCB
  408.           MVI    C,OPENF
  409.     CALL    BDOS    ;OPEN THE FILE
  410.     INR    A    ;CHECK CPM RETURN
  411.     JZ    NONE1    ;NONE EXISTS ALREADY
  412. ;
  413. ;    $$$.SUB EXISTS, SO SET
  414. ;    FCB TO APPEND TO IT
  415. ;
  416.     LDA    SUBFCB+FCBRC ;GET RECORD COUNT
  417.     STA    SUBFCB+FCBNR ;MAKE NEXT RECORD
  418.     RET
  419. ;
  420. ;    COME HERE WHEN NO $$$.SUB EXISTS
  421. ;
  422. NONE1:    LXI    D,SUBFCB
  423.     MVI    C,MAKEF
  424.     CALL    BDOS
  425.     INR    A
  426.     JZ    NOMAKE    ;0FFH=CAN'T CREATE FILE
  427.     RET
  428. ;
  429. ;    WRITE THE "$$$.SUB" FILE
  430. ;
  431. WRSUB:    LHLD    PREV    ;THIS CODE SCANS BACKWARD
  432.     MOV    A,H    ;  THRU THE FILE STORED IN
  433.     ORA    L    ;  MEMORY TO THE FIRST NON-
  434.     JZ    NOTEXT    ;  NULL LINE.  IF NONE IS
  435.     MOV    E,M    ;  FOUND, ABORTS
  436.     INX    H
  437.     MOV    D,M    ;HERE, WE PICK UP PNTR TO PREV LINE
  438.     INX    H    ;NOW WE POINT TO LENGTH
  439.     XCHG        ;WE NEED TO STORE AWAY
  440.     SHLD    PREV    ;  POINTER TO PREV LINE
  441.     XCHG
  442.     MOV    A,M    ;NOW PICK UP THE LENGTH
  443.     ORA    A    ;SET Z FLAG ON LENGTH
  444.     JNZ    WRNTRY    ;GOT LINE W/LENGTH: GO DO IT
  445.     LHLD    LINNUM    ;NOTHING HERE, FIX LINE NUMBER
  446.     DCX    H    ;(WORKING BACKWARD NOW)
  447.     SHLD    LINNUM
  448.     JMP    WRSUB
  449. WRLOP:    LHLD    PREV    ;GET PREV LINE POINTER
  450.     MOV    A,H
  451.     ORA    L    ;IF THERE IS NO PREV LINE
  452.     JZ    CLOSE    ;  THEN WE ARE DONE
  453.     MOV    E,M    ;ELSE SET UP PREV FOR NEXT
  454.     INX    H    ;  PASS THRU HERE
  455.     MOV    D,M
  456.     INX    H
  457.     XCHG        ;NOW STORE IT AWAY
  458.     SHLD    PREV
  459.     XCHG
  460. WRNTRY: CALL    PUTLIN    ;WRITE THE LINE TO THE FILE
  461.     LHLD    LINNUM    ;BUMP THE LINE NUMBER
  462.     DCX    H    ;DOWN (WORKING BACK NOW)
  463.     SHLD    LINNUM
  464.     JMP    WRLOP
  465. ;
  466. ;    $$$.SUB IS WRITTEN, CLOSE THE FILE
  467. ;
  468. CLOSE:    LXI    D,SUBFCB
  469.     MVI    C,CLOSEF
  470.     JMP    BDOS
  471. ;
  472. ;    THIS SUBROUTINE WRITES A LINE
  473. ;    TO THE $$$.SUB FILE BUFFER,
  474. ;    AND FLUSHES THE BUFFER AFTER
  475. ;    THE LINE IS WRITTEN.
  476. ;
  477. PUTLIN: MOV    A,M    ;PICK UP LENGTH BYTE
  478.     INX    H    ;POINT PAST IT
  479.     STA    GETCNT    ;MAKE A COUNT FOR "GET"
  480.     SHLD    GETPTR    ;MAKE A POINTER FOR "GET"
  481.     LXI    H,TBUF+1;TEXT GOES AFTER LENGTH
  482.     SHLD    PUTPTR    ;MAKE POINTER FOR "PUT"
  483.     XRA    A    ;INITIALIZE PUT COUNT
  484.     STA    PUTCNT
  485.     MOV    B,L    ;COUNT FOR CLEAR LOOP
  486. CLR:    MOV    M,A    ;ZERO OUT BUFFER LOC
  487.     INX    H
  488.     INR    B    ;COUNT
  489.     JNZ    CLR
  490. ;
  491. ;    THIS LOOP COLLECTS CHARACTERS
  492. ;    FROM THE LINE STORED IN MEMORY
  493. ;    AND WRITES THEM TO THE FILE.
  494. ;    IF THE "$" PARAMETER SPECIFIER
  495. ;    IS ENCOUNTERED, PARAMETER SUB-
  496. ;    STITUTION IS DONE
  497. ;
  498. PUTLP:    CALL    GETCHR    ;PICK UP A CHARACTER
  499.     JC    FLUSH    ;CY = NO MORE CHAR IN LINE
  500.     CPI    '^'    ;CONTROL-CHAR TRANSLATE PREFIX?
  501.     JNZ    NOTCX
  502.     CALL    GETCHR    ;YES, GET THE NEXT
  503.     JC    CCERR    ;ERROR: EARLY END OF INPUT
  504.     SUI    '@'    ;MAKE IT A CONTROL-CHAR
  505.     JC    CCERR    ;ERROR: TOO SMALL
  506.     CPI    ' '
  507.     JNC    CCERR    ;ERROR: TOO LARGE
  508. NOTCX:    CPI    '$'    ;PARAMETER SPECIFIER?
  509.     JNZ    STOBYT    ;IF NOT, JUST WRITE CHAR
  510.     LDA    OPTION    ;CHECK OPTION: '$' DOESN'T
  511.     CPI    '/'    ;  COUNT IN '/' MODE
  512.     MVI    A,'$'    ;(RESTORE THE '$')
  513.     JZ    STOBYT
  514.     CALL    LKAHED    ;PEEK AT NEXT CHAR
  515.     JC    PARERR    ;LINE ENDING MEANS PARAM ERR
  516.     CPI    '$'    ;ANOTHER "$"?
  517.     JNZ    SUBS    ;IF NOT THEN GO DO SUBSTITUTION
  518.     CALL    GETCHR    ;GET THE 2ND "$" (WE ONLY LOOKED
  519.             ;  AHEAD BEFORE)
  520. STOBYT: CALL    PUTCHR    ;WRITE CHAR TO FILE
  521.     JMP    PUTLP
  522. ;
  523. ;    PARAMETER SUBSTITUTION...LOOKS UP THE
  524. ;    PARAMETER # AFTER THE "$" AND PLUGS IT
  525. ;    IN IF IT EXISTS.
  526. ;
  527. SUBS:    CALL    NUMTST    ;IT BETTER BE A NUMBER
  528.     JC    PARERR    ;  OTHERWISE PARAM ERROR
  529.     MVI    B,0    ;INITIALIZE PARM #
  530.     JMP    LPNTRY    ;WE JOIN LOOP IN PROGRESS...
  531. SUBLP:    CALL    LKAHED    ;LOOK AT NEXT CHAR
  532.     JC    DOSUBS    ;IF LINE EMPTY, THEN PLUG IN PARM
  533.     CALL    NUMTST    ;CHECK FOR NUMERIC
  534.     JC    DOSUBS    ;DONE IF NOT
  535. LPNTRY: CALL    GETCHR    ;NOW REMOVE THE CHAR FROM INPUT STREAM
  536.     SUI    '0'    ;REMOVE ASCII BIAS
  537.     MOV    C,A    ;SAVE IT
  538.     MOV    A,B    ;OUR ACCUMULATED COUNT
  539.     ADD    A    ;MULTIPLY  BY TEN
  540.     ADD    A
  541.     ADD    B
  542.     ADD    A
  543.     ADD    C    ;THEN ADD IN NEW DIGIT
  544.     MOV    B,A    ;RESTORE COUNT
  545.     JMP    SUBLP
  546. ;
  547. ;    PERFORM THE SUBSTITUTION
  548. ;
  549. DOSUBS: MOV    A,B    ;GET PARM #
  550.     DCR    A    ;MAKE ZERO RELATIVE
  551.     JM    PARERR    ;OOPS
  552.     CALL    LOOKUP    ;LOOK IT UP IN PARM TABLE
  553.     JC    PARERR    ;IT'S NOT THERE
  554.     MOV    B,A    ;LENGTH IN B
  555. SUBLP1: INR    B    ;TEST B FOR ZERO
  556.     DCR    B
  557.     JZ    PUTLP    ;DONE
  558.     MOV    A,M    ;GET CHAR OF REAL PARAMETER
  559.     INX    H    ;POINT PAST FOR NEXT TIME
  560.     PUSH    H    ;SAVE REAL PARM POINTER
  561.     CALL    PUTCHR    ;PUT IT IN THE FILE
  562.     POP    H    ;GET BACK REAL PARM POINTER
  563.     DCR    B    ;COUNTDOWN
  564.     JMP    SUBLP1
  565. ;
  566. ;    COME HERE WHEN A LINE IS FINISHED,
  567. ;    AND WE NEED TO WRITE THE BUFFER TO DISK
  568. ;
  569. FLUSH:    LXI    D,SUBFCB
  570.     MVI    C,WRITEF
  571.     CALL    BDOS
  572.     ORA    A
  573.     JNZ    WRERR    ;CPM RETURNED A WRITE ERROR
  574.     RET
  575. ;
  576. ;    GETCHR GETS ONE CHAR FROM
  577. ;    LINE STORED IN MEMORY
  578. ;
  579. GETCHR: LXI    H,GETCNT
  580.     MOV    A,M    ;PICK UP COUNT
  581.     DCR    A    ;REMOVE THIS CHAR
  582.     STC        ;PRESET ERROR
  583.     RM        ;RETURN CY IF OUT OF CHARS
  584.     MOV    M,A    ;UPDATE COUNT
  585.     LHLD    GETPTR    ;CURRENT CHAR POINTER
  586.     MOV    A,M    ;PICK UP CHAR
  587.     INX    H    ;BUMP POINTER
  588.     SHLD    GETPTR    ;PUT IT BACK
  589.     CMC        ;TURN CARRY OFF
  590.     RET
  591. ;
  592. ;    PUTCHR PUTS ONE CHAR TO
  593. ;    THE OUTPUT BUFFER
  594. ;
  595. PUTCHR: LXI    H,PUTCNT
  596.     INR    M    ;INCREMENT COUNT
  597.     JM    LENERR    ;LINE WENT TO > 128 CHARS
  598.     LHLD    PUTPTR    ;GET BUFFER POINTER
  599.     MOV    M,A    ;PUT CHAR THERE
  600.     INX    H    ;BUMP POINTER
  601.     SHLD    PUTPTR    ;PUT IT BACK
  602.     RET        ;ALL DONE
  603. ;
  604. ;    LOOK AHEAD ONE CHAR IN
  605. ;    THE INPUT STREAM.  SET
  606. ;    CARRY IF NONE LEFT.
  607. ;
  608. LKAHED: LDA    GETCNT
  609.     ORA    A    ;SEE IF COUNT IS DOWN TO ZERO
  610.     STC        ;PRE SET INDICATOR
  611.     RZ
  612.     MOV    A,M    ;PICK UP CHAR
  613.     CMC        ;TURN OFF CARRY FLAG
  614.     RET
  615. ;
  616. ;    LOOK UP PARAMETER WITH NUMBER IN
  617. ;    A REG. RETURN A=LENGTH OF PARM,
  618. ;    AND HL => PARAMETER
  619. ;
  620. LOOKUP: CPI    NPAR
  621.     JNC    PAROVF    ;PARM # TOO HIGH
  622.     MOV    L,A
  623.     MVI    H,0    ;NOW HAVE 16 BIT NUMBER
  624.     DAD    H    ;DOUBLE FOR WORD OFFSET
  625.     LXI    D,TABLE
  626.     DAD    D    ;DO THE OFFSET
  627.     MOV    E,M    ;GET ADDRESS OF PARM
  628.     INX    H
  629.     MOV    D,M
  630.     MOV    A,D    ;ANYTHING THERE?
  631.     ORA    E
  632.     JNZ    LKUPOK
  633.     XRA    A    ;NO, ZERO LENGTH
  634.     RET
  635. LKUPOK: XCHG        ;NOW IN DE
  636.     MOV    A,M    ;PICK UP LENGTH
  637.     INX    H    ;POINT PAST LENGTH
  638.     RET
  639. ;
  640. ;    UTILITY COMPARE SUBROUTINE
  641. ;
  642. COMPAR: LDAX    D
  643.     CMP    M
  644.     RNZ
  645.     INX    H
  646.     INX    D
  647.     DCR    B
  648.     JNZ    COMPAR
  649.     RET
  650. ;
  651. ;    NUMERIC TEST UTILITY SUBROUTINE
  652. ;
  653. NUMTST: CPI    '0'
  654.     RC
  655.     CPI    '9'+1
  656.     CMC
  657.     RET
  658. ;
  659. ;DECIMAL OUTPUT ROUTINE
  660. ;
  661. DECOUT: PUSH    B
  662.     PUSH    D
  663.     PUSH    H
  664.     LXI    B,-10
  665.     LXI    D,-1
  666. ;
  667. DECOU2: DAD    B
  668.     INX    D
  669.     JC    DECOU2
  670.     LXI    B,10
  671.     DAD    B
  672.     XCHG
  673.     MOV    A,H
  674.     ORA    L
  675.     CNZ    DECOUT
  676.     MOV    A,E
  677.     ADI    '0'
  678.     CALL    TYPE
  679.     POP    H
  680.     POP    D
  681.     POP    B
  682.     RET
  683. ;
  684. ; PRINT CR, LF ON CONSOLE
  685. ;
  686. CRLF:    MVI    A,CR
  687.     CALL    TYPE
  688.     MVI    A,LF
  689. ;
  690. ; PRINT CHAR IN A ON CONSOLE
  691. ;
  692. TYPE:    PUSH    H    ;SAVE REGS
  693.     PUSH    D
  694.     PUSH    B
  695.     MOV    E,A    ;PUT IN E FOR CP/M
  696.     MVI    C,FPCHAR
  697.     CALL    BDOS    ;PRINT IT
  698.     POP    B    ;RESTORE ALL
  699.     POP    D
  700.     POP    H
  701.     RET
  702. ;
  703. ; CONVERT CHAR IN A TO UPPER CASE
  704. ;
  705. UCASE:    CPI    'a'    ;VALIDATE CASE
  706.     RC
  707.     CPI    'z'+1
  708.     RNC
  709.     ANI    5FH    ;GOT LC, CONV TO UC
  710.     RET
  711. ;
  712. ;    ERROR HANDLERS
  713. ;
  714. WRERR:    CALL    ERRXIT
  715.     DB    'Disk full$'
  716. NOMAKE: CALL    ERRXIT
  717.     DB    'Directory full$'
  718. MEMERR: CALL    ERRXIT
  719.     DB    'Memory full$'
  720. NOTFND: CALL    ERRXIT
  721.     DB    'Submit file not found$'
  722. PARERR: CALL    ERRXIT
  723.     DB    'Parameter$'
  724. PAROVF: CALL    ERRXIT
  725.     DB    'Too many parameters:$'
  726. LENERR: CALL    ERRXIT
  727.     DB    'Line too long:$'
  728. NOTEXT: CALL    ERRXIT
  729.     DB    'Submit file empty$'
  730. CCERR:    CALL    ERRXIT
  731.     DB    'Control character$'
  732. ERRXIT: POP    D
  733.     MVI    C,PRINTF
  734.     CALL    BDOS
  735.     LXI    D,ERRMSG    ;PRINT 2ND HALF MSG
  736.     MVI    C,PRINTF
  737.     CALL    BDOS
  738.     LHLD    LINNUM        ;TELL LINE NUMBER
  739.     CALL    DECOUT
  740.     CALL    CRLF
  741.     LXI    D,SUBFCB    ;DELETE THE $$$.SUB FILE
  742.     MVI    C,DELETF
  743.     CALL    BDOS
  744.     JMP    CPBASE
  745. ;
  746. ERRMSG: DB    ' error on line number: $'
  747. ;
  748. ; PROMPT FOR COMMAND LINE INPUT
  749. ;
  750. PROMPT: DB    CR,LF,'*$'
  751. ;
  752. ;    INITIALIZE ALL VARIABLES
  753. ;
  754. INITVAR:
  755.     LXI    H,VAR
  756.     LXI    B,ENDVAR-VAR
  757. INITLP: MVI    M,0    ;ZERO ENTIRE VAR AREA
  758.     INX    H
  759.     DCX    B
  760.     MOV    A,B
  761.     ORA    C
  762.     JNZ    INITLP
  763.     LXI    H,TABLE ;INIT PARM TABLE POINTER
  764.     SHLD    TBLPTR
  765.     LXI    H,0FFFFH ;MARK END OF TABLE
  766.     SHLD    ENDTBL
  767.     LXI    H,FREMEM ;FREE MEMORY STARTS TXT AREA
  768.     SHLD    TXTPTR
  769.     MVI    A,80H    ;FORCE READ
  770.     STA    IBP
  771.     STA    CLCNT    ;FORCE CONSOLE READ
  772.     RET
  773.  
  774. ;THIS ROUTINE CHECKS FOR MP/M OPERATING SYSTEM. IF IT'S CP/M THEN IT RETURNS
  775. ;IF ITS MP/M IT FINDS THE CONSOLE NO FROM THE SYSTEM AND INSERTS IT IN THE
  776. ;SECOND CHARACTER POSITION OF THE FILE TYPE IN THE FCB FOR THE SUBMIT FILE
  777. ;AND SETS A FLAG IN THE MP/M SYSTEM TO TELL IT THERE'S A SUBMIT FILE TO 
  778. ;EXECUTE WHEN THE NEXT WARM BOOT OCCURRS. GAG
  779.  
  780. ISMPM:    PUSH      PSW
  781.           PUSH      B
  782.           PUSH      D
  783.           PUSH      H
  784.           MVI       C,0CH          ;GET VERSION NUMBER IN HL
  785.           CALL      005H
  786.           XRA       A
  787.           CMP       H              ;IS IT CP/M?
  788.           JZ        RSET           ;ZERO MEANS CP/M. DON'T NEED ANYTHING ELSE
  789. MPM:      MVI       C,9AH          ;GET SYSTEM DATA ADDRESS IN HL
  790.           CALL      005H
  791.           LXI       D,80H
  792.           DAD       D              ;ADD 128 TO IT TO FIND SUBMIT FLAGS
  793.           PUSH      H              ;SAVE POINTER TO SUBMIT FLAGS
  794.           MVI       C,99H          ;GET CONSOLE NUMBER IN A
  795.           CALL      005H
  796.           MVI       D,0
  797.           MOV       E,A            ;DE = A
  798.           ADI       30H            ;PUT ASCII OF CONSOLE NO IN FCB
  799.           LXI       H,CONSOL       ;SECOND LETTER IN FILE TYPE IN FCB
  800.           MOV       M,A            ;PUT ASCII OF CONSOLE NO IN FCB
  801.           POP       H              ;RESTORE POINTER TO SUBMIT FLAGS
  802.           DAD       D              ;CONSOLE SUBMIT FLAG = PTR + CON NO.
  803.           MVI       M,0FFH         ;SET CON SUBMIT FLAG TO TRUE
  804. RSET:     POP       H              ;RETURN TO MAIN PROGRAM
  805.           POP       D
  806.           POP       B
  807.           POP       PSW
  808.           RET
  809. ;
  810. ; PRINT HELP WITH PROGRAM OPTIONS
  811. ;
  812. HELP:    LXI    D,HLPMSG ;PRINT THE HELP STUFF
  813.     MVI    C,PRINTF
  814.     CALL    BDOS
  815.     LHLD    SPSAVE     ;THEN RETURN W/NO WARM-BOOT
  816.     SPHL
  817.     RET
  818. ;
  819. HLPMSG: DB    CR,LF,'How to use SUPERSUB:',CR,LF
  820.     DB    CR,LF,'SUPERSUB<CR>            :print this HELP message'
  821.     DB    CR,LF,'SUPERSUB /<CR>          :go into interactive mode'
  822.     DB    CR,LF,'SUPERSUB /<cmd lines>   :use SUMMARY mode'
  823.     DB    CR,LF,'SUPERSUB <FILE> <PARMS> :as in standard SUBMIT.COM'
  824.     DB    CR,LF
  825.     DB    CR,LF,'In "/" (interactive) mode, SUPERSUB will prompt you'
  826.     DB    CR,LF,'a line at a time for the SUBMIT job input...logical'
  827.     DB    CR,LF,'lines may be combined on the same input line by sep-'
  828.     DB    CR,LF,'erating them with semicolons.  Example:'
  829.     DB    CR,LF,'  A>SUPERSUB /STAT;DIR'
  830.     DB    CR,LF,'specifies two commands on the same input line.',CR,LF
  831.     DB    CR,LF,'Submitted jobs may be nested...SUPERSUB does not erase'
  832.     DB    CR,LF,'any existing submit job (appends to them instead).'
  833.     DB    CR,LF
  834.     DB    CR,LF,'To insert a control character into the output, pre-'
  835.     DB    CR,LF,'fix it with a "^" (works in any mode).'
  836.     DB    CR,LF,'$'
  837. ;
  838. ;    VARIABLE STORAGE
  839. ;
  840. VAR    EQU    $
  841. ;
  842. TXTPTR: DW    0    ;FREE MEMORY POINTER
  843. TBLPTR: DW    0    ;POINTER TO PARM TABLE
  844. LINNUM: DW    0    ;CURRENT LINE NUMBER
  845. PREV:    DW    0    ;POINTER TO PREV LINE
  846. GETCNT: DB    0    ;COUNTER FOR 'GET'
  847. GETPTR: DW    0    ;POINTER FOR 'GET'
  848. PUTPTR: DW    0    ;POINTER FOR 'PUT'
  849. IBP:    DB    0    ;INPUT BUFFER POINTER
  850. CLPTR:    DW    0    ;COMMAND LINE POINTER
  851. CLFLAG: DB    0    ;USE CP/M CMD LINE FLAG
  852. OPTION: DB    0    ;'/' OPTION FLAG STORE
  853. TABLE:    DS    NPAR*3    ;PARAMETER TABLE
  854. ENDTBL: DW    0FFFFH    ;END OF PARAMETER TABLE
  855. ;
  856. ENDVAR    EQU    $
  857. ;
  858. ; COMMAND LINE BUFFER...NOT INITIALIZED
  859. ;
  860. CLBUF:    DB    128    ;BUFFER LENGTH
  861. CLCNT:    DB    0    ;CHARACTER COUNTER
  862. CLTEXT: DS    128    ;THE BUFFER ITSELF
  863. ;
  864. SPSAVE: DW    0    ;STACK POINTER SAVE
  865. ;
  866. ;
  867. ;    FCB FOR $$$.SUB
  868. ;
  869. SUBFCB: DB    SUBDRV     ;DRIVE SPECIFIER
  870.     DB    '$'
  871. CONSOL: DB      '$'      ; IF MPM THEN PUT ASCII OF CONSOLE NO HERE.
  872.         DB      '$     '
  873. SUBTYP: DB    'SUB'
  874.     DW    0,0,0,0  ;INITIALIZE REST OF FCB
  875.     DW    0,0,0,0
  876.     DW    0,0
  877. ;
  878. ;    STACK AREA
  879. ;
  880.     DS    200    ;WHY NOT?
  881. STACK    EQU    $
  882. FREMEM    EQU    $
  883. ;
  884.     END    SUBMIT
  885.