home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
turbodsg
/
typel.mac
< prev
next >
Wrap
Text File
|
1994-07-13
|
15KB
|
699 lines
.comment \
TYPEL.MAC v3.5
(c) 1984 ESKAY Software Services
7120 Skillman #2104
Dallas, TX 75231
NOTE:
=====
If you feel the urge to "improve" this program,
PLEASE, call the SENECA RCPM first to see if there
is a later version. THEN send me your update.
Created from the LDIR code in LDIR12, LTYPE17, SYSLIB routines, and,
of course, thanks to Dave Rand for the USQ baseline code.
Revision history:
08/19/84 Rewrote USQB, added prompted mode
07/21/84 Allowed type of $SYS files, adapted for SYSLIB3
07/07/84 Fixed bug introduced in 3.2
05/23/84 Fixed problem with end-of-file detection
05/06/84 Added $L argument option
04/14/84 General cleanup, added $N argument option
02/15/84 Fixed problem in lbr member filename scanner
02/13/84 Single file mode skipped logging - could only
type files in default drive/user.
02/12/84 MAJOR REVISION AND NAME CHANGE v2.00
Program now called TYPEL. It is now able to type
(almost) any single file. See doc for more info
01/25/84 Added display of original file name if squeezed.
01/20/84 Made M80/L80 compatible, changed drive/user code
to allow use in restricted area if already logged.
Added page mode.
01/06/84 Rewrote part of LTYPE to allow reconfig without
reassembly, other minor mods. SFK
12/09/83 Fixed ^C bug (problem with CONDIN when remote active)
also fixed problem with 0-length files. SFK
12/09/83 Added code to save/restore default drive/user SFK.
11/29/83 Made ^C and ^S checks more frequent to fix a problem
which sometimes caused it to ignore ^C. SFK
11/24/83 Strips bit 7, made MAXLIN a DB at 101H
11/20/83 Initially written.
For further info and reassembly instructions read the DOC file!
\
.8080
;
EXTRN BBLINE ;SYSLIB line input
EXTRN CCOUT ;SYSLIB character out (convert ctl chars)
EXTRN CLOUT ;SYSLIB list char out
EXTRN COMPB ;SYSLIB compare .DE-.HL
EXTRN CIN ;SYSLIB character in
EXTRN DIVHD ;SYSLIB HL DIV DE
EXTRN F$OPEN ;SYSLIB open file
EXTRN F$READ ;SYSLIB file read
EXTRN BDOS ;SYSLIB BDOS call
EXTRN FNAME ;SYSLIB file name parser
EXTRN PUTUD ;SYSLIB save current DU
EXTRN GETUD ;SYSLIB restore default DU
EXTRN LOGUD ;SYSLIB log drive/user
EXTRN PRINT ;SYSLIB print routine
EXTRN PSTR ;SYSLIB print <HL>
EXTRN R$READ ;SYSLIB random read
EXTRN RETUD ;SYSLIB return drive/user
;
EXTRN USQ ;Baseline USQ code
EXTRN UINIT ;USQ init code
PUBLIC FCB
PUBLIC BUFF ;start of buffer
PUBLIC TOPRAM ;end of buffer location
PUBLIC EREXT ;error intercept from USQ
PUBLIC TABLE ;1032 bytes
PUBLIC BUFULL ;buffer full (print) routine
;
.request usqb,syslib ;take the workload off the user
;
cr equ 0dh
lf equ 0ah
argch equ '$' ;option delimiter
;
bufsz equ 1 ;buffer size in K bytes
dbuf equ 80h ;default buffer
dfcb equ 5ch ;default fcb
;
begin: jmp skipc
maxdrv: db 1+'B'-40H ;highest accessible drive + 1 (A=2)
maxusr: db 1+30 ;highest accessible user + 1
maxlin: db 80 ;number of lines to print max (0=all)
maxlps: db 23 ;max lines per screen -1 (0= no page)
lsten: db 0 ;zero=list disable, nz=list enable
sysen: db 0 ;zero=no sys files, nz=sys files ok
;
; refuse to type these file types
; (note that type check is done after USQ so no need to
; check for .CQM etc)
;
notyp: db 'COM'
db 'OBJ' ;renamed COM
db 'LBR' ;library
db 'OV?' ;OVR,OVL,OV1,OV2 etc
db 'ARC' ;archive file
; db 'DIR' ;archive directory
db 'BAD' ;locked out bad spot
; db 'SYS' ;system file
db '??#' ;specially marked file (USERS.TX# etc)
; db 'LOG' ;log file
db 'INT' ;intermediate file (CBASIC etc)
db 'REL' ;relocatable object file
db '?RL' ;PRL, CRL, IRL
; db 'CMD' ;hard to say... (dbase ok, cp/m86 no-go)
db 'EXE' ;executable MSDOS file, renamed COMs
db 0 ;end of table
ds 9*3 ;room for 9 more types
;
skipc: lxi sp,stack ;set up local stack
call print
db 'TYPEL v3.49 (c) ESKAY 10-07-84',cr,lf,0
lxi h,dbuf ;point to buffer
mov b,m ;char count to b
inr b
arglp: dcr b
jz sk1
inx h
mov a,m
cpi argch ;check for option delimiter
jnz arglp
dcx h
mov a,m
inx h
cpi ' ' ;option must come after a blank
jnz arglp
dcx h
mvi m,0 ;remove option
inx h
inx h ;point to arg
mov a,m
cpi 'N' ;N=nopage
mvi m,0
jz na
cpi 'L'
jnz exarg
sta lout
na: xra a
sta maxlps ;non paging
exarg: lda lsten
ora a
jnz sk1
sta lout
sk1: call putud ;save default DU
lxi d,bufsz*1024 ;compute...
lxi h,buff ;...buffer size
dad d ;for disk read
mov a,h
sta topram
call retud ;get current drive/user
mov a,c
ora a
jz no00
mov h,b
mov l,c
shld userno ;save current DU
lda dfcb+1 ;check if no file name specified
cpi ' '
jnz single
loop: call print
db cr,lf,'* ',0
mvi a,1
sta singfl
call bbline
call print
db cr,lf,lf,0
ora a
jz finish
lxi sp,stack
jmp nextfl
;
stlin: lda maxlin ;max number of lines displayed
sta maxls
sta maxls1
lda maxlps
ora a
jz mls
dcr a ;first page is one less than normal
mls: sta lps
ret
;
single: lxi h,dbuf+2 ;point to argument
nextfl: lxi d,fcb
call stlin
call fname ;parse file name
jz what ;not a valid file name
mov a,m ;get delimiter
sta fflag ;set flag LBR/non-LBR
push h ;save command line ptr
inx b ;check if current DU:
mov a,b
ora c
dcx b ;restore DU: value
jz currdu ;skip this if current
call print
db cr,lf,lf
db 'Can only display current drive/user!',cr,lf,lf,0
rst 0
mov a,b ;get specified drive
dcr b ;get into range 0..f
cpi 0ffh ;ff means current drive
lxi h,maxdrv
jnz newdsk ;skip if different
lda driveno
mov b,a
jmp curdsk
;
newdsk: cmp m
jnc illdu ;yes - complain
curdsk: mov a,c ;get specified user area
cpi '?' ;all user areas???
jz illdu ;yes - complain
cpi 0ffh ;current user area?
jnz newusr
lda userno
mov c,a
jmp curusr
;
newusr: inx h ;illegal user specified?
cmp m
jnc illdu ;yes - complain
curusr: call logud ;log into specified DU:
currdu: lda fflag ;get flag
cpi ' ' ;LBR member request?
pop h ;get cmd line ptr back
jnz nolbf ;nope, must be singlefile
inx h ;get next char
lxi d,memfcb ;point to member fcb
call fname ;parse member name
lxi h,fcb+1
call ckamb ;check ambiguity
lxi h,memfcb+1
call ckamb
lxi h,FCB+9 ;default to .LBR
mvi m,'L'
inx h
mvi m,'B'
inx h
mvi m,'R'
lxi d,fcb
call f$open ;attempt to open file
jnz nofile ;not a LBR file
xra a
sta dirs ;set directory check size to 0
lda sysen ;if $SYS suppress
ora a ;then...
cz sysck ;check for $sys bit
xra a
sta lin ;set line count to 0
lxi h,memfcb+9 ;point to member type
call typck ;check valid type
call f$read ;read directory into default buffer
jnz rderr
lxi h,dbuf ;point to dbuf
lxi d,dirname ;point to 8 blanks
call cpfn ;compare
jnz nolbr ;not equal
lxi d,14
dad d
mov a,m
sta dirsiz ;directory size
xra a
sta memfcb
jmp c00 ;skip into directory check
;
dirlp: lxi d,fcb
call f$read
jnz rderr
c00: lxi b,20h
lxi h,dbuf
lxi d,memfcb
call cpfn
jz found
dad b
call cpfn
jz found
dad b
call cpfn
jz found
dad b
call cpfn
jz found
lda dirs
inr a
sta dirs
mov b,a
lda dirsiz
cmp b
jnz dirlp
call print
db cr,lf
db 'Member file not found in LBR directory',cr,lf,0
jmp erext
;
; Found the member file name in the LDIR
;
found: lxi d,12
dad d
push h ;save pointer for now,
inx h ;point to size
inx h
mov a,m ;get low byte
inx h
ora m ;if a=0 then file is 0k
jz nullen ;go complain
pop h ;get pointer back
mov a,m ;get file address
inx h
mov h,m
mov l,a
;
; enter here from non-LBR routine with HL=0000
;
dotyp: lxi d,fcb ;get fcb...
call r$read ;...and read random
jnz rderr
lxi b,dbuf ;point to buffer
ldax b ;get first byte
cpi 76h ;if not 76H (=not squeezed)...
jnz plain ;...then process as text
inx b ;point to and...
ldax b ;...get next byte
cpi 0ffh ;if FF then squeezed..
jnz plain ;...else plain text (?)
call uinit
lxi h,dbuf+4 ;point to original name
call chktp ;check it's type
mvi a,'(' ;print the original name...
call ccout ;...in parentheses
lxi h,dbuf+4
call pstr
call print
db ')',cr,lf,0
call usq ;now unsqueeze and print
jmp goteof
;
; This routine fills the buffer then calls the print routine
;
plain: lxi d,fcb
lxi b,dbuf ;default buffer
fnext: lxi h,buff
rdlp: call f$read ;changed to properly detect eof...
jnz goteof ;...in unsqueezed single files
mlp: ldax b
mov m,a
inx h
inr c
jnz mlp
mvi c,80h
lda topram
cmp h
jnz rdlp
call bufull ;print buffer contents
jmp fnext
;
goteof: call bufull
jmp erext
;
; This is the print buffer routine (BUFULL)
;
bufull: push h
push d
push b
push psw
lxi h,buff
buflp: mov a,m
cpi 1ah
jz erext
cpi 'I'-40h
jz proctab
ani 7fh ;strip high bits
call putchr
cpi lf
jz eoln
call condin ;get keybd char if available
jz goon ;none there, go on
cpi 'C'-40h ;if ^C...
jz erext ;...then finished
cpi 'S'-40h ;if not ^S...
jnz goon ;...then go on, else...
call cin ;...wait for keypress
cpi 'C'-40h
jz erext
jmp goon
;
; This is NOT the SYSLIB routine by same name...
;
condin: push h
push d
push b
mvi c,6
mvi e,0ffh
call bdos
ora a
pop b
pop d
pop h
ret
;
eoln: mvi a,0ffh ;reset tab counter
sta tab
lda maxlps ;get max lines per screen
ora a
jz nopag ;skip if no page mode
lda lps
dcr a
sta lps
jnz nopag
call print
db '[more]',cr,0
call cin
cpi 'C'-40h
jz erext
call print
db ' ',cr,0
lda maxlps
sta lps
nopag: mvi a,0 ;filled by program
maxls equ $-1 ;if maxln=0...
ora a
jz goon ;..then skip line counter
lda lin ;else increment...
inr a
sta lin ;...the line counter
cpi 0 ;see if maxlin reached
maxls1 equ $-1
jnz goon ;no, continue
call print ;else abort with message
db cr,lf
db 'TYPEL aborted - maximum number of lines exceeded.',cr,lf
db 'Please use XMODEM to transfer file to your system.'
db cr,lf,lf,0
jmp erext
;
proctab:lda tab ;get current tab value
mov b,a ;save current
ani 0f8h ;round down to last full 8
adi 8 ;make next tab stop
tablp: call spout ;put space
inr b ;continue spaces to..
cmp b ;...next tab stop
jnz tablp
sta tab ;save next tab stop
jmp go1
;
; Print a space
;
spout: push psw
mvi a,' '
call putchr
pop psw
ret
;
goon: lda tab ;increment...
inr a
sta tab ;...tab counter
go1: inx h ;increment buffer pointer
lda topram ;get top of ram
cmp h ;if not yet reached...
jnz buflp ;...then get next char
pop psw ;else return to caller...
pop b ;...to get more
pop d
pop h
ret
;
; process non-LBR file
;
nolbf: lxi h,fcb+1
call ckamb
lxi h,fcb+9 ;point to type
call typck ;check valid type
lxi d,fcb
call f$open ;open the file
jnz nofile ;not found...
lda sysen
ora a
cz sysck ;$sys file?
call f$read ;read first sector
lxi h,0
jz dotyp ;type it now...
call print
db cr,lf
db 'Unable to type - empty file?',cr,lf,0
jmp erext
;
; check type of squeezed file (HL=original fn)
;
chktp: push b
mvi b,9 ;9 char max
chkt1: mov a,m
inx h
cpi '.' ;end of fn?
jz typck1
dcr b
jnz chkt1
pop b
ret
;
; check file type at <HL> against table
; PSW, HL munched, ret only if ok
;
typck: push b
typck1: push d
push h
lxi d,notyp ;point to no-type table
tck1: pop h
push h
mvi b,3 ;3 chars to compare
tck2: ldax d
ora a ;if end of table...
jz typok ;...then return
cpi '?' ;ambiguous?
jz tck3 ;yes, skip
cmp m ;if no match...
jnz tck4 ;...then skip to next table entry
inx h
inx d
dcr b
jnz tck2 ;loop until all 3 match
pop h
pop d
pop b
jmp tckno ;not ok to type
;
; skip next character in table and filetype
;
tck3: inx h
inx d
dcr b
jnz tck2
jmp tck1
;
; skip to next table entry
;
tck4: inx d
dcr b
jnz tck4
jmp tck1
;
; restore registers and return (ok to type)
;
typok: pop h
pop d
pop b
ret
;
; complain and abort (type found in table)
;
tckno: call print
db cr,lf
db 'Can''t type a .',0
mvi b,3
tcl: mov a,m
inx h
call ccout
dcr b
jnz tcl
call print
db ' file!',cr,lf,0
jmp erext
;
; check if DE+10 has bit 7 set ($SYS file)
;
sysck: push h ;save HL
lxi h,10
dad d
mov a,m
pop h
ani 80h
rz
jmp nofile ;pretend not there
;
; Here are the messages
;
illdu: call print
db cr,lf
db 'Drive/user out of bounds',cr,lf,0
jmp erext
;
nofile: call print
db cr,lf
db 'No such file on disk',cr,lf,0
jmp erext
;
cpfn: push h
push d
push b
mvi b,12 ;12 characters
call compb
pop b
pop d
pop h
ret
;
ckamb: mvi a,'?' ;see if there is any...
mvi e,11 ;...ambiguity in the file spec
ckamlp: cmp m
jz noamb ;complain if ambiguous fn
inx h
dcr e
jnz ckamlp
ret
;
putchr: push b
mov b,a
lda lout
ora a
mov a,b
jnz cot
call ccout
pop b
ret
;
cot: call clout
pop b
ret
;
nolbr: call print
db cr,lf
db 'LBR directory may be damaged - aborting',cr,lf,0
jmp erext
;
nomem: call print
db cr,lf
db 'No member file name specified.',cr,lf,0
jmp what
;
nullen: call print
db cr,lf
db 'Member file is 0k - cannot type.',cr,lf,0
jmp erext
;
rderr: call print
db cr,lf
db 'Cannot read file',cr,lf,0
jmp erext
;
no00: call print
db cr,lf,lf,7
db 'ERROR - cannot use in users 0 and 31!',cr,lf,0
rst 0
;
noamb: call print
db cr,lf
db 'No ambiguous file names allowed',cr,lf,0
what: call print
db cr,lf
db 'TYPEL v3.5 universal single-file lister',cr,lf
db 'Usage:',cr,lf
db 9,'TYPEL [du:]fn[.ft] [fn.ft]',cr,lf
db 'Examples:',cr,lf
db 9,'TYPEL MDM722 MDM722.IQF types member file in LBR',cr,lf
db 9,'TYPEL TEST.AQM types normal file',cr,lf
db 9,'TYPEL F4:TEST.BQS accepts ZCPR drive/user',cr,lf
db 9,'TYPEL FOO.ASM $N $N option=not paging',cr,lf
db 9,'TYPEL BAR.ZOT $L $L option=LST: device',cr,lf
db 'If 1 argument is supplied, single file is typed.',cr,lf
db 'If 2 arguments, TYPEL assumes first arg is type LBR',cr,lf
db 'and attempts to type LBR member.',cr,lf
db 9,'Typing TYPEL without argument starts interactive mode.'
db cr,lf,'You can enter individual filenames or RETURN to stop.'
db cr,lf,lf,0
erext: call getud ;restore default DU
lda singfl
ora a
jnz loop
finish: rst 0
;
singfl: db 0 ;0=single files, 1=prompted
lout: db 0 ;flag for list out
fflag: db 0 ;flag for LBR/non-LBR
topram: db 0 ;hi byte of buffer end
dirs: db 0 ;# of dir sectors processed
dirsiz: db 0 ;# of total dir sectors
tab: db 0 ;current line tab
lin: db 0 ;line count
lps: db 0 ;line count for page mode
userno: db 0 ;current user #
driveno:db 0 ;current drive
fcb: ds 36 ;out fcb
memfcb: ds 12
ds 50 ;25 level stack
stack: dw 0 ;save CP/M stack pointer here
dirname:db 0,' '
buff equ 2000h ;start buffer
table equ buff-1048 ;usq table
end
option=LST: device',cr,lf
db 'If 1 argument is supplied, single file is typ