*******************************************************************************
* Scan_Diz					   Copyright İ 1994 2-Cool/EX4!
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Release	: 0.1 $
* $Revision	: 1.01 $
* $Date		: 12-Jan-94 $
*
* $Author(s)	: Written by 2-Cool/EX4! (In MC680x0 Assembly under Asm-One)
* $Note(s)	: Position Independacy off a4 - (WARNING: DON`T TRASH A4!)
*		: Execbase Ptr is cached so that if running in fastmem access
*		: to execbase ptr is faster.
*
* $Purpose	: For calculating the checksum of a file to see if its been
*		: either corrupted or modified by some lamers like fish, etc.
*		: trying to rip off your work...
*******************************************************************************
AbsExecBase	=	4			/* Execbase Definition */
SUCCESS		=	0			/* result return codes... */
VAR_ERROR	=	1			/* memory alloction failcode */
CSI		=	$1b
CLS		macro
		dc.b	CSI,'c',LF
		endm
		
*-------------- Definition Includes...

		incdir	_include:
		include	exec/exec.i
		include	"include:exec/funcdef.i"
		include	intuition/intuition.i
		include	graphics/videocontrol.i
		include	libraries/asl.i
		include	libraries/gadtools.i
		include	libraries/dos_lib.i
		include	libraries/intuition_lib.i
		include	libraries/graphics_lib.i
		include	libraries/exec_lib.i
		include	libraries/asl_lib.i
		include	libraries/icon_lib.i
		include	libraries/diskfont_lib.i
		include	libraries/gadtools_lib.i
		include	libraries/wb_lib.i
		include	libraries/rexxsyslib_lib.i
		include	libraries/utility_lib.i
		include	libraries/dosextens.i
		include	utility/tagitem.i
		include	dos/datetime.i
		include	libraries/reqtools.i
		
*-------------- Definition of Main Variables (Public) Block...

		STRUCTURE VarsBlock,0

		APTR	_ExecBase			/* ExecBase base */
		APTR	_DOSBase			/* DOS lib base */
		APTR	_DOSOutput			/* DOS output base */
		APTR	_ArgPtr
		APTR	_ArgPtr2
		ULONG	_ArgLen

		APTR	ProgBuff			/* ptr to progbuffer */
		APTR	ProgHandle			/* ptr to filehandle */
		ULONG	ProgSize			/* length file */

		APTR	DizStart
		APTR	DizEnd
		APTR	DizSize

		LABEL	vars_SIZEOF

*-------------- Definition of Macros...

PUSH		macro
		movem.l	\1,-(sp)
		endm
PULL		macro
		movem.l	(sp)+,\1
		endm
PUSHW		macro
		movem.w	\1,-(sp)
		endm
PULLW		macro
		movem.w	(sp)+,\1
		endm
PUSHR		macro
		move.l	\1,-(sp)
		endm
PULLR		macro
		move.l	(sp)+,\1
		endm
CALL		macro
		jsr	_LVO\1(a6)
		endm
CALLJ		macro
		jmp	_LVO\1(a6)
		endm
CALLREL		macro
		move.l	\2(a4),a6
		CALL	\1
		endm
		
*******************************************************************************
*-------------- Allocate our Variables (RS.) Area

ProgStart:	move.l	a0,a5
		move.l	d0,d5

		move.l	#vars_SIZEOF,d0		;length for our variables
		move.l	#MEMF_PUBLIC+MEMF_CLEAR,d1 ;we want public mem, cleared
		move.l	(AbsExecBase).w,a6	;get SysBase
		CALL	AllocMem		;allocate it...
		move.l	d0,a4			;ptr to our RS.Variables base
		bne.s	RSValid			;did the alloc fail, if so exit
		moveq	#VAR_ERROR,d0		;Memory allocation fail code
		rts				;exit to dos...

*-------------- From here a4 points to our variables area (DON`T DESTROY A4!)

RSValid:	move.l	a6,(a4)			;cache execptr in Public so if
		move.l	a5,_ArgPtr(a4)
		move.l	d5,_ArgLen(a4)
		sf.b	-1(a5,d5.w)		;null terminate arg string..

*-------------- Open DOS Library

		moveq	#0,d0			;set lib version
  		lea	Dosname(pc),a1		;lib name in a1
  		CALL	OpenLibrary		;try to open library
  		move.l	d0,_DOSBase(a4)		;store lib base
  		beq.w	ShutDown		;cleanup and quit if fail

*-------------- Get DOS Output

		move.l	d0,a6			;get dosbase
		CALL	Output			;get output base
		move.l	d0,_DOSOutput(a4)	;save outputbase

*-------------- Program starts here

		lea	About.Txt(pc),a0		;format string
		bsr.w	OSPutStr

		move.l	_ArgPtr(a4),a0
		move.b	(a0)+,d0		;we are in fastmem were faster
		cmp.b	#"e",d0
		beq.s	do_extract
		cmp.b	#"a",d0
		beq.w	no_adding

*-------------- check for extracting...

do_extract:	cmp.b	#"?",(a0)
		bne.s	no_usage

		lea	Args.Txt(pc),a0		;format string
		bsr.w	OSPutStr
		bra.w	ShutDown
		
no_usage:	tst.b	(a0)+
		move.l	a0,a1
		move.l	_ArgLen(a4),d1
.findname:	cmp.b	#" ",(a1)+
		beq.s	found
		subq.l	#1,d1
		bne.s	.findname

		lea	Args.Txt(pc),a0		;format string
		bsr.w	OSPutStr
		bra.w	ShutDown

found		tst.b	-(a1)
		sf.b	(a1)+
		move.l	a1,_ArgPtr2(a4)

		
		bsr.w	LoadDOSFile
		cmp.b	#-2,d0
		beq.w	LoadFailedMem		;load 'express failed'
		cmp.b	#-1,d0
		beq.w	LoadNotFound

		lea	Scan.txt(pc),a0		;format string
		bsr.w	OSPutStr

*-------------- Search for Diz Start

		move.l	ProgBuff(a4),a0		;start adr
		move.l	a0,a1
		add.l	ProgSize(a4),a1		;end adr
		lea	StartDiz.txt(pc),a2	;string to find
		bsr.w	FindString
		bne.w	StartDiz_Error

		lea	18(a0),a0		;skip header
		move.l	a0,DizStart(a4)		;start of description found?

*-------------- Search for Diz End

		lea	EndDiz.txt(pc),a2
		bsr.w	FindString
		bne.w	EndDiz_Error
		move.l	a0,DizEnd(a4)		;end of description found?

		sub.l	DizStart(a4),a0
		move.l	a0,DizSize(a4)

		cmp.l	#512,a0		;description over 1k??
		beq.w	DizSize_TooBig

*-------------- Copy File_ID Diz to destination buffer

		move.l	a0,d0
		move.l	DizStart(a4),a1		;memadr
		move.l	_ArgPtr2(a4),a0
*-------------- Program ends here

*-------------- d0=length
*		a0=filename
*		a1=mem adr
		bsr	SaveMem2File
		cmp.b	#1,d0			;d0.l = result-code..
		beq.w	SaveError

		lea	FoundDiz.txt(pc),a0		;format string
		bsr.w	OSPutStr

		move.l	DizStart(a4),a0		;memadr
		move.l	DizSize(a4),d0
		sf.b	(a0,d0.w)
		bsr.w	OSPutStr

		lea	Done.txt(pc),a0		;format string
		bsr.w	OSPutStr

*******************************************************************************
* Shutdown() - Free all allocated resources & exit program
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Frees all previously allocated resources, sanity checks are made so only
* allocated memory/open libraries will be removed.
*******************************************************************************
*-------------- Free DOS Library

ShutDown:	bsr	FreeDOSFile

		move.l	_DOSBase(a4),d0		;dos lib base in a1
		beq.s	RSFreeMem
		move.l	d0,a1
 	 	CALL	CloseLibrary		;close intuition
		clr.l	_DOSBase(a4)		;clear out base
		
*-------------- Free RS Variables Area

RSFreeMem:	move.l	a4,a1			;ptr to our RS.Variables base
		move.l	#vars_SIZEOF,d0		;no. of bytes to free
		move.l	(a4),a6			;get execbase
		CALL	FreeMem			;free the memory

		moveq	#SUCCESS,d0		;no return code
		rts				;exit...

*******************************************************************************
* OSPutStr
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Sends a ascii text string to current console output
* 
* $Inputs:	a0.l = String ptr (null terminated)
*******************************************************************************

OSPutStr:	move.l	a0,d2
		moveq	#-1,d3			;d4=0
.getlen2	addq.l	#1,d3			;increase string length by 1
		tst.b	(a0)+			;increase position
		bne.s	.getlen2		;nope not found, so keep on

		move.l	_DOSOutput(a4),d1
		move.l	_DOSBase(a4),a6
		jmp	_LVOWrite(a6)		;print error msg to cli


*******************************************************************************
* _LoadDOSFile :- Loads an AmigaDOS file from any device into memory
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 (.L)	= Filename
*
* OUTPUTS:	d0 (.L) = Result Code (0=File Ok,-1=Load Failed!)	
*		d1 (.L) = Length
*******************************************************************************
	
LoadDOSFile:	movem.l	d2-d7/a0-a6,-(sp)
		clr.l	ProgHandle(a4)
		clr.l	ProgBuff(a4)
		clr.l	ProgSize(a4)

;-------------- Open file
		move.l	a0,d1			;get filename
		move.l	#MODE_OLDFILE,d2
		move.l	_DOSBase(a4),a6
		jsr	_LVOOpen(a6)		;open file
		move.l	d0,ProgHandle(a4)
		beq.s	NotFound

;-------------- Get Length of file

		move.l	d0,d5			;ProgHandle
		move.l	d5,d1			;file handle
		moveq	#0,d2
		moveq	#1,d3
		move.l	_DOSBase(a4),a6
		jsr	_LVOSeek(a6)		;seek start of file
		move.l	d5,d1			;file handle
		moveq	#0,d2
		moveq	#-1,d3
		jsr	_LVOSeek(a6)		;seek end of file
		move.l	d0,ProgSize(a4)

;-------------- Allocate Memory for file

		move.l	4.w,a6			;get execbase
		move.l	#MEMF_PUBLIC,d1		;we want public mem
		CALL	AllocMem		;allocate it...
		move.l	d0,ProgBuff(a4)		;save base
		beq.b	TooBig			;fail?

;-------------- Load in whole file
				
		move.l	ProgHandle(a4),d1
		move.l	d0,d2
		move.l	ProgSize(a4),d3
		move.l	_DOSBase(a4),a6
		jsr	_LVORead(a6)		;read file

;-------------- Close file

CloseFile:	move.l	ProgHandle(a4),d1
		jsr	_LVOClose(a6)		;close file

		move.l	ProgSize(a4),d1	;d1=ProgSize
		move.l	ProgBuff(a4),a1		

		movem.l	(sp)+,d2-d7/a0-a6
		moveq	#0,d0			;resultcode (okay)
		rts

NotFound:	movem.l	(sp)+,d2-d7/a0-a6
		move.b	#-1,d0			;file not found error-code
		rts

TooBig:
		move.l	ProgHandle(a4),d1
		move.l	_DOSBase(a4),a6
		jsr	_LVOClose(a6)		;close file
		movem.l	(sp)+,d2-d7/a0-a6
		move.b	#-2,d0			;file too big error-code
NotAlloc	rts

;-------------- Free Memory for DOSFile

FreeDOSFile:	move.l	(AbsExecBase).w,a6	;get execbase
		move.l	ProgBuff(a4),d0		;ptr to our RS.Variables base
		move.l	d0,a1
		beq.s	NotAlloc
		move.l	ProgSize(a4),d0		;no. of Bytes to free
		beq.s	NotAlloc
		jmp	_LVOFreeMem(a6)		;free the memory

*******************************************************************************
* SaveMem2File
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	a0.l	= Filename
*		a1.l	= Mem Address
*		d0.l	= Save Length
*
* $Outputs:	d0.l	= 0 - success
*		d0.l	= 1 - failure
*******************************************************************************

SaveMem2File:	movem.l	d2-d7/a0-a6,-(sp)
		move.l	a0,d1			;filename
		move.l	a1,d5			;progbuffer
		move.l	d0,d6			;proglength
		move.l	#MODE_NEWFILE,d2
		move.l	_DOSBase(a4),a6
		jsr	_LVOOpen(a6)
		move.l	d0,d7
		beq.b	_SaveError
		move.l	d7,d1			;fh...
		move.l	d5,d2			;adr
		move.l	d6,d3			;length
		jsr	_LVOWrite(a6)		;write file
		move.l	d7,d1
		jsr	_LVOClose(a6)		;close file
		movem.l	(sp)+,d2-d7/a0-a6
		moveq	#0,d0
		rts
_SaveError:	movem.l	(sp)+,d2-d7/a0-a6
remcode		moveq	#1,d0
		rts

LoadFailedMem	lea	ErrorMem.txt(pc),a0
		bra.s	OSPut
LoadNotFound	lea	ErrorLoad.txt(pc),a0
		bra.s	OSPut
EndDiz_Error:
StartDiz_Error:
DizSize_TooBig
NoDiz:		lea	NoDiz.txt(pc),a0
		bra.s	OSPut
no_adding:	lea	NoAdd.txt(pc),a0
		bra.s	OSPut
SaveError	lea	ErrorSave.txt(pc),a0
OSPut		bsr.w	OSPutStr
		bra	ShutDown


*******************************************************************************
* FindString
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* This routine will scan through Memory for a ascii (case dependant) string.
* The routine will not find its 'search string' if the start and end addresses 
* are within the same address range as an added precaution.
*
* INPUTS ;	a0.l=start address for search
*	 	a1.l=end address for search
*	 	a2.l=string to search for
*
* OUTPUTS;	d0.b=If failed to located string =$FF.B, else =$00.B FOUND!
*		a0.l=ptr to string
*******************************************************************************

FindString:	movem.l	a1-a6,-(sp)
		subq.l	#4,a0
		bsr.s	Search
		movem.l	(sp)+,a1-a6
		rts

cmp4bytesd2:	macro
		cmp.b	(a0)+,d2		;do these 4 bytes match source?
		beq.s	\1
		cmp.b	(a0)+,d2		;do these 4 bytes match source?
		beq.s	\1
		cmp.b	(a0)+,d2		;do these 4 bytes match source?
		beq.s	\1
		cmp.b	(a0)+,d2		;do these 4 bytes match source?
		beq.s	\1
		endm
cmp32bytes	macro
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		cmp4bytesd2 .yup
		bra.s	\1
.yup:		move.l	d4,d3
.cmp:		cmpm.b	(a2)+,(a0)+
		dbne	d3,.cmp
		bne.w	_Not_It
		sub.l	d6,a0
		rts
		endm

Search:		move.l	a2,a3
		moveq	#-3,d4			;d4=0
.getlen		addq.l	#1,d4			;increase string length by 1
		tst.b	(a2)+			;increase position
		bne.s	.getlen			;nope not found, so keep on
		move.l	a3,a2
		move.l	d4,d6
		addq.l	#2,d6
		moveq	#0,d5			;d5=0
		move.b	(a2)+,d2
_Not_It		move.l	a3,a2			;a3=search string ptr
		tst.b	(a0)+			;incr search pos
		tst.b	(a2)+
_contt		lea	-512(a1),a4		;>512 bytes left to search?
		cmp.l	a4,a0
		blt.s	fastcmp			;if so do a 512 byte search...
_cmpcontt	cmp.b	(a0)+,d2		;does this byte match string byte?
		beq.s	_nbyte			;yes!,lets investigate more...
		cmp.l	a1,a0			;end of Memory region reached?
		blt.s	_cmpcontt		;yes,so string wasn`t found!
		st	d0			;d0=not found!
		rts
_nbyte:		move.l	d4,d3
_nloop:		cmpm.b	(a2)+,(a0)+
		dbne	d3,_nloop
		bne.s	_Not_It
		sub.l	d6,a0
		rts
fastcmp		cmp32bytes _1			;test 512 Bytes FAAAAST
_1		cmp32bytes _2
_2		cmp32bytes _3
_3		cmp32bytes _4
_4		cmp32bytes _5
_5		cmp32bytes _6
_6		cmp32bytes _7
_7		cmp32bytes _8
_8		cmp32bytes _9
_9		cmp32bytes _10
_10		cmp32bytes _11
_11		cmp32bytes _12
_12		cmp32bytes _13
_13		cmp32bytes _14
_14		cmp32bytes _15
_15		cmp32bytes _16
_16		cmp.l	a4,a0
		blt.w	fastcmp
		bra.w	_cmpcontt

StartDiz.txt:	dc.b	"@BEGIN_FILE_ID.DIZ",0
		even
EndDiz.txt:	dc.b	"@END_FILE_ID.DIZ",0
		even		
******************************************************************************
* String & Data Variable definitions

Dosname:	dc.b	'dos.library',0				;dos lib name
		even
ErrorAlloc.txt	dc.b	$a,'Error: Out of Memory!',$a,0
		even
ErrorMem.txt	dc.b	$a,'Error: Not enough memory to load file!',$a,0
		even
ErrorLoad.txt	dc.b	$a,'Error: Cannot open file!',$a,$a,0
		even
ErrorSave.txt	dc.b	$a,'Error: Cannot save file!',$a,$a,0
		even
Scan.txt:	dc.b	'Scanning for file_id in file...',$a,$a,0
		even
NoAdd.txt:	dc.b	'Sorry, Adding of "FILE.ID_DIZ" not yet supported!',$a,$a,0
		even
FoundDiz.txt:	dc.b	'Found a file_id in file, viewing;',$a,$a,0
		even
NoDiz.txt:	dc.b	$a,'Sorry, this textfile does not contain a vaild "file_id.diz" description!',$a,$a,0
		even
Done.txt:	dc.b	$a,$a,'Operation Successful!',$a,$a,0
		even
About.Txt:	CLS	; clear screen
		dc.b	CSI,'[0m',CSI,'[1mTXTExtract v0.1',CSI,'[0m ',CSI,'[33m(Turbo Version) ',CSI,'[0m',CSI,'[3mBy 2-Cool/EX4!',LF
		dc.b	CSI,'[0mCopyright EX4 İ 1993-94. All Rights Are Reserved.',LF
		dc.b	'Last Assembled: 18-Oct-94.',LF
		dc.b	$a
		dc.b	0
		even
Args.Txt:	dc.b	'Usage   : ',CSI,'[32mTXTExtract ',CSI,'[31m<opt> <src> <dest>',LF
		dc.b	'Example : ',CSI,'[32mTXTExtract ',CSI,'[31me lsd-suxx.txt bbs:file_id.diz',LF,LF
		dc.b	'        : Where <opt> is <e>xtract description.',LF
		dc.b	'        :             or <a>dd description.',LF,LF
		dc.b	0
