home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
bye5
/
new.asm
< prev
next >
Wrap
Assembly Source File
|
1994-07-13
|
20KB
|
775 lines
; NEW05.ASM - Displays KMD.LOG in reverse order - 05/04/86
;
; NEW.ASM
; by
; Irvin M. Hoff
; copyrighted for use with public domain
; (17 July 1985)
;
ASEG ; For M80 and RMAC, ignore if using MAC
;
;
; This program is really two-in-one. It is for use with RCPM systems
; having a KMD.LOG of all file transfers created by the KMD file pgm.
;
; Program 1 = shows the KMD.LOG in reverse order, newest first
; Program 2 = shows only uploads in reverse, ignoring downloads
;
;=======================================================================
; Revisions
;
; 05/10/86 Sorry for another release, but an error came up when the
; v06 file got to big. Now it will be able to read up to
; 65000, 128 byte records. I tested it on at 130+k file and
; it work fine.
; Joubert Berger
;
; 05/04/86 Rewrote the entire read file section so it would read the
; v05 the file backwards. Now, there is no more wait while it
; reads the entire file into memory. On most RCPM's, users
; only read the first few enteries anyway, so why bother
; reading the entire file. This was quit anoying. So now it
; will read the file one line at a time, backwards, and display
; it like it is supposed to. At the lable FILE: put in whatever
; your up/download log file is called.
;
; It struck me that one could use this program to read the
; CALLER file of BBS systems. This has come in handy many times
; when I wanted to see who has called latley, and not have to
; use TYPE or WS. I renamed it to CALL.COM and changed the file
; name at the lable FILE: to whatever my BBS caller file was called.
; I set all options to zero and it worked great....
; Joubert Bergere
; Atlanta Kaypro MBBS
; (404) 923-258 [300/1200]
;
; 08/20/85 Redated for use with KMD04 - Irv Hoff
; 07/17/85 Original version for KMDxx - Irv Hoff
;
;=======================================================================
;
; SHOWAL set to 0 - gives Program 1
; ---------------------------------
; When the SHOWAL option is set to "0", all files in the KMD.LOG are
; shown in reverse order. This is particularly useful to SYSOPs to see
; who has most recently uploaded/downloaded any files and what they are.
; It can be placed in A15: with other private .COM files or A0: for all
; to use, if desired. Call this program ALL.COM for easy reference.
;
; SHOWAL set to 1, gives Program 2
; --------------------------------
; This program displays the "R" (new files) entries entered by KMD.COM
; into the KMD.LOG file, in inverse order. It replaces the WHATSNEW
; files used in the past for RCPM systems. (If the wheel byte is set
; for the SYSOP's use, it includes any "P" private uploads. These are
; shown with an "*" after the drive/user number.) This program is de-
; signed to work with KMD.COM. It may need to be customized slightly,
; depending on how your LASTCALR file is arranged. It goes in the A0:
; area and can be called from any drive/user area. It is essentially
; self-maintaining, which makes it quite different from WHATSNEW pro-
; grams previously used (made via D-29), etc. It is 1k long and fully
; secure. (Change equates below if your KMD.LOG isn't in A14: area.)
;
; NOTE: You can use DDT to set the following byte:
;
; 0103H 00 program 1, shows all file transfers
; 01 program 2, uploads only, for NEW.
;
; Then A>SAVE 5 NEW.COM
;
; Suggestion: Make one of each, call one ALL.COM
; ahd put it on A15: for easy use by the SYSOP and
; the other NEW.COM and put on A0: for all to use.
;
;-----------------------------------------------------------------------
;
; INFO:
; ----
; A companion program currently called KMDEL automatically
; deletes all downloaded files from KMD.LOG, keeping the
; uploads for NEW. This minimimizes the length of the KMD.LOG
; file, since "most" of the lines are for downloads. The com-
; bination of NEW and KMDEL make the entire new file display
; almost fully self-maintaining.
;
;-----------------------------------------------------------------------
;
; OPTIONS:
; -------
; SHOWAL 0 = Shows all files in the KMD.LOG in reverse manner
; Makes this into a second program, see below
; 1 = Allows options above to work normally
;
; OPTION 0 = No header, shows "R" lines of KMD.LOG "as is".
; 1 = Header, uses example 1 below (OxGate 001 system)
; 2 = Header, uses example 2 below (Potpourri system)
;
; HEADER 0 = No header, regardless of option below
; 1 = use header selected by option below
;
;---------------
;
; Example 0: (no header, no changes, before and after the same. Picks
; out the "R" lines from the KMD.LOG and displays in re-
; verse order (newest uploads, first).
;
;---------------
;
; Example 1: OxGate 001
;
; (before)
;
; R6 02:22 B00>M7DATA-1LBR 26k Irv Hoff 08/20/85
;
; (after)
;
; D/U Filename Size Speed Uploaded by
;
; B00: M7DATA-1.LBR 26k 1200 bps Irv Hoff 08/20/85
;
;---------------
;
; Example 2: Potpourri
;
; (before)
;
; R6 02:22 B00>M7DATA-1LBR 26k 08/20/85 16:44 Irv Hoff
;
; (after)
;
; D/U Filename Size Speed Date Time Uploaded by
;
; B00: M7DATA-1.LBR 26k 1200 bps 08/20/85 16:44 Irv Hoff
;
;-----------------------------------------------------------------------
;
; Features:
; ---------
; 1) Should be placed in A0: so any user can call the program
; 2) Should be renamed to NEW.COM at that time
; 3) Automatically remembers current drive/user area
; 4) Jumps to A14: to read the KMD.LOG file, with full security
; 5) Opens the KMD.LOG file, if empty says "NO NEW FILES"
; 6) Copies each line starting with "R" into a one-line buffer
; 7) Customizes that line, if OPTION 1 or 2 is selected
; 8) Stores the line in a memory buffer
; 9) When all lines are read, displays them in inverse order,
; thus showing most recent files first.
; 10) CTL-C, CTL-K, CTL-X, C, K, X, c, k, x all will abort after
; finishing the current line.
; 11) Can be called from any drive/user area
; 12) Returns to original drive/user area from which it was called
;
; The SYSOP can readily customize this program to suit his preferences.
; The area around HEAD: would be the sections to customize if
; selection 1 or 2 is not sufficient.
; - Notes by Irv Hoff W6FFC
;
;-----------------------------------------------------------------------
;
; 07/17/85 First version based on my WHATSNEW, version 03.
; - Irv Hoff
;
;-----------------------------------------------------------------------
;
; User choices
;
SHOWAL EQU 1 ; 0=all file transfers, 1=uploads only
OPTION EQU 2 ; Must be 0, 1 or 2 (see above)
HEADER EQU 1 ; 0=no header, regardless of option
;
DRIVE EQU 'A' ; KMD.LOG stored here in your system
USER EQU 14 ; KMD.LOG stored here in your system
;
WHEEL EQU 003EH ; Location of wheel byte for RCPM use
;-----------------------------------------------------------------------
;
; Equates
;
CR EQU 0DH ; Carriage return
EOF EQU 1AH ; End of file - ^Z
LF EQU 0AH ; Line feed
TBUF EQU 0080H ; Default buffer address
;
;-----------------------------------------------------------------------
;
; BDOS equates
;
BDOS EQU 0005H ; CP/M BDOS entry address
RDCON EQU 1 ; Get character from console
WRCON EQU 2 ; Write character to console
PRINT EQU 9 ; Print string (DE) until '$'
CONST EQU 11 ; Get console status function
SELDSK EQU 14 ; Select requested disk drive
OPEN EQU 15 ; Open disk file
CLOSE EQU 16 ; Close disk file
READ EQU 33 ; Read random file
STDMA EQU 26 ; Set DMA address
SETUSR EQU 32 ; Set user area on disk
;
;-----------------------------------------------------------------------
;
; Program starts here
;
;
ORG 100H
;
JMP START
;
;
SHOL: DB SHOWAL ; Shows complete KMD.LOG in reverse
OPTN: DB OPTION ; Simple selection without assembling
HDR: DB HEADER ; Selects header option
;
;
START: LXI H,0
DAD SP ; Get 'CCP' stack
SHLD STACK ; Save it for exit
LXI SP,STACK ; Set stack pointer
;
LDA 0004H ; Get current drive/user
STA DRUSER ; Store
;
;
; Set drive/user to the KMD.LOG area listed above
;
MVI E,USER ; Set user to KMD.LOG area
MVI C,SETUSR
CALL BDOS
;
MVI A,DRIVE ; Set drive to KMD.LOG area
SUI 41H
MOV E,A
MVI C,SELDSK
CALL BDOS
;
;
; Open source file
;
CALL ILPRT
DB CR,LF,0
LXI D,FILE
MVI C,OPEN
CALL BDOS
INR A ; Check for no open
JZ NONE ; No file, exit
;
CALL ILPRT
DB 'NEW Type ^S to pause, ^C, ^X or ^K to abort'
DB CR,LF,LF,0
;
LXI D,FILE
MVI C,35 ; Determine end-of-file
CALL BDOS
LXI D,BUFFER+81 ; Stick a CR so it will get by the first time
MVI A,CR
STAX D ; Save it now
DCR E
CALL HEAD
;
READX: PUSH D
LXI H,RECORD ; Decrement record counter
MOV E,M ; Get 16 bit number into DE
INX H
MOV D,M
DCX D ; Now that we have the number, decrement
MOV M,D ; And now store it again
DCX H
MOV M,E
MOV A,E ; Now lets see if we are at the end
CPI 0FFH ; First check high #
JNZ READLP ; Ok, go on - else,, check low number
MOV A,D
CPI 0FFH ; One past zero, so we can get the last record
JZ TDONE ; We are at the end, so now finished with job
;
;
; Read sector from source file
;
READLP: LXI D,TBUF ; Set the DMA for our read
MVI C,STDMA
CALL BDOS ; And do it now
;
LXI D,FILE ; Now read the record
MVI C,READ
CALL BDOS
POP D ; Restore register
;
ORA A ; Read ok?
JZ GOAHEAD ; Yes, procede
CALL EXIT
DB CR,LF,'++ SOURCE FILE READ ERROR ++','$'
;
GOAHEAD:LXI H,TBUF+127 ; Set up end of buffer
MVI B,128 ; The buffer will be filed up backwards
ONEMORE:MOV A,M ; Get character
ANI 7FH
CPI LF ; Check for end of line -- LF is our marker
JZ WRDISK ; that we will use to determine each line
CPI 7FH
JZ NEXTONE
CPI 1AH ; Check for CTRL-Z, end-of-file marker
JZ NEXTONE
XCHG
MOV M,A ; Store character in our working buffer
XCHG
DCR E ; Decrement counters (DE=work buffer)
NEXTONE:DCR L ; (HL=DMA)
DCR B ; (B=Counter for number of char.)
JZ READX ; If zero, go read another record
JMP ONEMORE
;
; Write sector to output file (with buffering)
;
WRDISK: DCR B ; Decrement our counter
PUSH PSW ; As well as the flags
DCR L ; Decrement our DMA buffer
PUSH H ; Save it
PUSH B ; Save counter
XCHG ; HL will now be our working buffer
MOV M,A ; Go save CR
LDA SHOL ; Check options
ORA A
JZ WRDLOP ; If show all, go show all now
INR L ; If not, go see if it is a uploaded file
MOV A,M
STA STORE2 ; Store this away for later
DCR L
CPI 'S' ; Was this a "Send" file
JZ SENDX ; Yes, so go on
CPI 'L' ; A "Library" file
JZ SENDX ; Yes, so go on
LDA WHEEL ; Check wheel for private files
ORA A
JNZ WRDLOP ; Ok, cheeck if it was a private file
LDA STORE2
CPI 'P' ; It was Private, and wheel was not set,
JZ SENDX ; So goodbye
;
WRDLOP: MOV A,M ; Get byte from read buffer
MOV B,A ; Save the character for now
CPI CR
JZ SENDLF ; Go send a CR and start all over again
CPI LF ; If LF then just send it to output
JZ SEND
;
; Will show entire KMD.LOG in reverse if requested
;
LDA SHOL ; Check to see if show entire file
ORA A
JZ SEND
LDA COLUMN ; See if in first column
ORA A
JNZ WRDL3 ; If not, exit
INR A
STA COLUMN ; Won't be in first column any longer
;
;
; Shows "P" entries only if wheel byte is set for SYSOP's use
;
MOV A,B ; Get the character back
CPI 'P' ; This line a private upload?
JNZ WRDL1 ; If not, exit
LDA WHEEL
ORA A
JZ WRD2 ; "P" lines not shown without wheel byte
STA PRIVT ; To distinguish "P" lines when shown
STA STORE ; Just in case it is
JMP WRDL4
;
WRDL1: CPI 'S'
JNZ WRDL11
XRA A
STA STORE
STA COLUMN
JMP SENDX
;
WRDL11: CPI 'R' ; This a "received file"?
STA STORE ; Set the flag just in case
JZ WRDL4 ; If 'R', keep the flag set
;
WRD2: XRA A
STA STORE ; Otherwise reset flag to zero
;
WRDL3: LDA STORE ; Storing into memory?
ORA A
JZ NEXT ; If not, exit
;
WRDL4: LDA COLUMN ; Increment the column counter
INR A
STA COLUMN
;
;
; The following retains original format of KMD "R" lines
;
LDA OPTN ; Get option
ORA A
JZ SEND ; If not customizing, exit
LDA COLUMN ; Get the column count back
CPI 3 ; User's modem speed is in column 2
JNZ WR1 ; If not column 2, continue
MOV A,B ; Otherwise get the character
STA STORE ; Store it for conversion to baud rate
JMP NEXT ; Do not print the "MSPEED" number
;
WR1: CPI 11
JC NEXT ; Skip everything through column 9
CPI 14
JC SEND ; Print everything through column 12
JNZ WR4
LDA PRIVT ; Going to distinguish a "P" line?
ORA A
JZ WR2
XRA A
STA PRIVT
MVI B,'*'
CALL SEND1
JMP WR3
;
WR2: MVI B,':' ; Stick in a colon after column 12
CALL SEND1
;
WR3: MVI B,' ' ; Send a space
JMP SEND
;
WR4: CPI 22 ; Print through column 20
JC SEND
JNZ WR5
CALL SEND1 ; Send character in colum 21
MVI B,'.' ; Add a period after the file name
JMP SEND
;
WR5: CPI 27
JC SEND ; Print file type and some spaces
CPI 39
JC NEXT ; Ignore the "big gap"
CPI 43
JC SEND ; Print the file size
JZ WR6
;
;
; Customizes area after the file size
;
LDA OPTN
CPI 1
JZ SEND ; If option 2, exit
LDA COLUMN ; Get the column count back again
JMP WR7 ; If not column 42, continue
;
WR6: CALL SEND1 ; Print first space
CALL SEND1 ; Add two extras
CALL BAUD ; Print the baud rate and two spaces
JMP NEXT
;
WR7: CPI 52
JC SEND ; Print the date
JNZ WR8
CALL SEND1 ; Print first space after date
JMP SEND ; Add a space
;
WR8: CPI 58
JC SEND ; Print the time program was sent
JNZ SEND ; If not column 57, continue
CALL SEND1 ; Print the first space
CALL SEND1 ; Add two spaces
JMP NEXT ; Continue with rest of line (name)
;
SEND: PUSH H ; Keep buffer address
MOV A,B ; Get the character back
CALL OUTCHR
POP H ; Get input buffer address back
;
NEXT: INR L ; Done with sector?
JMP WRDLOP ; No, get another byte
;...
;
;
SEND1: PUSH H ; Keep buffer address
MOV A,B ; Get the character back
CALL OUTCHR
POP H ; Get input buffer address back
RET
;.....
;
;
SENDLF: XRA A
STA COLUMN ; Othewise in column 0 now
CALL ABORT ; Want to quit already?
;
SENDL1: LDA COUNT
INR A ; Just to get a positive value
STA COUNT ; Have at least one line to show
CALL ILPRT
DB CR,0
SENDX: XRA A ; Now restore everything so
STA COLUMN ; We can get on with our business
LXI D,BUFFER+80
POP B
POP H
POP PSW
JZ READX ; If we out of character in DMA buffer,
JMP ONEMORE ; go read a sector
;.....
;
;
;-----------------------------------------------------------------------
;
; SUBROUTINES
;
;-----------------------------------------------------------------------
;
; Aborts the display when requested, but only at end of line
;
ABORT: PUSH H ; Save the TBUF address
PUSH D
PUSH B
MVI C,CONST ; Check to see if key pressed
CALL BDOS
ORA A
JZ ABORT3 ; If no key pressed, then continue
MVI C,RDCON ; If key pressed, then check for abort
ANI 7FH ; Remove parity, insure upper-case
CALL BDOS
CPI 'S'-40H ; CTL-S to pause?
JNZ ABORT1 ; If not, exit
MVI C,RDCON ; Otherwise wait for another character
CALL BDOS
ANI 7FH ; Remove parity, insure upper-case
;
ABORT1: CPI 'C'-40H ; Is it CTL-C?
JZ ABORT2
CPI 'K'-40H ; Is it CTL-K?
JZ ABORT2 ; If no, then continue
CPI 'X'-40H ; Is it CTL-X?
JZ ABORT2
ANI 5FH ; Convert to upper-case
CPI 'C'
JZ ABORT2
CPI 'K'
JZ ABORT2
CPI 'X'
JNZ ABORT3
;
ABORT2: POP B ; Reset the stack
POP D
POP H
POP H ; Clear "CALL ABORT" from stack
CALL EXIT ; If yes, then print abort message
DB CR,LF,LF,'++ ABORTED ++','$'
;
ABORT3: POP B
POP D
POP H
RET
;.....
;
;
; Shows the received baud rate
;
BAUD: LDA STORE
CPI '0'
JZ B110
CPI '1'
JZ B300
CPI '5'
JZ B1200
CPI '6'
JZ B2400
MVI B,' '
CALL SEND1
CALL SEND1
CALL SEND1
CALL SEND1
JMP BFIN2
;...
;
;
B110: MVI B,' '
CALL SEND1
MVI B,'1'
CALL SEND1
MVI B,'1'
CALL SEND1
JMP BFIN1
;
B300: MVI B,' '
CALL SEND1
MVI B,'3'
JMP BFINSH
;
B1200: MVI B,'1'
CALL SEND1
MVI B,'2'
JMP BFINSH
;
B2400: MVI B,'2'
CALL SEND1
MVI B,'4'
;
BFINSH: CALL SEND1
MVI B,'0'
CALL SEND1
;
BFIN1: MVI B,'0'
CALL SEND1
;
BFIN2: MVI B,' '
CALL SEND1
MVI B,'b'
CALL SEND1
MVI B,'p'
CALL SEND1
MVI B,'s'
CALL SEND1
MVI B,' '
CALL SEND1
MVI B,' '
JMP SEND1
;.....
;
;
; Print message then exit to CP/M
;
EXIT: POP D ; Get message address
MVI C,PRINT ; Print message
CALL BDOS
CALL ILPRT ; Print CRLF before quitting
DB CR,LF,0
;
LDA DRUSER ; Get original drive/user area back
RAR
RAR
RAR
RAR
ANI 0FH ; Just look at the user area
MOV E,A
MVI C,SETUSR ; Restore original user area
CALL BDOS
;
LDA DRUSER ; Get the original drive/user back
ANI 0FH ; Just look at the drive for now
MOV E,A
MVI C,SELDSK ; Restore original drive
CALL BDOS
;
LHLD STACK
SPHL
RET
;.....
;
;
; Inline print routine - prints string pointed to by stack until a zero
; is found. Returns to caller at the next address after the zero ter-
; minator.
;
ILPRT: XTHL ; Save HL, get message address
;
ILPLP: MOV A,M ; Get the character
CALL TYPE ; Show on the CRT
INX H ; Next character location
MOV A,M ; Get the character
ORA A ; If Zero, all done
JNZ ILPLP ; Else keep going
XTHL ; Restore HL, ret address
RET ; Return past the end of the message
;.....
;
;
; Output a character to the new file buffer - first, see if there is
; room in the buffer for this character.
;
OUTCHR: PUSH PSW ; Store the character for now
CALL TYPE
POP PSW
RET
;.....
;
;
; Transfer is done - close destination file
;
TDONE: MVI C,CLOSE
LXI D,FILE
CALL BDOS
TDONE2: CALL EXIT
DB CR,LF,LF,CR,'[End of listing]','$'
;.....
;
;
; Show the header at the beginning
;
HEAD: LDA HDR ; Using a header?
ORA A
RZ ; If not skip header
LDA SHOL ; Showing entire KMD.LOG?
ORA A
RZ ; If yes, don't bother with header
;
;
; Customizes header
;
LDA OPTN
ORA A
RZ
CALL ILPRT
DB CR,'D/U Filename Size Speed ',0
LDA OPTN
CPI 1
JZ TDONE1
CALL ILPRT
DB ' Date Time Uploaded by',0
RET
;
TDONE1: CALL ILPRT
DB 'Uploaded by Date',0
RET
;.....
;
;
; Send character in A register to console
;
TYPE: PUSH B
PUSH D
PUSH H
MOV E,A ; Character to 'E' for CP/M
MVI C,WRCON ; Write to console
CALL BDOS
POP H
POP D
POP B
RET
;.....
;
;
NONE: CALL EXIT
DB CR,'++ NO NEW FILES ++','$'
;
;
; 'Declare' output file
;
FILE: DB 0
DB 'LOG SYS'
DB 0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0
RECORD: DB 0,0,0
;
COLUMN: DB 0 ; Column of KMD.LOG line
COUNT: DB 0
DRUSER: DB 0 ; Original drive/user, for return
LENGTH: DB 0 ; Maximum length of useable memory
PRIVT: DB 0 ; Distinguishes "P" lines if shown
STORE: DB 0
STORE2: DB 0
;
DS 100 ; Room for 50-level stack
;
;
; Set write buffer to even page boundry
;
;
BUFFER DS 81 ; Write buffer starts here
STACK EQU BUFFER-2
;
;
END START
; Set