*************************************************************************
* 512*512/65535色 -> ８色変換
*************************************************************************
* void g8conv()
*************************************************************************

	.include	defines.mac

SHIFT1		equ 3		* /8
AND1		equ %111	* %8

	* 使用ワークエリア
	.xref		tonebuf0
	.xref		tonebuf1

SIZE_OF_X	equ	512
SIZE_OF_Y	equ	512
LIGHT		equ	%111110.shl.7	* これ以上の値になる時はドットＯＮにする
					* 整数化演算をするため＊１２８する（本当は＊１００）
		*	%111111.shl.7にすると白の部分の処理が異なる

*************************************************************************
* test routine
	.text

*	bsr	_g8conv
*	clr.w	-(sp)		* exit(0)
*	DOS	_EXIT2
*
*************************************************************************
* １ドット分変換

DOT_SUB	macro
local	blue1,red1,green1
	move.w	(a2),d0				* (GRAM).w -> d0
	move.w	d0,d3				* 青
	move.w	d0,d4				* 赤
	move.w	d0,d5				* 緑
	and.w	#1,d0				* 輝度
	lsl.w	#7,d0
	
	and.w	#%00000_00000_11111_1,d3	* 青＋輝度を取り出す
	lsl.w	#7,d3				* *128（整数演算のため）
	
	and.w	#%00000_11111_00000_0,d4	* 赤を取り出す
	add.w	d4,d4				* lsl.w #2,d4よりこのほうが速い
	add.w	d4,d4				* *128（整数演算のため）
	or.w	d0,d4				* 赤＋輝度
	
	and.w	d6,d5				* 緑を取り出す
	lsr.w	#3,d5				* *128（整数演算のため）
	or.w	d0,d5				* 緑＋輝度
	
	* +現在行バッファー
	add.w	(a0)+,d3			* 青
	add.w	(a0)+,d4			* 赤
	add.w	(a0)+,d5			* 緑
	
	* +carry
	move.l	d3,d0				* 青
	swap	d0
	add.w	d0,d3
	
	move.l	d4,d0				* 赤
	swap	d0
	add.w	d0,d4
	
	move.l	d5,d0				* 緑
	swap	d0
	add.w	d0,d5
	
	* 変換後ドット書き込み
	moveq.l	#0,d0
	cmp.w	d2,d3				* 青：ＯＮになる明るさは以上？
	blt	blue1				* no : <LIGHT
	sub.w	d2,d3				* -=LIGHT
	move.w	#%00000_00000_11111_0,d0	* on パターン
blue1:
	cmp.w	d2,d4				* 赤：ＯＮになる明るさは以上？
	blt	red1				* no : <LIGHT
	sub.w	d2,d4				* -=LIGHT
	or.w	#%00000_11111_00000_0,d0	* on パターン
red1:
	cmp.w	d2,d5				* 緑：ＯＮになる明るさは以上？
	blt	green1				* no : <LIGHT
	sub.w	d2,d5				* -=LIGHT
	or.w	d6,d0				* on パターン
green1:
	move.w	d0,(a2)+			* ドット書き込み
	
	endm

*************************************************************************
* 最初ドットの周りへの配分

DOT_MAWARI1	macro	reg
* reg=d3（青）, d4（赤）, d5（緑）
	move.w	reg,d0
	and.w	d7,d0			* tone%8
	lsr.w	#SHIFT1,reg		* tone/8 = carry
	move.w	reg,6(a1)		* carry -> 右下への送り分
	add.w	reg,d0			* (tone/8+tone%8:真下)
	add.w	reg,reg			* carry*2
	add.w	reg,d0			* (tone/8+tone%8:真下)+(carry*2:左下)
	move.w	d0,(a1)+		*  -> 真下への送り分
	add.w	reg,reg			* carry*2*2
	swap	reg			* reg.h.w=carry*4 -> 右への送り分
	endm

*************************************************************************
* 途中ドットの周りへの配分

DOT_MAWARI2	macro	reg
* reg=d3（青）, d4（赤）, d5（緑）
	move.w	reg,d0
	and.w	d7,d0			* tone%8
	lsr.w	#SHIFT1,reg		* tone/8 = carry
	move.w	reg,6(a1)		* carry -> 右下への送り分
	add.w	reg,d0			* tone/8+tone%8
	add.w	d0,(a1)+		*  -> 真下への送り分
	add.w	reg,reg			* carry*2
	add.w	reg,-8(a1)		* -> 左下への送り分
	add.w	reg,reg			* carry*2*2
	swap	reg			* reg.h.w=carry*4 -> 右への送り分
	endm

*************************************************************************
* 最終ドットの周りへの配分

DOT_MAWARI3	macro	reg
* reg=d3（青）, d4（赤）, d5（緑）
	move.w	reg,d0
	and.w	d7,d0			* tone%8
	lsr.w	#SHIFT1-1,reg		* tone/4 = carry*2
	add.w	reg,-6(a1)		* carry*2 -> 左下への送り分
	add.w	reg,d0			* (tone/8+tone%8:真下)+(tone/8:右下)=tone/8*2+tone%8
	add.w	d0,(a1)+		* -> 真下への送り分
	endm

*************************************************************************

	.xdef	_g8conv			* Ｃインターフェース
_g8conv:
	movem.l	d3-d7/a3-a4,-(sp)
	
	SUPERMODE			* SuperVisor mode
	move.l	d0,-(sp)		* save user mode stack pointer
	
	* 行バッファークリア
	move.l	#tonebuf0,a0		* tonebuf0/1はつながっているので連続で消す
	move.w	#SIZE_OF_X*3-1,d0	* *3 for 青赤緑 , -1 for dbra
l1:
	clr.l	(a0)+			* .wのところを.lにすることで倍の領域を消す
	dbra	d0,l1
	
	move.w	#%11111_00000_00000_0,d6 * 緑の読み出し/dot on パターン
	move.w	#AND1,d7		* %8のand.wパターン
	move.w	#LIGHT,d2		* ＤＯＴ　ＯＮになる明るさの値
	move.l	#GRAM,a2		* GRAM line top address
	move.l	#tonebuf0,a4		* a3=下のラインバッファー、a4=今のラインバッファー
	move.l	#tonebuf1,a3		* 最初のexgで入れ替わるから逆にしておく
	
	move.w	#SIZE_OF_Y-1,d1		* y
l2:
	exg	a3,a4			* a3=今のラインバッファー、a4=下のラインバッファー
					* １行毎に入れ替える
	move.l	a4,a1
	move.l	a3,a0
	
	* Ｘ方向展開
	* 行最初のドット
	moveq.l	#0,d3			* 青 : carry=0
	moveq.l	#0,d4			* 赤 : carry=0
	moveq.l	#0,d5			* 緑 : carry=0
	
	DOT_SUB				* ドット書き込み
					* 周りへの配分
	DOT_MAWARI1	d3		* 青
	DOT_MAWARI1	d4		* 赤
	DOT_MAWARI1	d5		* 緑
	
	* 中間の５１２−２ドット
	swap	d1
	move.w	#SIZE_OF_X-2-1,d1	* -1 for dbra
l3:
	DOT_SUB				* ドット書き込み
					* 周りへの配分
	DOT_MAWARI2	d3		* 青
	DOT_MAWARI2	d4		* 赤
	DOT_MAWARI2	d5		* 緑
	
	dbra	d1,l3			* x - loop
	swap	d1
	
	* 行最後のドット
	DOT_SUB				* ドット書き込み
					* 周りへの配分
	DOT_MAWARI3	d3		* 青
	DOT_MAWARI3	d4		* 赤
	DOT_MAWARI3	d5		* 緑
	
	dbra	d1,l2			* y - loop
	
	move.l	(sp)+,a1
	USERMODE			* to user mode
	movem.l	(sp)+,d3-d7/a3-a4
	rts

*************************************************************************
	.end
