*
* EPFix.asm: Copyright 1986 by Limited Reality, Inc.
*

	INCLUDE "exec/types.i"
	INCLUDE "libraries/dos.i"

XLIB	MACRO			;avoid _LVO on XREF's
	XREF	_LVO\1
	ENDM

SysCall	MACRO			;avoid typing _LVO every time
	jsr	_LVO\1(a6)
	ENDM

WriteFile MACRO ;File,String,Len
	move.l	\1,d1		;file to write
	move.l	\2,d2		;string to write
	move.l	\3,d3		;number of chars to write
	SysCall	Write		;write 'em
	ENDM

	XREF	_AbsExecBase	;base address for exec library
	XLIB	OpenLibrary	;exec: open a library
	XLIB	AllocMem	;      allocate memory block
	XLIB	FreeMem		;      free memory block

	XLIB	Lock		;DOS functions
	XLIB	UnLock
	XLIB	DupLock
	XLIB	CurrentDir
	XLIB	Examine
	XLIB	ExNext
	XLIB	Output
	XLIB	Open
	XLIB	Close
	XLIB	Read
	XLIB	Write
	XLIB	Exit

* StoredFile structure
EPLen	EQU	0		;size of the file in this block
EPFile	EQU	EPLen+4		;contents of the file start here

***************************** initialization ***************************

	movem.l	d0/a0,-(SP)
	move.l	#FSpec1,d0
	move.l	d0,FileSpec

**************************** open DOS library **************************

	move.l	_AbsExecBase,a6	;find exec library
	move.l	#DOS_Name,a1	;pass string containing name
	clr.l	d0		;expect any version
	SysCall	OpenLibrary
	move.l	d0,a6
	move.l	a6,DosLibrary
	beq	Abort2

*************************** find output device ***************************

	SysCall	Output		;get a file handle, already open
	move.l	d0,StdOut
	beq	Abort2

*************************** check command line ***************************

	movem.l	(SP)+,a0/d0
	cmpi.l	#1,d0
	beq	GoToIt

ScanArgs:
	cmpi.b	#' ',(a0)
	bne	OkSoFar
	addq.l	#1,a0
	subq.l	#1,d0
	beq	BadArgs
	bra	ScanArgs

OkSoFar:
	andi.b	#$5f,(a0)
	cmpi.b	#'J',(a0)
	bne	BadArgs
DoJX:
	move.l	#FSpec2,d0
	move.l	d0,FileSpec
	move.b	#1,d0
	move.b	d0,JXFlag

GoToIt:
	WriteFile StdOut,#IntroMsg1,#IM1Len
	move.l	#JXFlag,a3
	cmpi.b	#1,(a3)
	bne	GTI2
	WriteFile StdOut,#JX80,#JXLen
GTI2:
	WriteFile StdOut,#IntroMsg2,#IM2Len

************************ find DEVS:printers directory *******************
ChangeDir:
	move.l	#Path,d1
	move.l	#ACCESS_READ,d2
	SysCall	Lock		;try to find this device
	move.l	d0,DirLock
	beq	Abort2		;got it?
	SysCall	CurrentDir	;make it current
	move.l	d0,OldDir	;save old directory

*********************** get data about directory **************************

ExamineDir:
	move.l	DirLock,d1
	move.l	#DirItem,d2
	SysCall	Examine		;get data about dir
	tst.l	d0		;successful?
	beq	Abort		; no: quit
NextFile:
	move.l	DirLock,d1
	move.l	#DirItem,d2
	movea.l	DosLibrary,a6
	SysCall	ExNext		;get data about next entry
	tst.l	d0		;is there another?
	beq	NotFound	; no: quit
	tst.l	fib_DirEntryType+DirItem ;is dir?
   	bpl	NextFile	;can't use it

*********************** does it match the file spec **********************

	movea.l	#DirItem+fib_FileName,a0
	movea.l	FileSpec,a1
FMatchLoop:
	move.b	(a1),d0		;get char from FSpec
	cmp.b	(a0),d0		;match?
	bne	NextFile
CharMatch:
	tst.b	d0		;matched null terminators?
	beq	Match		; yes: success
NotFNEnd:
	addq.l	#1,a1
	addq.l	#1,a0
	bra	FMatchLoop
Match:

************* allocate space to hold file info and contents ************

* space needed:
*  4-- length of file
* ??-- contents of file: fib_Size
* total: length of file+4

	move.l	DirItem+fib_Size,d0 ;length of file
	addq.l	#4,d0		;+4
	clr.l	d1		;request any kind of RAM
	movea.l	_AbsExecBase,a6
	SysCall	AllocMem
	tst.l	d0		;successful?
	beq	NoMem		;  no:  quit

********************* load the file into RAM *************************

	move.l	d0,FilePTR	;save file pointer for later use
	move.l	d0,a1
	move.l	DirItem+fib_Size,(a1)+ ;store file size
	move.l	DirLock,d1
	movea.l	DosLibrary,a6
	SysCall	CurrentDir	;make it current
	move.l	#DirItem+fib_FileName,d1
	move.l	#MODE_OLDFILE,d2
	SysCall	Open		;Open the file
	move.l	d0,d1
	move.l	d0,FileHandle
	move.l	FilePTR,d2
	addq.l	#EPFile,d2
	move.l	DirItem+fib_Size,d3
	SysCall	Read		;Read it
	move.l	FileHandle,d1
	SysCall	Close		;be nice

******************************* patches *********************************

	movea.l	FilePTR,a4	;point to beginning of file
	addq.l	#EPFile,a4

	move.b	#72,117(a4)	;offset 117: (Same for both drivers)
				;  changed from 82 to 72 dpi for
				;  correct graphic renditions.

	move.l	#JXFlag,a3	;check to see if we are modifying
	cmpi.b	#1,(a3)		;  the JX-80 driver
	beq	ModJX		;  if so, do it right!

ModEp:				; (Mods for standard Epson)
	move.b	#3,2665(a4)	;offset 2665:
				;  changed from 02 to 03 to
				;  tell new number of data
				;  bytes to read to set
				;  correct line spacing.

	move.b	#65,3339(a4)	;offset 3339, 3340:
	move.b	#8,3340(a4)	;  changed from $31,0 to $41,8
				;  to set correct line spacing
				;  of 8/72" instead of 7/72"
	bra	EPFixDone

ModJX:				; (Mods for JX-80)
	move.b	#3,2893(a4)	;offset 2893:
				;  changed from 02 to 03 to
				;  tell new number of data
				;  bytes to read to set
				;  correct line spacing.

	move.b	#65,3945(a4)	;offset 3945, 3946:
	move.b	#8,3946(a4)	;  changed from $31,0 to $41,8
				;  to set correct line spacing
				;  of 8/72" instead of 7/72"

********************** clean up house and leave ************************

EPFixDone:
	bsr	SaveFile	;write out the file
	bsr	RestoreDir	;restore original directory
	move.l	DirLock,d1	;free lock structure
	SysCall	UnLock
	WriteFile StdOut,#Fini,#FLen ;tell 'em we're done
	bra	Abort2		;and end

********************* error handling routines **************************

BadArgs:			;bad command line arguments
	WriteFile StdOut,#BAMsg,#BALen
	bra	Abort2

NotFound:
	WriteFile StdOut,#NoFile,#NFLen
	bra	Abort1

NoMem:				;file too big to load
	movea.l	DosLibrary,a6
	WriteFile StdOut,#NoMemMSG,#NMMLen
	bra	Abort

WriteFailed:			;file is open
	move.l	FileHandle,d1
	SysCall	Close		;close the file

SaveAbort:
	WriteFile StdOut,#FailedMSG,#FailedLen

Abort:
	bsr	FreeRAM		;free all memory
Abort1:
	bsr	RestoreDir	;restore original current directory
	move.l	DirLock,d1
	SysCall	UnLock		;unlock source directory
Abort2:
	SysCall	Exit		;flee!

********************* subroutine to save the file **********************

SaveFile:
	movea.l	FileSpec,a3
	move.l	a3,d1
	move.l	#MODE_NEWFILE,d2
	SysCall	Open		;open it
	move.l	d0,FileHandle
	beq	SaveAbort

***************************** write the file ***************************

	movea.l	FilePTR,a0
	move.l	d0,d1		;file handle
	move.l	a0,d2
	addi.l	#EPFile,d2	;pointer to data
	move.l	EPLen(a0),d3	;file length
	SysCall	Write
	cmpi.l	#-1,d0		;error
	beq	WriteFailed
	move.l	FileHandle,d1
	SysCall	Close		;close the file
SaveDone:
	bsr	FreeRAM		;free memory used for file
	rts

************** restore original current directory **********************

RestoreDir:
	move.l	OldDir,d1
	movea.l	DosLibrary,a6
	SysCall	CurrentDir
	rts

************** give back all the allocated memory ***********************

FreeRAM:
	movea.l	FilePTR,a1
	move.l	(a1),d0		;length of file
	addi.l	#4,d0		;+4 = length of block
	movea.l	_AbsExecBase,a6
	SysCall	FreeMem		;free this block
	rts

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

	SECTION	data,DATA
DOS_Name:
	dc.b	'dos.library',0

IntroMsg1:
	dc.b	'Patching Epson'
IM1Len	EQU	*-IntroMsg1

JX80:
	dc.b	' JX-80'
JXLen	EQU	*-JX80

IntroMsg2:
	dc.b	' printer driver for proper operation...'
IM2Len	EQU	*-IntroMsg2

Fini:
	dc.b	'Done.',13,10
FLen	EQU	*-Fini

BAMsg:
	dc.b	'Bad Arguments!',13,10
BALen	EQU	*-BAMsg

NoFile:
	dc.b	'File NOT found!',13,10
NFLen	EQU	*-NoFile

NoMemMSG:
	dc.b	'Not enough RAM to load driver!',13,10
NMMLen	EQU	*-NoMemMSG

FailedMSG:
	dc.b	'Unable to write file!',13,10
FailedLen EQU	*-FailedMSG

Path:
	dc.b	'DEVS:printers',0	;directory name

FSpec1:
	dc.b	'epson',0		;file name

FSpec2:
	dc.b	'epson_jx-80',0		;alternate

JXFlag:
	dc.b	0

	SECTION mem,BSS

	CNOP	0,4	;long word align
DosLibrary:
	ds.l	1	;handle for DOS Library

FileSpec:
	ds.l	1	;pointer to filename
FilePTR:
	ds.l	1	;pointer to file
FileHandle:
	ds.l	1	;handle of driver file

DirLock:
	ds.l	1	;lock for directory being examined
OldDir:
	ds.l	1	; "    "  old directory
StdOut:
	ds.l	1	;handle for default output device

DirItem:
	ds.b	fib_SIZEOF

	END
