
	; Archipelagos imager

	; A track contains 5 sectors, each containing 1024 bytes data.

	; Sector format description:

	; sync ($4489)
	; 1 unused byte ($FF)
	; 1 byte which indicates the distance to the track gap
	; 1 byte sector number (0-5)
	; 1 word checksum
	; 512 words data

	; The checksum is calculated by adding all 512 data words.

	; The MFM decoding is done by skipping all odd bits in the bitstream.

		incdir	Includes:
		include	RawDIC.i

		SLAVE_HEADER
		dc.b	1	; Slave version
		dc.b	0	; Slave flags
		dc.l	DSK_1	; Pointer to the first disk structure
		dc.l	Text	; Pointer to the text displayed in the imager window

		dc.b	"$VER:"
Text:		dc.b	"Archipelagos imager V1.0",10,"by John Selck on 02.03.1999",0
		cnop	0,4

DSK_1:		dc.l	0		; Pointer to next disk structure
		dc.w	1		; Disk structure version
		dc.w	0		; Disk flags
		dc.l	TL_1		; List of tracks which contain data
		dc.l	0		; UNUSED, ALWAYS SET TO 0!
		dc.l	FL_DISKIMAGE	; List of files to be saved
		dc.l	0		; Table of certain tracks with CRC values
		dc.l	0		; Alternative disk structure, if CRC failed
		dc.l	0		; Called before a disk is read
		dc.l	0		; Called after a disk has been read

TL_1:		TLENTRY	0,0,$1400,SYNC_STD,DMFM_STD
		TLENTRY	1,1,$1400,SYNC_INDEX,DMFM_NULL
		TLENTRY	2,22,$1400,SYNC_STD,DMFM_Arc
		TLENTRY	23,25,$1400,SYNC_INDEX,DMFM_NULL
		TLENTRY	26,48,$1400,SYNC_STD,DMFM_Arc
		TLENTRY	49,50,$1400,SYNC_INDEX,DMFM_NULL
		TLENTRY	51,67,$1400,SYNC_STD,DMFM_Arc
		TLENTRY	68,74,$1400,SYNC_INDEX,DMFM_NULL
		TLENTRY	75,76,$1400,SYNC_STD,DMFM_Arc
		;TLENTRY	77,99,$1400,SYNC_INDEX,DMFM_NULL
		;TLENTRY	100,100,SYNC_STC,DMFM_Arc
		TLEND

	; track 100 is formatted but contains obsolete data

DMFM_Arc:

		lea	SectorFlags(pc),a2
		moveq	#4,d1
.l0		sf	(a2)+		; clear sector flags
		dbra	d1,.l0

		moveq	#4,d1
		bra.b	.skip		; first sync is already synced
.l1		jsr	rawdic_NextSync(a5)
.skip		bsr.b	DMFM_ArcBlock
		bne.b	.error
		dbra	d1,.l1

		lea	SectorFlags(pc),a2
		moveq	#4,d1
.l2		tst.b	(a2)+		; if one sector is missing, one of
		dbeq	d1,.l2		; these flags will be FALSE
		beq.b	.nosect

		moveq	#IERR_OK,d0
.error		rts
.nosect		moveq	#IERR_NOSECTOR,d0
		rts

DMFM_ArcBlock:	; decoder of a block

		movem.l	d1/a0-a1,-(sp)

		addq.l	#1*2,a0		; skip 1 byte

		bsr.b	NextWord	; get sector number and distance to gap
		and.w	#$00ff,d0	; mask sector number
		subq.b	#1,d0
		cmp.b	#5,d0		; sector number has to be 1 to 5
		bhs.b	.error

		lea	SectorFlags(pc),a2
		st	(a2,d0.w)	; set flag for sector

		mulu.w	#$0400,d0	; calculate offset in track
		add.l	d0,a1

		bsr.b	NextWord	; get checksum
		move.w	d0,d2

		move.w	#$01ff,d1
.l0		bsr.b	NextWord	; decode data
		move.w	d0,(a1)+
		sub.w	d0,d2
		dbra	d1,.l0

		tst.w	d2		; checksum ok?
		bne.b	.error

		movem.l	(sp)+,d1/a0-a1
		moveq	#IERR_OK,d0
		rts
.error		movem.l	(sp)+,d1/a0-a1
		moveq	#IERR_CHECKSUM,d0
		rts

NextWord:	move.l	(a0)+,d0
		BITSKIP_W d0
		rts

SectorFlags:	ds.b	5

