;==============================================================================
;	<< 386ASM V2.0 >>  for  FM TOWNS
;==============================================================================
.386p
		PAGE		60,132
		NAME		VRAMWRITE
		TITLE		VRAM PUT Strings
;==============================================================================
;	VRAMに文字列を書く(16色,480line)
;
;	CREATE : 1990.06.01
;	FINISH : 1990.06.02
;
;	< High C からの呼出形式 >
;	---------------------------------------------------------------------------
;	『VRAM書き込みﾍﾟｰｼﾞ設定』
;	extern	int	VRAM_page( int page ) ;
;	page : 書き込みﾍﾟｰｼﾞ(0 or 1)
;
;	VRAM_page( page ) ;
;	---------------------------------------------------------------------------
;	『VRAM描画色設定』
;	extern	int	VRAM_color( int fcol,int bcol ) ;
;	fcol : 文字色(0〜15)
;	bcol : 背景色(0〜15)
;
;	VRAM_color( fcol,bcol ) ;
;	---------------------------------------------------------------------------
;	『VRAM文字列書き込み』
;	extern	int VRAM_putstr( int x,int y,char *s ) ;
;	x,y  : 書き込み開始位置(文字左下座標をﾄﾞｯﾄで示す. x=0〜1015, y=0〜503)
;	*s   : 文字列先頭ｱﾄﾞﾚｽ
;	ただし、x は 8の倍数に限ります.
;
;	VRAM_putstr( x,y,"文字列" ) ;
;	---------------------------------------------------------------------------
;
;	< note > : TABS = 4
;
;	< History >
;	1990.06.01 : CREATE
;	1991.04.28 : 清書
;
;	Programmed by Y.Hirata ( Nifty-ID : NAB03321 )
;==============================================================================
;
INCLUDE	hc.inc								;
;
CGROUP	GROUP pmcode, CODE					;
DGROUP	GROUP pmdata, DATA					;
;
;--------------------------------------------
		public	VRAM_page					; VRAM書き込みﾍﾟｰｼﾞ設定
		public	VRAM_color					; VRAM描画色設定
		public	VRAM_putstr					; 文字列をVRAMに描く
;--------------------------------------------
;
;////////////////////////////////////////////
;			ネイティブ部
;////////////////////////////////////////////
;
;============================================
;	定数定義
;============================================
DOTPVLINE		EQU		512					;  512ﾄﾞｯﾄ/1垂直ﾗｲﾝ
DOTPHLINE		EQU		512					; 1024ﾄﾞｯﾄ/1水平ﾗｲﾝ (4ﾋﾞｯﾄ/ﾋﾟｸｾﾙ)
XCDOT			EQU		8					; 横 8ﾄﾞｯﾄ
YCDOT			EQU		16					; 縦16ﾄﾞｯﾄ
;
;********************************************
;	データ領域
;********************************************
;
DATA	SEGMENT								;
;
page_offset		DD		0					; 書き込みﾍﾟｰｼﾞのｵﾌｾｯﾄ
font_data		DB		32 dup(?)			; 漢字/ANKﾌｫﾝﾄ格納領域
color_table		DD		256 dup(?)			; VRAM描画色ﾃｰﾌﾞﾙ
color_pattern	DD		000000000h,0F0000000h,00F000000h,0FF000000h
				DD		000F00000h,0F0F00000h,00FF00000h,0FFF00000h
				DD		0000F0000h,0F00F0000h,00F0F0000h,0FF0F0000h
				DD		000FF0000h,0F0FF0000h,00FFF0000h,0FFFF0000h
				DD		00000F000h,0F000F000h,00F00F000h,0FF00F000h
				DD		000F0F000h,0F0F0F000h,00FF0F000h,0FFF0F000h
				DD		0000FF000h,0F00FF000h,00F0FF000h,0FF0FF000h
				DD		000FFF000h,0F0FFF000h,00FFFF000h,0FFFFF000h
				DD		000000F00h,0F0000F00h,00F000F00h,0FF000F00h
				DD		000F00F00h,0F0F00F00h,00FF00F00h,0FFF00F00h
				DD		0000F0F00h,0F00F0F00h,00F0F0F00h,0FF0F0F00h
				DD		000FF0F00h,0F0FF0F00h,00FFF0F00h,0FFFF0F00h
				DD		00000FF00h,0F000FF00h,00F00FF00h,0FF00FF00h
				DD		000F0FF00h,0F0F0FF00h,00FF0FF00h,0FFF0FF00h
				DD		0000FFF00h,0F00FFF00h,00F0FFF00h,0FF0FFF00h
				DD		000FFFF00h,0F0FFFF00h,00FFFFF00h,0FFFFFF00h
				DD		0000000F0h,0F00000F0h,00F0000F0h,0FF0000F0h
				DD		000F000F0h,0F0F000F0h,00FF000F0h,0FFF000F0h
				DD		0000F00F0h,0F00F00F0h,00F0F00F0h,0FF0F00F0h
				DD		000FF00F0h,0F0FF00F0h,00FFF00F0h,0FFFF00F0h
				DD		00000F0F0h,0F000F0F0h,00F00F0F0h,0FF00F0F0h
				DD		000F0F0F0h,0F0F0F0F0h,00FF0F0F0h,0FFF0F0F0h
				DD		0000FF0F0h,0F00FF0F0h,00F0FF0F0h,0FF0FF0F0h
				DD		000FFF0F0h,0F0FFF0F0h,00FFFF0F0h,0FFFFF0F0h
				DD		000000FF0h,0F0000FF0h,00F000FF0h,0FF000FF0h
				DD		000F00FF0h,0F0F00FF0h,00FF00FF0h,0FFF00FF0h
				DD		0000F0FF0h,0F00F0FF0h,00F0F0FF0h,0FF0F0FF0h
				DD		000FF0FF0h,0F0FF0FF0h,00FFF0FF0h,0FFFF0FF0h
				DD		00000FFF0h,0F000FFF0h,00F00FFF0h,0FF00FFF0h
				DD		000F0FFF0h,0F0F0FFF0h,00FF0FFF0h,0FFF0FFF0h
				DD		0000FFFF0h,0F00FFFF0h,00F0FFFF0h,0FF0FFFF0h
				DD		000FFFFF0h,0F0FFFFF0h,00FFFFFF0h,0FFFFFFF0h
				DD		00000000Fh,0F000000Fh,00F00000Fh,0FF00000Fh
				DD		000F0000Fh,0F0F0000Fh,00FF0000Fh,0FFF0000Fh
				DD		0000F000Fh,0F00F000Fh,00F0F000Fh,0FF0F000Fh
				DD		000FF000Fh,0F0FF000Fh,00FFF000Fh,0FFFF000Fh
				DD		00000F00Fh,0F000F00Fh,00F00F00Fh,0FF00F00Fh
				DD		000F0F00Fh,0F0F0F00Fh,00FF0F00Fh,0FFF0F00Fh
				DD		0000FF00Fh,0F00FF00Fh,00F0FF00Fh,0FF0FF00Fh
				DD		000FFF00Fh,0F0FFF00Fh,00FFFF00Fh,0FFFFF00Fh
				DD		000000F0Fh,0F0000F0Fh,00F000F0Fh,0FF000F0Fh
				DD		000F00F0Fh,0F0F00F0Fh,00FF00F0Fh,0FFF00F0Fh
				DD		0000F0F0Fh,0F00F0F0Fh,00F0F0F0Fh,0FF0F0F0Fh
				DD		000FF0F0Fh,0F0FF0F0Fh,00FFF0F0Fh,0FFFF0F0Fh
				DD		00000FF0Fh,0F000FF0Fh,00F00FF0Fh,0FF00FF0Fh
				DD		000F0FF0Fh,0F0F0FF0Fh,00FF0FF0Fh,0FFF0FF0Fh
				DD		0000FFF0Fh,0F00FFF0Fh,00F0FFF0Fh,0FF0FFF0Fh
				DD		000FFFF0Fh,0F0FFFF0Fh,00FFFFF0Fh,0FFFFFF0Fh
				DD		0000000FFh,0F00000FFh,00F0000FFh,0FF0000FFh
				DD		000F000FFh,0F0F000FFh,00FF000FFh,0FFF000FFh
				DD		0000F00FFh,0F00F00FFh,00F0F00FFh,0FF0F00FFh
				DD		000FF00FFh,0F0FF00FFh,00FFF00FFh,0FFFF00FFh
				DD		00000F0FFh,0F000F0FFh,00F00F0FFh,0FF00F0FFh
				DD		000F0F0FFh,0F0F0F0FFh,00FF0F0FFh,0FFF0F0FFh
				DD		0000FF0FFh,0F00FF0FFh,00F0FF0FFh,0FF0FF0FFh
				DD		000FFF0FFh,0F0FFF0FFh,00FFFF0FFh,0FFFFF0FFh
				DD		000000FFFh,0F0000FFFh,00F000FFFh,0FF000FFFh
				DD		000F00FFFh,0F0F00FFFh,00FF00FFFh,0FFF00FFFh
				DD		0000F0FFFh,0F00F0FFFh,00F0F0FFFh,0FF0F0FFFh
				DD		000FF0FFFh,0F0FF0FFFh,00FFF0FFFh,0FFFF0FFFh
				DD		00000FFFFh,0F000FFFFh,00F00FFFFh,0FF00FFFFh
				DD		000F0FFFFh,0F0F0FFFFh,00FF0FFFFh,0FFF0FFFFh
				DD		0000FFFFFh,0F00FFFFFh,00F0FFFFFh,0FF0FFFFFh
				DD		000FFFFFFh,0F0FFFFFFh,00FFFFFFFh,0FFFFFFFFh
; ↑ ｲﾒｰｼﾞﾃﾞｰﾀのMSB-LSBを逆にした形(面倒だなぁ･･･)
;
DATA	ENDS								;
;
;********************************************
;	文字列のVRAMへの直接書き込み
;********************************************
;
pmcode	SEGMENT								;
		ASSUME	cs:CGROUP, ds:DGROUP		;
											;
;
;------------------------------------------------------------------------------
;	漢字の1ﾊﾞｲﾄ目か？ ((0x81 <= c && c <= 0x9F) || (0xE0 <= && c <= 0xFC))
;	< INPUT  > : AL - 文字ｺｰﾄﾞ
;	< RETURN > : 漢字の1ﾊﾞｲﾄ目ならばｷｬﾘｰﾌﾗｸﾞｸﾘｱ
;			     漢字の1ﾊﾞｲﾄ目でなければｷｬﾘｰﾌﾗｸﾞｾｯﾄ
;------------------------------------------------------------------------------
		ALIGN	4							; dword boundary
iskanji1:
			cmp		al,081h					;
			jb		short next1				;
			cmp		al,09Fh					;
			ja		short next1				;
			clc								; ｷｬﾘｰﾌﾗｸﾞｸﾘｱ
			ret								;
next1:										;
			cmp		al,0E0h					;
			jb		short notkanji1			;
			cmp		al,0FCh					;
			ja		short notkanji1			;
			clc								; ｷｬﾘｰﾌﾗｸﾞｸﾘｱ
			ret								;
notkanji1:									;
			stc								; ｷｬﾘｰﾌﾗｸﾞｾｯﾄ
			ret								;
;
;------------------------------------------------------------------------------
;	漢字の2ﾊﾞｲﾄ目か？ ((0x40 <= c && c <= 0x7E) || (0x80 <= && c <= 0xFC))
;	< INPUT  > : AL - 文字ｺｰﾄﾞ
;	< RETURN > : 漢字の2ﾊﾞｲﾄ目ならばｷｬﾘｰﾌﾗｸﾞｸﾘｱ
;			     漢字の2ﾊﾞｲﾄ目でなければｷｬﾘｰﾌﾗｸﾞｾｯﾄ
;------------------------------------------------------------------------------
		ALIGN	4							; dword boundary
iskanji2:
			cmp		al,040h					;
			jb		short next2				;
			cmp		al,07Eh					;
			ja		short next2				;
			clc								; ｷｬﾘｰﾌﾗｸﾞｸﾘｱ
			ret								;
next2:										;
			cmp		al,080h					;
			jb		short notkanji2			;
			cmp		al,0FCh					;
			ja		short notkanji2			;
			clc								; ｷｬﾘｰﾌﾗｸﾞｸﾘｱ
			ret								;
notkanji2:									;
			stc								; ｷｬﾘｰﾌﾗｸﾞｾｯﾄ
			ret								;
;
;------------------------------------------------------------------------------
;	書き込みﾍﾟｰｼﾞ設定
;	< INPUT  > : 第一引数 - 書き込みﾍﾟｰｼﾞ(0 or 1)
;------------------------------------------------------------------------------
		ALIGN	4							; dword boundary
VRAM_page	PROC	NEAR					;
#WPAGE		EQU	(dword PTR [ebp+8])			; 書き込みﾍﾟｰｼﾞ
;
			push	ebp						;
			mov		ebp,esp					; ｽﾀｯｸﾌﾚｰﾑ形成
;
			cmp		#WPAGE,ZERO				;
			jne		page1					;
			xor		eax,eax					;
			mov		page_offset,eax			;
											; page 0
			jmp		short endpage			;
page1:
			mov		eax,DOTPHLINE			;
			shl		eax,9					; 512ﾄﾞｯﾄ / 縦1ﾗｲﾝ
			mov		page_offset,eax			;
											; page 1
;
endpage:									;
			xor		eax,eax					; RETURN = 0
;
			pop		ebp						; ｽﾀｯｸﾌﾚｰﾑ開放
			ret								;
VRAM_page	ENDP							;
;
;------------------------------------------------------------------------------
;	VRAM描画色設定
;	< INPUT  > : 第一引数 - 文字色( 0〜15 )
;			   : 第二引数 - 背景色( 0〜15 )
;------------------------------------------------------------------------------
		ALIGN	4							; dword boundary
VRAM_color	PROC	NEAR					;
#FCOL		EQU	(dword PTR [ebp+8])			; 文字色
#BCOL		EQU	(dword PTR [ebp+12])		; 背景色
;
			push	ebp						;
			mov		ebp,esp					; ｽﾀｯｸﾌﾚｰﾑ形成
;
			push	es						;
			push	esi						; ﾚｼﾞｽﾀ退避
			push	edi						;
			push	edx						;
			push	ecx						;
			cld								;
;
			mov		eax,#FCOL				; 4 bit -> 4 byte
			mov		edx,#BCOL				; 4 bit -> 4 byte
			mov		ecx,7					; dword分
ptnset:										;
			shl		eax,4					;
			shl		edx,4					;
			or		eax,#FCOL				;
			or		edx,#BCOL				;
			loop	ptnset					;
			mov		#FCOL,eax				;
			mov		#BCOL,edx				;
;
			push	ds						;
			pop		es						; es = ds
			mov		esi,OFFSET color_pattern; 組合せ
			mov		edi,OFFSET color_table	; 色ﾊﾟﾀｰﾝ格納先
			mov		ecx,256					; 全ﾊﾟﾀｰﾝ(8bit)
colset:										;
			lodsd							; ﾊﾟﾀｰﾝ取得
			mov		edx,eax					;
			not		edx						; 反転
			and		eax,#FCOL				; 文字色
			and		edx,#BCOL				; 背景色
			or		eax,edx					; 色ﾊﾟﾀｰﾝ作成
			stosd							;
			loop	colset					;
;
			pop		ecx						; ﾚｼﾞｽﾀ復元
			pop		edx						;
			pop		edi						;
			pop		esi						;
			pop		es						;
			xor		eax,eax					; RETURN = 0
;
			pop		ebp						; ｽﾀｯｸﾌﾚｰﾑ開放
			ret								;
VRAM_color	ENDP							;
;
;------------------------------------------------------------------------------
;	文字列をVRAMに描く
;	< INPUT  > : 第一引数 - 書き込み位置(X座標)
;			   : 第二引数 - 書き込み位置(Y座標)
;			   : 第三引数 - 文字列ﾎﾟｲﾝﾀ
;------------------------------------------------------------------------------
		ALIGN	4							; dword boundary
VRAM_putstr	PROC	NEAR					;
#WPOSX		EQU	(dword PTR [ebp+8])			; X座標
#WPOSY		EQU	(dword PTR [ebp+12])		; Y座標
#STRADR		EQU	(dword PTR [ebp+16])		; 文字列ﾎﾟｲﾝﾀ
;
#writep		EQU	(dword PTR [ebp-4])			; 次の文字書き込み位置
;
			push	ebp						;
			mov		ebp,esp					; ｽﾀｯｸﾌﾚｰﾑ形成
			sub		esp,4					; ﾛｰｶﾙ変数分確保
;
			push	gs						; ﾚｼﾞｽﾀ退避
			push	fs						;
			push	es						;
			push	ds						;
			push	edi						;
			push	esi						;
			push	edx						;
			push	ecx						;
			push	ebx						;
;
			mov		ax,VRAMSEG1				;
			mov		es,ax					; es = VRAMｾﾚｸﾀ
			mov		ax,ds					;
			mov		fs,ax					;
			mov		gs,ax					; gs = fs = ds
;
			mov		edi,#WPOSX				; 書き込み位置計算
			shr		edi,1					; / 2
			mov		eax,#WPOSY				;
			shl		eax,9					; 1024ﾄﾞｯﾄ / 1ﾗｲﾝ ( 512byte )
			add		edi,eax					;
			or		edi,page_offset			;
			mov		#writep,edi				; 書き込み位置ｾｯﾄ
;
putstart:									;
			cld								; 増加
			mov		esi,#STRADR				; 文字列ﾎﾟｲﾝﾀ
			lodsb							; 文字 -> al
			or		al,al					; 文字列終了?
			jz		endstr					; 後処理へ
;
			call	iskanji1				; 漢字の1ﾊﾞｲﾄ目?
			jc		putank					;
;
			xchg	al,ah					; al <-> ah
			lodsb							; 次の文字 -> al
			or		al,al					;
			jz		endstr					; 文字列終了!
;
			call	iskanji2				; 漢字の2ﾊﾞｲﾄ目?
			jc		putank					;
putkanji:									;
			mov		#STRADR,esi				; 次の文字のﾎﾟｲﾝﾀ
			mov		bx,ax					; 文字 -> BX
;			mov		ax,0200h				; ah=02h,al=00h
			TBIOS	FNT_BIOS,0200h			; sjis -> jis (BX->BX)
			mov		dx,1010h				; 16*16
			mov		esi,OFFSET gs:font_data	;
;			mov		ax,0100h				; ah=01h,al=00h
			TBIOS	FNT_BIOS,0100h			; 漢字ﾌｫﾝﾄ読出 (DS:ESI)
;
			mov		edi,#writep				; 書き込み位置
;
			mov		ebx,OFFSET gs:color_table
											; 色ﾊﾟﾀｰﾝｱﾄﾞﾚｽ
			xor		ecx,ecx					; ecx = 0 (Left Pattern)
			xor		edx,edx					; edx = 0 (Right Pattern)
			add		esi,31					; ﾌｫﾝﾄﾃﾞｰﾀを逆に読むため
;
; 386はｼﾞｬﾝﾌﾟ命令がない方が速いからREPTを使う.
;
			REPT	YCDOT					;
				std							; ﾃﾞｰﾀが上下反転しているのに注意
				lodsb						; 漢字ﾌｫﾝﾄ(Right Pattern)取り出し
				movzx	edx,al				;
				lodsb						; 漢字ﾌｫﾝﾄ(Left Pattern)取り出し
				movzx	ecx,al				;
				cld							;
				mov		eax,gs:[ebx+ecx*4]	; Left Pattern
				stosd						; VRAMへ転送
				mov		eax,gs:[ebx+edx*4]	; Right Pattern
				stosd						; VRAMへ転送
				sub		edi,8				; 次の文字書き込み位置
				sub		edi,DOTPHLINE		;
			ENDM							;
			add		#writep,8				; 書き込み位置更新
			push	gs						;
			pop		ds						; DS復元
;
			jmp		putstart				;
;
putank:										;
			mov		#STRADR,esi				; 次の文字のﾎﾟｲﾝﾀ
			mov		bl,al					; ANK -> BL
			mov		dx,0810h				; 8*16
			mov		esi,OFFSET gs:font_data	;
;			xor		ax,ax					; ah=00h
			TBIOS	FNT_BIOS,0000h			; ANKﾌｫﾝﾄ読出 (DS:ESI)
;
			mov		edi,#writep				; 書き込み位置
;
			mov		ebx,OFFSET gs:color_table
											; 色ﾊﾟﾀｰﾝｱﾄﾞﾚｽ
			xor		ecx,ecx					; ecx = 0
			add		esi,15					; ﾌｫﾝﾄﾃﾞｰﾀを逆に読むため
;
			std								; ﾃﾞｰﾀが上下反転しているのに注意
			REPT	YCDOT					;
				lodsb						; ANKﾌｫﾝﾄ取り出し
				movzx	ecx,al				;
				mov		eax,gs:[ebx+ecx*4]	; 色ﾊﾟﾀｰﾝ取得
				stosd						; VRAMへ転送
				add		edi,4				; 次の文字書き込み位置
				sub		edi,DOTPHLINE		;
			ENDM							;
			add		#writep,4				; 書き込み位置更新
			push	gs						;
			pop		ds						; DS復元
;
			jmp		putstart				;
;
endstr:										;
			pop		ebx						; ﾚｼﾞｽﾀ復元
			pop		ecx						;
			pop		edx						;
			pop		esi						;
			pop		edi						;
			pop		ds						;
			pop		es						;
			pop		fs						;
			pop		gs						;
			xor		eax,eax					; RETURN = 0
;
			add		esp,4					; ﾛｰｶﾙ変数分開放
			pop		ebp						; ｽﾀｯｸﾌﾚｰﾑ開放
			ret								;
VRAM_putstr	ENDP							;
;
pmcode		ENDS							;
;
		END

