;==============================================================================
; Efektywny algorytm chunky-to-planar
; Konwertuje 32 piksele w 8 bitplanach.
;
; Autor: Robert Szacki
; 13 stycznia 2019
;==============================================================================

;==============================================================================
; Przydatne makra
;==============================================================================
merge	macro
	move.l	\1,d0
	move.l	\2,d1

	and.l	\3,\1
	and.l	\3,d1

	eor.l	\1,d0
	eor.l	d1,\2

	lsl.l	#\4,d0
	lsr.l	#\4,d1

	or.l	d1,\1
	or.l	d0,\2
	endm

merge2	macro
	move.l	\1,d0
	
	and.l	\2,\1
	eor.l	\1,d0

	lsr.w	#2,d0
	swap	d0
	lsl.w	#2,d0

	or.l	d0,\1
	endm

merge3	macro
	swap	\1
	eor.w	\1,\2
	eor.w	\2,\1
	eor.w	\1,\2
	swap	\1
	endm


;==============================================================================
; Przygotowanie masek
;==============================================================================
constants:

	move.l	#$f0f0f0f0,a6
	move.l	#$cccc3333,a5
	move.l	#$ff00ff00,a4
	move.l	#$aaaaaaaa,a3

;==============================================================================
; Początek konwersji
; a0: Adres pikseli chunky.
; a1: Adres końca bufora na piksele planarne.
; a2: Adres końca pomocniczego bufora na pośrednie wyniki dla bitplanów 4-7
;==============================================================================
c2p_pass1:

; Konwersja pod kątem jak najwyższej liczby pikseli

	move.l	a6,d7

	move.l	(a0)+,d2
	move.l	(a0)+,d3

	merge	d2,d3,d7,4

	move.l	(a0)+,d4
	move.l	(a0)+,d5

	merge	d4,d5,d7,4

; Zapamiętać w pamięci wyniki obliczeń (d2/d4)

	move.l	d2,-(a2)
	move.l	d4,-(a2)

	move.l	(a0)+,d2
	move.l	(a0)+,d4

	merge	d2,d4,d7,4

; Zapamiętać w pamięci wyniki obliczeń (d2)

	move.l	d2,-(a2)

	move.l	(a0)+,d2
	move.l	(a0)+,d6

	merge	d2,d6,d7,4

	move.l	d2,-(a2)

; W rejestrach d3/d5/d4/d6 mamy 32 piksele po 4 bitplany
; Konwertujemy dalej	

	move.l	a5,d7

	merge2	d3,d7
	merge2	d5,d7
	merge2	d4,d7
	merge2	d6,d7

	move.l	a4,d7

	merge	d3,d5,d7,8
	merge	d4,d6,d7,8

	move.l	a3,d7

	merge	d3,d5,d7,1
	merge	d4,d6,d7,1

	merge3	d3,d4
	merge3	d5,d6

; Gotowe bitplany 0-3
; Więcej niż połowa pracy za nami :)

; d3: a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 A3B3C3D3E3F3G3H3 I3J3K3L3M3N3O3P3
; d4: a1b1c1d1e1f1g1h1 i1j1k1l1m1n1o1p1 A1B1C1D1E1F1G1H1 I1J1K1L1M1N1O1P1
; d5: a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2 A2B2C2D2E2F2G2H2 I2J2K2L2M2N2O2P2
; d6: a0b0c0d0e0f0g0h0 i0j0k0l0m0n0o0p0 A0B0C0D0E0F0G0H0 I0J0K0L0M0N0O0P0

; Zapis
;==============================================================================
; Zapis pikseli planarnych bitplanów 0-3
;==============================================================================
	movem.l	d3-d6,-(a1)

;==============================================================================
; Kontynuacja konwersji bitplanów 4-7
;==============================================================================
c2p_pass2:

	movem.l	(a2)+,d2-d5
	
	move.l	a5,d7
	
	merge2	d5,d7
	merge2	d4,d7
	merge2	d3,d7
	merge2	d2,d7

	move.l	a4,d7

	merge	d5,d4,d7,8
	merge	d3,d2,d7,8

	move.l	a3,d7

	merge	d5,d4,d7,1
	merge	d3,d2,d7,1

	merge3	d5,d3
	merge3	d4,d2

; Gotowe bitplany 4-7
;==============================================================================
; Zapis pikseli planarnych bitplanów 4-7
;==============================================================================
	movem.l	d2-d5,-(a1)

	rts