* テキスト画面pset3(tpset2のアクセスマスク使わない版)
* void tpset3(int planes,int x,int y,int sz,int fset)
*		4	  8	12	16	20
* planes : BIT0=plane0,BIT1=plane1,BIT2=plane2,BIT3=plane3
*	   同時に複数のプレーン指定可能
* sz	 : 1dotの大きさ:1,2,4,8,16のみ
* fset	 : 0=reset , 1=set
* x,y	 : 表示座標:0〜(1024/sz)-1
*
* この関数は指定した以外のプレーンを消さない。従って、確実のその色で描画するには
* 画面をクリアするか、fset=0で必要プレーンをクリアしておく。
* or/andが必要なので同時アクセスも使えない

	.include	defines.mac

.if	0
sz	=	4
x	=	10
y	=	10
	move.l	#1,-(sp)	* fset
	move.l	#sz,-(sp)	* sz
	move.l	#y,-(sp)	* y
	move.l	#x,-(sp)	* x
	move.l	#%0010,-(sp)	* planes
	bsr	_tpset3
	lea	4*5(sp),sp
	*
	move.l	#1,-(sp)	* fset
	move.l	#sz,-(sp)	* sz
	move.l	#y+1,-(sp)	* y
	move.l	#x+1,-(sp)	* x
	move.l	#%0001,-(sp)	* planes
	bsr	_tpset3
	lea	4*5(sp),sp
	*
	move.l	#1,-(sp)	* fset
	move.l	#sz,-(sp)	* sz
	move.l	#y+2,-(sp)	* y
	move.l	#x+2,-(sp)	* x
	move.l	#%0011,-(sp)	* planes
	bsr	_tpset3
	lea	4*5(sp),sp
	*
	clr.w	-(sp)
	DOS	_EXIT2
.endif

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

	.xdef	_tpset3
_tpset3:
	move.l	sp,a2
	SUPERMODE			* SuperVisor mode(a1破壊)
	move.l	d0,-(sp)		* save user mode stack pointer
	bsr	TPX3
	move.l	(sp)+,a1
	USERMODE			* to user mode
	rts

***********************************************************************
* _tpset3はTEXT-VRAMをアクセスするので、SuperVisor Modeにしておくこと

	.xdef	__tpset3
__tpset3:
	move.l	sp,a2
TPX3:
	movem.l	d3-d4,-(sp)
	* 座標取得＆判定→アドレスa0.l
	move.w	16+2(a2),d2	* sz(規定以外の時は無保証)
	lea	TPLANE0,a0	* TEXT-VRAM plane0先頭アドレス
	* x
	move.w	8+2(a2),d0	* x
	mulu.w	d2,d0		* x'=x*sz
	cmp.l	#1024-1,d0	* x'=0〜1023
	bhi	1f		* クリッピング外
	move.w	d0,a1		* x'保存
	lsr.l	#3,d0		* x'/8
	bclr.l	#0,d0		* 手抜きの関係で、xは偶数のみ
	add.l	d0,a0
	* y
	move.w	12+2(a2),d0	* y
	mulu.w	d2,d0		* y'=y*sz
	cmp.l	#1024-1,d0	* y'=0〜1023
	bhi	1f		* クリッピング外
	lsl.l	#7,d0		* y'*128
	add.l	d0,a0		* ドット書き込みオフセットアドレス
	*
	* ドットパターン作成→d1.w
	move.w	#$8000,d1	* bit15=1
	move.w	d2,d0		* sz
	subq.w	#1,d0		* sz-1
	beq	@f		* sz=1のときはd1.w=%1-0
	asr.w	d0,d1		* d1.w=%11-0(sz=2),%1111-0(sz=4),%11111111-0(sz=8)
@@:	move.w	a1,d0		* x'
	and.w	#$0f,d0		* x'%16
	lsr.w	d0,d1		* d1=dotパターン
@@:	*
	* a0.l = ドット書き込みアドレス
	moveq.l	#4-1,d3		* 4plane対象
	move.l	a0,a1		* 元アドレス保存
	move.w	4+2(a2),d0	* planes
	*
	subq.w	#1,d2		* for dbra
	tst.l	20(a2)		* set/reset
	bne	5f		* set
	* reset
	not.w	d1		* ドット消しはandなのでビット反転する
2:	move.l	a1,a0
	lsr.w	#1,d0
	bcc	3f		* このプレーンは対象外
	move.l	d2,d4		* ループカウンタ
@@:	and.w	d1,(a0)		* ドット消し
	lea	1024/8(a0),a0	* 次のライン
	dbra	d4,@b		* szライン分
3:	add.l	#TPSIZE,a1
	dbra	d3,2b		* planes
	bra	1f
*
5:	* set
	move.l	a1,a0
	lsr.w	#1,d0
	bcc	4f		* このプレーンは対象外
	move.l	d2,d4		* ループカウンタ
@@:	or.w	d1,(a0)		* ドット書き込み
	lea	1024/8(a0),a0	* 次のライン
	dbra	d4,@b		* szライン分
4:	add.l	#TPSIZE,a1
	dbra	d3,5b		* planes
	*
1:	* 表示できない座標の時はここに飛んでくる
	movem.l	(sp)+,d3-d4
	rts

* このプログラムは自己書き替えを使えばもっと小さくなる。
* が、当然キャッシュのあるＭＰＵでは駄目になるので今回は２重に書いている。

	.end
