;	FAD - File-ASCII-Druck
;	ASCII-Teil von beliebigen Files drucken

;	© 1990 Ebsche Hermesmann Junior (EHJ) - PUBLIC DOMAIN

;	Aufruf: FAD (-L) <Filename>

;	-L unterdrückt Linefeeds

;	<Filename> kann JEDES beliebige File sein,
;		   die Filelänge ist nicht begrenzt

ExecBase=4

;---EXEC-Funktionen
AllocMem=-198
FreeMem=-210
OpenLibrary=-552
CloseLibrary=-414

;---DOS-Funktionen
Open=-30
Close=-36
Read=-42
Write=-48
Output=-60
Lock=-84
Examine=-102
UnLock=-90

g:	move.b	#0,-1(a0,d0)	;Nullbyte an Filenamen anhängen
	subq.l	#1,d0		;D0 = Länge Filename (ohne 0)
	move.l	a0,a5		;Adresse Name und
	move.l	d0,d7		;Länge Name merken

;---Dos öffnen
	lea	DosName(pc),a1	;'dos.library'
	moveq	#0,d0		;Version egal
	move.l	ExecBase,a6	;
	jsr	OpenLibrary(a6)	;öffnen
	move.l	d0,DosBase
	bne.s	w1		;weiter, sonst

	rts			;zurück ins CLI

;---Ausgabekanal (CLI-Fenster) holen
w1:	move.l	d0,a6		;DosBase nach A6
	jsr	Output(a6)	;Output holen
	move.l	d0,Outhd	;und merken
	beq	TUESS		;hat nicht geklappt

;---Überschrift ausgeben
	lea	Text1(pc),a0
	bsr	Text

;---Suche ersten Buchstaben im Filenamen
	move.l	d7,d0		;Länge Filename nach D0
	beq	noName		;Länge = 0, Fehler

	move.l	a5,a0		;Filename ab (A0)
SuchNa:	cmp.b	#" ",(a0)+	;Space ?
	bne.s	NameDa		;nein, Name fängt an

	dbra	d0,SuchNa	;sonst weiter 1.Buchstaben suchen

	bra	noName 		;NUR Leerzeichen, Fehler

;---Fileame gefunden, testen ob '?' oder '-L' davor
NameDa:	cmp.b	#"?",-(a0)	;'?' ?
	beq	noName		;dann Aufruf ausgeben

	cmp.b	#"-",(a0)	;1.Buchstabe = '-' ?
	bne.s	holFIB		;nein, weiter

	cmp.b	#" ",2(a0)	;3.Buchstabe = ' ' ?
	bne.s	holFIB		;nein, weiter

	st	Linefeeds	;Linefeeds NICHT erlaubt
	addq.l	#3,a0		;A0 um 3 Bytes ('-L ') weiter

;---Speicher für FileInfoBlock reservieren
holFIB:	move.l	a0,Filename	;Adresse Filename merken
	move.l	#260,d0		;260 Bytes
	bsr	Reservieren	;reservieren
	move.l	d0,FIB		;Header merken
	beq	noFree		;hat nicht geklappt, Fehler

;---Filelänge holen
	move.l	Filename,d1	;Adresse Filename nach D1
	moveq	#-2,d2		;Lock auf Filenamen
	move.l	DosBase,a6
	jsr	Lock(a6)	;holen
	move.l	d0,d5		;und in D5 merken
	beq	noFile		;hat nicht geklappt

	move.l	d0,d1		;Lock nach D1
	move.l	FIB,d2		;FileInfoBlock
	jsr	Examine(a6)	;einlesen
	tst.l	d0
	bne.s	w2		;hat geklappt, sonst

;---Examine hat nicht geklappt
	move.l	d5,d1		;Lock
	jsr	UnLock(a6)	;freigeben und
	bra	noFile		;Fehler ausgeben

;---Filelänge holen
w2:	move.l	FIB,a0		;Aus 124.Langwort im FIB
	move.l	124(a0),d6	;Filelänge nach D6 holen
	move.l	d5,d1		;Lock
	jsr	UnLock(a6)	;freigeben

;---2 mal Filelänge im RAM reservieren
	move.l	d6,d7		;Länge des Files
	lsl.l	#1,d7		;* 2 (File und Druckerfile)
	addq.l	#2,d7		;+ 2 (LF und RETURN)
	move.l	d7,d0		;= Gesamtlänge
	bsr	Reservieren	;Gesamtlänge reservieren
	move.l	d0,Puffer	;Ab 'Puffer' im Speicher
	beq	noFree		;hat nicht geklappt

	add.l	d6,d0		;Pufferanfang + Filelänge
	move.l	d0,Puffer2	;= Anfang von Puffer2
	move.l	d7,GesLaenge	;Gesamtlänge merken

;---File öffnen
	move.l	Filename,d1	;File
	move.l	#1005,d2	;Modus 'OLD'
	move.l	DosBase,a6	;
	jsr	Open(a6)	;öffnen
	move.l	d0,Filehd	;Header merken
	beq	noFile		;hat nicht geklappt

;---File in Puffer einlesen
	move.l	d0,d1		;Header nach D1
	move.l	d6,d3		;Gesamtes File
	move.l	Puffer,d2	;in Puffer
	jsr	Read(a6)	;einlesen
	cmp.l	d6,d0		;Wirklich alle Bytes gelesen ?
	bne	noFile		;nein, Fehler

;---File schließen
	bsr	CloseFile

;---ASCII-Zeichen in Puffer2 einlesen
	move.l	Puffer,a5	;Von (A5) holen
	move.l	Puffer2,a4	;nach (A4) bringen
Drloop:	move.b	(a5)+,d0	;1 Byte holen
	cmp.b	#10,d0		;Linefeed ?
	bne.s	Gr126		;nein, weiter

	tst.b	Linefeeds	;Linefeeds ausgeben erlaubt ?
	beq.s	OK		;ja, weiter

Gr126:	cmp.b	#126,d0		;> 126 ?
	bpl.s	Nicht		;dann nicht drucken

	cmp.b	#32,d0		;< 32 ?
	bmi.s	Nicht		;dann nicht drucken

;---Byte in Ausgabepuffer eintragen
OK:	move.b	d0,(a4)+	;Byte in Puffer2 eintragen
Nicht:	subq.l	#1,d6		;D6 erniedrigen
	bne.s	DrLoop		;<> 0, dann nächstes Byte holen

;---Gewandeltes File ausdrucken
DasWars:
	move.b	#10,(a4)+	;Linefeed anhängen
	move.b	#13,(a4)	;Return anhängen
	sub.l	Puffer2,a4	;A4 - Anfang Puffer2 = Länge

;---PRT: öffnen
	move.l	#PRTname,d1	;PRT:
	move.l	#1006,d2	;Modus 'NEW'
	move.l	DosBase,a6	;
	jsr	Open(a6)	;öffnen
	move.l	d0,d7		;Header nach D7
	beq	noPRT		;hat nicht geklappt

;---Puffer2 auf Drucker ausgeben
	move.l	d0,d1		;Header nach D1
	move.l	a4,d3		;A4 Bytes
	move.l	Puffer2,d2	;Aus Puffer2
	jsr	Write(a6)	;drucken

;---PRT: schließen
	move.l	d7,d1		;Header nach D1
	jsr	Close(a6)	;PRT: schließen

;---Programm beenden
Ende:	move.l	GesLaenge,d0	;Länge Puffer nach D0
	beq.s	Ende2		;= 0 ?, dann NICHT freigeben

	move.l	Puffer,a1	;Puffer
	bsr	Freigeben	;freigeben

Ende2:	tst.l	FIB		;Gibt's 'n FileInfoBlock ?
	beq.s	Ende3		;nein, weiter

	move.l	FIB,a1		;FileInfoBlock
	move.l	#260,d0		;260 Bytes
	bsr	Freigeben	;freigeben

Ende3:	bsr	CloseFile	;File schließen (falls noch offen)

TUESS:	move.l	DosBase,a1	;Doslibrary
	move.l	ExecBase,a6
	jmp	CloseLibrary(a6);schließen und PRG beenden
;---------------
;FEHLERMELDUNGEN
;---------------
;---Kein Filename oder falscher Filename angegeben
noName:	lea	Text2(pc),a0

;---Text ab (A0) ausgeben und Programm beenden
TxtOut:	bsr	Text
	bra.s	Ende

;---Drucker nicht geöffnet
noPRT:	lea	Text3(pc),a0
	bra.s	TxtOut

;---File nicht gefunden
noFile:	lea	Text4(pc),a0
	bra.s	TxtOut

;---Nicht genug Speicher
noFree:	lea	Text5(pc),a0
	bra.s	TxtOut
;-----------------------------------
;UP - Text ausgeben, Adresse ab (A0)
;-----------------------------------
Text:	move.l	a0,a2		;Adresse in A2 merken
Kopie:	move.b	(a0)+,d3	;Bytes nach D3
	bne.s	Kopie		;kopieren bis Nullbyte

	tst.b	-(a0)		;zurück auf's Nullbyte
	sub.l	a2,a0		;Jetzige Adresse - Anfangsadresse
	move.l	a0,d3		;= Länge Text nach D3
	move.l	a2,d2		;Textpuffer ab D2
	move.l	Outhd,d1	;Text im CLI-Fenster
	move.l	DosBase,a6	;
	jmp	Write(a6)	;ausgeben und zurück
;------------------------------------
;UP - File schließen - falls geöffnet
;------------------------------------
CloseFile:
	move.l	Filehd,d1	;Fileheader vorhanden ?
	beq.s	CloRET		;nein, zurück, sonst

	move.l	DosBase,a6	;File
	jsr	Close(a6)	;schließen
	clr.l	Filehd		;Fileheader löschen
CloRET:	rts			;und zurück
;---------------------------------------
;UP - Speicher reservieren, Anzahl in D0
;---------------------------------------
Reservieren:
	move.l	#$10000,d1	;irgendwo im RAM
	move.l	ExecBase,a6
	jmp	AllocMem(a6)	;D0 Bytes reservieren
;----------------------------------------------------
;UP - Speicher freigeben, Anzahl in D0, Adresse in A1
;----------------------------------------------------
Freigeben:
	move.l	ExecBase,a6
	jmp	FreeMem(a6)
;----------------------------------------
DosBase:	dc.l	0	;Dosbasis
Outhd:		dc.l	0	;Ausgabekanal (CLI-Fenster)
FIB:		dc.l	0	;FileInfoBlock im RAM
Filename:	dc.l	0	;Filename
Filehd:		dc.l	0	;Fileheader
Puffer:		dc.l	0	;Puffer für Textfile
Puffer2:	dc.l	0	;Puffer für gewandeltes File
GesLaenge:	dc.l	0	;Gesamtlänge des Puffers

Linefeeds:	dc.b	0
Text1:		dc.b	10,$9b,"1mFAD"
		dc.b	$9b,"0m - FILE-ASCII-DRUCK - "
		dc.b	"© 1990 by EHJ",10,10,0
Text2:		dc.b	"Aufruf: FAD [-L] <Filename>",10,13
		dc.b	"        -L unterdrückt Linefeeds",10,10,0
Text3:		dc.b	"Kann Drucker nicht öffnen !",10,10,0
Text4:		dc.b	"Kann File nicht finden !",10,10,0
Text5:		dc.b	"Nicht genug Speicher !",10,10,0
DosName:	dc.b	"dos.library",0
PRTname:	dc.b	"PRT:",0
