;----------------------------------------------------------------------
;	VDBTYPE.ASM VERSION 1.0 MAY 9, 1985 (C) Norman H. Strassner
;
; This assembly language subroutine will, when assembled by ASM.COM and
; loaded into high memory by Dbase][, permit the typing of text files
; using a simple 'CALL' from Dbase][. These files may be standard ASCII or
; squeezed text files and may reside inside a Novieleski library, in any
; drive or user area.
;
; ****** THIS FILE IS NOT AN INDEPENDENTLY EXECUTABLE .COM FILE ******
; ******   IT MUST BE USED AS A CALLED FUNCTION UNDER DBASE][	******
;----------------------------------------------------------------------
; To assemble:
; A>REN VDBTYPE.ASM=VDBTYP10.ASM	;(make it an easier name)
; A>ASM VDBTYPE.AAZ			;You won't need a .PRN file
;
;  In Dbase][, the format would be as follows:
;
; 1. Load the hex file:     (Dbase][ assumes an extension of .HEX)
;	LOAD VDBTYPE
;
; 2. Establish a "SET CALL TO":
;
;	SET CALL TO 41984	(This may be changed according to the
;				'ORG' statement at start of the program)
;
; 3. Store the filename, including optional drive/user and library name
;    information to a memory variable:
;
;	STORE '[DRIVE] [USER] [:] [LIBRARY]  <FILENAME.EXT>' TO <MEMVAR>
;	       ^^^^^^^^^^^^^^^^^^(see note below)^^^^^^^^^^^^^^^^^^^^^^^
;
; 4. Use the "CALL" instruction to pass the variable to VDBTYPE
;	CALL	<MEMVAR>
;
;	The filename will now be typed on your screen, with pauses every
; 23 lines.  A ^C will abort the listing and return you to Dbase][.
;
;-----------------------------------------------------------------------
; * Notes on filenames:
; Examples of valid filenames to store to a dbase][ memory variable:
; if the dbase variable name is 'FNAME'
;
; This will type 'TEST.DAT' from the default drive/user
;	STORE 'TEST.DAT' TO FNAME
;	CALL FNAME
;
; This will unsqueeze 'TEST.DQT' from drive B, user 5 and type it
;	STORE 'B5:TEST.DQT' TO FNAME
;	CALL FNAME
;
; This will get 'TEST.DQT' from the library 'TESTLBR', unsqueeze it,
; and type it out.
;	STORE 'A1:TESTLBR TEST.DQT' TO FNAME
;	CALL FNAME
;-------------------------------------------------------------------
;
;	    SAMPLE DBASE][ PROGRAM FOR USE WITH VDBTYP
;	  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; *VDBTYPE.CMD
; SET TALK OFF
; ERASE
; LOAD VDBTYPE
; SET CALL TO 41984
; DO WHILE T
; ?
; ? 'Text typing program for Dbase][.'
; ?
; ? 'Any text file, squeezed or not, even residing in a library,'
; ? 'may be listed on your computer screen directly from Dbase][.'
; ?
; ? 'At the prompt below, you may enter any valid filename in the forms:'
; ?
; ? 'FILENAME.EXT	   --->  types FILENAME.EXT'
; ? 'FILENAME.EQT	   --->  unsqueezes and types FILENAME.EXT'
; ? 'A3:FILNAME.EXT	   --->  types the file from drive A, User 3'
; ? 'LBRNAME FILENAME.EXT  --->  types the file from within a library'
; ?
; ACCEPT 'Enter the file to display, or RETURN to exit ' TO FNAME
; IF FNAME=' '
;  RETURN
; ENDIF
; CALL FNAME
; ENDDO
;
;-------------------------------------------------------------------
;
; From the original TYPEL32.MAC by ESKAY.  All required subroutines that
; were originally called using the M80 assembler (SYSLIB.REL and USQB.REL
; files) were disassembled and incorporated into this .ASM file for easier
; assembly with ASM.COM or LASM.COM
;
;
; Revision History:
;--May 9, 1985--
;	Original writing.  Donated to the public domain for free
; distribution and use.  No one may charge for the use of this program
; without the express written permission of the author.
;
; Please report any bugs or updates to:
;
;	Norman H. Strassner c/o
;	VIDEOMAN RCP/M, XBBS, and DATABASES
;	1950 N. Normandie Ave.
;	Los Angeles, Ca.  90027
;	Voice: (213) 661-5000
;	BBS:   (213) 666-8588  1200/300bd
;
;------------------------------------------------------------------
;
;some needed equates:
CR	EQU	0DH
LF	EQU	0AH
BDOS	EQU	0005H
;
MXDRV:	EQU	1+'P'-40H	;highest accessible drive + 1 (a=2)
MXUSR:	EQU	1+15		;highest accessible user + 1
MXLPS:	EQU	23		;max lines per screen -1 (0= no page)
;
;-------------------------------------------------------------------------
;
; This program is 6k of .HEX file on disk, but will actually use
; about 4608 bytes (1200H bytes) of memory.  For an 'ORG' of A400H, the
; last byte used for buffer space is at B5FFH, so do not locate any other
; program in high memory less than B600H for an ORG of A400H.
;
; 0A400H IS THE LOWEST POSSIBLE FREE MEMORY ADDRESS THAT DBASE][ DOES NOT
; USE FOR ANYTHING EXCEPT SORT ROUTINES. ** IF A SORT IS USED FROM DBASE][,
; THIS PROGRAM WILL BE WIPED OUT AND WOULD NEED TO BE LOADED AGAIN
;
	ORG	0A400H	;change this to suite your requirments
			;dbase][ call set to 41984 for org at A400H
;
;-------------------------------------------------------------------------
;
;Start of program:
;
TYPE:	CALL	PRINT
	DB	CR,LF,'VDBTYPE 1.0 (C)1985 Norman H. Strassner',CR,LF,0

SKIPC:	SHLD	STRING		;save the string pointer
;
	LXI	H,0		;set up a local stack
	DAD	SP
	SHLD	STACK
	LXI	SP,STACK
;
	LXI	D,DBUF		;set up our own default buffer
	CALL	SETDMA
;
	MVI	A,MXLPS
	DCR	A		;first page is one less than normal
	STA	LPS
	CALL	PUTUD		;save default du
	LXI	H,BUFF+1024	;...buffer size
	MOV	A,H
	STA	TOPRAM
	CALL	RETUD		;get current drive/user
	MOV	H,B
	MOV	L,C
	SHLD	USERNO		;save current du
	LHLD	STRING
	MOV	A,M
	INX	H
	DCR	A		;see if any file??? a=1=no=z
	JZ	WHAT
;
	LXI	D,FCB
	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
	MOV	A,B		;get specified drive
	DCR	B		;get into range 0..f
	CPI	0FFH		;ff means current drive
	MVI	H,MXDRV
	MVI	L,MXUSR
	JNZ	NEWDSK		;skip if different
	LDA	DRIVENO
	MOV	B,A
	JMP	CURDSK
;
NEWDSK:
	CMP	H
	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:
	CMP	L		;illegal user specified?
	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+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
	INR	A
	JZ	NOFILE		;not a lbr file
	CALL	F$READ		;read directory into default buffer
	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
C00:	LXI	B,20H
	LXI	H,DBUF
	LXI	D,MEMFCB
	CALL	CPFN
	JZ	FOUND
	CALL	CPFN0
	JZ	FOUND
	CALL	CPFN0
	JZ	FOUND
	CALL	CPFN0
	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',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:
	SHLD	FCB+33		;set random record
	LXI	D,FCB		;get fcb...
	CALL	RNDREAD		;...and read random
	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
	CALL	USQ		;now unsqueeze and print
	JMP	GOTEOF
;
; this routine fills the buffer then calls the print routine
;
PLAIN:
	MVI	B,8		;(bufsz*1024)/128
				;128 bytes each for 8 buffers=1024 bytes
	LXI	D,BUFF		;this is the destination
MLP:
	LXI	H,DBUF		;this is the dbuf
	PUSH	D
	LXI	D,FCB
	CALL	F$READ
	POP	D
	JNZ	GOTEOF		;...in unsqueezed single files
	MVI	C,80H
MMV1:
	MOV	A,M		;get a dbuf character
	STAX	D		;and move it to buff
	INX	H		;increment buff ptr
	INX	D		;increment dbuf ptr
	DCR	C		;move bc number of bytes total
	JNZ	MMV1		;buffer is full, print it
;
	DCR	B		;for 8 times
	JNZ	MLP
	CALL	BUFULL		;print the buffer
	JMP	PLAIN
;
GOTEOF:	MVI	M,1AH		;definitely eof
	CALL	BUFULL
	JMP	FINISHED
;
; 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	FINISHED
	CPI	'I'-40H
	JZ	PROCTAB
	ANI	7FH		;strip high bits
	CALL	CCOUT
	CPI	LF
	JZ	EOLN
	CALL	CONDIN		;get keybd char if available
	JZ	GOON		;none there, go on
	CPI	'C'-40H		;if ^c...
	JZ	ABORT		;...then finished
	CPI	'S'-40H		;if not ^s...
	JNZ	GOON		;...then go on, else...
	CALL	CIN		;...wait for keypress
	CPI	'C'-40H
	JZ	ABORT
	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

	MVI	A,MXLPS		;get max lines per screen
	ORA	A
	JZ	GOON		;skip if no page mode
	LDA	LPS
	DCR	A
	STA	LPS
	JNZ	GOON
	CALL	PRINT
	DB	'[more]',CR,0
	CALL	CIN
	CPI	'C'-40H
	JZ	ABORT
	CALL	PRINT
	DB	'       ',CR,0
	MVI	A,MXLPS
	STA	LPS
	JMP	GOON
;
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	CCOUT
	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
;
; read random record, save all regs
;
RNDREAD:
	PUSH	D
	PUSH	H
	MVI	C,33
	CALL	BDOS
	POP	H
	POP	D
	RET
;
; process non-lbr file
NOLBF:
	LXI	D,FCB
	CALL	F$OPEN		;open the file
	JNZ	NOFILE		;not found...
	CALL	F$READ		;read first sector
	ORA	A
	LXI	H,0
	JZ	DOTYP		;type it now...
	CALL	PRINT
	DB	CR,LF
	DB	'Empty file?',CR,LF,0
	JMP	WHAT

; here are the messages
;
ILLDU:	CALL	PRINT
	DB	CR,LF
	DB	'Bad drive/user',CR,LF,0
	JMP	WHAT
;
NOFILE:	CALL	PRINT
	DB	CR,LF
	DB	'No such file',CR,LF,0
	JMP	EREXT
;
CPFN0:
	DAD	B
;
CPFN:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	B,12	;12 characters
CLPCP:	LDAX	D
	CMP	M	;check file name
	JNZ	QCPFN	;no match - quit
	INX	D
	INX	H
	DCR	B
	JNZ	CLPCP
QCPFN:	POP	B
	POP	D
	POP	H
	RET
;
NOLBR:	CALL	PRINT
	DB	CR,LF
	DB	'LBR directory may be damaged',CR,LF,0
	JMP	EREXT
;
NOMEM:	CALL	PRINT
	DB	CR,LF
	DB	'Specify member file',CR,LF,0
	JMP	WHAT
;
NULLEN:	CALL	PRINT
	DB	CR,LF
	DB	'0k - cannot type.',CR,LF,0
	JMP	EREXT
;
NOAMB:	CALL	PRINT
	DB	CR,LF
	DB	'Bad filename.',CR,LF,0
;
WHAT:	CALL	PRINT
	DB	';;ERROR!',CR,LF,0
	DB	CR,LF,0
	JMP	EREXT
;
ABORT:
	CALL	PRINT
	DB	CR,LF,'+++ABORTED+++',CR,LF,0
	JMP	EREXT
;
FINISHED:
	CALL	PRINT
	DB	CR,LF,'[--End of File--]  Press any key>',7,0
	CALL	CIN
	MVI	A,CR
	CALL	CO
EREXT:
	CALL	GETUD		;restore default du
	LXI	D,80H
	CALL	SETDMA
	LHLD	STACK
	SPHL
	RET
;
SETDMA:
	MVI	C,1AH
	JMP	5
;
;unsqueeze routine
USQ:
	XRA	A
	STA	X0345
	STA	X0346
	LHLD	X033B
	SHLD	X033F
	SHLD	X0341
	CALL	X0267
	CALL	X0267
	SHLD	X0347
X013A:
	CALL	X0216
	JNZ	EREXT
	ORA	A
	JNZ	X013A
	CALL	X0267
	SHLD	X034B
	LXI	D,0102H
	CALL	CMP$HLDE
	JC	X0180
	CALL	PRINT
	DB	CR,LF,'Illegal decode size.',0
	JMP	WHAT
;
X0180:
	LXI	D,TABLE
X0183:
	SHLD	X034D
	MOV	A,H
	ORA	L
	JZ	X01A7
	PUSH	D
	CALL	X0267
	POP	D
	XCHG
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H
	PUSH	H
	CALL	X0267
	XCHG
	POP	H
	MOV	M,E
	INX	H
	MOV	M,D
	INX	H
	XCHG
	LHLD	X034D
	DCX	H
	JMP	X0183
X01A7:
	LXI	H,0
X01AA:
	PUSH	H
	CALL	X02A2
	POP	H
	JNZ	X01D2
	MOV	E,A
	MVI	D,0
	DAD	D
	PUSH	H
	PUSH	PSW
	LHLD	X0343
	LDA	TOPRAM
	CMP	H
	JNZ	X01C8
	CALL	BUFULL
	LXI	H,BUFF
X01C8:
	POP	PSW
	MOV	M,A
	INX	H
	SHLD	X0343
	POP	H
	JMP	X01AA
X01D2:
	XCHG
	LHLD	X0347
	CALL	CMP$HLDE
	RZ
	CALL	PRINT
	DB	CR,LF,'File checksum error',0
	JMP	WHAT
;
CMP$HLDE:
	MOV	A,H
	CMP	D
	RNZ
	MOV	A,L
	CMP	E
	RET
;
X0216:
	LHLD	X0341
	XCHG
	LHLD	X033F
	CALL	CMP$HLDE
	JZ	X022A
	MOV	A,M
	INX	H
	SHLD	X033F
	CMP	A
	RET
X022A:
	LHLD	X033B
	SHLD	X033F
	SHLD	X0341
X0233:
	PUSH	H
	XCHG
	MVI	C,1AH
	CALL	BDOS$CALL
	LXI	D,FCB
	MVI	C,14H
	CALL	BDOS$CALL
	POP	H
	ORA	A
	JNZ	X0256
	LXI	D,80H
	DAD	D
	XCHG
	LHLD	X033D
	CALL	CMP$HLDE
	XCHG
	JNC	X0233
X0256:
	SHLD	X0341
	XCHG
	LHLD	X033F
	CALL	CMP$HLDE
	JNZ	X0216
	MVI	A,0FFH
	ORA	A
	RET
X0267:
	CALL	X0216
	JNZ	PREM$EOF
	PUSH	PSW
	CALL	X0216
	JNZ	PREM$EOF
	MOV	H,A
	POP	PSW
	MOV	L,A
	RET
PREM$EOF:
	CALL	PRINT
	DB	CR,LF,'Premature EOF',0
	JMP	WHAT
X02A2:
	LDA	X0346
	ORA	A
	JZ	X02B2
	DCR	A
	STA	X0346
	LDA	X0349
	CMP	A
	RET
X02B2:
	CALL	X02D4
	CPI	90H
	JNZ	X02CF
	CALL	X02D4
	ORA	A
	JNZ	X02C5
	MVI	A,90H
	CMP	A
	RET
X02C5:
	DCR	A
	DCR	A
	STA	X0346
	LDA	X0349
	CMP	A
	RET
X02CF:
	STA	X0349
	CMP	A
	RET
X02D4:
	LXI	D,0
	LDA	X034A
	MOV	C,A
X02DB:
	LDA	X0345
	ORA	A
	JNZ	X02ED
	PUSH	D
	CALL	X0216
	JNZ	PREM$EOF
	POP	D
	MOV	C,A
	MVI	A,8
X02ED:
	DCR	A
	STA	X0345
	MOV	A,C
	RRC
	MOV	C,A
	LXI	H,TABLE
	JNC	X02FC
	INX	H
	INX	H
X02FC:
	DAD	D
	DAD	D
	DAD	D
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	MOV	A,D
	ANI	80H
	JZ	X02DB
	MOV	A,C
	STA	X034A
	MOV	A,D
	CPI	0FEH
	MVI	A,1AH
	JZ	X0319
	MOV	A,E
	CMA
	CMP	A
	RET
X0319:
	POP	H
	ORA	A
	RET
;
UINIT:
	LXI	H,DBUF
	SHLD	X033B
	SHLD	X033F
	SHLD	X0341
	LXI	H,X0345
	MVI	A,9
X032D:
	MVI	M,0
	INX	H
	DCR	A
	JNZ	X032D
	LXI	H,BUFF
	SHLD	X0343
	RET
;
FNAME:
	PUSH	D
	MVI	A,0FFH
	STA	L0485
	STA	L0486
	MVI	B,'$'
	PUSH	D
	XRA	A
L03A0:
	STAX	D
	INX	D
	DCR	B
	JNZ	L03A0
	POP	D
	PUSH	H
L03A8:
	MOV	A,M
	INX	H
	CPI	':'
	JZ	L03BC
	CPI	','
	JZ	L0417
;
	CPI	'!'
	JC	L0417
	JMP	L03A8
L03BC:
	POP	H
	MOV	A,M
	CALL	MAKEUCASE
	CPI	'A'
	JC	L03D5
	SUI	'A'
	CPI	10H
	JC	L03D0
L03CD:
	XRA	A
	POP	D
	RET
L03D0:
	INR	A
	STA	L0485
	INX	H
L03D5:
	MOV	A,M
	CPI	':'
	JZ	L0418
	CPI	'?'
	JNZ	L03ED
	STA	L0486
	INX	H
	MOV	A,M
	CPI	':'
	JZ	L0418
	JMP	L03CD
L03ED:
	XRA	A
	MOV	B,A
L03EF:
	MOV	A,M
	INX	H
	CPI	':'
	JZ	L040B
	SUI	'0'
	JC	L03CD
	CPI	LF
	JNC	L03CD
	MOV	C,A
	MOV	A,B
	ADD	A
	ADD	A
	ADD	B
	ADD	A
	ADD	C
	MOV	B,A
	JMP	L03EF
L040B:
	MOV	A,B
	CPI	' '
	JNC	L03CD
	STA	L0486
	JMP	L0418
L0417:
	POP	H
L0418:
	MOV	A,M
	CPI	':'
	JNZ	L041F
	INX	H
L041F:
	MOV	A,M
	CPI	','
	JZ	L042A
	CPI	'!'
	JNC	L0442
L042A:
	INX	D
	MVI	B,0BH
	MVI	A,'?'
L042F:
	STAX	D
	INX	D
	DCR	B
	JNZ	L042F
L0435:
	LDA	L0485
	MOV	B,A
	LDA	L0486
	MOV	C,A
	POP	D
	MVI	A,0FFH
	ORA	A
	RET
L0442:
	MVI	B,8
	CALL	L045C
	MVI	B,3
	MOV	A,M
	CPI	'.'
	JNZ	L0456
	INX	H
	CALL	L045C
	JMP	L0435
L0456:
	CALL	L047C
	JMP	L0435
L045C:
	CALL	CHAR$CHK
	JZ	L047C
	INX	D
	CPI	'*'
	JNZ	L046E
	MVI	A,'?'
	STAX	D
	JMP	L0470
L046E:
	STAX	D
	INX	H
L0470:
	DCR	B
	JNZ	L045C
L0474:
	CALL	CHAR$CHK
	RZ
	INX	H
	JMP	L0474
L047C:
	INX	D
	MVI	A,' '
	STAX	D
	DCR	B
	JNZ	L047C
	RET
;
CHAR$CHK:
	MOV	A,M
	CALL	MAKEUCASE
	ORA	A
	RZ
	CPI	'!'
	JC	L04AA
	CPI	'='
	RZ
	CPI	'_'
	RZ
	CPI	'.'
	RZ
	CPI	':'
	RZ
	CPI	';'	;3bh
	RZ
	CPI	','
	RZ
	CPI	'<'
	RZ
	CPI	'>'
	RET
L04AA:
	CMP	M
	RET
;
F$OPEN:	; open file:
	PUSH	B
	PUSH	D
	PUSH	H
	MVI	C,0FH
	CALL	BDOS
	CPI	0FFH
	JNZ	L04BF
L04B9:
	MVI	A,0FFH
	ORA	A
	JMP	L04C0
L04BF:
	XRA	A
L04C0:
	POP	H
	POP	D
	POP	B
	RET
;
F$READ:	; file read:
	PUSH	H
	PUSH	B
	MVI	C,14H
	CALL	BDOS$CALL
	ORA	A
	POP	B
	POP	H
	RET
;
PRINT:	;in line print routine
	XTHL
	CALL	PRINT1
	XTHL
	RET
PRINT1:
	PUSH	D
	PUSH	B
	PUSH	PSW
	MVI	C,0
PRINT$LP:
	MOV	A,M
	INX	H
	ORA	A
	JZ	L0543
	CPI	9
	JZ	L052D
	INR	C
	CALL	CCOUT
	CPI	CR
	JZ	L051A
	CPI	LF
	JZ	L051F
	CPI	7
	JZ	L051F
	CPI	8
	JZ	L0523
	JMP	PRINT$LP
L051A:
	MVI	C,0
	JMP	PRINT$LP
L051F:
	DCR	C
	JMP	PRINT$LP
L0523:
	MOV	A,C
	ORA	A
	JZ	PRINT$LP
	DCR	C
	DCR	C
	JMP	PRINT$LP
L052D:
	MOV	A,C
	ANI	7
	MOV	B,A
	MVI	A,8
	SUB	B
	MOV	B,A
	ADD	C
	MOV	C,A
	MVI	A,' '
L0539:
	CALL	CO
	DCR	B
	JNZ	L0539
	JMP	PRINT$LP
L0543:
	POP	PSW
	POP	B
	POP	D
	RET
;
CCOUT:	; character out (convert ctl chars):
	CPI	' '
	JNC	CO
	CPI	0
	JZ	CO
	CPI	7
	JZ	CO
	CPI	8
	JZ	CO
	CPI	LF
	JZ	CO
	CPI	CR
	JZ	CO
	PUSH	PSW
	PUSH	PSW
	MVI	A,'^'
	CALL	CO
	POP	PSW
	ADI	'@'
	CALL	CO
	POP	PSW
	RET
;
CIN:	; character in:
	PUSH	B
	PUSH	H
	MVI	C,1
	CALL	BDOS$CALL
	POP	H
	POP	B
	RET
;
CO:
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,A
	MVI	C,2
	CALL	BDOS
	POP	H
	POP	D
	POP	B
	POP	PSW
	RET
;
PUTUD:	; save current du:
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	MVI	C,19H
	CALL	BDOS
	STA	CURNTDSK
	MVI	E,0FFH
	MVI	C,' '
	CALL	BDOS
	STA	CURNTUSR
	JMP	L05C8
;
GETUD:	; restore default du:
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	LDA	CURNTDSK
	MOV	E,A
	MVI	C,0EH
	CALL	BDOS
	LDA	CURNTUSR
	MOV	E,A
	MVI	C,' '
	CALL	BDOS
L05C8:
	POP	H
	POP	D
	POP	B
	POP	PSW
	RET
;
LOGUD:
	PUSH	PSW
	PUSH	B
	PUSH	D
	PUSH	H
	MOV	E,C
	MVI	C,' '
	PUSH	B
	CALL	BDOS
	POP	B
	MOV	E,B
	MVI	C,0EH
	CALL	BDOS
	POP	H
	POP	D
	POP	B
	POP	PSW
	RET
RETUD:
	PUSH	PSW
	PUSH	D
	PUSH	H
	MVI	C,19H
	CALL	BDOS
	PUSH	PSW
	MVI	E,0FFH
	MVI	C,' '
	CALL	BDOS
	MOV	C,A
	POP	PSW
	MOV	B,A
	POP	H
	POP	D
	POP	PSW
	RET
;
BDOS$CALL:	; bdos call:
	PUSH	B
	PUSH	D
	CALL	BDOS
	POP	D
	POP	B
	RET
;
DIVHD:
	PUSH	PSW
	PUSH	B
	PUSH	H
	LXI	H,0
	SHLD	L0662
	POP	H
	MOV	A,H
	CMP	D
	JC	L0647
	JNZ	L061C
	MOV	A,L
	CMP	E
	JC	L0647
L061C:
	MVI	B,10H
L061E:
	CALL	L064D
	PUSH	H
	LHLD	L0662
	CALL	L065E
	SHLD	L0662
	MOV	A,L
	SUB	E
	MOV	L,A
	MOV	A,H
	SBB	D
	MOV	H,A
	JC	L063F
	SHLD	L0662
	POP	H
	MOV	A,L
	ORI	1
	MOV	L,A
	JMP	L0640
L063F:
	POP	H
L0640:
	DCR	B
	JNZ	L061E
L0644:
	POP	B
	POP	PSW
	RET
L0647:
	LXI	H,0
	JMP	L0644
L064D:
	PUSH	PSW
	ANA	A
L064F:
	MOV	A,L
	RAL
	MOV	L,A
	MOV	A,H
	RAL
	MOV	H,A
	JNC	L065B
	POP	PSW
	STC
	RET
L065B:
	POP	PSW
	ORA	A
	RET
L065E:
	PUSH	PSW
	JMP	L064F
;
MAKEUCASE:
	ANI	7FH
	CPI	61H
	RC
	CPI	7BH
	RNC
	ANI	'_'
	RET
;
;storage for unsqueeze routines
CURNTDSK:
	DB	0
CURNTUSR:
	DB	0
;
L0485:	DB	0
L0486:	DB	0
L0662:	DW	0	;divide storage
X033B:	DW	0
X033D:	DW	0
X033F:	DW	0
X0341:	DW	0
X0343:	DW	0
X0345:	DB	0
X0346:	DB	0
X0347:	DW	0
X0349:	DB	7EH
X034A:	DB	0FEH
X034B:	DW	0
X034D:	DW	0
;
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
DIRNAME:DB	0,'           '
STRING:	DW	0
STORDMA:DW	0
;
	DS	50		;25 level stack
STACK:	DW	0		;save cp/m stack pointer here
;
MEMFCB	EQU	$
FCB	EQU	MEMFCB+37
DFCB	EQU	FCB+37
DBUF	EQU	DFCB+37
TABLE	EQU	DBUF+129
BUFF	EQU	((TABLE	+ 1034)	OR 0FFH) + 1 ;set on page boundry
;
	END
7
DFCB	EQU	FCB+37
DBUF	EQU	DFCB+37
TABLE	EQU	DBUF+129
BUFF	EQU	((TABLE	+ 1034)	OR 0FFH) + 1 ;set on pa