home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
bye5
/
whatsn05.lbr
/
WHATSN05.AQM
/
WHATSN05.ASM
Wrap
Assembly Source File
|
1986-04-18
|
20KB
|
824 lines
; WHATSN05 - Displays XMODEM.LOG (or LOG.SYS) in reverse order - 03/01/86
;
; WHATSNEW.ASM
; by
; Irvin M. Hoff
; (01 March 1986)
;
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 XMODEM.LOG (or LOG.SYS) of all file transfers created by the
; XMODEM file transfer program. (If using MBYE, substitute the term
; LOG.SYS wherever appears and set the MBYE equate to YES.)
;
; Program 1 = shows the XMODEM.LOG in reverse order, newest first
; Program 2 = shows only uploads in reverse, ignoring downloads
;
; WARNING: Versions of XMODEM prior to 101 did not
; mark uploads to private areas differently
; from normal uploads.
;
;=======================================================================
;
; 03/01/86 - Added pagination, also allowed WHEEL users to specify
; v05 WHATSNEW A to see uploads and downloads without maintaining
; a second copy of program online. - Michael Conley
;
;=======================================================================
;
; SHOWAL set to 0 - gives Program 1
; ---------------------------------
; Before configuring this, note that WHEEL users may show all files by
; typing "WHATSNEW A" on the command line, regardless of SHOWAL equate.
;
; When the SHOWAL option is set to "0", all files in the XMODEM.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 XMODEM
; into the XMODEM.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 XMDM101 or later. 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 essen-
; tially self-maintaining, which makes it quite different from WHATSNEW
; programs previously used, made via D-29, etc. It is 1k long and fully
; secure. (Change equates below if your XMODEM.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 WHATSNEW.
;
; Then A>SAVE 5 NEW.COM
;
; Suggestion: Make one of each, call one ALL.COM and put on
; A15: for easy use by the SYSOP and the other
; WHATSNEW.COM and put on A0: for all to use.
;
;-----------------------------------------------------------------------
;
; INFO:
; ----
; A companion program currently called XMDEL automatically
; deletes all downloaded files from XMODEM.LOG, keeping
; the uploads for WHATSNEW. This minimimizes the length
; of the XMODEM.LOG file, since "most" of the lines are
; for downloads. The combination of WHATSNEW and XMDEL make
; the entire new file display almost fully self-maintaining.
;
;-----------------------------------------------------------------------
;
; OPTIONS:
; -------
; SHOWAL 0 = Shows all files in the XMODEM.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 XMODEM.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 XMODEM.LOG and displays in re-
; verse order (newest uploads, first).
;
;---------------
;
; Example 1: OxGate 001 (before)
;
; R6 02:22 B00>WHATSNEWLBR 26k Irv Hoff 1/22/85
;
; (after)
;
; D/U Filename Size Speed Uploaded by
;
; B00: WHATSNEW.LBR 26k 1200 bps Irv Hoff 1/22/85
;
;---------------
;
; Example 2: Potpourri (before)
;
; R6 02:22 B00>WHATSN01LBR 26k 01/22/85 16:44 Irv Hoff
;
; (after)
; D/U Filename Size Speed Date Time Uploaded by
;
; B00: WHATSN01.LBR 26k 1200 bps 01/22/85 16:44 Irv Hoff
;
;-----------------------------------------------------------------------
;
; Features:
; ---------
; 1) Should be placed in A0: so any user can call the program
; 2) Should be renamed to WHATSNEW.COM at that time
; 3) Automatically remembers current drive/user area
; 4) Jumps to A14: to read the XMODEM.LOG file, with full security
; 5) Opens the XMODEM.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
; 13) WHEEL users may specify "WHATSNEW A" to see uploads and
; downloads regardless of SHOWAL equate setting.
; 14) Pagination added -- equate sets page length or 0 to override
; pagination feature.
;
; The SYSOP can readily customize this program to suit his preferences.
; The area around W7: and TDONE1: would be the sections to customize if
; selection 1 or 2 is not sufficient.
; - Notes by Irv Hoff W6FFC
;
;-----------------------------------------------------------------------
;
; 05/05/85 Added option to select MBYE's LOG.SYS instead of XMODEM.LOG.
; v04 - Irv Hoff
;
; 02/22/85 Modest change to ABORT: area for CTL-S to work with TURBODOS
; v03 systems. - Irv Hoff
;
; 02/07/85 If a file was 100k or more, was not showing the first digit
; v02 on some systems. - Irv Hoff
;
; 02/02/85 Initial version - thanks to Wayne Masters for suggestions.
; v01 - Irv Hoff
;
;-----------------------------------------------------------------------
;
; User choices
;
;
NO EQU 0
YES EQU NOT NO
;
MBYE EQU NO ; Yes for LOG.SYS, No for XMODEM.LOG
;
SHOWAL EQU 1 ; 0=all file transfers, 1=uploads only
OPTION EQU 1 ; Must be 0, 1 or 2 (see above)
HEADER EQU 1 ; 0=no header, regardless of option
;
DRIVE EQU 'A' ; XMODEM.LOG stored here in your system
USER EQU 14 ; XMODEM.LOG stored here in your system
PGLEN EQU 22 ; paging length / set to 0 for no paging
;
WHEEL EQU 03EH ; 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
TCHR EQU TBUF + 2 ; Address of first command line option char.
;
;
;-----------------------------------------------------------------------
;
; BDOS equates
;
BDOS EQU 0005H ; CP/M BDOS entry address
RDCON EQU 1 ; Get character from console
WRCON EQU 2 ; Write character to console
DIRCON EQU 6 ; Direct console I/O
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 20 ; Read sequential 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 LOG file 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
;
AOPT: LDA WHEEL ; See if wheel user
CPI 0
JZ NOPT ; NO? don't look for options
AOPT1: LDA TBUF ; See if option present
CPI 0
JZ NOPT
LDA TCHR
CPI 'A' ; If it's an A, show uploads & downloads
JNZ NOPT
MVI A,0
STA SHOL
NOPT: LDA 0004H ; Get current drive/user
STA DRUSER ; Store
;
;
; Set drive/user to the XMODEM.LOG area listed above
;
; Set drive/user to the XMODEM.LOG or LOG.SYS area listed above
;
MVI E,USER ; Set user to XMODEM.LOG area
MVI C,SETUSR
CALL BDOS
;
MVI A,DRIVE ; Set drive to XMODEM.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 'WHATSNEW Type ^S to pause, ^C, ^X or ^K to abort'
DB CR,LF,CR,LF,'wait a moment...',0
;
LDA 0007H ; Find end of TPA
DCR A ; Do not allow to get too close
DCR A
STA LENGTH ; store new value for buffer area
LXI H,0 ; Reset output pointers
SHLD PTR
MVI B,EOF ; EOF to terminate reverse reading later
CALL SEND1 ; Put in memory
MVI B,LF ; Allows a single line to be shown
CALL SEND1 ; Put in memory
;
;
; Read sector from source file
;
READLP: LXI D,TBUF
MVI C,STDMA
CALL BDOS
;
LXI D,FILE
MVI C,READ
CALL BDOS
;
ORA A ; Read ok?
JZ WRDISK ; Yes, send it to output
CPI 1 ; End-of-file?
JZ TDONE ; Transfer done, close, exit
CALL EXIT
DB '++ SOURCE FILE READ ERROR ++','$'
;
;
; Write sector to output file (with buffering)
;
WRDISK: LXI H,80H ; Read buffer address
;
WRDLOP: MOV A,M ; Get byte from read buffer
ANI 7FH ; Strip parity bit
CPI 7FH ; Del (rubout)?
JZ NEXT ; Yes, ignore it
CPI EOF ; End of file marker?
JZ TDONE ; Transfer done, close, exit
MOV B,A ; Save the character for now
CPI LF ; New line?
JZ SENDLF ; If yes, exit
;
;
; Will show entire XMODEM.LOG in reverse if requested
;
LDA SHOL
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 '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 XMODEM "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?
JZ READLP ; If yes get another 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?
LDA SHOL ; Showing entire XMODEM.LOG?
ORA A
JZ SENDL1
LDA STORE ; End of a "R" line?
ORA A
JZ NEXT ; If not, ignore this "LF"
;
SENDL1: INR A ; Just to get a positive value
STA COUNT ; Have at least one line to show
LDA LAST+1 ; Get "H" value of current memory
MOV C,A ; Store temporarily
LDA LENGTH
SUB C
JNC SEND
CALL SEND1 ; Put the LF into memory
JMP TOLONG ; If same or more, memory full
;.....
;
;
;-----------------------------------------------------------------------
;
; SUBROUTINES
;
;-----------------------------------------------------------------------
;
; Aborts the display when requested, but only at end of line
;
ABORT: PUSH H
PUSH D
PUSH B
MVI C,DIRCON ; See if anything from console
MVI E,0FFH ;
CALL BDOS ;
CPI 0 ; NO KEY?
JZ CKPAG
ABORT0:
ANI 5FH ; Convert to upper case
ORI 40H
CPI 'C'
JZ ABORT1
CPI 'K'
JZ ABORT1
CPI 'S' ; How about S?
JZ FINGER ; If so, pause till next key
CPI 'X'
JZ ABORT1
CKPAG:
MVI A,PGLEN ; Are we paging?
CPI 0
JZ NOABT ; no, return
LDA PGCNT ; pickup current count
MOV B,A ; save in b
MVI A,PGLEN ; get total length
SUB B ; minus current count
CPI 0
JZ FINGER ; equal? then pause
NOABT:
POP B
POP D
POP H
RET
;
ABORT1: POP B ; Restore the registers
POP D
POP H
POP H ; Clear "CALL ABORT" from stack
CALL EXIT ; If yes, then print abort message
DB CR,LF,'++ ABORTED ++','$'
;
;
FINGER:
CALL ILPRT
DB '[more]',CR,0
FING1:
MVI C,DIRCON ; Check to see if key pressed
MVI E,0FFH
CALL BDOS
CPI 0
JZ FING1 ; If no key pressed, then wait more
PUSH PSW ; save the char
XRA A
STA PGCNT
POP PSW
JMP ABORT0 ; otherwise go back and check char
;.....
; Backs up to the start of the previous line
;
BACKUP: DCX H
MOV A,M
CPI EOF
JZ BACK1
CPI LF ; End of line character?
JNZ BACKUP ; IF NOT, KEEP REVERSING
RET
;
BACK1: POP H ; Restore stack
JMP TDONE4 ; All finished this file
;.....
;
;
; 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 char
CALL TYPE ; Output it
INX H ; Point to next
MOV A,M ; Test for end
ORA A
JNZ ILPLP
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
LHLD PTR ; Now get the buffer pointers
XCHG
LHLD ADR
DAD D
SHLD LAST
XCHG
POP PSW ; Get the character back
STAX D ; Store the character
LHLD PTR ; Get the buffer pointer
INX H ; Increment them
SHLD PTR ; Store the new pointer address
RET
;.....
;
;
; Shows the line from memory, quits with a "LF" character
;
SHOW: INX H ; Next character position in line
MOV A,M ; Get the character
CALL TYPE ; Send to CRT display
MOV A,M ; Get the character again
CPI LF ; Was it a line feed?
JNZ SHOW ; If not, get next character
LDA PGCNT ; increment line counter
INR A
STA PGCNT
RET ; Otherwise finished this line
;.....
;
;
; Transfer is done - close destination file
;
TDONE: MVI C,CLOSE
LXI D,FILE
CALL BDOS
CALL ABORT
LDA COUNT ; See if anything to display
ORA A
JZ NONE ; If not, say "NO NEW FILES"
;
CALL ILPRT
DB CR,0
LDA HDR ; Using a header?
ORA A
JZ TDONE2 ; If not skip header
LDA SHOL ; Showing entire XMODEM.LOG?
ORA A
JZ TDONE2 ; If yes, don't bother with header
;
;
; Customizes header
;
LDA OPTN
ORA A
JZ TDONE2
CALL ILPRT
DB CR,'D/U Filename Size Speed ',0
LDA OPTN
CPI 1
JZ TDONE1
CALL ILPRT
DB ' Date Time Uploaded by',CR,LF,CR,LF,0
JMP TDONE2
;
TDONE1: CALL ILPRT
DB 'Uploaded by Date',CR,LF,CR,LF,0
;
TDONE2: LHLD LAST ; Get address of last character stored
CALL BACKUP ; Print first line in memory
CALL SHOW
;
TDONE3: CALL ABORT
CALL BACKUP ; Need to back twice for rest of lines
CALL BACKUP
CALL SHOW
JMP TDONE3 ; Keep going until all are printed
;
TDONE4: CALL EXIT
DB LF,CR,'[End of listing]','$'
;.....
;
;
TOLONG: CALL ILPRT
DB CR,'++ FILE TOO LONG, NEWEST ENTRIES LIKELY NOT '
DB 'SHOWN ++',CR,LF,CR,LF,0
JMP TDONE
;
;.....
;
;
; 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: IF MBYE
DB 0,'LOG ','S','Y'+80H,'S'
ENDIF ; MBYE
;
IF NOT MBYE
DB 0,'XMODEM LOG'
ENDIF ; NOT MBYE
;
DB 0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0
;
ADR: DW BUFFER ; Address of buffer start
LAST: DW 0 ; Address of last character in buffer
PTR: DW 0 ; Pointer count for buffer
;
COLUMN: DB 0 ; Column of XMODEM.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
PGCNT: DB 0 ; For paging
;
DS 100 ; Room for 50-level stack
;
;
; Set write buffer to even page boundry
;
ORG ($+255)/256*256
;
BUFFER EQU $ ;write buffer starts here
STACK EQU BUFFER-2
;
;
END START