*************************************************************************
* 512*512/65535色 -> 白黒変換
* この中では画面の初期化はしないので外部で行なうこと
*************************************************************************
* void gbwconv()
*************************************************************************

	.include	defines.mac

	* 使用ワークエリア
	.xref		btonebuf0
	.xref		btonebuf1

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

	.text
*
*	bsr	_gbwconv
*	clr.w	-(sp)		* exit(0)
*	DOS	_EXIT2
*
*************************************************************************

SIZE_OF_X	equ	512
SIZE_OF_Y	equ	512
WHITE		equ	6200	* 白になる明るさの値
				* 計算値では6300であるが、それでは白部分
				* にノイズが入るので、実験の結果この値にした
*************************************************************************
* ドット配分表（カラー版もみんな同じ）
* 最初		     途中		  最後
* ＠　4/8	     ＠   4/8		　＠
* 2/8		2/8　1/8　1/8	     2/8　1/8
* 1/8		     余り		　1/8
* 余り					　余り
*************************************************************************
* １ドット分変換（高速化のためマクロ展開する）

DOT_SUB	macro
local	gb5
	move.w	(a2),d0		* (GRAM).w -> d0
	move.w	d0,d3
	move.w	d0,d4
	and.w	#1,d0		* d0=輝度
	
	and.w	d7,d3		* 青ビット取り出し
	or.w	d0,d3		* d3=青
	
	lsr.w	#5,d4
	move.w	d4,d5
	and.w	d7,d4		* 赤ビット取り出し
	or.w	d0,d4		* d4=赤
	
	lsr.w	#5,d5
	and.w	d7,d5		* 緑ビット取り出し
	or.w	d0,d5		* d5=緑
	
	* 緑*59 : 59=64-4-1=64-(4+1)
	move.w	d5,d0
	add.w	d0,d0		* *2
	add.w	d0,d0		* *2 : lsl.w #2,d0 よりこのほうが速いから
	add.w	d5,d0		* *(4+1)
	lsl.w	#6,d5		* *64
	sub.w	d0,d5		* 64-(4+1)
	
	* 赤*30 = (32-2)
	move.w	d4,d0
	add.w	d0,d0		* *2
	lsl.w	#5,d4		* *32
	sub.w	d0,d4		* 32-2
	
	* 青*11 = (8+2+1)
	move.w	d3,d0
	add.w	d0,d0		* *2
	add.w	d3,d0		* *(2+1)
	lsl.w	#3,d3		* *8
	add.w	d0,d3		* 8+2+1
	
	add.w	d5,d3
	add.w	d4,d3		* 緑＊５９＋赤＊３０＋青＊１１
	
	add.w	(a0)+,d3	* +現在行バッファー
	add.w	d2,d3		* +carry -> tone(d3)
	
	* 変換後ドット書き込み
	moveq.l	#0,d0		* 黒パターン
	cmp.w	d6,d3		* 白になる明るさは以上？
	blt	gb5		* <WHITE
	* d3>=WHITE
	sub.w	d6,d3		* -=WHITE
	moveq.l	#-2,d0		* -2=$ffff_fffe：白パターン
				* 最下位ビット＝輝度ビットは入れない（Z'sSTAFF/PIC対応）
gb5:
	move.w	d0,(a2)+	* 書き込み
	
	endm

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

	.xdef	_gbwconv
_gbwconv:
	movem.l	d3-d7/a3-a4,-(sp)
	
	SUPERMODE		* SuperVisor mode
	move.l	d0,-(sp)	* save user mode stack pointer
	
	* 行バッファークリア
	move.l	#btonebuf0,a0	* btonebuf0/1はつながっているので連続で消す
	move.w	#SIZE_OF_X-1,d0	* -1 for dbra
gb1:
	clr.l	(a0)+		* .wのところを.lにすることで倍の領域を消す
	dbra	d0,gb1
	
	move.w	#WHITE,d6	* 白になる明るさ
	move.w	#%111110,d7	* 色信号取り出しＡＮＤパターン
	move.l	#GRAM,a2	* GRAM line top address
	move.l	#btonebuf0,a4	* a3=今のラインバッファー、a4=下のラインバッファー
	move.l	#btonebuf1,a3	* 最初のexgで入れ替わるから逆にしておく
	
	move.w	#SIZE_OF_Y-1,d1	* y
gb2:
	exg	a3,a4		* a3=今のラインバッファー、a4=下のラインバッファー
				* １行毎に入れ替える
	move.l	a4,a1
	move.l	a3,a0
	
	moveq.l	#0,d2		* carry=0
	
	* Ｘ方向展開
	* 行最初のドット
	DOT_SUB			* ドット書き込み
	move.w	d3,d0		* 周りへの配分
	and.w	#%111,d0	* tone%8
	lsr.w	#3,d3		* tone/8 = carry
	move.w	d3,2(a1)	* -> 右下への送り分
	add.w	d3,d0		* tone/8+tone%8
	add.w	d3,d3		* carry*2
	add.w	d3,d0		* (tone/8+tone%8:真下)+(carry*2:左下)
	move.w	d0,(a1)+	* -> 真下への送り分
	add.w	d3,d3		* carry*2*2
	move.w	d3,d2		* carry*=4 : 右隣への送り分
	
	* 中間の５１２−２ドット
	swap	d1
	move.w	#SIZE_OF_X-2-1,d1	* -1 for dbra
gb4:
	DOT_SUB			* ドット書き込み
	move.w	d3,d0		* 周りへの配分
	and.w	#%111,d0	* tone%8
	lsr.w	#3,d3		* tone/8 = carry
	move.w	d3,2(a1)	* -> 右下への送り分
	add.w	d3,d0		* tone/8+tone%8
	add.w	d3,d3		* carry*2
	add.w	d3,-2(a1)	* -> 左下への送り分
	add.w	d0,(a1)+	* tone/8+tone%8 -> 真下への送り分
	add.w	d3,d3		* carry*2*2
	move.w	d3,d2		* carry*=4 : 右隣への送り分
	
	dbra	d1,gb4		* x - loop
	swap	d1
	
	* 行最後のドット
	DOT_SUB			* ドット書き込み
	move.w	d3,d0		* 周りへの配分
	and.w	#%111,d0	* tone%8
	lsr.w	#2,d3		* tone/8*2
	add.w	d3,-2(a1)	* 左下への送り分
	add.w	d3,d0		* (tone/8+tone%8:真下)+(tone/8:右下)=tone/8*2+tone%8
	add.w	d0,(a1)		* -> 真下への送り分
				* 最後は右隣送りはいらない
	
	dbra	d1,gb2		* y - loop
	
	move.l	(sp)+,a1
	USERMODE		* to user mode
	movem.l	(sp)+,d3-d7/a3-a4
	rts

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