 	page	58
;	dbdir.asm      
;
;
;		THIS PROGRAM WILL ...
;			produce a directory list on the
;			console and will be called from dBASEII.
;						- Mike Kelly
;
;	08-20-82  v1.0	written
;
;	08-22-82  v1.0 	updated
;	08-30-82  v1.1	Add routine to load the program to upper memory
;			when it has been assembled in lower memory. To
;			do this requires adding a base number (offset)
;			to all labels and variables so that after the
;			move to upper memory, all addresses will have
;			been adjusted properly.
;	09-20-82  v1.2	Changed routine to add function byte to 
;			select which function of this routine.
;			Expanded routine to add set user function.
;
;				Function:
;				   00h = alter user number
;				   01h = show directory
;	01-20-83   v1.3	Added seperator between filenames in display.
;
; 
;
	global	tcmd,tfcb,bldfcb,loop1,prtit
	global	srchnxt,end
	global	linecnt,diroffset,prtfn
	global	srchfrst,prtspace,prtdot,prtcrlf
	global	nohit,findme,notfound,count
	global	function,setusr,showdir,badfunc
	global	badbyte,user,usrmsg
;
;SYSTEM EQUATES
;
cr	equ	0dh		;carriage return
lf	equ	0ah		;line feed
esc	equ	1bh		;escape
exitcpm	equ	0		;warmboot exit point
base	equ	0		;find wboot jmp address at rst0
dumyadr	equ	0
tfcb	equ	5ch		;default fcb
tcmd 	equ	80h		;default command line and DBA addr       
tbuf	equ	80h		;default buffer
bdos	equ	5		;CP/M function calls entry point
entsize equ	13		;bytes per sorted directory entry
;				; includes: 1-2   for user number
;				;           3-13  for fn,ft (no period)
pagesize equ	20		;# of lines to print on a page
dirsect  equ	26		;# of sectors in directory track
tpa	 equ	100h
dbasetop equ	00400h		;free memory above dBASEII (a400h-a000h)
dbload	 equ	00500h		;load asm. routine here
x	 equ	0a000h		;offset to add to all labels and     
				; variables
;
;
	aseg
 	org	tpa 
;
;				;this routine will move the code at
;				; 400h to a400h
;
	ld	hl,st1		;from address
	ld	de,x+dbasetop	;to address
	ld	bc,fini1-st1	;length
	ldir			;move it
;
;				;this routine will move the code at
;				; 500h to a500h
;
	ld	hl,start	;from address
	ld	de,x+dbload	;to address
	ld	bc,fini-start	;length
	ldir			;do the move
;
 	jp	x+start		;then jump to the newly moved code
;	jp	exitcpm
;
 	org	dbasetop		;put variables here
;
st1:					;start of variables
;
function:
	db	01h			;function byte
;					; 0 = set user
;					; 1 = show directory
findme:  
	db	'???????????'		;directory entry to look for
userno:
	db	00h			;user number
drive:
	db	00h			;drive to search
junk:
	db	'end of storage used by dbdir'
;
fini1:             			;end of variables
;
;
 	org	dbload
;
;
start:
	ld	(x+oldstack),sp		;save current stack pointer
	ld 	sp,x+stack	        ;set stack pointer to my stack
;
	push	psw			;save the world
	push	bc
	push	de
	push	hl
;
	ld	a,(x+function)		;get function
	cp	00h			;=00h then set user
	jp	z,x+setusr
	cp	01h			;=01h then show directory
	jp	z,x+showdir
	jp	x+badfunc		;bad function passed 
;
setusr:
	call	x+user
	ld 	de,x+usrmsg
	call	x+sout
	call	bdos
	jp	x+end
;
showdir:
	ld	de,x+dirmsg		;print signon msg
	call	x+sout
	ld	bc,0000h		;init count
	ld	(x+count),bc
;
	call	x+setdma		;set dma to addr of tbuf(80h)
	call	x+bldfcb
	call	x+srchfrst		;get 1st entry
	jp	z,x+nohit  		;=z,no entry found
      	call	x+prtit 
loop1:
	call	x+srchnxt		;get n+1 entry
	jp	z,x+end  		;=z,all done
	call	x+prtit			;print the entry
	jp	x+loop1			;loop til done
;
bldfcb:
	ld	a,(x+drive)		;get drive byte
	ld	(tfcb),a     		;put in fcb
;
	ld	hl,x+findme		;sending addr (search string)
	ld	de,tfcb+1    		;receiving addr
	ld	bc,000bh		;count of 11
	ldir				;do move
	ret
;
prtit:
	ld	a,(x+count)		;check how many entries have
	cp  	05h			; printed-only 5 per line
	call	z,x+prtcrlf
	inc	a			;up count
	ld	(x+count),a
;
	ld	hl,tbuf+1     		;addr of buffer
	ld	bc,(x+diroffset)	;offset into directory entry
	ld	b,00h
	add	hl,bc
	ld	bc,000bh		;count of 11
;
	call	x+prtspace	        ;format print of each entry
	ld	bc,0008h
	call	x+prtfn
	call	x+prtdot
	ld	bc,0003h
	call	x+prtfn
	call	x+prtgate
	ret
;
prtspace:
	ld	e,' '
	call	x+conout
	ret
;
prtgate:
	ld	e,'|'
	call	x+conout
	ret
;
prtdot:
	ld	e,'.'
	call	x+conout
	ret
;
prtcrlf: 
	ld	de,x+crlf
	call	x+sout
 	xor	a			;put zero in A
 	ld	(x+count),a		;zero out count
	ret
;
prtfn:  
	ld	e,(hl)			;get a char
	call	x+conout		;print it
	inc	hl			;point to next char
	dec	c			;dec count
	ret	z			;return if done
	jp	x+prtfn  		;loop til done
;
nohit:    
	ld	de,x+notfound
	call	x+sout
	jp	x+end
;
badfunc:
	ld	de,x+badbyte
	call	x+sout
	jp	x+end
;
end:
	pop	hl			;put the world back as you 
	pop	de			; found it
	pop	bc
	pop	psw
	ld	sp,(x+oldstack)		;dont forget the stack
 	ret				;ret, not jp to 0
;
;
;
;
conin:
      	ld  	c,1     
	call	bdos
	ret
conout:
	push	psw
	push	bc
	push	de
	push	hl
       	ld 	c,2      
	call	bdos
	pop	hl
	pop	de
	pop	bc
	pop	psw
	ret
dirin:
	ld	c,6
	ld	e,0ffh
	call	bdos
	cp	00h 			;=00h, then char not ready
	jp	z,x+dirin		; will want to wait for it
	ret
sout:
       	ld 	c,9                     ;write string to console
	call	bdos
	ret
;
setdma:
	ld	c,1ah			;set dma addr to 80h
	ld	de,tbuf
	call	bdos
	ret
user:    
	ld	a,(x+userno)		;set user number
	ld	e,a
	ld	c,20h
	call	bdos
	ret
;
srchfrst:				;do search first
	call	x+user			;alter user #
;
	ld	c,11h			;bdos search 1st
	ld	de,tfcb			;de with addr of fcb
	call	bdos
	push	psw			;save A register and z flag
	add	a,a			;adjust A to get offset to
	add	a,a			; the found entry
	add	a,a
	add	a,a
	add	a,a
	ld	(x+diroffset),a		;save the offset
	pop	psw			;get the original value of A
	inc	a			;to detect 0ffh
	ret
;
srchnxt:				;do search next
;					;  will only set srcheof flag
;					;   when have checked all users
	ld	c,12h
	call	bdos
	push	psw			;save A register and z flag
	add	a,a			;adjust A to get offset to
	add	a,a			; the found entry
	add	a,a
	add	a,a
	add	a,a
	ld	(x+diroffset),a		;save the offset
	pop	psw			;get the original value of A
	inc	a			;to detect 0ffh
	ret	
;
;
;
;		Variables
;
count:
	db	00h,00h
linecnt:
	db	00h			;count of # of lines printed
					; init at 2 for heading
diroffset:
	db	00h			;offset into directory entry
;					; returned by bdos search,
;					; incremented by 32, max.
;					; should be 255
;
dirmsg:
	db	cr,lf
	db	'dBASEII directory routine'
	db	cr,lf
	db	'Version 1.3     '
	db	'01-20-83'
	db	cr,lf
	db	'$'
notfound:
       	db	'++ Entry not found ++'
	db	'$'
usrmsg:
	db	cr,lf
	db	'User number has been altered'
	db	cr,lf
	db	'$'
badbyte:
	db	'++ Invalid function passed ++'
	db	cr,lf
	db	'$'
anykey:
	db	'                         '
	db	'Press any key to continue'
	db	cr
	db	'$'
crlf:  
	db	cr,lf
	db	'$'
stktop: ds	64	                ;top of stack
stack:	ds	1	                ;stack          
oldstack:				;saves old stack pointer
	dw	0000h
junk2:
	db	'after old stack'
;
fini:
 	end
