testmode	=	1

	include	"src:shadowlord.i"

; V1.01
; Added bigger understanding of PC box characters.
; Now also understands one-wide box chars, and thick corner changed to #,
; single corner to +.

; V1.02
; Added bad mode error, and error on no space between mode and the rest.

; V1.10
; Cut endspace.
; Text output.

; V1.13
; Percentage & size change
; extra lf
; extra cr removal in topc mode

; V1.16
; Faster translate routines  25% speedup in frompc
; 6 more in frompc
; New helptext.

; V1.18  11-feb
; Upper and lower case modes.

; V1.22  19-feb
; tabs to spaces
; 3 new pc box chars
; bug fixed that confused port if the end of the commandline had spaces.
; spaces to tabs

; V1.24  21-feb
; size reduced by 48
; bug fixed where tabconversion wasn't turned on in spacestotabs
; causing some strange behavior.
; reduced code size by making routines use same parts of code.
; Logic check for options
; 20% when quiet

; V1.25  11-mar
; buffer overflow bug fixed
; new table conversion system
; buffered input
; handles one filename differently
; ctrl+c detection
; doesn't screw up pp files
; 6856 -> 6636
; 9 new pc chars
; end lf removal
; no longer translates one space

; V1.28  20-mar
; - first 7292 -> 6952 = -340 !
; - bug fixed: some bytes got cut off from the beginning if the file was less
;   than 4 bytes long.
; - bug fix: ami->pc no didn't make cr+lf pairs as it should have in 1.25
;   same with ami->sf
; - most modes use table now
; - priorities changed for endspace removal and translation. this also fixes
;   the bug where endlfs didn't get removed if there were nulls or ctrl+zs
;   etc.
; - code rationalized, size down
; - doesn't trigger anything from cr's
; - make eols option
; - automode

; V1.30  27-mar
; - added 13 pc chars
; - no longer can convert 1 space to tabs (made no sense)

* 27-Mar-93
* 32 days of hard coding

; during the program
; a0=source
; a1=dest
; a2=spacebuf
; a3=translation table

; d0=current char
; d1=load counter
; d2=savebyte counter
; d3=translation char


	if	testmode=1
	lea	test_comline,a0
	move.l	#test_len,d0
	endc

progstart:
	clr.b	-1(a0,d0.l)
	movem.l	a0,-(a7)
	move.w	d0,commandlen
	add.l	d0,a0
	subq.l	#1,a0
	move.l	a0,commandend

	lea	dosname,a1
	moveq	#0,d0
	move.l	execbase,a6
	jsr	openlibrary(a6)
	move.l	d0,dosbase

	move.l	dosbase,a6
	jsr	output(a6)
	move.l	d0,outstruct

	if	testmode=1
	bne	err_testmode
	endc

	move.l	#text_cursoroff,d2
	moveq	#5,d3
	bsr	printtext

	movem.l	(a7)+,a0		; commandstart
	tst.b	(a0)			; if blank commandline, instructions
	beq	helptext
	cmp.b	#"?",(a0)
	beq	helptext

parsestart:
	cmp.b	#"-",(a0)
	beq	checkoption

parse:
	cmp.b	#" ",1(a0)		; at least one space after option
	bne	err_nocomlinespace
	cmp.b	#"p",(a0)
	beq	frompcmode
	cmp.b	#"P",(a0)
	beq	topcmode
	cmp.b	#"s",(a0)
	beq	fromsf7mode
	cmp.b	#"S",(a0)
	beq	tosf7mode
	cmp.b	#"u",(a0)
	beq	toupcasemode
	cmp.b	#"l",(a0)
	beq	tolowcasemode
	cmp.b	#"a",(a0)
	beq	automode
	cmp.b	#"n",(a0)
	beq	modetonull
	bra	err_badmode

checkoption:
	cmp.b	#"e",1(a0)
	beq	opt_makeeols
	cmp.b	#"n",1(a0)
	beq	opt_nocutspace
	cmp.b	#"?",1(a0)
	beq	credits
	cmp.b	#"t",1(a0)
	beq	opt_tabconv
	cmp.b	#"s",1(a0)
	beq	opt_spaceconv
	cmp.b	#"q",1(a0)
	beq	opt_quietmode
	cmp.b	#"b",1(a0)
	beq	opt_nobuffermode
	bra	err_badcomline

opt_nocutspace:
	tst.b	size_makeeols
	bne	err_badlogic
	move.b	#1,mode_nocutspace
	addq.l	#2,a0
	bra	opt_next

opt_tabconv:
	tst.b	tabsize
	bne	err_badlogic
	move.b	2(a0),d0
	cmp.b	#" ",d0
	beq	opt_tabconv1
	sub.b	#"0",d0
	cmp.b	#9,d0
	bhi	err_badcomline
	cmp.b	#1,d0
	bcs	err_badcomline
	bra	opt_bothconv

opt_tabconv1:
	move.b	#8,d0
	subq.l	#1,a0
	bra	opt_bothconv

opt_spaceconv:
	tst.b	tabsize
	bne	err_badlogic
	tst.b	size_makeeols
	bne	err_badlogic
	move.b	2(a0),d0
	cmp.b	#" ",d0
	beq	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 low limit
	move.b	d0,spacesize
	bra	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	opt_next

opt_quietmode:
	move.b	#1,mode_quiet
	addq.l	#2,a0
	bra	opt_next

opt_makeeols:
	tst.b	spacesize
	bne	err_badlogic
	move.b	2(a0),d0
	cmp.b	#" ",d0
	beq	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	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	opt_next

opt_makeeols1:
	move.b	d0,size_makeeols
	addq.l	#3,a0
	bra	opt_next

opt_nobuffermode:
	move.b	#1,mode_nobuffer
	addq.l	#2,a0

opt_next:
	cmp.b	#" ",(a0)
	bne	err_badcomline
	bsr	skipspace
	cmp.l	#0,a0
	beq	err_badcomline
	bra	parsestart

frompcmode:
	move.b	#1,mode
	move.l	#table_frompc,table
	bra	nameparse

fromsf7mode:
	move.b	#2,mode
	move.l	#table_fromsf7,table
	bra	nameparse

tosf7mode:
	move.b	#-2,mode
	move.l	#table_tosf7,table
	bra	nameparse

topcmode:
	move.b	#-1,mode
	move.l	#table_topc,table
	bra	nameparse

toupcasemode:
	move.b	#3,mode
	bra	nameparse

tolowcasemode:
	move.b	#4,mode
	bra	nameparse

automode:
	tst.b	mode_nobuffer		; mode_nobuffer=0? means we have buffer
	bne	err_needbuffer		; if not
	move.b	#6,mode
	bra	nameparse

modetonull:
	move.b	#5,mode
	move.l	#table_null,table

nameparse:
	addq.l	#1,a0			; one after mode
	bsr	skipspace
	cmp.l	#0,a0
	beq	err_badcomline
	move.l	a0,sourcenamestart
	bsr	findend
	movem.l	a0,-(a7)		; push sourcename end in stack
	addq.l	#1,a0			; find the length for sourcename
	sub.l	sourcenamestart,a0
	move.l	a0,sourcenamelen

	move.l	sourcenamestart,a0
	move.l	#sourcename,a1
	move.l	sourcenamelen,d0
	bsr	copyname
	clr.b	(a1)

	movem.l	(a7)+,a0		; get sourcename's end from stack
	addq.l	#1,a0
	cmp.l	commandend,a0
	beq	nodest

	bsr	skipspace
	move.l	a0,destnamestart	; if 0, go nodest
	beq	nodest
	bsr	findend
	addq.l	#1,a0			; add 1 to destname end, and get
	sub.l	destnamestart,a0	; get destnamelen in a0
	move.l	a0,d0

	move.l	destnamestart,a0
	lea	destname,a1
	bsr	copyname
	bra	openfiles

nodest:
	move.l	sourcenamestart,a0
	move.l	sourcenamelen,d0
	lea	destname,a1
	bsr	copyname

	tst.b	mode_nobuffer		; if nobuffer=0, no suffix
	beq	openfiles

	cmp.b	#-1,mode
	beq	pcsuffix
	cmp.b	#-2,mode
	beq	sf7suffix

amigasuffix:
	lea	text_amigasuf,a0
	moveq	#4-1,d0
	bra	addsuffix

pcsuffix:
	lea	text_pcsuf,a0
	moveq	#3-1,d0
	bra	addsuffix

sf7suffix:
	lea	text_sf7suf,a0
	moveq	#4-1,d0

addsuffix:
	move.b	(a0)+,(a1)+
	dbf	d0,addsuffix

openfiles:
	tst.b	mode_nobuffer		; if nobuffer=0, no suffix
	beq	openfiles1

	clr.b	(a1)			; end of filename

	move.l	#sourcename,d1
	move.l	#mode_oldfile,d2
	move.l	dosbase,a6
	jsr	open(a6)
	move.l	d0,sourcehandle
	beq	err_nosource

	move.l	sourcehandle,d1
	move.l	#sourcebuf,d2
	move.l	#4,d3
	move.l	dosbase,a6
	jsr	read(a6)
	cmp.l	#4,d0
	bne	openfiles3

	move.l	sourcebuf,d0
	cmp.l	#"PP20",d0
	beq	err_powerpacked

openfiles3:
	move.l	sourcehandle,d1		; seek back to the beginning of file
	moveq	#0,d2
	moveq	#offset_beginning,d3
	move.l	dosbase,a6
	jsr	seek(a6)

	move.l	#destname,d1
	move.l	#mode_newfile,d2
	move.l	dosbase,a6
	jsr	open(a6)
	move.l	d0,desthandle
	beq	err_nodest

	move.l	#sourcebuf,sourcepointer
	bra	readblock

openfiles1:
	clr.b	(a1)			; end of filename

	move.l	#sourcename,d1
	move.l	#access_read,d2
	move.l	dosbase,a6
	jsr	lock(a6)
	movem.l	d0,-(a7)		; error detection, 0=fail

	move.l	d0,d1
	move.l	#fib,d2
	move.l	dosbase,a6
	jsr	examine(a6)		; error detection, 0=fail

	lea	fib,a0
	move.l	fib_size(a0),sourcelen

	lea	sourcelenascii,a0
	move.l	sourcelen,d0
	bsr	num2ascii
	move.l	a0,sourcelenasciiaddr
	move.l	d0,sourcelenasciilen

	movem.l	(a7)+,d1
	move.l	dosbase,a6
	jsr	unlock(a6)

	move.l	#sourcename,d1
	move.l	#mode_oldfile,d2
	move.l	dosbase,a6
	jsr	open(a6)
	move.l	d0,sourcehandle
	beq	err_nosource

	move.l	sourcehandle,d1
	move.l	#sourcebuf,d2
	move.l	#4,d3
	move.l	dosbase,a6
	jsr	read(a6)
	cmp.l	#4,d0
	bne	openfiles2

	move.l	sourcebuf,d0
	cmp.l	#"PP20",d0
	beq	err_powerpacked

openfiles2:
	move.l	sourcehandle,d1		; seek back to the beginning of file
	moveq	#0,d2
	moveq	#offset_beginning,d3
	move.l	dosbase,a6
	jsr	seek(a6)

	move.l	sourcelen,d0
	moveq	#1,d1			; public mem
	move.l	execbase,a6
	jsr	allocmem(a6)
	move.l	d0,sourcepointer
	beq	err_nomem

readfile:
	move.l	sourcehandle,d1
	move.l	sourcepointer,d2
	add.l	readbytes,d2
	move.l	#10240,d3
	move.l	dosbase,a6
	jsr	read(a6)
	cmp.l	#-1,d0
	beq	err_readfail
	add.l	d0,readbytes
	movem.l	d0,-(a7)
	tst.b	mode_quiet
	bne	testread

	move.l	#text_read,d2
	moveq	#14,d3
	bsr	printtext

	lea	readascii,a0
	move.l	readbytes,d0
	bsr	num2ascii

	move.l	a0,readasciiaddr
	move.l	d0,readasciilen
	move.l	a0,d2
	move.l	d0,d3
	bsr	printtext

	move.l	#text_slash,d2
	moveq	#1,d3
	bsr	printtext

	move.l	sourcelenasciiaddr,d2
	move.l	sourcelenasciilen,d3
	bsr	printtext

	move.l	#text_cr,d2
	moveq	#1,d3
	bsr	printtext

testread:
	movem.l	(a7)+,d0
	tst.l	d0			; = number of bytes read
	beq	readfinished

	sub.l	d0,d0
	sub.l	d1,d1
	move.l	execbase,a6
	jsr	setsignal(a6)

	btst	#ctrl_c,d0			; check if ^C was pressed
	bne	breakpressed

	bra	readfile

readfinished:
	move.l	readbytes,leftbytes

	move.l	sourcehandle,d1
	move.l	dosbase,a6
	jsr	close(a6)

	cmp.b	#6,mode
	beq	detectmode
readfinished1:
	move.l	#destname,d1
	move.l	#1006,d2
	move.l	dosbase,a6
	jsr	open(a6)
	move.l	d0,desthandle
	beq	err_nodest

	bra	moredata

detectmode:
	move.l	#text_checking,d2
	moveq	#34,d3
	bsr	printtext

	sub.l	d2,d2
	sub.l	d3,d3
	sub.l	d4,d4
	move.l	sourcepointer,a0
	cmp.l	#10240,leftbytes
	bcs	detectmode1
	move.l	#10240-1,d1
detectmode2:
	move.b	(a0)+,d0
	cmp.b	#"{",d0
	beq	dm_sf7
	cmp.b	#"[",d0
	beq	dm_sf7
	cmp.b	#"|",d0
	beq	dm_sf7
	cmp.b	#"\",d0
	beq	dm_sf7

	cmp.b	#"ä",d0
	beq	dm_ami
	cmp.b	#"Ä",d0
	beq	dm_ami
	cmp.b	#"ö",d0
	beq	dm_ami
	cmp.b	#"Ö",d0
	beq	dm_ami

	cmp.b	#$84,d0
	beq	dm_pc
	cmp.b	#$8e,d0
	beq	dm_pc
	cmp.b	#$94,d0
	beq	dm_pc
	cmp.b	#$99,d0
	beq	dm_pc

	cmp.b	#13,d0
	beq	dm_foreign

detectmode3:
	dbf	d1,detectmode2

	cmp.l	d2,d3
	beq	samewarn1
	cmp.l	d2,d4
	beq	samewarn1
	cmp.l	d3,d4
	beq	samewarn2

detectmode4:
	movem.l	d2-d4,-(a7)
	move.l	#text_uses,d2
	moveq	#14,d3
	bsr	printtext
	movem.l	(a7)+,d2-d4

	cmp.l	d2,d3			; sf7 or ami
	bhi	dm_notsf7

dm_notami:
	cmp.l	d2,d4			; sf7 or pc
	bhi	dm_makepc
	bra	dm_makesf7

dm_notsf7:
	cmp.l	d3,d4			; ami or pc
	bhi	dm_makepc

dm_makeami:
	move.b	#5,mode
	move.l	#table_null,table

	move.l	#text_nullmode,d2
	moveq	#9,d3
	bsr	printtext

	bra	readfinished1	

dm_makepc:
	move.b	#1,mode
	move.l	#table_frompc,table

	move.l	#text_pcmode,d2
	moveq	#7,d3
	bsr	printtext

	bra	readfinished1

dm_makesf7:
	move.b	#2,mode
	move.l	#table_fromsf7,table

	move.l	#text_sf7mode,d2
	moveq	#8,d3
	bsr	printtext

	bra	readfinished1

samewarn1:
	cmp.l	d3,d4
	beq	err_sameprobability
	bra	detectmode4

samewarn2:
	cmp.l	d2,d3
	beq	err_sameprobability
	bra	detectmode4

detectmode1:
	move.l	leftbytes,d1
	subq.l	#1,d1
	bra	detectmode2

dm_sf7:
	addq.l	#1,d2
	bra	detectmode3

dm_ami:
	addq.l	#1,d3
	bra	detectmode3

dm_pc:
	addq.l	#1,d4
	bra	detectmode3

dm_foreign:
	addq.l	#1,d2
	addq.l	#1,d4
	bra	detectmode3

readblock:
	tst.b	mode_nobuffer
	beq	moredata

	move.l	sourcehandle,d1
	move.l	sourcepointer,d2
	move.l	#1024,d3
	move.l	dosbase,a6
	jsr	read(a6)
	cmp.l	#-1,d0
	beq	err_readfail
	add.l	d0,readbytes
	move.l	d0,d1
	beq	closefiles		; readbytes=0 - quit
	subq.l	#1,d1			; counter always one less than real
	sub.l	d2,d2			; bytes to be written zeroed
	lea	sourcebuf,a0
	lea	destbuf,a1
	bra	morecharacters

moredata:
	tst.l	leftbytes
	beq	closefiles
	sub.l	d2,d2
	cmp.l	#1024,leftbytes
	bls	moredata1
	sub.l	#1024,leftbytes
	move.l	sourcepointer,a0
	add.l	inputbytes,a0
	add.l	#1024,inputbytes
	move.l	#1024-1,d1
	lea	destbuf,a1
	bra	morecharacters

moredata1:
	move.l	leftbytes,d0
	clr.l	leftbytes
	move.l	sourcepointer,a0
	add.l	inputbytes,a0
	add.l	d0,inputbytes
	subq.l	#1,d0
	move.l	d0,d1
	lea	destbuf,a1

morecharacters:
	move.b	(a0)+,d0

	cmp.b	#-2,mode		; tosf7
	beq	translate
	cmp.b	#-1,mode		; topc
	beq	translate
	cmp.b	#2,mode			; fromsf7
	beq	translate
	cmp.b	#3,mode
	beq	toupcase
	cmp.b	#4,mode
	beq	tolowcase
	cmp.b	#5,mode
	beq	nullmode

frompc:
	cmp.b	#" ",d0
	bcs	translate
	cmp.b	#"~",d0
	bhi	translate
	bra	nextchar

translate:
	move.l	table,a3
	tst.b	d0
	beq	nochar

translate1:
	move.w	(a3)+,d3
	beq	nextchar		; 0=end of table
	cmp.b	d3,d0
	beq	translate2
	bra	translate1

translate2:
	lsr.w	#8,d3
	move.b	d3,d0			; if 0=no char
	beq	nochar

nextchar:
	bra	cutspace

checknormal:
	move.b	d0,(a1)+
	addq.l	#1,d2
	addq.w	#1,col

nochar:
	dbf	d1,morecharacters

	move.l	desthandle,d1		; write the converted data ~1024 bytes
	move.l	d2,d3
	add.l	d2,writtenbytes
	move.l	#destbuf,d2
	move.l	dosbase,a6
	jsr	write(a6)
	cmp.l	#-1,d0
	beq	err_writefail

	sub.l	d0,d0
	sub.l	d1,d1
	move.l	execbase,a6
	jsr	setsignal(a6)

	btst	#ctrl_c,d0			; check if ^C was pressed
	bne	endprogram5

	tst.b	mode_quiet
	bne	readblock

	tst.b	mode_nobuffer
	beq	alternateoutput

	move.l	#text_input,d2
	moveq	#15,d3
	bsr	printtext

	lea	numberbuf,a0
	move.l	readbytes,d0
	bsr	num2ascii

	move.l	a0,d2
	move.l	d0,d3
	bsr	printtext

	move.l	#text_output,d2
	moveq	#18,d3
	bsr	printtext

	lea	numberbuf,a0
	move.l	writtenbytes,d0
	bsr	num2ascii

	move.l	a0,d2
	move.l	d0,d3
	bsr	printtext

	move.l	#text_cr,d2
	moveq	#1,d3
	bsr	printtext

	bra	readblock

alternateoutput:
	move.l	#text_converted,d2
	moveq	#19,d3
	bsr	printtext

	lea	numberbuf,a0
	move.l	inputbytes,d0
	bsr	num2ascii

	move.l	a0,d2
	move.l	d0,d3
	bsr	printtext

	move.l	#text_slash,d2
	moveq	#1,d3
	bsr	printtext

	move.l	readasciiaddr,d2
	move.l	readasciilen,d3
	bsr	printtext

	move.l	#text_cr,d2
	moveq	#1,d3
	bsr	printtext

	bra	readblock

cutspace:
	move.l	spacepointer,a2
	cmp.b	#" ",d0
	beq	addspace
	cmp.b	#9,d0			; tab
	beq	addtab
	bsr	addeol			; check if char is 10, and add eols

	tst.b	mode_nocutspace
	bne	cutspace2

	cmp.b	#10,d0			; lf
	beq	cutspaces

cutspace1:				; a character which is not a space,
	tst.b	prespace		; tab or a linefeed.  Trigger things
	bne	insertprespace
	tst.l	tabs
	bne	linkspaces

cutspace3:
	tst.l	spacenumber
	bne	linkspaces2

cutspace4:
	cmp.b	#10,d0			; has been buffered, nochar
	beq	nochar
	tst.b	mode_nocutspace
	beq	testforspace

linkeols:
	bsr	inserteols		; insert any eols currently in buffer

	cmp.b	#" ",d0			; if the char was a space or a tab,
	beq	nochar			; we don't want it to pass straight
	cmp.b	#9,d0			; in the buffer.  otherwise yes.
	beq	nochar
	bra	checknormal

testforspace:
	cmp.b	#" ",d0			; if cutspace is on, spaces and tabs
	beq	nochar			; don't automatically trigger eols
	cmp.b	#9,d0			; in: they will be triggered when
	beq	nochar			; the tabs and spaces get triggered
	bra	linkeols

cutspace2:
	cmp.b	#10,d0
	bne	cutspace1
	clr.w	col
	bra	cutspace1

addspace:
	move.b	d0,(a2)+
	move.l	a2,spacepointer
	addq.l	#1,spacenumber
	addq.w	#1,col
	bra	checkconvspace

addtab:
	move.b	tabsize,d4		; if tabsize is zero, just add it in
	bne	tabconv			; spacebuffer
	bra	addspace

tabconv:
	ext.w	d4
	ext.l	d4
	move.w	col,d3
	ext.l	d3
	divu	d4,d3
	swap	d3
	sub.w	d3,d4
	add.l	d4,spacenumber
	add.w	d4,col
	subq.w	#1,d4
	move.b	#" ",d0

tabconv1:
	move.b	d0,(a2)+
	dbf	d4,tabconv1
	move.l	a2,spacepointer

checkconvspace:
	tst.b	spacesize		; spacesize=0 means no space2tab
	beq	cutspace4
	cmp.l	#1,spacenumber		; if spacenumber<1, skip
	bcs	cutspace4
	move.w	col,d5
	ext.l	d5
	move.l	spacenumber,d3
	move.b	spacesize,d4
	ext.w	d4
	ext.l	d4

	divu	d4,d5			; if column is divisible by spacesize,
	swap	d5			; go to "foundconvspace"
	tst.w	d5
	beq	foundconvspace
	bra	cutspace4		; otherwise just continue

foundconvspace:
	cmp.l	#1,spacenumber		; if only one space is won, don't
	beq	foundconvspace2
	move.l	#spacebuf,spacepointer
	addq.l	#1,tabs
	sub.l	d4,spacenumber
	bmi	foundconvspace1
	bra	cutspace4

foundconvspace1:
	clr.l	spacenumber
	bra	cutspace4

foundconvspace2:
	move.b	#1,prespace
	move.l	#spacebuf,spacepointer
	clr.l	spacenumber
	bra	cutspace4

cutspaces:
	clr.l	spacenumber
	clr.l	tabs
	move.l	#spacebuf,spacepointer
	clr.w	col
	bra	nochar

addeol:
	cmp.b	#10,d0
	beq	addeol1
	rts

addeol1:
	addq.l	#1,eols
	rts

linkspaces:
	tst.b	mode_nocutspace
	bne	linkspaces4
	bsr	inserteols

linkspaces4:
	move.l	tabs,d3
	clr.l	tabs
	add.l	d3,d2			; tabs -> bytes to be written
	subq.l	#1,d3

linkspaces1:
	move.b	#9,(a1)+
	dbf	d3,linkspaces1
	bra	cutspace3

linkspaces2:
	tst.b	mode_nocutspace
	bne	linkspaces5
	bsr	inserteols

linkspaces5:
	move.l	spacenumber,d3
	tst.b	size_makeeols
	bne	ls_checkmakeeols
linkspaces6:
	add.l	d3,d2			; spaces -> bytes to be written
	subq.l	#1,d3
	lea	spacebuf,a2
	move.l	a2,spacepointer

linkspaces3:
	move.b	(a2)+,(a1)+
	dbf	d3,linkspaces3
	clr.l	spacenumber
	bra	cutspace4

ls_checkmakeeols:
	cmp.b	size_makeeols,d3
	bcs	linkspaces6
	addq.l	#1,d2
	move.b	#10,(a1)+
	clr.l	spacenumber
	move.l	#spacebuf,spacepointer
	bra	cutspace4

insertprespace:
	clr.b	prespace
	move.b	#" ",(a1)+
	addq.l	#1,d2
	bra	cutspace1

toupcase:
	cmp.b	#"ä",d0
	beq	ami_upae
	cmp.b	#"ö",d0
	beq	ami_upoe
	cmp.b	#"a",d0
	bcs	nextchar
	cmp.b	#"z",d0
	bhi	nextchar

	and.b	#%11011111,d0
	bra	nextchar

tolowcase:
	cmp.b	#"Ä",d0
	beq	ami_lowae
	cmp.b	#"Ö",d0
	beq	ami_lowoe
	cmp.b	#"A",d0
	bcs	nextchar
	cmp.b	#"Z",d0
	bhi	nextchar

	or.b	#%100000,d0
	bra	nextchar

nullmode:
	bra	translate

ami_lowae:
	move.b	#"ä",d0
	bra	nextchar

ami_lowoe:
	move.b	#"ö",d0
	bra	nextchar

ami_upae:
	move.b	#"Ä",d0
	bra	nextchar

ami_upoe:
	move.b	#"Ö",d0
	bra	nextchar

pc_lowae:
	move.b	#$84,d0
	bra	nextchar

pc_lowoe:
	move.b	#$94,d0
	bra	nextchar

pc_upae:
	move.b	#$8e,d0
	bra	nextchar

pc_upoe:
	move.b	#$99,d0
	bra	nextchar

sf7_lowae:
	move.b	#"{",d0
	bra	nextchar

sf7_lowoe:
	move.b	#"|",d0
	bra	nextchar

sf7_upae:
	move.b	#"[",d0
	bra	nextchar

sf7_upoe:
	move.b	#"\",d0
	bra	nextchar

closefiles:
	tst.b	mode_nobuffer
	beq	freebuffer
	bsr	closesource
	bra	closefiles3

freebuffer:
	bsr	freememory

closefiles3:
	bsr	closedest

	move.l	#text_final,d2
	moveq	#26,d3
	bsr	printtext

	move.l	readbytes,d1
	move.l	writtenbytes,d0

	sub.l	d1,d0
	bmi	closefiles1		; negative

	move.l	d0,d7
	beq	closefiles2		; if zero, no sign

	move.l	#text_possign,d2
	moveq	#1,d3
	bsr	printtext
	bra	closefiles2

closefiles1:
	neg.l	d0
	move.l	d0,d7

	move.l	#text_negsign,d2
	moveq	#1,d3
	bsr	printtext

closefiles2:
	move.l	d7,d0
	lea	numberbuf,a0
	bsr	num2ascii

	move.l	a0,d2
	move.l	d0,d3
	bsr	printtext

	move.l	#text_doublespace,d2
	moveq	#2,d3
	bsr	printtext

	move.l	writtenbytes,d0
	move.l	readbytes,d1
	bsr	percentage

	lea	numberbuf,a0
	bsr	num2ascii

	move.l	a0,d2
	move.l	d0,d3
	bsr	printtext

	move.l	#text_percentsign,d2
	move.l	#5,d3
	bsr	printtext

	move.l	#text_lf,d2
	move.l	#1,d3
	bsr	printtext
	bra	endprogram1

helptext:
	move.l	#text_helptext,d2
	move.l	#len_helptext,d3
	bsr	printtext
	bra	endprogram1

credits:
	move.l	#text_credits,d2
	move.l	#len_credits,d3
	bsr	printtext
	bra	endprogram1

	if	testmode=1
err_testmode:
	move.l	#$ffff,d0

err_testmode1:
	move.w	#$f00,$dff180
	dbf	d0,err_testmode1
	bra	endprogram1
	endc

err_nosource:
	move.l	#text_nosource,d2
	moveq	#28,d3
	bsr	printerror
	bra	endprogram1

err_badcomline:
	move.l	#text_badcomline,d2
	moveq	#17,d3
	bsr	printerror
	bra	endprogram1

err_nodest:
	move.l	#text_nodest,d2
	moveq	#33,d3
	bsr	printerror
	bra	endprogram2

err_badmode:
	move.l	#text_badmode,d2
	moveq	#24,d3
	bsr	printerror
	bra	endprogram1

err_nocomlinespace:
	move.l	#text_nocomlinespace,d2
	moveq	#52,d3
	bsr	printerror
	bra	endprogram1

err_badlogic:
	move.l	#text_badlogic,d2
	moveq	#25,d3
	bsr	printerror
	bra	endprogram1

err_nomem:
	move.l	#text_nomemory,d2
	moveq	#36,d3
	bsr	printerror
	bsr	closesource
	bra	endprogram1

err_powerpacked:
	move.l	#text_powerpacked,d2
	moveq	#48,d3
	bsr	printerror
	bsr	closesource
	bra	endprogram1

err_seekfail:
	move.l	#text_badsource,d2
	moveq	#23,d3
	bsr	printerror
	bsr	closesource
	bra	endprogram1

err_readfail:
	move.l	#text_badsource,d2
	moveq	#23,d3
	bsr	printerror
	bra	endprogram3

err_writefail:
	move.l	#text_baddest,d2
	moveq	#18,d3
	bsr	printerror
	bra	endprogram3

err_needbuffer:
	move.l	#text_needbuffer,d2
	moveq	#42,d3
	bsr	printerror
	bra	endprogram1

err_sameprobability:
	move.l	#text_sameprobability,d2
	moveq	#28,d3
	bsr	printerror
	bsr	freememory
	bra	endprogram1

endprogram5:
	tst.b	mode_nobuffer
	beq	endprogram6

	bsr	closesource
	bsr	closedest

	move.l	#destname,d1
	move.l	dosbase,a6
	jsr	deletefile(a6)		; error detection here

	move.l	#text_break,d2
	moveq	#20,d3
	bsr	printtext
	bra	endprogram1

endprogram6:
	bsr	closedest
	bsr	freememory

	move.l	#destname,d1
	move.l	dosbase,a6
	jsr	deletefile(a6)		; error detection here

	move.l	#text_break,d2
	moveq	#20,d3
	bsr	printtext
	bra	endprogram1

breakpressed:				; source and mem open, dest not
	bsr	freememory
	bsr	closesource
	move.l	#text_break,d2
	moveq	#20,d3
	bsr	printtext
	bra	endprogram1

	bsr	closedest

endprogram3:
	bsr	closesource
	tst.b	mode_nobuffer
	beq	endprogram3_1
	bsr	closedest
	bra	endprogram1

endprogram3_1:
	bsr	freememory
	bra	endprogram1

endprogram2:
	tst.b	mode_nobuffer		; closes source if nobuffer
	beq	endprogram1
	bsr	closesource

endprogram1:
	move.l	#text_cursoron,d2
	moveq	#5,d3
	bsr	printtext

	move.l	execbase,a6
	move.l	dosbase,a1
	jsr	closelibrary(a6)
	moveq	#0,d0
	rts


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

inserteols:
	move.l	eols,d3
	bne	inserteols1
	rts

inserteols1:
	add.l	d3,d2
	subq.l	#1,d3

inserteols2:
	cmp.b	#0,mode		; if mode is negative, adds crs
	bmi	insertcr
inserteols3:
	move.b	#10,(a1)+
	dbf	d3,inserteols2
	clr.l	eols
	rts

insertcr:
	move.b	#13,(a1)+
	addq.l	#1,d2
	bra	inserteols3

copyname:
	subq.l	#1,d0
	cmp.b	#'"',(a0)		; if no quote, go to copyname1, else
	bne	copyname1		; take one char from each side
	addq.l	#1,a0
	subq.l	#2,d0

copyname1:
	move.b	(a0)+,(a1)+
	dbf	d0,copyname1
	rts

freememory:
	move.l	sourcepointer,a1
	move.l	sourcelen,d0
	move.l	execbase,a6
	jsr	freemem(a6)
	rts

closedest:
	move.l	desthandle,d1
	move.l	dosbase,a6
	jsr	close(a6)
	rts

closesource:
	move.l	sourcehandle,d1
	move.l	dosbase,a6
	jsr	close(a6)
	rts

printerror:
	movem.l	d2/d3,-(a7)
	move.l	#text_error,d2
	move.l	#8,d3
	bsr	printtext
	movem.l	(a7)+,d2/d3
	bsr	printtext
	rts

printtext:
	if	testmode=1
	rts
	endc

	move.l	outstruct,d1
	move.l	dosbase,a6
	jsr	write(a6)
	rts

skipspace:
	cmp.b	#" ",(a0)
	beq	skipspace1
	rts

skipspace1:
	addq.l	#1,a0
	cmp.l	commandend,a0
	bcs	skipspace
	move.l	#0,a0
	rts

findend:
	cmp.b	#'"',(a0)		; if the first letter is a quote,
	beq	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	findend_space1
	tst.b	(a0)			; if it's the end of comline, we found
	beq	findend_space1		; the end of name
	bra	findend_space

findend_space1:
	subq.l	#1,a0
	rts

findend_quote:
	addq.l	#1,a0
	tst.b	(a0)			; if end of comline, error
	beq	findend_quote2
	cmp.b	#'"',(a0)
	bne	findend_quote
	rts

findend_quote2:
	move.l	#0,a0
	rts

	include	"src:Num2ASCII-2.S"
	include	"src:Percentage.S"

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

	section	fastdata,data

spacepointer:
	dc.l	spacebuf

table_frompc:
	dc.b	$00,$0d
	dc.b	$00,$1a
	dc.b	$b6,$14
	dc.b	$e7,$80
	dc.b	$dc,$81
	dc.b	"å",$83
	dc.b	"ä",$84
	dc.b	"Ä",$8e
	dc.b	$e6,$91
	dc.b	$c6,$92
	dc.b	"ö",$94
	dc.b	"Ö",$99
	dc.b	$7f,$b0
	dc.b	$7f,$b1
	dc.b	$7f,$b2
	dc.b	"|",$b3
	dc.b	"+",$b4
	dc.b	"#",$b6
	dc.b	"+",$b7
	dc.b	"#",$b8
	dc.b	"|",$ba
	dc.b	"#",$bb
	dc.b	"#",$bc
	dc.b	"+",$bd
	dc.b	"#",$be
	dc.b	"+",$bf
	dc.b	"+",$c0
	dc.b	"+",$c1
	dc.b	"+",$c2
	dc.b	"+",$c3
	dc.b	"-",$c4
	dc.b	"+",$c5
	dc.b	"#",$c7
	dc.b	"#",$c8
	dc.b	"#",$c9
	dc.b	"=",$cd
	dc.b	"#",$cf
	dc.b	"+",$d3
	dc.b	"#",$d4
	dc.b	"#",$d5
	dc.b	"+",$d9
	dc.b	"+",$d6
	dc.b	"+",$da
	dc.b	$7f,$db
	dc.b	"_",$dc
	dc.b	"|",$dd
	dc.b	"|",$de
	dc.b	"¯",$df
	dc.b	"=",$f0
	dc.b	$b7,$f9
	dc.b	$b7,$fa
	dc.b	$b7,$fe
	dc.w	0

table_topc:
	dc.b	$00,$0d
	dc.b	$00,$1a
	dc.b	$84,"ä"
	dc.b	$8e,"Ä"
	dc.b	$94,"ö"
	dc.b	$99,"Ö"
	dc.w	0

table_null:
	dc.b	$00,$0d
	dc.b	$00,$1a
	dc.w	0

table_tosf7:
	dc.b	$00,$0d
	dc.b	$00,$1a
	dc.b	"{","ä"
	dc.b	"|","ö"
	dc.b	"[","Ä"
	dc.b	"\","Ö"
	dc.w	0

table_fromsf7:
	dc.b	$00,$0d
	dc.b	$00,$1a
	dc.b	"ä","{"
	dc.b	"ö","|"
	dc.b	"Ä","["
	dc.b	"Ö","\"
	dc.w	0


text_helptext:
	incbin	"src:Port/PortOpts1"

text_credits:
	incbin	"src:Port/PortOpts2"

text_cursoroff:
	dc.b	27,"[0 p"

text_cursoron:
	dc.b	27,"[1 p"

text_error:
	dc.b	"ERROR!  "

text_badcomline:
	dc.b	"Bad commandline.",10

text_nosource:
	dc.b	"Could not open source file.",10

text_nodest:
	dc.b	"Could not open destination file.",10

text_badmode:
	dc.b	"Bad mode specification.",10

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

text_badlogic:
	dc.b	"Conflict in commandline.",10

text_nomemory:
	dc.b	"Not enough memory to load the file.",10

text_powerpacked:
	dc.b	"File is a PowerPacker data file, can't process.",10

text_badsource:
	dc.b	"Source file corrupted.",10

text_baddest:
	dc.b	"Can't write data.",10

text_needbuffer:
	dc.b	"Auto-mode only works with buffered input.",10

text_sameprobability:
	dc.b	"Can't decide between modes.",10

text_input:
	dc.b	27,"[1mInput: ",27,"[0m"

text_output:
	dc.b	"  ",27,"[1mOutput: ",27,"[0m"

text_read:
	dc.b	27,"[1mRead: ",27,"[0m"

text_converted:
	dc.b	27,"[1mConverted: ",27,"[0m"

text_checking:
	dc.b	27,"[1mChecking file type...",27,"[0m",27,"[0K",13

text_uses:
	dc.b	27,"[1mMode: ",27,"[0m"

text_nullmode:
	dc.b	"Null",27,"[0K",10

text_sf7mode:
	dc.b	"SF7",27,"[0K",10

text_pcmode:
	dc.b	"PC",27,"[0K",10

text_break:
	dc.b	27,"[1m-BREAK-",27,"[0m",27,"[0K",10

text_cleareol:
	dc.b	27,"[0K"

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

text_amigasuf:
	dc.b	".AMI"

text_pcsuf:
	dc.b	".PC"

text_sf7suf:
	dc.b	".SF7"

text_cr:
	dc.b	13

text_lf:
	dc.b	10

text_final:
	dc.b	27,"[1mFile size change:",27,"[0m "

text_negsign:
	dc.b	"-"

text_possign:
	dc.b	"+"

text_percentsign:
	dc.b	"%",27,"[0K"

text_doublespace:
	dc.b	"  "

text_slash:
	dc.b	"/"

	if	testmode=1

test_comline:
	dc.b	"P ram:port.doc ram:shit2",10

test_comlineend:

test_len	=	test_comlineend-test_comline

	endc

	section	fastblank,bss

eols:
	ds.l	1

readasciiaddr:
	ds.l	1

sourcepointer:
	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

sourcenamelen:
	ds.l	1

commandstarrt:
	ds.l	1

commandend:
	ds.l	1

commandlen:
	ds.l	1

dosbase:
	ds.l	1

spacenumber:
	ds.l	1

readasciilen:
	ds.l	1

sourcelenasciilen:
	ds.l	1

sourcelenasciiaddr:
	ds.l	1

col:
	ds.w	1

; all bytedata that needs to be word-aligne here

fib:
	ds.b	260

sourcebuf:
	ds.b	1024

sourcename:
	ds.b	256

destname:
	ds.b	256

destbuf:
	ds.b	9216

spacebuf:
	ds.b	1024

numberbuf:
	ds.b	10

readascii:
	ds.b	10

sourcelenascii:
	ds.b	10

mode:
	ds.b	1

tabsize:
	ds.b	1

spacesize:
	ds.b	1

size_makeeols:
	ds.b	1

prespace:
	ds.b	1

mode_case:
	ds.b	1

mode_nocutspace:
	ds.b	1

mode_quiet:
	ds.b	1

mode_nobuffer:
	ds.b	1

len_helptext	=	text_credits-text_helptext
len_credits	=	text_cursoroff-text_credits
