;Code020  	=	1		; Define for 020 code, comment for 000.

	IFND	Code020
	MACHINE	68000
	ENDC
	IFD	Code020
	MACHINE	68020
	ENDC

	XREF	StrNumCat
	XREF	StrCpy
	XREF	StrLFCat

	XDEF	NumToStr

; Last CodeError code used: 3

; During the translation loop:
; A0 = Pointer to source data
; A1 = Pointer to destination data
; A2 = Pointer to space buffer
; A3 = Pointer to translation table
; A4 = Pointer to the mode respective translation code.
; A5 = Data base pointer. [Not implemented yet]

; D0 = Current char
; D1 = Counter of bytes left in the source buffer.
; D2 = Counter of converted bytes in the destination buffer.
; D3 = Character read in Translation routine.

	INCDIR	"INCLUDE:"
	INCLUDE	"Darkness.I"
	INCLUDE	"Exec.Offsets"
	INCLUDE	"Dos.Offsets"
	INCLUDE "exec/types.i"
	INCLUDE	"exec/execbase.i"
	INCLUDE	"exec/memory.i"
	INCLUDE	"hardware/intbits.i"
	INCLUDE	"dos/dos.i"
	INCLUDE	"dos/dosasl.i"
	INCLUDE "libraries/ppbase.i"
	INCLUDE "libraries/powerpacker_lib.i"

	STRUCTURE	FileLink,0
	LONG	fl_Next
	LONG	fl_DirType		; Obsolete, should never be needed.
	LONG	fl_Size
	LONG	fl_DirLock
	STRUCT	fl_FileName,108
	LABEL	fl_SIZEOF

; Modes which want CRs must be negative.
MODE_TOPC	=	-1
MODE_TOSF7	=	-2

MODE_FROMPC	=	 1
MODE_FROMSF7	=	 2
MODE_TOUPCASE	=	 3
MODE_TOLOWCASE	=	 4
MODE_TONULL	=	 5
MODE_AUTOMODE	=	 6
MODE_TOASCII	=	 7
MODE_COMBINED	=	 8

SIZE_SRCBUF	=	20480
SIZE_DESTBUF	=	102400
SIZE_MAXNEW	=	9		; Maximum size change in one cycle.

CR		=	13
LF		=	10
TAB		=	 9

; A macro to call a library routine.

Call	MACRO
	move.l	_\1Base,a6
	jsr	_LVO\2(a6)
	ENDM

BToLong	MACRO
	IFD	Code020			; Convert TabSize
	extb.l	\1
	ENDC
	IFND	Code020
	ext.w	\1
	ext.l	\1
	ENDC
	ENDM

ProgStart:
	move.l	sp,OldStack
	clr.b	-1(a0,d0.w)
	move.l	a0,-(sp)
	add.l	d0,a0
	subq.l	#1,a0

	lea	_DosName,a1
	moveq	#36,d0
	Call	Exec,OpenLibrary
	move.l	d0,_DosBase
	beq	Err_NewerKickNeeded

	IFD	Code020
	move.l	_ExecBase,a6		; Tests if we have 68020.
	move.w	AttnFlags(a6),d0
	btst.w	#AFB_68020,d0
	beq	Err_OldProcessor
	ENDC

	move.l	_DosBase,a6
	jsr	_LVOOutput(a6)
	move.l	d0,OutStruct

	move.l	#Text_Header,d2
	bsr	PrintText

	lea	PPName,a1		; Open PP library if we have it.
	moveq	#0,d0
	Call	Exec,OpenLibrary
	move.l	d0,_PPBase

	move.l	4.w,a6			; Set up the interrupt.
	move.l	VBlankFrequency(a6),VBFreq

	moveq	#INTB_VERTB,d0		; Add the counter interrupt.
	lea	VertBInterrupt,a1
	move.l	_ExecBase,a6
	jsr	_LVOAddIntServer(a6)
	st	Flag_IntActive

	move.l	(a7)+,a0		; CommandStart
	tst.b	(a0)			; If blank commandline, instructions.
	beq.w	HelpText
	cmp.b	#"?",(a0)
	beq.w	HelpText

ParseStart:
	cmp.b	#"-",(a0)
	beq.b	CheckOption

Parse:
	cmp.b	#" ",1(a0)		; At least one space after option
	bne.w	Err_BadComLine
	cmp.b	#"p",(a0)
	beq.w	FromPCMode
	cmp.b	#"P",(a0)
	beq.w	ToPCMode
	cmp.b	#"c",(a0)
	beq.w	CombinedMode
	cmp.b	#"s",(a0)
	beq.w	FromSF7Mode
	cmp.b	#"S",(a0)
	beq.w	ToSF7Mode
	cmp.b	#"u",(a0)
	beq.w	ToUpCaseMode
	cmp.b	#"l",(a0)
	beq.w	ToLowCaseMode
	cmp.b	#"a",(a0)
	beq.w	AutoMode
	cmp.b	#"n",(a0)
	beq.w	ModeToNull
	cmp.b	#"o",(a0)
	beq.w	ModeToOnlyASCII
	bra.w	Err_BadComLine

CheckOption:
	cmp.b	#"e",1(a0)
	beq.w	Opt_MakeEOLs
	cmp.b	#"n",1(a0)
	beq.b	Opt_NoCutSpace
	cmp.b	#"?",1(a0)
	beq.w	Credits
	cmp.b	#"t",1(a0)
	beq.b	Opt_TabConv
	cmp.b	#"s",1(a0)
	beq.b	Opt_SpaceConv
	cmp.b	#"q",1(a0)
	beq.w	Opt_QuietMode
	cmp.b	#"b",1(a0)
	beq.w	Opt_NoBufferMode
	bra.w	Err_BadComLine

Opt_NoCutSpace:
	tst.b	Size_MakeEOLs
	bne.w	Err_BadLogic
	move.b	#1,Mode_NoCutSpace
	addq.l	#2,a0
	bra.w	Opt_Next

Opt_TabConv:
	tst.b	TabSize
	bne.w	Err_BadLogic
	move.b	2(a0),d0		; Get the number.
	cmp.b	#" ",d0
	beq.b	Opt_TabConv1
	sub.b	#"0",d0			; Check that it really is a number.
	cmp.b	#9,d0
	bhi	Err_BadComLine
	cmp.b	#1,d0
	bcs	Err_BadComLine
	bra.b	Opt_BothConv

Opt_TabConv1:
	move.b	#8,d0
	subq.l	#1,a0
	bra.b	Opt_BothConv

Opt_SpaceConv:
	tst.b	TabSize
	bne.w	Err_BadLogic
	tst.b	Size_MakeEOLs
	bne.w	Err_BadLogic
	move.b	2(a0),d0
	cmp.b	#" ",d0
	beq.b	Opt_SpaceConv1
	sub.b	#"0",d0
	cmp.b	#9,d0
	bhi	Err_BadComLine
	cmp.b	#2,d0			; No sense in converting to one tab
	bcs	Err_BadComLine		; so 2 is the lower limit.
	move.b	d0,SpaceSize
	bra.b	Opt_BothConv

Opt_SpaceConv1:
	move.b	#8,d0
	move.b	d0,SpaceSize
	subq.l	#1,a0

Opt_BothConv:
	move.b	d0,TabSize
	addq.l	#3,a0
	bra.b	Opt_Next

Opt_QuietMode:
	move.b	#1,Mode_Quiet
	addq.l	#2,a0
	bra.b	Opt_Next

Opt_MakeEOLs:
	tst.b	SpaceSize
	bne.w	Err_BadLogic
	move.b	2(a0),d0
	cmp.b	#" ",d0
	beq.w	Err_BadComLine
	sub.b	#"0",d0
	cmp.b	#9,d0
	bhi	Err_BadComLine
	cmp.b	#1,d0
	bcs	Err_BadComLine
	move.b	3(a0),d1
	cmp.b	#" ",d1
	beq.b	Opt_MakeEOLs1
	sub.b	#"0",d1
	cmp.b	#9,d1
	bhi	Err_BadComLine
	cmp.b	#0,d1
	bcs	Err_BadComLine
	ext.w	d0
	mulu	#10,d0
	add.b	d1,d0
	move.b	d0,Size_MakeEOLs
	addq.l	#4,a0
	bra.b	Opt_Next

Opt_MakeEOLs1:
	move.b	d0,Size_MakeEOLs
	addq.l	#3,a0
	bra.b	Opt_Next

Opt_NoBufferMode:
	move.b	#1,Mode_NoBuffer
	addq.l	#2,a0

Opt_Next:
	cmp.b	#" ",(a0)
	bne.w	Err_BadComLine
	bsr	SkipSpace
	cmp.l	#0,a0
	beq.w	Err_BadComLine
	bra.w	ParseStart

FromPCMode:
	move.b	#MODE_FROMPC,Mode
	move.l	#Table_FromPC,Table
	bra.w	NameParse

FromSF7Mode:
	move.b	#MODE_FROMSF7,Mode
	move.l	#Table_FromSF7,Table
	bra.w	NameParse

ToSF7Mode:
	move.b	#MODE_TOSF7,Mode
	move.l	#Table_ToSF7,Table
	bra.w	NameParse

CombinedMode:
	move.b	#MODE_COMBINED,Mode
	move.l	#Table_Combined,Table
	bra.w	NameParse

ToPCMode:
	move.b	#MODE_TOPC,Mode
	move.l	#Table_ToPC,Table
	bra.w	NameParse

ToUpCaseMode:
	move.b	#MODE_TOUPCASE,Mode
	move.l	#Table_Uppercase,Table
	bra.b	NameParse

ToLowCaseMode:
	move.b	#MODE_TOLOWCASE,Mode
	move.l	#Table_Lowercase,Table
	bra.b	NameParse

AutoMode:
	tst.b	Mode_NoBuffer		; Mode_NoBuffer=0? means we have buffer
	bne.w	Err_NeedBuffer		; if not
	move.b	#MODE_AUTOMODE,Mode
	bra.b	NameParse

ModeToNull:
	move.b	#MODE_TONULL,Mode
	move.l	#Table_Null,Table
	bra.b	NameParse

ModeToOnlyASCII:
	move.b	#MODE_TOASCII,Mode
	move.l	#Table_Null,Table

NameParse:
	addq.l	#1,a0			; One after Mode
	bsr	SkipSpace
	cmp.l	#0,a0
	beq.w	Err_BadComLine
	move.l	a0,SourceNameStart
	bsr	FindEnd
	move.l	a0,SourceNameEnd	; Save source name end.
	addq.l	#1,a0			; Find the length for source name.
	sub.l	SourceNameStart,a0
	move.l	a0,SourceNameLen

	move.l	SourceNameStart,a0	; Copy the name to SourceName
	move.l	#SourceName,a1
	move.l	SourceNameLen,d0
	bsr	CopyName

StartNewFile:
	lea	SourceName,a0
	bsr	FormFileLinks
	move.l	FileLinkBase,CurrentLink
	move.l	CurrentLink,d0
	lea	PrintBuf,a0
	bsr	StrNumCat
	bsr	WritePrintBuf
	beq	LinkEnd

ContNewFile:
	move.l	CurrentLink,a0		; Get the next FileLink.
	move.l	(a0,fl_Next),a0
	move.l	a0,CurrentLink
	beq	LinkEnd

	move.l	(fl_Size,a0),SourceLen
	lea	(fl_FileName,a0),a1
	move.l	#RealSourceName,a0
	bsr	StrCpy

	move.l	SourceNameEnd,a0
	addq.l	#1,a0
	tst.b	(a0)
	beq.w	NoDest
	bsr	SkipSpace
	move.l	a0,DestNameStart	; If 0, go NoDest
	beq.w	NoDest
	bsr	FindEnd
	addq.l	#1,a0			; Add 1 to DestName end, and get
	sub.l	DestNameStart,a0	; DestNameLen in a0
	move.l	a0,d0
	move.l	d0,DestNameLen
	move.l	DestNameStart,a0	; Copy the destination name to DestName.
	lea	DestName,a1
	bsr	CopyName

	move.l	#DestName,d1		; Try to lock dest filename.
	move.l	#ACCESS_READ,d2
	Call	Dos,Lock
	move.l	d0,DestLock
	beq.w	DestNameCheck		; If no lock, we'll have a file.

	move.l	DestLock,d1		; Otherwise check it
	move.l	#FIB,d2
	Call	Dos,Examine
	move.l	d0,-(sp)		; Save result code
	move.l	DestLock,d1
	Call	Dos,UnLock
	clr.l	DestLock
	move.l	(sp)+,d0		; Boolean
	beq.w	Err_DestCorrupt		; 0 means error
	lea	FIB,a0
	tst.l	fib_DirEntryType(a0)	; Dir or a file?
	bgt	DestIsDir		; > 0 means directory.

DestNameCheck:
	lea	MyAnchor,a0
	btst.b	#APB_ITSWILD,(a0,ap_Flags)
	bne	Err_FileDest
	bra 	OpenFiles

LinkEnd:
	tst.b	Flag_FileFound
	beq	Err_NoSource
	bra	EndProgram

DestIsDir:
	move.l	#DestName,d1
	move.l	#RealSourceName,d2
	move.l	#256,d3
	Call	Dos,AddPart
	moveq	#3,d7
	tst.l	d0
	beq	CodeError
	bra.b	OpenFiles

NoDest:
	lea	RealSourceName,a0	; If no destination name, use the
	lea	DestName,a1		; sourcename (i.e. writing on the
	bsr	CopyUntilNull		; original).
	subq.l	#1,a1

	tst.b	Mode_NoBuffer		; If we have a buffer, add no suffix.
	beq.w	ProtectSrc

	cmp.b	#MODE_TOPC,Mode		; Add the right type of suffix.
	beq.b	PCSuffix
	cmp.b	#MODE_TOSF7,Mode
	beq.b	SF7Suffix

AmigaSuffix:
	lea	Text_AmigaSuf,a0
	bra.b	AddSuffix

PCSuffix:
	lea	Text_PCSuf,a0
	bra.b	AddSuffix

SF7Suffix:
	lea	Text_SF7Suf,a0

AddSuffix:
	move.b	(a0)+,(a1)+
	bne	AddSuffix

OpenFiles:
	clr.b	(a1)			; Add the terminating null.

	tst.b	Mode_NoBuffer		; We have a buffer, go to OpenFiles1.
	beq.w	OpenFiles1

	bsr	OpenCheckPP
	bra	OpenFiles3

; Open file MyAnchor.ap_Last and check if it's PowerPacked.
; If we have PP library, decrunch the file.
; If not, show error.

OpenCheckPP:
	move.l	CurrentLink,a0
	move.l	(fl_DirLock,a0),d1
	Call	Dos,CurrentDir
	move.l	d0,OldDirLock

	bsr	ClearPrintBuf		; Start a new buffer.
	move.l	#Text_ConvFile1,a0
	bsr	AddPrintBuf
	move.l	#MyAnchor+ap_Info+fib_FileName,a0
	bsr	AddPrintBuf
	move.l	#Text_ConvFile2,a0
	bsr	AddPrintBuf
	bsr	WritePrintBuf

	move.l	#MyAnchor+ap_Info+fib_FileName,d1
	move.l	#MODE_OLDFILE,d2
	Call	Dos,Open
	moveq	#1,d7			; Unlikely error -code.
	move.l	d0,SourceHandle
	beq.w	CodeError

	move.l	SourceHandle,d1		; Read 4 bytes.
	move.l	#SourceBuf,d2
	move.l	#4,d3
	Call	Dos,Read
	cmp.l	#4,d0			; Did we read 4 bytes?
	bne	.SeekBack		; No, just seek back.
	move.l	SourceBuf,d0		; Get a long from the buffer, and check
	cmp.l	#"PP20",d0		; if it is a PowerPacker datafile.
	beq.w	.PackedData
	cmp.l	#"PX20",d0		; if it is a PowerPacker datafile.
	beq.w	.PackedData

.SeekBack:
	move.l	SourceHandle,d1		; Seek back to the
	moveq	#0,d2			; beginning of the file.
	moveq	#OFFSET_BEGINNING,d3
	Call	Dos,Seek
	bsr	MakeSourceASCII
	rts

.PackedData:
	move.l	SourceHandle,d1
	Call	Dos,Close
	clr.l	SourceHandle

	move.l	_PPBase,a6
	IFD	Code020
	tst.l	a6
	ENDC
	IFND	Code020
	cmp.l	#0,a6
	ENDC
	beq	Err_PowerPacked
	tst.b	Mode_NoBuffer
	bne	Err_NeedBufPP

	move.l	#Text_Decrunching,d2
	bsr	PrintText

	st	Flag_PPUsed
	lea	MyAnchor+ap_Info+fib_FileName,a0
	moveq	#DECR_NONE,d0
	moveq	#0,d1			; Memory type.
	lea	SourcePointer,a1
	lea	SourceLen,a2
	move.l	#0,a3			; Use default PW function.
	Call	PP,ppLoadData	
	tst.l	d0
	bne	.PackedError		; If error.
	bsr	MakeSourceASCII
	rts

.PackedError:
	cmp.l	#PP_OPENERR,d0		; Should never happen, since we did
	beq	Err_SourceCorrupt	; check that it was a PP file.
	cmp.l	#PP_READERR,d0
	beq	Err_SourceCorrupt
	cmp.l	#PP_NOMEMORY,d0
	beq	Err_NoMem
	cmp.l	#PP_PASSERR,d0
	beq	Err_PassError
	cmp.l	#PP_EMPTYFILE,d0
	beq	Err_SourceCorrupt
	cmp.l	#PP_UNKNOWNPP,d0
	beq	Err_UnknownPP
	moveq	#2,d7
	bra	CodeError

OpenFiles3:
	bsr	OpenDest
	bra.w	ReadBlock

ProtectSrc:
	move.b	#1,Mode_SrcDeleted

OpenFiles1:
	bsr	OpenCheckPP

	tst.b	Flag_PPUsed
	beq	OpenFilesNoPP
	move.l	SourceLen,ReadBytes
	bra	ReadFinished

OpenFilesNoPP:
	move.l	SourceLen,d0		; Allocate for the whole source file.
	moveq	#0,d1			; No special needs for the memory.
	Call	Exec,AllocMem
	move.l	d0,SourcePointer
	beq.w	Err_NoMem

ReadFile:
	move.l	SourceHandle,d1
	move.l	SourcePointer,d2	; To our file buffer.
	add.l	ReadBytes,d2
	move.l	RBlockSize,d3
	clr.w	TickCount
	Call	Dos,Read
	cmp.l	#-1,d0
	beq.w	Err_ReadFail		; If error reading the file.
	add.l	d0,ReadBytes
	move.l	d0,-(sp)		; Save "bytes read".

	bsr	CalcReadRate		; Determine the optimal block size.

	tst.b	Mode_Quiet		; Check if we should be quiet.
	bne.b	TestRead		; If so, go to TestRead.

	bsr	ClearPrintBuf		; Start a new buffer.

	move.l	#Text_Read,a0		; Print our progress to Shell.
	bsr	AddPrintBuf

	lea	ReadASCII,a0		; First convert the number into a
	move.l	ReadBytes,d0		; string, and then add the string into
	bsr	NumToStr		; the buffer.
	move.l	a0,ReadASCIIAddr
	move.l	d0,ReadASCIILen

	bsr	AddPrintBuf

	move.l	#Text_Slash,a0
	bsr	AddPrintBuf

	move.l	SourceLenASCIIAddr,a0	; The size of the source file.
	bsr	AddPrintBuf

	move.l	#Text_CR,a0		; And back to the beginning of the line.
	bsr	AddPrintBuf
	bsr	WritePrintBuf

TestRead:
	move.l	(a7)+,d0		; How many bytes we read, if null, we're
	beq.b	ReadFinished		; finished.

	moveq	#0,d0			; Get the signals.
	moveq	#0,d1
	move.l	_ExecBase,a6
	jsr	_LVOSetSignal(a6)

	btst	#SIGBREAKB_CTRL_C,d0	; Check if ^C was pressed.
	bne.w	BreakPressed

	bra.w	ReadFile		; Read more of the file.

ReadFinished:
	move.l	ReadBytes,LeftBytes
	tst.b	Flag_PPUsed
	bne	ReadFinished2

	move.l	SourceHandle,d1		; Close the source, since we're done.
	Call	Dos,Close
	clr.l	SourceHandle		; Note that it's closed.

ReadFinished2:
	cmp.b	#MODE_AUTOMODE,Mode	; AutoMode on?
	beq.b	DetectMode		; Determine the real mode to use.

ReadFinished1:
	bsr	OpenDest
	bra.w	MoreData

DetectMode:
	move.l	#Text_Checking,d2	; Tell that we're checking the mode.
	bsr	PrintText

	moveq	#0,d2
	moveq	#0,d3
	moveq	#0,d4
	move.l	SourcePointer,a0
	cmp.l	#10240,LeftBytes	; Less data to determine with, otherwise
	bcs	DetectMode1		; use 10KB.
	move.l	#10240-1,d1

DetectMode2:
	move.b	(a0)+,d0		; Get a byte.
	cmp.b	#"{",d0			; Signs of possible SF7.
	beq.w	DM_SF7
	cmp.b	#"[",d0
	beq.w	DM_SF7
	cmp.b	#"|",d0
	beq.w	DM_SF7
	cmp.b	#"\\",d0
	beq.w	DM_SF7

	cmp.b	#"ä",d0			; Signs of possible Amiga format.
	beq.w	DM_Amy
	cmp.b	#"Ä",d0
	beq.w	DM_Amy
	cmp.b	#"ö",d0
	beq.w	DM_Amy
	cmp.b	#"Ö",d0
	beq.w	DM_Amy

	cmp.b	#$84,d0			; Signs of possible PC format.
	beq.w	DM_PC
	cmp.b	#$8e,d0
	beq.w	DM_PC
	cmp.b	#$94,d0
	beq.w	DM_PC
	cmp.b	#$99,d0
	beq.w	DM_PC

	cmp.b	#CR,d0			; CR, can't be an Amiga format.
	beq.w	DM_Foreign

DetectMode3:
	dbf	d1,DetectMode2		; If bytes left to check, do so.

	cmp.l	d2,d3			; xx0
	beq.w	SameWarn1
	cmp.l	d2,d4			; x0x
	beq.w	SameWarn1
	cmp.l	d3,d4			; 0xx
	beq.w	SameWarn2

DetectMode4:
	movem.l	d2-d4,-(a7)
	move.l	#Text_Uses,d2		; Tell what mode it uses.
	bsr	PrintText
	movem.l	(a7)+,d2-d4

	cmp.l	d2,d3			; SF7 or Amy
	bhi	DM_NotSF7

DM_NotAmy:
	cmp.l	d2,d4			; SF7 or PC
	bhi	DM_MakePC
	bra.b	DM_MakeSF7

DM_NotSF7:
	cmp.l	d3,d4			; Amy or PC
	bhi	DM_MakePC

DM_MakeAmy:
	move.b	#MODE_TONULL,Mode	; Amiga file, use Null mode.
	move.l	#Table_Null,Table

	move.l	#Text_NullMode,d2	; Tell the user that.
	bsr	PrintText

	bra.w	ReadFinished1

DM_MakePC:
	move.b	#MODE_FROMPC,Mode	; PC file, use FromPC mode.
	move.l	#Table_FromPC,Table

	move.l	#Text_PCMode,d2		; And tell that.
	bsr	PrintText

	bra.w	ReadFinished1

DM_MakeSF7:
	move.b	#MODE_FROMSF7,Mode	; SF7 file, use FromSF7 mode.
	move.l	#Table_FromSF7,Table
	move.l	#Text_SF7Mode,d2	; Tell it.
	bsr	PrintText
	bra.w	ReadFinished1

SameWarn1:
	cmp.l	d3,d4			; Could be either one.
	beq.w	Err_SameProbability
	bra.w	DetectMode4

SameWarn2:				; Same as above.
	cmp.l	d2,d3
	beq.w	Err_SameProbability
	bra.w	DetectMode4

DetectMode1:				; Since we don't have 10KB for
	move.l	LeftBytes,d1		; comparing, take all we can get.
	subq.l	#1,d1
	bra.w	DetectMode2

DM_SF7:
	addq.l	#1,d2			; One point to SF7.
	bra.w	DetectMode3

DM_Amy:
	addq.l	#1,d3			; One to Amiga.
	bra.w	DetectMode3

DM_PC:
	addq.l	#1,d4			; etc...
	bra.w	DetectMode3

DM_Foreign:
	addq.l	#1,d2			; One point to SF7 and PC.
	addq.l	#1,d4
	bra.w	DetectMode3

ReadBlock:
	tst.b	Mode_NoBuffer
	beq.b	MoreData		; We have a buffer -> MoreData
	movem.l	d0/d2-d7/a0-a6,-(sp)
	move.l	SourceHandle,d1		; Otherwise read.
	move.l	SourcePointer,d2
	move.l	#SIZE_SRCBUF,d3
	move.l	_DosBase,a6
	jsr	_LVORead(a6)
	cmp.l	#-1,d0
	beq.w	Err_ReadFail		; Couldn't read?  -> Err_ReadFail.
	add.l	d0,ReadBytes
	add.l	d0,InputBytes
	move.l	d0,d1
	beq.b	RB_CloseFiles		; !ReadBytes -> Quit.
	movem.l	(sp)+,d0/d2-d7/a0-a6
	subq.l	#1,d1			; Counter always one less than loops.
	lea	SourceBuf,a0		; Buffer locations to regs.
	bra.w	CheckOutBuf		; Continue converting.

RB_CloseFiles:				; Same as CloseFiles, but pops
	movem.l	(sp)+,d0/d2-d7/a0-a6	; the regs after ReadBlock messing with
	bra.w	CloseFiles		; them.

MoreData:
	tst.l	LeftBytes		; We have no more bytes left?
	beq.w	CloseFiles		; -> Quit.
	move.l	LeftBytes,d1
	clr.l	LeftBytes
	move.l	SourcePointer,a0
	add.l	InputBytes,a0
	add.l	d1,InputBytes
	subq.l	#1,d1			; Loop counter starts from 0, i.e. -1.
	bra.w	CheckOutBuf

MoreCharacters:
	move.b	(a0)+,d0		; Get a new byte from the buffer.
	and.w	#$ff,d0			; a3 contains the table base-address.
	move.b	(a3,d0.w),d0		; Replace the original character.
	beq.b	NoChar			; $00 = Drop this byte.

	cmp.b	#" ",d0			; Process white.
	beq	FoundSpace
	bhi	FoundBlack
	cmp.b	#TAB,d0
	beq	FoundTab
	cmp.b	#LF,d0
	beq	FoundLF
	bra	FoundBlack

FoundSpace:
	tst.b	TabSize			; Test for Tab-Space conversion.
	beq	.NoSpaceTab
	addq.l	#1,SpaceNumber
	addq.w	#1,Col
	tst.b	SpaceSize
	bne	.SpaceConv
	bra	NoChar

.SpaceConv:
	bsr	SpaceConv
	bra	NoChar

.NoSpaceTab:
	bsr	BufChar
	bra	NoChar

FoundTab:
	tst.b	TabSize			; Test for Tab-Space conversion.
	beq	.NoSpaceTab
	bsr	TabConv
	tst.b	SpaceSize
	bne	.SpaceConv
	bra	NoChar

.SpaceConv:
	bsr	SpaceConv
	bra	NoChar

.NoSpaceTab:
	bsr	BufChar
	bra	NoChar

FoundLF:
	clr.w	Col
	tst.b	Mode_NoCutSpace
	bne.b	.NoEndSpaceRem
	addq.l	#1,EOLs
	bsr	ResetArea
	bra	NoChar

.NoEndSpaceRem:
	bsr	FlushArea
	bsr	InsertOneEOL	
	bra	NoChar

FoundBlack:
	bsr	InsertEOLs
	move.b	Size_MakeEOLs,d3
	beq	.NoMakeEOLs
	BToLong	d3
	cmp.l	SpaceNumber,d3
	bhi	.NoMakeEOLs
	bsr	ResetArea
	bsr	InsertSingleEOL
	addq.l	#1,d2
	bra	InsertInDest

.NoMakeEOLs:
	bsr	FlushArea	
	bra	InsertInDest

InsertInDest:
	move.b	d0,(a1)+		; Store the translated byte in the buf.
	addq.l	#1,d2			; Add the bytes to be saved.
	addq.w	#1,Col			; And add the column counter.

NoChar:
	subq.l	#1,d1			; One less byte in the sourcebuffer.
	bmi	ReadBlock		; Went negative, load more.

CheckOutBuf:				; Have we converted a full buffer yet?
	tst.b	Flag_StatsDue
	bne.b	.DoStats

.ContCheckOutBuf:
	cmp.l	#SIZE_DESTBUF-SIZE_MAXNEW,d2
	bcs	MoreCharacters		; Everything okay, continue conversion.
	bra	WriteDestBuf

.DoStats:
	bsr	PrintStats
	bra	.ContCheckOutBuf

WriteDestBuf:
	movem.l	d1/d3-d7/a0/a2-a5,-(sp)
	move.l	DestHandle,d1		; Write the converted data.
	move.l	d2,d3			; Number of bytes to write.
	add.l	d2,WrittenBytes		; Add the buffer to WrittenBytes.
	move.l	#DestBuf,d2
	move.l	_DosBase,a6
	jsr	_LVOWrite(a6)
	cmp.l	#-1,d0
	beq.w	Err_WriteFail
	tst.b	Mode_SrcDeleted		; If the sourcefile has been destroyed,
	bne.b	.NoBreak		; don't allow breaking.
	moveq	#0,d0			; Get the signals.
	moveq	#0,d1
	move.l	_ExecBase,a6
	jsr	_LVOSetSignal(a6)
	btst	#SIGBREAKB_CTRL_C,d0	; Check if ^C was pressed
	bne.w	BreakPressed

.NoBreak:
	movem.l	(sp)+,d1/d3-d7/a0/a2-a5
	moveq	#0,d2			; No converted bytes now.
	lea	DestBuf,a1
	bra.w	MoreCharacters

CloseFiles:
	tst.l	EOLs
	beq	.NoEOLsLeft
	addq.l	#1,d2
	bsr	InsertSingleEOL
	tst.b	Mode			; If ToPC or ToSF7, add a CR too.
	bpl	.NoEOLsLeft
	addq.l	#1,d2

.NoEOLsLeft:
	move.l	d2,d3			; Do we have stuff in DestBuf?
	beq.b	CF_TellData		; No, show the final stats.
	move.l	DestHandle,d1		; We do, flush it.
	add.l	d2,WrittenBytes		; Add the buffer to WrittenBytes.
	move.l	#DestBuf,d2
	Call	Dos,Write
	cmp.l	#-1,d0
	beq.w	Err_WriteFail

CF_TellData:
	bsr	ClearPrintBuf		; Tell the file size change.
	move.l	#Text_Final,a0
	bsr	AddPrintBuf

	move.l	WrittenBytes,d0

	sub.l	ReadBytes,d0
	bmi	CloseFiles1		; Negative

	move.l	d0,d7
	beq.b	CloseFiles2		; If zero, no sign.

	move.l	#Text_PosSign,a0
	bsr	AddPrintBuf


	bra.b	CloseFiles2

CloseFiles1:
	neg.l	d0
	move.l	#Text_NegSign,a0
	bsr	AddPrintBuf

CloseFiles2:
	lea	NumberBuf,a0
	bsr	NumToStr
	bsr	AddPrintBuf

	move.l	#Text_DoubleSpace,a0
	bsr	AddPrintBuf

	move.l	WrittenBytes,d0
	move.l	ReadBytes,d1
	bsr	Percentage

	lea	NumberBuf,a0
	bsr	NumToStr

	bsr	AddPrintBuf

	move.l	#Text_PercentSign,a0
	bsr	AddPrintBuf

	move.l	#Text_LF,a0
	bsr	AddPrintBuf
	move.l	#Text_LF,a0
	bsr	AddPrintBuf
	bsr	WritePrintBuf
	bra.w	EndProgram

HelpText:
	move.l	#Text_HelpText,d2
	bsr	PrintText
	bra.w	EndProgram

Credits:
	move.l	#Text_Credits,d2
	bsr	PrintText
	bra.w	EndProgram

CodeError:
	move.l	d7,-(sp)
	move.l	#Text_CodeError,d2
	bsr	PrintText
	lea	NumberBuf,a0
	move.l	(sp)+,d0
	bsr	NumToStr
	move.l	a0,d2
	move.l	d0,d3
	bsr	PrintTextLen
	move.l	#Text_LF,d2
	bsr	PrintText
	bra.w	EndProgram

Err_NeedBufPP:
	move.l	#Text_NeedBufPP,d2
	bra	ShowErr

Err_UnknownPP:
	move.l	#Text_UnknownPP,d2
	bra	ShowErr

Err_PassError:
	move.l	#Text_WrongPass,d2
	bra	ShowErr

Err_FileDest:
	move.l	#Text_FileDest,d2
	bra	ShowErr

	IFD	Code020

Err_OldProcessor:
	move.l	#Text_OldProcessor,d2
	bra	ShowErr

	ENDC

Err_NewerKickNeeded:
	move.l	#Text_NewKickNeed,d2
	bra	ShowErr

Err_NoSource:
	move.l	#Text_NoSource,d2
	bra.b	ShowErr

Err_BadComLine:
	move.l	#Text_BadComLine,d2
	bra.b	ShowErr

Err_NoDest:
	move.l	#Text_NoDest,d2
	bra.b	ShowErr

Err_NoComLineSpace:
	move.l	#Text_NoComLineSpace,d2
	bra.b	ShowErr

Err_BadLogic:
	move.l	#Text_BadLogic,d2
	bra.b	ShowErr

Err_NoMem:
	move.l	#Text_NoMemory,d2
	bra.b	ShowErr

Err_PowerPacked:
	move.l	#Text_PowerPacked,d2
	bra.b	ShowErr

Err_SeekFail:
Err_ReadFail:
Err_SourceCorrupt:
	move.l	#Text_BadSource,d2
	bra.b	ShowErr

Err_DestCorrupt:
	move.l	#Text_BadDest,d2
	bra.b	ShowErr

Err_SourceIsDir:
	move.l	#Text_SourceIsDir,d2
	bra.b	ShowErr

Err_WriteFail:
	move.l	#Text_WriteFail,d2
	bra.b	ShowErr

Err_NeedBuffer:
	move.l	#Text_NeedBuffer,d2
	bra.b	ShowErr

Err_SameProbability:
	move.l	#Text_SameProbability,d2
	bra.b	ShowErr

BreakPressed:
	st	Flag_Stop
	move.l	#Text_Break,d2
	bsr	PrintText
	bra.b	EndProgramErr

ShowErr:
	move.l	d2,-(sp)
	bsr	ClearPrintBuf
	lea	Text_Error,a0
	bsr	AddPrintBuf
	move.l	(sp)+,a0
	bsr	AddPrintBuf
	lea	Text_ClearEOL,a0
	bsr	AddPrintBuf
	lea	Text_LF,a0
	bsr	AddPrintBuf
	bsr	WritePrintBuf
	bra.b	EndProgramErr

EndProgram:
	clr.b	Mode_DeleteErrDest
	bra	EndProgramNoErr

EndProgramErr:
	st	Flag_Stop

EndProgramNoErr:
	move.l	_DosBase,a6
	move.l	SourceHandle,d1
	beq.b	EndProgram1
	jsr	_LVOClose(a6)
	clr.l	SourceHandle

EndProgram1:
	move.l	DestHandle,d1
	beq.b	EndProgram2
	jsr	_LVOClose(a6)
	clr.l	DestHandle

EndProgram2:
	move.l	SourceLock,d1
	beq.b	EndProgram3
	jsr	_LVOUnLock(a6)
	clr.l	SourceLock

EndProgram3:
	move.l	DestLock,d1
	beq.b	EndProgram4
	jsr	_LVOUnLock(a6)
	clr.l	DestLock

EndProgram4:
	tst.b	Mode_DeleteErrDest
	beq.b	EndProgram5
	move.l	#DestName,d1
	jsr	_LVODeleteFile(a6)	; *!* Error detection here

EndProgram5:
	move.l	_ExecBase,a6
	cmp.l	#SourceBuf,SourcePointer
	beq.b	EndProgram6
	move.l	SourcePointer,a1
	move.l	SourceLen,d0
	jsr	_LVOFreeMem(a6)
	clr.l	SourcePointer

EndProgram6:
	move.l	OldDirLock,d1
	beq	EndProgram7
	Call	Dos,CurrentDir
	clr.l	OldDirLock

EndProgram7:
	tst.b	Flag_Stop
	bne	EndProgram8
	bsr	ClearVars
	bra	StartNewFile

EndProgram8:
	tst.b	Flag_AnchorUsed
	beq	EndProgram9
	move.l	#MyAnchor,d1
	Call	Dos,MatchEnd

EndProgram9:
	move.l	_PPBase,a1
	IFD	Code020
	tst.l	a1
	ENDC
	IFND	Code020
	cmp.l	#0,a1
	ENDC
	beq	EndProgram10
	Call	Exec,CloseLibrary

EndProgram10:
	tst.b	Flag_IntActive
	beq.b	EndProgram11
	moveq	#INTB_VERTB,d0		; Remove the counter interrupt.
	lea	VertBInterrupt,a1
	Call	Exec,RemIntServer

EndProgram11:
	move.l	FileLinkBase,a2
	beq	EndProgram12

.LinkLeft:
	move.l	(a2,fl_Next),a2		; Get the link after this one.
	move.l	a2,a1
	move.l	#fl_SIZEOF,d0
	Call	Exec,FreeMem
	cmp.l	#0,a2
	bne	.LinkLeft

EndProgram12:
	move.l	#Text_CursorOn,d2
	bsr	PrintText
	move.l	_DosBase,a1
	Call	Exec,CloseLibrary
	moveq	#0,d0			; *!* Add some error codes.
	move.l	OldStack,sp		; At least it's ok this way...
	rts

*********************
** VERTB INTERRUPT **
*********************

VertBIntCode:
	addq.b	#1,(a1)			; Add the frame counter.
	addq.w	#1,4(a1)		; Add the tick counter.
	move.b	1(a1),d0		; Get VBlank frequency.
	cmp.b	(a1),d0			; One second passed?
	bcs	.StuffDue
	moveq	#0,d0
	rts

.StuffDue:
	clr.b	(a1)			; Reset counter.
	st	2(a1)			; Set statistics due flag.
	moveq	#0,d0
	rts

**********
** SUBS **
**********

; A0 - Ptr to pattern.

FormFileLinks:
	move.l	a0,d1
	move.l	#MyAnchor,d2
	pea	FileLinkBase
	Call	Dos,MatchFirst
	st	Flag_AnchorUsed
	tst.l	d0
	bne	.NoMatch

.GetNextFile:
	move.w	#$0f0,$dff180
	move.l	#fl_SIZEOF,d0		; Allocate a new FileLink.
	moveq	#MEMF_CLEAR,d1
	Call	Exec,AllocMem
	move.l	(sp)+,a0		; Link it to the old FileLink.
	move.l	d0,(a0)
	move.l	d0,a1			; Prepare copying data from the anchor

.UseOldLink:
	lea	MyAnchor+ap_Info,a0	; to the FileLink.
	move.l	(fib_DirEntryType,a0),(fl_DirType,a1)
	bgt	.SkipDir		; Skip directories.
	st	Flag_FileFound		; Now we have at least one file.
	move.l	(fib_Size,a0),(fl_Size,a1)
	movem.l	a0-a1,-(sp)
	lea	(fib_FileName,a0),a0
	lea	(fl_FileName,a1),a1
	exg	a0,a1
	bsr	StrCpy
	movem.l	(sp)+,a0-a1
	IFD	Code020
	move.l	([ap_Last,a0],an_Lock),(fl_DirLock,a1)
	ENDC
	IFND	Code020
	move.l	ap_Last(a0),a0
	move.l	an_Lock(a0),(fl_DirLock,a1)
	ENDC
	move.l	a1,-(sp)		; Store for .GetNextFile linkage.
	move.l	#MyAnchor,d1
	Call	Dos,MatchNext
	tst.l	d0
	bne	.NoMatch
	bra	.GetNextFile

.SkipDir:
	move.w	#$00f,$dff180
	move.l	#MyAnchor,d1
	Call	Dos,MatchNext
	tst.l	d0
	bne	.NoMatch
	bra	.UseOldLink

.NoMatch:
	addq.l	#4,sp
	lea	MyAnchor,a0
	tst.l	ap_FoundBreak(a0)
	bne	BreakPressed
	Call	Dos,IoErr
	cmp.l	#ERROR_NO_MORE_ENTRIES,d0
	bne	.RealError
	move.w	#$f00,$dff180
	rts

.RealError:
	st	Flag_Stop
	cmp.l	#ERROR_OBJECT_NOT_FOUND,d0
	beq	Err_NoSource
	cmp.l	#ERROR_DEVICE_NOT_MOUNTED,d0
	beq	Err_NoSource
	move.l	d0,d1
	move.l	#Text_Error,d2
	move.l	#PrintBuf,d3
	move.l	#256,d4
	Call	Dos,Fault
	lea	PrintBuf,a0
	bsr	StrLFCat
	bsr	WritePrintBuf
	bra	EndProgramErr

InsertEOLs:
	move.l	EOLs,d3
	bne	.EOLsWaiting
	rts

.EOLsWaiting:
	clr.l	EOLs
	add.l	d3,d2			; Add the number of LFs.
	tst.b	Mode			; If ToPC or ToSF7, add a CR too.
	bpl	.DoInsertEOLs
	add.l	d3,d2			; Add the number of CRs.

.DoInsertEOLs:
	subq.l	#1,d3

.DoInsert:
	bsr	InsertSingleEOL
	dbf	d3,.DoInsert
	rts

; Inserts an EOL according to Mode, and adds D2.

InsertOneEOL:
	move.b	#LF,(a1)+
	tst.b	Mode			; If ToPC or ToSF7, add a CR too.
	bmi	.ForeignEOL
	addq.l	#1,d2
	rts

.ForeignEOL:
	move.b	#CR,(a1)+
	addq.l	#2,d2
	rts

; Inserts an EOL according to Mode, but does not add D2.

InsertSingleEOL:
	move.b	#LF,(a1)+
	tst.b	Mode			; If ToPC or ToSF7, add a CR too.
	bmi	.ForeignEOL
	rts

.ForeignEOL:
	move.b	#CR,(a1)+
	rts

FlushArea:
	tst.b	TabSize
	bne	.SpaceTabConv
	lea	SpaceBuf,a2
	move.l	SpaceNumber,d3
	beq	.NothingToCopy
	add.l	d3,d2
	subq.l	#1,d3

.CopyArea:
	move.b	(a2)+,(a1)+
	dbf	d3,.CopyArea

.NothingToCopy:
	bsr	ResetArea
	rts

.SpaceTabConv:
	tst.b	PreSpace
	beq	.NoPreSpace
	move.b	#" ",(a1)+
	addq.l	#1,d2

.NoPreSpace:
	move.l	Tabs,d3
	beq	.NoTabs
	add.l	d3,d2
	subq.l	#1,d3

.InsertTabs
	move.b	#TAB,(a1)+
	dbf	d3,.InsertTabs

.NoTabs:
	move.l	SpaceNumber,d3
	beq	.NoSpaces
	add.l	d3,d2
	subq.l	#1,d3

.InsertSpaces
	move.b	#" ",(a1)+
	dbf	d3,.InsertSpaces

.NoSpaces:
	bsr	ResetArea
	rts

ResetArea:
	tst.b	TabSize
	beq	.NoSpaceTabConv
	clr.l	SpaceNumber
	clr.l	Tabs
	clr.b	PreSpace
	rts

.NoSpaceTabConv:
	lea	SpaceBuf,a2
	clr.l	SpaceNumber
	rts

BufChar:
	move.b	d0,(a2)+		; No Space-Tab conversion active,
	addq.l	#1,SpaceNumber		; buffer all area found.
	addq.w	#1,Col
	rts

SpaceConv:
	cmp.l	#1,SpaceNumber		; If Spacenumber<1, don't try to convert
	bcc	.ContConv		; to tabs.  No use, and time wasted in
	rts

.ContConv:
	move.w	Col,d5
	ext.l	d5
	move.l	SpaceNumber,d3
	move.b	SpaceSize,d4
	IFD	Code020			; Convert TabSize
	extb.l	d4
	ENDC
	IFND	Code020
	ext.w	d4
	ext.l	d4
	ENDC
	divu.w	d4,d5			; If column is divisible by SpaceSize,
	swap	d5			; it can be converted to a tab.
	tst.w	d5
	beq.b	.CanConv
	rts

.CanConv:
	cmp.l	#1,SpaceNumber		; If only one space is won, instead
	beq.b	.GotPreSpace		; of conversion, make it PreSpace.
	addq.l	#1,Tabs			; More tabs.
	clr.l	SpaceNumber		; Take the spaces out.
	rts

.GotPreSpace:
	st	PreSpace
	clr.l	SpaceNumber		; Reset SpaceNumber.
	rts

TabConv:
	move.b	TabSize,d4		; TabSize = 0 means no Tabs2Spaces conv
	IFD	Code020			; Convert TabSize
	extb.l	d4
	ENDC
	IFND	Code020
	ext.w	d4
	ext.l	d4
	ENDC
	move.w	Col,d3			; Get current column
	ext.l	d3
	divu.w	d4,d3			; Divide column with TabSize -> we get
	swap	d3			; the offset from last tab as chars.
	sub.w	d3,d4			; Get the # of spaces to the next tab
	add.l	d4,SpaceNumber		; Add the converted spaces to SpaceBuf.
	add.w	d4,Col			; And add column too.
	rts

OpenDest:
	move.l	#DestName,d1		; Open the DestName file.
	move.l	#MODE_NEWFILE,d2
	move.l	_DosBase,a6
	jsr	_LVOOpen(a6)
	move.l	d0,DestHandle
	beq.w	Err_NoDest
	move.b	#1,Mode_DeleteErrDest	; Delete the dest file in case of error.

	moveq	#0,d2
	lea	DestBuf,a1
	move.l	Table,a3		; Get the table.
	lea	SpaceBuf,a2
	rts

MakeSourceASCII:
	lea	SourceLenASCII,a0	; Make a string out of the file length.
	move.l	SourceLen,d0
	bsr	NumToStr
	move.l	a0,SourceLenASCIIAddr
	move.l	d0,SourceLenASCIILen
	rts
	
CalcReadRate:
	move.w	TickCount,d1
	ext.l	d1
	add.l	d1,ReadTime
	move.l	ReadTime,d1
	move.l	ReadBytes,d0
	move.b	VBFreq,d2
	IFD	Code020
	extb.l	d2
	divu.l	d1,d0			; Bytes/tick.
	mulu.l	d2,d0			; Bytes/sec.
	ENDC
	IFND	Code020
	ext.w	d2
	divu.w	d1,d0
	bvs	.Overflow
	ext.l	d0
	mulu.w	d2,d0
	ENDC
	cmp.l	#10240,d0
	bcs	.TooLow
	move.l	d0,RBlockSize
	rts

.TooLow:
	move.l	#10240,RBlockSize
	rts

.Overflow:
	move.l	#65535,d0
	mulu.w	d2,d0
	move.l	d0,RBlockSize
	rts

PrintStats:
	movem.l	d1/a0-a1,-(sp)
	moveq	#0,d0			; Get the signals.
	moveq	#0,d1
	Call	Exec,SetSignal
	movem.l	(sp)+,d1/a0-a1
	btst	#SIGBREAKB_CTRL_C,d0	; Check if ^C was pressed.
	bne	BreakPressed
	clr.b	Flag_StatsDue
	tst.b	Mode_Quiet		; See if we should be quiet.
	beq.b	.DoPrint
	rts

.DoPrint:
	movem.l	d1-d7/a0-a6,-(sp)
	move.l	d2,-(sp)
	bsr	ClearPrintBuf
	move.l	#Text_Converted,a0	; The progress info for fully buffered
	bsr	AddPrintBuf		; input.
	lea	NumberBuf,a0
	move.l	(sp)+,d0		; The bytes in the current buffer and
	add.l	WrittenBytes,d0		; the bytes already written.
	bsr	NumToStr
	bsr	AddPrintBuf
	move.l	#Text_Slash,a0
	bsr	AddPrintBuf
	move.l	SourceLenASCIIAddr,a0
	bsr	AddPrintBuf
	move.l	#Text_CR,a0
	bsr	AddPrintBuf
	bsr	WritePrintBuf
	movem.l	(sp)+,d1-d7/a0-a6
	rts

ClearVars:
	move.l	#SourceBuf,SourcePointer
	lea	SpaceBuf,a2
	clr.l	EOLs
	clr.l	WrittenBytes
	clr.l	ReadBytes
	clr.l	LeftBytes
	clr.l	InputBytes
	clr.l	SpaceNumber
	clr.b	PreSpace
	clr.b	Flag_PPUsed
	rts

ClearPrintBuf:
	move.l	#PrintBuf,PrintBufPtr
	rts

AddPrintBuf:
	move.l	PrintBufPtr,a1

apb_Copy:
	move.b	(a0)+,(a1)+
	bne.b	apb_Copy
	subq.l	#1,a1			; A1 is 1 past the null. We want to
	move.l	a1,PrintBufPtr		; overwrite the null.
	rts

WritePrintBuf:
	move.l	#PrintBuf,d2
	bsr	PrintText
	rts

PrintText:
	move.l	d2,a0
	move.l	_DosBase,a6
	IFD	Code020
	tst.l	a6
	ENDC
	IFND	Code020
	cmp.l	#0,a6
	ENDC
	beq	OpenErrDos
	tst.l	OutStruct
	beq	OpenErrDos

PrintText1:
	tst.b	(a0)+
	bne.b	PrintText1

	sub.l	d2,a0
	subq.w	#1,a0
	move.l	a0,d3
	move.l	OutStruct,d1
	jsr	_LVOWrite(a6)
	tst.l	_DosBase
	beq	CloseErrDos
	rts

OpenErrDos:
	movem.l	d0-d7/a0-a5,-(sp)
	lea	_DosName,a1
	moveq	#0,d0
	move.l	_ExecBase,a6
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,ErrDosBase
	move.l	d0,a6
	IFD	Code020
	tst.l	a6
	ENDC
	IFD	Code020
	cmp.l	#0,a6
	ENDC
	bne	OpenErrDos2
	movem.l	(sp)+,d0-d7/a0-a5
	rts

OpenErrDos2:
	move.l	d0,a6
	jsr	_LVOOutput(a6)
	move.l	d0,OutStruct
	bne	OpenErrDos1
	movem.l	(sp)+,d0-d7/a0-a5
	rts

OpenErrDos1:
	movem.l	(sp)+,d0-d7/a0-a5
	bra	PrintText1

CloseErrDos:
	move.l	ErrDosBase,a1
	move.l	_ExecBase,a6
	jsr	_LVOCloseLibrary(a6)
	rts

PrintTextLen:
	move.l	OutStruct,d1
	move.l	_DosBase,a6
	jsr	_LVOWrite(a6)
	rts

; Skips spaces in a string pointed to by A0, returns A0 as zero if it ran out
; of string.

SkipSpace:
	cmp.b	#" ",(a0)
	beq.b	SkipSpace1
	rts

SkipSpace1:
	addq.l	#1,a0
	tst.b	(a0)
	bne.b	SkipSpace
	sub.l	a0,a0
	rts

FindEnd:
	cmp.b	#'"',(a0)		; If the first letter is a quote,
	beq.b	FindEnd_Quote		; go to FindEnd_Quote

FindEnd_Space:
	addq.l	#1,a0			; Get the next position, if it is a
	cmp.b	#" ",(a0)		; Space, we found the end
	beq.b	FindEnd_Space1
	tst.b	(a0)			; If it's the end of comline, we found
	beq.b	FindEnd_Space1		; the end of the name.
	bra.b	FindEnd_Space

FindEnd_Space1:
	subq.l	#1,a0
	rts

FindEnd_Quote:
	addq.l	#1,a0
	tst.b	(a0)			; If end of comline, error.
	beq.b	FindEnd_Quote2
	cmp.b	#'"',(a0)
	bne.b	FindEnd_Quote
	rts

FindEnd_Quote2:
	sub.l	a0,a0
	rts

CopyUntilNull:
	move.b	(a0)+,(a1)+
	bne.b	CopyUntilNull
	rts

	INCDIR	"SRC:Routines/"

	IFD	Code020
	INCLUDE	"NumToStr-020.S"
	ENDC

	IFND	Code020
	INCLUDE	"NumToStr.S"
	ENDC

	INCLUDE	"Percentage.S"
	INCLUDE	"CopyName.S"

**********
** DATA **
**********

	SECTION	FastData,DATA

SourcePointer:
	dc.l	SourceBuf

	CNOP	0,4

MyAnchor:
	dc.l	0			; ap_Base
	dc.l	0			; ap_Last
	dc.l	SIGBREAKF_CTRL_C	; ap_BreakBits
	dc.l	0			; ap_FoundBreak
	dc.b	0			; ap_Flags
	dc.b	0
	dc.w	0			; ap_Strlen
	ds.b	fib_SIZEOF

VertBInterrupt:
	dc.l	0			; Successor.
	dc.l	0			; Predecessor.
	dc.b	NT_INTERRUPT		; Type.
	dc.b	0			; Pri.
	dc.l	Text_VertBIntName	; Ptr to name.
	dc.l	TimeCounter		; Ptr to TimeCounter, IS_DATA.
	dc.l	VertBIntCode		; Ptr to VBLANK code.

RBlockSize:				; Bytes of data for a single Read().
	dc.l	10240

ReadTime:				; Time taken in all Read()'s.
	dc.l	1

***********************
** Conversion tables **
***********************

; *!* Get rid of the technique under here, and use real conversion tables.

; The byte from which to convert is on the right, and the byte into which it
; turns is on the left.  If a null is on the left, it means the byte doesn't
; get to the destination file at all.  Must be word aligned since the data
; gets fetched one word at a time.

Table_ToPC:
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0A,$00,$00,$00,$00,$00 ;10
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/"
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?"
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_"
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","{","|","}","~",$7F
	dc.b	$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
	dc.b	$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
	dc.b	$A0,"¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯"
	dc.b	"°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿"
	dc.b	"À","Á","Â","Ã",$8E,"Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï"
	dc.b	"Ð","Ñ","Ò","Ó","Ô","Õ",$99,"×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß"
	dc.b	"à","á","â","ã",$84,"å","æ","ç","è","é","ê","ë","ì","í","î","ï"
	dc.b	"ð","ñ","ò","ó","ô","õ",$94,"÷","ø","ù","ú","û","ü","ý","þ","ÿ"

Table_Null:
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0A,$00,$00,$00,$00,$00 ;10
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/"
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?"
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_"
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","{","|","}","~",$7F
	dc.b	$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
	dc.b	$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
	dc.b	$A0,"¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯"
	dc.b	"°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿"
	dc.b	"À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï"
	dc.b	"Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß"
	dc.b	"à","á","â","ã","ä","å","æ","ç","è","é","ê","ë","ì","í","î","ï"
	dc.b	"ð","ñ","ò","ó","ô","õ","ö","÷","ø","ù","ú","û","ü","ý","þ","ÿ"

Table_Lowercase:
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0A,$00,$00,$00,$00,$00 ;10
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/"
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?"
	dc.b	"@","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","[","\\","]","^","_"
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","{","|","}","~",$7F
	dc.b	$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
	dc.b	$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
	dc.b	$A0,"¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯"
	dc.b	"°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿"
	DC.B	"à","á","â","ã","ä","å","æ","ç","è","é","ê","ë","ì","í","î","ï"
	dc.b	"ð","ñ","ò","ó","ô","õ","ö","÷","ø","ù","ú","û","ü","ý","þ","ß"
	dc.b	"à","á","â","ã","ä","å","æ","ç","è","é","ê","ë","ì","í","î","ï"
	dc.b	"ð","ñ","ò","ó","ô","õ","ö","÷","ø","ù","ú","û","ü","ý","þ","ÿ"

Table_Uppercase:
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0A,$00,$00,$00,$00,$00 ;10
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/"
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?"
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_"
	dc.b	"`","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","{","|","}","~",$7F
	dc.b	$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
	dc.b	$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
	dc.b	$A0,"¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯"
	dc.b	"°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿"
	dc.b	"À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï"
	dc.b	"Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß"
	dc.b	"À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï"
	dc.b	"Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ÿ"

Table_ToSF7:
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0A,$00,$00,$00,$00,$00 ;10
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/"
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?"
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_"
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","{","|","}","~",$7F
	dc.b	$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
	dc.b	$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
	dc.b	$A0,"¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯"
	dc.b	"°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿"
	dc.b	"À","Á","Â","Ã","[","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï"
	dc.b	"Ð","Ñ","Ò","Ó","Ô","Õ","\\","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß"
	dc.b	"à","á","â","ã","{","å","æ","ç","è","é","ê","ë","ì","í","î","ï"
	dc.b	"ð","ñ","ò","ó","ô","õ","|","÷","ø","ù","ú","û","ü","ý","þ","ÿ"

Table_FromSF7:
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0A,$00,$00,$00,$00,$00 ;10
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/"
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?"
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O"
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","Ä","Ö","Å","^","_"
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","ä","ö","å","~",$7F
	dc.b	$80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F
	dc.b	$90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F
	dc.b	$A0,"¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯"
	dc.b	"°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿"
	dc.b	"À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï"
	dc.b	"Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß"
	dc.b	"à","á","â","ã","ä","å","æ","ç","è","é","ê","ë","ì","í","î","ï"
	dc.b	"ð","ñ","ò","ó","ô","õ","ö","÷","ø","ù","ú","û","ü","ý","þ","ÿ"

Table_FromPC:	;0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0a,$00,$00,$00,$00,$00 ;00
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/" ;20
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?" ;30
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O" ;40
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_" ;50
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o" ;60
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","{","|","}","~","" ;70
	dc.b	"Ç","ü","é","å","ä","à","å","ç","ê","ë","è","ï","î","ì","Ä","Å" ;80
	dc.b	"È","æ","Æ","ô","ö","ò","û","ù","ÿ","Ö","Ü",$a2,"£",$a5,"P","f" ;90
	dc.b	"á","í","ó","ú","ñ","Ñ","ª","º","¿",".",".","½","¼","¡","«","»" ;A0
	dc.b	$7f,$7f,$7f,"|","+","#","+",".","#","#","|","#","#","'","#","." ;B0
	dc.b	"`","+","+","+","-","+","#","+","#","#","#","#","#","=","#","#" ;C0
	dc.b	"+","#","+","`","#","#",".","+","#","'",".",$7f,"æ","[","]","^" ;D0
	dc.b	"c","ß","r","+","E","ó",$b5,"i","o","0","O","ð","ø","ø","E","A" ;E0
	dc.b	"=","±",">","<","í","j","÷","~","°","·","·","V","n","²","·"," " ;F0

Table_Combined:	;0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$09,$0a,$00,$00,$00,$00,$00 ;00
	dc.b	$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1b,$00,$00,$00,$00 ;10
	dc.b	" ","!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/" ;20
	dc.b	"0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?" ;30
	dc.b	"@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O" ;40
	dc.b	"P","Q","R","S","T","U","V","W","X","Y","Z","Ä","Ö","Å","^","_" ;50
	dc.b	"`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o" ;60
	dc.b	"p","q","r","s","t","u","v","w","x","y","z","ä","ö","å","~","" ;70
	dc.b	"Ç","ü","é","å","ä","à","å","ç","ê","ë","è","ï","î","ì","Ä","Å" ;80
	dc.b	"È","æ","Æ","ô","ö","ò","û","ù","ÿ","Ö","Ü",$a2,"£",$a5,"P","f" ;90
	dc.b	"á","í","ó","ú","ñ","Ñ","ª","º","¿",".",".","½","¼","¡","«","»" ;A0
	dc.b	$7f,$7f,$7f,"|","+","#","+",".","#","#","|","#","#","'","#","." ;B0
	dc.b	"`","+","+","+","-","+","#","+","#","#","#","#","#","=","#","#" ;C0
	dc.b	"+","#","+","`","#","#",".","+","#","'",".",$7f,"æ","[","]","^" ;D0
	dc.b	"c","ß","r","+","E","ó",$b5,"i","o","0","O","ð","ø","ø","E","A" ;E0
	dc.b	"=","±",">","<","í","j","÷","~","°","·","·","V","n","²","·"," " ;F0

	INCDIR	"SRC:Port/"

Text_VertBIntName:
	dc.b	"Port VBlank Timer",0

Text_CodeError:
	INCBIN	"PortCodeError"
	dc.b	0

Text_HelpText:
	INCBIN	"PortOpts1"
	dc.b	0

Text_Credits:
	INCBIN	"PortOpts2"
	dc.b	0

Text_Header:
	INCBIN	"Port.Header"
	dc.b	0

Text_CursorOff:
	dc.b	"\c0 p",0

Text_CursorOn:
	dc.b	"\c1 p",0

Text_Error:
	dc.b	"Error!  ",0

Text_NeedBufPP:
	dc.b	"Cannot use NoBuffer mode with PowerPacked files.\0"

Text_Decrunching:
	dc.b	"Loading & decrunching a PowerPacked file...\n\0"

Text_UnknownPP:
	dc.b	"The file is packed with an unknown version of PowerPacker.\0"

Text_WrongPass:
	dc.b	"Incorrect password, can't decrypt.\0"

Text_FileDest:
	dc.b	"Can't have a file destination for wildcards.\0"

	IFD	Code020

Text_OldProcessor:
	dc.b	"At least 68020 is needed.\0"

	ENDC

Text_NewKickNeed:
	dc.b	"At least Kick V36 needed.\0"

Text_BadComLine:
	dc.b	"Bad commandline.",0

Text_NoSource:
	dc.b	"Could not open source file.",0

Text_NoDest:
	dc.b	"Could not open destination file.",0

Text_SourceIsDir:
	dc.b	"Source cannot be a directory.",0

Text_WriteFail:
	dc.b	"Can't write data.",0

Text_NoComLineSpace:
	dc.b	"The mode must be separated with at least one space.",0

Text_BadLogic:
	dc.b	"Conflicting options in commandline.",0

Text_NoMemory:
	dc.b	"Not enough memory to load the file.",0

Text_PowerPacked:
	dc.b	"File is a PowerPacked, \"powerpacker.library\" is needed to read.\0"

Text_BadSource:
	dc.b	"Source file corrupted.",0

Text_BadDest:
	dc.b	"Destination corrupted.",0

Text_NeedBuffer:
	dc.b	"Auto-mode only works with buffered input.",0

Text_SameProbability:
	dc.b	"Can't decide between modes.",0

Text_ConvFile1:
	dc.b	"Converting file \"\0"

Text_ConvFile2:
	dc.b	"\"...\n\0"

Text_Input:
	dc.b	"Input: ",0

Text_Output:
	dc.b	"  Output: ",0

Text_Read:
	dc.b	"Read: ",0

Text_Converted:
	dc.b	"Converted: ",0

Text_Checking:
	dc.b	"Checking file type...\c0K\r\0"

Text_Uses:
	dc.b	"Type: ",0

Text_NullMode:
	dc.b	"Amiga\c0K\n\n"

Text_SF7Mode:
	dc.b	"SF7\c0K\n\0"

Text_PCMode:
	dc.b	"PC\c0K\n\0"

Text_Break:
	dc.b	"-BREAK-\c0K\n\0"

Text_ClearEOL:
	dc.b	"\c0K\0"

_DosName:
	dc.b	"dos.library",0

PPName:
	PPNAME

Text_AmigaSuf:
	dc.b	".AMY\0"

Text_PCSuf:
	dc.b	".PC\0"

Text_SF7Suf:
	dc.b	".SF7\0"

Text_CR:
	dc.b	CR,0

Text_LF:
	dc.b	LF,0

Text_Final:
	dc.b	"File size change: \0"

Text_NegSign:
	dc.b	"-",0

Text_PosSign:
	dc.b	"+",0

Text_PercentSign:
	dc.b	"%\c0K\0"

Text_DoubleSpace:
	dc.b	"  ",0

Text_Slash:
	dc.b	"/",0


	SECTION	FastBlank,BSS

FIB:
	ds.b	fib_SIZEOF

FileLinkBase:				; Pointer to the first FileLink.
	ds.l	1

CurrentLink:				; Pointer to the current FileLink.
	ds.l	1

ErrDosBase:				; DosBase used in case of error.
	ds.l	1

PrintBufPtr:
	ds.l	1

OldStack:
	ds.l	1

DestNameLen:
	ds.l	1

SourceLock:
	ds.l	1

DestLock:
	ds.l	1

EOLs:
	ds.l	1

ReadASCIIAddr:
	ds.l	1

Table:
	ds.l	1

SourceLen:
	ds.l	1

Tabs:
	ds.l	1

WrittenBytes:
	ds.l	1

ReadBytes:
	ds.l	1

LeftBytes:
	ds.l	1

InputBytes:
	ds.l	1

SourceHandle:
	ds.l	1

DestHandle:
	ds.l	1

OutStruct:
	ds.l	1

DestNameStart:
	ds.l	1

SourceNameStart:
	ds.l	1

SourceNameEnd:
	ds.l	1

SourceNameLen:
	ds.l	1

Commandstarrt:
	ds.l	1

_DosBase:
	ds.l	1

_PPBase:
	ds.l	1

SpaceNumber:
	ds.l	1

ReadASCIILen:
	ds.l	1

SourceLenASCIILen:
	ds.l	1

SourceLenASCIIAddr:
	ds.l	1

OldDirLock:
	ds.l	1

Col:
	ds.w	1

; VBLANK interrupt's IS_DATA.

TimeCounter:				; Frame counter.
	ds.b	1
VBFreq:					; VBlankFrequency.
	ds.b	1
Flag_StatsDue:				; Statistics due -flag.
	ds.b	1
	ds.b	1			; Padding.
TickCount:				; VB counter for read sync.
	ds.w	1

SourceBuf:
	ds.b	SIZE_SRCBUF

RealSourceName:
	ds.b	108			; Max filename size in FIB

StrBuf:
	ds.b	256

SourceName:
	ds.b	256

DestName:
	ds.b	256

PrintBuf:
	ds.b	256

SpaceBuf:
	ds.b	1024

NumberBuf:
	ds.b	11

ReadASCII:
	ds.b	11

SourceLenASCII:
	ds.b	11

Flag_IntActive:				; VBLANK interrupt is active.
	ds.b	1

Flag_AnchorUsed:			; Indicates that we need to MatchEnd().
	ds.b	1

Flag_Stop:				; Indicates that exit should be taken.
	ds.b	1

Flag_FileFound:				; At least one file was found.
	ds.b	1

Flag_PPUsed:				; PowerPacker library was used to load
	ds.b	1			; the file.

Mode:
	ds.b	1

TabSize:
	ds.b	1

SpaceSize:
	ds.b	1

Size_MakeEOLs:
	ds.b	1

PreSpace:
	ds.b	1

Mode_NoCutSpace:
	ds.b	1

Mode_Quiet:
	ds.b	1

Mode_NoBuffer:
	ds.b	1

Mode_DeleteErrDest:
	ds.b	1

Mode_SrcDeleted:
	ds.b	1

DestBuf:
	ds.b	SIZE_DESTBUF
