*************************************************
* ls.asm					*
* v4.1						*
* Jörgen Grahn					*
*						*
* 910718 ... 921116 ... 921221 ...		*
* 921231 ... 930101				*
*						*
*************************************************

ABSEXECBASE		EQU 4
SHARED_LOCK		EQU -2
ERROR_DIR_NOT_FOUND	EQU 204
ERROR_NO_MORE_ENTRIES	EQU 232
SIGBREAKF_CTRL_C	EQU $00001000
fib_SIZEOF		EQU 260
fib_DIRENTRYTYPE	EQU 4			* <0 = dir, >0 = fil
fib_FILENAME		EQU 8

	INCLUDE "offsets204.i"

libcall	MACRO
	jsr _LVO\1(a6)
	ENDM

*************************************************

	CSECT "text",code

entrypoint:
	movem.l	d1-d7/a0-a6,-(sp)

	lea	bssbase,a4

	move.l	ABSEXECBASE.w,a6

	lea	dosname(pc),a1
	moveq	#36,d0

	libcall	OpenLibrary
	move.l	d0,a6
	beq	exit

	* We now have DosBase in a6, and BSS in a4.

	lea	ra_array(a4),a0
	clr.l	(a0)
	move.l	a0,d2
	lea	template(pc),a0
	move.l	a0,d1
	clr.l	d3

	libcall	ReadArgs
	move.l	d0,a5				* Save the ReadArgs struct
	bne.s	readargs_ok

	bsr	printioerr
	bra	closedos

readargs_ok:					* Dos in a6, ReadArgs in a5.

	move.l	ra_array(a4),d1			* Program argument string
	move.l	#SHARED_LOCK,d2
	libcall	Lock
	move.l	d0,d7
	bne.s	locked_ok

	bsr	printioerr
	bra.s	freeargs

locked_ok:				* Dos - a6	ReadArgs - a5
					* Lock - d7	BSS - a4
	lea	fib(a4),a3		* fib - a3

	move.l	d7,d1
	move.l	a3,d2
	libcall	Examine
	tst.l	d0
	beq.s	examine_failed
	tst.l	fib_DIRENTRYTYPE(a3)	* Did we Lock() a file?
	bpl.s	dir_examined

examine_on_file:
	moveq	#0,d2
	move.l	#ERROR_DIR_NOT_FOUND,d1
	libcall	PrintFault
	bra.s	freelock

	* d3 holds how many names have been written to this row.
	* d4 holds the _real_ position on the row.
dir_examined:
	clr.l	d3
	move.l	d3,d4

exnext:
	lea	file(a4),a2
	bsr	readname		* fib (a3) file (a2) lock (d7)
					* nr_names (d3) pos (d4)
	tst.l	d0
	bne.s	print_file
	bsr.s	newline			* Put us on new line...
	bra.s	no_more_files		* ...and close down

print_file:
	move.l	a2,a0
	bsr.s	putstr

	move.l	#SIGBREAKF_CTRL_C,d1
	libcall	CheckSignal		* Check for ^C.
	tst.l	d0
	beq.s	exnext

	bsr.s	newline			* Put us on new line...
	lea	breakstring(pc),a0
	bsr.s	putstr
	bra.s	freelock

examine_failed:		* Sort of cheating, but it works. Putting this here
			* is exactly the same as calling printioerr,
			* as ENME will never happen.
no_more_files:
	libcall	IoErr			* Should an error be printed?
	cmpi.l	#ERROR_NO_MORE_ENTRIES,d0
	beq.s	freelock
	bsr	printioerr

freelock:
	move.l	d7,d1
	libcall	UnLock

freeargs:
	move.l	a5,d1
	libcall	FreeArgs

closedos:
	move.l	a6,a1
	move.l	ABSEXECBASE.w,a6
	libcall	CloseLibrary

exit:
	moveq	#0,d0
	movem.l	(sp)+,d1-d7/a0-a6
	rts

*************************************************
*
* Puts us on a new line, if necessary.
* Destroys d0-d2/a0-a1.

newline:
	tst.l	d4
	beq.s	1$
	lea	newlinestr(pc),a0
	bsr.s	putstr
1$:	rts

*************************************************
*
* fputs(string (a0))
* Förstör d0-d1/d5/a0-a1
*

putstr:
	move.l	a0,-(sp)
	libcall	Output
	move.l	d0,d5
	beq.s	1$
	move.l	(sp)+,d1
	libcall	PutStr
	move.l	d5,d1
	libcall	Flush
1$:	rts

*************************************************
*
* Reads a filename for printing.
*
* a2 - 'file' array
* a3 - fib
* d7 - lock
* d3 - number of names previous on row (altered [0..3])
* d4 - position on row (altered)
*
* returns 0 if end of names.

readname:
	movem.l	d1-d2/d5-d7/a0-a6,-(sp)

	move.l	d7,d1
	move.l	a3,d2
	libcall	ExNext
	tst.l	d0
	beq.s	sorry

	lea	fib_FILENAME(a3),a0
	move.l	a2,a1

	tst.l	fib_DIRENTRYTYPE(a3)
	bmi.s	1$
	move.l	#$9b33336d,(a1)+		* ESC[33m - highlight mode

1$:	move.b	(a0)+,d0
	beq.s	name_filled
	addq.l	#1,d4
	move.b	d0,(a1)+
	bra.s	1$

name_filled:
	tst.l	fib_DIRENTRYTYPE(a3)
	bmi.s	fill_spaces
	move.b	#$9b,(a1)+		* reset highlight mode
	move.b	#'3',(a1)+
	move.b	#'1',(a1)+
	move.b	#'m',(a1)+

fill_spaces:
	move.b	positions(pc,d3),d0
1$:	move.b	#' ',(a1)+
	addq.l	#1,d4
	cmp.b	d0,d4
	ble.s	1$

done_spaces:
	addq.l	#1,d3
	cmpi.w	#4,d3
	bne.s	1$

	clr.l	d3
	move.l	d3,d4
	move.b	#10,(a1)+
1$:	move.b	#0,(a1)

sorry:	movem.l	(sp)+,d1-d2/d5-d7/a0-a6
	rts

*************************************************

* Skriver ut IoErr().
* Förstör a0-a1/d0-d2.
*
printioerr:
	libcall	IoErr
	moveq	#0,d2
	move.l	d0,d1
	libcall	PrintFault
	rts

*************************************************

positions:	dc.b	16,32,48,64
template:	dc.b	'DIR',0
dosname:	dc.b	'dos.library',0
versionstring:	dc.b	0,'$VER: ls 4.1 (1.1.93) Jörgen Grahn',0
breakstring:	dc.b	'***Break'
newlinestr:	dc.b	10,0

*************************************************

	CSECT	"__MERGED",BSS

bssbase:
ra_array:
	ds.l	1
	CNOP	0,4
fib:	ds.b	fib_SIZEOF		* FileInfoBlock in BSS segment
	CNOP	0,2
file:	ds.b	4+30+4+1+1		* Room for:
					* a) Escape sequence
					* b) 30 byte filename
					* c) Escape sequence
					* d) one space
					* e) terminating NULL byte
	END
