home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / RCPM / COMSEC13.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  16KB  |  726 lines

  1. ;            COMSEC    v1.3
  2. ; This program is similar in nature as the 'message service' for a
  3. ; SYSOP  on a BBS. The  main  point is, that it can be used in the
  4. ; command line in CP/M.  I was tired of having to re-enter the BBS
  5. ; just to  leave a  message  because the  SYSOP didn't  answer  on
  6. ; CHAT.
  7.  
  8. ; Some of these  routines were  borrowed from CHAT.  The origional
  9. ; author of CHAT was: Roderick Hart...
  10.  
  11. ; The caller simply enters the program  name or uses the option to
  12. ; immediately  start without instructions.  Using a ' D' after the
  13. ; name will directly enter it.
  14.  
  15. ; It should also be noted that this program has  NO provisions for
  16. ; anything less than CP/M 2.x...
  17.  
  18. ;###############################################
  19. ; Written by:
  20. ;(except where noted)
  21. ; Version 1.0
  22. ;        R. Kester
  23. ;        JAN 05 84
  24.  
  25. ; Version 1.1
  26. ;    Minor changes, renumbered for me
  27. ; Version 1.2
  28. ;    Some more minor changes...
  29. ; Version 1.3
  30. ;    Re-did code so compatible with NUCHAT's..
  31. ;################################################
  32.  
  33. NO    EQU    0
  34. YES    EQU    0FFH
  35.  
  36. STDCPM    EQU    YES        ;Yes for 'standard' CP/M
  37. ALTCPM    EQU    NO        ;Yes for other type CP/M (TRS-80,etc)
  38.  
  39.     IF    STDCPM
  40. BASE    EQU    0
  41.     ENDIF
  42.  
  43.     IF    ALTCPM
  44. BASE    EQU    4200H
  45.     ENDIF
  46.  
  47.     ORG    BASE+100H
  48.  
  49. ;Version 1.3
  50. VER    EQU    13        ;* Current version number
  51.  
  52. BDOS    EQU    BASE+5
  53. FCB    EQU    5CH
  54. OPEN    EQU    0FH
  55. MAKE    EQU    16H
  56. READ    EQU    14H
  57. WRITE    EQU    15H
  58. CLOSE    EQU    10H
  59. SETDMA    EQU    1AH
  60. USR    EQU    20H
  61. DEFBUF    EQU    80H
  62.  
  63. CR    EQU    0DH
  64. LF    EQU    0AH
  65. BELL    EQU    07H
  66. SPACE    EQU    20H
  67. SECT    EQU    80H
  68. DEL    EQU    7FH
  69.  
  70. ABORT    EQU    'A'-40H        ;Abort program in message mode
  71. FINIS    EQU    'C'-40H        ;Quit and save file (message)
  72. EOF    EQU    'Z'-40H        ;End Of File
  73. BACKUP    EQU    'H'-40H        ;Baskspace
  74.  
  75.     JMP    START        ;Bypass
  76.  
  77. ; NOTE: When specifying the drive code, enter the number
  78. ; corrosponding to the drive.
  79. ; i.e.        0=current drive
  80. ;        1=dirve 'A'
  81. ;        2=drive 'B'.....etc.
  82.  
  83. ; 'MEMLIM' = This allows that number (MEMLIM) of bytes to be added
  84. ; starting at BUFF.  BUFF is the area directly following this pro-
  85. ; gram where all received characters are stored, INCLUDING already
  86. ; existing messages (if any). i.e. If the value of MEMLIM were 50,
  87. ; then this program would only allow 50 bytes to be placed in mem-
  88. ; ory. It would then issue an error telling the user it is running
  89. ; low on memory and  automatically  'close up shop'.  It should be
  90. ; noted that,  even if it does enter the error condition, it still
  91. ; includes the LASTCALR information. So this number should be used
  92. ; as a reference only.
  93.  
  94. ; I.E. 20,000 = 20,000 BYTE MESSAGE FILE.
  95.  
  96. ;* * * * * *  USER MOD AREA * * * * * * *
  97.  
  98. ;*    Message limit (see note above)    *
  99. MEMLIM    EQU    20000
  100.  
  101. ;*    Set YES for an RBBS system    *
  102. ;*        (use the LASTCALR file)    *
  103. RBBS    EQU    YES
  104.  
  105. ;*       # of characters per line    *
  106. LIMIT    EQU    72
  107.  
  108. ;*   How many repeatative characters    *
  109. ;*       before tagging an error?    *
  110. TOMANY    EQU    LIMIT-8
  111.  
  112. ;*    User area you want messages in    *
  113. USER    EQU    10
  114.  
  115. ;*  Drive for messages, put number here    *
  116. DFDRV    EQU    1
  117.  
  118. ;*       Drive with LASTCALR on it    *
  119. CALLDR    EQU    1
  120.  
  121. ;*        User area of LASTCALR        *
  122. CALLU    EQU    0
  123.  
  124. ;*    File name created for messages    *
  125. ;*         spaces ||||||||||| =11      *
  126. FNAME    DB DFDRV,'MESSAGE CPM'
  127. ;*         spaces ||||||||||| =11      *
  128.  
  129. ;    End of option selections    *
  130. ;****************************************
  131.  
  132. ; From here on, you shouldn't need to modify anything else...
  133.  
  134.     IF    RBBS
  135. DBUF    EQU    80H
  136. BSIZE    EQU    80H
  137. CALLERFCB:
  138.     DB    CALLDR,'LASTCALR   ',0
  139.     DS    23
  140.     DB    0FFH
  141. CALLERADR:DW    DBUF
  142. CALLERSIZ:EQU    BSIZE
  143. CALLERLEN:DW    BSIZE
  144. CALLERPTR:DS    2
  145.     ENDIF        ;RBBS
  146.  
  147. START:
  148. ; Do the usual routine for the SP
  149.     LXI    H,0
  150.     DAD    SP
  151.     SHLD    STACK
  152.     LXI    SP,STACK
  153.  
  154. ; Initialize direct CBIOS calls
  155.     LHLD    1
  156.     LXI    D,3
  157.     DAD    D
  158.     SHLD    CSTAT+1        ;Con stat
  159.     DAD    D
  160.     SHLD    CIN+1        ;Con in
  161.     DAD    D
  162.     SHLD    COUT+1        ;Con out
  163.  
  164. ; Get current user area and save it
  165.     MVI    E,0FFH        ;Code for GET
  166.     MVI    C,USR
  167.     CALL    BDOS        ;Do it
  168.     STA    OLDUSR        ;Save it for return
  169.  
  170. ;Get any potential options next
  171.     LDA    DEFBUF+1
  172.     ORA    A
  173.     JZ    NNOP
  174.     LDA    DEFBUF+2
  175.     STA    OPT
  176.  
  177. NNOP:
  178.     IF    RBBS
  179.     XRA    A        ;Zero A
  180.     STA    CALLERFCB+12
  181.     STA    CALLERFCB+32
  182.     LXI    H,CALLERSIZ    ;Get value
  183.     SHLD    CALLERLEN
  184.     SHLD    CALLERPTR
  185.     MVI    E,CALLU        ;Set area for LASTCALR
  186.     MVI    C,USR
  187.     CALL    BDOS
  188.     LXI    D,CALLERFCB    ;Point to filename
  189.     MVI    C,OPEN
  190.     CALL    BDOS
  191.     CPI    YES        ;Was it successful?
  192.     JNZ    OPENOK        ;Zero = No
  193.  
  194.     CALL    ILPRT
  195.     DB BELL,CR,LF,LF
  196.     DB 'ERROR --> LASTCALR file not found!...ABORTING'
  197.     DB CR,LF,LF,0
  198.  
  199.     JMP    LEAVE
  200.  
  201. OPENOK:
  202.     LXI    D,DEFBUF    ;Point to default buffer
  203.     MVI    C,SETDMA    ;Make new DMA addr
  204.     CALL    BDOS
  205.     MVI    C,READ        ;Read in file @DMA
  206.     LXI    D,CALLERFCB
  207.     CALL    BDOS
  208.     ORI    0FFH        ;Read OK?
  209.     JNZ    ROK
  210.  
  211.     CALL    ILPRT
  212.     DB BELL,CR,LF,LF
  213.     DB 'ERROR -> Can''t read LASTCALR file!'
  214.     DB CR,LF,LF,0
  215.     JMP    LEAVE
  216.  
  217. ROK:
  218.     CALL    VEIW        ;Set up name
  219.     MVI    M,'$'        ;Mark end
  220.     ENDIF        ;RBBS
  221.  
  222. ; Do sign-on
  223.     CALL    ILPRT
  224.     DB CR,LF,LF
  225.     DB '            Computer Secretary v'
  226.     DB VER/10+'0','.',VER MOD 10+'0'
  227.     DB CR,LF,LF,0
  228.  
  229. ; See if any requests are there
  230.     LDA    OPT
  231.     CPI    NO        ;Any options?
  232.     JZ    NONE        ;No...
  233.     CPI    'D'        ;Direct entry?
  234.     JZ    DIRECT        ;We saw a 'D'
  235.  
  236. ; Otherwise give brief instructions
  237. NONE:
  238.     CALL    ILPRT
  239.     DB CR,LF
  240.     DB 'When the  -:  prompt appears, you may  start entering'
  241.     DB CR,LF
  242.     DB 'your message. Hitting the RETURN key is not necessary'
  243.     DB CR,LF
  244.     DB 'for terminating lines. You may  ABORT  the process by'
  245.     DB CR,LF
  246.     DB 'entering a  ^A. Use  ^C for saving message.'
  247.     DB CR,LF
  248.     DB 'You may also make your life easier next time by:'
  249.     DB CR,LF,LF
  250.     DB 'A>progname D           <-- use a ''D'' for direct entry'
  251.     DB CR,LF,LF
  252.     DB 0
  253.  
  254. ; First, move the FNAME into the FCB
  255. DIRECT:
  256.     MVI    B,12        ;Number of bytes to move
  257.     LXI    H,FCB        ;The 'to' place
  258.     LXI    D,FNAME        ;The 'what to move' name
  259. LOOP:
  260.     LDAX    D        ;Get the byte
  261.     MOV    M,A        ;Get the 'what' byte
  262.     INX    H        ;Bump the pointer
  263.     INX    D        ;Bump the 'getter'
  264.     DCR    B        ;Decrement the counter
  265.     JNZ    LOOP        ;If B<>0 then keep chuggin'
  266.     CALL    CLRFCB        ;Clear certain extensions
  267.  
  268. ; And set the area for the messages...
  269.     MVI    E,USER        ;Get ready to set the
  270.     MVI    C,USR        ; user are desired
  271.     CALL    BDOS        ;Do it.
  272.     LXI    D,FCB        ;Point to the filename
  273.     MVI    C,OPEN        ;Get ready to open
  274.     CALL    BDOS        ;the file pointed by DE
  275.     CPI    YES        ;Was it successful?
  276.     JZ    MAKEIT        ;Zero = make it the first time
  277.  
  278. ; Now read in the current contents...
  279.     LXI    D,BUFF        ;Point to buffer
  280. RLOOP:
  281.     MVI    C,SETDMA
  282.     PUSH    D        ;Save previous DMA addr.
  283.     CALL    BDOS
  284.     LXI    D,FCB        ;Point to filename
  285.     MVI    C,READ        ;Read it in
  286.     CALL    BDOS
  287.     POP    D
  288.     ORA    A        ;Find out DIR code
  289.     JNZ    FINISHED    ;Zero = not finished
  290.     LXI    H,80H        ;Value of 1 sector
  291.     DAD    D        ;HL has new DMA addr.
  292.     XCHG            ;Now DE has
  293.     JMP    RLOOP
  294.  
  295. CLRFCB:
  296.     XRA    A        ;Zero A
  297.     STA    FCB+12
  298.     STA    FCB+32
  299.     RET
  300.  
  301. ; We finished reading the file in to buffer
  302. FINISHED:
  303.     XCHG            ;Get the last DMA for a double check
  304.     SHLD    POINTR
  305.     CALL    CLRFCB        ;Clear the record info for writing
  306.     CALL    SEARCH        ;Find the EOF mark and cancel it.
  307.                 ; and then reset the POINTR.
  308. BEGIN:
  309.     IF    RBBS
  310.     CALL    FIRSTNM        ;Get & print callers name
  311.     ENDIF        ;RBBS
  312.  
  313.     CALL    ILPRT
  314.     DB BELL,CR,LF
  315.     DB '      - ^A  aborts  -  ^C saves message'
  316.     DB CR,LF,LF
  317.     DB '-: '
  318.     DB 0
  319.  
  320. READIT:
  321.     CALL    TESTMEM        ;Check memory limit
  322.     CALL    CIN        ;Get a byte typed by the user
  323.     CPI    FINIS        ;A ^C?
  324.     JZ    QUIT        ;Yes?, then tidy up
  325.     CPI    ABORT        ;Change their mind?
  326.     JZ    STOP        ;Yes?, then don't tidy up
  327.     CPI    CR        ;A return?
  328.     JZ    CRLF        ;Yes?, do the dirty work
  329.     CPI    BACKUP        ;A backspace?
  330.     JZ    BACK        ;Do what it requires
  331.     CPI    DEL
  332.     JZ    BACK
  333.     CPI    ' '        ;A space?
  334.     JC    READIT        ;If it equals a value below, then loop
  335.     CALL    PUTNMEM        ;Slip it in memory
  336.     PUSH    PSW        ;Save 'A'
  337.     MOV    C,A        ;Swap it for output
  338.     CALL    COUT        ;Send it to them
  339.     POP    B        ;Get 'A' into 'B' now
  340.     LDA    COUNT        ;How far we gone on the screen?
  341.     INR    A        ;Bump it
  342.     STA    COUNT        ;Save it
  343.     CPI    LIMIT        ;Too many characters yet?
  344.     JZ    CRLF        ;Yep
  345.     CPI    LIMIT-8        ;Near the limit?
  346.     JC    READIT        ;Nope
  347.     MOV    A,B        ;Find out if we can
  348.     CPI    ' '        ; help'm out and do a
  349.     JNZ    READIT        ; return for them...
  350. CRLF:
  351.     CALL    ILPRT        ;...we could!
  352.     DB CR,LF
  353.     DB '-: '
  354.     DB 0
  355.  
  356.     XRA    A        ;Reset the counter
  357.     STA    COUNT
  358.     MVI    A,CR        ;Load a RETURN
  359.     CALL    PUTNMEM
  360.     MVI    A,LF        ;Load a LINE FEED
  361.     CALL    PUTNMEM
  362.     JMP    READIT        ;Do it all again
  363.  
  364. BACK:
  365.     LDA    COUNT        ;Get the counter
  366.     DCR    A        ;Sub one for a backspace
  367.     JM    READIT        ;Already at 0?
  368.     STA    COUNT        ;Then save it
  369.  
  370.     CALL    ILPRT
  371.     DB BACKUP,' ',BACKUP,0
  372.  
  373.     LHLD    POINTR        ;Get pointer value
  374.     MVI    A,L        ;If it is already
  375.     ORA    H        ; a zero then
  376.     JZ    READIT        ; skip the rest
  377.     DCX    H        ;Sub one for backup
  378.     SHLD    POINTR        ;Save it
  379.     JMP    READIT        ;Go back and do some more
  380.  
  381. ; Inline print routine using direct I/O
  382. ILPRT:
  383.     XTHL            ;Swap SP/HL
  384. ILPLP:
  385.     MOV    C,M        ;'C' = ->HL
  386.     PUSH    H
  387.     CALL    COUT        ;Send it to the console
  388.     POP    H
  389.     INX    H        ;Bump the char. pointer
  390.     MOV    A,M        ;'A' = ->(HL)
  391.     ORA    A        ;Is it a null?
  392.     JNZ    ILPLP        ;Nope, do some more
  393.     XTHL            ;Yep, swap HL/SP
  394.     RET
  395.  
  396.     IF    RBBS
  397. ;Enter here to display callers name to CRT...
  398. FIRSTNM:
  399.     CALL    ILPRT
  400.     DB 'Sorry I wasn''t around ',0
  401.  
  402.     LXI    H,DEFBUF    ;Point to area
  403. HAGA:
  404.     MOV    A,M        ;Get byte
  405.     CPI    '$'        ;See if end
  406.     JZ    ALM        ;Yes...
  407.     PUSH    H        ;Else, save HL
  408.     MOV    C,A        ;Get byte to send
  409.     CALL    COUT        ;Send it to CRT
  410.     POP    H        ;Get HL back
  411.     INX    H        ;Bump it
  412.     JMP    HAGA        ;Loop..
  413.  
  414. ALM:
  415.     CALL    ILPRT
  416.     DB '....',CR,LF,LF,0        ;Send this for looks
  417.     RET
  418.  
  419. ;Enter this routine to set-up the name to be printed
  420. ;in the file, Replaces the comma with a space. Puts
  421. ;it the default buffer...
  422. VEIW:
  423.     LXI    H,DEFBUF    ;Point to defualt buffer
  424. DLOP:
  425.     MOV    A,M        ;Get a byte
  426.     CPI    EOF        ;End of file
  427.     RZ            ;Yes..or
  428.     CPI    CR        ; found a CR?
  429.     RZ            ;Yes...
  430.  
  431. ALOOP:
  432.     CPI    ','        ;Then check for this
  433.     JNZ    BLOP        ;No...
  434.     MVI    A,' '        ;Then make it a space
  435. BLOOP:
  436.     MOV    M,A        ;Put it in memory
  437. BLOP:
  438.     INX    H        ;Bump pointer
  439.     JMP    DLOP        ;Loop...
  440.     ENDIF        ;RBBS
  441.  
  442. ;Message for SYSOP if too many chars. in  arow.
  443.  
  444. TOMSG:    DB CR,LF,LF,'This person possibly tried to fool you!',CR,LF,'$'
  445.  
  446. ;Enter here when we got too many of the same character in a row.
  447. TOERR:
  448.     CALL    ILPRT
  449.     DB BELL,CR,LF,LF
  450.     DB 'ERROR -> Too many similar characters, ABORTING!'
  451.     DB CR,LF,LF,0
  452.  
  453.     LHLD    ORNPTR        ;Get value before anything was entered
  454.     SHLD    POINTR        ;Make that the current value
  455.     LXI    D,TOMSG        ;Enter a msg. so SYSOP nows why
  456.     CALL    PLOOP        ; nothing was entered
  457. QUIT:
  458.     MVI    A,CR        ;Put some area in for readibility
  459.     CALL    PUTNMEM
  460.     MVI    A,LF
  461.     CALL    PUTNMEM
  462.     CALL    PUTNMEM
  463.  
  464.     IF    NOT RBBS
  465.     JMP    ALMOST
  466.     ENDIF        ;NOT RBBS
  467.  
  468.     IF    RBBS
  469.     CALL    CALLGET        ;Put name into file
  470.     JMP    ALMOST
  471.  
  472. ;Enter here to place callers name into file..
  473. CALLGET:
  474.     LXI    D,DEFBUF
  475. HLOOP:
  476.     LDAX    D        ;Get byte
  477.     CPI    '$'        ;End?
  478.     RZ            ;Yes..
  479.     PUSH    D        ;Then save DE
  480.     CALL    PUTNMEM        ;Get byte=>DE put in file by (HL)
  481.     POP    D        ;Get DE back
  482.     INX    D        ;Bump it
  483.     JMP    HLOOP        ;Loop...
  484.     ENDIF        ;RBBS
  485.  
  486. ; Call this routine each time we enter a byte into the buffer
  487. ; and keep track of twits...
  488.  
  489. PUTNMEM:
  490.     STA    TEMP        ;Save A for the following
  491.     LHLD    POINTR        ;Get current value
  492.     MOV    B,A        ;Save it
  493.     MOV    M,A        ;Slip in byte
  494.     INX    H        ;Bump the pointer
  495.     SHLD    POINTR        ;Save it
  496.     LHLD    POINTR        ;Get it back
  497.     DCX    H        ;Decrement it
  498.     DCX    H        ; again
  499.     MOV    A,M        ;Get byte
  500.     CMP    B        ;The same as B?
  501.     JZ    SETNOT        ;Yep..
  502.     CPI    CR        ; ?
  503.     JZ    SETNOT        ;Yep..
  504.     CPI    LF        ; ?
  505.     JZ    SETNOT        ;Yes?, do something about it
  506.     XRA    A        ;No?, then
  507.     STA    MNYCNT        ; reset count
  508.     LDA    TEMP        ;Get A back
  509.     RET
  510.  
  511. ;Enter here when we find the same character typed twice in a row.
  512. ;And exit if too many of them, and keep the caller's name.
  513.  
  514. SETNOT:
  515.     LDA    MNYCNT        ;Get count
  516.     INR    A        ;Bump it
  517.     STA    MNYCNT        ;Save new count
  518.     CPI    TOMANY        ;Too many of them?
  519.     JZ    TOERR        ;Yes?, then error exit
  520.     LDA    TEMP        ;Get A back
  521.     RET
  522.  
  523. ; Test memory limit... if we are there, then quit
  524.  
  525. TESTMEM:
  526.     LHLD    MEMS        ;The number not to exceed
  527.     XCHG            ;Swap
  528.     LHLD    POINTR        ;The number to compare to
  529.     MOV    A,H        ;Put MS part in A
  530.     CMP    D
  531.     RC            ;Ok, if carry
  532.     MOV    A,L        ;Else do the same
  533.     CMP    E
  534.     RC            ;Ok, if carry
  535.  
  536. ;No carry so we are over exteneded...
  537.     CALL    ILPRT        ;Then print error message
  538.     DB BELL,CR,LF,LF
  539.     DB 'SORRY -> Ending things, running low on memory!'
  540.     DB CR,LF
  541.     DB 'Please try again another time...'
  542.     DB CR,LF,LF,0
  543.  
  544.     JMP    QUIT        ;Close up shop
  545.     
  546. MEMS:    DW    BUFF+MEMLIM    ;Max. value not to exceed
  547.  
  548. ; Put some sort of marking for the next message
  549. ; when being typed out.
  550.  
  551. ; End of message delimmiter.
  552. ENDING:    DB CR,LF,LF,'+ + + + + + + + + + + + + + + +',CR,LF,LF,'$'
  553.  
  554. ALMOST:
  555.     LXI    D,ENDING    ;Put the above line in the file
  556.     CALL    PLOOP        ; for readibility
  557.     JMP    GONE
  558.  
  559. ;Used elsewhere...
  560. PLOOP:
  561.     LDAX    D
  562.     CPI    '$'
  563.     RZ
  564.     CALL    PUTNMEM
  565.     INX    D
  566.     JMP    PLOOP
  567.  
  568. GONE:
  569.     MVI    A,EOF        ;Get EOF mark
  570.     CALL    PUTNMEM
  571.  
  572. ; Change the user area for the message file
  573.     MVI    E,USER
  574.     MVI    C,USR
  575.     CALL    BDOS
  576.     LXI    D,BUFF        ;Beginning of DMA
  577.     PUSH    D        ;Save it
  578. WLOOP:
  579.     POP    D        ;Get previous push into DE
  580.     PUSH    D        ;Save on the stack
  581.     MVI    C,SETDMA    ;Set the DMA to
  582.     CALL    BDOS        ;the addr. in DE
  583.     LXI    D,FCB        ;Point to filename
  584.     MVI    C,WRITE        ;Write to it
  585.     CALL    BDOS
  586.     CPI    NO        ;Successful?
  587.     JNZ    WEXIT        ;Zero = yes
  588.     POP    H        ;Get the past DMA addr.
  589.     LXI    D,SECT        ;One more sector
  590.     DAD    D        ; is added to the value
  591.     PUSH    H        ;Save the next DMA addr.
  592.     MOV    A,H        ;Get the high byte
  593.     CMA            ;1's compliment
  594.     MOV    D,A        ;Save that in D
  595.     MOV    A,L        ;Get the low byte
  596.     CMA            ;1's compliment
  597.     MOV    E,A        ;Save that in E
  598.     INX    D        ;= inverted current DMA addr.+1
  599.     LHLD    POINTR        ;Get # of bytes that were typed
  600.     DAD    D        ;Effectively -> NEW - CURRENT =
  601.                 ; # of bytes left to write in HL
  602.     MOV    A,H        ;Get the MS value in A
  603.     INR    A        ;Bump it
  604.     ANA    A        ;Set any flags? (a -1?)
  605.     JNZ    WLOOP        ;No, then we have more to write.
  606.     POP    H        ;Clean the stack
  607.     JMP    EXIT
  608.  
  609. WEXIT:
  610.     CALL    ILPRT
  611.     DB CR,LF,LF,BELL
  612.     DB 'ERROR --> Can''t write file, ABORTING!'
  613.     DB CR,LF,LF,0
  614.  
  615.     JMP    LEAVE        ;Leave and do nothing
  616.  
  617. EXIT:
  618.     LXI    D,FCB        ;Point to filename
  619.     MVI    C,CLOSE        ;And close it
  620.     CALL    BDOS
  621.     CPI    YES        ;Successful?
  622.     JNZ    LEAVE        ;Zero = No
  623.  
  624.     CALL    ILPRT
  625.     DB CR,LF,LF,BELL
  626.     DB 'ERROR --> Can''t close file, ABORTING!'
  627.     DB CR,LF,LF,0
  628.  
  629. LEAVE:
  630.     MVI    C,SETDMA    ;Re-set the DMA
  631.     LXI    D,DEFBUF    ; so we don't
  632.     CALL    BDOS        ; mess up.
  633.  
  634.     LDA    OLDUSR        ;Get origional
  635.     MOV    E,A        ; user area and
  636.     MVI    C,USR        ; return us to
  637.     CALL    BDOS        ; there.
  638.     LHLD    STACK        ;Get origional SP
  639.     SPHL            ; for 'soft' return
  640.     RET
  641.  
  642. STOP:
  643.     CALL    ILPRT
  644.     DB CR,LF,LF
  645.     DB '* * *  ABORTED! - Nothing saved  * * *'
  646.     DB CR,LF,LF,0
  647.  
  648.     JMP    LEAVE
  649.  
  650. ; Create the file
  651. MAKEIT:
  652.     CALL    ILPRT
  653.     DB CR,LF
  654.     DB 'Creating file...'
  655.     DB CR,LF,LF,0
  656.  
  657.     LXI    D,FCB        ;We had to create it new
  658.     MVI    C,MAKE
  659.     CALL    BDOS
  660.     CPI    YES        ;successful?
  661.     LXI    H,BUFF        ;If we goto BEGIN....
  662.     SHLD    POINTR
  663.     JNZ    BEGIN        ;Zero = No
  664.  
  665.     CALL    ILPRT
  666.     DB CR,LF,LF,BELL
  667.     DB 'ERROR --> No directory space or trouble opening.'
  668.     DB CR,LF,LF
  669.     DB 'Please try again another time....'
  670.     DB CR,LF,LF,0
  671.  
  672.     JMP    EXIT
  673.  
  674. ;Search the current file and blank out the EOF mark...
  675. SEARCH:
  676.     LXI    D,BUFF        ;Point to beginning
  677.     LHLD    POINTR        ;Get current position
  678. SLOOP:
  679.     LDAX    D        ;Move byte into A
  680.     CPI    EOF        ;Was it the EOF?
  681.     JZ    NULLIT        ;Yep?, the zero it
  682.     INX    D        ;No?, then keep searching
  683.     DCX    H        ;Decrement the pointer
  684.     MOV    A,H        ;Find out if we have no
  685.     ORA    L        ; more positions
  686.     JZ    NULLERR        ;Just used for a double check
  687.     JMP    SLOOP        ;Else, check some more
  688. NULLIT:
  689.     XRA    A        ;Zero A
  690.     XCHG            ;Get position in HL
  691.     MOV    M,A        ;Put a '0' there
  692.     SHLD    POINTR        ;Save the area where our new
  693.     DCX    H        ;Save for later if we
  694.     SHLD    ORNPTR        ; need it...
  695.     RET            ; buffer starts
  696.  
  697. ; Enter here if we did not find an EOF mark in the available
  698. ; number of positions (double check)
  699. NULLERR:
  700.     CALL    ILPRT
  701.     DB BELL,CR,LF,LF
  702.     DB 'The validity of the file might be questioned'
  703.     DB CR,LF
  704.     DB 'Did NOT find the EOF, and should have!'
  705.     DB CR,LF,LF,0
  706.     RET
  707.  
  708. CSTAT:    JMP    $-$        ;Set upon entry
  709. CIN:    JMP    $-$        ; "    "    "
  710. COUT:    JMP    $-$        ; "    "    "
  711. COUNT:    DB    0
  712. OPT:    DB    NO
  713. TEMP:    DS    1
  714. MNYCNT:    DS    1
  715. OLDUSR:    DS    1
  716. POINTR:    DS    2
  717. ORNPTR:    DS    2
  718.  
  719.     DS    64        ;32 level stack
  720. STACK:
  721.     DS    2        ;Storge for incoming stack
  722.  
  723. BUFF    EQU    $        ;Message buffer starts here
  724.  
  725.     END
  726.