;*---------------------------------------------------------------------------
;  :Program.	nebulus2.imager.asm
;  :Contents.	Imager for Nebulus 2
;  :Author.	Wepl
;  :Version.	$Id: nebulus2.imager.asm 1.3 1998/11/25 13:39:39 jah Exp jah $
;  :History.	01.08.98 started
;		14.09.98 insertdisk fixed
;		17.09.98 some files forgotten
;		25.09.98 duplicate file (199-21d) excluded
;		24.11.98 index flag removed
;  :Requires.	-
;  :Copyright.	Public Domain
;  :Language.	68000 Assembler
;  :Translator.	Barfly V2.9
;  :To Do.
;---------------------------------------------------------------------------*
;
;	Disk format:
;	Disk 1:		0-1	standard
;			2-152	$18a8 bytes sync=9521,...
;	Disk 2:		9-155	$18a8 bytes sync=9521,...
;	Disk 3:		9-158	$18a8 bytes sync=9521,...
;
;---------------------------------------------------------------------------*

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

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

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

	SECTION a,CODE

		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,3			;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	0
		dc.l	0
		dc.l	0
.disknamearray	dc.l	.d
		dc.l	.d
		dc.l	.d
.specialarray	dc.l	_Special
		dc.l	_Special
		dc.l	_Special
.statearray	dc.l	.insertdisk
		dc.l	.insertdisk
		dc.l	.insertdisk

.d		dc.b	"Nebulus2",0

.adname		dc.b	"Done by Wepl.",0
.name		dc.b	"Nebulus 2, 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)

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

BYTESPERTRACK	= $18a8
RAWREADLEN	= 5*BYTESPERTRACK

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

_lengtharray	dc.l	$1c*BYTESPERTRACK
		dc.l	$1c*BYTESPERTRACK
		dc.l	$1c*BYTESPERTRACK

_tablearray	dc.l	_t1
		dc.l	_t2
		dc.l	_t3

FILE	MACRO
		dc.l	(\1<<24)|\2
	ENDM

_t1		FILE	  3,27956
		FILE	  8,78344
		FILE	$15,67004
		FILE	$20,43292
		FILE	$27,60312
		FILE	$31,130100
		FILE	$46,128188
		FILE	$5B,128420
		FILE	$70,125936
		FILE	$96,$447c
		FILE	$99,$901c
		dc.w	0

_t2		FILE	  1,$244c
		FILE	  8,126204
	;	FILE	$1d,$901c	;the same as file "199"
		FILE	$23,129692
		FILE	$38,130300
		FILE	$4D,112052
		FILE	$5F,112576
		FILE	$71,$1e08
		FILE	$73,121700
		FILE	$87,122172
		FILE	$9b,$5d64
		dc.w	0

_t3		FILE	  8,122656
		FILE	$1C,123112
		FILE	$30,$1efc
		FILE	$32,110560
		FILE	$44,111136
		FILE	$56,$2c50
		FILE	$58,125396
		FILE	$6C,125600
		FILE	$80,$23f0
		FILE	$82,173740
		dc.w	0

_filename	dc.b	"Nebulus2:"
_filename2	dsb	4
_loader		dc.b	"Nebulus2:100",0

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

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

.idisk		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	.idisk

		cmp.w	#0,d6				;first cycle ?
		bne	.notfirst
		move.l	(PTB_DEVICESOURCEPTR,a5),a1
		move.l	(PTB_ADDRESSOFFILE,a5),(IO_DATA,a1)
		move.l	#$2c00,(IO_LENGTH,a1)
		move.l	#0,(IO_OFFSET,a1)
		move.w	#CMD_READ,(IO_COMMAND,a1)
		move.b	#0,(IO_FLAGS,a1)
		move.l	(4).w,a6
		jsr	(_LVODoIO,a6)
		moveq	#0,d2				;if it has failed
		tst.l	d0
		bne	.readerr
		move.l	#$2000-$300,d0
		lea	(_loader),a0
		move.l	(PTB_ADDRESSOFFILE,a5),a1
		add.l	#$17e,a1
		bsr	_WriteFile
		tst.b	d0
		beq	.readerr
.notfirst
		moveq	#"1",d0
		add.b	d6,d0
		move.b	d0,(_filename2)
		
		lsl.w	#2,d6
		lea	(_tablearray),a0
		move.l	(a0,d6.w),a3			;A3 = file table

		move.l	a3,a0
		moveq	#0,d6
.calcd6		tst.b	(a0)
		beq	.jmpin
		move.l	(a0)+,d1
		and.l	#$ffffff,d1
		add.l	#BYTESPERTRACK-1,d1
		divu	#BYTESPERTRACK,d1
		add.w	d1,d6				;D6 = amount of tracks over all
		bra	.calcd6

.nextfile	move.l	(PTB_ADDRESSOFFILE,a5),a2	;A2 = file address

.nexttrack	moveq	#5-1,d4				;D4 = retries
.readretry	bchg	#0,d2
		bsr	_ReadTrack
		bchg	#0,d2
		tst.b	d0
		beq	.readerr

		move.l	(PTB_SPACE,a5),a0		;source
		move.l	a2,a1				;destination
		bsr	_Decode
		tst.b	d0
		bne	.readok
		dbf	d4,.readretry
		bra	.readerr

.readok		add.l	#BYTESPERTRACK,a2
		addq.w	#1,d2				;one tracks further
		subq.w	#1,d6				;one track less
		sub.l	#BYTESPERTRACK,d3
		bcc	.nexttrack
		
		move.l	d5,d0
		lea	(_filename),a0
		move.l	(PTB_ADDRESSOFFILE,a5),a1
		bsr	_WriteFile
		tst.b	d0
		beq	.motoff

.jmpin		moveq	#0,d2
		move.b	(a3),d2				;D2 = start/actual track

		move.l	d2,d0
		lea	(_filename2+1),a0
		ror.l	#4,d0
		move.b	(.list,PC,d0.w),(a0)+
		clr.w	d0
		rol.l	#4,d0
		move.b	(.list,PC,d0.w),(a0)
		
		move.l	(a3)+,d3
		and.l	#$ffffff,d3			;D3 = file size left
		move.l	d3,d5				;D5 = file size
		tst.l	d2
		bne	.nextfile
		moveq	#0,d7
		bra	.motoff

.readerr	bchg	#0,d2
		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

.list		dc.b	"0123456789abcdef"

;======================================================================
; IN:	D2 = track
;	D6 = amount tracks left
; OUT:	D0 = error

_ReadTrack
		move.l	d2,d0
		move.l	d6,d1
		bsr	_Display

SOURCE = 0	;0=real 1=nomadwarp 2=wwarp

	IFEQ SOURCE
	;reading from a real disk
		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	#0,(IO_FLAGS,a1)
		move.l	(4).w,a6
		jsr	(_LVODoIO,a6)
		tst.l	d0
		seq	d0
		rts
	ENDC
	IFEQ SOURCE-1
	;reading from a track-file written by nomad-warp
		movem.l	d2-d4/a2-a3,-(a7)
		lea	(.name),a0			;format string
		move.w	d2,d0
		lsr.w	#1,d0
		and.w	#1,d2
		movem.w	d0/d2,-(a7)
		move.l	a7,a1				;arg array
		lea	(_PutChar),a2
		sub.l	#100-4,a7
		move.l	a7,a3				;buffer
		move.l	(4),a6
		jsr	(_LVORawDoFmt,a6)
		move.l	a7,d1
		move.l	#MODE_OLDFILE,d2
		move.l	(PTB_DOSBASE,a5),a6
		jsr	(_LVOOpen,a6)
		add.l	#100,a7
		move.l	d0,d4
		beq	.err
		move.l	d4,d1
		move.l	(PTB_SPACE,a5),d2
		move.l	#RAWREADLEN,d3
		jsr	(_LVORead,a6)
		move.l	d4,d1
		jsr	(_LVOClose,a6)
		moveq	#-1,d0
.err		movem.l	(a7)+,d2-d4/a2-a3
		rts
.name		dc.b	"ram:track_%02d_head_%02d",0,0
	ENDC
	IFEQ SOURCE-2
	;reading from a wwarp image
		movem.l	d2-d6,-(a7)
		move.l	d2,d6
		moveq	#0,d5
		sub.w	#168*4,a7
		lea	.name,a0
		move.l	a0,d1
		move.l	#MODE_OLDFILE,d2
		move.l	(PTB_DOSBASE,a5),a6
		jsr	(_LVOOpen,a6)
		move.l	d0,d4
		beq	.err
		move.l	d4,d1
		move.l	#16,d2
		move.l	#OFFSET_BEGINNING,d3
		jsr	(_LVOSeek,a6)			;skip header
		move.l	d4,d1
		move.l	a7,d2
		move.l	#168*4,d3
		jsr	(_LVORead,a6)
		cmp.l	d0,d3
		bne	.close
		moveq	#0,d0
		moveq	#0,d1
		moveq	#0,d2
.0		cmp.w	d0,d6
		beq	.1
		move.l	(a7,d1.l),d3
		and.l	#$ffff,d3
		beq	.2
		add.l	d3,d2
		add.l	#16,d2				;skip track headline
.2		addq.l	#1,d0
		addq.l	#4,d1
		bra	.0
.1		move.l	d4,d1
		add.l	#16,d2				;skip track headline
		move.l	#OFFSET_CURRENT,d3
		jsr	(_LVOSeek,a6)
		move.l	d4,d1
		move.l	(PTB_SPACE,a5),d2
		move.l	#RAWREADLEN,d3
		jsr	(_LVORead,a6)
		cmp.l	d0,d3
		bne	.close
		moveq	#-1,d5
.close		move.l	d4,d1
		jsr	(_LVOClose,a6)
.err		add.w	#168*4,a7
		move.l	d5,d0
		movem.l	(a7)+,d2-d6
		rts
.name		dc.b	"develop:cracks/nebulus2/neb2.wwp",0
	EVEN
	ENDC

;======================================================================
; IN:	D0 = size
;	A0 = name
;	A1 = address
; OUT:	D0 = error

_WriteFile	movem.l	d2-d7,-(a7)
		move.l	a0,-(a7)
		move.l	d0,d3
		moveq	#0,d5
		move.l	a1,d6
		move.l	(PTB_DOSBASE,a5),a6
		move.l	a0,d1
		move.l	#MODE_NEWFILE,d2
		jsr	(_LVOOpen,a6)
		move.l	d0,d4
		beq	.err
		move.l	d4,d1
		move.l	d6,d2
		jsr	(_LVOWrite,a6)
		cmp.l	d0,d3
		bne	.err
		moveq	#-1,d5
		bra	.close
.err		jsr	(_LVOIoErr,a6)
		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	d0,-(a7)
		move.l	a7,a3				;Args
		move.l	(PTB_INTUITIONBASE,a5),a6
		jsr	(_LVOEasyRequestArgs,a6)
		add.w	#6*4,a7
.close		move.l	d4,d1
		beq	.1
		jsr	(_LVOClose,a6)
.1		move.l	d5,d0
		movem.l	(a7)+,d1-d7
		rts

.titel		dc.b	"Error",0
.text		dc.b	"Dos Error %ld writing file '%s'",0
.gadgets	dc.b	"OK",0
	EVEN

;======================================================================
; 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
GetL2	MACRO
		GetWI2	\1
		swap	\1
		GetW2	\2
		move.w	\2,\1
		subq.l	#2,a2
	ENDM

_synctable	dc.w	$9521,$A891,$4291,$44A1

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

		lsr.w	#2,d2
		and.w	#6,d2
		move.w	(_synctable,pc,d2),d2	;D2 = sync

	;find sync
.sync1		moveq	#16-1,d5		;D5 = shift count
.sync2		GetW	d0
		cmp.w	d2,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

		addq.l	#6,a0			;skip sync

		moveq	#0,d4
		MOVE.L	#$55555555,D6
		move.l	#BYTESPERTRACK/4-1,d7

.loop		GetLI	d0,d3
		GetLI	d1,d3
		AND.L	D6,D0
		AND.L	D6,D1
		LSL.L	#1,D0
		OR.L	D1,D0
		move.l	d0,(a1)+
		add.l	d0,d4
		dbf	d7,.loop

		GetLI	d0,d3
		GetLI	d1,d3
		AND.L	D6,D0
		AND.L	D6,D1
		LSL.L	#1,D0
		OR.L	D1,D0
		cmp.l	d0,d4
		beq	.success

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

.success	moveq	#-1,d0
.quit		move.l	a6,a7
		movem.l	(a7)+,d1-a6
		rts
.error		moveq	#0,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

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

_PutChar	move.b	d0,(a3)+
		rts

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

	END

