; This is an example program which shows how to work
; with the coder.library in Assembler.
; It opens a file and decodes it if it was coded with
; MasterCoder. Moreover it decodes protected AmigaBasic
; files to the binary format of AmigaBasic.

; MasterCoder and coder.library are FREEWARE!
; ©1994 by Norbert Tausch, Karlstr. 30, D-90763 Fuerth

; See docs for more information!


	incdir 	"include:"
	include	"exec/exec_lib.i"
	include "exec/memory.i"
	include	"libraries/dos_lib.i"
	include "libraries/dos.i"
	include "libraries/coder_lib.i"
	include "libraries/coder.i"

GotoXY:	macro
	dc.b $9b,'\2;\1H'
	endm

Color:	macro
	dc.b $9b,'\1;\2;\3m'
	endm


	moveq	#CODER_VERSION,d0
	lea	_CoderName(pc),a1
	CALLEXEC OpenLibrary
	move.l	d0,_CoderBase
	beq	LibraryError

	moveq	#0,d0
	lea	_DosName(pc),a1
	CALLEXEC OpenLibrary
	move.l	d0,_DOSBase
	beq CloseCoderLib

	CALLDOS	Output
	move.l	d0,OutputHandle
	CALLDOS	Input
	move.l	d0,InputHandle

	; Print information
	move.l	OutputHandle,d1
	move.l	#Text1,d2
	move.l	#Text2-Text1,d3
	CALLDOS	Write

; LibVersion returns a pointer to a string contenting information
; about version and release date.
	CALLCODER LibVersion
	; Get length of info-string
	move.l	d0,a0
	moveq	#-1,d3
Loop1:	addq.l	#1,d3
	cmp.b	#0,(a0)+
	bne.s	Loop1
	; Length of string in d3!
	move.l	OutputHandle,d1
	move.l	d0,d2
	CALLDOS Write

	; Input of source-file name
	move.l	OutputHandle,d1
	move.l	#Text2,d2
	move.l	#Text3-Text2,d3
	CALLDOS	Write

	move.l	InputHandle,d1
	move.l	#Source,d2
	move.l	#80,d3
	CALLDOS	Read

	lea	Source(pc),a0
	move.b	#0,-1(a0,d0)

	; Open source file
	move.l	#Source,d1
	move.l	#MODE_OLDFILE,d2
	CALLDOS	Open
	move.l	d0,SHandle1
	beq	SourceFileError

	; Get length of file
	move.l	SHandle1,d1
	moveq	#0,d2
	move.l	#OFFSET_END,d3
	CALLDOS	Seek
	move.l	SHandle1,d1
	moveq	#0,d2
	move.l	#OFFSET_BEGINNING,d3
	CALLDOS	Seek
	move.l	d0,FileLength

	; Alloc memory
	move.l	FileLength,d0
	move.l	#MEMF_CLEAR+MEMF_PUBLIC,d1
	CALLEXEC AllocMem
	move.l	d0,Memory
	beq	MemoryError

	move.l	OutputHandle,d1
	move.l	#Text3,d2
	move.l	#Text4-Text3,d3
	CALLDOS	Write

	; Read source file
	move.l	SHandle1,d1
	move.l	Memory,d2
	move.l	FileLength,d3
	CALLDOS	Read
	cmp.l	d0,d3
	bne	ReadError

	movea.l	Memory,a0
	cmp.b	#AMIGABASIC_PROTECTED,(a0)
	bne	Loop2

; ***** Decoding protected AmigaBasic file:
	
	move.l	OutputHandle,d1
	move.l	#Text4,d2
	move.l	#Text5-Text4,d3
	CALLDOS	Write

	; Change first character of file to 245 (=binary)
	movea.l	Memory,a0
	move.b	#AMIGABASIC_BINARY,(a0)

; ABasDeCode decodes the protected datas to the binary
; format of AmigaBasic.
	movea.l	Memory,a0
	adda.l	#1,a0
	movea.l	a0,a1
	move.l	FileLength,d0
	subq.l	#1,d0
	CALLCODER ABasDeCode
	bra	Loop6

; ***** Decoding file of MasterCoder:

Loop2:
; TestCoderID tests if the file was coded with MasterCoder
; and returns the number of the algorithm and the length
; of the MasterCoder fileheader in the CoderID-Structure.
	movea.l	Memory,a0
	lea	CoderID(pc),a1
	CALLCODER TestCoderID

	cmp.b	#CODER_OK,Status(a1)
	bne	Loop5

	; Input of codeword
	move.l	OutputHandle,d1
	move.l	#Text5,d2
	move.l	#Text6-Text5,d3
	CALLDOS	Write

	move.l	InputHandle,d1
	move.l	#Codeword,d2
	move.l	#160,d3
	CALLDOS	Read

	lea	Codeword(pc),a0
	move.b	#0,-1(a0,d0)

	move.l	OutputHandle,d1
	move.l	#Text6,d2
	move.l	#Text7-Text6,d3
	CALLDOS	Write

; FuncInfo returns a pointer to a table including
; information about the algorithms of the coder.library.
	CALLCODER FuncInfo
	move.l	d0,FuncTable
	beq	Loop3

	move.l	OutputHandle,d1
	move.l	#Text7,d2
	move.l	#Text8-Text7,d3
	CALLDOS	Write

	; Get a pointer to the first letter of the algorithm name
	movea.l	FuncTable,a0
	adda.l	#12,a0
	lea	CoderID(pc),a1
	moveq	#0,d0
	move.b	Recog(a1),d0
	mulu.w	#14,d0
	adda.l	d0,a0

	; Get length of algorithm name
	moveq	#-1,d3
	movea.l	a0,a1
Loop2.1:
	addq.l	#1,d3
	move.b	(a1)+,d0
	cmp.b	#32,d0
	beq.s	Loop2.2
	cmp.b	#0,d0
	bne.s	Loop2.1

Loop2.2:
	; Print algorithm name
	move.l	OutputHandle,d1
	move.l	a0,d2
	CALLDOS	Write

	move.l	OutputHandle,d1
	move.l	#Text8,d2
	move.l	#Text9-Text8,d3
	CALLDOS	Write

	; Clear memory for FuncTable
	movea.l	FuncTable,a1
	move.l	(a1),d0
	CALLEXEC FreeMem
	bra	Loop4

Loop3:	move.l	OutputHandle,d1
	move.l	#Text9,d2
	move.l	#Text10-Text9,d3
	CALLDOS	Write

Loop4:
; UnknownDeCode decodes the coded datas. The algorithm number
; (=Recog(FuncTable)) says which algorithm is used for decoding.
	lea	CoderID(pc),a3
	movea.l	Memory,a0
	adda.w	Length(a3),a0
	movea.l a0,a1
	lea	Codeword(pc),a2
	move.l	FileLength,d0
	sub.w	Length(a3),d0
	moveq	#0,d1
	move.b	Recog(a3),d1
	CALLCODER UnknownDeCode
	
	cmp.l	#CODER_OK,d0
	bne.s	Loop4.1

	move.l	OutputHandle,d1
	move.l	#Text10,d2
	move.l	#Text11-Text10,d3
	CALLDOS	Write
	bra	Loop6

Loop4.1:
	move.l	OutputHandle,d1
	move.l	#Text11,d2
	move.l	#Text12-Text11,d3
	CALLDOS	Write
	bra	Loop7

Loop5:	move.l	OutputHandle,d1
	move.l	#Text12,d2
	move.l	#Text13-Text12,d3
	CALLDOS	Write

	lea	CoderID(pc),a0
	cmp.b	#CODER_HIGHER_VERSION,Status(a0)
	beq	VersionError
	cmp.b	#CODER_NO_HEADER,Status(a0)
	beq	NoFileHeader
	bra	Loop7

Loop6:	; Save datas:
	; Input of destination-file name
	move.l	OutputHandle,d1
	move.l	#Text13,d2
	move.l	#Text14-Text13,d3
	CALLDOS	Write

	move.l	InputHandle,d1
	move.l	#Destination,d2
	move.l	#80,d3
	CALLDOS	Read

	lea	Destination(pc),a0
	move.b	#0,-1(a0,d0)

	; Open destination file
	move.l	#Destination,d1
	move.l	#MODE_NEWFILE,d2
	CALLDOS	Open
	move.l	d0,SHandle2
	beq	DestinationError

	move.l	OutputHandle,d1
	move.l	#Text14,d2
	move.l	#Text15-Text14,d3
	CALLDOS	Write

	; Write datas
	lea	CoderID(pc),a0
	move.l	SHandle2,d1
	move.l	Memory,d2
	add.w	Length(a0),d2
	move.l	FileLength,d3
	sub.w	Length(a0),d3
	CALLDOS	Write
	cmp.l	d0,d3
	bne	WriteError

	move.l	OutputHandle,d1
	move.l	#Text15,d2
	move.l	#Text16-Text15,d3
	CALLDOS	Write
	bra CloseDestination

Loop7:	move.l	OutputHandle,d1
	move.l	#Text16,d2
	move.l	#Text17-Text16,d3
	CALLDOS	Write
		
CloseDestination:
	move.l	SHandle2,d1
	CALLDOS	Close

CloseMemory:
	move.l	FileLength,d0
	movea.l	Memory,a1
	CALLEXEC FreeMem

CloseSourceFile:
	move.l	SHandle1,d1
	CALLDOS	Close

CloseDosLib:
	move.l	OutputHandle,d1
	move.l	#Text17,d2
	move.l	#Text18-Text17,d3
	CALLDOS	Write

	movea.l	_DOSBase,a1
	CALLEXEC CloseLibrary

CloseCoderLib:
	movea.l	_CoderBase,a1
	CALLEXEC CloseLibrary

LibraryError:
	moveq #0,d0
	rts

; *********** Errors ***********

SourceFileError:
	move.l	OutputHandle,d1
	move.l	#ErrorText1,d2
	move.l	#ErrorText2-ErrorText1,d3
	CALLDOS	Write
	bra	CloseDosLib

MemoryError:
	move.l	OutputHandle,d1
	move.l	#ErrorText2,d2
	move.l	#ErrorText3-ErrorText2,d3
	CALLDOS	Write
	bra	CloseSourceFile

ReadError:
	move.l	OutputHandle,d1
	move.l	#ErrorText3,d2
	move.l	#ErrorText4-ErrorText3,d3
	CALLDOS	Write
	bra	CloseMemory

VersionError:
	move.l	OutputHandle,d1
	move.l	#ErrorText4,d2
	move.l	#ErrorText5-ErrorText4,d3
	CALLDOS	Write
	bra	Loop7
	
NoFileHeader:
	move.l	OutputHandle,d1
	move.l	#ErrorText5,d2
	move.l	#ErrorText6-ErrorText5,d3
	CALLDOS	Write
	bra	Loop7

DestinationError:
	move.l	OutputHandle,d1
	move.l	#ErrorText6,d2
	move.l	#ErrorText7-ErrorText6,d3
	CALLDOS	Write
	bra	CloseMemory

WriteError:
	move.l	OutputHandle,d1
	move.l	#ErrorText7,d2
	move.l	#ErrorText8-ErrorText7,d3
	CALLDOS	Write
	bra	CloseDestination

; *********** Datas ***********

_DosName:	DOSNAME
_DOSBase:	dc.l 0
_CoderName:	CODERNAME
_CoderBase:	dc.l 0

OutputHandle:	dc.l 0
InputHandle:	dc.l 0
SHandle1:	dc.l 0
SHandle2:	dc.l 0

FileLength:	dc.l 0
Memory:		dc.l 0
FuncTable:	dc.l 0

CoderID:	dc.b 0,0
		dc.w 0

Source:		ds.b 82
Destination:	ds.b 82
Codeword:	ds.b 162

Text1:		dc.b 12
		GotoXY 2,2
		dc.b 'This program decodes crypted files of the MasterCoder'
		GotoXY 2,3
		dc.b 'using coder.library '
Text2:		GotoXY 4,5
		dc.b 'Please enter the name of a coded file: '
Text3:		GotoXY 4,6
		dc.b 'Loading file...'
Text4:		GotoXY 4,7
		dc.b 'Decoding protected AmigaBasic file! Please wait...'
Text5:		GotoXY 4,7
		dc.b 'Please enter codeword: '
Text6:		GotoXY 4,8
Text7:		dc.b 'Decoding file with '
Text8:		dc.b 'Code! Please wait...'
Text9:		dc.b 'Decoding file! Please wait...'
Text10:		dc.b 'OK',10
Text11:		dc.b 'ERROR!',10
Text12:		GotoXY 6,7
		Color 1,33,42
Text13:		GotoXY 4,10
		dc.b 'Please enter name of destination file: '
Text14:		GotoXY 4,11
		dc.b 'Writing...'
Text15:		GotoXY 4,12
		dc.b 'Datas were saved!',10
Text16:		GotoXY 6,10
		Color 1,33,42
		dc.b 'Datas weren',39,'t saved!',10
Text17:		Color 0,31,40
Text18:		even

ErrorText1:	GotoXY 6,6
		Color 1,33,42
		dc.b 'Error: I can',39,'t open file!',10,10
ErrorText2:	GotoXY 6,6
		Color 1,33,42
		dc.b 'Not enough memory to load file!',10,10
ErrorText3:	GotoXY 6,7
		Color 1,33,42
		dc.b 'Error while reading!',10,10
ErrorText4:	dc.b 'File is of a higher version!',10
ErrorText5:	dc.b 'This file isn',39,'t a file of MasterCoder',10
ErrorText6:	GotoXY 6,11
		Color 1,33,42
		dc.b 'Error! I can',39,'t open destination file!',10
ErrorText7:	GotoXY 6,12
		Color 1,33,42
		dc.b 'Error while writing!',10
ErrorText8:
