************************************************************
* 仮想テキスト画面圧縮（パターン＋色）
*   仮想的な圧縮により、_gettext3の必要なワークエリアサイズを得る
* void _calctext3(int adrs,unchar *buff)
* buff[0,1]=wx(text)
* buff[2,3]=wy(text)
* buff[12〜27]=code table(16)
* リターン
* use size of buff  -> buff[4,5,6,7]
* use size of cbuff -> buff[8,9,10,11]
************************************************************

	.include	defines.mac
	.include	getput3.mac

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

WRTLEN	macro	buff,wLIM,c
* d3.w = fl/fcl は破壊してもいい
* buff=a2,wLIM=CLIM,c=d5でこのままcsubになる
local	L1,L2,L3,L4
	cmp.w	#wLIM,d3	* len<wLIM?
	bcc	L1		* No
	* 長さ:1〜wLIM-1
*	or.b	c,d3		* 長さそのものを入れて記録
*	move.b	d3,(buff)+
	addq.l	#1,buff
	bra.s	L4
	*
L1:	cmp.w	#$ff+wLIM,d3	* len<=$ff+wLIM?
	bhi	L2		* No
	* 長さ:wLIM〜$ff+wLIM:8bit
*	move.b	c,(buff)+	* 長さのところには０が入る
*	sub.w	#wLIM,d3
*	move.b	d3,(buff)+
	addq.l	#2,buff
	bra.s	L4
	*
L2:	* 長さ:16bit
*	or.b	#wLIM,c		* 長さのところにはwLIMが入る
*	move.b	c,(buff)+
*	move.b	d3,1(buff)	* low
*	lsr.w	#8,d3
*	move.b	d3,(buff)	* high
	addq.w	#3,buff
L4:
	endm

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

GSUB	macro			* 圧縮コード出力
* d3.w = fl は破壊してもいい
	lsl.b	#SFT,d4
	or.b	#%10000000,d4	* BIT7=1
	WRTLEN	a0,LIM,d4
	endm

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

GSUB2	macro			* 長さ圧縮付きコード出力
local	L1,L2,L3,L4,L5,L6,L7
* d6.w = cl は破壊してもいい
	btst.l	#7,d5		* BIT7=1コード ?
	bne	L2		* Yes : 2byte
	cmp.b	#C16,d5		* 制御コード ?
	bhi	L1		* No : 1byte
L2:	* ２バイトコード
	* ２バイトコードは長さ＝１でなければ必ず圧縮される
	cmp.w	#1,d6		* 長さ＝１？
	bne	L3		* No
	* 長さ１の非圧縮出力
*	clr.b	(a0)+		* 2byte Symbol : move.b #C0,(a0)+
*	move.b	d5,(a0)+
	addq.l	#2,a0
	bra.s	L6

L1:	* １バイトコード：長さ＝４から圧縮
	cmp.w	#4,d6		* 長さ圧縮可能?
	blt	L4		* No
L3:	* 長さ圧縮可能
	cmp.w	#256,d6		* 長さ16bit?
	blt	L7		* No
	* 16bit長
*	move.b	#C16,(a0)+	* 識別子
*	move.b	d6,1(a0)	* low
*	lsr.w	#8,d6
*	move.b	d6,(a0)		* high
*	move.b	d5,(a0)+	* コード
	addq.l	#4,a0
	bra.s	L6

L7:	* 8bit長
*	move.b	#C8,(a0)+	* 識別子
*	move.b	d6,(a0)+	* 長さ
*	move.b	d5,(a0)+	* コード
	addq.l	#3,a0
	bra.s	L6

L4:	* 長さ圧縮不可
	subq.w	#1,d6		* -1 for dbra
L5:*	move.b	d5,(a0)+
	addq.l	#1,a0
	dbra	d6,L5
L6:
	endm

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

PRESS	macro
local	L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L31,CPRES,CPRES0
	* パターン読みだし
	move.b	(a5),d1		* plane 0
	move.b	(a6),d2		* plane 1
	move.b	d1,d0
	or.b	d2,d0
	* パターン圧縮
	cmp.b	d0,d5		* 直前のコードと同じ？
	bne	L1		* No
	* 直前のコードと同じ時 : c==bc
	tst.w	d3		* fl=0?
	beq	L2		* Yes
	addq.w	#1,d3		* fl++
	bra	CPRES

L2:	tst.w	d6		* cl=0?
	beq	L1		* Yes
	addq.w	#1,d6		* cl++
	bra	CPRES
	
L1:	* 直前のコードと違う c!=bc
	move.l	a1,a4		* a4=buff0
	rept	JOUI
	cmp.b	(a4)+,d0
	beq	L31
	endm
	* 非圧縮コード : 前のコードを出力
	tst.w	d6		* cl=0?
	beq	L6		* Yes
	* 圧縮していない
	GSUB2
	bra	L7

L6:	tst.w	d3		* fl=0?
	beq	L7		* Yes
	GSUB
	clr.w	d3		* fl=0
L7:	move.w	#1,d6		* cl=1
	bra	CPRES0

L31:	* 一致=圧縮コード : 前のコードを出力
	subq.w	#1,a4		* a4は1つ先に進んでいるから
	sub.l	a1,a4		* a4=no
	tst.w	d3		* fl=0?
	beq	L4		* No
	GSUB
	bra	L5

L4:	* 圧縮していない
	tst.w	d6		* cl=0?
	beq	L5		* No
	GSUB2
	clr.w	d6		* cl=0
L5:	move.w	#1,d3		* fl=1 : d3.h.wは色が使うからmoveq.lは使えない
	move.w	a4,d4		* fi=i : 圧縮コード番号
CPRES0:	move.b	d0,d5		* bc=c : コードを記録
CPRES:	* 色圧縮
	swap	d3		* 色は?.h.wを使う
	swap	d5
	* プレーン設定
	move.b	#%11<<CSFT,d7	* 白＆黒
	tst.b	d0		* 黒?
	beq	L9		* Yes
	tst.b	d1		* plane0あり?
	bne	L8		* Yes
	eor.b	#%01<<CSFT,d7	* plane0 none
L8:	tst.b	d2		* plane1あり？
	bne	L9		* No
	eor.b	#%10<<CSFT,d7	* plane1 none
L9:	cmp.b	d5,d7		* 前と同じ色?
	beq	L10		* Yes
	tst.w	d3		* fcl=0?
	beq	L11		* Yes
	WRTLEN	a2,CLIM,d5	* 前の色を出力
	clr.w	d3		* fcl=0
L11:	move.b	d7,d5		* 色記録
L10:	addq.w	#1,d3		* fcl++
	swap	d5
	swap	d3		* 色は?.h.wを使う
	endm

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

	.xdef	__calctext3
__calctext3:
	move.l	4(sp),a2	* text address
	move.l	8(sp),a0	* buff
	move.w	(a0)+,xx	* wx
	move.w	(a0)+,y		* wy/CHY
	addq.w	#4*2,a0		* skip size/csize
	movem.l	d3-d7/a3-a6,-(sp)
	
	SUPERMODE		* SuperVisor mode
	move.l	d0,-(sp)	* push SSP
	
	move.l	a2,a1		* address
	move.l	a1,a3		* VRAM初期アドレス(plane0)
	clr.l	a2		* cbuff
	move.l	a0,a1		* buff0=buff
	lea	JOUI(a0),a0	* buff+=JOUI
	moveq.l	#0,d3		* fl=fcl=0
	moveq.l	#0,d6		* cl=0
	move.l	#$0004_ffff,d5	* bcol=BIT2,bc=$ff
L1:	*
	move.l	a3,a5		* active VRAM address
	move.l	a3,a6
	add.l	#TPSIZE,a6	* plane1
	move.w	xx,x		* wx
L2:	*
	move.w	#CHY,yy		* 16lines=1char単位
L3:	PRESS			* 圧縮
	lea	TX(a5),a5	* next dot line
	lea	TX(a6),a6
	subq.w	#1,yy
	bne	L3
	*
	lea	1-TX*CHY(a5),a5	* next char
	lea	1-TX*CHY(a6),a6	* next char
	subq.w	#1,x
	bne	L2
	*
	lea	TX*CHY(a3),a3	* next text line
	subq.w	#1,y
	bne	L1
	
	* 残りコード出力
	tst.w	d3		* fl=0?
	beq	L4		* Yes
	GSUB			* 圧縮コード
	bra	L5
L4:	tst.w	d6		* cl=0?
	beq	L5		* Yes
	GSUB2			* 非圧縮コード
L5:	* 残り色出力
	swap	d3
	tst.w	d3		* fcl=0?
	beq	L6		* Yes
	swap	d5
	WRTLEN	a2,CLIM,d5	* 色圧縮コード
	* d3/d5はもう使わないので復帰しない
	*
L6:	sub.l	a1,a0		* buff-buff0
	lea	12(a0),a0	* headerの分(short*2+int*2)
	move.l	a0,-8(a1)	* buff size
	
	move.l	a2,-4(a1)	* cbuff size
	
	move.l	(sp)+,a1	* pop SSP
	USERMODE		* to user mode
	
	movem.l	(sp)+,d3-d7/a3-a6
	rts

*-----------------------------------------------------------
* work area
*-----------------------------------------------------------

	.even
	.bss
x:	.ds.w	1
y:	.ds.w	1
xx:	.ds.w	1
yy:	.ds.w	1

************************************************************
*	d0.b	c		a0	buff
*	d1.b	c1		a1	buff0
*	d2.b	c2		a2	cbuff(=cbuff size)
*	d3.w	fl/fcl		a3	VRAM Plane0
*	d4.b(w)	fi		a4	汎用
*	d5.b	bc/bcol		a5	active Plane 0
*	d6.w	cl		a6	active Plane 1
*	d7.w/.b	i/汎用		
************************************************************
	.end
