home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
nubye
/
nukmd111.ark
/
NUNEW10.ASM
< prev
Wrap
Assembly Source File
|
1987-02-02
|
15KB
|
731 lines
;
; NUNEW v1.0
; 02/01/87
;
; NuNEW is an RCP/M utility which displays your log of file transfer
; activity (i.e. NUKMD.LOG, LOG.SYS, etc) in various formats. Normal
; users are only able to view current uploads, while the sysop (and
; someone with WHEEL access) has a command line choice of 5 additional
; display options:
;
; WHEEL Option Description
; ------------ -----------
; E Show *all* uploads and downloads
; D Show *all* downloads
; A Show *only* .ARK/.ARC file member downloads
; L Show *only* .LBR file member downloads
; P Show *only* private uploads
;
;
; NuNEW offers a number of enhancements which make it a perfect companion
; utility for those of you logging your file transfer activity via NUKMD
; or other remote file transfer utilities. Regardless of your log file's
; size, display of requested information begins with virtually no delay.
;
; (Note: NEW.ASM was copyrighted and released to public domain [1985] by
; Irv Hoff -- NuNEW is a direct upgrade.)
;
; Tom Brady
; Decibel PBBS
; (404) 288-6858
; 300/1200/2400 bps
;
; -----
;
; Remove the apostrophe from before the ASEG instruction, if using
; Microsoft's macro-assembler MACRO-80 (known as M80). Everyone
; else can ignore the next line.
;
; ASEG ; Required by M80
;
; -----
;
NO EQU 0
YES EQU NOT NO
;
; User choices
;
WHEEL EQU 3EH ; Location of your WHEEL byte
CLOCK EQU yes ; Yes, if .LOG/.SYS contains TIME xfrs
; took place
LOGSYS EQU no ; Yes, if your log file is stored as LOG.SYS,
; rather than *.LOG (i.e. MBBS systems).
LOGDRV EQU 'C' ; .LOG/.SYS stored on this drive
LOGUSR EQU 15 ; .LOG/.SYS stored in this user area
;
PGPAWS: EQU yes ; Yes, page pausing wanted
;
; =======
;
; Program starts here
;
ORG 100H
;
LXI H,0
DAD SP
SHLD STACK ; Save current return to CCP address
LXI SP,STACK ; Reset the stack
;
; If WHEEL is on, check for command line option requests.
;
LDA WHEEL
ORA A ; Ok to check?
JZ START ; No, skip rest
LXI H,FCB+1
MOV A,M ; Get the show option
ORA A ; Anything?
JZ START ; No, show uploads only, else...
STA OPTION ; Save it
;
; Show program name and version number
;
START: CALL ILPRT
DB CR,LF,'NuNEW v',MAIN+'0','.',VERS+'0',' - '
DB MONTH/10+'0',MONTH MOD 10+'0','/'
DB DAY/10+'0',DAY MOD 10+'0','/'
DB YEAR/10+'0',YEAR MOD 10+'0',' '
DB CR,LF,LF,0
;
LDA 4 ; Get current drive/user
STA DRUSER ; Store it
MVI E,LOGUSR ; Set to user area of .LOG file
MVI C,SETUSR
CALL BDOS
MVI A,LOGDRV ; Set to drive of .LOG file
SUI 41H
MOV E,A
MVI C,SELDSK
CALL BDOS
;
; Open source file
;
LXI D,FILE
MVI C,OPEN
CALL BDOS
INR A ; Check for no open
JZ NONE ; No file, exit
CALL ILPRT
DB '[ ^S = pause / ^C, ^X or ^K = abort ]',CR,LF,LF,0
LXI D,FILE
MVI C,35 ; Determine end-of-file
CALL BDOS
LXI D,BUFFER+81
MVI A,CR ; Force first line through
STAX D
DCR E
LDA OPTION
CPI 'P' ; Uploads?
JZ HEADU
CPI ' ' ; Uploads?
JZ HEADU
;
HEAD: CALL ILPRT
DB 'd/u Filename Parent Size Speed Date '
;
IF CLOCK
DB 'Time '
ENDIF
;
DB 0
LDA OPTION
CPI 'E' ; Everything?
JNZ HEADD ; No
CALL ILPRT
DB 'Xfer by',0
JMP READX
;
HEADD: CALL ILPRT
DB 'Downloaded by',LF,CR,0
JMP READX
;
HEADU: CALL ILPRT
DB 'D/U Filename Size Speed Date '
;
IF CLOCK
DB 'Time '
ENDIF
;
DB 'Uploaded by',LF,CR,0
;
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 get last record
JZ TDONE ; At the end, so finished
;
; 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?
JNZ RDERR ; No, abort
LXI H,TBUF+127 ; Set up end of buffer
MVI B,128 ; The buffer will be filled up backwards
;
ONEMOR: MOV A,M ; Get character
ANI 7FH
CPI LF ; Check for end of line -- LF is our marker
JZ WRDISK ; that we'll use to determine each line
CPI 7FH
JZ NXTONE
CPI 1AH ; Check for CTRL-Z, end-of-file marker
JZ NXTONE
XCHG
MOV M,A ; Store character in our working buffer
XCHG
DCR E ; Decrement counters (DE=work buffer)
;
NXTONE: DCR L ; (HL=DMA)
DCR B ; (B=Counter for number of char.)
JZ READX ; If zero, go read another record
JMP ONEMOR
;
; 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 OPTION
CPI 'E' ; Show all?
JZ WRDLOP ; Yes, else...
INR L ; See if it is an upload
MOV A,M
STA STORE2 ; Store this away for later
DCR L
;
; Check xfr types
;
CPI 'S' ; Send?
JNZ CKOPT ; No
LDA OPTION
CPI 'D' ; Downloads?
JZ WRDLOP ; Ok
JMP SENDX ; Yes, skip incorrect
;
CKOPT: CPI 'L' ; .LBR?
JNZ CKOPT1 ; No
LDA OPTION ; Get command option
CPI 'L' ; .LBR?
JZ WRDLOP ; Ok
CPI 'D' ; Downloads?
JZ WRDLOP ; Ok
JMP SENDX ; No, skip
;
CKOPT1: CPI 'A' ; .ARK/.ARC?
JNZ CKOPT2 ; No
LDA OPTION
CPI 'A' ; .ARK/.ARC?
JZ WRDLOP ; Ok
CPI 'D' ; Downloads?
JZ WRDLOP ; Ok
JMP SENDX ; No, skip
;
CKOPT2: CPI 'P' ; Private?
JNZ CKOPT3 ; No
LDA OPTION
CPI 'P' ; Private?
JZ WRDLOP ; Ok
JMP SENDX ; No, skip
;
CKOPT3: CPI 'R' ; Upload?
JNZ SENDX ; No
LDA OPTION
CPI ' ' ; Anything else?
JNZ SENDX ; Yes, no good
;
WRDLOP: MOV A,M ; Get byte from read buffer
MOV B,A ; Save the character for now
CPI CR ; CR?
JZ SENDLF ; Yes, send it and start over
CPI LF ; LF?
JNZ WRDL0 ; No, continue output
;
IF PGPAWS
PUSH PSW ; Save LF
LDA LINECT
CPI 20 ; Page yet?
CZ MORE ; Yes, pause
POP PSW ; Restore LF or CR
ENDIF
;
JMP SEND ; Continue next line
;
; Will show entire .LOG in reverse if requested
;
WRDL0: LDA COLUMN
CPI 79 ; End of display?
JZ WRD2 ; Yes
ORA A ; First column?
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
STA STORE
CPI 'P' ; This line a private upload?
JNZ WRDL1 ; If not, exit
LDA OPTION
CPI 'E' ; Everything?
JNZ WRDL00 ; No
STA PRIVT ; Mark '*'
JMP WRDL4
;
WRDL00: CPI 'P' ; Private?
JNZ WRDL13 ; No
STA PRIVT ; Mark '*'
JMP WRDL4
;
WRDL1: CPI 'S' ; Download?
JNZ WRDL11
LDA OPTION
CPI 'D'
JZ WRDL4
JMP WRDL13 ; Yes, incorrect
;
WRDL11: CPI 'L'
JNZ WRDL12 ; No
LDA OPTION
CPI 'D'
JZ WRDL4
CPI 'L'
JZ WRDL4
JMP WRDL13
;
WRDL12: CPI 'A'
JNZ WRDL14 ; No
LDA OPTION
CPI 'D'
JZ WRDL4
CPI 'A'
JZ WRDL4
;
WRDL13: CPI 'E' ; Everything?
JZ WRDL4 ; Yes, no skip
XRA A
STA STORE
STA COLUMN
JMP NEXT
;
WRDL14: CPI 'R' ; Upload?
JNZ WRDL13 ; No
LDA OPTION
CPI 'P'
JNZ WRDL4
JMP WRDL13
;
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
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
LDA OPTION
CPI ' ' ; Uploads?
LDA COLUMN
JZ WR5B ; Yes, an orphan...
LDA OPTION
CPI 'P' ; Uploads?
LDA COLUMN
JZ WR5B ; More orphans...
CPI 34 ; Parent possible, print through column 34
JC SEND
JNZ WR5A ; Done here, print type
CALL SEND1 ; Send character in column 33
MVI B,'.' ; Add a period after the file name
JMP SEND
;
WR5A: CPI 39
JC SEND ; Print file type
JMP WR5C
;
WR5B: CPI 39
JC NEXT ; Ignore the "big gap"
;
WR5C: CPI 43
JC SEND ; Print the file size
JZ WR6
JMP WR7 ; Continue with date
;
WR6: CALL SEND1 ; Print space
CALL BAUD ; Print the baud rate and a space
JMP NEXT
;
WR7: CPI 52
JC SEND ; Print the date
JNZ WR8
JMP SEND ; Add a space
;
WR8: IF CLOCK
CPI 58
JC SEND ; Print the time program was sent
JNZ SEND ; If not column 57, continue
ENDIF
;
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: IF PGPAWS
LDA LINECT
INR A
STA LINECT ; Increment line counter
ENDIF
;
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 out of character in DMA buffer,
JMP ONEMOR ; go read a sector
;
; -----------
; SUBROUTINES
; -----------
;
; Display message and pause for user input
;
IF PGPAWS
MORE: PUSH H ; Save TBUF address
PUSH D
PUSH B
XRA A
STA LINECT ; Clear counter
POP PSW
MVI A,CR ; Only need CR
PUSH PSW
CALL ILPRT
DB CR,LF,' [Hit any key to continue]',CR,0
JMP ABORT0
ENDIF
;
; 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
;
ABORT0: MVI C,RDCON ; Otherwise wait for another character
CALL BDOS
ANI 7FH ; Remove parity, insure upper-case
;
ABORT1: CPI 'C'-40H ; ^C?
JZ ABORT2
CPI 'K'-40H ; ^K?
JZ ABORT2
CPI 'X'-40H ; ^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 from stack
CALL EXIT
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,' '
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,'[End of listing]','$'
;
; 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
;
; Error messages
;
RDERR: CALL EXIT
DB CR,LF,'++ File read error ++','$'
;
NONE: CALL EXIT
DB CR,'++ No transfer log file found ++','$'
;
; .LOG file definition -- no need to define, since it looks for
; wild-card matching of your .LOG file. If LOGSYS is YES, your log
; file is normally stored as LOG.SYS and defined as such below.
;
FILE: DB 0
;
IF NOT LOGSYS
DB '????????LOG'
ENDIF
;
IF LOGSYS
DB 'LOG SYS'
ENDIF
;
DB 0,0,0,0,0
DB 0,0,0,0,0
DB 0,0,0,0,0
DB 0,0,0,0,0,0
;
RECORD: DB 0,0,0
;
COLUMN: DB 0 ; Column of .LOG line
DRUSER: DB 0 ; Original drive/user, for return
LENGTH: DB 0 ; Maximum length of useable memory
LINECT: DB 0 ; Line counter
OPTION: DB ' ' ; Option flag
PRIVT: DB 0 ; Flag for private uploads
STORE: DB 0
STORE2: DB 0
;
; -----
;
; Equates
;
CR EQU 0DH ; Carriage return
EOF EQU 1AH ; End of file - ^Z
FCB EQU 5CH ; Command buffer
LF EQU 0AH ; Line feed
TBUF EQU 80H ; Default buffer address
;
MAIN EQU 1
VERS EQU 0
MONTH EQU 2
DAY EQU 1
YEAR EQU 87
;
; -----
;
; BDOS equates
;
BDOS EQU 5 ; 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
;
; -----
;
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