*******************************************************************************
* DMS-Checker/Adder v1.0 (Pro-DMS-Checker)
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* A simple DMS file Checksum checker/adder, checks if the dms file is valid
* and free from DMS-CRC Errors. This checker validates;
*
* ğ DMS Info Header_ID
* ğ DMS Info Header CRC`s
* ğ Individual Track Header_ID`s
* ğ Individual Track Header CRC`s
* ğ Individual Track Data CRC`s
*
* It does *NOT* however check the CRC`s for Unpacked Track Data. This would
* require decompression of the entire track which would take considerable time
* The checking that is done however should be sufficient for 99% of cases of
* bad dms-files...
*******************************************************************************
_LVOOpen		=	-$1E
_LVORead		=	-$2A
_LVOFreeMem		=	-$D2
_LVOCloseLibrary	=	-$19E
_LVOExamine		=	-$66
_LVOCacheClearU		=	-$27C
_LVOUnLock		=	-$5A
_LVOOutput		=	-$3C
_LVOWrite		=	-$30
_LVODeleteFile		=	-$48
_LVOOpenLibrary		=	-$228
_LVORename		=	-$4E
_LVOAllocMem		=	-$C6
_LVOClose		=	-$24
_LVOLock		=	-$54

AbsExecBase		=	$4
AttnFlags		=	$128
MEMF_CLEAR		=	$10000
MEMF_PUBLIC		=	$1
MODE_NEWFILE		=	$3EE
MODE_OLDFILE		=	$3ED
SHARED_LOCK		=	$FFFFFFFE

CALL		macro
		jsr	_LVO\1(a6)
		endm
		
		section	dmscheck,code

ProgStart:	lea	DT,a5			;relative dt-base
		move.l	d0,_ArgLen-DT(a5)
		move.l	a0,_ArgPtr-DT(a5)
		move.l	sp,_OldStack-DT(a5)
		bsr.w	OpenDOS

*-------------- Show info about DMS checker..

		bsr.w	ParseArgs		;read CLI Arguments

*-------------- Attempt to load the whole DMS into memory...

		bsr.w	LoadDMSFile
		tst.l	d0
		beq.s	DMSFileOpen.fail

*-------------- Attempt to load DMS Banners to add into memory...

		bsr.w	LoadBanners
		bsr.w	CheckDMSFile
		tst.l	d0
		beq.s	ShutDown

*-------------- Actually add them to the dms file...

		bsr.w	AddBanners
		tst.l	d0
		beq.s	ShutDown

*-------------- Save the new DMS back to disk...

		bsr.w	WriteNewDMS
		bra.s	ShutDown

DMSFileOpen.fail:
		lea	LoadErr.txt(pc),a0
		bsr.w	OSPutStr
		bra.w	ShutDown

ShutDown:	move.l	(AbsExecBase).w,a6
		move.l	_TotalBnrSize-DT(a5),d0
		beq.s	FreeFrontMem
		move.l	_TotalBnPt-DT(a5),a1
		CALL	FreeMem

FreeFrontMem:	move.l	_FrontMemSize-DT(a5),d0
		beq.s	FreeZeroMem
		move.l	_FrontMemPt-DT(a5),a1
		CALL	FreeMem

FreeZeroMem:	move.l	_ZeroMemSize-DT(a5),d0
		beq.s	FreeRearMem
		add.l	#64,d0
		move.l	_ZeroMemPt-DT(a5),a1
		CALL	FreeMem

FreeRearMem:	move.l	_RearMemSize-DT(a5),d0
		beq.s	FreeDMSMem
		move.l	_RearMemPt-DT(a5),a1
		CALL	FreeMem

FreeDMSMem:	move.l	_DMSFileSize-DT(a5),d0
		beq.s	ExitPrg
		move.l	_DMSMemPt-DT(a5),a1
		CALL	FreeMem

ExitPrg:	move.l	_OldStack-DT(a5),sp
		bsr.s	CloseDOS
		moveq	#0,d0
		rts

DOSReturnCode:	moveq	#10,d0
		rts

OpenDOS:	movem.l	d0-d7/a0-a6,-(sp)
		move.l	(AbsExecBase).w,a6
		lea	DOSName(pc),a1
		moveq	#0,d0
		CALL	OpenLibrary
		move.l	d0,_DOSBase-DT(a5)
		beq.s	DOSError
		move.l	d0,a6
		CALL	Output
		move.l	d0,_Output-DT(a5)
		movem.l	(sp)+,d0-d7/a0-a6
		rts

DOSError:	movem.l	(sp)+,d0-d7/a0-a6
		move.l	(sp)+,d0
		bra.s	DOSReturnCode

CloseDOS:	movem.l	d0-d7/a0-a6,-(sp)
		move.l	(AbsExecBase).w,a6
		move.l	_DOSBase-DT(a5),d0
		beq.s	NoDOS
		move.l	d0,a1
		CALL	CloseLibrary
NoDOS:		movem.l	(sp)+,d0-d7/a0-a6
		rts

OSPutStr:	movem.l	d0-d7/a0-a6,-(sp)
		move.l	_Output-DT(a5),d1
		move.l	a0,d2
		moveq	#0,d3
.getlen:	addq.w	#1,d3
		tst.b	(a0)+
		bne.s	.getlen
		subq.w	#1,d3
		move.l	_DOSBase-DT(a5),a6
		CALL	Write
		movem.l	(sp)+,d0-d7/a0-a6
		rts

ParseArgs:	movem.l	d0-d7/a0-a6,-(sp)
		move.l	_ArgLen-DT(a5),d1
		move.l	_ArgPtr-DT(a5),a0
		clr.b	-1(a0,d1.w)
		cmp.l	#1,d1
		beq.s	ShowUsage

		moveq	#0,d7
		cmp.b	#'-',(a0)
		bne.s	SetFlags

		addq.w	#1,a0
ArgLoop:	subq.w	#1,d1
		move.b	(a0)+,d0
		cmp.b	#' ',d0
		beq.s	ArgsDone
		cmp.b	#'b',d0
		bne.s	CheckFront
		bset	#0,d7
		bra.s	ArgLoop

CheckFront:	cmp.b	#'f',d0
		bne.s	CheckTrk0Add
		bset	#2,d7
		bra.s	ArgLoop

CheckTrk0Add:	cmp.b	#'t',d0
		bne.s	__ShowUsage
		bset	#3,d7
		bra.s	ArgLoop

__ShowUsage:	bra.s	ShowUsage

ArgsDone:	tst.b	d7
		beq.s	ShowUsage

		subq.w	#2,d1
		tst.w	d1
		beq.s	ShowUsage

SetFlags:	move.b	d7,_BnrFlags-DT(a5)
		move.l	a0,_FilenamePt-DT(a5)
		movem.l	(sp)+,d0-d7/a0-a6
		rts

ShowUsage:	lea	Usage.txt(pc),a0
		bsr.w	OSPutStr

		movem.l	(sp)+,d0-d7/a0-a6
		addq.w	#4,sp
		bra.w	ShutDown

LoadDMSFile:	movem.l	d1-d7/a0-a6,-(sp)

		lea	Loading.txt(pc),a0
		bsr.w	OSPutStr
		move.l	_FilenamePt-DT(a5),a0
		bsr.w	OSPutStr

		move.l	_FilenamePt-DT(a5),a0
		moveq	#0,d0
		bsr.w	LoadFile
		tst.l	d0
		beq.s	LoadDMSFailed

		move.l	d0,_DMSFileSize-DT(a5)
		move.l	a0,_DMSMemPt-DT(a5)
		lea	Ok.txt(pc),a0
		bsr.w	OSPutStr

		moveq	#1,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

LoadDMSFailed:	moveq	#0,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

LoadBanners:	movem.l	d0-d7/a0-a6,-(sp)
LoadFrntBanner:	btst	#2,_BnrFlags-DT(a5)
		beq.s	LoadTrk0Banner

		lea	FrntFilename.txt(pc),a0
		moveq	#0,d0
		bsr.w	LoadFile
		tst.l	d0
		bne.s	FrontOk

		bclr	#2,_BnrFlags-DT(a5)
		bra.s	LoadTrk0Banner

FrontOk:	move.l	a0,_FrontMemPt-DT(a5)
		move.l	d0,_FrontMemSize-DT(a5)
LoadTrk0Banner:	btst	#3,_BnrFlags-DT(a5)
		beq.s	noban2

		lea	Trk0Filename.txt(pc),a0
		moveq	#1,d0
		bsr.w	LoadFile

		tst.l	d0
		bne.s	CheckLength

		bclr	#3,_BnrFlags-DT(a5)
		bra.s	noban2

CheckLength:	cmp.l	#960,d0
		beq.s	ZeroOk

		move.l	(AbsExecBase).w,a6
		add.l	#64,d0
		move.l	a0,a1
		CALL	FreeMem

		lea	NoTrkZeroAdd.txt(pc),a0
		bsr.w	OSPutStr

		bclr	#3,_BnrFlags-DT(a5)
		bra.s	noban2

ZeroOk:		move.l	a0,_ZeroMemPt-DT(a5)
		move.l	d0,_ZeroMemSize-DT(a5)
		move.l	#('DOS'<<8),(a0)
		add.l	d0,a0

		lea	AboutADDY.txt(pc),a1
		moveq	#16-1,d0
IncludeInfo:	move.l	(a1)+,(a0)+
		dbra	d0,IncludeInfo

noban2:		btst	#0,_BnrFlags-DT(a5)
		beq.s	ExitLoadBanners

		lea	RearFilename.txt(pc),a0
		moveq	#0,d0
		bsr.w	LoadFile
		tst.l	d0
		bne.s	RearOk

		bclr	#0,_BnrFlags-DT(a5)
		bra.s	ExitLoadBanners

RearOk:		move.l	a0,_RearMemPt-DT(a5)
		move.l	d0,_RearMemSize-DT(a5)
ExitLoadBanners:
		movem.l	(sp)+,d0-d7/a0-a6
		rts

*******************************************************************************
* DMS-Track CRC Error Checking Procedure...
*******************************************************************************
;// Definitions of the DMS-Info Header

		rsreset
identifier:	rs.l	1	/* type eg; "FILE" or " PRO"
Infobits        rs.l	1	/* General Purpose flags */
timestamp:	rs.l	1	/* When archive was created */
lowtrack:	rs.w	1	/* Low track in Archive */
hightrack:	rs.w	1	/* High track in Archive */
info_plength:	rs.l	1	/* Total Packed bytes */
info_ulength:	rs.l	1	/* Total UnPacked bytes (of disk) */
OS_Version:	rs.w	1	/* Amiga OS Version used */
OS_Revision:	rs.w	1	/* Amiga OS Revision used */
cpu:		rs.w	1	/* CPU type of machine (680xx, 80x86, etc...) */
cpuco:		rs.w	1	/* CPU coprocessor (68881, 8087, ...) */
machine:	rs.w	1	/* Machine of creator (Amiga, ST, IBM, etc...) */
mextra:		rs.w	1	/* Extra ID information (Machine Specific) */
speed:		rs.w	1	/* CPU speed index (Approximate) */
timecreate:	rs.l	1	/* Time it took to create archive */
version_made_by:rs.w	1	/* What version created it */
version_needed:	rs.w	1	/* What version is needed to extract it */
disktype:	rs.w	1	/* Disk type of archive */
info_cmode:	rs.w	1	/* Compression mode (generally) used */
info_hdrsum:	rs.w	1	/* Header checksum */
INFO_HDR_Size:	rs.w	0

;// Definitions of the DMS-Track Header
		
		rsreset
ident:		rs.w	1	/* "TR" identification */
track:		rs.w	1	/* track number */
flags:		rs.w	1	/* General flags */
plength:	rs.w	1	/* actual packed length */
rlength:	rs.w	1	/* packed pre-RLE length */
ulength:	rs.w	1	/* unpacked length */
cflag:		rs.b	1	/* general purpose compression flag */
cmode:		rs.b	1	/* compression mode used */
checksum:	rs.w	1	/* checksum of unpacked bytes */
datasum:	rs.w	1	/* Data Checksum */
hdrsum:		rs.w	1	/* Header Checksum */
tr_data:	rs.w	0	/* actual tr_data */
TR_HDR_Size:	rs.w	0
		rsreset

CheckDMSFile:	movem.l	d1-d7/a0-a6,-(sp)
		move.l	_DMSFileSize-DT(a5),a1
		move.l	_DMSMemPt-DT(a5),a0	;a0=ptr to dms buffer
		add.l	a0,a1			;a1=end of dms buffer
		lea	_TmpBuff-DT(a5),a4

*-------------- Check DMS-Info Header_ID

		cmp.l	#'DMS!',(a0)+		;skip past to the structure..
		bne.s	NotDMSErr

*-------------- Check DMS-Info Header Checksum

		moveq	#INFO_HDR_Size-2,d0
		bsr.w	DMSCheckCRC		;calculate DMS Info Header
		cmp.w	info_hdrsum(a0),d0	;check header info is okay..
		bne.s	BadInfoErr

*-------------- Skip Info header to get to Track_structure

		lea	INFO_HDR_Size(a0),a0	;skip info part..
		sub.l	a3,a3
		moveq	#0,d2

CheckTrkLoop:	cmp.l	a1,a0		;end of dms buffer?
		bge.s	CheckDone	;we have done our job.. lets exit..

*-------------- (TR) TRACK_DATA CRC Checking Phase..
		
		cmp.w	#'TR',(a0)		;check track_header (id_hd)
		bne.s	TrackHdErr
		move.w	track(a0),d0		;get track no.
		bne.s	noid

*-------------- Get track info for kill/add... if its a TEXT type track

		move.l	a4,a3
noid:		move.w	d0,(a4)+		;save trk no.
		move.l	a0,(a4)+		;header ptr
		move.w	plength(a0),(a4)	;cmode packed
		add.w	#20,(a4)+

*-------------- Calculate Header_CRC

		moveq	#TR_HDR_Size-2,d0	;length of checksum (headerlen)
		bsr.s	DMSCheckCRC
		cmp.w	hdrsum(a0),d0		;compare header crc (hcrc)
		bne.s	TrkHdCorruptErr

*-------------- Calculate Trackdata_CRC

		move.w	plength(a0),d0		;actual packed length
		move.w	datasum(a0),d1		;packed data crc
		lea	tr_data(a0),a0		;a0=ptr to packed data
		move.l	d0,d2
		bsr.s	DMSCheckCRC
		cmp.w	d0,d1			;packed data crc with current
		bne.s	CorruptTrkErr		;is packed track data corrupt?

*-------------- Point to next track

		add.l	d2,a0			;point to next track..
		bra.s	CheckTrkLoop

CheckDone:	move.l	a3,_DMSTrkPt-DT(a5)	;save Last Track Ptr..

*-------------- File Passed CRC_Checking...

		lea	FileOkay.txt(pc),a0
		bsr.w	OSPutStr

		moveq	#1,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts



NotDMSErr:	lea	NotDMS.txt(pc),a0
		bra.s	ShowMsg

BadInfoErr:	lea	InfoHeader.txt(pc),a0
		bra.s	ShowMsg

TrackHdErr:	lea	TrackHdError.txt(pc),a0
		bra.s	ShowMsg

TrkHdCorruptErr:
		lea	TrackHdCorrupt.txt(pc),a0
		bra.s	ShowMsg

CorruptTrkErr:	lea	TrackCorrupt.txt(pc),a0
ShowMsg:	bsr.w	OSPutStr

		moveq	#0,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

*******************************************************************************
* Calculate CRC (16-Bit)
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	d0.l = Length
*		a0.l = Source Ptr.
*
* $Outputs:	d0.l = CRC
*******************************************************************************

DMSCheckCRC:	movem.l	d1/d2/a0/a1,-(sp)
		lea	CRC_TAB(pc),a1
		subq.w	#1,d0
		moveq	#0,d1
		moveq	#8,d3
.calcsum:	moveq	#0,d2
		move.b	(a0)+,d2
		eor.b	d1,d2
		add.w	d2,d2
		lsr.w	d3,d1
		move.w	0(a1,d2.w),d2
		eor.w	d2,d1
		dbra	d0,.calcsum
		move.w	d1,d0
		movem.l	(sp)+,d1/d2/a0/a1
		rts

AddBanners:	movem.l	d1-d7/a0-a6,-(sp)
		moveq	#60,d0
		add.l	_DMSFileSize-DT(a5),d0
		add.l	_FrontMemSize-DT(a5),d0
		add.l	_ZeroMemSize-DT(a5),d0
		add.l	_RearMemSize-DT(a5),d0
		move.l	d0,_TotalBnrSize-DT(a5)
		move.l	(AbsExecBase).w,a6
		moveq	#1,d1
		CALL	AllocMem

		move.l	d0,_TotalBnPt-DT(a5)
		beq.w	NoBnrMemErr

		move.l	d0,a1
		move.l	_DMSMemPt-DT(a5),a0
		moveq	#14-1,d0
.copyheader:	move.l	(a0)+,(a1)+
		dbra	d0,.copyheader

TestFrontAdd:	btst	#2,_BnrFlags-DT(a5)
		beq.s	TestTrk0Add

		move.l	_FrontMemPt-DT(a5),a2
		move.l	_FrontMemSize-DT(a5),d1
		move.l	a2,a0
		move.l	d1,d0
		bsr.s	DMSCheckCRC

		move.l	d0,d6
		move.l	a2,a0
		move.l	d1,d0
		bsr.w	CalcBannerCRC

		move.l	d0,d7
		move.l	a1,a0
		move.w	#'TR',(a1)+
		move.w	#$FFFF,(a1)+
		move.l	d1,(a1)+
		move.w	d1,(a1)+
		move.w	d1,(a1)+
		clr.w	(a1)+
		move.w	d7,(a1)+
		move.w	d6,(a1)+
		moveq	#18,d0
		bsr.w	DMSCheckCRC

		move.w	d0,(a1)+
		subq.w	#1,d1
addcrc_front:	move.b	(a2)+,(a1)+
		dbra	d1,addcrc_front

TestTrk0Add:	btst	#3,_BnrFlags-DT(a5)
		beq.s	CheckRearAdd

		move.l	_ZeroMemPt-DT(a5),a2
		move.l	#1024,d1
		move.l	a2,a0
		move.l	d1,d0
		bsr.w	DMSCheckCRC

		move.l	d0,d6
		move.l	a2,a0
		move.l	d1,d0
		bsr.w	CalcBannerCRC

		move.l	d0,d7
		move.l	a1,a0
		move.w	#'TR',(a1)+
		clr.w	(a1)+
		move.l	d1,(a1)+
		move.w	d1,(a1)+
		move.w	d1,(a1)+
		clr.w	(a1)+
		move.w	d7,(a1)+
		move.w	d6,(a1)+
		moveq	#18,d0
		bsr.w	DMSCheckCRC

		move.w	d0,(a1)+
		subq.w	#1,d1
.byteinsert:	move.b	(a2)+,(a1)+
		dbra	d1,.byteinsert

CheckRearAdd:	move.l	_DMSTrkPt-DT(a5),a0
		cmp.l	#0,a0
		beq.s	GetLastTrack

		move.w	6(a0),d0
		move.l	2(a0),a0
		subq.w	#1,d0
.bytecpy:	move.b	(a0)+,(a1)+
		dbra	d0,.bytecpy

GetLastTrack:	lea	_TmpBuff-DT(a5),a4
findlast_trk:	move.w	(a4)+,d1
		move.l	(a4)+,a0
		move.w	(a4)+,d0
		cmp.l	#0,a0
		beq.s	TestAddRear

		tst.b	d1
		beq.s	findlast_trk

		cmp.w	#$FFFF,d1
		beq.s	findlast_trk

		subq.w	#1,d0
.bytecopy2:	move.b	(a0)+,(a1)+
		dbra	d0,.bytecopy2
		bra.s	findlast_trk

TestAddRear:	btst	#0,_BnrFlags-DT(a5)
		beq.s	TestFreeBnrMem

		move.l	_RearMemPt-DT(a5),a2
		move.l	_RearMemSize-DT(a5),d1
		move.l	a2,a0
		move.l	d1,d0
		bsr.w	DMSCheckCRC

		move.l	d0,d6
		move.l	a2,a0
		move.l	d1,d0
		bsr.s	CalcBannerCRC

		move.l	d0,d7
		move.l	a1,a0
		move.w	#'TR',(a1)+
		move.w	#$FFFF,(a1)+
		move.l	d1,(a1)+
		move.w	d1,(a1)+
		move.w	d1,(a1)+
		clr.w	(a1)+
		move.w	d7,(a1)+
		move.w	d6,(a1)+
		moveq	#18,d0
		bsr.w	DMSCheckCRC

		move.w	d0,(a1)+
		subq.w	#1,d1
.bytecopy4:	move.b	(a2)+,(a1)+
		dbra	d1,.bytecopy4

TestFreeBnrMem:	move.l	_TotalBnPt-DT(a5),a0
		sub.l	a0,a1
		move.l	a1,_TotalBnrNewSize-DT(a5)

		move.l	(AbsExecBase).w,a6
		cmp.w	#37,20(a6)		;Has OS Got Cache Control?
		blt.s	NoFreeCache

		CALL	CacheClearU		;if so Flush`em!

NoFreeCache:	moveq	#1,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

NoBnrMemErr:	lea	NoRemoveAdd.txt(pc),a0
		bsr.w	OSPutStr

		moveq	#0,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

CalcBannerCRC:	movem.l	d1/d2/a0,-(sp)
		subq.w	#1,d0
		moveq	#0,d2
		moveq	#0,d1
.crcmake:	move.b	(a0)+,d1
		add.w	d1,d2
		dbra	d0,.crcmake
		move.l	d2,d0
		movem.l	(sp)+,d1/d2/a0
		rts

WriteNewDMS:	movem.l	d0-d7/a0-a6,-(sp)
		move.l	_FilenamePt-DT(a5),a0
		lea	_TmpBuff-DT(a5),a1
cpy_fname:	move.b	(a0)+,(a1)+
		bne.s	cpy_fname

		move.b	#'.',-1(a1)
		move.b	#'t',(a1)+
		move.b	#'m',(a1)+
		move.b	#'p',(a1)+
		clr.b	(a0)+
		move.l	_DOSBase-DT(a5),a6
		move.l	_FilenamePt-DT(a5),d1
		lea	_TmpBuff-DT(a5),a2
		move.l	a2,d2
		jsr	_LVORename(a6)

		tst.l	d0
		beq.s	_NoRemoveErr

		move.l	_FilenamePt-DT(a5),d1
		move.l	#MODE_NEWFILE,d2
		jsr	_LVOOpen(a6)
		move.l	d0,d7
		beq.s	RenameTmp

		move.l	d7,d1
		move.l	_TotalBnPt-DT(a5),d2
		move.l	_TotalBnrNewSize-DT(a5),d3
		jsr	_LVOWrite(a6)

		move.l	d0,d4
RemClose:	move.l	d7,d1
		jsr	_LVOClose(a6)
		tst.l	d0
		beq.s	RemClose

		cmp.l	d3,d4
		bne.s	ZapTempFile

		lea	_TmpBuff-DT(a5),a1
		move.l	a1,d1
		jsr	_LVODeleteFile(a6)

		movem.l	(sp)+,d0-d7/a0-a6
		rts

ZapTempFile:	move.l	_FilenamePt-DT(a5),d1
		jsr	_LVODeleteFile(a6)

RenameTmp:	lea	_TmpBuff-DT(a5),a1
		move.l	a1,d1
		move.l	_FilenamePt-DT(a5),d2
		jsr	_LVORename(a6)

_NoRemoveErr:	lea	NoRemoveAdd.txt(pc),a0
		bsr.w	OSPutStr
		movem.l	(sp)+,d0-d7/a0-a6
		rts

LoadFile:	movem.l	d1-d7/a1-a6,-(sp)
		move.l	d0,_ExtraMemFlg-DT(a5)
		moveq	#0,d6
		moveq	#0,d5
		moveq	#0,d4
		sub.l	a3,a3
		move.l	a0,d7
		move.l	_DOSBase-DT(a5),a6
		move.l	d7,d1
		moveq	#SHARED_LOCK,d2
		jsr	_LVOLock(a6)
		move.l	d0,d6
		beq.s	OpenError

		move.l	d6,d1
		lea	_DTBase-DT(a5),a4
		move.l	a4,d2
		jsr	_LVOExamine(a6)
		tst.l	d0
		beq.s	OpenError

		move.l	124(a4),d5
		move.l	(AbsExecBase).w,a6
		move.l	d5,d0
		cmp.l	#1,_ExtraMemFlg-DT(a5)
		bne.s	NoExtraParam

		add.l	#64,d0
NoExtraParam:	move.l	#(MEMF_PUBLIC+MEMF_CLEAR),d1
		jsr	_LVOAllocMem(a6)
		tst.l	d0
		beq.s	OpenError

		move.l	d0,a3
		move.l	_DOSBase-DT(a5),a6
		move.l	d7,d1
		move.l	#MODE_OLDFILE,d2
		jsr	_LVOOpen(a6)
		tst.l	d0
		beq.s	OpenError

		move.l	d0,a4
		move.l	a4,d1
		move.l	a3,d2
		move.l	d5,d3
		jsr	_LVORead(a6)
		exg	d0,a4
		move.l	d0,d1
		jsr	_LVOClose(a6)
		cmp.l	d5,a4
		bne.s	OpenError
		moveq	#0,d7
		bsr.s	UnlockFile

		move.l	d5,d0
		move.l	a3,a0
		movem.l	(sp)+,d1-d7/a1-a6
		rts

OpenError:	moveq	#1,d7
		move.l	a3,a1
		cmp.l	#0,a1
		beq.s	UnlockFile
		move.l	d5,d0
		beq.s	UnlockFile

		move.l	(AbsExecBase).w,a6
		jsr	_LVOFreeMem(a6)

UnlockFile:	tst.l	d6
		beq.s	NoLock

		move.l	_DOSBase-DT(a5),a6
		move.l	d6,d1
		jsr	_LVOUnLock(a6)

NoLock:		tst.l	d7
		bne.s	FreeFile
		rts

FreeFile:	moveq	#0,d0
		sub.l	a0,a0
		movem.l	(sp)+,d1-d7/a1-a6
		rts

Usage.txt:		dc.b	$a,'Usage : DMSValid [-<options>] <filename>',$A
			dc.b	'b Add to Rear, f Add to Front, t Add to Trk 0.',$a
			dc.b	$A,$A,0
Loading.txt:		dc.b	$a,'Examining file for DMS Checking...',$a,'Loading... ',0
NotDMS.txt:		dc.b	10,"This is not a DMS file!",$a,0
InfoHeader.txt:		dc.b	10,"Error: Info Header Corrupt!",$a,0
TrackHdError.txt:	dc.b	10,"Error: Track Header Error!",$a,0
TrackHdCorrupt.txt:	dc.b	10,"Error: Track Header Corrupt!",$a,0
TrackCorrupt.txt:	dc.b	10,"Error: Track Data Corrupt!",$a,0
NoRemoveAdd.txt:	dc.b	10,"Note: Skipped Removing/adding of Banners, Not Enough Memory!",10,10,0
NoTrkZeroAdd.txt:	dc.b	10,"Error: TRK0-Banner text should be 960 bytes long!",$a,0
Ok.txt:			dc.b	'... Done',10,0
FileOkay.txt:		dc.b	10,"DMS-File Passed CRC Checking!",0
LoadErr.txt:		dc.b	10,10,"Error: Unable to Open file.",10,0

FrntFilename.txt:	dc.b	'S:PDC_Banner_Front',0
Trk0Filename.txt:	dc.b	'S:PDC_Track_Zero',0
RearFilename.txt:	dc.b	'S:PDC_Banner_Rear',0

AboutADDY.txt:	dc.b	"`---- PrO-DmScHeCk ----- by ExOdOuS/ TLS, XPress & O.T.T  ----''",$A,0
DOSName:	dc.b	'dos.library',0
		even

CRC_TAB		dc.l	$0000C0C1,$C1810140,$C30103C0,$0280C241,$C60106C0
		dc.l	$0780C741,$0500C5C1,$C4810440,$CC010CC0,$0D80CD41
		dc.l	$0F00CFC1,$CE810E40,$0A00CAC1,$CB810B40,$C90109C0
		dc.l	$0880C841,$D80118C0,$1980D941,$1B00DBC1,$DA811A40
		dc.l	$1E00DEC1,$DF811F40,$DD011DC0,$1C80DC41,$1400D4C1
		dc.l	$D5811540,$D70117C0,$1680D641,$D20112C0,$1380D341
		dc.l	$1100D1C1,$D0811040,$F00130C0,$3180F141,$3300F3C1
		dc.l	$F2813240,$3600F6C1,$F7813740,$F50135C0,$3480F441
		dc.l	$3C00FCC1,$FD813D40,$FF013FC0,$3E80FE41,$FA013AC0
		dc.l	$3B80FB41,$3900F9C1,$F8813840,$2800E8C1,$E9812940
		dc.l	$EB012BC0,$2A80EA41,$EE012EC0,$2F80EF41,$2D00EDC1
		dc.l	$EC812C40,$E40124C0,$2580E541,$2700E7C1,$E6812640
		dc.l	$2200E2C1,$E3812340,$E10121C0,$2080E041,$A00160C0
		dc.l	$6180A141,$6300A3C1,$A2816240,$6600A6C1,$A7816740
		dc.l	$A50165C0,$6480A441,$6C00ACC1,$AD816D40,$AF016FC0
		dc.l	$6E80AE41,$AA016AC0,$6B80AB41,$6900A9C1,$A8816840
		dc.l	$7800B8C1,$B9817940,$BB017BC0,$7A80BA41,$BE017EC0
		dc.l	$7F80BF41,$7D00BDC1,$BC817C40,$B40174C0,$7580B541
		dc.l	$7700B7C1,$B6817640,$7200B2C1,$B3817340,$B10171C0
		dc.l	$7080B041,$500090C1,$91815140,$930153C0,$52809241
		dc.l	$960156C0,$57809741,$550095C1,$94815440,$9C015CC0
		dc.l	$5D809D41,$5F009FC1,$9E815E40,$5A009AC1,$9B815B40
		dc.l	$990159C0,$58809841,$880148C0,$49808941,$4B008BC1
		dc.l	$8A814A40,$4E008EC1,$8F814F40,$8D014DC0,$4C808C41
		dc.l	$440084C1,$85814540,$870147C0,$46808641,$820142C0
		dc.l	$43808341,$410081C1,$80814040

		section	dmscheckbss,bss
DT:
_DTBase:	ds.l	260
_OldStack:	ds.l	1
_DOSBase:	ds.l	1
_ArgLen:	ds.l	1
_ArgPtr:	ds.l	1
_FilenamePt:	ds.l	1
_BnrFlags:	ds.w	1
_Output:	ds.l	1
_ExtraMemFlg:	ds.l	1
_DMSMemPt:	ds.l	1
_DMSFileSize:	ds.l	1
_FrontMemPt:	ds.l	1
_FrontMemSize:	ds.l	1
_ZeroMemPt:	ds.l	1
_ZeroMemSize:	ds.l	1
_RearMemPt:	ds.l	1
_RearMemSize:	ds.l	1
_TotalBnrSize:	ds.l	1
_TotalBnPt:	ds.l	1
_TotalBnrNewSize:	ds.l	1
_DMSTrkPt:	ds.l	1
_TmpBuff:	ds.b	1282

		end
