;OSCDIR.ASM  04/03/83  Osborne-1 Compare Directory.
;	     Shows filename differences in 
;	     half intensity mode.
;	     Derived by Tom McCormick from.........
;
;CDIR.ASM by:	Robert Wilcox
;		920 N. Washington St.
;		Owosso,  MI	48867
;Date:		15 Sept. 82
;
;		Assemble using ASM.COM:
;
;		A>ASM B:OSCDIR.BBZ
;
;		A>LOAD B:OSCDIR
;
;		A>REN B:CDIR.COM=B:OSCDIR.COM
;		(you may remove the 'OS' prefix.)
;
;Operation: CDIR<CR> prints a directory of files of the disk in drive
;	    A, with files that are also on drive B indicated by the
;	    file name being in half-intensity.
;
;	    Wild cards (CDIR *.ASM, CDIR test?.as?, etc. are supported.
;
;	    CDIR ?<CR> gives a help message.
;
;	    Any key pressed while the directory is being printed aborts
;	    the program.
;
FALSE	EQU	0
TRUE	EQU	NOT FALSE
;
;One and only one of the following conditionals should be true
;to select the visual attributes and cursor addressing for the
;terminal used.
;
;
;CP/M FUNCTION CODES - PASS IN REGISTER C TO BDOS
RCCFC	EQU	01	;READ CONSOLE CHARACTER
WCCFC	EQU	02	;WRITE CONSOLE CHARACTER
WCBFC	EQU	09	;WRITE CONSOLE BUFFER
GCSFC	EQU	11	;GET CONSOLE STATUS
RESET	EQU	13	;DISK RESET
SRFFC	EQU	17	;SEARCH FIRST
SRNFC	EQU	18	;SEARCH NEXT
;
;CP/M ADDRESS EQUATES
;
BDOS	EQU	0005H	;BDOS ENTRY POINT
SFCB	EQU	005CH	;SYSTEM FILE CONTROL BLOCK
DBUF	EQU	0080H	;SYSTEM DISK BUFFER
;
;ASCII EQUATES
;
BEL	EQU	07H		;BELL
LF	EQU	0AH		;LINE FEED
CR	EQU	0DH		;CARRIAGE RETURN
ESC	EQU	1BH		;ESCAPE
EOS	EQU	'$'		;END OF STRING
;
PRTN:	EQU	3		;number of file names on a line
				;SEE ALSO SPACES:
;
	ORG	0100H		;program originate address
;
START:	LXI	H,0		;begin by saving system
	DAD	SP		;stack pointer and setting
	SHLD	OLDSP		;program stack
	LXI	SP,STACK+64
;
	LXI	D,MSG0
	CALL	WASC		;print program title
;
;	print a help message if '?' was
;	typed after the program name.
;
	lda	dbuf		;look at dbuf
	ana	a		;see if anything typed after "CDIR"
	jz	makefcb 	;if not, make like "CDIR *.*"
	cpi	2		;2 characters (" ?") typed?
	jnz	nohelp		;no -
	lda	dbuf+2		;if yes, was it '?'
	cpi	'?'
	jnz	nohelp
	lxi	d,helpmsg	;if '?' type help message and
	call	wasc		;return to cp/m
	jmp	exit
;
makefcb:
	lxi	h,fcba		;if no file specifications typed,
	lxi	d,sfcb		;make it as if "*.*" was typed.
	mvi	b,16
	call	move
;
nohelp:;			;program continues - -
	LXI	D,MSG2
	CALL	WASC		;give instructions
WAIT:	CALL	RACC		;wait for <CR>
	CPI	' '		;space returns
	JZ	DONE		;to CP/M
	CPI	CR
	JNZ	WAIT
	MVI	C,RESET
	CALL	BDOS
	LXI	D,MSG1
	CALL	WASC		;print header
	LXI	D,SFCB
	CALL	GETFL		;get file list
	LDA	FLCNT
	ORA	A
	JZ	NONE		;no matching files on drive A
	MVI	A,PRTN
	STA	PCOUNT
;
LOOP:	CALL	CKABRT		;check if any key pressed
				;abort if so.
	LHLD	FLPTR		;HL = ptr to next name
	LXI	D,SFCB		;DE = destination addr
	MVI	B,16		;# bytes to move
	CALL	MOVE
	SHLD	FLPTR		;update file list ptr
	MVI	A,2		;set drive specification for B
	STA	SFCB
	LXI	D,SFCB		;search for file
	CALL	SRCHF		;on drive B.
	INR	A
	PUSH	PSW
;
	JZ	LOOP1
	LXI	D,MSG6		;set attribute tag
	CALL	WASC
;
LOOP1:
	MVI	A,' '
	CALL	WACC		;print a space
	LXI	H,SFCB+1	;point to file name
	MVI	B,8
	CALL	PMSG		;print file name
	MVI	A,' '
	CALL	WACC		;print a space
	MVI	B,3
	CALL	PMSG		;print file type
	MVI	A,' '
	CALL	WACC		;print a space
	POP	PSW
	JZ	LOOP3
	LXI	D,MSG7		;reset attribute tag
				;or "*"
	CALL	WASC
;
LOOP3:	LXI	H,FLCNT 	;decrement filelist count
	DCR	M		;and quit if no files left,
	JZ	DONE		;otherwise continue.
	LXI	H,PCOUNT
	DCR	M		;if this line is full skip the
	JZ	LOOP4		;spaces and start a new line.
	LXI	D,SPACES
	CALL	WASC		;print "  |  "
	JMP	LOOP		;and get next file name
;
LOOP4:	CALL	WEOLC		;start a new line
	MVI	A,PRTN
	STA	PCOUNT
	JMP	LOOP		;and get next file name.
;
CKABRT: MVI	C,GCSFC 	;get console status function code
	CALL	BDOS
	ANA	A		;set flags..A=0 if no key pressed
	RZ
	CALL	RACC
;
DONE:	CALL	WEOLC
	LXI	D,MSG4
	CALL	WASC
	CALL	RACC
	MVI	C,RESET
	CALL	BDOS
;
	JMP	EXIT		;back to CP/M
NONE:	LXI	D,MSG3
	CALL	WASC
;
;EXIT ROUTINE RESETS SYSTEM STACK AND RETURNS TO CP/M
;
EXIT:	LHLD	OLDSP
	SPHL
	RET
;
GETFL:	LXI	H,FLIST 	;FLPTR = FWA OF FILELIST
	SHLD	FLPTR
	XRA	A		;FLCNT = 0
	STA	FLCNT
	PUSH	D
GETFL1: CALL	SRCHF		;SEARCH FOR FIRST OCCURRENCE
	CPI	255		;JUMP IF NONE FOUND
	JZ	GETFL3
GETFL2: ANI	03H		;DE = DBUF + 32 * (A AND 3)
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	ADD	A
	MOV	L,A
	MVI	H,0
	LXI	D,DBUF
	DAD	D
	XCHG
	LHLD	FLPTR		;HL = FILE LIST PTR
	XCHG
	MVI	B,16		;B = # OF BYTES TO MOVE
	CALL	MOVE
	XCHG
	SHLD	FLPTR		;UPDATE FILELIST POINTER
	LXI	H,FLCNT 	;INCREMENT FILELIST COUNT
	INR	M
	POP	D
	PUSH	D
	CALL	SRCHN		;SEARCH FOR NEXT OCCURRENCE
	CPI	255		;LOOP IF ANOTHER FOUND
	JNZ	GETFL2
GETFL3: POP	D
	LXI	H,FLIST 	;RESET FILELIST POINTER
	SHLD	FLPTR
	RET
;
MOVE:	MOV	A,M		;move B bytes from HL to DE
	INX	H
	STAX	D
	INX	D
	DCR	B
	JNZ	MOVE
	RET
;
;SEARCH FOR FIRST OCCURRENCE OF FILE
;ON ENTRY DE POINTS TO FCB
;RETURNS 0, 1, 2 OR 3 IF FOUND, 255 IF NOT FOUND
;
SRCHF:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,SRFFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET

;SEARCH FOR NEXT OCCURRENCE OF FILE
;
SRCHN:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,SRNFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;READ CONSOLE CHARACTER
;EXIT: CHARACTER IN ACCUM.
;
RACC:	PUSH	H
	PUSH	D
	PUSH	B
	MOV	E,A
	MVI	C,RCCFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;WASC - WRITE BUFFER TO CONSOLE
;ENTRY - DE POINTS TO MESSAGE BUFFER
;MSG MUST END IN '$'
;
WASC:	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,WCBFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
;WEOLC - WRITE END OF LINE (CR,LF)
;
WEOLC:	MVI	A,CR
	CALL	WACC
	MVI	A,LF
;
;WRITE CONSOLE CHARACTER
;ENTRY: CHARACTER IN ACCUM.
;
WACC:	PUSH	H
	PUSH	D
	PUSH	B
	MOV	E,A
	MVI	C,WCCFC
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	RET
;
PMSG:	MOV	A,M		;prints B characters
	CALL	WACC		;pointed at by HL
	INX	H
	DCR	B
	JNZ	PMSG
	RET
;
;
;
;MESSAGE AND STORAGE AREA
;
MSG0:
;
	DB	1BH	;Osborne-1 Clear Screen
	DB	CR,LF
;
	DB	'     CDIR - OS-1 04/03/83 R Wilcox/T McCormick',CR,LF
	DB	' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= '
	DB	CR,LF,LF,EOS
MSG1:
;
	DB	CR,LF
;
	DB	'      Directory is for drive A:. ',CR,LF
	DB	'      Files also on B:',ESC,')',' HALF-INTENSITY '
	DB	ESC,'(',CR,LF,EOS
;
MSG2:	DB	'   --> Place diskettes in drives A and B '
	DB	CR,LF
	DB	'    RETURN to start',cr,lf
	DB	'    SPACE  to quit  >',EOS
MSG3:	DB	' there are no files on drive A:',EOS
MSG4:	DB	cr,lf,'--> Replace ORIG disk in drive A , press RETURN: '
	DB	EOS
;
MSG6:	DB	ESC,')',EOS
MSG7:	DB	ESC,'(',EOS
;
HELPMSG:
	DB	' CDIR prints a directory of disk A.',cr,lf
	DB	' Files which also exist on disk B are',cr,lf
	DB	' indicated by '
;
	DB	ESC,')',' HALF-INTENSITY. '
	DB	ESC,'('
;
	DB	cr,lf,lf,lf
	DB	'      Usage: CDIR<CR>',CR,LF
	DB	'             CDIR *.*<CR>',CR,LF
	DB	'             CDIR *.COM<CR>',CR,LF
	DB	'             CDIR AB??.??Z<CR>',CR,LF,LF
	DB	' You will be given a chance to change',CR,LF
	DB	' diskettes in both drives A: and B:.',CR,LF
	DB	LF,EOS
SPACES: DB	'   ',EOS	;SPACES BETWEEN COLUMNS
FCBA:	DB	1,'???????????',0,0,0,0 ;ambig file name
OLDSP:	DS	2			;SYSTEM SP
STACK:	DS	64			;LOCAL STACK
;
FLCNT:	DS	1		;file list count
FLPTR:	DS	2		;file list pointer
PCOUNT: DS	1		;print counter
FLIST:	EQU	$		;file list starts here
	END	START

list co