home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / bye5 / new.asm < prev    next >
Assembly Source File  |  1994-07-13  |  20KB  |  775 lines

  1. ; NEW05.ASM - Displays KMD.LOG in reverse order - 05/04/86
  2. ;
  3. ;                NEW.ASM
  4. ;                   by
  5. ;              Irvin M. Hoff
  6. ;         copyrighted for use with public domain
  7. ;             (17 July 1985)
  8. ;
  9.     ASEG            ; For M80 and RMAC, ignore if using MAC
  10. ;
  11. ;
  12. ; This program is really two-in-one.  It is for use with RCPM systems
  13. ; having a KMD.LOG of all file transfers created by the KMD file pgm.
  14. ;
  15. ;    Program 1 = shows the KMD.LOG in reverse order, newest first
  16. ;    Program 2 = shows only uploads in reverse, ignoring downloads
  17. ;
  18. ;=======================================================================
  19. ;                      Revisions
  20. ;
  21. ; 05/10/86  Sorry for another release, but an error came up when the
  22. ;    v06    file got to big.  Now it will be able to read up to
  23. ;           65000, 128 byte records.  I tested it on at 130+k file and
  24. ;           it work fine.
  25. ;                           Joubert Berger
  26. ;
  27. ; 05/04/86  Rewrote the entire read file section so it would read the
  28. ;    v05    the file backwards.  Now, there is no more wait while it
  29. ;           reads the entire file into memory.  On most RCPM's, users
  30. ;           only read the first few enteries anyway, so why bother
  31. ;           reading the entire file.  This was quit anoying.  So now it
  32. ;           will read the file one line at a time, backwards, and display
  33. ;           it like it is supposed to.  At the lable FILE: put in whatever
  34. ;        your up/download log file is called.
  35. ;
  36. ;           It struck me that one could use this program to read the
  37. ;           CALLER file of BBS systems.  This has come in handy many times
  38. ;           when I wanted to see who has called latley, and not have to
  39. ;           use TYPE or WS.  I renamed it to CALL.COM and changed the file
  40. ;        name at the lable FILE: to whatever my BBS caller file was called.
  41. ;        I set all options to zero and it worked great....
  42. ;                        Joubert Bergere
  43. ;                        Atlanta Kaypro MBBS
  44. ;                        (404) 923-258 [300/1200]
  45. ;
  46. ; 08/20/85  Redated for use with KMD04    - Irv Hoff
  47. ; 07/17/85  Original version for KMDxx    - Irv Hoff
  48. ;
  49. ;=======================================================================
  50. ;
  51. ; SHOWAL set to 0 - gives Program 1
  52. ; ---------------------------------
  53. ; When the SHOWAL option is set to "0", all files in the KMD.LOG are
  54. ; shown in reverse order.  This is particularly useful to SYSOPs to see
  55. ; who has most recently uploaded/downloaded any files and what they are.
  56. ; It can be placed in A15: with other private .COM files or A0: for all
  57. ; to use, if desired.  Call this program ALL.COM for easy reference.
  58. ;
  59. ; SHOWAL set to 1, gives Program 2
  60. ; --------------------------------
  61. ; This program displays the "R" (new files) entries entered by KMD.COM
  62. ; into the KMD.LOG file, in inverse order.  It replaces the WHATSNEW
  63. ; files used in the past for RCPM systems.  (If the wheel byte is set
  64. ; for the SYSOP's use, it includes any "P" private uploads.  These are
  65. ; shown with an "*" after the drive/user number.)  This program is de-
  66. ; signed to work with KMD.COM.    It may need to be customized slightly,
  67. ; depending on how your LASTCALR file is arranged.  It goes in the A0:
  68. ; area and can be called from any drive/user area.  It is essentially
  69. ; self-maintaining, which makes it quite different from WHATSNEW pro-
  70. ; grams previously used (made via D-29), etc.  It is 1k long and fully
  71. ; secure.  (Change equates below if your KMD.LOG isn't in A14: area.)
  72. ;
  73. ;    NOTE:  You can use DDT to set the following byte:
  74. ;
  75. ;        0103H 00 program 1, shows all file transfers
  76. ;              01 program 2, uploads only, for NEW.
  77. ;
  78. ;        Then  A>SAVE 5 NEW.COM
  79. ;
  80. ;        Suggestion:  Make one of each, call one ALL.COM
  81. ;        ahd put it on A15: for easy use by the SYSOP and
  82. ;        the other NEW.COM and put on A0: for all to use.
  83. ;
  84. ;-----------------------------------------------------------------------
  85. ;
  86. ; INFO:
  87. ; ----
  88. ;    A companion program currently called KMDEL automatically
  89. ;    deletes all downloaded files from KMD.LOG, keeping the
  90. ;    uploads for NEW.  This minimimizes the length of the KMD.LOG
  91. ;    file, since "most" of the lines are for downloads.  The com-
  92. ;    bination of NEW and KMDEL make the entire new file display
  93. ;    almost fully self-maintaining.
  94. ;
  95. ;-----------------------------------------------------------------------
  96. ;
  97. ; OPTIONS:
  98. ; -------
  99. ;    SHOWAL  0 = Shows all files in the KMD.LOG in reverse manner
  100. ;            Makes this into a second program, see below
  101. ;         1 = Allows options above to work normally
  102. ;
  103. ;    OPTION  0 = No header, shows "R" lines of KMD.LOG "as is".
  104. ;         1 = Header, uses example 1 below  (OxGate 001 system)
  105. ;         2 = Header, uses example 2 below  (Potpourri system)
  106. ;
  107. ;    HEADER  0 = No header, regardless of option below
  108. ;         1 = use header selected by option below
  109. ;
  110. ;---------------
  111. ;
  112. ; Example 0:  (no header, no changes, before and after the same.  Picks
  113. ;          out the "R" lines from the KMD.LOG and displays in re-
  114. ;          verse order (newest uploads, first).
  115. ;
  116. ;---------------
  117. ;
  118. ; Example 1:  OxGate 001
  119. ;
  120. ;        (before)
  121. ;
  122. ; R6 02:22 B00>M7DATA-1LBR        26k Irv Hoff 08/20/85
  123. ;
  124. ;        (after)
  125. ;
  126. ; D/U     Filename   Size   Speed    Uploaded by
  127. ;
  128. ; B00: M7DATA-1.LBR  26k  1200 bps  Irv Hoff 08/20/85
  129. ;
  130. ;---------------
  131. ;
  132. ; Example 2:  Potpourri
  133. ;
  134. ;        (before)
  135. ;
  136. ; R6 02:22 B00>M7DATA-1LBR        26k 08/20/85 16:44 Irv Hoff
  137. ;
  138. ;        (after)
  139. ;
  140. ; D/U     Filename   Size   Speed      Date    Time   Uploaded by
  141. ;
  142. ; B00: M7DATA-1.LBR  26k  1200 bps  08/20/85  16:44  Irv Hoff
  143. ;
  144. ;-----------------------------------------------------------------------
  145. ;
  146. ; Features:
  147. ; ---------
  148. ;    1) Should be placed in A0: so any user can call the program
  149. ;    2) Should be renamed to NEW.COM at that time
  150. ;    3) Automatically remembers current drive/user area
  151. ;    4) Jumps to A14: to read the KMD.LOG file, with full security
  152. ;    5) Opens the KMD.LOG file, if empty says "NO NEW FILES"
  153. ;    6) Copies each line starting with "R" into a one-line buffer
  154. ;    7) Customizes that line, if OPTION 1 or 2 is selected
  155. ;    8) Stores the line in a memory buffer
  156. ;    9) When all lines are read, displays them in inverse order,
  157. ;        thus showing most recent files first.
  158. ;      10) CTL-C, CTL-K, CTL-X, C, K, X, c, k, x all will abort after
  159. ;        finishing the current line.
  160. ;      11) Can be called from any drive/user area
  161. ;      12) Returns to original drive/user area from which it was called
  162. ;
  163. ; The SYSOP can readily customize this program to suit his preferences.
  164. ; The area around HEAD: would be the sections to customize if
  165. ; selection 1 or 2 is not sufficient.
  166. ;                    - Notes by Irv Hoff W6FFC
  167. ;
  168. ;-----------------------------------------------------------------------
  169. ;
  170. ; 07/17/85  First version based on my WHATSNEW, version 03.
  171. ;                    - Irv Hoff
  172. ;
  173. ;-----------------------------------------------------------------------
  174. ;
  175. ; User choices
  176. ;
  177. SHOWAL    EQU    1        ; 0=all file transfers, 1=uploads only
  178. OPTION    EQU    2        ; Must be 0, 1 or 2 (see above)
  179. HEADER    EQU    1        ; 0=no header, regardless of option
  180. ;
  181. DRIVE    EQU    'A'        ; KMD.LOG stored here in your system
  182. USER    EQU    14        ; KMD.LOG stored here in your system
  183. ;
  184. WHEEL    EQU    003EH        ; Location of wheel byte for RCPM use
  185. ;-----------------------------------------------------------------------
  186. ;
  187. ; Equates
  188. ;
  189. CR    EQU    0DH        ; Carriage return
  190. EOF    EQU    1AH        ; End of file - ^Z
  191. LF    EQU    0AH        ; Line feed
  192. TBUF    EQU    0080H        ; Default buffer address
  193. ;
  194. ;-----------------------------------------------------------------------
  195. ;
  196. ; BDOS equates
  197. ;
  198. BDOS    EQU    0005H        ; CP/M BDOS entry address
  199. RDCON    EQU    1        ; Get character from console
  200. WRCON    EQU    2        ; Write character to console
  201. PRINT    EQU    9        ; Print string (DE) until '$'
  202. CONST    EQU    11        ; Get console status function
  203. SELDSK    EQU    14        ; Select requested disk drive
  204. OPEN    EQU    15        ; Open disk file
  205. CLOSE    EQU    16        ; Close disk file
  206. READ    EQU    33        ; Read random file
  207. STDMA    EQU    26        ; Set DMA address
  208. SETUSR    EQU    32        ; Set user area on disk
  209. ;
  210. ;-----------------------------------------------------------------------
  211. ;
  212. ; Program starts here
  213. ;
  214. ;
  215.     ORG    100H
  216. ;
  217.     JMP    START
  218. ;
  219. ;
  220. SHOL:    DB    SHOWAL        ; Shows complete KMD.LOG in reverse
  221. OPTN:    DB    OPTION        ; Simple selection without assembling
  222. HDR:    DB    HEADER        ; Selects header option
  223. ;
  224. ;
  225. START:    LXI    H,0
  226.     DAD    SP        ; Get 'CCP' stack
  227.     SHLD    STACK        ; Save it for exit
  228.     LXI    SP,STACK    ; Set stack pointer
  229. ;
  230.     LDA    0004H        ; Get current drive/user
  231.     STA    DRUSER        ; Store
  232. ;
  233. ;
  234. ; Set drive/user to the KMD.LOG area listed above
  235. ;
  236.     MVI    E,USER        ; Set user to KMD.LOG area
  237.     MVI    C,SETUSR
  238.     CALL    BDOS
  239. ;
  240.     MVI    A,DRIVE        ; Set drive to KMD.LOG area
  241.     SUI    41H
  242.     MOV    E,A
  243.     MVI    C,SELDSK
  244.     CALL    BDOS
  245. ;
  246. ;
  247. ; Open source file
  248. ;
  249.     CALL    ILPRT
  250.     DB    CR,LF,0
  251.     LXI    D,FILE
  252.     MVI    C,OPEN
  253.     CALL    BDOS
  254.     INR    A        ; Check for no open
  255.     JZ    NONE        ; No file, exit
  256. ;
  257.     CALL    ILPRT
  258.     DB    'NEW Type ^S to pause, ^C, ^X or ^K to abort'
  259.     DB    CR,LF,LF,0
  260. ;
  261.     LXI    D,FILE
  262.     MVI    C,35        ; Determine end-of-file
  263.     CALL    BDOS
  264.     LXI    D,BUFFER+81    ; Stick a CR so it will get by the first time
  265.     MVI    A,CR
  266.     STAX    D        ; Save it now
  267.     DCR    E
  268.     CALL    HEAD
  269. ;
  270. READX:    PUSH    D
  271.     LXI    H,RECORD    ; Decrement record counter
  272.     MOV    E,M        ; Get 16 bit number into DE
  273.     INX    H
  274.     MOV    D,M
  275.     DCX    D        ; Now that we have the number, decrement
  276.     MOV    M,D        ; And now store it again
  277.     DCX    H
  278.     MOV    M,E
  279.     MOV    A,E        ; Now lets see if we are at the end
  280.     CPI    0FFH        ; First check high #
  281.     JNZ    READLP        ; Ok, go on - else,, check low number
  282.     MOV    A,D
  283.     CPI    0FFH        ; One past zero, so we can get the last record
  284.     JZ    TDONE        ; We are at the end, so now finished with job
  285. ;
  286. ;
  287. ; Read sector from source file
  288. ;
  289. READLP: LXI    D,TBUF        ; Set the DMA for our read
  290.     MVI    C,STDMA
  291.      CALL    BDOS        ; And do it now
  292. ;
  293.     LXI    D,FILE        ; Now read the record
  294.     MVI    C,READ
  295.     CALL    BDOS
  296.     POP    D        ; Restore register
  297. ;
  298.     ORA    A        ; Read ok?
  299.     JZ    GOAHEAD        ; Yes, procede
  300.     CALL    EXIT
  301.     DB    CR,LF,'++ SOURCE FILE READ ERROR ++','$'
  302. ;
  303. GOAHEAD:LXI    H,TBUF+127    ; Set up end of buffer
  304.     MVI    B,128        ; The buffer will be filed up backwards
  305. ONEMORE:MOV    A,M        ; Get character
  306.     ANI    7FH
  307.     CPI    LF        ; Check for end of line -- LF is our marker
  308.     JZ    WRDISK        ;  that we will use to determine each line
  309.     CPI    7FH
  310.     JZ    NEXTONE
  311.     CPI    1AH        ; Check for CTRL-Z, end-of-file marker
  312.     JZ    NEXTONE
  313.     XCHG
  314.     MOV    M,A        ; Store character in our working buffer
  315.     XCHG
  316.     DCR    E        ; Decrement counters (DE=work buffer)
  317. NEXTONE:DCR    L        ;              (HL=DMA)
  318.     DCR    B        ;              (B=Counter for number of char.)
  319.     JZ    READX        ; If zero, go read another record
  320.     JMP    ONEMORE
  321. ;
  322. ; Write sector to output file (with buffering)
  323. ;
  324. WRDISK:    DCR    B        ; Decrement our counter
  325.     PUSH    PSW        ; As well as the flags
  326.     DCR    L        ; Decrement our DMA buffer
  327.     PUSH    H        ; Save it
  328.     PUSH    B        ; Save counter
  329.     XCHG            ; HL will now be our working buffer
  330.     MOV    M,A        ; Go save CR
  331.     LDA    SHOL        ; Check options
  332.     ORA    A
  333.     JZ    WRDLOP        ; If show all, go show all now
  334.     INR    L        ; If not, go see if it is a uploaded file
  335.     MOV    A,M
  336.     STA    STORE2        ; Store this away for later
  337.     DCR    L
  338.     CPI    'S'        ; Was this a "Send" file
  339.     JZ    SENDX        ; Yes, so go on
  340.     CPI    'L'        ; A "Library" file
  341.     JZ    SENDX        ; Yes, so go on
  342.     LDA    WHEEL        ; Check wheel for private files
  343.     ORA    A
  344.     JNZ    WRDLOP        ; Ok, cheeck if it was a private file
  345.     LDA    STORE2
  346.     CPI    'P'        ; It was Private, and wheel was not set, 
  347.     JZ    SENDX        ; So goodbye
  348. ;
  349. WRDLOP:    MOV    A,M        ; Get byte from read buffer
  350.     MOV    B,A        ; Save the character for now
  351.     CPI    CR
  352.     JZ    SENDLF        ; Go send a CR and start all over again
  353.     CPI    LF        ; If LF then just send it to output
  354.     JZ    SEND
  355. ;
  356. ; Will show entire KMD.LOG in reverse if requested
  357. ;
  358.      LDA    SHOL        ; Check to see if show entire file
  359.     ORA    A
  360.     JZ    SEND
  361.     LDA    COLUMN        ; See if in first column
  362.     ORA    A
  363.     JNZ    WRDL3        ; If not, exit
  364.     INR    A
  365.     STA    COLUMN        ; Won't be in first column any longer
  366. ;
  367. ;
  368. ; Shows "P" entries only if wheel byte is set for SYSOP's use
  369. ;
  370.     MOV    A,B        ; Get the character back
  371.     CPI    'P'        ; This line a private upload?
  372.     JNZ    WRDL1        ; If not, exit
  373.     LDA    WHEEL
  374.     ORA    A
  375.     JZ    WRD2        ; "P" lines not shown without wheel byte
  376.     STA    PRIVT        ; To distinguish "P" lines when shown
  377.     STA    STORE        ; Just in case it is
  378.     JMP    WRDL4
  379. ;
  380. WRDL1:    CPI    'S'
  381.     JNZ    WRDL11
  382.     XRA    A
  383.     STA    STORE
  384.     STA    COLUMN
  385.     JMP    SENDX
  386. ;
  387. WRDL11:    CPI    'R'        ; This a "received file"?
  388.     STA    STORE        ; Set the flag just in case
  389.     JZ    WRDL4        ; If 'R', keep the flag set
  390. ;
  391. WRD2:    XRA    A
  392.     STA    STORE        ; Otherwise reset flag to zero
  393. ;
  394. WRDL3:    LDA    STORE        ; Storing into memory?
  395.     ORA    A
  396.     JZ    NEXT        ; If not, exit
  397. ;
  398. WRDL4:    LDA    COLUMN        ; Increment the column counter
  399.     INR    A
  400.     STA    COLUMN
  401. ;
  402. ;
  403. ; The following retains original format of KMD "R" lines
  404. ;
  405.     LDA    OPTN        ; Get option
  406.     ORA    A
  407.     JZ    SEND        ; If not customizing, exit
  408.     LDA    COLUMN        ; Get the column count back
  409.     CPI    3        ; User's modem speed is in column 2
  410.     JNZ    WR1        ; If not column 2, continue
  411.     MOV    A,B        ; Otherwise get the character
  412.     STA    STORE        ; Store it for conversion to baud rate
  413.     JMP    NEXT        ; Do not print the "MSPEED" number
  414. ;
  415. WR1:    CPI    11
  416.     JC    NEXT        ; Skip everything through column 9
  417.     CPI    14
  418.     JC    SEND        ; Print everything through column 12
  419.     JNZ    WR4
  420.     LDA    PRIVT        ; Going to distinguish a "P" line?
  421.     ORA    A
  422.     JZ    WR2
  423.     XRA    A
  424.     STA    PRIVT
  425.     MVI    B,'*'
  426.     CALL    SEND1
  427.     JMP    WR3
  428.  
  429. ;
  430. WR2:    MVI    B,':'        ; Stick in a colon after column 12
  431.     CALL    SEND1
  432. ;
  433. WR3:    MVI    B,' '        ; Send a space
  434.     JMP    SEND
  435. ;
  436. WR4:    CPI    22        ; Print through column 20
  437.     JC    SEND
  438.     JNZ    WR5
  439.     CALL    SEND1        ; Send character in colum 21
  440.     MVI    B,'.'        ; Add a period after the file name
  441.     JMP    SEND
  442. ;
  443. WR5:    CPI    27
  444.     JC    SEND        ; Print file type and some spaces
  445.     CPI    39
  446.     JC    NEXT        ; Ignore the "big gap"
  447.     CPI    43
  448.     JC    SEND        ; Print the file size
  449.     JZ    WR6
  450. ;
  451. ;
  452. ; Customizes area after the file size
  453. ;
  454.     LDA    OPTN
  455.     CPI    1
  456.     JZ    SEND        ; If option 2, exit
  457.     LDA    COLUMN        ; Get the column count back again
  458.     JMP    WR7        ; If not column 42, continue
  459. ;
  460. WR6:    CALL    SEND1        ; Print first space
  461.     CALL    SEND1        ; Add two extras
  462.     CALL    BAUD        ; Print the baud rate and two spaces
  463.     JMP    NEXT
  464. ;
  465. WR7:    CPI    52
  466.     JC    SEND        ; Print the date
  467.     JNZ    WR8
  468.     CALL    SEND1        ; Print first space after date
  469.     JMP    SEND        ; Add a space
  470. ;
  471. WR8:    CPI    58
  472.     JC    SEND        ; Print the time program was sent
  473.     JNZ    SEND        ; If not column 57, continue
  474.     CALL    SEND1        ; Print the first space
  475.     CALL    SEND1        ; Add two spaces
  476.     JMP    NEXT        ; Continue with rest of line (name)
  477. ;
  478. SEND:    PUSH    H        ; Keep buffer address
  479.     MOV    A,B        ; Get the character back
  480.     CALL    OUTCHR
  481.     POP    H        ; Get input buffer address back
  482. ;
  483. NEXT:    INR    L        ; Done with sector?
  484.     JMP    WRDLOP        ; No, get another byte
  485. ;...
  486. ;
  487. ;
  488. SEND1:    PUSH    H        ; Keep buffer address
  489.     MOV    A,B        ; Get the character back
  490.     CALL    OUTCHR
  491.     POP    H        ; Get input buffer address back
  492.     RET
  493. ;.....
  494. ;
  495. ;
  496. SENDLF:    XRA    A
  497.     STA    COLUMN        ; Othewise in column 0 now
  498.     CALL    ABORT        ; Want to quit already?
  499. ;
  500. SENDL1:    LDA    COUNT
  501.     INR    A        ; Just to get a positive value
  502.     STA    COUNT        ; Have at least one line to show
  503.     CALL    ILPRT
  504.     DB    CR,0
  505. SENDX:    XRA    A        ; Now restore everything so 
  506.     STA    COLUMN        ; We can get on with our business
  507.     LXI    D,BUFFER+80
  508.     POP    B
  509.     POP    H
  510.     POP    PSW
  511.     JZ    READX        ; If we out of character in DMA buffer, 
  512.     JMP    ONEMORE        ;  go read  a sector
  513. ;.....
  514. ;
  515. ;
  516. ;-----------------------------------------------------------------------
  517. ;
  518. ;              SUBROUTINES
  519. ;
  520. ;-----------------------------------------------------------------------
  521. ;
  522. ; Aborts the display when requested, but only at end of line
  523. ;
  524. ABORT:    PUSH    H        ; Save the TBUF address
  525.     PUSH    D
  526.     PUSH    B
  527.     MVI    C,CONST        ; Check to see if key pressed
  528.     CALL    BDOS
  529.     ORA    A
  530.     JZ    ABORT3        ; If no key pressed, then continue
  531.     MVI    C,RDCON        ; If key pressed, then check for abort
  532.     ANI    7FH        ; Remove parity, insure upper-case
  533.     CALL    BDOS
  534.     CPI    'S'-40H        ; CTL-S to pause?
  535.     JNZ    ABORT1        ; If not, exit
  536.     MVI    C,RDCON        ; Otherwise wait for another character
  537.     CALL    BDOS
  538.     ANI    7FH        ; Remove parity, insure upper-case
  539. ;
  540. ABORT1:    CPI    'C'-40H        ; Is it CTL-C?
  541.     JZ    ABORT2
  542.     CPI    'K'-40H        ; Is it CTL-K?
  543.     JZ    ABORT2        ; If no, then continue
  544.     CPI    'X'-40H        ; Is it CTL-X?
  545.     JZ    ABORT2
  546.     ANI    5FH        ; Convert to upper-case
  547.     CPI    'C'
  548.     JZ    ABORT2
  549.     CPI    'K'
  550.     JZ    ABORT2
  551.     CPI    'X'
  552.     JNZ    ABORT3
  553. ;
  554. ABORT2:    POP    B        ; Reset the stack
  555.     POP    D
  556.     POP    H
  557.     POP    H        ; Clear "CALL ABORT" from stack
  558.     CALL    EXIT        ; If yes, then print abort message
  559.     DB    CR,LF,LF,'++ ABORTED ++','$'
  560. ;
  561. ABORT3:    POP    B
  562.     POP    D
  563.     POP    H
  564.     RET
  565. ;.....
  566. ;
  567. ;
  568. ; Shows the received baud rate
  569. ;
  570. BAUD:    LDA    STORE
  571.     CPI    '0'
  572.     JZ    B110
  573.     CPI    '1'
  574.     JZ    B300
  575.     CPI    '5'
  576.     JZ    B1200
  577.     CPI    '6'
  578.     JZ    B2400
  579.     MVI    B,' '
  580.     CALL    SEND1
  581.     CALL    SEND1
  582.     CALL    SEND1
  583.     CALL    SEND1
  584.     JMP    BFIN2
  585. ;...
  586. ;
  587. ;
  588. B110:    MVI    B,' '
  589.     CALL    SEND1
  590.     MVI    B,'1'
  591.     CALL    SEND1
  592.     MVI    B,'1'
  593.     CALL    SEND1
  594.     JMP    BFIN1
  595. ;
  596. B300:    MVI    B,' '
  597.     CALL    SEND1
  598.     MVI    B,'3'
  599.     JMP    BFINSH
  600. ;
  601. B1200:    MVI    B,'1'
  602.     CALL    SEND1
  603.     MVI    B,'2'
  604.     JMP    BFINSH
  605. ;
  606. B2400:    MVI    B,'2'
  607.     CALL    SEND1
  608.     MVI    B,'4'
  609. ;
  610. BFINSH:    CALL    SEND1
  611.     MVI    B,'0'
  612.     CALL    SEND1
  613. ;
  614. BFIN1:    MVI    B,'0'
  615.     CALL    SEND1
  616. ;
  617. BFIN2:    MVI    B,' '
  618.     CALL    SEND1
  619.     MVI    B,'b'
  620.     CALL    SEND1
  621.     MVI    B,'p'
  622.     CALL    SEND1
  623.     MVI    B,'s'
  624.     CALL    SEND1
  625.     MVI    B,' '
  626.     CALL    SEND1
  627.     MVI    B,' '
  628.     JMP    SEND1
  629. ;.....
  630. ;
  631. ;
  632. ; Print message then exit to CP/M
  633. ;
  634. EXIT:    POP    D        ; Get message address
  635.     MVI    C,PRINT        ; Print message
  636.     CALL    BDOS
  637.     CALL    ILPRT        ; Print CRLF before quitting
  638.     DB    CR,LF,0
  639. ;
  640.     LDA    DRUSER        ; Get original drive/user area back
  641.     RAR
  642.     RAR
  643.     RAR
  644.     RAR
  645.     ANI    0FH        ; Just look at the user area
  646.     MOV    E,A
  647.     MVI    C,SETUSR    ; Restore original user area
  648.     CALL    BDOS
  649. ;
  650.     LDA    DRUSER        ; Get the original drive/user back
  651.     ANI    0FH        ; Just look at the drive for now
  652.     MOV    E,A
  653.     MVI    C,SELDSK    ; Restore original drive
  654.     CALL    BDOS
  655. ;
  656.     LHLD    STACK
  657.     SPHL
  658.     RET
  659. ;.....
  660. ;
  661. ;
  662. ; Inline print routine - prints string pointed to by stack until a zero
  663. ; is found.  Returns to caller at the next address after the zero ter-
  664. ; minator.
  665. ;
  666. ILPRT:    XTHL            ; Save HL, get message address
  667. ;
  668. ILPLP:    MOV    A,M        ; Get the character
  669.     CALL    TYPE        ; Show on the CRT
  670.     INX    H        ; Next character location
  671.     MOV    A,M        ; Get the character
  672.     ORA    A        ; If Zero, all done
  673.     JNZ    ILPLP        ; Else keep going
  674.     XTHL            ; Restore HL, ret address
  675.     RET            ; Return past the end of the message
  676. ;.....
  677. ;
  678. ;
  679. ; Output a character to the new file buffer - first, see if there is
  680. ; room in the buffer for this character.
  681. ;
  682. OUTCHR:    PUSH    PSW        ; Store the character for now
  683.     CALL    TYPE
  684.     POP    PSW
  685.     RET
  686. ;.....
  687. ;
  688. ;
  689. ; Transfer is done - close destination file
  690. ;
  691. TDONE:    MVI    C,CLOSE
  692.     LXI    D,FILE
  693.     CALL    BDOS
  694. TDONE2:    CALL    EXIT
  695.     DB    CR,LF,LF,CR,'[End of listing]','$'
  696. ;.....
  697. ;
  698. ;
  699. ;  Show the header at the beginning
  700. ;
  701. HEAD:    LDA    HDR        ; Using a header?
  702.     ORA    A
  703.     RZ            ; If not skip header
  704.     LDA    SHOL        ; Showing entire KMD.LOG?
  705.     ORA    A
  706.     RZ            ; If yes, don't bother with header
  707. ;
  708. ;
  709. ; Customizes header
  710. ;
  711.     LDA    OPTN
  712.     ORA    A
  713.     RZ
  714.     CALL    ILPRT
  715.     DB    CR,'D/U    Filename   Size   Speed    ',0
  716.     LDA    OPTN
  717.     CPI    1
  718.     JZ    TDONE1
  719.     CALL    ILPRT
  720.     DB    '  Date    Time   Uploaded by',0
  721.     RET
  722. ;
  723. TDONE1:    CALL    ILPRT
  724.     DB    'Uploaded by  Date',0
  725.     RET
  726. ;.....
  727. ;
  728. ;
  729. ; Send character in A register to console
  730. ;
  731. TYPE:    PUSH    B
  732.     PUSH    D
  733.     PUSH    H
  734.     MOV    E,A        ; Character to 'E' for CP/M
  735.     MVI    C,WRCON        ; Write to console
  736.     CALL    BDOS
  737.     POP    H
  738.     POP    D
  739.     POP    B
  740.     RET
  741. ;.....
  742. ;
  743. ;
  744. NONE:    CALL    EXIT
  745.     DB    CR,'++ NO NEW FILES ++','$'
  746. ;
  747. ;
  748. ; 'Declare' output file
  749. ;
  750. FILE:    DB    0
  751.     DB    'LOG     SYS'
  752.     DB    0,0,0,0,0,0,0,0,0,0,0
  753.     DB    0,0,0,0,0,0,0,0,0,0
  754. RECORD:    DB    0,0,0
  755. ;
  756. COLUMN:    DB    0        ; Column of KMD.LOG line
  757. COUNT:    DB    0
  758. DRUSER:    DB    0        ; Original drive/user, for return
  759. LENGTH:    DB    0        ; Maximum length of useable memory
  760. PRIVT:    DB    0        ; Distinguishes "P" lines if shown
  761. STORE:    DB    0
  762. STORE2:    DB    0
  763. ;
  764.     DS    100        ; Room for 50-level stack
  765. ;
  766. ;
  767. ; Set write buffer to even page boundry
  768. ;
  769. ;
  770. BUFFER    DS    81        ; Write buffer starts here
  771. STACK    EQU    BUFFER-2
  772. ;
  773. ;
  774.     END    START
  775. ; Set