
*
*   c2p15.s - conversion routine from 15 bit hicolour to HAM8
*   Copyright (C) 1997 Aki Laukkanen
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation; either version 2 of the License, or
*   (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program; if not, write to the Free Software Foundation,
*   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*

	include "exec/types.i"
	include "exec/memory.i"
	include "dos/dos.i"

	include "lvo/exec_lib.i"
	include "lvo/dos_lib.i"
	include "lvo/graphics_lib.i"

	include "mmu.i"
	include "evd_context.i"
	include "evd_prefs.i"

	XDEF    _c2p15
	XDEF    @c2p15
	XDEF    _c2p15_reloc
	XDEF    @c2p15_reloc
	XDEF    _c2p15_deinit
	XDEF    @c2p15_deinit

	XREF    _evd_loadham8

*
*   SYNOPSIS
*       void __asm CalcLut( register __a0 context *ct);
*
*   FUNCTION
*
*       To calculate the table used to convert single truecolour
*       pixel to HAM8 pixel.
*

	cnop    0,16

; a2: context

_get_lut
	movem.l d2-d3/a6,-(sp)
	move.w  (ct_UsedPalette,a2),d0
	mulu.w  #pe_SIZEOF,d0
	move.l  (ct_Palettes,a2),a0
	lea     (a0,d0.l),a0
	move.l  a0,-(sp)
	lea     (pe_rgb,a0),a0
	jsr     _evd_loadham8
	move.l  (sp)+,a0
	move.l  (ct_DOSBase,a2),a6
	move.l  (pe_off_cached_palname,a0),d1
	move.l  #MODE_OLDFILE,d2
	jsr     (_LVOOpen,a6)
	tst.l   d0
	beq     .error
	move.l  d0,d1
	move.l  d0,-(sp)
	move.l  (ct_Lut15,a2),d2
	move.l  #3*32768,d3
	jsr     (_LVORead,a6)
	move.l  (sp)+,d1
	move.l  d0,d2
	jsr     (_LVOClose,a6)
	cmp.l   #3*32768,d2
	bne     .error
	movem.l (sp)+,d2-d3/a6
	moveq   #1,d0
	rts
.error
	movem.l (sp)+,d2-d3/a6
	moveq   #0,d0
	rts

	cnop    0,16

_c2p15_reloc
@c2p15_reloc
	movem.l a2/a6,-(sp)
	move.l  a0,a2
	move.l  (ct_SysBase,a2),a6
	move.l  #3*32768,d0
	move.l  #MEMF_FAST,d1
	jsr     (_LVOAllocVec,a6)
	move.l  d0,(ct_Lut15,a2)
	beq     .fail
	bsr     _get_lut
	tst.l   d0
	beq     .fail2
	move.l  #_c2p15_end-_c2p15,d0
	move.l  #MEMF_FAST,d1
	jsr     (_LVOAllocVec,a6)
	tst.l   d0
	beq     .fail2
	move.l  d0,a0
	lea     _c2p15,a1
	move.w  #_c2p15_end-_c2p15-1,d1
.loop
	move.b  (a1)+,(a0)+
	dbf     d1,.loop

	move.l  d0,a0
	move.l  (ct_ChunkyBuffer,a2),d1
	add.l   (ct_Size,a2),d1
	move.l  d1,(c2p15_chunkyend1-_c2p15,a0)
	move.l  d1,(c2p15_chunkyend2-_c2p15,a0)
	move.l  d1,(c2p15_chunkyend3-_c2p15,a0)
	move.l  d1,(c2p15_chunkyend4-_c2p15,a0)
	move.l  d1,(c2p15_chunkyend5-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+4,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p1_1-_c2p15,a0)
	move.l  d1,(c2p15_p1_2-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+8,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p2_1-_c2p15,a0)
	move.l  d1,(c2p15_p2_2-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+12,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p3_1-_c2p15,a0)
	move.l  d1,(c2p15_p3_2-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+16,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p4_1-_c2p15,a0)
	move.l  d1,(c2p15_p4_2-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+20,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p5_1-_c2p15,a0)
	move.l  d1,(c2p15_p5_2-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+24,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p6_1-_c2p15,a0)
	move.l  d1,(c2p15_p6_2-_c2p15,a0)
	move.l  (ct_BitMap+bm_Planes+28,a2),d1
	sub.l   (ct_BitMap+bm_Planes,a2),d1
	move.l  d1,(c2p15_p7_1-_c2p15,a0)
	move.l  d1,(c2p15_p7_2-_c2p15,a0)

	movem.l d2-d4,-(sp)
	move.l  (ct_Lut15,a2),d2
	move.l  d2,d3
	add.l   #32768,d3
	move.l  d2,d4
	add.l   #65536,d4

	move.l  d2,(c15_lutr_1-_c2p15,a0)
	move.l  d3,(c15_lutg_1-_c2p15,a0)
	move.l  d4,(c15_lutb_1-_c2p15,a0)
	move.l  d2,(c15_lutr_2-_c2p15,a0)
	move.l  d3,(c15_lutg_2-_c2p15,a0)
	move.l  d4,(c15_lutb_2-_c2p15,a0)
	move.l  d2,(c15_lutr_3-_c2p15,a0)
	move.l  d3,(c15_lutg_3-_c2p15,a0)
	move.l  d4,(c15_lutb_3-_c2p15,a0)
	move.l  d2,(c15_lutr_4-_c2p15,a0)
	move.l  d3,(c15_lutg_4-_c2p15,a0)
	move.l  d4,(c15_lutb_4-_c2p15,a0)
	move.l  d2,(c15_lutr_5-_c2p15,a0)
	move.l  d3,(c15_lutg_5-_c2p15,a0)
	move.l  d4,(c15_lutb_5-_c2p15,a0)
	move.l  d2,(c15_lutr_6-_c2p15,a0)
	move.l  d3,(c15_lutg_6-_c2p15,a0)
	move.l  d4,(c15_lutb_6-_c2p15,a0)
	move.l  d2,(c15_lutr_7-_c2p15,a0)
	move.l  d3,(c15_lutg_7-_c2p15,a0)
	move.l  d4,(c15_lutb_7-_c2p15,a0)
	move.l  d2,(c15_lutr_8-_c2p15,a0)
	move.l  d3,(c15_lutg_8-_c2p15,a0)
	move.l  d4,(c15_lutb_8-_c2p15,a0)
	move.l  d2,(c15_lutr_9-_c2p15,a0)
	move.l  d3,(c15_lutg_9-_c2p15,a0)
	move.l  d4,(c15_lutb_9-_c2p15,a0)
	move.l  d2,(c15_lutr_10-_c2p15,a0)
	move.l  d3,(c15_lutg_10-_c2p15,a0)
	move.l  d4,(c15_lutb_10-_c2p15,a0)
	move.l  d2,(c15_lutr_11-_c2p15,a0)
	move.l  d3,(c15_lutg_11-_c2p15,a0)

	move.l  d2,(c15_lutr_20-_c2p15,a0)
	move.l  d3,(c15_lutg_20-_c2p15,a0)
	move.l  d4,(c15_lutb_20-_c2p15,a0)
	move.l  d2,(c15_lutr_21-_c2p15,a0)
	move.l  d3,(c15_lutg_21-_c2p15,a0)
	move.l  d4,(c15_lutb_21-_c2p15,a0)
	move.l  d2,(c15_lutr_22-_c2p15,a0)
	move.l  d3,(c15_lutg_22-_c2p15,a0)
	move.l  d4,(c15_lutb_22-_c2p15,a0)
	move.l  d2,(c15_lutr_23-_c2p15,a0)
	move.l  d3,(c15_lutg_23-_c2p15,a0)
	move.l  d4,(c15_lutb_23-_c2p15,a0)
	move.l  d2,(c15_lutr_24-_c2p15,a0)
	move.l  d3,(c15_lutg_24-_c2p15,a0)
	move.l  d4,(c15_lutb_24-_c2p15,a0)
	move.l  d2,(c15_lutr_25-_c2p15,a0)
	move.l  d3,(c15_lutg_25-_c2p15,a0)
	move.l  d4,(c15_lutb_25-_c2p15,a0)
	move.l  d2,(c15_lutr_26-_c2p15,a0)
	move.l  d3,(c15_lutg_26-_c2p15,a0)
	move.l  d4,(c15_lutb_26-_c2p15,a0)
	move.l  d2,(c15_lutr_27-_c2p15,a0)
	move.l  d3,(c15_lutg_27-_c2p15,a0)
	move.l  d4,(c15_lutb_27-_c2p15,a0)
	move.l  d2,(c15_lutr_28-_c2p15,a0)
	move.l  d3,(c15_lutg_28-_c2p15,a0)
	move.l  d4,(c15_lutb_28-_c2p15,a0)
	move.l  d2,(c15_lutr_29-_c2p15,a0)
	move.l  d3,(c15_lutg_29-_c2p15,a0)
	move.l  d4,(c15_lutb_29-_c2p15,a0)
	move.l  d2,(c15_lutr_30-_c2p15,a0)
	move.l  d3,(c15_lutg_30-_c2p15,a0)
	movem.l (sp)+,d2-d4
	move.l  d0,a2
	jsr     (_LVOCacheClearU,a6)
	move.l  a2,d0
.fail
	movem.l (sp)+,a2/a6
	rts
.fail2
	move.l  (ct_Lut15,a2),a1
	jsr     (_LVOFreeVec,a6)
	clr.l   d0
	movem.l (sp)+,a2/a6
	rts

	cnop    0,16

_c2p15_deinit
@c2p15_deinit
	movem.l a2/a6,-(sp)
	move.l  a0,a2
	move.l  (ct_SysBase,a2),a6
	move.l  (ct_C2P,a2),a1
	jsr     (_LVOFreeVec,a6)
	clr.l   (ct_C2P,a2)
	move.l  (ct_Lut15,a2),a1
	jsr     (_LVOFreeVec,a6)
	clr.l   (ct_Lut15,a2)
	movem.l (sp)+,a2/a6
	rts

	cnop    0,16

_c2p15
@c2p15
	movem.l d2-d7/a2-a6,-(sp)

	move.l  (ct_ChunkyBuffer,a0),a1
	move.l  (ct_DeltaBuffer,a0),a3
	move.l  (ct_PageDesc,a0),a4
	move.l  (ct_BitMap+bm_Planes,a0),a2

	move.l  a1,a5                       ; a5 : end of the MMU page
c2p15_loop
	add.l   #$1000,a5

	cmp.l   #$DEADBEEF,a5               ; test with the end of the chunky buffer
c2p15_chunkyend1 EQU *-4                ; self modify
	bls     c2p15_skip_move
	move.l  #$DEADBEEF,a5
c2p15_chunkyend2 EQU *-4
c2p15_skip_move
	move.l  (a4)+,a0                    ; fetch the page descriptor
	move.l  (a0),d0
	btst    #PDB_M,d0
	bne     c2p15_skip

	adda.l  #$1000,a1                   ; update chunky buffers
	add.l   #$100,a2                    ; update BitPlane pointers
	adda.l  #$1000,a3

	cmp.l   #$DEADBEEF,a1               ; check if more to c2p
c2p15_chunkyend3 EQU *-4
	bcs     c2p15_loop

	movem.l (sp)+,d2-d7/a2-a6
	rts

	cnop    0,16

c2p15_skip
	bclr    #PDB_M,d0                   ; modified bit was set
	move.l  d0,(a0)
c2p15_iloop

	move.l  a1,a0                       ; chunkybuffer -> a0
	move.l  a3,d5                       ; deltabuffer -> a0

	cmp.l   (a1)+,(a3)+                 ; compare chunky and delta buffers
	bne.w   c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+                 ; compare chunky and delta buffers
	bne.w   c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+                 ; compare chunky and delta buffers
	bne.w   c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+                 ; compare chunky and delta buffers
	bne.w   c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first
	cmp.l   (a1)+,(a3)+
	bne     c2p15_found_first

	addq.l  #4,a2                       ; update bitplane and chunky pointers

	cmp.l   a5,a1                       ; check if end of the current page
	bcs     c2p15_iloop

	cmp.l   #$DEADBEEF,a1               ; check if end of the chunky buffer
c2p15_chunkyend4 EQU *-4
	bcs     c2p15_loop

	movem.l (sp)+,d2-d7/a2-a6
	rts

	cnop    0,16

c2p15_found_first
	move.l  a0,a6                       ; address from where we should start c2ping
c2p15_found
	move.l  d5,a3                       ; backup these
	move.l  a0,a1

	move16  (a1)+,(a3)+                 ; use move16 to copy the data to
										; deltabuffer - fastest way
										; by far because it uses burst writes and no copyback
	move16  (a1)+,(a3)+
	move16  (a1)+,(a3)+
	move16  (a1)+,(a3)+

	move.l  a3,d5                       ; update backups
	move.l  a1,a0

	cmp.l   a5,a1                       ; this page
	bcc.s   c2p15_c2p                   ; end of so lets start c2ping

	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found
	cmp.l   (a3)+,(a1)+
	bne.s   c2p15_found

c2p15_c2p
	move.l  a3,-(sp)
	move.l  a4,-(sp)
	move.l  a5,-(sp)
c2p15_start
; a6 - chunky
; a0 - end
; a2 - bitplanes
	move.w  (a6),a1
	move.w  ($12341234,a1),d0
c15_lutr_1 EQU *-4
	move.w  (8*2,a6),a1
	move.b  ($12341234,a1),d0
c15_lutg_1 EQU *-4
	move.w  (16*2,a6),a1
	swap    d0
	move.w  ($12341234,a1),d0
c15_lutb_1 EQU *-4
	move.w  (24*2,a6),a1
	move.b  ($12341234,a1),d0
c15_lutr_2 EQU *-4

	move.w  (4*2,a6),a1
	move.w  ($12341234,a1),d1
c15_lutg_2 EQU *-4
	move.w  (12*2,a6),a1
	move.b  ($12341234,a1),d1
c15_lutb_2 EQU *-4
	move.w  (20*2,a6),a1
	swap    d1
	move.w  ($12341234,a1),d1
c15_lutr_3 EQU *-4
	move.w  (28*2,a6),a1
	move.b  ($12341234,a1),d1
c15_lutg_3 EQU *-4

	move.w  (1*2,a6),a1
	move.w  ($12341234,a1),d2
c15_lutb_3 EQU *-4
	move.w  (9*2,a6),a1
	move.b  ($12341234,a1),d2
c15_lutr_4 EQU *-4
	move.w  (17*2,a6),a1
	swap    d2
	move.w  ($12341234,a1),d2
c15_lutg_4 EQU *-4
	move.w  (25*2,a6),a1
	move.b  ($12341234,a1),d2
c15_lutb_4 EQU *-4

	move.w  (5*2,a6),a1
	move.w  ($12341234,a1),d3
c15_lutr_5 EQU *-4
	move.w  (13*2,a6),a1
	move.b  ($12341234,a1),d3
c15_lutg_5 EQU *-4
	move.w  (21*2,a6),a1
	swap    d3
	move.w  ($12341234,a1),d3
c15_lutb_5 EQU *-4
	move.w  (29*2,a6),a1
	move.b  ($12341234,a1),d3
c15_lutr_6 EQU *-4

	move.w  (2*2,a6),a1
	move.w  ($12341234,a1),d4
c15_lutg_6 EQU *-4
	move.w  (10*2,a6),a1
	move.b  ($12341234,a1),d4
c15_lutb_6 EQU *-4
	move.w  (18*2,a6),a1
	swap    d4
	move.w  ($12341234,a1),d4
c15_lutr_7 EQU *-4
	move.w  (26*2,a6),a1
	move.b  ($12341234,a1),d4
c15_lutg_7 EQU *-4

	move.w  (6*2,a6),a1
	move.w  ($12341234,a1),d5
c15_lutb_7 EQU *-4
	move.w  (14*2,a6),a1
	move.b  ($12341234,a1),d5
c15_lutr_8 EQU *-4
	move.w  (22*2,a6),a1
	swap    d5
	move.w  ($12341234,a1),d5
c15_lutg_8 EQU *-4
	move.w  (30*2,a6),a1
	move.b  ($12341234,a1),d5
c15_lutb_8 EQU *-4

	move.w  (3*2,a6),a1
	move.w  ($12341234,a1),d6
c15_lutr_9 EQU *-4
	move.w  (11*2,a6),a1
	move.b  ($12341234,a1),d6
c15_lutg_9 EQU *-4
	move.w  (19*2,a6),a1
	swap    d6
	move.w  ($12341234,a1),d6
c15_lutb_9 EQU *-4
	move.w  (27*2,a6),a1
	move.b  ($12341234,a1),d6
c15_lutr_10 EQU *-4

	move.w  (7*2,a6),a1
	move.w  ($12341234,a1),d7
c15_lutg_10 EQU *-4
	move.w  (15*2,a6),a1
	move.b  ($12341234,a1),d7
c15_lutb_10 EQU *-4
	move.w  (23*2,a6),a1
	swap    d7
	move.w  ($12341234,a1),d7
c15_lutr_11 EQU *-4
	move.w  (31*2,a6),a1
	move.b  ($12341234,a1),d7
c15_lutg_11 EQU *-4
	lea     (64,a6),a6
	move.l  d7,a1

; 2x4: (d0,d4),(d1,d5),(d2,d6)
; 2x4: (d3,d7)
; 1x2: (d0,d2),(d1,d3)
; 4x1: (d0,d1),(d2,d3)
; 1x2: (d4,d6),(d5,d7)
; 4x1: (d4,d5),(d6,d7)

; 2x4: (d0,d4),(d1,d5),(d2,d6)

	move.l  d4,d7
	lsr.l   #2,d7
	eor.l   d0,d7
	and.l   #$33333333,d7
	eor.l   d7,d0
	lsl.l   #2,d7
	eor.l   d7,d4

	move.l  d5,d7
	lsr.l   #2,d7
	eor.l   d1,d7
	and.l   #$33333333,d7
	eor.l   d7,d1
	lsl.l   #2,d7
	eor.l   d7,d5

	move.l  d6,d7
	lsr.l   #2,d7
	eor.l   d2,d7
	and.l   #$33333333,d7
	eor.l   d7,d2
	lsl.l   #2,d7
	eor.l   d7,d6

	exg     a1,d6               ; d7 -> d6

; 2x4: (d3,d7)

	move.l  d6,d7
	lsr.l   #2,d7
	eor.l   d3,d7
	and.l   #$33333333,d7
	eor.l   d7,d3
	lsl.l   #2,d7
	eor.l   d7,d6

; 1x2: (d0,d2),(d1,d3)

	move.l  d2,d7
	lsr.l   #1,d7
	eor.l   d0,d7
	and.l   #$55555555,d7
	eor.l   d7,d0
	add.l   d7,d7
	eor.l   d7,d2

	move.l  d3,d7
	lsr.l   #1,d7
	eor.l   d1,d7
	and.l   #$55555555,d7
	eor.l   d7,d1
	add.l   d7,d7
	eor.l   d7,d3

; 4x1: (d0,d1)

	move.l  d1,d7
	lsr.l   #4,d7
	eor.l   d0,d7
	and.l   #$0f0f0f0f,d7
	eor.l   d7,d0
	move.l  d0,($12341234,a2)
c2p15_p7_1 EQU *-4
	lsl.l   #4,d7
	eor.l   d7,d1

; 4x1: (d2,d3)

	move.l  d3,d7
	lsr.l   #4,d7
	eor.l   d2,d7
	and.l   #$0f0f0f0f,d7
	eor.l   d7,d2
	lsl.l   #4,d7
	eor.l   d7,d3

; 1x2: (d4,d6),(d5,d7)

	move.l  a1,d0               ; d6 -> d0
	move.l  d1,($12341234,a2)
c2p15_p3_1 EQU *-4

	move.l  d0,d7
	lsr.l   #1,d7
	eor.l   d4,d7
	and.l   #$55555555,d7
	eor.l   d7,d4
	add.l   d7,d7
	eor.l   d7,d0

	move.l  d6,d7
	lsr.l   #1,d7
	move.l  d2,($12341234,a2)
c2p15_p6_1 EQU *-4
	eor.l   d5,d7
	and.l   #$55555555,d7
	eor.l   d7,d5
	add.l   d7,d7
	eor.l   d7,d6

; 4x1: (d4,d5),(d6,d7)

	move.l  d5,d7
	lsr.l   #4,d7
	eor.l   d4,d7
	move.l  d3,($12341234,a2)
c2p15_p2_1 EQU *-4
	and.l   #$0f0f0f0f,d7
	eor.l   d7,d4
	lsl.l   #4,d7
	eor.l   d7,d5

	move.l  d6,d7
	lsr.l   #4,d7
	eor.l   d0,d7
	and.l   #$0f0f0f0f,d7
	move.l  d4,($12341234,a2)
c2p15_p5_1 EQU *-4
	eor.l   d7,d0
	lsl.l   #4,d7
	eor.l   d7,d6

	move.l  d5,a3
	move.l  d0,a4
	move.l  d6,a5

	cmp.l   a6,a0
	beq     c2p15_end
c2p15_x1
	move.w  (a6),a1
	move.w  ($12341234,a1),d0
c15_lutr_20 EQU *-4
	move.w  (8*2,a6),a1
	move.b  ($12341234,a1),d0
c15_lutg_20 EQU *-4
	move.w  (16*2,a6),a1
	swap    d0
	move.w  ($12341234,a1),d0
c15_lutb_20 EQU *-4
	move.w  (24*2,a6),a1
	move.b  ($12341234,a1),d0
c15_lutr_21 EQU *-4

	move.w  (4*2,a6),a1
	move.w  ($12341234,a1),d1
c15_lutg_21 EQU *-4
	move.w  (12*2,a6),a1
	move.b  ($12341234,a1),d1
c15_lutb_21 EQU *-4
	move.w  (20*2,a6),a1
	swap    d1
	move.w  ($12341234,a1),d1
c15_lutr_22 EQU *-4
	move.w  (28*2,a6),a1
	move.b  ($12341234,a1),d1
c15_lutg_22 EQU *-4

	move.w  (1*2,a6),a1
	move.w  ($12341234,a1),d2
c15_lutb_22 EQU *-4
	move.w  (9*2,a6),a1
	move.b  ($12341234,a1),d2
c15_lutr_23 EQU *-4
	move.w  (17*2,a6),a1
	swap    d2
	move.w  ($12341234,a1),d2
c15_lutg_23 EQU *-4
	move.w  (25*2,a6),a1
	move.b  ($12341234,a1),d2
c15_lutb_23 EQU *-4

	move.w  (5*2,a6),a1
	move.w  ($12341234,a1),d3
c15_lutr_24 EQU *-4
	move.w  (13*2,a6),a1
	move.b  ($12341234,a1),d3
c15_lutg_24 EQU *-4
	move.w  (21*2,a6),a1
	swap    d3
	move.w  ($12341234,a1),d3
c15_lutb_24 EQU *-4
	move.w  (29*2,a6),a1
	move.b  ($12341234,a1),d3
c15_lutr_25 EQU *-4

	move.w  (2*2,a6),a1
	move.w  ($12341234,a1),d4
c15_lutg_25 EQU *-4
	move.w  (10*2,a6),a1
	move.b  ($12341234,a1),d4
c15_lutb_25 EQU *-4
	move.w  (18*2,a6),a1
	swap    d4
	move.w  ($12341234,a1),d4
c15_lutr_26 EQU *-4
	move.w  (26*2,a6),a1
	move.b  ($12341234,a1),d4
c15_lutg_26 EQU *-4

	move.w  (6*2,a6),a1
	move.w  ($12341234,a1),d5
c15_lutb_26 EQU *-4
	move.w  (14*2,a6),a1
	move.b  ($12341234,a1),d5
c15_lutr_27 EQU *-4
	move.w  (22*2,a6),a1
	swap    d5
	move.w  ($12341234,a1),d5
c15_lutg_27 EQU *-4
	move.w  (30*2,a6),a1
	move.b  ($12341234,a1),d5
c15_lutb_27 EQU *-4

	move.w  (3*2,a6),a1
	move.w  ($12341234,a1),d6
c15_lutr_28 EQU *-4
	move.w  (11*2,a6),a1
	move.b  ($12341234,a1),d6
c15_lutg_28 EQU *-4
	move.w  (19*2,a6),a1
	swap    d6
	move.w  ($12341234,a1),d6
c15_lutb_28 EQU *-4
	move.w  (27*2,a6),a1
	move.b  ($12341234,a1),d6
c15_lutr_29 EQU *-4

	move.w  (7*2,a6),a1
	move.w  ($12341234,a1),d7
c15_lutg_29 EQU *-4
	move.w  (15*2,a6),a1
	move.b  ($12341234,a1),d7
c15_lutb_29 EQU *-4
	move.w  (23*2,a6),a1
	swap    d7
	move.w  ($12341234,a1),d7
c15_lutr_30 EQU *-4
	move.w  (31*2,a6),a1
	move.b  ($12341234,a1),d7
c15_lutg_30 EQU *-4
	move.l  a3,($12341234,a2)
c2p15_p1_1 EQU *-4
	lea     (64,a6),a6
	move.l  d7,a1

; 2x4: (d0,d3),(d1,d5),(d2,d6)

	move.l  d4,d7
	lsr.l   #2,d7
	eor.l   d0,d7
	and.l   #$33333333,d7
	eor.l   d7,d0
	lsl.l   #2,d7
	eor.l   d7,d4

	move.l  d5,d7
	lsr.l   #2,d7
	eor.l   d1,d7
	and.l   #$33333333,d7
	eor.l   d7,d1
	lsl.l   #2,d7
	eor.l   d7,d5

	move.l  d6,d7
	move.l  a4,($12341234,a2)
c2p15_p4_1 EQU *-4
	lsr.l   #2,d7
	eor.l   d2,d7
	and.l   #$33333333,d7
	eor.l   d7,d2
	lsl.l   #2,d7
	eor.l   d7,d6

	exg     a1,d6               ; d7 -> d6

; 2x4: (d3,d7)

	move.l  d6,d7
	lsr.l   #2,d7
	eor.l   d3,d7
	and.l   #$33333333,d7
	eor.l   d7,d3
	lsl.l   #2,d7
	eor.l   d7,d6

; 1x2: (d0,d2),(d1,d3)

	move.l  d2,d7
	lsr.l   #1,d7
	move.l  a5,(a2)+
	eor.l   d0,d7
	and.l   #$55555555,d7
	eor.l   d7,d0
	add.l   d7,d7
	eor.l   d7,d2

	move.l  d3,d7
	lsr.l   #1,d7
	eor.l   d1,d7
	and.l   #$55555555,d7
	eor.l   d7,d1
	add.l   d7,d7
	eor.l   d7,d3

; 4x1: (d0,d1)

	move.l  d1,d7
	lsr.l   #4,d7
	eor.l   d0,d7
	and.l   #$0f0f0f0f,d7
	eor.l   d7,d0
	move.l  d0,($12341234,a2)
c2p15_p7_2 EQU *-4
	lsl.l   #4,d7
	eor.l   d7,d1

; 4x1: (d2,d3)

	move.l  d3,d7
	lsr.l   #4,d7
	eor.l   d2,d7
	and.l   #$0f0f0f0f,d7
	eor.l   d7,d2
	lsl.l   #4,d7
	eor.l   d7,d3

; 1x2: (d4,d6),(d5,d7)

	move.l  a1,d0               ; d6 -> d0
	move.l  d1,($12341234,a2)
c2p15_p3_2 EQU *-4

	move.l  d0,d7
	lsr.l   #1,d7
	eor.l   d4,d7
	and.l   #$55555555,d7
	eor.l   d7,d4
	add.l   d7,d7
	eor.l   d7,d0

	move.l  d6,d7
	lsr.l   #1,d7
	move.l  d2,($12341234,a2)
c2p15_p6_2 EQU *-4
	eor.l   d5,d7
	and.l   #$55555555,d7
	eor.l   d7,d5
	add.l   d7,d7
	eor.l   d7,d6

; 4x1: (d4,d5),(d6,d7)

	move.l  d5,d7
	lsr.l   #4,d7
	eor.l   d4,d7
	move.l  d3,($12341234,a2)
c2p15_p2_2 EQU *-4
	and.l   #$0f0f0f0f,d7
	eor.l   d7,d4
	lsl.l   #4,d7
	eor.l   d7,d5

	move.l  d6,d7
	lsr.l   #4,d7
	eor.l   d0,d7
	and.l   #$0f0f0f0f,d7
	move.l  d4,($12341234,a2)
c2p15_p5_2 EQU *-4
	eor.l   d7,d0
	lsl.l   #4,d7
	eor.l   d7,d6

	move.l  d5,a3
	move.l  d0,a4
	move.l  d6,a5

	cmp.l   a6,a0
	bne     c2p15_x1
c2p15_end
	move.l  a3,($12341234,a2)
c2p15_p1_2 EQU *-4
	move.l  a4,($12341234,a2)
c2p15_p4_2 EQU *-4
	move.l  a5,(a2)+
	addq.l  #4,a2
	lea     (64,a6),a1

	move.l  (sp)+,a5
	move.l  (sp)+,a4
	move.l  (sp)+,a3

	cmp.l   a5,a1
	bcs     c2p15_iloop
	beq     c2p15_skipper

	lea     (-64,a1),a1
	subq.l  #4,a2
c2p15_skipper
	cmp.l   #$DEADBEEF,a1
c2p15_chunkyend5 EQU *-4
	bcs     c2p15_loop

	movem.l (sp)+,d2-d7/a2-a6

	rts
_c2p15_end
