; This source file is part of the LynxLib miscellaneous library by
; Robert Fischer, and is Copyright 1990 by Robert Fischer.  It costs no
; money, and you may not make money off of it, but you may redistribute
; it.  It comes with ABSOLUTELY NO WARRANTY.  See the file LYNXLIB.DOC
; for more details.
; To contact the author:
; 	Robert Fischer \\80 Killdeer Rd \\Hamden, CT   06517   USA
; 	(203) 288-9599     fischer-robert@cs.yale.edu

.include "atari.s"
; This is the companion .S file for colsw.c

; This is test code:
;	Physbase
;	move.l	d0, d7
;	Fopen	#test, #0
;	move.l	d0, d6
;	Fread 	d6, #128, #buf
;	Fread	d6, #32000, d7
;	Fclose	d6

;	move.l	#pal, -(sp)
;	move.l	d7, -(sp)
;	bsr.s	_change_colors
;	addq.l	#8, sp

*	Physbase
*	move.l	d0, d7
*	Fcreate	#test2, #0
*	move.l	d0, d6
*	Fwrite	d6, #128, #buf
*	Fwrite	d6, #32000, d7
*	Fclose	d6

;	Cnecin
;	Pterm0
;*-------------------------------------------------------------

_switch_colors:: .cargs .pic.l, .pal.l
;* Does the main work.
;* .pic: the pointer to the 32000 bytes of picture
;* .pal: the pointer to the 16 words of color changing information.
;*       This will change color x to color x(.pal)
;
;*	Register use:
;*		a0: current point in picture
;*		a1: pointer to palette
;*		a3: last byte in picture + 1
;*		a4: temporary

;*		d0: word 0 in a set of four words which represent four bit planes
;*		d1: word 1.......
;*		d2: word 2.......
;*		d3: word 3.......
;*		d4: temp
;*		d5: color word
;*		d6, d7: temp
	move.l	4(sp), a0		;* Picture stuff
	move.l	8(sp), a1		;* Palette stuff

	;* Convert the 1*16 table of colors to 16*16
	;* a4 is memory counter
	;* d0 is counter for rows
	;* d1 is counter for the columns
	;* d2 is the high-order nybble for the rows
	move.l	sp, a4
	sub.l	#256, sp
	move.w	#15, d0		;* Counter for the rows
	.maketab:
		move.b	0(a1, d0), d2	; Get high-order nybble
		lsl.b	#4, d2

		move.w	#15, d1
		.innermtab:
			;* d4 is the new color value for the low order
			;* d3 is a temporary
			move.b	0(a1, d1), d4
			or.b	d2, d4
			move.b	d4, -(a4)
		dbra d1, .innermtab		;* Stop when d1 goes < 0
	dbra	d0, .maketab		;* Stop when d0 goes < 0

	;* Load up all the registers
	move.l	a4, a1
	lea		32000(a0), a3

	.startloop:
	cmpa.l	a3, a0		;* for (; a0 < a3; a0 += 8) {
	beq		.endloop

.macro LDREG xreg, xoffset
	move.w	\xoffset(a0), \xreg	;* Load up the d registers for this
	swap	\xreg
	move.w	8+\xoffset(a0), \xreg
.endm

		LDREG	d0, 0	; Load up the registers
		LDREG	d1, 2
		LDREG	d2, 4
		LDREG	d3, 6

		bsr.s		transpose

		movem.l		d0/d1/d2/d3, regsv	; Put in temporary memory

		lea			regsv, a4		; Do the actual lookup work
		move.w	#16, d4
		.workloop:
			move.b	(a4), d5		; Look up 1 byte at a time
			move.b	0(a1, d5), (a4)+
		dbra	d4, .workloop

		movem.l		regsv, d0/d1/d2/d3

		bsr.s		transpose

.macro SVREG xreg, xoffset
	move.w	\xreg, 8+\xoffset(a0)	;* Save the d registers for this
	swap	\xreg
	move.w	\xreg, \xoffset(a0)
.endm

		SVREG	d0, 0	; Save the registers
		SVREG	d1, 2
		SVREG	d2, 4
		SVREG	d3, 6

	add.l	#16, a0
	bra		.startloop
	.endloop:

	lea		256(sp), sp	;* Pop our table off the stack

	rts
;*-------------------------------------------------------------

		; Transpose the matrix
.macro TRANSPOSE reg1, reg2, bits
	move.l	\reg1, d6	; Make 1st set of alternating bits
	and.l	d4, d6
	eor.l	d6, \reg1
	move.l	\reg2, d7	; Make 2nd set of alternating bits
	and.l	d4, \reg2
	eor.l	\reg2, d7
	lsl.l	#\bits, d6	; Mesh the bits
	lsr.l	#\bits, d7
	or.l	d6, \reg2
	or.l	d7, \reg1
.endm

mask2 = %00110011001100110011001100110011
mask1 = %01010101010101010101010101010101
transpose:
	move.l		#mask2, d4
	TRANSPOSE	d3, d1, 2
	TRANSPOSE	d2, d0, 2
	move.l		#mask1, d4
	TRANSPOSE	d3, d2, 1
	TRANSPOSE	d1, d0, 1
	rts



	.data
test: dc.b "TEST.NEO"
test2: dc.b "TEST2.NEO"
pal: dc.w 0, 15, 1, 2, 4, 6, 3, 5, 7, 8, 9, 10, 12, 14, 11, 13
;pal: dc.b 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
;pal: dc.b 15, 14, 13, 12, 11, 10, 9,8,7,6,5,4,3,2,1,0
	.bss
buf: ds.b	128
regsv: ds.l	4
