;
; SAS/C isn't capable of inlining assembler subroutines, nor does it produce
; appropriate code for straight division/modulo operations, nor does it .....
; So, let's it do the work, and then I do the rest to it.
;
; Michael Rausch, 3/94
;

	SECTION	text,CODE

	XREF	_clamp


	XREF	_BIMcm_reconstruct
	XREF	_BIM_reconstruct
	XREF	_BMcm_reconstruct
	XREF	_BM_reconstruct

	XDEF	@ReconIMBlock
	XDEF	@ReconPMBlock
	XDEF	@ReconBMBlock
	XDEF	@ReconBiMBlock


@ReconIMBlock:
	MOVEM.L	D4-D7/A3,-(A7)
	MOVE.L  D0,D7
	MOVE.L  $c(A0),D6
	MOVE.L  $86(A0),D4
	divu.w  d6,D4
	moveq	#0,d5
	move.w	d4,d5
	swap	d4
	ext.l	d4
	move.L	$178(a0),a1
	MOVEQ.L	#$4,D0
	CMP.L	D0,D7
	BGE.B	ReconIMBlock__7
	lSL.L	#$4,D5
	lSL.L	#$4,D4
	MOVEQ	#$1,D1
	CMP.L	D1,D7
	BLE.B	ReconIMBlock__4
	ADDQ.L	#$8,D5
ReconIMBlock__4:
	BTST	#$0,D7
	BEQ.B	ReconIMBlock__6
	ADDQ.L	#$8,D4
ReconIMBlock__6:
	lSL.L	#$4,D6
	MOVE.L	(A1),A3
	BRA.B	ReconIMBlock__10
ReconIMBlock__7:
	lSL.L	#$3,D4
	lSL.L	#$3,D5
	lSL.L	#$3,D6
	SUBQ.L	#$4,D7
	BNE.B	ReconIMBlock__9
	MOVE.L	$4(A1),A3
	BRA.B	ReconIMBlock__10
ReconIMBlock__9:
	MOVE.L	$8(A1),A3
ReconIMBlock__10:
	MULu.w	D6,D5
	add.w	#$d2,a0
	ADD.L	D5,A3
	ADD.L	D4,A3

	lea	_clamp,a1
	subq.l	#8,d6			; correct row_size
	moveq	#7,d4
cdct_all_rows:
	REPT	2
	move.w	(a0)+,d1
	move.w	(a1,d1.w*2),d5
	move.w	(a0)+,d1
	move.b	(a1,d1.w*2),d5
	swap	d5
	move.w	(a0)+,d1
	move.w	(a1,d1.w*2),d5
	move.w	(a0)+,d1
	move.b	(a1,d1.w*2),d5
	move.l	d5,(a3)+
	ENDR
	add.l	d6,a3
	dbra	d4,cdct_all_rows

	movem.l	(A7)+,D4-D7/A3
	rts




@ReconPMBlock:
	SUB.W	#$1c,A7
	MOVEM.L D2/D3/D4/D6/D7/A2/A3/A5,-(A7)

	MOVE.L	D0,D4
	MOVE.L	$c(A0),D7
	MOVE.L	$178(A0),A3
	MOVE.L	$86(A0),D2
	DIVu.w	D7,D2
	moveq	#0,d6
	move.w	d2,d6
	swap	d2
	LEA	$24(A7),A5
	ext.l	d2
	MOVE.L	D0,(A5)+
	MOVE.L	D1,(A5)+
	MOVE.L	A0,(A5)+


	MOVEQ.L	#$4,D0
	CMP.L	D0,D4
	BGE.B	ReconPMBlock__12
ReconPMBlock__2:
	MOVEQ.L	#$1,D0
	AND.L	D1,D0
	MOVEQ.L	#$1,D3
	LEA	$40(A7),A5
	AND.L	(A5),D3
	aSR.L	#$1,D1
	MOVE.L	D1,$28(A7)
	MOVE.L	(A5),D1
	aSR.L	#$1,D1
	MOVE.L	(A3),A2
	MOVE.L	D1,(A5)+
	MOVE.L	D0,$34(A7)
	MOVE.L	D3,$30(A7)

	MOVEQ.L	#$3,D0
	CMP.L	$4e(A0),D0
	BNE.B	ReconPMBlock__5
ReconPMBlock__3:
	MOVE.L	$170(A0),A1
	BRA.B	ReconPMBlock__7
ReconPMBlock__5:
	MOVE.L	$174(A0),A1
ReconPMBlock__7:
	MOVE.L	A1,D3
	BEQ	ReconPMBlock__34	; error, no future/past frame! not in the original code!
	MOVE.L	 (A1),A3
ReconPMBlock__8:

	lSL.L	#$4,D7
	MOVE.L	D6,D0
	lSL.L	#$4,D0
	MOVE.L	D2,D6
	lSL.L	#$4,D6
	MOVE.L	D0,$38(A7)
	MOVEQ.L	#$1,D1
	CMP.L	D1,D4
	BLE.B	ReconPMBlock__10
ReconPMBlock__9:
	ADDQ.L	#$8,$38(A7)
ReconPMBlock__10:
	BTST	#$0,D4
	BEQ.W	ReconPMBlock__24
ReconPMBlock__11:
	ADDQ.L	#$8,D6
	BRA.W	ReconPMBlock__24
ReconPMBlock__12:
	MOVEQ.L	#$2,D0
	AND.L	D1,D0
	aSR.L	#$1,D0
	MOVEQ.L	#$2,D3
	LEA	$40(A7),A5
	AND.L	(A5),D3
	aSR.L	#$2,D1
	MOVE.L	D1,$28(A7)
	MOVE.L	(A5),D1
	aSR.L	#$2,D1
	lSL.L	#$3,D7
	MOVE.L	D1,(A5)+
	MOVE.L	D6,D1
	lSL.L	#$3,D1
	MOVE.L	D2,D6
	lSL.L	#$3,D6
	MOVE.L	D1,$38(A7)
	MOVE.L	D0,$34(A7)
	MOVE.L	D3,$30(A7)

	move.l	$4e(a0),d0
	subq.l	#$3,d0
	bne.s	ReconPMB_11
	MOVE.L	$170(A0),A1
	bra.s	ReconPMB_12
ReconPMB_11:
	MOVE.L	$174(A0),A1
ReconPMB_12:
	move	a1,d0
	beq	ReconPMBlock__34	; no future/past frame!

	SUBQ.L	#$4,D4
	BNE.B	ReconPMBlock__18
ReconPMBlock__13:
	MOVE.L	$4(A3),A2
	MOVE.L	$4(A1),A3
	BRA.B	ReconPMBlock__24
ReconPMBlock__18:
	MOVE.L	$8(A3),A2
	MOVE.L	$8(A1),A3

ReconPMBlock__24:
	MOVE.L	$38(A7),D1 
	MULS.w	D7,D1
	MOVE.L	A3,A5
	ADD.L	D6,D1
	ADD.L	D1,A2
	MOVE.L	$38(A7),D1
	ADD.L	$40(A7),D1
	MULs.w	D7,D1
	ADD.L	D6,D1
	ADD.L	$28(A7),D1
	ADD.L	D1,A5
	MOVE.L	$30(A7),D1
	MOVE.L	$34(A7),D2
	MOVE.L	$44(A7),D3


	TST.L	D1
	BNE	ReconPMBlock__29
ReconPMBlock__25:
	TST.L	D2
	BNE	ReconPMBlock__29
ReconPMBlock__26:
	subq.l	#8,d7			; correct row_size
	TST.L	D3
	BNE.B	ReconPMBlock__28

ReconPMBlock__27:
	lea	_clamp,a3
	LEA	$d2(A0),A1
	moveq	#7,d0
bmcm_all_rows1:
	REPT	2
	move.l	(a5)+,d3
	moveq	#0,d1
	move.b	d3,d1
	lsr.l	#8,d3
	moveq	#0,d4
	move.b	d3,d4
	lsr.w	#8,d3
	add.l	(a1)+,d3
	move.w	d3,d2
	swap	d3
	move.w	(a3,d3.w*2),d3
	move.b	(a3,d2.w*2),d3
	swap	d3
	add.w	(a1)+,d4
	add.w	(a1)+,d1
	move.w	(a3,d4.w*2),d3
	move.b	(a3,d1.w*2),d3
	move.l	d3,(a2)+
	ENDR
	add.l	d7,a2
	add.l	d7,a5
	dbra	d0,bmcm_all_rows1

	bra	ReconPMBlock__34

ReconPMBlock__28:
	moveq	#3,d1
bm_all_rows1:
	rept	2
	move.l	(a5)+,(a2)+
	move.l	(a5)+,(a2)+
	add.l	d7,a2
	add.l	d7,a5
	endr
	dbra	d1,bm_all_rows1

	bra	ReconPMBlock__34


ReconPMBlock__29:
	sub.l	a3,a3
	TST.L	D1
	BEQ.B	ReconPMBlock__31
ReconPMBlock__30:
	move.l	d7,a3
ReconPMBlock__31:
	add.L	A5,A3
	ADD.L	D2,A3

	subq.l	#8,d7			; correct row_size
	move.l	#$fefefefe,d4
	moveq	#7,d0

	TST.L	D3
	BNE	ReconPMBlock__33
ReconPMBlock__32:

	MOVE.L	$2c(A7),A1
	ADD.W	#$d2,A1
	lea	_clamp,a0
bimcm_all_rows1:
	REPT	2
	move.l	(a5)+,d1
	move.l	(a3)+,d3
	and.l	d4,d1
	and.l	d4,d3
	add.l	d1,d3
	roxr.l	#1,d3		; tricky! get bit #32 from the previous addition
	moveq	#0,d1
	move.b	d3,d1
	lsr.l	#8,d3
	moveq	#0,d6
	move.b	d3,d6
	lsr.w	#8,d3		; *grin evilly*  eadiz, peecee  *strut*
	add.l	(a1)+,d3
	move.w	d3,d2
	swap	d3
	move.w	(a0,d3.w*2),d3
	move.b	(a0,d2.w*2),d3
	swap	d3
	add.w	(a1)+,d6
	add.w	(a1)+,d1
	move.w	(a0,d6.w*2),d3
	move.b	(a0,d1.w*2),d3
	move.l	d3,(a2)+
	ENDR
	add.l	d7,a2
	add.l	d7,a5
	add.l	d7,a3
	dbra	d0,bimcm_all_rows1

	BRA	ReconPMBlock__34
ReconPMBlock__33:

bim_all_rows1:
	REPT	2
	move.l	(a5)+,d1
	move.l	(a3)+,d2
	and.l	d4,d1
	and.l	d4,d2
	add.l	d1,d2
	roxr.l	#1,d2			; tricky! get bit no 32 from the previous addition
	move.l	d2,(a2)+		; this one kicks ass !!!
	ENDR
	add.l	d7,a2
	add.l	d7,a5
	add.l	d7,a3
	dbra	d0,bim_all_rows1

ReconPMBlock__34:
	MOVEM.L	(A7)+,D2/D3/D4/D6/D7/A2/A3/A5
	ADD.W	#$1c,A7
	RTS






@ReconBMBlock:
	SUB.W	#$1c,A7
	MOVEM.L D2/D3/D4/D6/D7/A2/A3/A5,-(A7)

	MOVE.L	D0,D4
	MOVE.L	$c(A0),D7
	MOVE.L	$178(A0),A3
	MOVE.L	$86(A0),D2
	DIVu.w	D7,D2
	moveq	#0,d6
	move.w	d2,d6
	swap	d2
	LEA	$24(A7),A5
	ext.l	d2
	MOVE.L	D0,(A5)+
	MOVE.L	D1,(A5)+
	MOVE.L	A0,(A5)+


	MOVEQ.L	#$4,D0
	CMP.L	D0,D4
	BGE.B	ReconBMBlock__12
ReconBMBlock__2:
	MOVEQ.L	#$1,D0
	AND.L	D1,D0
	MOVEQ.L	#$1,D3
	LEA	$40(A7),A5
	AND.L	(A5),D3
	aSR.L	#$1,D1
	MOVE.L	D1,$28(A7)
	MOVE.L	(A5),D1
	aSR.L	#$1,D1
	MOVE.L	(A3),A2
	MOVE.L	D1,(A5)+
	MOVE.L	D0,$34(A7)
	MOVE.L	D3,$30(A7)
	MOVE.L	$4e(A0),D1

	MOVE.L	$174(A0),A1
	MOVE.L	A1,D3
	BEQ.B	ReconPMBlock__34
	MOVE.L	 (A1),A3

	lSL.L	#$4,D7
	MOVE.L	D6,D0
	lSL.L	#$4,D0
	MOVE.L	D2,D6
	lSL.L	#$4,D6
	MOVE.L	D0,$38(A7)
	MOVEQ.L	#$1,D1
	CMP.L	D1,D4
	BLE.B	ReconBMBlock__10
ReconBMBlock__9:
	ADDQ.L	#$8,$38(A7)
ReconBMBlock__10:
	BTST	#$0,D4
	BEQ.W	ReconPMBlock__24
ReconBMBlock__11:
	ADDQ.L	#$8,D6
	BRA.W	ReconPMBlock__24
ReconBMBlock__12:
	MOVEQ.L	#$2,D0
	AND.L	D1,D0
	aSR.L	#$1,D0
	MOVEQ.L	#$2,D3
	LEA	$40(A7),A5
	AND.L	(A5),D3
	aSR.L	#$2,D1
	MOVE.L	D1,$28(A7)
	MOVE.L	(A5),D1
	aSR.L	#$2,D1
	lSL.L	#$3,D7
	MOVE.L	D1,(A5)+
	MOVE.L	D6,D1
	lSL.L	#$3,D1
	MOVE.L	D2,D6
	lSL.L	#$3,D6
	MOVE.L	D1,$38(A7)
	MOVE.L	D0,$34(A7)
	MOVE.L	D3,$30(A7)

	bra	ReconPMB_11





@ReconBiMBlock:
	SUB.W	#$1c,A7
	MOVEM.L	D2-D7/A2/A3/A5/A6,-(A7)
	MOVE.L	D0,D4

	MOVE.L	$c(A0),D7
	MOVE.L	$86(A0),D5
	DIVS.w	D7,d5
	moveq	#0,d6
	move.w	d5,d6
	swap	d5
	ext.l	d5

	LEA	$2c(A7),A6
	MOVE.L	$178(A0),A3
	MOVE.L	D0,(A6)+
	MOVE.L	D1,(A6)+
	MOVE.L	A0,(A6)+
	CMP.w	#4,D4
	BGE.s	ReconBiMBlock__11
ReconBiMBlock__2:
	MOVE.L	(A3),a1

	MOVE.L	$170(A0),A6
	MOVE.L	A6,D2
	BEQ	ReconBiMBlock__23	; no frame
	MOVE.L	(A6),A3

	MOVE.L	$174(A0),A6
	MOVE.L	A6,D2
	BEQ	ReconBiMBlock__23
	MOVE.L	(A6),A2

	lSL.L	#$4,D7
	MOVE.L	D6,D0
	lSL.L	#$4,D0
	MOVE.L	D5,D6
	lSL.L	#$4,D6
	MOVE.L	D7,$3c(A7)
	MOVE.L	D0,$40(A7)
	CMP.w	#1,D4
	BLE.s	ReconBiMBlock__8
ReconBiMBlock__7:
	ADDQ.L	#$8,$40(A7)
ReconBiMBlock__8:
	BTST	#$0,D4
	BEQ.B	ReconBiMBlock__10
ReconBiMBlock__9:
	ADDQ.L	#$8,D6
ReconBiMBlock__10:
	MOVE.L	D1,D7
	ASR.L	#$1,D7
	LEA	$48(A7),A6
	ADD.L	D6,D7
	MOVE.L	(A6)+,D5
	ASR.L	#$1,D5
	MOVE.L	$40(A7),D0
	ADD.L	D0,D5
	MOVE.L	(A6)+,D1
	ASR.L	#$1,D1
	ADD.L	D6,D1
	MOVE.L	(A6)+,D2
	ASR.L	#$1,D2
	ADD.L	D0,D2
	MOVE.L	D2,$50(A7)
	MOVE.L	D1,$4c(A7)
	BRA	ReconBiMBlock__20
ReconBiMBlock__11:
	MOVE.L	D7,D2
	lSL.L	#$3,D2
	MOVE.L	D6,D3
	lSL.L	#$3,D3
	MOVE.L	D5,D6
	lSL.L	#$3,D6
	ASR.L	#$2,D1
	LEA 	$48(A7),A6
	ADD.L	D6,D1
	MOVE.L	D1,D7
	MOVE.L	(A6)+,D5
	ASR.L	#$2,D5
	ADD.L	D3,D5
	MOVE.L	(A6)+,D1
	ASR.L	#$2,D1
	ADD.L	D6,D1
	MOVE.L	(A6)+,D0
	ASR.L	#$2,D0
	ADD.L	D3,D0
	MOVE.L	D0,$50(A7)
	MOVE.L	D1,$4c(A7)
	MOVE.L	D2,$3c(A7)
	MOVE.L	D3,$40(A7)
	SUBQ.L	#$4,D4
	BNE.s	ReconBiMBlock__16
ReconBiMBlock__12:
	MOVE.L	$4(A3),a1

	MOVE.L	$170(A0),A6
	MOVE.L	A6,D1
	BEQ	ReconBiMBlock__23
	MOVE.L	$4(A6),A3

	MOVE.L	$174(A0),A6
	MOVE.L	A6,D1
	BEQ	ReconBiMBlock__23
	MOVE.L	$4(A6),A2
	BRA.B 	ReconBiMBlock__20

ReconBiMBlock__16:
	MOVE.L	$8(A3),a1

	MOVE.L	$170(A0),A6
	MOVE.L	A6,D1
	BEQ	ReconBiMBlock__23
	MOVE.L	$8(A6),A3

	MOVE.L	$174(A0),A6
	MOVE.L	A6,D1
	BEQ	ReconBiMBlock__23
	MOVE.L	$8(A6),A2

ReconBiMBlock__20:

	MOVE.L	$3c(A7),D2
	MOVE.L	$40(A7),D1
	MULS.w	D2,D1
	ADD.L	D6,D1
	MULS.w	D2,D5
	ADD.L	D1,A1
	MOVE.L	A1,A5
	ADD.L	D7,D5
	MOVE.L	$50(A7),D1
	MULS.w	D2,D1
	ADD.L	D5,A3
	ADD.L	$4c(A7),D1
	ADD.L	D1,A2

	subq.l	#8,d2			; correct row_size
	move.l	#$fefefefe,d4
	moveq	#7,d0

	TST.L	$54(A7)
	BNE	ReconBiMBlock__22
ReconBiMBlock__21:

	LEA	$d2(A0),A1

	lea	_clamp,a0
bimcm_all_rows3:
	REPT	2
	move.l	(a3)+,d1
	move.l	(a2)+,d3
	and.l	d4,d1
	and.l	d4,d3
	add.l	d1,d3
	roxr.l	#1,d3		; tricky! get bit #32 from the previous addition
	moveq	#0,d1
	move.b	d3,d1
	lsr.l	#8,d3
	moveq	#0,d6
	move.b	d3,d6
	lsr.w	#8,d3		; *grin evilly*  eadiz, peecee  *strut*
	add.l	(a1)+,d3
	move.w	d3,d7
	swap	d3
	move.w	(a0,d3.w*2),d3
	move.b	(a0,d7.w*2),d3
	swap	d3
	add.w	(a1)+,d6
	add.w	(a1)+,d1
	move.w	(a0,d6.w*2),d3
	move.b	(a0,d1.w*2),d3
	move.l	d3,(a5)+
	ENDR
	add.l	d2,a5
	add.l	d2,a3
	add.l	d2,a2
	dbra	d0,bimcm_all_rows3

	BRA.s	ReconBiMBlock__23
ReconBiMBlock__22:

bim_all_rows3:
	REPT	2
	move.l	(a3)+,d1
	move.l	(a2)+,d7
	and.l	d4,d1
	and.l	d4,d7
	add.l	d1,d7
	roxr.l	#1,d7			; tricky! get bit no 32 from the previous addition
	move.l	d7,(a5)+		; this one kicks ass !!!
	ENDR
	add.l	d2,a5
	add.l	d2,a3
	add.l	d2,a2
	dbra	d0,bim_all_rows3

ReconBiMBlock__23:
	MOVEM.L	(A7)+,D2-D7/A2/A3/A5/A6
	ADD.W	#$1c,A7
	RTS


	END