;*---------------------------------------------------------------------------
;  :Program.	interphase.imager.asm
;  :Contents.	Imager for Interphase
;  :Author.	Wepl
;  :Version.	$Id: interphase.imager.asm 1.3 1998/06/27 23:48:35 jah Exp jah $
;  :History.	06.02.98 started
;		23.04.98 adapted for Patcher 1.05
;  :Requires.	-
;  :Copyright.	Public Domain
;  :Language.	68000 Assembler
;  :Translator.	Barfly V1.131
;  :To Do.
;---------------------------------------------------------------------------*
;
;	Disk format:
;	Disk 1:		0	standard
;			1	unformatted
;			2-75	$1400 bytes sync=4489
;
;	Image format:
;	Disk 1		tracks 2-75 = 373760
;
;---------------------------------------------------------------------------*

	INCDIR	Includes:
	INCLUDE	devices/trackdisk.i
	INCLUDE	intuition/intuition.i
	INCLUDE	utility/tagitem.i
	INCLUDE	lvo/exec.i
	INCLUDE	lvo/intuition.i
	INCLUDE	patcher.i

	IFD BARFLY
	OUTPUT	"C:Parameter/interphase.imager"
	BOPT	O+ OG+			;enable optimizing
	BOPT	ODd- ODe-		;disable mul optimizing
	ENDC

;======================================================================

		moveq	#-1,d0
		rts
		dc.l	_Table
		dc.l	"PTCH"

;======================================================================

_Table		dc.l	PCH_ADAPTOR,.adname		;name adaptor
		dc.l	PCH_NAME,.name			;description of parameter
		dc.l	PCH_FILECOUNT,1			;number of cycles
		dc.l	PCH_FILENAME,.filenamearray	;file names
		dc.l	PCH_DATALENGTH,_lengtharray	;file lengths
		dc.l	PCH_DISKNAME,.disknamearray	;disk names
		dc.l	PCH_SPECIAL,.specialarray	;functions
		dc.l	PCH_STATE,.statearray		;state texts
		dc.l	PCH_MINVERSION,.patcherver	;minimum patcher version required
		dc.l	PCH_INIT,_Init			;init routine
		dc.l	PCH_FINISH,_Finish		;finish routine
		dc.l	PCH_ERRORINPARAMETER,_Finish	;finish routine
		dc.l	TAG_DONE

.filenamearray	dc.l	.f1
.disknamearray	dc.l	.d
.specialarray	dc.l	_Special
.statearray	dc.l	.insertdisk

.f1		dc.b	"Disk.1",0
.d		dc.b	"Interphase",0

.adname		dc.b	"Done by Wepl.",0
.name		dc.b	"Interphase, Diskimager for HD-Install",0
.patcherver	dc.b	"V1.05"
.insertdisk	dc.b	'Please insert your original writepro-',10
		dc.b	'tected disk in the source drive.',0
	IFD BARFLY
		dc.b	"$VER: "
	DOSCMD	"WDate >T:date"
	INCBIN	"T:date"
		dc.b	0
	ENDC
	EVEN

;======================================================================

_Init		moveq	#0,d0				;source drive
		move.l	PTB_INHIBITDRIVE(a5),a0		;inhibit drive
		jsr	(a0)
		tst.l	d0
		bne	.error
		
		moveq	#0,d0				;source drive
		move.l	PTB_OPENDEVICE(a5),a0		;open source device
		jsr	(a0)
		tst.l	d0
		bne	.error
		rts

.error		bsr	_Finish
		moveq	#-1,d0
		rts

;======================================================================

_Finish		moveq	#0,d0				;source drive
		move.l	PTB_ENABLEDRIVE(a5),a0		;deinhibit drive
		jmp	(a0)

;======================================================================

RAWREADLEN	= $7c00
BYTESPERTRACK	= $1400
SYNC		= $4489

;======================================================================

TRACKS_1	= 73

_lengtharray	dc.l	BYTESPERTRACK*TRACKS_1
_starttrack	dc.b	2
_counttrack	dc.b	TRACKS_1

;======================================================================

_Special	moveq	#-1,d7				;D7 = return code (default=error)

		bsr	_InsertDisk
		tst.l	d0
		beq	.nodisk
		
	;check for disk in drive
		move.l	(PTB_DEVICESOURCEPTR,a5),a1
		move.w	#TD_CHANGESTATE,(IO_COMMAND,a1)
		move.l	(4).w,a6
		jsr	(_LVODoIO,a6)
		tst.l	(IO_ACTUAL,a1)
		bne	.nodisk

		moveq	#0,d2				;D2 = start/actual track
		move.b	(_starttrack,pc,d6.w),d2
		moveq	#0,d3				;D3 = amount of tracks
		move.b	(_counttrack,pc,d6.w),d3
		move.l	(PTB_ADDRESSOFFILE,a5),a2	;A2 = file address

.next		move.l	d2,d0
		move.l	d3,d1
		bsr	_Display
		moveq	#5-1,d6				;D6 = retries decoding
.decretry	moveq	#5-1,d5				;D5 = retries rawread
.tdretry	move.l	(PTB_DEVICESOURCEPTR,a5),a1
		move.l	(PTB_SPACE,a5),(IO_DATA,a1)	;track is to load in ptb_space
		move.l	#RAWREADLEN,(IO_LENGTH,a1)	;double length of track to decode the index-sync-read data
		move.l	d2,(IO_OFFSET,a1)
		move.w	#TD_RAWREAD,(IO_COMMAND,a1)
		move.b	#IOTDB_INDEXSYNC,(IO_FLAGS,a1)
		move.l	(4).w,a6
		jsr	(_LVODoIO,a6)
		tst.l	d0
		beq	.tdok
		dbf	d5,.tdretry
		bra	.tderr
.tdok
		move.l	(PTB_SPACE,a5),a0		;source
		move.l	a2,a1				;destination
		bsr	_Decode
		tst.l	d0
		beq	.decok
		dbf	d6,.decretry
		bra	.decerr
.decok
		add.l	#BYTESPERTRACK,a2
		addq.w	#1,d2				;one track further
		subq.w	#1,d3				;one track less
		bne	.next

		moveq	#0,d7				;return code
		bra	.motoff
.decerr
.tderr		bsr	_ReadError

	;switch motor off
.motoff		move.l	(PTB_DEVICESOURCEPTR,a5),a1
		clr.l	(IO_LENGTH,a1)
		move.w	#TD_MOTOR,(IO_COMMAND,a1)
		move.l	(4).w,a6
		jsr	(_LVODoIO,a6)
.nodisk
	;enable drive
		tst.b	d7
		beq	.quit
		bsr	_Finish
		
.quit		move.l	d7,d0
		rts

;======================================================================
; IN:	A0 = raw
;	A1 = dest
; OUT:	D0 = error

GetW	MACRO
		cmp.l	a0,a5
		bls	.error
		move.l	(a0),\1
		lsr.l	d5,\1
	ENDM
GetW2	MACRO
		cmp.l	a2,a5
		bls	.error
		move.l	(a2),\1
		lsr.l	d5,\1
	ENDM
GetWI	MACRO
		GetW	\1
		addq.l	#2,a0
	ENDM
GetWI2	MACRO
		GetW2	\1
		addq.l	#2,a2
	ENDM
GetLI	MACRO
		GetWI	\1
		swap	\1
		GetWI	\2
		move.w	\2,\1
	ENDM
GetLI2	MACRO
		GetWI2	\1
		swap	\1
		GetWI2	\2
		move.w	\2,\1
	ENDM

_Decode		movem.l	d1-a6,-(a7)
		move.l	a7,a6			;A6 = return stack
		lea	(RAWREADLEN,a0),a5	;A5 = end of raw data

	;find sync
.sync1		moveq	#16-1,d5		;D5 = shift count
.sync2		GetW	d0
		cmp.w	#SYNC,d0
		beq	.sync3
.sync_retry	dbf	d5,.sync2
		addq.l	#2,a0
		bra	.sync1

.sync3		movem.l	a0/a1,-(a7)		;save this point for new try

.sync4		addq.l	#2,a0
		GetW	d0
		cmp.w	#SYNC,d0
		beq	.sync4
		
	;now stuff from original
		MOVE.L	#$55555555,D4		;D4 = mask

		GetLI	d0,d7
		GetLI	d1,d7			;track number
		and.l	d4,d0
		and.l	d4,d1
		add.l	d0,d0
		or.l	d1,d0
		cmp.b	d0,d2			;D2 = track
		bne	.fail

		GetLI	d0,d7
		GetLI	d1,d7			;track number
		and.l	d4,d0
		and.l	d4,d1
		add.l	d0,d0
		or.l	d1,d0
		move.l	d0,a3			;A3 = checksum

						;A0 = pointer 1
		lea	(BYTESPERTRACK,a0),a2	;A2 = pointer 2
		MOVE.W	#BYTESPERTRACK/4-1,D3	;D3 = loop count
		moveq	#0,d6			;D6 = sum
.lp		GetLI	d0,d7
		GetLI2	d1,d7
		and.l	d4,d0
		and.l	d4,d1
		eor.l	d0,d6
		eor.l	d1,d6
		add.l	d0,d0
		or.l	d1,d0
		move.l	d0,(a1)+
		dbf	d3,.lp
		
		cmp.l	d6,a3
		beq	.success

.fail		movem.l	(a7)+,a0/a1
		bra	.sync_retry		;try again

.success	moveq	#0,d0
.quit		move.l	a6,a7
		movem.l	(a7)+,d1-a6
		rts
.error		moveq	#-1,d0
		bra	.quit

;======================================================================

_InsertDisk	sub.l	a0,a0				;window
		pea	(.gadgets)
		pea	(.text)
		pea	(.titel)
		clr.l	-(a7)
		pea	(EasyStruct_SIZEOF)
		move.l	a7,a1				;easyStruct
		sub.l	a2,a2				;IDCMP_ptr
		move.l	d6,-(a7)
		addq.l	#1,(a7)
		move.l	a7,a3				;Args
		move.l	(PTB_INTUITIONBASE,a5),a6
		jsr	(_LVOEasyRequestArgs,a6)
		add.w	#6*4,a7
		rts

.titel		dc.b	"Insert Disk",0
.text		dc.b	"Insert your orginal disk %ld",10
		dc.b	"into the source drive !",0
.gadgets	dc.b	"OK|Cancel",0,0

;======================================================================

_ReadError	sub.l	a0,a0				;window
		pea	(.gadgets)
		pea	(.text)
		pea	(.titel)
		clr.l	-(a7)
		pea	(EasyStruct_SIZEOF)
		move.l	a7,a1				;easyStruct
		sub.l	a2,a2				;IDCMP_ptr
		move.l	d2,-(a7)
		move.l	a7,a3				;Args
		move.l	(PTB_INTUITIONBASE,a5),a6
		jsr	(_LVOEasyRequestArgs,a6)
		add.w	#6*4,a7
		rts

.titel		dc.b	"Error",0
.text		dc.b	"Can't read track %ld",0
.gadgets	dc.b	"OK",0

;======================================================================
; IN:	D0 = actual tracknumber
;	D1 = tracks left to do

_Display	movem.l	d0-d1/a0-a3/a6,-(a7)
		lea	(.text),a0		;format string
		move.l	d1,-(a7)
		move.l	d0,-(a7)
		move.l	a7,a1			;arg array
		lea	(.PutChar),a2
		sub.l	#100-8,a7
		move.l	a7,a3			;buffer
		move.l	(4),a6
		jsr	(_LVORawDoFmt,a6)
		move.l	a7,a0
		move.l	(PTB_DISPLAY,a5),a6
		jsr	(a6)
		add.l	#100,a7
		movem.l	(a7)+,d0-d1/a0-a3/a6
		rts

.PutChar	move.b	d0,(a3)+
		rts

.text		dc.b	"reading track %ld, left %ld",0

;======================================================================

	END

