home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / a / autosub.lbr / AUTOSUB.AZM / AUTOSUB.ASM
Encoding:
Assembly Source File  |  1993-10-26  |  15.0 KB  |  699 lines

  1. ;
  2. ;    "AUTOSUB"    C.FLARITY    20-NOV-82
  3. ;
  4. ;    This program reads a SUBMIT "file" from memory
  5. ;    rather from disk, see SUBCOM. Can be renamed to
  6. ;    be AUTOST.COM.    
  7. ;    
  8. ;
  9. ;
  10. ;************************************************************
  11. ;
  12. ;        --  User customizable options --
  13. ;
  14. NPAR    EQU    10    ;NUMBER OF ALLOWABLE PARAMETERS
  15. SUBDRV    EQU    0    ;MAKE 0 FOR DFLT, 1,2,3,ETC FOR A,B,C
  16. ;
  17. ;
  18. ;
  19. ;************************************************************
  20. ;
  21. ; CP/M DEFINITIONS
  22. ;
  23. FPCHAR    EQU    2    ;PRINT CHAR FUNCTION
  24. PRINTF    EQU    9    ;PRINT STRING FUNCTION
  25. RDBUF    EQU    10    ;READ CONSOLE BUFFER
  26. OPENF    EQU    15    ;OPEN FILE FUNCTION
  27. CLOSEF    EQU    16    ;CLOSE FILE FUNCTION
  28. DELETF    EQU    19    ;DELETE FILE FUNCTION
  29. WRITEF    EQU    21    ;WRITE RECORD FUNCTION
  30. MAKEF    EQU    22    ;MAKE (CREATE) FILE FUNCTION
  31. ;
  32. BDOS    EQU    5
  33. ;
  34. FCB    EQU    5CH    ;DEFAULT FILE CONTROL BLOCK
  35. FCBRC    EQU    15    ;FCB OFFSET TO RECORD COUNT
  36. FCBNR    EQU    32    ;FCB OFFSET TO NEXT RECORD
  37. FN    EQU    1    ;FCB OFFSET TO FILE NAME
  38. FT    EQU    9    ;FCB OFFSET TO FILE TYPE
  39. TBUF    EQU    80H      ;DEFAULT BUFFER
  40. TPA    EQU    100H     ;TRANSIENT PROGRAM AREA
  41. ;
  42. PUTCNT    EQU    TBUF    ;COUNTER FOR OUTPUT CHARS
  43. ;
  44. ; DEFINE SOME TEXT CHARACTERS
  45. ;
  46. CR    EQU    13    ;CARRIAGE RETURN
  47. LF    EQU    10    ;LINE FEED
  48. TAB    EQU    9
  49. ;
  50. ; START OF PROGRAM CODE
  51. ;
  52.     ORG    TPA
  53.     JMP    START
  54. ;
  55. ;    SIGN-ON MESSAGE
  56. ;
  57. SIGNON    DB    1Ah    ;Clear screen
  58.     DB    LF,LF,LF,LF
  59.     DB    '   AUTOSUB FOR '
  60.     DB    'ADVENTURE -- SHANNON',CR,LF
  61.     DB    '$'    ;End of message.
  62. ;
  63. ;    SUBMIT THE FOLLOWING COMMANDS...
  64. ;
  65. SUBCOM:    DB    'XDIR',CR
  66.     DB    'ADVENT SHANNON',CR
  67.     DB    1Ah    ;End of SUBMIT commands
  68. ;
  69. ;    GET THE BALL ROLLING
  70. ;
  71. START:    LXI    SP,STACK
  72.     LXI    D,SIGNON
  73.     MVI    C,PRINTF
  74.     CALL    BDOS    ;PRINT THE SIGN-ON
  75.     CALL    INITVAR ;INITIALIZE THE VARIABLE AREA
  76.     CALL    GETPAR    ;GET COMMAND LINE PARAMETERS
  77.     CALL    RDFILE    ;READ THE SUBMIT FILE
  78.     CALL    WRSET    ;SET UP WRITE OF "$$$.SUB"
  79.     CALL    WRSUB    ;WRITE "$$$.SUB"
  80.     JMP    0    ;GO START THE SUBMIT
  81. ;
  82. ;
  83. ; MOVE # BYTES IN B REGISTER FROM @HL TO @DE
  84. ;
  85. MOVE:    MOV    A,M    ;PICK UP
  86.     STAX    D    ;PUT DOWN
  87.     INX    H    ;I'M SURE
  88.     INX    D    ; YOU'VE SEEN THIS
  89.     DCR    B    ; BEFORE...
  90.     JNZ    MOVE    ;100 TIMES AT LEAST
  91.     RET        ;I KNOW I HAVE!
  92. ;
  93. ; GETPAR MOVES THE SUBSTITUTION PARAMETERS SPECIFIED
  94. ; IN THE COMMAND LINE INTO MEMORY, AND STORES THEIR
  95. ; ADDRESSES IN THE PARAMETER TABLE.  THIS ALLOWS
  96. ; SUBSTITUTION OF $1, $2, ETC., IN THE SUBMIT COMMANDS
  97. ; WITH THEIR ACTUAL VALUES SPECIFED IN THE COMMAND
  98. ; LINE.
  99. ;
  100. GETPAR: LXI    H,TBUF+1 ;WHERE WE FIND THE COMMAND TAIL
  101. GLP:    CALL    SCANTO     ;SKIP SUBMIT FILE NAME
  102.     RC         ;LINE ENDED?
  103.     CALL    PUTPAR    ;NOW PUT THE PARAMETER INTO MEM
  104.     RC        ;CY RETURNED IF END OF CMD LINE
  105.     JMP    GLP    ;GET THEM ALL
  106. ;
  107. ; SCANTO SCANS PAST BLANKS TO THE FIRST NON-BLANK. IF
  108. ; END OF COMMAND LINE FOUND, RETURNS CARRY SET.
  109. ;
  110. SCANTO: MOV    A,M
  111.     INX    H
  112.     ORA    A    ;SET FLAGS ON ZERO
  113.     STC        ;IN CASE ZERO FOUND (END OF CMD LIN)
  114.     RZ
  115.     CPI    ' '
  116.     JZ    SCANTO    ;SCAN PAST BLANKS
  117.     CPI    TAB    ;DO TABS TOO, JUST FOR
  118.     JZ    SCANTO    ;  GOOD MEASURE
  119.     DCX    H    ;FOUND CHAR, POINT BACK TO IT
  120.     ORA    A    ;INSURE CARRY CLEAR
  121.     RET
  122. ;
  123. ; PUTPAR PUTS THE PARAMETER POINTED TO BY HL INTO
  124. ; MEMORY POINTED TO BY "TXTPTR".  ALSO STORES THE
  125. ; ADDRESS OF THE PARAMETER INTO THE PARAMETER TABLE
  126. ; FOR EASY ACCESS LATER, WHEN WE WRITE $$$.SUB
  127. ;
  128. PUTPAR: PUSH    H    ;SAVE POINTER TO PARM
  129.     LHLD    TXTPTR    ;NEXT FREE MEMORY
  130.     XCHG        ;  INTO DE
  131.     LHLD    TBLPTR    ;NEXT FREE AREA OF TABLE
  132.     MOV    A,M    ;NON-ZERO IN TABLE
  133.     ORA    A    ; INDICATES TABLE
  134.     JNZ    PAROVF    ; TABLE OVERFLOW (TOO MANY PARMS)
  135.     MOV    M,E    ;STORE THE PARM ADRS
  136.     INX    H
  137.     MOV    M,D
  138.     INX    H
  139.     SHLD    TBLPTR    ;SAVE TABLE PNTR FOR NEXT TIME
  140.     POP    H    ;GET BACK PARM POINTER
  141.     PUSH    D    ;SAVE FREE MEM POINTER BECAUSE
  142.             ;  WE WILL HAVE TO HAVE IT BACK
  143.             ;  LATER TO STORE THE LENGTH
  144.     INX    D    ;POINT PAST LENGTH STORAGE
  145.     MVI    B,0    ;INITIALIZE LENGTH OF PARM
  146. PPLP:    MOV    A,M    ;GET NEXT BYTE OF PARM
  147.     INX    H
  148.     ORA    A    ;TEST FOR END OF CMD LINE
  149.     JZ    PP2    ;JUMP IF END
  150.     CPI    ' '    ;TEST FOR END OF COMMAND
  151.     JZ    PP2
  152.     CPI    TAB    ;TAB ALSO ENDS COMMAND
  153.     JZ    PP2
  154.     STAX    D    ;PUT PARAMETER BYTE-BY-BYTE
  155.     INX    D    ;INTO FREE MEMORY
  156.     INR    B    ;BUMP LENGTH
  157.     JMP    PPLP
  158. PP2:    XCHG
  159.     SHLD    TXTPTR    ;NEW FREE MEMORY POINTER
  160.     POP    H    ;REMEMBER OUR LENGTH POINTER?
  161.     MOV    M,B    ;STORE THE LENGTH
  162.     XCHG        ;HAVE TO RETN HL > CMD LINE
  163.     ORA    A    ;NOW RETURN END OF LINE FLAG
  164.     STC
  165.     RZ        ;RETURN CY IF ZERO (EOL MARK)
  166.     CMC
  167.     RET
  168. ;
  169. ;    RDFILE READS THE .SUB FILE SPECIFIED
  170. ;    IN THE SUBMIT COMMAND INTO MEMORY
  171. ;
  172. RDFILE: LHLD    LINNUM    ;INCREMENT THE LINE NUMBER
  173.     INX    H
  174.     SHLD    LINNUM
  175.     LHLD    PREV    ;GET PREV PREVIOUS LINE POINTER
  176.     XCHG
  177.     LHLD    TXTPTR    ;GET CURRENT FREE MEM POINTER
  178.     SHLD    PREV    ;MAKE IT THE PREV LINE (FOR NXT PASS)
  179.     MOV    M,E    ;STORE AT BEGIN OF CURRENT LINE,
  180.     INX    H    ;  A POINTER TO THE PREVIOUS
  181.     MOV    M,D
  182.     INX    H
  183.     PUSH    H    ;LATER WE WILL PUT LENGTH HERE
  184.     INX    H    ;SKIP PAST LENGTH
  185.     MVI    C,0    ;INITIALIZE LENGTH TO ZERO
  186. LLP:    CALL    GNB    ;GET NEXT BYTE FROM INPUT FILE
  187.     JC    EOF    ;CY SET IF END OF FILE FOUND
  188.     CALL    UCASE    ;CONVERT TO UPPER CASE
  189.     CPI    1AH    ;SEE IF CPM END OF FILE INDICATOR
  190.     JZ    EOF
  191.     CPI    LF    ;IGNORE LINEFEEDS
  192.     JZ    LLP
  193.     CPI    CR    ;IF IT'S A CARRIAGE RETURN,
  194.     JZ    EOL    ;  THEN DO END OF LINE
  195.     MOV    M,A    ;STORE ALL OTHERS INTO MEMORY
  196.     INX    H
  197.     CALL    SIZE    ;MAKE SURE NO MEMORY OVERFLOW
  198.     INR    C    ;BUMP CHAR COUNT
  199.     JM    LENERR    ;MAX OF 128 CHARS PER LINE
  200.     JMP    LLP    ;GO DO NEXT CHAR
  201. ;
  202. ;    DO END OF LINE SEQUENCE
  203. ;
  204. EOL:    SHLD    TXTPTR    ;SAVE FREE MEMORY POINTER
  205.     POP    H    ;CURRENT LINE'S LENGTH POINTER
  206.     MOV    M,C    ;STORE LENGTH AWAY
  207.     JMP    RDFILE    ;GO DO NEXT LINE
  208. ;
  209. ;    END OF TEXT FILE
  210. ;
  211. EOF:    SHLD    TXTPTR    ;SAVE FREE MEMORY POINTER
  212.     POP    H    ;CURRENT LINE'S LENGTH POINTER
  213.     MOV    M,C    ;STORE LENGTH AWAY
  214.     RET        ;ALL DONE READING SUB FILE
  215. ;
  216. ;    GET NEXT BYTE FROM INPUT FILE
  217. ;
  218. GNB:    PUSH    H    ;DON'T ALTER ANYBODY
  219.     PUSH    D
  220.     PUSH    B
  221.     LHLD    COMPTR
  222.     MOV    A,M    ;GET CHAR THERE
  223.     INX    H
  224.     SHLD    COMPTR
  225.     POP    B    ;RESTORE EVERYBODY
  226.     POP    D
  227.     POP    H
  228.     ORA    A    ;TURN ON CARRY
  229.     RET
  230. ;
  231. ; COME HERE TO GET A .SUB CHARACTER WHEN
  232. ; WE'RE NOT USING A .SUB FILE ("/" OPTION)
  233. ;
  234. GNBKBD: LDA    CLFLAG    ;USE CP/M CMD LINE?
  235.     ORA    A
  236.     JNZ    GNBCL    ;THEN GO DO IT
  237.     LDA    CLCNT    ;NOT, CHECK LOCAL
  238.     ORA    A    ;  CMD LINE CHAR COUNT
  239.     CM    CLFILL    ;REFILL WHEN IT WRAPS BACK
  240.     JC    GKEND    ;GOT CARRY (FROM CLFILL), RETURN EOF
  241.     DCR    A    ;COUNT DOWN
  242.     STA    CLCNT
  243.     JP    GNBCL    ;IF PLUS, BUFFER NOT EMPTY
  244.     MVI    A,CR    ;OUT OF CHARS, RETURN A CR
  245.     RET
  246. GKEND:    MVI    A,1AH    ;RETURN EOF
  247.     RET
  248. ;
  249. ; GET NEXT BYTE OF INPUT FROM CMD LINE @CLPTR
  250. ;
  251. GNBCL:    LHLD    CLPTR    ;LOAD THE POINTER
  252.     MOV    A,M    ;GET THE CHAR
  253.     INX    H    ;BUMP POINTER FOR NEXT TIME
  254.     SHLD    CLPTR
  255.     CPI    ';'    ;LOGICAL END-OF-LINE?
  256.     JNZ    NSEMI    ;JUMP IF NOT
  257.     MVI    A,CR    ;YES, TRANSLATE IT
  258.     RET
  259. NSEMI:    ORA    A    ;PHYSICAL END-OF-LINE
  260.     RNZ        ;THIS ONLY NEEDED WHEN INPUT
  261.             ;  SOURCE IS ORIG CPM CMD LINE
  262.     MVI    A,1AH    ;TRANSLATE THAT TO END OF FILE
  263.     RET
  264. ;
  265. ; SUBROUTINE TO RE-FILL THE LOCAL COMMAND LINE
  266. ;
  267. CLFILL: LXI    D,PROMPT ;PRINT A PROMPT
  268.     MVI    C,PRINTF ;USE CP/M FUNCT 9
  269.     CALL    BDOS
  270.     LXI    D,CLBUF  ;NOW FILL THE BUFFER
  271.     MVI    C,RDBUF
  272.     CALL    BDOS
  273.     LDA    CLCNT     ;RETURN WITH COUNT IN A
  274.     LXI    H,CLTEXT ;RESET THE CMD LINE POINTER
  275.     SHLD    CLPTR
  276.     ORA    A     ;SET CY ON LEN NZ
  277.     STC
  278.     RZ
  279.     CMC
  280.     RET
  281. ;
  282. ;    MAKE SURE NO MEMORY OVERFLOW
  283. ;
  284. SIZE:    LDA    BDOS+2    ;HIGHEST PAGE POINTER
  285.     DCR    A    ;MAKE IT BE UNDER BDOS
  286.     CMP    H    ;CHECK IT AGAINST CURRENT PAGE
  287.     RNC        ;NC=ALL OKAY
  288.     JMP    MEMERR    ;OTHERWISE ABORT
  289. ;
  290. ;    SET UP THE $$$.SUB FILE
  291. ;    FOR WRITING
  292. ;
  293. WRSET:    LXI    D,SUBFCB
  294.     MVI    C,OPENF
  295.     CALL    BDOS    ;OPEN THE FILE
  296.     INR    A    ;CHECK CPM RETURN
  297.     JZ    NONE1    ;NONE EXISTS ALREADY
  298. ;
  299. ;    $$$.SUB EXISTS, SO SET
  300. ;    FCB TO APPEND TO IT
  301. ;
  302.     LDA    SUBFCB+FCBRC ;GET RECORD COUNT
  303.     STA    SUBFCB+FCBNR ;MAKE NEXT RECORD
  304.     RET
  305. ;
  306. ;    COME HERE WHEN NO $$$.SUB EXISTS
  307. ;
  308. NONE1:    LXI    D,SUBFCB
  309.     MVI    C,MAKEF
  310.     CALL    BDOS
  311.     INR    A
  312.     JZ    NOMAKE    ;0FFH=CAN'T CREATE FILE
  313.     RET
  314. ;
  315. ;    WRITE THE "$$$.SUB" FILE
  316. ;
  317. WRSUB:    LHLD    PREV    ;THIS CODE SCANS BACKWARD
  318.     MOV    A,H    ;  THRU THE FILE STORED IN
  319.     ORA    L    ;  MEMORY TO THE FIRST NON-
  320.     JZ    NOTEXT    ;  NULL LINE.  IF NONE IS
  321.     MOV    E,M    ;  IS FOUND, ABORTS
  322.     INX    H
  323.     MOV    D,M    ;HERE, WE PICK UP PNTR TO PREV LINE
  324.     INX    H    ;NOW WE POINT TO LENGTH
  325.     XCHG        ;WE NEED TO STORE AWAY
  326.     SHLD    PREV    ;  POINTER TO PREV LINE
  327.     XCHG
  328.     MOV    A,M    ;NOW PICK UP THE LENGTH
  329.     ORA    A    ;SET Z FLAG ON LENGTH
  330.     JZ    WRSUB    ;LOOP UNTIL A LINE IS FOUND
  331.     JMP    WRNTRY    ;GOT ONE.  NOW JOIN LOOP IN PROGRESS...
  332. WRLOP:    LHLD    PREV    ;GET PREV LINE POINTER
  333.     MOV    A,H
  334.     ORA    L    ;IF THERE IS NO PREV LINE
  335.     JZ    CLOSE    ;  THEN WE ARE DONE
  336.     MOV    E,M    ;ELSE SET UP PREV FOR NEXT
  337.     INX    H    ;  PASS THRU HERE
  338.     MOV    D,M
  339.     INX    H
  340.     XCHG        ;NOW STORE IT AWAY
  341.     SHLD    PREV
  342.     XCHG
  343. WRNTRY: CALL    PUTLIN    ;WRITE THE LINE TO THE FILE
  344.     JMP    WRLOP
  345. ;
  346. ;    $$$.SUB IS WRITTEN, CLOSE THE FILE
  347. ;
  348. CLOSE:    LXI    D,SUBFCB
  349.     MVI    C,CLOSEF
  350.     JMP    BDOS
  351. ;
  352. ;    THIS SUBROUTINE WRITES A LINE
  353. ;    TO THE $$$.SUB FILE BUFFER,
  354. ;    AND FLUSHES THE BUFFER AFTER
  355. ;    THE LINE IS WRITTEN.
  356. ;
  357. PUTLIN: MOV    A,M    ;PICK UP LENGTH BYTE
  358.     INX    H    ;POINT PAST IT
  359.     STA    GETCNT    ;MAKE A COUNT FOR "GET"
  360.     SHLD    GETPTR    ;MAKE A POINTER FOR "GET"
  361.     LXI    H,TBUF+1;TEXT GOES AFTER LENGTH
  362.     SHLD    PUTPTR    ;MAKE POINTER FOR "PUT"
  363.     XRA    A    ;INITIALIZE PUT COUNT
  364.     STA    PUTCNT
  365.     MOV    B,L    ;COUNT FOR CLEAR LOOP
  366. CLR:    MOV    M,A    ;ZERO OUT BUFFER LOC
  367.     INX    H
  368.     INR    B    ;COUNT
  369.     JNZ    CLR
  370. ;
  371. ;    THIS LOOP COLLECTS CHARACTERS
  372. ;    FROM THE LINE STORED IN MEMORY
  373. ;    AND WRITES THEM TO THE FILE.
  374. ;    IF THE "$" PARAMETER SPECIFIER
  375. ;    IS ENCOUNTERED, PARAMETER SUB-
  376. ;    STITUTION IS DONE
  377. ;
  378. PUTLP:    CALL    GETCHR    ;PICK UP A CHARACTER
  379.     JC    FLUSH    ;CY = NO MORE CHAR IN LINE
  380.     CPI    '$'    ;PARAMETER SPECIFIER?
  381.     JNZ    STOBYT    ;IF NOT, JUST WRITE CHAR
  382.     LDA    OPTION    ;CHECK OPTION: '$' DOESN'T
  383.     CPI    '/'    ;  COUNT IN '/' MODE
  384.     MVI    A,'$'    ;(RESTORE THE '$')
  385.     JZ    STOBYT
  386.     CALL    LKAHED    ;PEEK AT NEXT CHAR
  387.     JC    PARERR    ;LINE ENDING MEANS PARAM ERR
  388.     CPI    '$'    ;ANOTHER "$"?
  389.     JNZ    SUBS    ;IF NOT THEN GO DO SUBSTITUTION
  390.     CALL    GETCHR    ;GET THE 2ND "$" (WE ONLY LOOKED
  391.             ;  AHEAD BEFORE)
  392. STOBYT: CALL    PUTCHR    ;WRITE CHAR TO FILE
  393.     JMP    PUTLP
  394. ;
  395. ;    PARAMETER SUBSTITUTION...LOOKS UP THE
  396. ;    PARAMETER # AFTER THE "$" AND PLUGS IT
  397. ;    IN IF IT EXISTS.
  398. ;
  399. SUBS:    CALL    NUMTST    ;IT BETTER BE A NUMBER
  400.     JC    PARERR    ;  OTHERWISE PARAM ERROR
  401.     MVI    B,0    ;INITIALIZE PARM #
  402.     JMP    LPNTRY    ;WE JOIN LOOP IN PROGRESS...
  403. SUBLP:    CALL    LKAHED    ;LOOK AT NEXT CHAR
  404.     JC    DOSUBS    ;IF LINE EMPTY, THEN PLUG IN PARM
  405.     CALL    NUMTST    ;CHECK FOR NUMERIC
  406.     JC    DOSUBS    ;DONE IF NOT
  407. LPNTRY: CALL    GETCHR    ;NOW REMOVE THE CHAR FROM INPUT STREAM
  408.     SUI    '0'    ;REMOVE ASCII BIAS
  409.     MOV    C,A    ;SAVE IT
  410.     MOV    A,B    ;OUR ACCUMULATED COUNT
  411.     ADD    A    ;MULTIPLY  BY TEN
  412.     ADD    A
  413.     ADD    B
  414.     ADD    A
  415.     ADD    C    ;THEN ADD IN NEW DIGIT
  416.     MOV    B,A    ;RESTORE COUNT
  417.     JMP    SUBLP
  418. ;
  419. ;    PERFORM THE SUBSTITUTION
  420. ;
  421. DOSUBS: MOV    A,B    ;GET PARM #
  422.     DCR    A    ;MAKE ZERO RELATIVE
  423.     JM    PARERR    ;OOPS
  424.     CALL    LOOKUP    ;LOOK IT UP IN PARM TABLE
  425.     JC    PARERR    ;IT'S NOT THERE
  426.     MOV    B,A    ;LENGTH IN B
  427. SUBLP1: INR    B    ;TEST B FOR ZERO
  428.     DCR    B
  429.     JZ    PUTLP    ;DONE
  430.     MOV    A,M    ;GET CHAR OF REAL PARAMETER
  431.     INX    H    ;POINT PAST FOR NEXT TIME
  432.     PUSH    H    ;SAVE REAL PARM POINTER
  433.     CALL    PUTCHR    ;PUT IT IN THE FILE
  434.     POP    H    ;GET BACK REAL PARM POINTER
  435.     DCR    B    ;COUNTDOWN
  436.     JMP    SUBLP1
  437. ;
  438. ;    COME HERE WHEN A LINE IS FINISHED,
  439. ;    AND WE NEED TO WRITE THE BUFFER TO DISK
  440. ;
  441. FLUSH:    LHLD    PUTPTR    ;PAD SECTOR WITH NULLS
  442. FLPAD:    MVI    M,0
  443.     INX    H
  444.     MOV    A,L    ;CHECK BUFF BOUND
  445.     ORA    A
  446.     JNZ    FLPAD
  447.     LXI    D,SUBFCB
  448.     MVI    C,WRITEF
  449.     CALL    BDOS
  450.     ORA    A
  451.     JNZ    WRERR    ;CPM RETURNED A WRITE ERROR
  452.     RET
  453. ;
  454. ;    GETCHR GETS ONE CHAR FROM
  455. ;    LINE STORED IN MEMORY
  456. ;
  457. GETCHR: LXI    H,GETCNT
  458.     MOV    A,M    ;PICK UP COUNT
  459.     DCR    A    ;REMOVE THIS CHAR
  460.     STC        ;PRESET ERROR
  461.     RM        ;RETURN CY IF OUT OF CHARS
  462.     MOV    M,A    ;UPDATE COUNT
  463.     LHLD    GETPTR    ;CURRENT CHAR POINTER
  464.     MOV    A,M    ;PICK UP CHAR
  465.     INX    H    ;BUMP POINTER
  466.     SHLD    GETPTR    ;PUT IT BACK
  467.     CMC        ;TURN CARRY OFF
  468.     RET
  469. ;
  470. ;    PUTCHR PUTS ONE CHAR TO
  471. ;    THE OUTPUT BUFFER
  472. ;
  473. PUTCHR: LXI    H,PUTCNT
  474.     INR    M    ;INCREMENT COUNT
  475.     JM    LENERR    ;LINE WENT TO > 128 CHARS
  476.     LHLD    PUTPTR    ;GET BUFFER POINTER
  477.     MOV    M,A    ;PUT CHAR THERE
  478.     INX    H    ;BUMP POINTER
  479.     SHLD    PUTPTR    ;PUT IT BACK
  480.     RET        ;ALL DONE
  481. ;
  482. ;    LOOK AHEAD ONE CHAR IN
  483. ;    THE INPUT STREAM.  SET
  484. ;    CARRY IF NONE LEFT.
  485. ;
  486. LKAHED: LDA    GETCNT
  487.     ORA    A    ;SEE IF COUNT IS DOWN TO ZERO
  488.     STC        ;PRE SET INDICATOR
  489.     RZ
  490.     MOV    A,M    ;PICK UP CHAR
  491.     CMC        ;TURN OFF CARRY FLAG
  492.     RET
  493. ;
  494. ;    LOOK UP PARAMETER WITH NUMBER IN
  495. ;    A REG. RETURN A=LENGTH OF PARM,
  496. ;    AND HL => PARAMETER
  497. ;
  498. LOOKUP: CPI    NPAR
  499.     JNC    PAROVF    ;PARM # TOO HIGH
  500.     MOV    L,A
  501.     MVI    H,0    ;NOW HAVE 16 BIT NUMBER
  502.     DAD    H    ;DOUBLE FOR WORD OFFSET
  503.     LXI    D,TABLE
  504.     DAD    D    ;DO THE OFFSET
  505.     MOV    E,M    ;GET ADDRESS OF PARM
  506.     INX    H
  507.     MOV    D,M
  508.     MOV    A,D    ;ANYTHING THERE?
  509.     ORA    E
  510.     JNZ    LKUPOK
  511.     XRA    A    ;NO, ZERO LENGTH
  512.     RET
  513. LKUPOK: XCHG        ;NOW IN DE
  514.     MOV    A,M    ;PICK UP LENGTH
  515.     INX    H    ;POINT PAST LENGTH
  516.     RET
  517. ;
  518. ;    UTILITY COMPARE SUBROUTINE
  519. ;
  520. COMPAR: LDAX    D
  521.     CMP    M
  522.     RNZ
  523.     INX    H
  524.     INX    D
  525.     DCR    B
  526.     JNZ    COMPAR
  527.     RET
  528. ;
  529. ;    NUMERIC TEST UTILITY SUBROUTINE
  530. ;
  531. NUMTST: CPI    '0'
  532.     RC
  533.     CPI    '9'+1
  534.     CMC
  535.     RET
  536. ;
  537. ;DECIMAL OUTPUT ROUTINE
  538. ;
  539. DECOUT: PUSH    B
  540.     PUSH    D
  541.     PUSH    H
  542.     LXI    B,-10
  543.     LXI    D,-1
  544. ;
  545. DECOU2: DAD    B
  546.     INX    D
  547.     JC    DECOU2
  548.     LXI    B,10
  549.     DAD    B
  550.     XCHG
  551.     MOV    A,H
  552.     ORA    L
  553.     CNZ    DECOUT
  554.     MOV    A,E
  555.     ADI    '0'
  556.     CALL    TYPE
  557.     POP    H
  558.     POP    D
  559.     POP    B
  560.     RET
  561. ;
  562. ; PRINT CR, LF ON CONSOLE
  563. ;
  564. CRLF:    MVI    A,CR
  565.     CALL    TYPE
  566.     MVI    A,LF
  567. ;
  568. ; PRINT CHAR IN A ON CONSOLE
  569. ;
  570. TYPE:    PUSH    H    ;SAVE REGS
  571.     PUSH    D
  572.     PUSH    B
  573.     MOV    E,A    ;PUT IN E FOR CP/M
  574.     MVI    C,FPCHAR
  575.     CALL    BDOS    ;PRINT IT
  576.     POP    B    ;RESTORE ALL
  577.     POP    D
  578.     POP    H
  579.     RET
  580. ;
  581. ; CONVERT CHAR IN A TO UPPER CASE
  582. ;
  583. UCASE:    CPI    'a'    ;VALIDATE CASE
  584.     RC
  585.     CPI    'z'+1
  586.     RNC
  587.     ANI    5FH    ;GOT LC, CONV TO UC
  588.     RET
  589. ;
  590. ;    ERROR HANDLERS
  591. ;
  592. WRERR:    CALL    ERRXIT
  593.     DB    'Disk full$'
  594. NOMAKE: CALL    ERRXIT
  595.     DB    'Directory full$'
  596. MEMERR: CALL    ERRXIT
  597.     DB    'Memory full$'
  598. NOTFND: CALL    ERRXIT
  599.     DB    'Submit file not found$'
  600. PARERR: CALL    ERRXIT
  601.     DB    'Parameter$'
  602. PAROVF: CALL    ERRXIT
  603.     DB    'Too many parameters:$'
  604. LENERR: CALL    ERRXIT
  605.     DB    'Line too long:$'
  606. NOTEXT: CALL    ERRXIT
  607.     DB    'Submit file empty.$'
  608. ERRXIT: POP    D
  609.     MVI    C,PRINTF
  610.     CALL    BDOS
  611.     LXI    D,ERRMSG    ;PRINT 2ND HALF MSG
  612.     MVI    C,PRINTF
  613.     CALL    BDOS
  614.     LHLD    LINNUM        ;TELL LINE NUMBER
  615.     CALL    DECOUT
  616.     CALL    CRLF
  617.     LXI    D,SUBFCB    ;DELETE THE $$$.SUB FILE
  618.     MVI    C,DELETF
  619.     CALL    BDOS
  620.     JMP    0
  621. ;
  622. ERRMSG: DB    ' error on line number: $'
  623. ;
  624. ; PROMPT FOR COMMAND LINE INPUT
  625. ;
  626. PROMPT: DB    CR,LF,'*$'
  627. ;
  628. ;    INITIALIZE ALL VARIABLES
  629. ;
  630. INITVAR:
  631.     LXI    H,VAR
  632.     LXI    B,ENDVAR-VAR
  633. INITLP: MVI    M,0
  634.     INX    H
  635.     DCX    B
  636.     MOV    A,B
  637.     ORA    C
  638.     JNZ    INITLP
  639.     LXI    H,SUBCOM
  640.     SHLD    COMPTR
  641.     LXI    H,TABLE
  642.     SHLD    TBLPTR
  643.     LXI    H,0FFFFH
  644.     SHLD    ENDTBL
  645.     LXI    H,FREMEM
  646.     SHLD    TXTPTR
  647.     MVI    A,80H    ;FORCE READ
  648.     STA    IBP
  649.     STA    CLCNT    ;FORCE CONSOLE READ
  650.     RET
  651. ;
  652. ;    VARIABLE STORAGE
  653. ;
  654. VAR    EQU    $
  655. ;
  656. COMPTR    DW    SUBCOM    ;For GNB routine
  657. TXTPTR: DW    0    ;FREE MEMORY POINTER
  658. TBLPTR: DW    0    ;POINTER TO PARM TABLE
  659. LINNUM: DW    0    ;CURRENT LINE NUMBER
  660. PREV:    DW    0    ;POINTER TO PREV LINE
  661. GETCNT: DB    0    ;COUNTER FOR 'GET'
  662. GETPTR: DW    0    ;POINTER FOR 'GET'
  663. PUTPTR: DW    0    ;POINTER FOR 'PUT'
  664. IBP:    DB    0    ;INPUT BUFFER POINTER
  665. CLPTR:    DW    0    ;COMMAND LINE POINTER
  666. CLFLAG: DB    0    ;USE CP/M CMD LINE FLAG
  667. OPTION: DB    0    ;'/' OPTION FLAG STORE
  668. TABLE:    DS    NPAR*3    ;PARAMETER TABLE
  669. ENDTBL: DW    0FFFFH    ;END OF PARAMETER TABLE
  670. ;
  671. ENDVAR    EQU    $
  672. ;
  673. ; COMMAND LINE BUFFER...NOT INITIALIZED
  674. ;
  675. CLBUF:    DB    128    ;BUFFER LENGTH
  676. CLCNT:    DB    0    ;CHARACTER COUNTER
  677. CLTEXT: DS    128    ;THE BUFFER ITSELF
  678. ;
  679. SPSAVE: DW    0    ;STACK POINTER SAVE
  680. ;
  681. ;
  682. ;    FCB FOR $$$.SUB
  683. ;
  684. SUBFCB: DB    SUBDRV     ;DRIVE SPECIFIER
  685.     DB    '$$$     '
  686. SUBTYP: DB    'SUB'
  687.     DW    0,0,0,0 ;INITIALIZE REST OF FCB
  688.     DW    0,0,0,0
  689.     DW    0,0
  690. ;
  691. ;    STACK AREA
  692. ;
  693.     DS    200    ;WHY NOT?
  694. STACK    EQU    $
  695. FREMEM    EQU    $
  696. ;
  697.     END    SUBMIT
  698.  
  699.