	include	"exec/types.i"
	include	"exec/memory.i"
	include	"libraries/dos.i"

	xref	_LVOOpenLibrary,_LVOCloseLibrary
	xref	_LVOAllocMem,_LVOFreeMem,_LVORawDoFmt,_LVOSetSignal
	xref	_LVOOutput,_LVOWrite,_LVOLock,_LVOUnLock
	xref	_LVOExamine,_LVOExNext,_LVOIoErr,_LVOCurrentDir

exec	macro				; makro exec-rutiinien kutsumiseen
	move.l	$4,a6			; execbase a6:een
	jsr	_LVO\1(a6)		; jsr _LVOxxx(a6)
	endm
dos	macro				; makro dos-rutiinien kutsumiseen
	move.l	a4,a6			; dosbase a6:een
	jsr	_LVO\1(a6)		; jsr _LVOxxx(a6)
	endm

BUFFER	equ	256			; tulostuspuskurin koko

main	clr.b	-1(a0,d0.l)		; nolla komentorivin loppuun
	move.l	a0,a2			; komentorivin osoite a2:een

	lea	dosname(pc),a1		; dos-kirjaston nimi
	moveq	#0,d0			; versio (mikä tahansa)
	exec	OpenLibrary		; avataan dos
	move.l	d0,a4			; dos-perusosoite a4:ään
	tst.l	d0			; aukesiko kirjasto?
	beq	cleanup			; ei -> pois

	move.l	#BUFFER,d0		; tulostuspuskurin koko
	moveq	#MEMF_PUBLIC,d1		; muistityyppi
	exec	AllocMem		; varataan muistia
	move.l	d0,a5			; puskurin osoite talteen a5:een
	tst.l	d0			; saatiinko muistia?
	beq	cleanup			; ei -> pois

	lea	spce(pc),a0		; spaceja nimien sisennystä varten
	move.l	a0,d5			; spacejen loppuosoite d5:een
	bsr	dir_it			; tulostetaan hakemisto!

cleanup	move.l	a5,d0			; muistia varattu?
	beq.s	100$			; ei -> hypätään yli
	move.l	d0,a1			; joo -> osoite a1:een
	move.l	#BUFFER,d0		; ja koko d0:aan
	exec	FreeMem			; vapautetaan muisti

100$	move.l	a4,d0			; dos-kirjasto auki?
	beq.s	110$			; ei -> hypätään yli
	move.l	d0,a1			; perusosoite a1:een
	exec	CloseLibrary		; suljetaan dos
110$	moveq	#0,d0			; ei virhettä!
	rts				; pois


dir_it	moveq	#0,d6			; ei ole vielä Lockattu
	moveq	#-1,d4			; eikä CurrentDirrattu
	move.l	#fib_SIZEOF,d0		; varataan tilaa FIBille
	moveq	#MEMF_PUBLIC,d1		; muistityyppi
	exec	AllocMem		; varaatn muisti
	move.l	d0,d7			; varatun muistin osoite
	beq	dir_err			; ei saatu muistia -> pois

	move.l	a2,d1			; kohteen nimi
	moveq	#SHARED_LOCK,d2		; Lock-tyyppi
	dos	Lock			; lukitaan kohde
	move.l	d0,d6			; lockin osoite
	beq	dir_err			; ei saatu lukittua -> pois

	move.l	d6,d1			; Lock
	move.l	d7,d2			; FileInfoBlock
	dos	Examine			; tutkitaan hakemistoa
	tst.l	d0			; virhe?
	beq	dir_err			; jop -> pois

	move.l	d7,a3			; FileInfoBlock
	tst.l	fib_DirEntryType(a3)	; onko olio hakemisto?
	bmi	dir_fil			; ei, vaan tiedosto -> hypi

	move.l	d6,d1			; Lock
	dos	CurrentDir		; mennään hakemistoon sisälle
	move.l	d0,d4			; entinen dir talteen

dir_lp	moveq	#0,d0			; tarkistetaanko, painettiinko
	moveq	#0,d1			; CTRL+C
	bset	#12,d1
	exec	SetSignal		; tutkitaan signaalit
	btst	#12,d0			; CTRT+C?
	beq	dir_cnt			; ei -> jatketaan

	lea	fmtbrk(pc),a0		; tulostetaan '*** break'
	bsr	dpymsg
	bra	dir_rrr			; ja sitten pois täältä ja heti!

dir_cnt	move.l	d6,d1			; Lock
	move.l	d7,d2			; FileInfoBlock
	dos	ExNext			; tutkitaan hakemiston oliota
	tst.l	d0			; virhe?
	beq	dir_err			; joo -> loppuiko hakemisto?

	move.l	d7,a3			; FileInfoBlock
	tst.l	fib_DirEntryType(a3)	; onko olio hakemisto?
	bmi.s	dir_fil			; ei, tiedosto -> hyppää

	lea	fib_FileName(a3),a3	; hakemiston nimi...
	move.l	a3,d1			; ...d1:een
	move.l	d5,d0			; sisennys
	lea	fmtdir(pc),a0		; moutoilurivi
	bsr	dpymsg			; tulostetaan hakemiston nimi

	movem.l	d4-d7/a0-a2,-(sp)	; rekisterit pinoon
	subq.l	#2,d5			; kasvatetaan sisennystä
	move.l	a3,a2			; alihakemiston nimi
	bsr	dir_it			; käsitellään alihakemisto
	movem.l	(sp)+,d4-d7/a0-a2	; rekisterit takaisin
	tst.l	d0			; virhe sisemmällä tasolla?
	bne	dir_rrr			; jep -> pois
	bra.s	dir_lp

dir_fil	lea	fib_FileName(a3),a0	; tiedoston nimi...
	move.l	a0,d1			; ...d1:een
	move.l	fib_Size(a3),d2		; tiedoston koko tavuina
	move.l	d5,d0			; sisennys
	lea	fmtfile(pc),a0		; muotoilurivi
	bsr	dpymsg			; tulostetaan nimi
	move.l	d4,d0			; tutkitaan, oliko käyttäjän
	addq.l	#1,d0			; antama kohde tiedosto.  Jos oli,
	bne	dir_lp			; homma on selvä.
	bra.s	dir_rrr

dir_err	dos	IoErr			; luetaan virhe dossilta
	cmp.l	#ERROR_NO_MORE_ENTRIES,d0 ; hakemisto lopussa?
	bne.s	100$			; ei -> tulostetaan virhe
	bsr.s	dir_cu			; joo -> kaikki hyvin, pois!
	moveq	#0,d0			; ei virhettä
	rts
100$	lea	fmterr(pc),a0		; virheen muotoilu...
	bsr	dpymsg			; ...ja tulostus
dir_rrr	bsr.s	dir_cu			; siivotaan jäljet
	moveq	#-1,d0			; virhe ylemmälle tasolle
	rts

dir_cu	move.l	d4,d1			; entinen dir
	addq.l	#1,d4			; -1 (ei ole CurrentDirrattu) ?
	beq.s	90$			; joop -> hypitään yli
	dos	CurrentDir		; mennään takaisin sinne
90$	tst.l	d7			; muisti varattu?
	beq.s	100$
	move.l	d7,a1			; jep, vapautetaan se
	move.l	#fib_SIZEOF,d0
	exec	FreeMem
100$	move.l	d6,d1			; Lock?
	beq.s	110$
	dos	UnLock			; jep, vapautetaan
110$	rts



dpymsg	movem.l	d0-d7/a0-a3,-(sp)	; rekisterit pinoon
	move.l	sp,a1			; osoitin datarekistereihin pinossa
	lea.l	putchar(pc),a2		; putchar-rutiinin osoite
	move.l	a5,a3			; puskurin osoite
	exec	RawDoFmt		; formatoidaan tulostus
	dos	Output			; tulostustiedoston filehandle
	move.l	d0,d1
	beq.s	201$			; jos nolla, ei voida tulostaa
	move.l	a3,d2
200$	tst.b	(a3)+			; lasketaan merkkijonon pituus
	bne.s	200$
	subq.w	#1,a3			; NULL-tavua ei lasketa
	move.l	a3,d3			; pituus d3:een
	sub.l	d2,d3
	dos	Write			; tulostetaan puskurin sisältö
201$	movem.l	(sp)+,d0-d7/a0-a3
	rts
putchar	move.b	d0,(a3)+		; putchar-rutiini RawDoFmt:lle
	rts

;;;; muotoilurivit RawDoFmt-tulostukseen
fmtdir	dc.b	$9b,'1m%s%s',$9b,'0m',10,0
fmtfile	dc.b	'%s%-34.34s  (%6.6ld tavua)',10,0
fmterr	dc.b	'*** dos-virhe %ld',10,0
fmtbrk	dc.b	'*** break',10,0
spcs	dc.b	'                    '
spce	dc.b	0

dosname	dc.b	'dos.library',0

	end


