*******************************************************************************
* FONTPUT/FONTPUT2共通ルーチンソース
*******************************************************************************
* FONTPUT : カーソル移動・改行・スクロールアップ対応
* FONTPUT2: カーソル移動のみ対応（改行スクロールアップなし）
*******************************************************************************
*	半角，１／２	全角
*	８＊１６	１６＊１６
*	１２＊２４	２４＊２４
*	１／４は　８＊　８→　８＊１６
*		１２＊１２→１２＊２４に拡張して渡すこと
*******************************************************************************
* V2.0：高速化
* V3.0：高速化＆小型化（同時アクセス利用）
* V3.1：２４ドット文字の表示行確保処理最適化

	.include	defines.mac
	
FNTPTS:				* a1 <- フォント構造体アドレス
	movem.l	d3-d5,-(sp)	* push registers
	
	move.l	a1,a0		* push a1（前バージョンとの互換性維持のため）
	SUPERMODE		* SuperVisor mode
	move.l	d0,spp		* save SSP
	move.l	a0,a1		* pop a1
	
	IOCS	_B_CUROFF	* カーソルを消しておかないと時々変になる
				* カーソルが下パターンを復帰しようとするから
	
	* フォントサイズ読み出し
	move.w	(a1)+,d1	* xl
	addq.w	#7,d1
	lsr.w	#3,d1		* (xl+7)/8 = byte数 -> d1
	move.w	(a1)+,d2	* yl -> d2
	* a1.l = font address
	
	* 自動改行＆表示後改行判定＆２４ライン文字時スクロールアップ
	.if	FCRLF==1
	clr.b	fcrlf		* 改行フラグクリア
	move.w	CURX,d0		* x
	add.w	d1,d0		* x+xbytes
	cmp.w	TXWDX,d0	* xwidth over ?
	ble	ac1		* no
	move.w	d2,d3		* push d2
	bsr	crlf24		* 自動改行
	move.w	d3,d2		* pop d2
	bra.s	ac2
	*
ac1:	bne	ac2		* 改行？ -> no
	* x+xbytes = xwidth : 表示後改行
	st	fcrlf		* 改行フラグ on
ac2:	cmp.w	#24,d2		* ２４ライン文字時スクロール対応処理
	bne	ac3		* ２４ライン文字ではない
	* ２４ドット文字で最下行にいる時は表示のため下１行を空ける
	move.w	TXWDY,d0	* .w 縦方向の表示桁数−１ = 最終行(ｽｸﾛｰﾙｴﾘｱは無視)
	cmp.w	CURY,d0		* ２４ドットでスクロールアップ可能性有り？
	bne	ac3		* ＮＯ
	IOCS	_B_DOWN_S	* １行下へ（スクロール付き）：これで２行分空く
	IOCS	_B_UP_S		* １行上へ（カーソルを戻す）
ac3:
	.endif
	
	* カーソル位置アドレス算出
	* text 1line = graphic 16lines , graphic 1line = 1024/8=128bytes
	* text 1line = 16*128=2048bytes
	* a0 <- plane 0 address
	move.l	#TPLANE0,a0	* plane 0 top address
	moveq.l	#0,d0		* for longword
	move.w	CURY,d0		* y
	swap	d0		* y*65536
	lsr.l	#5,d0		* y*(65536>>5)=y*2048
	add.l	d0,a0		* +line offset
	add.w	CURX,a0		* +colum
	
	* 表示後位置へのカーソル移動（これでは改行なし）
	add.w	d1,CURX		* カーソル右移動(d1.w桁)
	move.w	#1024/8,d5	* 1line size
	sub.w	d1,d5		* カーソル移動後に次のライン移動に必要なオフセット
	
	* 表示処理
	* d1.w = x bytes
	* d2.w = y lines
	* a0.l = text-vram adrs (plane0)
	* a1.l = font adrs
	*
	subq.w	#1,d1		* xbytes -1 for dbra
	move.w	d2,d4		* d4 = yline
	subq.w	#1,d2		* -1 for dbra
	*
	move.w	CRTCR21,-(sp)	* 画面モード保存
	move.b	TCOLOR,d0	* 色情報読みだし
	and.b	#%11,d0		* 色のみ取り出し
	beq	pblack		* 黒
	cmp.b	#%11,d0		* 白？
	bne	f2		* no -> 水色／黄色
	* 白Put
	move.w	#$133,CRTCR21	* plane0/1同時アクセス
f200:	move.w	d1,d3		* xbytes-1
f300:	move.b	(a1)+,(a0)+	* plane put
	dbra	d3,f300
	lea	(d5.w,a0),a0	* to next line (plane 0)
	dbra	d2,f200
	bra.s	f40

pblack:	* 黒Put
	move.w	#$133,CRTCR21	* plane0/1同時アクセス
f2000:	move.w	d1,d3		* xbytes-1
f3000:	clr.b	(a0)+		* plane clear
	dbra	d3,f3000
	lea	(d5.w,a0),a0	* to next line (plane 0)
	dbra	d2,f2000
	bra.s	f40
	*
f2:	* 水色／黄色
	move.w	#$033,CRTCR21	* plane0/1同時アクセスなし
	move.l	a0,a2		* a0.l = plane 0 adrs (for put)
	add.l	#TPSIZE,a2	* a2.l = plane 1 adrs (for clear)
	cmp.b	#%10,d0		* 黄色？
	bne	f20		* no = 水色
	exg	a0,a2		* plane 0 clear , plane 1 put
f20:	move.w	d1,d3		* xbytes-1
f30:	move.b	(a1)+,(a0)+	* plane put
	clr.b	(a2)+
	dbra	d3,f30
	*
	lea	(d5.w,a0),a0	* to next line (plane 0)
	lea	(d5.w,a2),a2	* to next line (plane 1)
	dbra	d2,f20
	*
f40:	* 12/24*24 character : clear 32lines（全色共通）
	cmp.w	#24,d4		* 12/24*24 ? (ylines=24?)
	bne	f50		* No
	move.w	#$133,CRTCR21	* plane0/1同時アクセス:常に0/1共消すから
f70:	* 残り32-24=8ライン一気消し
	clr.b	1024/8*7(a0)	* plane 0/1 clear
	clr.b	1024/8*6(a0)	* plane 0/1 clear
	clr.b	1024/8*5(a0)	* plane 0/1 clear
	clr.b	1024/8*4(a0)	* plane 0/1 clear
	clr.b	1024/8*3(a0)	* plane 0/1 clear
	clr.b	1024/8*2(a0)	* plane 0/1 clear
	clr.b	1024/8*1(a0)	* plane 0/1 clear
	clr.b	(a0)+		* plane 0/1 clear
	dbra	d1,f70
	*
f50:	move.w	(sp)+,CRTCR21	* 同時アクセス解除
	* 行末改行処理
	.if	FCRLF==1
	tst.b	fcrlf		* 改行？
	beq	f8		* no
	move.w	d4,d2		* ylines
	bsr	crlf24		* 行末改行
	.endif
f8:				* カーソル戻し
	tst.b	CURMODE		; カーソル表示スイッチ(<>0で表示)
				* 元はカーソルＯＦＦ？
	beq	cret		* yes
	IOCS	_B_CURON	* カーソル ON
cret:
	move.l	CURSOR,d1	* cursor position read mode -> d1.h=x , d1.l=y
	
	move.l	spp,a1		* a1=SSP
	USERMODE		* ユーザーモードに戻る
	move.l	d1,d0		* cursor -> d0
	movem.l	(sp)+,d3-d5	* pop registers
	rts

*******************************************************************************
* 改行処理
* d2.w ylines（d0,d2が破壊されるので注意すること）
	.if	FCRLF==1
	.xdef	crlf24		* アセンブラーインターフェース
crlf24:
	clr.w	CURX		* 最初はカーソルをその行の先頭に移動する(x=0)
	add.w	#15,d2		* ylines+15
	lsr.w	#4,d2		* (ylines+15)/16 = TEXT ylines
	subq.w	#1,d2		* -1 for dbra
cr2:	IOCS	_B_DOWN_S	* １行下へ
	dbra	d2,cr2		* スクロールアップをさせるためB_DOWNは使わない
	rts
	.endif

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

	.bss
spp:	* スタックポインター
	.ds.l	1

	.if	FCRLF==1
fcrlf:	* 表示後改行判定フラグ
	.ds.b	1
	.endif

*******************************************************************************
* 情報
* Ｘ６８０００のＢＩＯＳにはバグが有り、B_PUTC,B_LOCATEなどで返してくる座標が、
* ２行目以降の先頭で(96,y)のように(画面横幅,y)になる。本来は(0,y+1)になるべき
* であり、実際B_LOCATEに与える座標は正しい座標でなくてはならない。（誤った座標
* を与えても無視される。）
* このため、表示によって次の行の先頭にカーソルが移ったということをx=0で判定し
* ようと思ったのに出来なくなったのである。
* このため画面モードを読み取って、各画面モード別に改行処理をしている。
*（そうでなくても遅い表示が一層遅くなった。）
* まとめ：
* 画面右端で１文字表示すると、カーソル点滅はおなじ位置で座標は(画面端+1,y)に
* なる。この位置で改行する時は$0dのみでいい。($0aはいらない）
*
* 追記：
* ところが、HIOCS(V1.07以前)を組み込むと、$0dだけではだめで$0d$0aでなければならない。
* これはHIOCS V1.07以前のバグである。
* 本来はHIOCS使わないのがいいのだが、その高速性は捨てがたいので、FONTPUT側で
* これにも対応できるような改行方法に変更した。
* HIOCS V1.08以降では修正されている。
*******************************************************************************
	.end
