; True MAZE(maybe) for osask
; 2005/11/13	とりあえず始める。
; 2005/11/26	迷路マップ作成完了。
; 2005/11/29	パターンデータ構造の作成
; 2005/11/30	移動操作処理完了
; 2005/12/01	斜め移動補正処理の実装
; 2005/12/04	内部構造を変更開始。
; 2005/12/06	パターンマップ+重ね合わせ用VRAM+スプライト処理の完成。
; 2005/12/09	文字表示処理を変更。
; 2005/12/10	フレームレート調整処理の改善
; 2005/12/10	β版テストリリース
; 2005/12/11	スムーズスクロール処理を実装開始
; 2005/12/12	重ね合わせの順番変更
; 2005/12/12	オートマッピングの処理改良
; 2005/12/13	操作キャラクタのグラフィックを用意した。(8方向移動のみ)
; 2005/12/14	スムーズスクロール処理実装完了
; 2005/12/14	ダッシュ処理の追加
; 2005/12/15	パターン用VRAM方式やめ。
; 2005/12/15	乱数ルーチンを"randMT"に変更。
; 2005/12/16	名称を"True MAZE"に決定。
; 2005/12/17	マウスの操作性を改良
; 2005/12/24	TOWNSパッド対応化の相談をした。
; 2005/12/24	OSASK(拡張)フォントを利用するように変更。
; 2006/01/01	内部リニューアル開始
; 2006/01/12	TOWNSパッド対応した(多分。バグがある可能性がある)。
; 2006/01/15	IRCでBGM.DLLの構造の相談した。
; 2006/01/15	画面の拡大縮小に対応した(まだ半透明未対応版)。
; 2006/01/17	拡大縮小用にウィンドウをリサイズする様に変更。
; 2006/01/17	半透明メッセージウィンドウ描画対応
; 2006/01/18	画面の拡大縮小の進化(半透明対応化)
; 2006/01/18	簡易メインメニューの実装。
; 2006/01/24	セーブデータ表示用の動的メニューとprinf変換の実装。
; 2006/01/26	メニュー選択後の位置を基本的には記憶するようにした。
; 2006/01/26	メニュー選択後の暗いウィンドウを描画するときにカーソルも表示するようにした。
; 2006/02/01	タイトル画面を実装。
; 2006/02/01	タイトルとメニューの背景グラフィックを簡易実装(手抜き^^;)。
; 2006/02/04	設定メニューを実装。	
; 2006/02/13	やっとセーブデータにメニューが連動するようになった。
; 2006/02/24	名前入力ルーチンがほぼ完成。
; 2006/02/28	ゲームのメインを実装開始
; 2006/03/02	フェードイン/フェードアウトの実装。
; 2006/03/04	エフェクト仕様の実装開始。
; 2006/03/04	縦ライン式画面転換(フェード)のエフェクトを実装。
; 2006/03/05	フェードイン/フェードアウトを本格化してエフェクトとして取り込んだ。
; 2006/03/06	PC-9801-26/73/86を使用したMSXパッド対応化(未検証)
; 2006/03/07	メインゲーム中のパッド入力ルーチンを変更開始とセーブデータの仕様を変更開始
; 2006/03/08	上記にともなって全面的にキーボードルーチンを大幅変更開始。
; 2006/03/08	キーのシグナルの配置を変更。
; 2006/03/09	パッドエミュレーション主体に変更。
; 2006/03/09	スプライト描画処理(β)を実装。
; 2006/03/10	スプライト描画処理書き直し。
; 2006/03/11	パターン描画の仕組みを変更。従来のパターン描画ルーチンを削除。
; 2006/03/11	↑によりスムーズスクロール完全実装。
; 2006/03/11	↑によりスプライト描画完全対応版実装。
; 2006/03/11	迷路というより普通のダンジョン化してきたのでまたタイトルの変更を検討。
; 2006/03/12	セーブデータの仕様変更後の再現処理実装完了。
; 2006/03/14	フロア移動関係を実装。
; 2006/03/14	(今は何も無いけど)休憩所を実装。でも、専用グラフィックが無い…。
; 2006/03/15	サイズ・スタイル選択可能なオートマッピング表示を実装。
; 2006/03/16	はみ出たマッピング表示の自動スクロールを実装。
; 2006/03/17	ランキング画面を一応作成。ランク追加の方が未実装。
; 2006/03/17	OSC展示の為、手抜きなヘルプ(簡易操作説明)を実装。
; 2006/03/17	細かな点を修正。
; 2006/03/17	サウンドルーム選択時は未実装メッセージを表示するようにした。
; 2006/03/18	デフォルトサイズが2倍なっていたのを等倍に修正。
; 2006/03/18	"オープンソースカンファレンス@東京都新宿区大久保町"の開催日だ!
; 2006/03/21	ゲーム中に閉じる場合、セーブデータを書き出して終了するように変更。
; 2006/04/21	ダンジョン滞在時のBGMを作成。
; 2006/06/10	あるサイズ以上に広くなると落ちるバグを修正。
; 2006/06/11	"かなり広い迷路"の60Fの次が休憩所になっていなかったのを修正。
; 2006/06/11	マップ表示のサイズを3x3~16x16だったのを1x1~8x8にした。
; 2006/06/11	セーブデータファイルの容量が8KBでは少なかったので32KBに修正。
; 2006/06/14	とりあえずBGMLIBを使用してBGMを再生するように実装。
; 2006/07/01	BGMLIBを使用しても意図した通りにならなかったのでやっぱり削除。
; 2006/07/03	BGM再生で必ずライブラリ使用フラグを立てていたのを修正。
; 2006/07/03	とりあえず公開用に整理した。
; 2007/01/15	パッド判定ルーチンの不具合を修正。
; 2007/01/16	プレイ時間を記録するように実装し時間表示をプレイ時間に変更。
; 今後の目標・課題
; ・最低限あとはランキング!とヘルプ!
; ・各ダンジョンの最終フロアをクリアしたらスコアを計算してランキングに追加する
; ・オートマッピングの実装(全体/標準表示可、ピクセルサイズ変更可)。
; ・ウィンドウによるメッセージと状態表示
; ・アイテム(ダイナマイト,ワープ草,ライターなど)の実装
; ・モンスターとそのBOSSの実装
; ・HP, フロア, お金, レベル(経験値), 満腹度などの実装
; ・迷路に遊びを持たせる(広場や柱をつくるなど)
; ・マップチップの選択
; ・fps調整処理の詳細設定
;	フレームレート調整: オフ, オート, 固定
;	基本周波数: 30/50/60/70/72/75/85/100/120Hz, 指定値
; ・スクロール速度の選択
; ・BGM処理(やがてはDLL化も)の実装
; ・PC/ATアナログジョイスティック対応…は却下。
; ・名前入力画面のあの中途半端な性能をまともレベルにしないと!
; ・各機能のライブラリ化したものの使用
; ・明るさレイアとマスクレイアを実現して、KAODUNみたいな部屋の実装に向けた準備
; ・
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; stack:16k, malloc:0k, file:1040k
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[FORMAT "WCOFF"]
[INSTRSET "i486p"]
[OPTIMIZE 1]
[OPTION 1]
[BITS 32]
//[FILE "maze.nak"]
; 画面関係メモリ
extern	gbox
extern	vram_screen, vram, vram_back, vram_fore
extern	vram_ptnb, vram_ptnf, vram_oamb, vram_oamf, vram_font
; BGM関係ファンクション(ラッピング予定)
/*
extern	BGMLIB_DllMap, BGMLIB_Init, BGMLIB_Remove, BGMLIB_Timer
extern	BGMLIB_Open, BGMLIB_Close
extern	BGMLIB_Load, BGMLIB_Save, BGMLIB_Clear
extern	BGMLIB_AddData, BGMLIB_AddNote
extern	BGMLIB_Play, BGMLIB_Stop, BGMLIB_Pause
extern	BGMLIB_GetPos, BGMLIB_SetPos, BGMLIB_GetStat, BGMLIB_GetMoni
*/
extern	bgmlib_interval, bgmlib_unload
extern	getdeltatime, xswap

extern	bgmlib_init, bgmlib_load, bgmlib_play, bgmlib_stop
extern	bgmlib_pause, bgmlib_device, bgmlib_getptr, bgmlib_getstat

; ダンジョンバッファ関係
extern	mazemap, ptnmap, movemap, automap

; 固定値の設定
#include "const.h"
#include "vram.h"
#include "mazebss.h"

DEBUGSIZE	equ	0
STXSIZE		equ	12*16	; スタートアップ(ロード中表示)サイズ
STYSIZE		equ	3 *16
;SCXSIZE_DEFAULT	equ	512;768	; ディスプレイ(表示領域)サイズ(可変)
;SCYSIZE_DEFAULT	equ	448;512
SCRNUM_DEFAULT	equ	0	; 等倍:3,2倍:16,VGA:20
WINDOWTITLELEN	equ	9
#define	WINDOWTITLE	"True MAZE"
PTNDOTWIDTH	equ	16	; (計算用)
PTNDOTHEIGHT	equ	16
GPXSIZE		equ	(VGXSIZE / PTNDOTWIDTH)
GPYSIZE		equ	(VGYSIZE / PTNDOTHEIGHT)
PXSIZE		equ	MXSIZEMAX *2
PYSIZE		equ	MYSIZEMAX *2
BGM_WORK_SIZE	equ	256	; 128byte
BGM_DEVICE_SIZE	equ	65536	; 64KB
BGM_INT_HZ	equ	59999994; 60000001; μHz
BGMLIB_INT_HZ	equ	60
BGMDEV_DEFAULT	equ	1	; BEEP
SEQDEV_DEFAULT	equ	1
;TIMER_INT_HZ	equ	 2000000;
PRFLAG_DEFAULT	equ	001b	; 影付き8x16
FASTHALF_DEFAULT equ	1	; 半透明更新
MAPDOT_MIN	equ	1	; マップ表示の1コマのドットサイズ
MAPDOT_MAX	equ	8
MAPDOT_DEFAULT	equ	5
MAPSTYLE_DEFAULT equ	00000111b
SHORTPUSH_DEF	equ	30	; 1/2sec
OAM_DSP_MAX	equ	4	; MAX15bit(32768),1個8バイト
OAM_PTN_MAX	equ	512	; MAX12bit( 4096),1個4バイト
OAM_PAL_MAX	equ	2	; MAX 8bit(  256),1個16バイト
SKIPFLAME_MAX	equ	60
MO_LEVEL	equ	0x2000
MODE_FULLSCREEN	equ	0x3901
MODE_USEWINDOW	equ	0x2801
RANKDATA_MAX	equ	50
SAVEDATASIZE	equ	24576	; 確保するセーブデータの容量
#define	dfrom	bh
[SECTION .text]
; 汎用ルーチン
#include "sub.h"
#include "randmt.h"
#define	rnd	randMT
#define	setseed	setseedMT
#define	backrand	backrandMT
#define	remerand	remerandMT
#define	vupd	mov	byte [fps_flush], 2
#define MazeMakeOFF
#define	KEY(KeyCode)	byte [keymatrix + KeyCode]
#define	bpmupd	mov	byte [screen_update], 0
#define	oamupd	mov	byte [screen_update+1], 0
#define	fpmupd	mov	byte [screen_update+2], 0
#define	updreset		mov	dword [screen_update], 0x01010101

[SECTION .text]
		global	_OsaskMain
InitStretch:	; 画面拡大率の計算
		; in:	ecx,edx	等倍サイズ(仮想VRAMサイズ)
		;	esi,edi	拡大サイズ(スクリーンサイズ)
		; 小数部32bitで割り切れない場合は小数32bit目を切り上げ。
		pusha
		; Y座標の拡大率
		mov	eax, edi
		mov	ebx, edx
		mov	edx, 0
		div	ebx
		mov	[StretchYRate], eax
		mov	eax, 0
		div	ebx
		or	edx, edx
		jz	.yb
		inc	eax
.yb:		mov	[StretchYRate+4], eax
		; X座標の拡大率
		mov	eax, esi
		mov	edx, 0
		div	ecx
		mov	[StretchXRate], eax
		mov	eax, 0
		div	ecx
		or	edx, edx
		jz	.xb
		inc	eax
.xb:		mov	[StretchXRate+4], eax
		popa
		pusha
		; Y座標の縮小率(逆数)
		mov	eax, edx
		mov	edx, 0
		div	edi
		mov	[StretchYRate+8], eax
		mov	eax, 0
		div	edi
		or	edx, edx
		jz	.ys
		inc	eax
.ys:		mov	[StretchYRate+12], eax
		; X座標の縮小率(逆数)
		mov	eax, ecx
		mov	edx, 0
		div	esi
		mov	[StretchXRate+8], eax
		mov	eax, 0
		div	esi
		or	edx, edx
		jz	.xs
		inc	eax
.xs:		mov	[StretchXRate+12], eax
		popa
		ret
ScrToPtnAddr:	; マウス座標を内部座標へ変換
		; in:	ecx,edx	マウス座標(スクリーン内)
		; out:	ecx,edx	内部座標(仮想VRAM内)
		push	esi
		push	edi
		push	eax
		; フルスクリーン対応
		test	byte [us_windowopen+8], 2
		jz	.nfull
		add	ecx, 8
		add	edx, 29
.nfull:		mov	esi, ecx
		mov	edi, edx
		cmp	edx, 0
		jnl	.skpy1
		neg	edx
.skpy1:		cmp	ecx, 0
		jnl	.skpx1
		neg	ecx
.skpx1:		push	edx
		mov	eax, [StretchYRate +8]
		mul	edx	; 整数倍
		pop	edx
		push	eax
		mov	eax, [StretchYRate +12]
		mul	edx
		pop	eax
		add	edx, eax
		push	edx
		push	ecx
		mov	eax, [StretchXRate +8]
		mul	ecx	; 整数倍
		pop	ecx
		push	eax
		mov	eax, [StretchXRate +12]
		mul	ecx
		pop	eax
		lea	ecx, [edx + eax]
		pop	edx
		cmp	edi, 0
		jnl	.skpy2
		neg	edx
.skpy2:		cmp	esi, 0
		jnl	.skpx2
		neg	ecx
.skpx2:		pop	eax
		pop	edi
		pop	esi
		ret
SignalHandler:	; シグナル割り込み  /***//***/
		call	getsignal
		push	.ret
		; ウィンドウ制御情報
		cmp	eax, SIG_WINDOW
		jb	.notwindow
		cmp	eax, SIG_WINDOW+15
		ja	.notwindow
		mov	[winsignal], eax
		and	eax, 0x0F
		cmp	eax, 1	; VRAMアクセス禁止
		jne	.notvram
		mov	ebx, us_windowctrl
		mov	dword [ebx + 0x04], 0x0100
		call	0xC7:0
.notvram:	cmp	eax, 2	; (差分)描画の指示
		jb	.notredraw
		cmp	eax, 3
		ja	.notredraw
		call	GpFlush
		mov	ebx, us_windowctrl
		mov	dword [ebx + 0x04], 0x0200
		call	0xC7:0
		;mov	byte [redraw_init], 1
.notredraw:	cmp	eax, 4	; ウィンドウの移動
		jne	.notwinmove
		call	getparam
		mov	[winposx], eax
		call	getparam
		mov	[winposy], eax
		ret
.notwinmove:	cmp	eax, 5	; ウィンドウバーのカラー変更
		jne	.notwincolor
		call	getparam
		mov	[wincolor], eax
.notwincolor:	cmp	eax, 6	; タスク終了要求
		jne	.notwinclose
		mov	byte [winclosehandler+4], 1
		mov	ebx, [winclosehandler]
		or	ebx, ebx
		jz	.normalclose
		call	ebx
.normalclose:	call	_sti
		call	windowclose
		int	3
		ret
.notwinclose:	/*
		cmp	eax, 7	; ウィンドウクローズ完了
		jne	.notshutdown
		test	byte [winclosehandler+4], 1
		jz	.notshutdown
		int	3
.notshutdown:	*/
		ret
.notwindow:	; BGM処理用タイマ
		cmp	eax, SIG_BGM
		jne	.notbgm
		mov	ebx, us_getbgmtimer
		call	0xC7:0
		; 時刻表示用
		mov	eax, [us_getbgmtimer + 0x14]
		add	eax, [time_sec]
		mov	edx, 0
		mov	ecx, 60
		div	ecx
		mov	[time_temp+8], edx
		mov	edx, 0
		div	ecx
		mov	[time_temp], eax
		mov	[time_temp+4], edx
		mov	eax, [us_getbgmtimer + 0x10]
		mov	edx, 100
		mul	edx
		mov	[time_temp+12], edx
		test	dword [bgmdllversion], -1
		jz	.bgmset
		mov	esi, 0
		mov	ebp, BGM_WORK
		call	0x0207:0x00000048
		jmp	timer_int
.bgmset:	test	byte [bgmlibcall], 1
		jz	.nobgmlib
		call	bgmlib_interval
		jmp	timer_int
.nobgmlib:	mov	ebx, us_setbgmtimer
		call	0xC7:0
		jmp	timer_int
.notbgm:	
.notarrow:	; マウス移動
		cmp	eax, MO_MOVE
		jne	.skpmomove
		call	getparam
		mov	ecx, eax
		call	getparam
		mov	edx, eax
		call	ScrToPtnAddr
		mov	[mo_tmppos], ecx
		mov	[mo_tmppos+4], edx
		test	dword [mobstatus], -1
		jnz	.momoveup
		cmp	ecx, [ScreenSize]
		jnb	.notmomove
		cmp	edx, [ScreenSize]
		jnb	.notmomove
.momoveup:	mov	[newposx], ecx
		mov	[newposy], edx
		inc	dword [mmoveflag]
.notmomove:	ret
.skpmomove:	; マウスボタン
		test	eax, MO_KEY
		jz	.notmokey
		mov	ebx, eax
		and	ebx, 3
		test	eax, MO_RELEASE
		jnz	.morelease
		test	dword [mobstatus], -1
		jnz	.mobtnex
		mov	ecx, [winsize]
		cmp	dword [mo_tmppos], ecx
		jnb	.mobret
		mov	edx, [winsize+4]
		cmp	dword [mo_tmppos+4], edx
		jnb	.mobret
		mov	[mo_lpbutton], ebx
		mov	ecx, [mo_tmppos]
		mov	[mo_lastpress], ecx
		mov	edx, [mo_tmppos+4]
		mov	[mo_lastpress+4], edx
		cmp	byte [keypad_emu], 1
		je	.mobtnex
		call	addkeybuf
.mobtnex:	mov	byte [mobstatus + ebx], 1
		or	ebx, ebx
		jnz	.mobret
		mov	ecx, [newposx]
		mov	edx, [newposy]
		and	byte [mo_dushf], -PAD_B-1
		sar	ecx, 4; 16x16
		sar	edx, 4
		cmp	ecx, (GPXSIZE>>1)-1
		jb	.mobret
		cmp	ecx, (GPXSIZE>>1)+1
		jnb	.mobret
		cmp	edx, (GPYSIZE>>1)-1
		jb	.mobret
		cmp	edx, (GPYSIZE>>1)+1
		jnb	.mobret
		; ダッシュ
		or	byte [mospad_status], PAD_B
		ret
.morelease:	mov	byte [mobstatus + ebx], 0
		test	dword [mobstatus], -1
		jz	.mobret
		mov	[mo_lpbutton], bh
.mobret:	ret
.notmokey:	; エラーコード (同時処理可能版:4個まで)
		cmp	eax, SIG_NOERROR
		jb	.notnoerror
		cmp	eax, SIG_NOERROR+63
		ja	.notnoerror
		sub	eax, SIG_NOERROR
		mov	ebx, eax
		shr	ebx, 4
		and	eax, 15
		and	ebx, 3
		; 呼び出し処理判定
		cmp	dword [RetSigJump + ebx*4], 0
		jz	.ercnojmp
		; 呼び出し処理
		mov	edx, [RetSigSlot + ebx*4]
		mov	byte [ReturnSignal + ebx], 0
		mov	ebx, [RetSigJump + ebx*4]
		dec	dword [addjobings]
		jmp	ebx
.ercnojmp:	; エラーコード情報格納
		or	eax, 0x20
		mov	[ReturnSignal + ebx], al
		ret
.notnoerror:	; キー押下状態の更新
		/* キーコンフィグできるように配慮すること! */
		cmp	eax, KY_ALL
		jnb	.notkeycode
		mov	edx, eax
		mov	ecx, 0
		and	edx, -KY_RELEASE-1
		mov	bh, 1
		mov	bl, 0
.notkeylop:	cmp	[KeyPadTable + ecx*4], edx
		jne	.notkeypad
		or	bl, bh
.notkeypad:	shl	bh, 1
		inc	ecx
		cmp	ecx, 8
		jb	.notkeylop
		test	eax, KY_RELEASE
		jnz	.keyrelease
		mov	KEY(eax), 1
		or	byte [keypad_status], bl
		cmp	byte [keypad_emu], 0
		jne	.adkyskp
		call	addkeybuf
.adkyskp:	ret
.keyrelease:	not	bl
		mov	KEY(eax), 0
		and	byte [keypad_status], bl
		ret
.notkeycode:	ret
.ret:		; ハンドラからの復帰
		mov	ebx, us_ret
		call	0xC7:0
timer_int:	; タイマ割り込み
		inc	dword [timer_count]
		; パッド情報更新処理
		test	byte [UsePadFlags], 7
		jz	.padskp
		mov	eax, [UsePadFlags]
		or	eax, eax
		jz	.padskp
		cmp	eax, [userpadnames]
		jnb	.padskp
		test	byte [padbusy], 1
		jnz	.padskp
		call	near [userpadtable + eax*4]
.padskp:	; パッド情報拡張処理
		call	.getpad
		mov	ebx, eax
		xor	eax, [oldpad_status]
		and	eax, ebx
		; 新しく押されたボタンをチェック
		mov	ecx, 1
		mov	edx, 0
.padlp:		test	eax, ecx
		jz	.padps
		mov	dword [pad_scancount + edx*4], 0
		cmp	byte [keypad_emu], 2
		jne	.keypad
		push	eax
		mov	eax, [keypad_emutable + edx*4]
		call	addkeybuf
		pop	eax
.keypad:	test	byte [pad_scanuser + edx*4], 2
		jnz	.padxr
		mov	byte [pad_scanuser + edx*4], 1
		jmp	.padps
.padxr:		xor	byte [pad_scanuser + edx*4], 1
.padps:		inc	edx
		shl	ecx, 1
		cmp	edx, 16
		jb	.padlp
		; 新しく離されたボタンの処理は必要ない
		; 押されているボタンをカウントアップする
		mov	ecx, 1
		mov	edx, 0
.padli:		test	ebx, ecx
		jz	.padpi
		inc	dword [pad_scancount + edx*4]
.padpi:		inc	edx
		shl	ecx, 1
		cmp	edx, 16
		jb	.padli
		mov	[oldpad_status], ebx

		; アニメーション更新処理
		call	anime
		
		; 画面の処理
		test	byte [vsync_flags], 1
		jz	.ret
		test	byte [window_status], 1
		jz	.ret
		mov	eax, [fps_remain]
		inc	eax
		cmp	eax, SKIPFLAME_MAX
		jl	.noskp
		mov	eax, 0
.noskp:		mov	[fps_remain], eax
		cmp	eax, 0
		jg	.ret
		test	byte [vsync_flags], 2
		jnz	.ret
		test	byte [fasthalf], 1
		jz	.draw
		cmp	byte [fps_flush], 0
		jle	.ret
		dec	byte [fps_flush]
.draw:		or	byte [vsync_flags], 2
		call	_sti	; 再入可
		test	byte [screen_mode], 0xFF
		jz	.skp
		
		call	GpRedraw
		jmp	.sko
.skp:		call	GpFlush
.sko:		call	_cli	; 
		inc	dword [fps_count]
		and	byte [vsync_flags], -3
.ret:		ret
.getpad:	mov	eax, [keypad_status]
		or	eax, [mospad_status]
		test	byte [UsePadFlags], -1
		jz	.ret
		or	eax, [msxpad_status]
		ret
vsync:		; VSYNC互換のウェイト(前回呼び出しからの時間指定)
		; in:	eax	ウェイト時間(単位:約1/60秒=フレーム数)
		;	コマ落ちが発生した(前回からの時間がeaxを上回っている)
		;	場合はすぐに復帰する(API呼び出しも無い)。
		vupd
vsync_nodraw:	or	eax, eax
		jnz	.nores
		call	vsync_init
		inc	eax
.nores:		sub	[fps_remain], eax
.lop:		cmp	dword [fps_remain], 0
		jnl	.ret
		call	sleep
		jmp	.lop
.ret:		ret
vsync_init:	; VSYNC互換ウェイトの使用開始
		mov	dword [fps_remain], 0
		mov	byte [vsync_flags], 1
		ret
_cli:		; シグナル処理割り込みを1段階禁止する
		push	ebx
		mov	ebx, us_cli
		call	0xC7:0
		pop	ebx
		ret
_sti:		; シグナル処理割り込みを1段階許可する
		push	ebx
		mov	ebx, us_sti
		call	0xC7:0
		pop	ebx
		ret
set_timertime:	; タイマの時間基点を指定する
		; in:	edx.eax	タイマ値(単位:秒->整数部.小数部)
		;	ecx	タイマスロット
		;	ebx	呼び出しAPI格納ポインタ
		; スロット設定
		mov	[ebx + 0x008], ecx
		mov	[ebx + 0x014], ecx
		; タイマ値設定
		mov	[ebx + 0x018 + 0x00], eax
		mov	[ebx + 0x018 + 0x04], edx
		;mov	dword [ebx + 0x018 + 0x08], 0
		ret
set_timerrate:	; タイマの時間間隔を指定する
		; in:	eax	周波数(単位:1'000'000分の1秒単位)
		;	ecx	タイマスロット
		;	ebx	呼び出しAPI格納ポインタ
		push	edx
		push	ebx
		mov	edx, 0
		mov	ebx, eax
		mov	eax, 1000000
		div	ebx
		push	eax
		mov	eax, 0
		div	ebx
		pop	edx
		pop	ebx
		call	set_timertime
		pop	edx
		ret
print_smally:	; 縦サイズ半分化(8x8/16x8)(転送しない)
		; in:	eax	半角数
		push	eax
		push	ecx
		push	edx
		push	ebx
		mov	edx, 0
		lea	ecx, [eax *8]
		mov	ah, [printsize]
.lopy:		push	ecx
		mov	ebx, 0
.lopx:		mov	al, [vram_font + edx*2 + ebx]
		or	al, [vram_font + edx*2 + ebx + VGXSIZE]
		mov	[vram_font + edx + ebx], al
		inc	ebx
		dec	ecx
		jnz	.lopx
		pop	ecx
		add	edx, VGXSIZE
		dec	ah
		jnz	.lopy
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		ret
print_small1:	; 影付きのために1ドット縮小する
		; in:	eax	半角数
		; 中心の1ラインは合成される
		push	eax
		push	ecx
		push	edx
		push	ebx
		push	esi
		push	edi
		lea	ecx, [eax *2]
		mov	eax, VGXSIZE>>1
		movzx	edx, byte [printsize]
		mul	edx
		lea	ebx, [eax + vram_font]
		mov	eax, vram_font
		push	ebx
		; 合成
.lop1:		mov	eax, [ebx]
		or	[ebx -VGXSIZE], eax
		add	ebx, 4
		dec	ecx
		jnz	.lop1
		pop	edi
		movzx	edx, byte [printsize]
		lea	esi, [edi + VGXSIZE]
		shr	edx, 1
		
		dec	edx
		mov	eax, VGXSIZE>>2
		mul	edx
		mov	ecx, eax
		; 移動
		repnz	movsd
		; 消去
		mov	eax, 0
		mov	ecx, VGXSIZE>>2
		repnz	stosd

		pop	edi
		pop	esi
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		ret
print_kagerd:	; 影付き修飾(右,右下,下のみ)(転送しない)
		; in:	eax	半角数
		push	eax
		push	ecx
		push	edx
		mov	edx, 0
		lea	ecx, [eax *8]
		mov	ah, [printsize]
.lopy:		push	ecx
		push	edx
.lopx:		mov	al, [vram_font + edx]
		cmp	al, 1
		jne	.skprd
		cmp	[vram_font + edx +1], al
		je	.skpr
		mov	byte [vram_font + edx +1], 2
.skpr:		cmp	[vram_font + edx + VGXSIZE], al
		je	.skpd
		mov	byte [vram_font + edx + VGXSIZE], 2
.skpd:		cmp	[vram_font + edx + VGXSIZE+1], al
		je	.skprd
		mov	byte [vram_font + edx + VGXSIZE+1], 2
.skprd:		inc	edx
		dec	ecx
		jnz	.lopx
		pop	edx
		pop	ecx
		add	edx, VGXSIZE
		dec	ah
		jnz	.lopy
		pop	edx
		pop	ecx
		pop	eax
		ret
print_copy:	; 直接転送(透明化可能版,画面外未対応)
		; in:	eax	半角数
		;	esi	表示先アドレス
		push	eax
		push	ecx
		push	edx
		push	ebx
		push	esi
		mov	edx, 0	
		mov	ebx, printcache
		lea	ecx, [eax * 8 + 1]
		mov	ah, [printsize]
.lopy:		push	ecx
		push	edx
		push	esi
.lopx:		mov	al, [vram_font + edx]
		xlatb
		mov	[esi], al
		inc	esi
		inc	edx
		dec	ecx
		jnz	.lopx
		pop	esi
		pop	edx
		pop	ecx
		add	esi, [printbyteline]
		add	edx, VGXSIZE
		dec	ah
		jnz	.lopy
		pop	esi
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		ret
print_thru:	; 直接転送(透明化可能版,画面外未対応)
		; in:	eax	半角数
		;	esi	表示先アドレス
		push	eax
		push	ecx
		push	edx
		push	ebx
		push	esi
		mov	edx, 0	
		mov	ebx, printcache
		lea	ecx, [eax * 8 + 1]
		mov	ah, [printsize]
.lopy:		push	ecx
		push	edx
		push	esi
.lopx:		mov	al, [vram_font + edx]
		cmp	al, 0
		je	.skp
		xlatb
		mov	[esi], al
.skp:		inc	edx
		inc	esi
		dec	ecx
		jnz	.lopx
		pop	esi
		pop	edx
		pop	ecx
		add	esi, [printbyteline]
		add	edx, VGXSIZE
		dec	ah
		jnz	.lopy
		pop	esi
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		ret
print_flags:	; 文字列表示修飾設定
		; in:	eax	フラグ
		; eax:	b0=1:背景色通過/0:背景色(透明色含)で塗り潰す
		;	b1=1:文字に影をつける,0:つけない
		;	b2=1:文字の縦サイズを半分にする,0:そのまま
		;	b3=1:文字の横サイズを倍にする,0:そのまま(予約)
		mov	[printflags], eax
		mov	dword [printsize], 0x0810
		mov	dword [printcall], print_copy
		test	eax, 0x08
		jz	.skpx
		mov	byte [printsize+1], 0x10
.skpx:		test	eax, 0x04
		jz	.skpy
		mov	byte [printsize], 0x08
.skpy:		test	eax, 0x01
		jz	.skpjp
		mov	dword [printcall], print_thru
.skpjp:		ret
print_color:	; 文字列表示色設定
		; in:	eax	フラグ
		;	ebx	背景色
		;	ecx	文字色
		;	edx	影色
		mov	[printcolor], ebx
		mov	[printcolor+4], ecx
		mov	[printcolor+8], edx
		mov	[printcache], bl
		mov	[printcache+1], cl
		mov	[printcache+2], dl
		ret
print_dist:	; 文字列描画先設定
		;	esi	ライン幅
		;	edi	ベースアドレス
		mov	[printbase], edi
		mov	[printbyteline], esi
		ret
print_mode:	; 文字列表示修飾設定
		; in:	eax	フラグ
		;	ebx	背景色
		;	ecx	文字色
		;	edx	影色
		;	esi	ライン幅
		;	edi	ベースアドレス
		; eax:	b0=1:背景色通過/0:背景色(透明色含)で塗り潰す
		;	b1=1:文字に影をつける,0:つけない
		;	b2=1:文字の縦サイズを半分にする,0:そのまま
		;	b3=1:文字の横サイズを倍にする,0:そのまま(予約)
		call	print_flags
		call	print_color
		jmp	print_dist
printf_conv:	; マルチ文字列の展開
		; in:	ds:esi	SJIS文字列(ESCは"%")
		;	ds:edi	展開後のSJIS文字列
		; ファンクションリスト
		; 	"%s"	SJIS文字列(配列引数変数,文字列テーブルへのポインタ)
		;	"%S"	SJIS文字列(表示文字列の位置を格納した変数へのポインタ)
		; 	"%"+[桁数]+"n"|"h"|"N"|"H"
		;		10進数/16進数の表示(桁数指定可能)
		;		(大文字は先頭の"0"の値の表示を逆にする)
		;		(10進数:空白,16進数:"0")
		; out:	ds:esi	次のSJIS文字列(ポインタが進行される)
		;	eax	展開後の文字数
		;	
		
		mov	eax, [esi]	; 文字数
		add	eax, 3
		and	eax, -4
		jnz	.exec
		mov	[edi], eax
		ret
.exec:		push	ecx
		push	edx
		push	ebx
		push	edi
		mov	ecx, [esi]	; ecx:残り文字数
		lea	ebx, [esi+eax+4]; ebx:パラメータの先頭
		xor	edx, edx	; edx:展開先文字数
		add	edi, 4
		add	esi, 4
		; 1バイト読み込み
.loop:		mov	al, [esi]
		inc	esi
		dec	ecx
		cmp	al, "%"
		jne	.write
		; 桁数処理
		call	keta
		mov	al, [esi]
		inc	esi
		dec	ecx
		; 各種ファンクションへ
		cmp	al, "%"
		je	.write
		push	esi
		push	.funcret
		mov	esi, 10
		mov	ah, 0x20
		cmp	al, "n"
		je	fcnv_ten
		add	esi, 6
		cmp	al, "H"
		je	fcnv_ten
		mov	ah, 0x30
		cmp	al, "h"
		je	fcnv_ten
		sub	esi, 6
		cmp	al, "N"
		je	fcnv_ten
		cmp	al, "s"
		je	fcnv_str
		cmp	al, "S"
		je	fcnv_Str
		pop	eax
.funcret:	pop	esi
		jmp	.skip
.write:		; 1バイト書き出し
		mov	[edi], al
		inc	edx
		inc	edi
.skip:		jecxz	.exit
		jmp	.loop
.exit:		; 終了処理
		pop	edi
		mov	[edi], edx
		mov	eax, edx
		mov	esi, ebx
		pop	ebx
		pop	edx
		pop	ecx
		ret
fcnv_ten:	; 10/16進数変換 (Default:4桁)
		; in:	[value]	数値を格納してあるアドレスへのポインタ
		push	edx
		mov	dl, [tmpketa]
		mov	dh, ah
		or	dl, dl
		jnz	.zskip
		mov	dl, 4
.zskip:		mov	eax, [ebx]	; パラメータ=
		mov	eax, [eax]	;  数値へのポインタ

		call	cnv32
		movzx	eax, dl
		pop	edx
		add	ebx, 4
		add	edx, eax
		add	edi, eax
		ret
fcnv_str:	; SJIS文字列取り込み(変数による選択可能)
		; in:	value	文字列配列の添え字(72未満)またはその変数へのポインタ
		;	ptr	文字列配列の先頭へのポインタ
		push	ecx
		mov	ecx, [ebx]	; パラメータ1:添え字
		add	ebx, 4
		cmp	ecx, 0x0048
		jb	.vskip
		mov	ecx, [ecx]
.vskip:		mov	esi, [ebx]	; パラメータ2:ポインタ
		add	ebx, 4
		cmp	ecx, [esi]	; 配列の最大値をチェック
		jb	.ok
		mov	ecx, 0
.ok:		mov	esi, [esi + ecx*4 +4]
		
		mov	ecx, [esi]	; (文字数)
		add	esi, 4
		add	edx, ecx
		repnz	movsb
		pop	ecx
		ret
fcnv_Str:	; SJIS文字列取り込み
		; in:	ptr	文字列へのポインタ
		push	ecx
		mov	esi, [ebx]	; パラメータ:ポインタ
		add	ebx, 4
.vloop:		mov	ecx, [esi]	; (文字数)
		cmp	ecx, 0x0048
		jb	.vskip
		mov	esi, ecx
		jmp	.vloop
.vskip:		add	esi, 4
		
		add	edx, ecx
		repnz	movsb
		pop	ecx
		ret
keta:		; 桁数指定処理用 文字列から数値への変換
		; in:	
		; out:	tmpketa	変換された数値
		mov	dword [tmpketa], 0
.klop:		mov	al, [esi]
		cmp	al, "9"
		ja	.kend
		sub	al, "0"
		jb	.kend
.kskp:		inc	esi
		dec	ecx
		push	edx
		push	eax
		mov	eax, [tmpketa]
		mov	edx, 10
		mul	edx
		pop	edx
		movzx	edx, dl
		add	eax, edx
		mov	[tmpketa], eax
		pop	edx
		jecxz	.kend
		jmp	.klop
.kend:		ret
printf:		; マルチファンクション仕様文字列の表示
		; in:	ecx,edx	表示先アドレス(文字レイア内)
		;	ds:edi	SJIS文字列
		push	esi
		mov	esi, edi
		mov	edi, cnvftemp
		call	printf_conv
		call	print
		mov	edi, esi
		pop	esi
		ret
print:		; 文字列表示(拡張フォント対応,文字修飾可能)
		; in:	ecx,edx	表示先アドレス(文字レイア内)
		;	ds:edi	SJIS文字列
		cmp	dword [edi], 0
		jne	.ok
		ret
.ok:		push	eax
		push	ecx
		push	edx
		push	ebx
		push	esi
		push	edi
		; 表示先アドレスを計算
		mov	eax, [printbyteline]
		mul	edx
		lea	esi, [eax + ecx]
		add	esi, [printbase]
		test	byte [us_print + 0x05], 0x30
		jnz	.ascii
		; シフトJISから半角コードに変換
		; ~一時保存場所へ文字を描画
		mov	ebx, us_sjisdecode
		mov	eax, [edi]
		add	edi, 4
		mov	[ebx + 0x008], eax
		inc	eax
		mov	[ebx + 0x00C], edi
		mov	[us_print + 0x024], eax
		call	0xC7:0
		mov	ebx, us_print
		mov	dword [sjistemp + eax*4-4], 0x20
		call	0xC7:0
		dec	eax
		jmp	.skp
.ascii:		; そのままASCII文字描画
		mov	ebx, us_print
		mov	eax, [edi]
		add	edi, 4
		mov	[ebx + 0x024], eax
		mov	[ebx + 0x028], edi
		call	0xC7:0
.skp:		; 修飾して文字転送
		; (透明色や影付き文字の実現のため)
		test	byte [printflags], 4
		jz	.skp1
		call	print_smally
.skp1:		test	byte [printflags], 2
		jz	.skp2
		test	byte [printflags], 4
		jnz	.skp3
		call	print_small1
.skp3:		call	print_kagerd
.skp2:		call	near [printcall]
		pop	edi
		pop	esi
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		vupd
		ret
cls:		; 画面を単色で塗り潰す
		; in:	eax	色
		push	ecx
		push	edi
		
		mov	ecx, SCXSIZE_MAX*SCYSIZE_MAX>>2
/*		push	eax
		push	edx
		mov	eax, [winsizex]
		mov	edx, [winsizey]
		mul	edx
		pop	edx
		mov	ecx, eax
		pop	eax
		add	ecx, 3
		shr	ecx, 2
		or	ecx, ecx
		jnz	.ret
		mov	ecx, (VGXSIZE*VGYSIZE+3)>>2
*/
		mov	edi, vram_screen
.ret:		repnz	stosd
		pop	edi
		pop	ecx
		ret
cls_2nd:	; 重ね合わせレイアのクリア
		; in:	eax	半透明レイアのクリア色
		;	edx	透明レイアのクリア色
		push	eax
		push	ecx
		push	edi
		mov	ecx, VGXSIZE*VGYSIZE>>2
		mov	edi, vram_back
		repnz	stosd
		mov	ecx, VGXSIZE*VGYSIZE>>2
		mov	edi, vram_fore
		mov	eax, edx
		repnz	stosd
		pop	edi
		pop	ecx
		pop	eax
		vupd
		ret
windowmaxsize:	; ウィンドウの最大サイズを取得する
		; out:	esi,edi	最大サイズ
		push	ebx
		mov	ebx, us_maxwinsize
		call	0xC7:0
		pop	ebx
		mov	ecx, [win_maxsize]
		mov	edx, [win_maxsize+4]
		test	byte [us_windowopen + 0x008], 2
		jz	.skp
		add	ecx, 8 +8
		add	edx, 29+8
.skp:		cmp	ecx, SCXSIZE_MAX
		jb	.skpx
		mov	ecx, SCXSIZE_MAX
.skpx:		cmp	edx, SCYSIZE_MAX
		jb	.skpy
		mov	edx, SCYSIZE_MAX
.skpy:		ret
windowclose:	; ウィンドウを閉じる(完了するまで待つ)
		push	eax
		push	ebx
		mov	eax, -1
		mov	dword [byteperline+4], 0
		mov	ebx, us_windowclose
		mov	[winsignal], eax
		call	0xC7:0
		mov	byte [window_status], 0
.lop:		call	sleep
		cmp	[winsignal], eax
		je	.lop
		pop	ebx
		pop	eax
		test	byte [winclosehandler+4], 1
		jz	.ret
		mov	ebx, us_libclose
		call	0xC7:0
.ret:		ret
windowopen:	; ウィンドウを開く
		; in:	esi,edi	ウィンドウサイズ
		;	[usewindow] ウィンドウ枠の有無(b0=1:無し)
		push	eax
		push	ecx
		push	edx
		push	ebx
		and	byte [us_windowopen + 0x008], 0xFD
		mov	byte [us_windowopen + 0x01C], 0x1C
		mov	byte [us_windowopen + 0x020], 0x1C
		mov	dword [us_windowopen + 0x014], MODE_USEWINDOW
		cmp	byte [usewindow], 1
		ja	.wfl
		je	.wok
		call	windowmaxsize
		cmp	edi, edx
		jbe	.wok
		;cmp	esi, ecx
		;jbe	.wok
.wfl:		or	byte [us_windowopen + 0x008], 0x02
		mov	byte [us_windowopen + 0x01C], 0x00
		mov	byte [us_windowopen + 0x020], 0x00
		mov	dword [us_windowopen + 0x014], MODE_FULLSCREEN
.wok:		call	windowmaxsize
		cmp	esi, ecx
		jbe	.xok
		mov	esi, ecx
.xok:		cmp	edi, edx
		jbe	.yok
		mov	edi, edx
.yok:		mov	[us_windowopen + 0x00C], esi
		mov	[us_windowopen + 0x010], edi
		mov	[us_windowgbox + 0x014], esi
		mov	[us_windowgbox + 0x018], edi
		mov	eax, edi
		mov	edx, 0
		mov	ecx, 3
		mov	[byteperline+4], esi
		div	ecx
		mov	[us_redraw + 0x014], esi
		mov	[us_redraw + 0x018], eax
		mov	edx, eax
		mov	[us_redraw_2 + 0x010], eax
		mov	[us_redraw_2 + 0x014], esi
		mov	[us_redraw_2 + 0x018], edx
		add	eax, edx
		mov	[us_redraw_3 + 0x010], eax
		mov	eax, edi
		sub	eax, edx
		sub	eax, edx
		mov	[us_redraw_3 + 0x014], esi
		mov	[us_redraw_3 + 0x018], eax
		mov	[us_redraw_line + 0x014], esi
		mov	[winsizex], esi
		mov	[winsizey], edi
		mov	eax, esi
		shr	eax, 3
		sub	eax, 12 ;10
		mov	[us_windowtitle1 + 0x010], eax
		mov	ebx, us_windowopen
		call	0xC7:0
		; 画面の拡大縮小率の更新
		mov	ecx, VGXSIZE
		mov	edx, VGYSIZE+DEBUGSIZE
		call	InitStretch
		mov	byte [window_status], 1
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		ret
inikillhandler:	; 終了前の処理の登録を解除する
		mov	ebx, 0
setkillhandler:	; 終了前の処理を登録する
		; in:	ebx	呼び出し先
		mov	[winclosehandler], ebx
		ret

bgmdllcall1:	; BGM.DLLの呼び出し
		; in:	esi	ファンクション番号
		;	その他	パラメータなど
		; 存在判定
		test	dword [bgmdllversion], -1
		jz	.notexist
		push	ebp
		mov	ebp, BGM_WORK
		call	0x0207:0x00000048
		pop	ebp
.notexist:	ret
bgmdllcall2:	; BGM.DLLの呼び出し
		; in:	esi	ファンクション番号
		;	ebp	バッファアドレス
		test	dword [bgmdllversion], -1
		jz	.notexist
		;mov	ebp, BGM_WORK_0
		call	0x0207:0x00000048
.notexist:	ret
bgml_loadplay:	; 演奏データを指定して再生開始
		; in:	ebx	演奏データへのポインタ
		;	ecx	(ファイスサイズ)
		;	dl	ループ設定(0:data,1:on,2:off)
		test	byte [bgmlibcall], 1
		jnz	.ok
		ret
.ok:		push	eax
		push	ebx
		push	edx
		and	al, 1
		push	eax
		push	eax
		call	bgmlib_pause
		pop	eax
		call	bgmlib_load
		pop	eax
		pop	ebx
		call	bgmlib_play
		pop	ebx
		pop	eax
		ret
;///////////////////////////////////////////////////////
_OsaskMain:	;/*//// メイン ///////////////////////*/
		cld
		mov	byte [keypad_emu], 2
		mov	dword [byteperline], VGXSIZE
		mov	dword [byteperline+4], STXSIZE
		mov	dword [sig_ptr], signalbuffer
		mov	ebx, init
		call	0xC7:0
		mov	eax, 0x08080808
		call	cls
		mov	esi, STXSIZE
		mov	edi, STYSIZE
		call	windowopen
		; デフォルト値設定
		mov	dword [propttemp], PRFLAG_DEFAULT
;		mov	dword [ScreenSize], SCXSIZE_DEFAULT
;		mov	dword [ScreenSize+4], SCYSIZE_DEFAULT
		mov	dword [dispresonum], SCRNUM_DEFAULT
		mov	dword [fasthalf], FASTHALF_DEFAULT
		mov	dword [SavPadCount], SHORTPUSH_DEF
		mov	dword [PlyBGMDevice], BGMDEV_DEFAULT
		mov	dword [PlySEQDevice], SEQDEV_DEFAULT
		mov	dword [PlySndTimer], BGMLIB_INT_HZ
		mov	esi, KeyPadTableInit
		mov	edi, KeyPadTable
		mov	ecx, 16
		repnz	movsd	; キーパッドデフォルト設定
		mov	eax, 0x0B
		mov	ebx, 0x08
		mov	ecx, 0x00
		mov	edx, 0x0F
		mov	esi, [winsizex]
		mov	edi, vram_screen
		call	print_mode

		mov	edi, loadingmsg
		mov	eax, [edi]
		mov	ecx, [winsizex]
		shl	eax, 3
		mov	edx, [winsizey]
		sub	edx, 18
		shr	edx, 1
		sub	ecx, eax
		shr	ecx, 1
		call	print
		call	GpFlush

		; 乱数系列の初期化
		mov	eax, [getrandseed + 0x008]
		call	setseed
		call	_sti	; シングルハンドラ許可
		; 以下、疑似マルチタスク。
		
		mov	ebx, us_settimer
		call	0xC7:0	/* タイマ時間基点のリセット */
		
		mov	eax, BGM_INT_HZ
		mov	ecx, BGM_SLOT
		mov	ebx, us_setbgmtimer
		call	set_timerrate
		call	0xC7:0	/* BGM処理兼VSYNC用タイマ */

		; 先にBGM.DLLの読み込み
		; (オープンした順にmmtがセットされる)
		; 00:初期化ファイル
		mov	eax, FILE_SLOT
		mov	edx, SaveFileName
		mov	edi, cs:[0x0010]
		mov	esi, 0
		mov	ebx, 0x05
		call	filelocalopen	/* ダミー */

		; 01:BGM.DLL
		mov	eax, FILE_SLOT+0x10
		mov	edx, BGMDLLName
		call	filelocalopen
		push	edi
		
		; 初期化情報の読み込み
		pusha
		mov	eax, 0
		call	savedataopen
		popa
		
		; 拡張フォントの準備
		mov	ebx, _loadfont1
		mov	eax, FONT_SLOT
		mov	edx, loadedfont
		call	addjob
		mov	[ebx + 0x10], eax
		call	0xC7:0

		; ファイル読み込み
		; (オープンした順にmmtがセットされる)
		; 02:PTNDAT.BMP
		pop	edi
		mov	eax, FILE_SLOT+0x20
		mov	edx, PTNDATFileName
		mov	esi, 0
		mov	ebx, 0x05
		push	edi
		call	filelocalopen
		; 03:PTNCHR.BMP
		mov	eax, FILE_SLOT+0x30
		mov	edx, PTNCHRFileName
		call	filelocalopen
		; 機種チェック
		call	TownsCheck
		call	PC98Check

.lop1:		call	sleep
		cmp	dword [addjobings], 0
		jne	.lop1

		; ファイル読み込み
		mov	eax, FILE_SLOT+0x20
		call	fileclose
		mov	eax, FILE_SLOT+0x30
		call	fileclose
		; 04:PTNTITLE.BMP
		pop	edi
		mov	eax, FILE_SLOT+0x20
		mov	edx, TITLEFileName
		mov	esi, 0
		mov	ebx, 0x05
		call	filelocalopen
		; 05:PTNMENU.BMP
		mov	eax, FILE_SLOT+0x30
		mov	edx, MENUBGFileName
		call	filelocalopen
		
.lop2:		call	sleep
		cmp	dword [addjobings], 0
		jne	.lop2

		; DLLマッピング
		; (ファイルがマップされていなくても多分
		;  失敗しない…と思う。リミット1byteになるかも。)
		mov	edx, [mmt_base+4]
		mov	ecx, [mmt_fsize+4]
		mov	eax, 0x0200
		cmp	ecx, 0
		jz	.dllnone
		call	newsegement
		; マップしたファイルを閉じてはいけない。
		;mov	eax, [mmt_fileid] ; FILE_SLOT
		;call	fileclose
		; バージョン確認
		mov	esi, -1
		call	0x0207:0x00000048
		; out:eax=version,ebx:revsion
		mov	[bgmdllversion], eax
		mov	[bgmdllrevsion], ebx
		; BGMライブラリの初期化
		; in:	esi	0x0001
		;	eax	タイマスロット
		;	edx	タイマ周波数(1Hz=1000000)
		;	ds:ebp	総合管理バッファのアドレス
		;	ecx	用意したバッファの最大サイズ
		; 読み込みの終了
		mov	esi, 1
		mov	eax, BGM_SLOT
		mov	edx, BGM_INT_HZ
		mov	ebp, BGM_WORK
		mov	ecx, BGM_WORK_SIZE
		call	0x0207:0x00000048
		jmp	.dllskip
.dllnone:	; BGMライブラリの初期化
		mov	eax, bgmlib_init
		or	eax, eax
		jz	.dllskip
		; ライブラリリセット
		mov	eax, BGM_SLOT
		mov	ecx, [PlySndTimer]
		or	ecx, ecx
		jnz	.dlls0
		mov	ecx, BGMLIB_INT_HZ
.dlls0:		mov	edx, 1
		call	bgmlib_init
		; タイマの管理を任せる
		mov	byte [bgmlibcall], 1
		; デバイスのリセット
		mov	ebx, [PlyBGMDevice]
		mov	edx, BEEP_SLOT
		cmp	ebx, 2
		jb	.dlls1
		mov	edx, [PlyBGMPort + ebx*4 -8]
		or	edx, edx
		jnz	.dlls1
		mov	edx, 0x03310330	; 0xE0D2E0D0
		cmp	ebx, 2
		ja	.dlls1
		mov	edx, 0x02290228
.dlls1:		mov	al, 0
		call	bgmlib_device
		mov	ebx, [PlySEQDevice]
		mov	edx, BEEP_SLOT
		cmp	ebx, 2
		jb	.dlls2
		mov	edx, [PlySEQPort + ebx*4 -8]
		or	edx, edx
		jnz	.dlls2
		mov	edx, 0x03310330 ; 0xE0D2E0D0
		cmp	ebx, 2
		ja	.dlls2
		mov	edx, 0x02290228
.dlls2:		mov	al, 1
		call	bgmlib_device
		
.dllskip:	; ロードしたBMPファイルをパターンに登録
		; タイトルグラフィックデータ
		mov	edi, [mmt_base +8]
		mov	ecx, [mmt_fsize +8]
		mov	ebx, 0
		call	bitmap_regist
		; メニューグラフィックデータ
		mov	edi, [mmt_base +12]
		mov	ecx, [mmt_fsize +12]
		mov	ebx, 1024
		call	bitmap_regist
		; パレット変換テーブルの初期化
		mov	eax, 0
		mov	ebx, palettetablebg
		call	bitmap_initpal
		mov	eax, 0x0CFF
		mov	ebx, palettetablefg
		call	bitmap_initpal
		; パターンメモリの確保
		;mov	dword [psize], 16
		;mov	dword [psize+4], 16

		; ウィンドウのリサイズ
		call	windowclose
		call	setnumtosize
		mov	esi, [ScreenSize]
		mov	edi, [ScreenSize+4]
		call	windowopen

		; VSYNC互換割り込みを使えるようにする
		call	vsync_init
		mov	eax, 0
		call	vsync
		call	screen_on
		mov	byte [redraw_init], 1
		
.title:		; タイトル画面の表示
		call	title
		mov	eax, 0
		mov	[fps_count], eax
		; メニュー
		; (背景グラフィック:無し)
		call	menu
		rol	eax, 1
		ror	eax, 1
		jc	.title
		
;///////////////////////////////////////////////////////
		call	screen_off
		call	windowclose
		
		mov	ebx, us_libclose
		call	0xC7:0
		
.iend:		mov	eax, 5
		call	vsync_nodraw
		jmp	.iend
setnumtosize:	; 解像度番号から解像度を設定
		push	eax
.st:		mov	eax, [dispresonum]
		cmp	eax, 0
		jl	.ret
		cmp	eax, displaytablesize>>3
		jb	.ok
.re:		mov	dword [dispresonum], 0
		jmp	.st
.ok:		mov	esi, [displaytable + eax*8]
		mov	edi, [displaytable + eax*8 +4]
		mov	eax, esi
		mov	[ScreenSize], esi
		mov	[ScreenSize+4], edi
		or	eax, edi
		jz	.re
.ret:		pop	eax
		ret
title:		; タイトル画面の表示
		mov	eax, 0
		mov	ecx, GPXSIZE
		mov	edx, GPYSIZE
		call	backgraphic
		bpmupd
		cmp	dword [vram_back], -1
		je	.tskip
		mov	al, 0
		mov	esi, 3
		mov	ecx, 0xFFFF8000
		call	screeneffect
.tskip:		mov	eax, 0
		call	vsync
		
		; タイトル画面BGMの再生
		mov	al, 0
		mov	ebx, se_startup
		mov	ecx, 4096
		mov	dl, 0	; (=2:ループ禁止)
		call	bgml_loadplay
		
		mov	edi, pushwaitmsg
		mov	edx, ((VGYSIZE-16)*3)>>2
		mov	ecx, [edi]
		mov	eax, VGXSIZE
		shl	ecx, 3
		sub	eax, ecx
		mov	ecx, eax
		shr	ecx, 1
		call	print
		
.lop:		mov	eax, 1
		call	vsync_nodraw
		call	getkeybuf
		cmp	eax, KY_ENTER
		je	.ext
		cmp	eax, KY_SPACE
		je	.ext
		cmp	eax, MO_LEFT
		je	.ext
		jmp	.lop
.ext:
		mov	al, 0
		mov	esi, 2
		mov	ecx, 0xFF0080FF
		call	screeneffect
		mov	eax, 0
		mov	edx, -1
		call	cls_2nd
		ret
_mainmenu:	; メインメニュー表示
		push	ecx
		push	edx
		mov	ebx, mainmenu
		mov	ecx, 16
		mov	edx, 64
		call	menu_disp
		pop	edx
		pop	ecx
		ret
_savedatamenu:	; セーブデータメニューの表示
		push	ecx
		push	edx
		or	eax, 0x20
		mov	ebx, savedatamenu
		mov	ecx, 56
		mov	edx, 48
		call	menu_disp
		pop	edx
		pop	ecx
		ret
_savesubmenu:	; セーブデータサブメニューの表示
		push	ecx
		push	edx
		mov	ecx, 112
		mov	edx, 32
		mov	ebx, entermenu
		call	menu_disp
		pop	edx
		pop	ecx
		ret
menu:		; タイトルメニュー
		; 背景グラフィック
		mov	eax, 1024
		mov	ecx, GPXSIZE
		mov	edx, GPYSIZE
		cmp	[ptnmap], ax
		je	.bgskip
		call	backgraphic
		bpmupd
		mov	al, 0
		mov	esi, 2
		mov	ecx, 0xFFFF8000
		call	screeneffect
		mov	eax, 10
		call	vsync_nodraw
.bgskip:	; タイトル画面BGMの再生
		mov	al, 0
		mov	ebx, bgm_tetris
		mov	ecx, 4096
		mov	dl, 0	; (=2:ループ禁止)
		call	bgml_loadplay

		; 風来のシレン風
		;	┌─────────────┐
		;	│1:風来のシレン   11回目│
		;	│    22F テーブルマウンテン│
		;	│2:風来のn i k a   20回目│
		;	│     8F ネブリ山廃坑      │
		;	└─────────────┘
		;	(記録なしは表示されない)
		; 		┌────────┐
		;		│冒険のつづきから│
		;		│渓谷の宿場に戻る│
		;		└────────┘
		; 実装
		; 	┌───────────┐
		;	│⇒1:名無しさん の冒険│
		;	│       0回目   0:00:00│
		;	│      0F  63x 63迷路  │
		;	│  2:データがありません│
		;	│                      │
		;	│                      │
		;	│  3:名無しさん の冒険│
		;	│       0回目   0:00:00│
		;	│      0F  63x 63迷路  │
		;	└───────────┘
		; 		┌───────┐
		;		│⇒新しく始める│
		;		└───────┘
		; 		┌────────┐
		;		│⇒続きから始める│
		;		│⇒あきらめる  │
		;		│⇒記録を消す  │
		;		│⇒記録をコピー │
		;		└────────┘
		;	
		; 半透明ウィンドウの色設定
.startmenu:	mov	dword [windowcache], 0x8F840FFF
		mov	byte [printcache+1], 0x0F
		; メインメニュー
		mov	eax, 1
		call	_mainmenu
		cmp	eax, 0x0048
		jl	.entermenu
		call	eax
		jmp	menu	; .startmenu
.entermenu:	; メニュー選択決定
		; out:	eax	返り値
		push	eax
		mov	al, 0
		mov	esi, 3
		mov	ecx, 0xFF0080FF
		call	screeneffect
		pop	eax
		ret
		; メッセージウィンドウ
		push	eax
		mov	ecx, 16
		mov	edx, 224 -8 -48
		mov	esi, 256 -32
		mov	edi, 48
		call	newwindow
		pop	eax
		ret
m_savedata:	; セーブデータ選択ウィンドウを開く
		; メインメニューを暗く表示

.ms_cancel2:	; 前準備
		mov	dword [windowcache], 0x878408FF
		mov	byte [printcache+1], 0x07
		mov	eax, 6
		call	_mainmenu
		call	saveindexupdate
		; セーブデータメニューを表示
		mov	dword [windowcache], 0x8F840FFF
		mov	byte [printcache+1], 0x0F
		mov	eax, 0x21
		;mov	ebx, savedatamenu
		;mov	ecx, 56
		;mov	edx, 48
		call	_savedatamenu

		movzx	ebx, bh
		; キャンセルチェック
		rol	eax, 1
		ror	eax, 1
		jnc	.ms_cancel1
		ret
.ms_cancel1:	; セーブデータ選択後の処理
		; 内部バッファを選択したセーブデータにする
		mov	eax, ebx
		inc	eax
		call	savedataopen
		; (セーブデータサブメニューの表示)
		; セーブデータメニューを暗くする
		mov	dword [windowcache], 0x878408FF
		mov	byte [printcache+1], 0x07
		push	ebx
		mov	eax, 6
		call	_savedatamenu
		; セーブデータ操作メニュー用バッファの初期化
		mov	ebx, entermenu
		mov	ecx, 0
		call	menu_clear
		mov	[ebx + 0x00C], ecx
		pop	ebx
		; セーブデータ操作メニューの作成
		mov	esi, entermenusrc
.ms_subloop:	cmp	dword [esi], 0x0048
		jb	.ms_subexit
		push	ebx
		push	esi
		mov	eax, 0
		call	near [esi]
		pop	esi
		; out:eax:b0=1:追加する
		mov	edi, cnvftemp
		push	dword [esi]
		add	esi, 4
		push	eax
		call	printf_conv
		pop	eax
		test	eax, 1
		pop	eax
		jz	.ms_addskip
		mov	ebx, entermenu
		mov	edx, 0
		call	menu_additem
.ms_addskip:	pop	ebx
		jmp	.ms_subloop
.ms_subexit:
		; セーブデータ操作メニューを表示
		mov	dword [windowcache], 0x8F840FFF
		mov	byte [printcache+1], 0x0F
		push	ebx
		mov	eax, 1
		call	_savesubmenu
		pop	ebx
		; キャンセルチェック
		rol	eax, 1
		ror	eax, 1
		jc	.ms_cancel2
		
		; セーブデータ処理
		; in:	ebx	セーブデータ番号(0~)
		; out:	eax	キャンセルフラグ/返り値
		;		(b31=1:キャンセル)(0<=EAX<72:返り値)
		push	ebx
		push	.ms_subretn
		push	eax
		mov	eax, 0
		dec	eax
		ret
.ms_subretn:	pop	ebx
		; キャンセルチェック
		rol	eax, 1
		ror	eax, 1
		jc	.ms_cancel2
		; キャンセルしない場合はメインメニューへ戻る
		push	eax
		mov	eax, 0x02
		call	_savedatamenu
		pop	eax
		shl	eax, 1
		stc
		rcr	eax, 1
		ret
m_config:	; ゲーム設定などを変える///////////////
		; 設定値バックアップ
		mov	esi, ConfigCopyBegin
		mov	edi, IndexDataEnd
		mov	ecx, ConfigCopySize
		
		repnz	movsb
.config:	; メニューの再構築
		mov	ebx, configmenu
		mov	ecx, 24
		call	menu_clear
		; eax,edx,ebx=menu,edi=addstr
		mov	esi, configmenusrc+4
		mov	edi, cnvftemp
		mov	edx, 0
.mlop:		cmp	[esi], edx
		je	.mext
		push	dword [esi-4]
		call	printf_conv
		pop	eax
		call	menu_additem
		add	esi, 4
		jmp	.mlop
.mext:		; 設定ウィンドウの表示
		mov	dword [windowcache], 0x8F840FFF
		mov	byte [printcache+1], 0x0F
		mov	eax, 0x01
		mov	ebx, configmenu
		mov	ecx, 24
		mov	edx, 64
		call	menu_disp
		movzx	ebx, bh
		cmp	eax, 0x48
		jl	.mend
		call	eax
		; 設定変更を常に書き出し。
		mov	eax, 0
		call	saveupdate
		jmp	.config
.mend:		mov	eax, 0x02
		mov	ebx, configmenu
		;call	menu_disp
		ret
m_config1:	; フィルタ変更
		inc	dword [scopyvalue]
		mov	eax, [scopyvalue]
		cmp	eax, [scopynames]
		jb	.ret
		mov	dword [scopyvalue], 0
.ret:		mov	eax, 0
		call	cls
		mov	byte [redraw_init], 1
		ret
m_config2:	; 表示画面領域のサイズ変更
		test	bl, 1
		jz	.inc
		sub	dword [dispresonum], 1
		jnb	.skp
		mov	dword [dispresonum], (displaytablesize>>3)-1
		jmp	.skp
.inc:		inc	dword [dispresonum]
.skp:		call	windowclose
		call	setnumtosize
		mov	esi, [ScreenSize]
		mov	edi, [ScreenSize+4]
		call	windowopen
		mov	eax, 0
		call	cls
		mov	byte [redraw_init], 1
		ret
m_config3:	; ウィンドウ枠の有無変更
		mov	eax, [usewindow]
		inc	eax
		cmp	eax, [inusenames]
		jb	.ok
		mov	eax, 0
.ok:		mov	[usewindow], eax
		call	windowclose
		mov	eax, 0
		call	cls
		mov	esi, [ScreenSize]
		mov	edi, [ScreenSize+4]
		call	windowopen
		mov	byte [redraw_init], 1
		ret
m_config4:	; 文字修飾フラグの変更
		mov	eax, [propttemp]
		inc	eax
		cmp	eax, [proptnames]
		jb	.ok
		mov	eax, 0
.ok:		mov	[propttemp], eax
		shl	eax, 1
		jmp	print_flags
m_config5:	; 半透明ディザリング処理の間引き設定
		xor	byte [fasthalf], 1
		ret
m_config6:	; ゲームパッドデバイス/使用・不使用の設定
		mov	eax, [userpadnames]
		inc	dword [UsePadFlags]
		cmp	[UsePadFlags], eax
		jb	.ret
		mov	dword [UsePadFlags], 0
.ret:		/* 変更と同時に初期化処理が自動的に呼ばれて 
		 * 画面が更新される頃には初期化(チェック)が完了している */
		ret
m_config7:	; ゲームパッドポートの選択
		mov	eax, [userpadpnames]
		inc	dword [UsePadFlags+4]
		cmp	[UsePadFlags+4], eax
		jb	.ret
		mov	dword [UsePadFlags+4], 0
.ret:		/* デバイスの設定とともにメニューを抜ける時に
		 * 実際の使用デバイスを変更するようにしたほうがいいだろう…
		 * が、手抜き。 */
		ret
m_config_back:	; 設定を元に戻す
		mov	esi, IndexDataEnd
		mov	edi, ConfigCopyBegin
		mov	ecx, ConfigCopySize
		
		repnz	movsb
		call	windowclose
		mov	eax, [propttemp]
		shl	eax, 1
		call	print_flags
		mov	eax, 0
		call	cls
		mov	esi, [ScreenSize]
		mov	edi, [ScreenSize+4]
		call	windowopen
		
		mov	byte [redraw_init], 1
		ret
menu_disp:	; 半透明ウィンドウと指定したメニューの表示
		; in:	eax	フラグ(通常は0)
		;		b6-b4:移動行数-1(000:1行,001:2行,010:3行,011:4行,100:5行…)
		;		b2=1:選択後のウィンドウを消さない
		;		b1=1:ウィンドウの表示のみ
		;		b0=1:キャンセル可能
		;	ebx	メニュー
		;	ecx,edx	表示位置
		; out:	eax	選択したメニューの返り値(選択しなかった場合は不定)
		;	bl,bh	選択したメニュー位置番号
		;	edx	選択したメニューのopt
		push	ecx
		push	edx
		push	esi
		push	edi
		; 最後に開いたメニュー情報を保存
		mov	[menu_oldmenu], ebx
		mov	[menu_oldleft], ecx
		mov	[menu_oldtop], edx
		mov	[menu_oldflag], eax
		; [ebx]:メニュー数, 最大半角数, opt, 前回の選択したメニュー番号(復帰用)
		; アイテム数・最大文字数キャッシュのチェック
		cmp	dword [ebx], 0
		je	.menuchecker
		cmp	dword [ebx+4], 0
		jne	.menuchecked
.menuchecker:	; ウィンドウの大きさを特定するためのチェック
		push	eax
		push	ecx
		push	edx
		push	ebx
		add	ebx, 0x10
		mov	dh, 0
		mov	ecx, 0
.chkloop:	cmp	dword [ebx+8], 0
		jz	.chkexit
		inc	ecx
		mov	eax, [ebx+8]
		mov	dl, [ebx+8]	/* len */
		add	eax, 3
		cmp	dl, dh
		jbe	.chkskp1
		mov	dh, dl
.chkskp1:	and	eax, -4
		lea	ebx, [ebx + eax +12]
		jmp	.chkloop
.chkexit:	pop	ebx
		mov	[ebx + 0x000], ecx
		mov	[ebx + 0x004], dh
		pop	edx
		pop	ecx
		pop	eax
.menuchecked:	; 半透明ウィンドウの表示
		mov	esi, [ebx +4]
		mov	edi, [ebx]
		lea	esi, [esi*8 +20]
		shl	edi, 4
		call	newwindow
		; メニューの表示
		push	eax
		push	esi
		push	ecx
		push	edx
		push	edi
		push	edx
		mov	edi, ebx
		mov	esi, eax
		add	edi, 0x18
		add	ecx, 18
.dsploop:	cmp	dword [edi], 0
		jz	.dspexit
		call	print
		mov	eax, [edi]
		add	edx, 16
		add	eax, 15
		and	eax, -4
		add	edi, eax
		jmp	.dsploop
.dspexit:	; カーソルの表示(描画のみの場合用)
		shr	esi, 4
		mov	edx, 16
		and	esi, 7
		movzx	eax, byte [ebx + 0x0D]
		inc	esi
		mul	edx
		mul	esi
		sub	ecx, 18
		pop	edx
		add	edx, eax
		mov	edi, menucursor
		call	print
		pop	edi
		pop	edx
		pop	ecx
		pop	esi
		pop	eax
		; メニューの選択
		push	eax
		test	eax, 2
		jnz	.menuskip
		push	esi
		push	edi
		push	ebx
		ror	eax, 16
		dec	esi
		mov	ax, [ebx + 0x0C]
		dec	edi
		rol	eax, 16
		lea	esi, [esi + ecx -1]
		mov	bh, al
		lea	edi, [edi + edx -1]
		and	bh, 0x70
		mov	bl, 0xFF
		add	bh, 0x10
		call	menu_select
		pop	edi
		mov	[edi + 0x00C], ebx
		; メニューの返り値を取得(横位置未対応)
		add	edi, 0x10
	;	mov	esi, eax
		push	ebx
		test	eax, 1
		jz	.selloop
		mov	bh, -1
.selloop:	cmp	bh, 0
		je	.selexit
		mov	eax, [edi +8]
		or	eax, eax
		jz	.selexit
		add	eax, 15
		and	eax, -4
		add	edi, eax
		dec	bh
		jnz	.selloop
.selexit:	mov	eax, [edi+4]	; edx=[opt]
		mov	[esp +0x18], eax
		mov	eax, [edi]
	;	test	esi, 1
	;	jz	.selnerr
	;	or	eax, 0x80000000
.selnerr:	pop	ebx
		pop	edi
		pop	esi
.menuskip:	; メニューの消去
		test	byte ds:[esp + 0x000], 4
		jnz	.deleskip
		call	delwindow
.deleskip:	add	esp, 4
		pop	edi
		pop	esi
		pop	edx
		pop	ecx
		ret
addkeybuf:	; 最後に入力したカーソルキーを設定
		; in:	eax	キーコード
		push	ebx
		inc	byte [vram_fore]
		and	byte [vram_fore], 0x0F
		mov	ebx, [getlastkeywrite]
		mov	[getlastkey + ebx*4], eax
		inc	ebx
		and	ebx, 0x0F
		cmp	[getlastkeyread], ebx
		je	.ret
		mov	[getlastkeywrite], ebx
.ret:		pop	ebx
		ret
getkeybuf:	; 最後に入力したカーソルキーを取得
		; out:	eax	キーコード
		mov	eax, 0
		push	ebx
		mov	ebx, [getlastkeyread]
		cmp	ebx, [getlastkeywrite]
		je	.ret
		mov	eax, [getlastkey + ebx*4]
		inc	ebx
		and	ebx, 0x0F
		mov	[getlastkeyread], ebx
.ret:		pop	ebx
		ret
; セーブデータの状態について
; ・未初期化状態(セーブデータが破損状態)
;	↓(自動)⇒m_savedatachk
; ・空きエリア状態←──────┐
;	↓(メニューから選択))	│
; ・最初から状態		│
;	↓(自動的にプレイへ)	│(削除)
; ・続きから状態←(再開時)	│
;	↓└→(プレイへ)	│
;	└───────────┘
;m_subprograms:	; /*****************/
	; in:	eax	ファンクション番号
	; in:	eax=0	メニューからの判断用呼び出し
	;	ebx	セーブデータ番号(0~(通常は0~2))
	; out:	eax	(b0=1:追加する)
	;	edx	オプション値
	; in:	eax=1	メニューの実行
	; out:	eax	(b31=1:メニューを全半透明ウィンドウを閉じて終了する=確定)
	;	edx	戻り値
	; その他のファンクションは未定
	; 内部仕様について
	; ・データの読み込みはSaveDataバッファに選択データが存在しているので直接参照できる
	; ・全体のデータは(Indexにも)読み込まれないのでコピー等の処理は現在はできない。
	
	
m_newgame:	; ゲームデータをゲーム開始状態にして始める
		cmp	eax, 1
		jb	.addcheck
		; 選択後の処理
		; =(セーブデータエリアを初期化して開始)
		; 初期化するもの
		; ・プレイヤーの名前
		; ・フロアとマップのサイズ
		; ・各種設定
		mov	eax, 0
		mov	ecx, SaveDataSize
		mov	edi, SaveDataBegin
		add	ecx, 3
		
		shr	ecx, 2
		repnz	stosd
		call	rnd
		mov	[SavProtect1], eax
		mov	eax, 0
		call	rnd
		mov	[SavProtect2], eax
		; 名前登録
		push	ebx
		; デフォルトの名前を転送
		mov	esi, defaultname
		mov	edi, SavNameLen
		mov	ecx, 12
		movsd
		repnz	movsb
		; 名前入力(セーブデータエリアを直接指定)
		mov	ecx, 12
		mov	edi, SavNameLen
		mov	eax, 0	/* キャンセル不可 */
		call	name_entry /* というか現在は名前入力ルーチンをキャンセルで終了することはできない。 */
		mov	dword [SavDungeonNum], 1
		mov	dword [SavDungeonOpt], 2
		
		; 乱数系列の設定
		mov	eax, 0
		call	rnd
		mov	[SavRandSeed], eax
		
		; 各種初期値の設定
		mov	dword [MapperDot], MAPDOT_DEFAULT
		mov	dword [MapperStyle], MAPSTYLE_DEFAULT
		mov	esi, MapperColorInit
		mov	edi, MapperColor
		mov	ecx, 16
		repnz	movsb
		
		; セーブデータ更新
		pop	ebx
		mov	eax, ebx
		inc	eax
		call	saveupdate
		
		
		/* 自動的に"続きから始める"を呼んでもいいかもしれない */
		mov	eax, -1
		jmp	m_loadgame
.execancel:	mov	eax, 0
		ret
.addcheck:	; 追加できるか。
		cmp	dword [SavDungeonNum], 1
		jnb	.noadd
		mov	eax, 1
.noadd:		ret
m_loadgame:	; セーブデータの状態を再現して始める//
		cmp	eax, 1
		jb	.addcheck
		; セーブされた場所(ダンジョン/休憩所)によって処理が異なる
		; 休憩所などの村の場合は常に同じところから始めるようにするべき
		; ダンジョンの場合はマップを再作成してプレイを再現して始められる。
		mov	eax, 1	/* リプレイをスキップ */
		jmp	GameMain
.addcheck:	; 追加チェック
		cmp	dword [SavDungeonNum], 1
		jb	.noadd
		mov	eax, 1
.noadd:		ret
m_leavegame:	; ゲームをあきらめる//
		cmp	eax, 1
		jb	.addcheck
		ret
.addcheck:	; 追加チェック
		mov	eax, 0
		ret
m_datadelete:	; ゲームデータを初期化して未使用状態にする//
		cmp	eax, 1
		jb	.addcheck
		/* 本来はデータ消去の確認をするべき */
		push	eax
		mov	dword [SavDungeonNum], 0
		; セーブデータエリアのすべて初期化する
		mov	edi, SaveDataBegin
		mov	eax, 0
		mov	ecx, (SaveDataSize+3)>>2
		
		repnz	stosd
		; セーブデータ更新
		mov	eax, ebx
		inc	eax
		call	saveupdate
		/* ファイルを消去すべきだろうか */
		pop	eax
		ret
.addcheck:	; 追加チェック
		cmp	dword [SavDungeonNum], 1
		jb	.noadd
		mov	eax, 1
.noadd:		ret
m_dataname:	; セーブデータのプレイヤーの名前を変更する//
		cmp	eax, 1
		jb	.addcheck
		; 名前登録
		push	eax
		push	ebx
		mov	ecx, 12
		mov	edi, SavNameLen
		call	name_entry
		pop	eax
		inc	eax
		call	saveupdate
		pop	eax
		ret
.addcheck:	; 追加チェック
		cmp	dword [SavDungeonNum], 1
		jb	.noadd
		mov	eax, 1
.noadd:		ret
m_datacopy:	; セーブデータのコピーをする//
		cmp	eax, 1
		jb	.addcheck
		ret
.addcheck:	; 追加チェック
		mov	eax, 0
		ret
m_datareview:	; セーブデータの最後のフロアのプレイを見る//
		cmp	eax, 1
		jb	.addcheck
		; セーブデータの再現を表示する
		mov	eax, 2	/* 再現後終了 */
		jmp	GameMain
.addcheck:	; 追加チェック
		cmp	dword [SavDungeonNum], 2
		jb	.noadd
		mov	eax, 1
.noadd:		ret
;m_subprograms2: /******************/
m_ranking:	; ランキングを見る
		push	eax
		mov	eax, -1
		mov	edx, -1
		call	cls_2nd
		mov	al, 0
		mov	esi, 2
		mov	ecx, 0xFF8AFFFF
		call	screeneffect
		movzx	edx, byte [printsize]
		mov	eax, VGXSIZE
		inc	edx
		mov	edi, vram_back
		mul	edx
		mov	ecx, eax
		mov	al, 0x8C
		repnz	stosb
		mov	ecx, 4
		mov	edx, 1
		mov	edi, rankcaptionmsg
		call	print
		mov	ebx, 0
		
	
.lop2:		push	ebx
		mov	edx, 60
		mov	ecx, 5
.lop3:		push	edx
		call	showrank
		pop	edx
		inc	ebx
		add	edx, 40
		dec	ecx
		jnz	.lop3
		pop	ebx
		vupd
.loop:		mov	eax, 1
		call	vsync_nodraw
		
		call	getkeybuf
		mov	edx, ebx
		cmp	eax, 0
		jz	.loop
		cmp	eax, MO_LEFT
		je	.ret
		cmp	eax, KY_ENTER
		je	.ret
		cmp	eax, KY_RIGHT
		jne	.notright
		add	ebx, 5
		cmp	ebx, RANKDATA_MAX-5
		jle	.notright
		mov	ebx, RANKDATA_MAX-5
.notright:	cmp	eax, KY_DOWN
		jne	.notdown
		inc	ebx
		cmp	ebx, RANKDATA_MAX-1
		jle	.notdown
		mov	ebx, RANKDATA_MAX-1
.notdown:	cmp	eax, KY_UP
		jne	.notup
		or	ebx, ebx
		jz	.notup
		dec	ebx
.notup:		cmp	eax, KY_LEFT
		jne	.notleft
		sub	ebx, 5
		jnl	.notleft
		mov	ebx, 0
.notleft:	cmp	ebx, edx
		jz	.loop
		jmp	.lop2
.ret:
		mov	al, 0
		mov	esi, 2
		mov	ecx, 0xFFFFBABA
		call	screeneffect
		mov	eax, -1
		mov	edx, -1
		call	cls_2nd
		pop	eax
		ret
showrank:	; 1つのランクを表示
		; in:	ebx	ランク番号
		;	edx	表示位置
		push	eax
		push	ecx
		push	edx
		push	esi
		push	edi
		push	edx
		mov	edx, ebx
		mov	eax, rk_SIZE
		mul	edx
		pop	edx
		mov	edi, rnk_NameLen
		lea	esi, [RankingData + eax]
		mov	ecx, rk_SIZE>>2
		repnz	movsd
		inc	ebx
		cmp	dword [rnk_PlayCnt], 0
		je	.del
		cmp	dword [rnk_NameLen], 12
		jbe	.skp1
		mov	dword [rnk_NameLen], 12
.skp1:		mov	[rnk_Num], ebx
		dec	ebx
		push	edx
		mov	eax, rnk_TotalTime
		mov	edx, 0
		mov	ecx, 60
		div	ecx
		mov	[rnk_Min], eax
		mov	[rnk_Sec], edx
		pop	edx
		mov	ecx, 0
		mov	edi, rankdatasrc
		call	printf
		movzx	eax, byte [printsize]
		mov	edi, rankdatasrc2
		add	edx, eax
		call	printf
.ret:		pop	edi
		pop	esi
		pop	edx
		pop	ecx
		pop	eax
		ret
.del:		jmp	.ret
m_sound:	; サウンドルームに入る
		pusha
		movzx	eax, byte [printsize]
		mov	edx, VGYSIZE
		shr	eax, 1
		mov	edi, nosoundmsg
		sub	edx, eax
		mov	esi, [edi]
		mov	ecx, VGXSIZE
		shl	esi, 3
		push	edi
		movzx	edi, byte [printsize]
		sub	ecx, esi
		shr	edx, 1
		shr	ecx, 1
		call	newwindow
		mov	eax, edi
		pop	edi
		push	eax
		call	print
		mov	eax, 0
		call	vsync
		mov	eax, 90
		call	vsync
		pop	edi
		call	delwindow
		popa
		mov	eax, -1
		ret
m_help:		; 操作説明などを見る
		pusha
.main:		mov	ecx, 48
		mov	edx, 72
		mov	ebx, helpmenusrc
		mov	eax, 1
		call	menu_disp
		
		cmp	eax, 0
		jl	.ext

		mov	eax, 1
		mov	ebx, edx
		mov	ecx, 32
		mov	edx, 44
		call	menu_disp
		jmp	.main
.ext:
		popa
		mov	eax, -1
		ret
m_setpage:	; 文字選択エリアへ文字を転送
		; in:	edx	opt(ページ番号)
		; ページ番号対応リスト
		; 000	ひらがな入力
		; 001	カタカナ入力
		; 002	全角記号入力
		; 003	半角記号入力
		; 004	音読み検索
		; 005	訓読み検索
		; 007	全角記号タイプ選択
		; 008	記号タイプ別入力(1)
		;	…
		; 00F	記号タイプ別入力(8)
		; 010	音読み漢字入力("ア")
		; 011	音読み漢字入力("イ")
		; 	…
		; 03D	音読み漢字入力("ワ")
		; 040	訓読み漢字入力("あ")
		;	…
		; 06D	訓読み漢字入力("ワ")
		; 070	画数別漢字入力(1画)
		;	…
		; 085	画数別漢字入力(21画)
		;	…
		; 090	画数別漢字入力(33画)
		; 
		pusha
		push	dword [name_pagenum]
		mov	dword [name_pageloc], 0
		mov	eax, edx
		push	.iret
		cmp	eax, 0x008
		jb	.rawpage
		cmp	eax, 0x010
		jb	.kigopage
		cmp	eax, 0x040
		jb	.chipage
		cmp	eax, 0x070
		jb	.jpnpage
		cmp	eax, 0x0A0
		jb	.lispage
		ret
.rawpage:	; ひらがな,カタカナ,漢字検索
		cmp	eax, [pageofstable]
		jb	.rawok
		ret
.rawok:		mov	ebx, [pageofstable +4 + eax*4]
		mov	[name_pagedata], ebx
		mov	[name_pagenum], eax
		ret
.kigopage:	; タイプ別記号入力
		ret
.chipage:	; 音読み別漢字入力
		push	eax
		sub	eax, 0x10
		cmp	eax, [kanjijpn]
		jb	.chiok1
		pop	eax
		ret
.chiok1:	cmp	dword [kanjijpn + eax*4 +4], 0
		je	.retx
		mov	ebx, eax
		pop	dword [name_pagenum]
		mov	eax, [kanjichi +4 + ebx*4]
		mov	ecx, [kanjichi +8 + ebx*4]
		mov	edi, kanjichidata
		sub	ecx, eax
		mov	[name_pagedata], edi
.chilop:	call	chitoeax ; 連続コード(EAX)→SJISコード変換(BX)
		mov	[edi], bx
		inc	edi
		inc	eax
		inc	edi
		dec	ecx
		jnz	.chilop
		mov	dword [edi], 0
		ret
.jpnpage:	; 訓読み別漢字入力
		push	eax
		sub	eax, 0x40
		cmp	eax, [kanjijpn]
		jb	.jpnok
.retx:		pop	eax
		ret
.jpnok:		mov	ebx, [kanjijpn +4 +eax*4]
		or	ebx, ebx
		jz	.retx
		pop	dword [name_pagenum]
		mov	[name_pagedata], ebx
		ret
.lispage:	; 画数別漢字入力
		push	eax
		sub	eax, 0x70
		cmp	eax, [kanjilines]
		jb	.lisok
		pop	eax
		ret
.lisok:		mov	ebx, [kanjilines +4 +eax*4]
		or	ebx, ebx
		jz	.retx
		pop	dword [name_pagenum]
		mov	[name_pagedata], ebx
		ret
.iret:		pop	eax
		cmp	eax, [name_pagenum]
		je	.iskp
		mov	[name_pageold], eax
.iskp:		popa
		ret
chitoeax:	; 漢字連続コード→SJISコード
		; in:	eax	漢字連続コード
		; out:	bl,bh	SJISコード(第1,2バイト目)
		push	eax
		mov	bl, 188
		div	bl	; ax / bl = al ... ah
		add	al, 0x81
		add	ah, 0x40
		cmp	al, 0xA0
		jb	.s1
		add	al, 0x40
.s1:		cmp	ah, 0x7F
		jb	.s2
		inc	ah
.s2:		mov	ebx, ebx
		mov	ebx, eax
		pop	eax
		ret
m_setcode:	; コード直接指定
		; in:	eax	opt
		call	int3
		ret
m_kanjilines:	; 漢字画数指定
		ret
menu_select:	; メニュー用カーソル選択/移動専用
		; in:	ecx,edx	左上(=デフォルト位置)(ピクセル単位)
		;	esi,edi	右下(ピクセル単位)
		;	bl,bh	ステップ単位(ピクセル単位)
		;	al	フラグ(b0=1:キャンセル可能)
		;	eah	デフォルト位置(選択肢単位)
		; out:	bl,bh	選択したメニュー
		;	eax	フラグ(b0=1:キャンセルで終了)
		push	ebp
		push	edi
		push	esi
		push	edx
		push	ecx
		push	ebx
		push	eax
		mov	ebp, esp
		mov	dword [mmoveflag], 0
		push	ecx
		push	edx
		; 初期位置の設定
		shr	eax, 16
		push	eax
		mov	ah, byte ds:[ebp + 0x004]
		mul	ah
		cwde
		add	ecx, eax
		pop	eax
		mov	al, byte ds:[ebp + 0x005]
		mul	ah
		cwde
		add	edx, eax
.lop:		; カーソルが移動していたら再描画
		cmp	ecx, [ebp -4]
		jne	.upd
		cmp	edx, [ebp -8]
		jne	.upd
		jmp	.ups
.upd:		; カーソルの消去
		push	ecx
		push	edx
		mov	ecx, [ebp -4]
		mov	edx, [ebp -8]
		mov	edi, menudelete
		call	print
		pop	edx
		pop	ecx
		; 表示更新
		mov	edi, menucursor
		call	print
		mov	[ebp -4], ecx
		mov	[ebp -8], edx
.ups:		mov	eax, 1
		call	vsync_nodraw
		
		; マウス移動
		cmp	dword [mmoveflag], 0
		jz	.skpmos
		mov	dword [mmoveflag], 0
		mov	eax, [newposx]
		cmp	eax, [ebp + 0x010]
		ja	.skpmos
		sub	eax, [ebp + 0x008]
		jb	.skpmos
		push	edx
		push	ebx
		mov	edx, 0
		movzx	ebx, byte ds:[ebp + 0x004]
		div	ebx
		mul	ebx
		pop	ebx
		add	eax, [ebp + 0x008]
		pop	edx
		mov	esi, eax
		mov	eax, [newposy]
		cmp	eax, [ebp + 0x014]
		ja	.skpmos
		sub	eax, [ebp + 0x00C]
		jb	.skpmos
		push	ebx
		mov	edx, 0
		movzx	ebx, byte ds:[ebp + 0x005]
		div	ebx
		mul	ebx
		pop	ebx
		add	eax, [ebp + 0x00C]
		mov	ecx, esi
		mov	edx, eax
		jmp	.skpkey
.skpmos:	; キーボード/マウス操作
		call	getkeybuf
		cmp	eax, 0
		jz	.skpkey
		cmp	eax, AR_LEFT
		jne	.skpleft
		movzx	ebx, byte ds:[ebp + 0x004]
		sub	ecx, ebx
		cmp	ecx, [ebp + 0x008]
		jg	.skpleft
		mov	ecx, [ebp + 0x008]
.skpleft:	cmp	eax, AR_UP
		jne	.skpup
		movzx	ebx, byte ds:[ebp + 0x005]
		sub	edx, ebx
		cmp	edx, [ebp + 0x00C]
		jg	.skpup
		mov	edx, [ebp + 0x00C]
.skpup:		cmp	eax, AR_RIGHT
		jne	.skpright
		movzx	ebx, byte ds:[ebp + 0x004]
		add	edx, ebx
		cmp	edx, [ebp + 0x010]
		jl	.skpright
		sub	edx, ebx
.skpright:	cmp	eax, AR_DOWN
		jne	.skpdown
		movzx	ebx, byte ds:[ebp + 0x005]
		add	edx, ebx
		cmp	edx, [ebp + 0x014]
		jl	.skpdown
		sub	edx, ebx
.skpdown:	cmp	eax, KY_ENTER
		je	.ext
		cmp	eax, KY_CTRL
		je	.can
		cmp	eax, KY_ESC
		je	.can
		cmp	eax, KY_BS
		je	.can
		cmp	eax, MO_LEFT
		je	.mex
		cmp	eax, MO_RIGHT
		je	.can
.skpkey:	jmp	.lop
.mex:		; マウス左クリックは範囲外を無効とする
		; 右クリック(キャンセル)は範囲外でも有効。
		mov	eax, [newposx]
		cmp	eax, [ebp + 0x010]
		ja	.skpkey
		cmp	eax, [ebp + 0x008]
		jb	.skpkey
		mov	eax, [newposy]
		cmp	eax, [ebp + 0x014]
		ja	.skpkey
		cmp	eax, [ebp + 0x00C]
		jb	.skpkey
		jmp	.ext
		; キャンセル
.can:		test	byte ds:[ebp + 0x000], 0x01	; no cancel flag
		jz	.skpkey
		mov	eax, 1
		jmp	.ret
.ext:		mov	eax, 0
.ret:		push	eax
		; 位置情報を選択単位で返す
		mov	eax, edx
		mov	edx, 0
		sub	eax, [ebp + 0x00C]
		movzx	edi, byte ds:[ebp + 0x005]
		div	edi
		mov	bh, al
		mov	eax, ecx
		mov	edx, 0
		sub	eax, [ebp + 0x008]
		movzx	edi, byte ds:[ebp + 0x004]
		div	edi
		mov	bl, al
		pop	eax
		pop	edx
		pop	ecx
		add	esp, 8
		pop	ecx
		pop	edx
		pop	esi
		pop	edi
		pop	ebp
		ret
name_entry:	; 名前変更/設定登録
		; in:	ecx	最大半角数
		;	esi	1行目のメッセージ
		;	edi	文字列
		; 操作方法
		; ・keyboard
		;	カーソルキー	入力文字の選択
		;	ENTER/SPACE	選択・決定
		;	直接入力	非対応
		;	HOME/END	カーソル位置の変更
		;	前行/次行	カーソル位置を左右へ
		;	SHIFT+前行/次行	文字ページ変更
		;	BS/DEL		1文字消去
		;	SHIFT+BS/DEL	全消去
		; ・mouse
		;	移動		入力文字の選択
		;	左クリック	選択/決定
		;	右クリック	1文字消去/キャンセル
		;	中クリック	入力ページを戻す
		;
		;-----------------------------------------------
		; トルネコの大冒険:
		; 		┌────────┐
		;		│ ♪名無しさん │
		;		└────────┘
		;	┌────────────────┐
		;	│ひらがな すすむ もどる 終わり│
		;	│ あ い う え お か き く け こ│
		;	│ さ し す せ そ た ち つ て と│
		;	│ な に ぬ ね の は ひ ふ へ ほ│
		;	│ ま み む め も や   ゆ   よ│
		;	│ ら り る れ ろ わ を ん ゛ ゜│
		;	│ ぁ ぃ ぅ ぇ ぉ ゃ ゅ ょ っ  │
		;	│ 1 2 3 4 5 6 7 8 9 0│
		;	│ + - ? ! / ~ → [ ]  │
		;	└────────────────┘
		; 最上位ライン:
		;	ページ切り替え等のファンクション系
		; その他のライン:
		;	挿入文字選択エリア
		;-----------------------------------------------
		; タクティクスオウガ:
		;  ┌─CHECK ────────────────┐
		;   │!名前を入力してください。	      │
		;   │	名前は8文字まで入力できます。	      │
		;  └────────────────────┘
		;		 _________
		;	 ___	│▼		 │ ___
		;	│←:X││名無しさん蕑  ││Y:→│
		;	  ̄ ̄ ̄	│-		 │  ̄ ̄ ̄
		;		  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
		;	┌MENU─────┐ ┌────┐
		;	│ ひらがな	│ │ はい │
		;	│ カタカナ	│ │ いいえ│
		;	│ 英・数字/記号│ └────┘
		;	│ 漢字	│
		;	│ 入力終了	│
		;	└───────┘
		;			  ┌MENU───┐
		; (漢字サブメニュー):	  │ 音検索 │
		;			  │ 訓検索 │
		;			  │ 画数検索│
		;			  └─────┘
		; (入力中メッセージ):
		;  ┌─CHECK ────────────────┐
		;   │!Y…文字入力バーを左に、 X…右に、  │
		;   │	A…入力、 B…前の画面へ戻る、      │
		;  └────────────────────┘
		; (ひらがな/カタカナ/漢字の音訓順):
		;	┌────────────────┐
		;10	│ あ い う え お か き く け こ △
		;1A	│ さ し す せ そ た ち つ て と │
		;24	│ な に ぬ ね の は ひ ふ へ ほ │
		;2E	│ ま み む め も や ゆ よ(わ を)│
		;38	│ ら り る れ ろ (ん/わ)   (ー)▽
		;42	└────────────────┘
		;	│ ぁ ぃ ぅ ぇ ぉ っ ゃ ゅ ょ(ヴ)│
		;	│ が ぎ ぐ げ ご ざ じ ず ぜ ぞ │
		;	│ だ ぢ づ で ど ば び ぶ べ ぼ │
		;	│ ぱ ぴ ぷ ぺ ぽ           │
		;	└────────────────┘
		; (英数字記号):
		;	┌────────────────┐
		;	│ 0 1 2 3 4 5 6 7 8 9 △
		;	│ A B C D E F G H I J │
		;	│ K L M N O P Q R S T │
		;	│ U V W X Y Z         │
		;	│ a b c d e f g h i j ▽
		;	│ k l m n o p q r s t │
		;	│ u v w x y z         │
		;	│ 、 。 - , . ・ : ; ? ! │
		;	│ _ % ─ ~ … ∞ ※ / 袠 ♪ │
		;	│ ♂ ♀ ☆ 蟵 + - ± × ÷ = │
		;	│ ( ) (○)  ( × ) 「 」 『 』 │
		;	│ ← → ↑ ↓             │
		;	└────────────────┘
		; (漢字)
		; ___	┏━━━━━━━━━━━━━━━━┓ ___
		;│←L│┃ あ				 ┃│R→│
		;  ̄ ̄	┃────────────────┃  ̄ ̄ 
		;	┃ 上 会 充 合 在 当 有 明 空 荒 △
		;	┃ 悪 開 相 間 青 赤 紅 銅 呆 章 ┃
		;	┃ 晶 照 輝 祥 朗 朱 朝 浅 麻 字 ┃
		;	┃ 足 畔 遊 与 辺 従 温 頭 新 厚 ▽
		;	┗━━━━━━━━━━━━━━━━┛
		pusha
		mov	eax, -1
		mov	edx, -1
		call	cls_2nd
		mov	[name_maxlen], ecx
		mov	[name_strofs], edi
		mov	eax, [edi]
		mov	[name_strloc], eax
		; 編集中文字列表示ウィンドウ
		lea	esi, [ecx *8]
		mov	ecx, VGXSIZE
		mov	edi, 16
		sub	ecx, esi
		mov	edx, 56+2
		shr	ecx, 1
		mov	[name_strwidth], esi
		mov	[name_strheight], edi
		mov	[name_strleft], ecx
		mov	[name_strtop], edx
		; メッセージウィンドウ
		mov	ecx, 10
		movzx	edi, byte [printsize]
		mov	edx, 24
		dec	edi
		mov	esi, VGXSIZE - 20
		sub	edx, edi
		shl	edi, 1
		mov	[name_msgleft], ecx
		mov	[name_msgtop], edx
		mov	[name_msgwidth], esi
		mov	[name_msgheight], edi
		; 入力エリア
		mov	esi,(16+4)*11
		mov	ecx, VGXSIZE
		mov	edx, 96
		sub	ecx, esi
		mov	edi, 20*6-4
		shr	ecx, 1
		mov	[name_inpwidth], esi
		mov	[name_inpheight], edi
		mov	[name_inpleft], ecx
		mov	[name_inptop], edx

		; まず、ページ選択メニュー
		call	.strwindow
.main:		mov	eax, 1
		mov	dword [name_1stmsg], name1stmsg
		call	.msgwindow
		call	_inputpagemenu
.answer:	cmp	eax, 0x48
		jl	.retmenu
		cmp	eax, _data
		jnb	.data
		call	eax
		jmp	.pagesel
.retmenu:	; 決定/キャンセルメニュー
		mov	dword [name_1stmsg], nameokmsg1
/*		mov	edi, cnvftemp
		call	printf_conv
		mov	dword [name_1stmsg], edi
		mov	dword [name_2ndmsg], nameokmsg2
*/		mov	eax, m_yesnomenu
		call	.msgwindow
.data:		; サブメニュー
		; 暗く
		push	dword [printcache]
		push	eax
		push	edx
		mov	byte [printcache+1], 7
		mov	eax, 6
		call	_oldmenu
		pop	edx
		pop	ebx
		pop	dword [printcache]
		;mov	eax, [inputpagemenu + 0x004]
		mov	edx, [name_inptop]
		;lea	ecx, [ecx + eax*8 +32]
		mov	ecx, VGXSIZE -16 -20 -48 -16
		mov	eax, 1
		call	menu_disp
		cmp	eax, 0
		jnl	.answer
		cmp	eax, -2
		jne	.main
		inc	eax
		inc	eax
		jmp	.ret
.pagesel:
		; 全体再描画
		mov	dword [name_1stmsg], nameingmsg1
		call	.msgwindow
		call	.strwindow
		mov	ebx, 0
		mov	dword [mmoveflag], 0
		mov	[name_pageloc], ebx
.plopredw:	call	.inpwindow
		vupd
.plopw:		mov	eax, 1
		call	vsync_nodraw

		; マウス移動感知
		cmp	dword [mmoveflag], 0
		je	.pskpmo
		mov	dword [mmoveflag], 0
		; マウス移動先範囲内チェック
		mov	ecx, [newposx]
		mov	edx, [newposy]
		sub	ecx, [name_sleft]
		jl	.pskpmo
		sub	edx, [name_stop]
		jl	.pskpmo
		dec	eax	; mov eax, 0
		push	ecx	; Y軸座標変換
		xchg	eax, edx
		mov	ecx, [name_sdivy]
		div	ecx
		mov	[name_stemp], eax
		pop	eax
		cmp	dl, [printsize]
		jnb	.pskpmo
		; X座標変換
		mov	edx, 0
		cmp	eax, [name_lcenter]
		jb	.pskpl
		cmp	eax, [name_rcenter]
		jb	.pskpmo
		sub	eax, [name_mcenter]
.pskpl:		
		mov	ecx, [name_sdivx]
		div	ecx
		mov	cl, [printsize+1]
		shl	cl, 1
		cmp	dl, cl
		jnb	.pskpmo
		cmp	eax, 10
		mov	ah, [name_stemp]
		jnb	.pskpmo
		cmp	eax, ebx	; cmp ax, bx
		mov	ebx, eax
		jne	.plopredw
.pskpmo:	; キーボード/マウス操作チェック
		mov	edx, ebx
		call	getkeybuf
		cmp	eax, 0
		jz	.pskpky
		cmp	eax, AR_LEFT
		jne	.pskpkl
		sub	bl, 1
		jnl	.pskpkl
		mov	bl, 9
.pskpkl:	cmp	eax, AR_RIGHT
		jne	.pskpkr
		inc	ebx
		cmp	bl, 9
		jle	.pskpkr
		mov	bl, 0
.pskpkr:	cmp	eax, AR_UP
		jne	.pskpku
		cmp	bh, 0
		je	.pchkku
		dec	bh
		jmp	.pskpku
.pchkku:	cmp	dword [name_pageloc], 0
		jle	.pskpku
		dec	dword [name_pageloc]
		jmp	.plopredw
.pskpku:	cmp	eax, AR_DOWN
		jne	.pskpkd
		inc	bh
		cmp	bh, [name_sheight]
		jl	.pskpkd
		dec	bh
		test	byte [name_pageend], 1
		jnz	.pskpkd
		inc	dword [name_pageloc]
		jmp	.plopredw
.pskpkd:	cmp	eax, KY_ENTER
		je	.pext
		cmp	eax, KY_CTRL
		je	.pcan
		cmp	eax, KY_ESC
		je	.ret
		cmp	eax, KY_BS	/* BSキーは1文字削除に利用 */
		je	.delchr
		cmp	eax, KY_DEL
		je	.delchr
		cmp	eax, KY_HOME
		je	.pleft
		cmp	eax, KY_END
		je	.pright
		cmp	eax, KY_PAGEUP
		je	.ppup
		cmp	eax, KY_PAGEDOWN
		je	.ppdown
		cmp	eax, MO_LEFT
		je	.pmex
		cmp	eax, MO_RIGHT
		je	.pcan
		cmp	eax, 0x80
		jb	.addchr
.pskpky:	cmp	ebx, edx
		je	.plopw
		jmp	.plopredw
.addchr:	call	addchar
		call	.strwindow
		jmp	.plopredw
.delchr:	call	delchar
		call	.strwindow
		jmp	.plopredw
.pleft:		cmp	dword [name_strloc], 0
		jz	.pskpky
		dec	dword [name_strloc]
		call	.strwindow
		jmp	.pskpky
.pright:	mov	eax, [name_strloc]
		cmp	eax, [name_maxlen]
		jnb	.pskpky
		inc	dword [name_strloc]
		call	.strwindow
		jmp	.pskpky
.ppup:		cmp	KEY(KY_SHIFT), 0
		jnz	.pprev
		mov	eax, [name_sheight]
		dec	eax
		sub	[name_pageloc], eax
		jnl	.plopredw
		add	[name_pageloc], eax
		jmp	.pskpky
.ppdown:	cmp	KEY(KY_SHIFT), 0
		jnz	.pnext
		test	byte [name_pageend], 1
		jnz	.pskpky
		mov	eax, [name_sheight]
		dec	eax
		add	dword [name_pageloc], eax
		jmp	.plopredw
.pprev:		push	dword [name_pageold]
		mov	edx, [name_pagenum]
		dec	edx
		call	m_setpage
		pop	dword [name_pageold]
		jmp	.plopredw
.pnext:		push	dword [name_pageold]
		mov	edx, [name_pagenum]
		inc	edx
		call	m_setpage
		pop	dword [name_pageold]
		jmp	.plopredw
.pmex:		; 左クリックは範囲外を無効とする
		; ただし選択エリア内をクリックした場合は文字の上でなくとも
		; カーソルの位置の文字を入力したことにする(なる)。
		; 右クリック(キャンセル)は範囲外でも有効。
		mov	eax, [newposy]
		sub	eax, [name_inptop]
		jb	.pskm1
		cmp	eax, [name_inpheight]
		jnb	.pskm1
		mov	eax, [newposx]
		sub	eax, [name_inpleft]
		jb	.pskm1
		cmp	eax, [name_inpwidth]
		jnb	.pskm1
		jmp	.pext
.pskm1:		mov	eax, [newposy]
		sub	eax, [name_strtop]
		jb	.pskm2
		cmp	eax, [name_strheight]
		jnb	.pskm2
		mov	eax, [newposx]
		sub	eax, [name_strleft]
		jb	.pskm2
		sar	eax, 3	; ÷8
		cmp	eax, [name_maxlen]
		ja	.pskm2
		mov	[name_strloc], eax
		call	.strwindow
		jmp	.plopredw
.pskm2:		jmp	.pskpky
.pext:		; 決定ボタン
		; (1文字入力または消す)
		mov	eax, [name_pagenum]
		cmp	eax, 4
		je	.pindex_chi
		cmp	eax, 5
		je	.pindex_jpn
		cmp	eax, 6
		je	.pindex_lis
		
		; 入力文字選択後
		push	ebx
		mov	eax, [name_cache]
		call	addchar
		call	.strwindow
		pop	ebx
.pic_r:		jmp	.plopredw

.pindex_chi:	; 漢字音読み選択
		mov	al, bh
		mov	ah, 10
		mul	ah
		add	al, bl
		adc	ah, 0
		; ページ変更
		cwde
		cmp	eax, [kanjijpn]
		jnb	.pic_r
		cmp	dword [kanjijpn+4+eax*4], 0
		jz	.pic_r
		lea	edx, [eax +0x10]
		call	m_setpage
		jmp	.plopredw
		
.pindex_jpn:	; 漢字訓読み選択
		mov	al, bh
		mov	ah, 10
		mul	ah
		add	al, bl
		adc	ah, 0
		cwde
		cmp	eax, [kanjijpn]
		jnb	.pic_r
		cmp	dword [kanjijpn+4+eax*4], 0
		jz	.pic_r
		lea	edx, [eax +0x40]
		call	m_setpage
		jmp	.plopredw
.pindex_lis:	; 画数選択
		cmp	dword [name_cache], 0
		je	.pskpky
		mov	al, bh
		mov	ah, 10
		mul	ah
		add	al, bl
		adc	bh, 0
		cwde
		lea	edx, [eax +0x70]
		call	m_setpage
		jmp	.plopredw
		
.pcan:		; キャンセルボタン
		call	.delwindow
		mov	eax, [name_pagenum]
		cmp	eax, 0x08
		jb	.main
		mov	edx, [name_pageold]
		call	m_setpage
		jmp	.plopredw
.ret:		mov	eax, -1
		mov	edx, -1
		call	cls_2nd
		popa
		ret
.msgwindow:	; メッセージの再表示
		pusha
		mov	ecx, [name_msgleft]
		mov	edx, [name_msgtop]
		mov	esi, [name_msgwidth]
		mov	edi, [name_msgheight]
		call	newwindow
		movzx	eax, byte [printsize]
		dec	edx
		push	eax
		mov	edi, [name_1stmsg]
		call	printf
		pop	eax
		add	edx, eax
		call	printf
		popa
		ret
.strwindow:	; 編集中の文字列の再表示
		; in:	ecx	編集位置
		pusha
		mov	ecx, [name_strleft]
		mov	edx, [name_strtop]
		mov	esi, [name_strwidth]
		mov	edi, [name_strheight]
		call	newwindow
		push	dword [printbase]
		push	ecx
		push	edx
		mov	ebx, [name_strloc]
		lea	ecx, [ecx + ebx*8]
		add	edx, 8
		mov	edi, undercursor
		call	print
		pop	edx
		pop	ecx
		mov	dword [printbase], vram_back
		mov	edi, [name_strofs]
		call	print
		push	dword [printcache]
		mov	dword [printcache], 0xFF000F84
		mov	edi, nameleftmsg
		mov	ecx, [name_strleft]
		mov	eax, [edi]
		sub	ecx, 12
		shl	eax, 3
		sub	edx, 2
		sub	ecx, eax
		call	print
		mov	ecx, [name_strleft]
		mov	edi, namerightmsg
		add	ecx, [name_strwidth]
		add	ecx, 11
		call	print
		pop	dword [printcache]
		pop	dword [printbase]
		/* 編集中文字列ウィンドウの横にガイドを置かなきゃ! */
		/* (Home:←) □ (→:End) */
		popa
		ret
.delwindow:	; 入力エリアの消去
		pusha
		mov	ecx, [name_inpleft]
		mov	edx, [name_inptop]
		mov	esi, [name_inpwidth]
		mov	edi, [name_inpheight]
		call	delwindow
		popa
		ret
.inpwindow:	; 入力エリアの再表示
		; in:	bl,bh	カーソル位置
		;	※キャンセルでのみ入力を終了できるため、
		;	  一部の入力デバイスでは終了できない可能性がある。
		/* ページが長い場合、ウィンドウの右に矢印ボタンを設置してページガイドを置かないと! */
		/* "△▽"でいいかなぁ。 漢字入力の時はさらに、読み仮名/画数の移動ができないと! */
		push	ebx
		pusha
		mov	ebp, esp
		; エリア全体
		mov	ecx, [name_inpleft]
		mov	edx, [name_inptop]
		mov	esi, [name_inpwidth]
		mov	edi, [name_inpheight]
		call	newwindow
		; ページ表示&カーソルの位置の文字をキャッシュへ
		push	ecx
		push	edx
		movzx	ecx, byte [printsize]
		mov	edx, 0
		add	ecx, 4
		lea	eax, [edi - 16]
		mov	[name_sdivy], ecx
		div	ecx
		mov	ecx, edx
		mov	[name_sheight], eax
		pop	edx
		shr	ecx, 1
		add	edx, ecx
		mov	ebx, 10
		pop	ecx
		;mov	[name_swidth], ebx
		mov	bh, al
		movzx	eax, byte [printsize]
		mov	esi, [name_pagedata]
		push	eax
		mov	eax, [name_pageloc]
		mov	dword [name_sdivx], 20
		lea	eax, [eax*5]
		add	ecx, 4
		shl	eax, 2
		mov	edi, cnvftemp
		add	esi, eax
		pop	eax
		add	edx, 16
		add	eax, 4
		mov	[name_stop], edx
		mov	[name_sleft], ecx
		push	eax
		mov	eax, 100
		mov	dword [name_mcenter], 16
		mov	[name_lcenter], eax
		add	eax, [name_mcenter]
		mov	[name_rcenter], eax
		pop	eax
.lopy:		push	ecx
		push	eax
		push	ebx
.lopx:		; 半角/全角を認識する
		movzx	eax, word [esi]
		inc	esi
		mov	[edi+4], eax
		inc	esi
		or	eax, eax
		jnz	.skpd
		dec	esi
		dec	esi
.skpd:		mov	byte [edi], 1
		cmp	ah, 0x40
		jb	.ok
		mov	byte [edi], 2
.ok:		; カーソル位置判定
		cmp	byte ds:[ebp + 0x11], 0
		jnz	.skp
		cmp	byte ds:[ebp + 0x10], 0
		jne	.skpx
		; 背景色を変更して描画
		mov	[name_cache], eax
		push	dword [printcache]
		mov	byte [printcache], 0x03
		xor	word [printcache+1], 0x0F0F
		call	print
		pop	dword [printcache]
		dec	byte ds:[ebp + 0x10]
		jmp	.net
.skpx:		dec	byte ds:[ebp + 0x10]
		; 通常の描画
.skp:		call	print
.net:		add	ecx, [name_sdivx]
		; 中心の空きエリアを作る
		cmp	bl, 6
		jne	.askp
		add	ecx, [name_mcenter]
.askp:	/**/	dec	bl
		jnz	.lopx
		pop	ebx
		pop	eax
		pop	ecx
		dec	byte ds:[ebp + 0x11]
		add	edx, eax
		dec	bh
		jnz	.lopy
		cmp	word [esi], 0
		mov	byte [name_pageend], 0
		jnz	.inpret
		mov	byte [name_pageend], 1
.inpret:	popa
		pop	ebx
		ret
_inputpagemenu:	; ページメニューの表示
		mov	ecx, [name_inpleft]
		mov	edx, [name_inptop]
		mov	ebx, inputpagemenu
		call	menu_disp
		ret
_oldmenu:	; 最後のメニューを再表示
		or	eax, [menu_oldflag]
		mov	ebx, [menu_oldmenu]
		mov	ecx, [menu_oldleft]
		mov	edx, [menu_oldtop]
		call	menu_disp
		ret
addchar:	; 1文字挿入
		; in:	eax	SJISコード(AL[,AH])
		;	name_strloc	挿入位置
		cmp	ah, 0x40
		jb	.ac_x
		call	.ac_x
		mov	al, ah
.ac_x:		push	ebx
		push	ecx
		mov	ebx, [name_strofs]
		mov	ecx, [name_strloc]
		cmp	ecx, [name_maxlen]
		jb	.ac_s
		mov	ecx, [name_maxlen]
		dec	ecx
.ac_s:		
.ac_l:		xchg	al, [ebx +4 + ecx]
		inc	ecx
		cmp	ecx, [name_maxlen]
		jb	.ac_l
		inc	dword [ebx]
		cmp	[ebx], ecx
		jbe	.ac_m
		mov	[ebx], ecx
.ac_m:		inc	dword [name_strloc]
		cmp	[name_strloc], ecx
		jbe	.ac_o
		dec	dword [name_strloc]
.ac_o:		pop	ecx
		pop	ebx
		ret
delchar:	; 1文字削除(2バイト文字非対応、文字化けの可能性あり)
		; in:	eax	=8:BS,<>8:DEL
		;	name_strloc	カーソル
		push	eax
		push	ebx
		cmp	al, KY_BS
		jne	.dc_d
		; BSキー(前方1文字削除)
		cmp	dword [name_strloc], 0
		je	.dc_d
		dec	dword [name_strloc]
.dc_d:		; DELキー(後方(カーソル位置)1文字削除)
		mov	ebx, [name_strofs]
		mov	ecx, [name_maxlen]
		mov	al, 0
.dc_l:		dec	ecx
		xchg	al, [ebx +4 + ecx]
		cmp	ecx, [name_strloc]
		ja	.dc_l
		mov	ecx, [name_strloc]
		cmp	[ebx], ecx
		jbe	.dc_o
		sub	dword [ebx], 1
		jnb	.dc_o
		inc	dword [ebx]
.dc_o:		
		pop	ebx
		pop	eax
		ret
/*/
print_vramset:	; 文字列表示先番号変更(カーソル表示用)
		; in:	eax	番号
		;	=0:	vram_back
		;	=1:	vram_fore
		test	eax, 1
		jz	.back
		mov	dword [printbase], vram_fore
		ret
.back:		mov	dword [printbase], vran_back
		ret
/*/
valueedit:	; 最大32bit数値編集/入力
		; in: 	reserved
		ret
		
screen_on:	; 特殊描画処理系の使用開始
		mov	byte [screen_mode], 0xFF
		mov	eax, 0xFFFFFFFF
		mov	edx, 0xFFFFFFFF
		call	cls_2nd
		mov	eax, 0x00000000
		call	cls
		mov	eax, [propttemp]
		mov	ebx, 0x84
		mov	ecx, 0x0F
		mov	edx, 0x00
		shl	eax, 1
		mov	esi, VGXSIZE
		mov	edi, vram_fore
		call	print_mode
		mov	eax, 0x00000000
		mov	[puttern_offset], eax
		mov	[puttern_offset+4], eax
		mov	dword [puttern_offset+0], (GPXSIZE<<3)-16
		mov	dword [puttern_offset+4], (GPYSIZE<<3)-16
		
		ret
screen_off:	; 特殊描画処理系を終了する
		mov	dword [screen_mode], 0
		mov	eax, 0011b
		mov	ebx, 0x00
		mov	ecx, 0x0F
		mov	edx, 0x00
		mov	esi, [ScreenSize]
		mov	edi, vram_screen
		call	print_mode
		ret
setwindowcolor:	; 半透明ウィンドウの色設定
		; in:	eax	ウィンドウ内の色
		;	ecx	ウィンドウ枠の色
		;	edx	ウィンドウ枠の外側(縁取り?)の色
		;	ebx	消去用の色
		mov	[windowcache+0], bl
		mov	[windowcache+1], cl
		mov	[windowcache+2], al
		mov	[windowcache+3], dl
		ret
newwindow:	; 半透明ウィンドウの描画(画面外非対応)
		; in:	ecx,edx	描画領域の左上の点の座標(枠は含まれない)
		;	esi,edi	領域のサイズ(内側のみ)
		;	枠のサイズは8x8でecx,edxの外側に描画される。その場合も画面外になることは許されない.
		push	eax
		push	ecx
		push	ebx
		push	esi
		push	edi
		push	edx
		; 左上の枠の描画
		sub	ecx, 8
		sub	edx, 8
		mov	eax, VGXSIZE
		mov	ebx, esi
		mul	edx
		mov	edx, edi
		lea	edi, [vram_back + eax + ecx]
		mov	esi, windowptn
		push	edi
		push	ebx
		push	edi
		call	drawwinptn
		; 上の枠の描画
.lop1:		sub	ebx, 8
		jb	.ext1
		add	edi, 8
		push	esi
		call	drawwinptn
		pop	esi
		jmp	.lop1
.ext1:		; 余りがある場合は描画
		and	ebx, 7
		jz	.end1
		add	edi, ebx
		push	esi
		call	drawwinptn
		pop	esi
.end1:		add	edi, 8
		add	esi, 32
		; 右上の枠の描画
		call	drawwinptn
		pop	edi
		pop	ebx
		add	edi, VGXSIZE*8
		; 左右の枠の描画
		push	edx
.lop2:		sub	edx, 8
		jnb	.exe2
		neg	edx
		and	edx, 7
		jz	.ext2
		mov	eax, VGXSIZE
		mul	edx	; edx=0
		sub	edi, eax
.exe2:		push	esi
		call	drawwinptn
		push	edi
		lea	edi, [edi + ebx +8]
		call	drawwinptn
		pop	edi
		pop	esi
		add	edi, VGXSIZE*8
		jmp	.lop2
.ext2:		pop	edx
		; 左下の枠の描画
		add	esi, 64
		call	drawwinptn
		push	ebx
		; 下の枠の描画
.lop3:		sub	ebx, 8
		jb	.ext3
		add	edi, 8
		push	esi
		call	drawwinptn
		pop	esi
		jmp	.lop3
.ext3:		; 余りがある場合は描画
		and	ebx, 7
		jz	.end3
		add	edi, ebx
		push	esi
		call	drawwinptn
		pop	esi
.end3:		add	edi, 8
		add	esi, 32
		; 右下の枠の描画
		call	drawwinptn
		pop	ebx
		pop	edi
		; 領域内の描画
		
		push	edi
		push	edx
		add	edi, VGXSIZE*8 + 8
		mov	al, [windowcache+2]
.lopy:		push	edi
		mov	ecx, ebx
		repnz	stosb
		pop	edi
		add	edi, VGXSIZE
		dec	edx
		jnz	.lopy
		pop	edx
		pop	edi
		mov	al, 0xFF
		sub	edi, vram_back
		add	edi, vram_fore
	/*	add	edi, VGXSIZE*(VGYSIZE)	*/
		;push	ebx
		add	ebx, 16
		add	edx, 16
.fill:		push	edi
		mov	ecx, ebx
		repnz	stosb
		pop	edi
		add	edi, VGXSIZE
		dec	edx
		jnz	.fill
		pop	edx
		pop	edi
		pop	esi
		pop	ebx
		pop	ecx
		pop	eax
		ret
delwindow:	; 半透明ウィンドウの消去
		; in:	ecx,edx	描画領域の左上の点の座標(枠は除く)
		;	esi,edi	領域のサイズ(枠は除く)
		push	eax
		push	ecx
		push	edx
		push	esi
		push	edi
		sub	ecx, 8
		sub	edx, 8
		mov	eax, VGXSIZE
		mul	edx
		lea	edx, [edi +16]
		add	esi, 16
		lea	edi, [vram_back + eax + ecx]
		
		
		mov	al, [windowcache]
		push	edx
		push	edi
.lopy:		push	edi
		mov	ecx, esi
		repnz	stosb
		pop	edi
		add	edi, VGXSIZE
		dec	edx
		jnz	.lopy
		pop	edi
		pop	edx
		sub	edi, vram_back
		add	edi, vram_fore
	//	add	edi, VGXSIZE*VGYSIZE*2
.lop2:		push	edi
		mov	ecx, esi
		repnz	stosb
		pop	edi
		add	edi, VGXSIZE
		dec	edx
		jnz	.lop2
		pop	edi
		pop	esi
		pop	edx
		pop	ecx
		pop	eax
		vupd
		ret
drawwinptn:	; 指定した場所に指定したパターンデータを描画する
		; in:	esi	コピー元
		;	edi	コピー先
		push	eax
		push	ecx
		push	edx
		push	ebx
		push	edi
		mov	ecx, 0x0804
		mov	ebx, windowcache
.lopy:		push	ecx
		mov	edx, [esi]
		push	edi
.lopx:		rol	edx, 4
		mov	eax, edx
		and	eax, 0x0F
		rol	edx, 4
		xlatb
		mov	ah, al
		mov	al, dl
		and	al, 0x0F
		xlatb
		xchg	al, ah
		mov	[edi], ax
		inc	edi
		inc	edi
		dec	cl
		jnz	.lopx
		add	esi, 4
		pop	edi
		pop	ecx
		add	edi, VGXSIZE
		dec	ch
		jnz	.lopy
		pop	edi
		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		vupd
		ret
newsegement:	; 一部のバッファをDLL実行用セレクタでアクセス可能にする
		; in:	edx	マップするデータのポインタ
		;	ecx	マップサイズ
		;	eax	マップされるセレクタ
		;	64KBを超える場合は4KBのページ単位になります。
		;	その際のサイズは4KB単位に切り上げられます。
		push	eax
		push	ecx
		push	ebx
		and	eax, -8
		mov	ebx, us_newselector
		mov	[ebx + 0x008], eax
		mov	eax, 0x40FA
		cmp	ecx, 0x10000
		jbe	.ok
		add	ecx, 0x00FFF
		or	eax, 0x8000
.ok:		dec	ecx
		mov	[ebx + 0x00C], eax /* ar */
		mov	[ebx + 0x010], ecx /* limit */
		mov	[ebx + 0x014], edx /* data source */
		call	0xC7:0
		pop	ebx
		pop	ecx
		pop	eax
		ret
loadedfont:	; OSASK拡張フォントの準備完了
		; in:	eax	エラーコード
		;	edx	スロット
		mov	[us_print + 0x1C], edx
		and	byte [us_print + 0x05], 0xCF
		mov	dword [us_print + 0x28], sjistemp
		mov	ebx, _loadfont2
		lea	eax, [edx + 0x10]
		mov	[ebx + 0x20], edx
		lea	edx, [eax + 0x40]
		mov	[ebx + 0x3C], eax
		mov	[ebx + 0x58], edx
		call	0xC7:0
		ret
addjob:		; シグナル待ちバックグラウンド処理登録
		; in:	eax	呼び出し時の引数2(スロット)
		;	edx	呼び出し先
		; out:	eax	基本シグナル番号
		;	edx	BG処理番号
		; 4つのBG登録/処理バッファがあり、並列実行できる。
		; そのバッファがすべて埋まっている場合は、
		; バッファが空くまで待つ。
		; 登録すると結果報告シグナルが来た時に処理
		; ルーチンを自動的に呼び出すことができます。
		; 呼び出しはハンドラの再入不可の状態で行われます。
		; エラーコードは引数として引数2とともにレジスタ
		; 経由で渡されます。
		; また、バッファは自動的に開放されます。
		; 呼び出し先を無効にしたい場合はedxを0にします。
		; その場合は手動で"ReturnSignal+BG処理番号"を
		; 参照しないといけません。bit4が1になるとb3-0に
		; エラーコードが入ります。
		; エラーコードを受け取ったらbit5-4を0にして下さい。
		; 自動的に呼び出さない場合てもエラー通知領域を
		; 使用するためBG登録バッファを消費します。
		; ※1つのファイル準備中はオープンできないなど
		;   OS側で対応できない場合があります。
		; 確認)test	byte [ReturnSignal + edx], 0x10
		push	ecx
		; 空きバッファの検索
.lop2:		mov	ecx, 0
.lop1:		test	byte [ReturnSignal + ecx], 0x30
		jz	.ok
		inc	ecx
		cmp	ecx, 4
		jb	.lop1
		; 空きバッファが無い
		call	sleep
		jmp	.lop2
.ok:		; BG処理登録
		mov	byte [ReturnSignal + ecx], 0x10
		mov	[RetSigJump + ecx*4], edx
		mov	[RetSigSlot + ecx*4], eax
		mov	eax, ecx
		inc	dword [addjobings]
		shl	eax, 4
		mov	edx, ecx
		add	eax, SIG_NOERROR
		pop	ecx
		ret
fileclose:	; ファイルを閉じる(バッファをクリアする)
		; in:	eax	ファイルスロット
		;		オープン準備中に閉じると
		;		ハングする可能性があります。
		push	eax
		push	ecx
		push	edx
		push	ebx
		mov	ecx, 0
.lop:		cmp	[mmt_fileid + ecx*4], eax
		je	.ok
		inc	ecx
		cmp	ecx, 4
		jb	.lop
		jmp	.ret
.sleep:		call	sleep
.ok:		; エラー情報(正常オープンなのか)を確認
		cmp	byte [mmt_errcode + ecx*4], 0x10
		je	.sleep
		cmp	byte [mmt_errcode + ecx*4], 0
		jne	.err
		; マッピングを解除する
		push	eax
		mov	ebx, _fileunmapper
		mov	edx, [mmt_limit + ecx*4]
		mov	eax, [mmt_base + ecx*4]
		mov	[ebx + 0x008], edx
		mov	[ebx + 0x00C], eax
		mov	[ebx + 0x010], ds
		call	0xC7:0
		pop	eax
		; 一応スロットを最初期化する
		push	byte 0
		push	eax
		push	byte 0x0C
		push	0xA0
		mov	ebx, esp
		call	0xC7:0
		add	esp, 16
.err:		; バッファを未使用状態にする
		mov	eax, 0
		mov	[mmt_fileid + ecx*4], eax
		mov	[mmt_fsize + ecx*4], eax
		mov	[mmt_errcode + ecx*4], eax
		mov	[mmt_writable + ecx*4], eax
.ret:		pop	ebx
		pop	edx
		pop	ecx
		pop	eax
		ret
savedataopen:	; セーブデータの読み込み
		; in:	eax	セーブデータ番号(0:index,1~3:セーブデータ1~3)
		pusha
		push	eax
		mov	ebx, 0x0005
		; ファイル名処理
		cmp	eax, 0
		jne	.skp
		sub	al, 0x10	/* "0"を" "へ変更する */
		or	ebx, 0x0010
.skp:		add	al, "0"
		mov	edx, SaveFileName
		mov	esi, 0
		mov	edi, cs:[0x10]
		mov	[edx +4], al	/* ファイル名の5文字目 */
		; ファイルオープン
		mov	eax, FILE_SLOT
		call	filelocalopen
		; 完了待ち
.sleep:		call	sleep
		cmp	dword [mmt_errcode], 0x10
		je	.sleep
		pop	eax
		mov	esi, cs:[0x10]
		mov	ecx, [mmt_fsize]
		cmp	eax, 0
		push	.close
		jz	.upskp
		mov	[nowsavenumber], eax
.upskp:		mov	eax, [mmt_errcode]
		je	.indexdata
		; セーブデータを内部バッファへ読み込み
		mov	dword [save_read], 0
		mov	dword [save_write], 0
		or	eax, eax
		jnz	.nosave
		or	ecx, ecx
		jz	.nosave
		
		cmp	ecx, SaveDataSize
		jbe	.s_ok
		mov	ecx, SaveDataSize
.s_ok:		mov	edi, SaveDataBegin
		add	ecx, 3
		
		shr	ecx, 2
		repnz	movsd
		ret
.nosave:	; セーブデータエリアをクリア
		mov	ecx, SaveDataSize
		mov	edi, SaveDataBegin
		add	ecx, 3
		
		shr	ecx, 2
		mov	eax, 0
		repnz	stosd
		ret
.indexdata:	; アプリデータを内部バッファへ読み込み
		or	eax, eax
		jnz	.indexret
		or	ecx, ecx
		jz	.indexret
		
		cmp	ecx, IndexDataSize
		jbe	.i_ok
		mov	ecx, IndexDataSize
.i_ok:		mov	edi, IndexDataBegin
		add	ecx, 3
		
		shr	ecx, 2
		repnz	movsd
.indexret:
		ret
.close:		; クローズ処理
		; (何もしない。手抜き。(^^;)
		popa
		ret
saveupdate:	; セーブデータファイルを更新する
		; in:	eax	セーブデータ番号
		pusha
		push	eax
		mov	ebx, 0x0007
		; ファイル名処理
		cmp	eax, 0
		jne	.skp
		sub	al, 0x10
.skp:		or	ebx, 0x0010
		add	al, "0"
		mov	edx, SaveFileName
		mov	esi, 0
		mov	edi, cs:[0x10]
		mov	[edx +4], al	/* ファイル名の5文字目 */
		; ファイルオープン
		mov	eax, FILE_SLOT
		call	filelocalopen
		; 完了待ち
.sleep:		call	sleep
		cmp	dword [mmt_errcode], 0x10 /*本来はmmtの配列番号を確認するべき */
		je	.sleep
		mov	eax, [mmt_errcode]
		cmp	eax, 0
		pop	eax
		jne	.writeerr
		; データサイズを指定する
		mov	edi, cs:[0x10]
		mov	ecx, [mmt_fsize]
		cmp	eax, 0
		push	.write
		je	.indexdata
		; セーブデータサイズ
		; 圧縮や暗号化処理した後のサイズを入れるところだけど、
		; テスト中のため圧縮や暗号化、切り詰めなどはしない。
		mov	ecx, SaveDataSize
		mov	esi, SaveDataBegin
		ret
.indexdata:	; アプリデータサイズ
		
		mov	ecx, IndexDataSize
		mov	esi, IndexDataBegin
		ret
.writeerr:	; ファイル作成エラー
		mov	ebp, 0x55818001
		int	3
.write:		; ファイルサイズを変更
		cmp	ecx, [mmt_fsize]
		je	.sizeskip
		mov	eax, FILE_SLOT
		call	fileresize
		;mov	ebp, 0x55818002
		;int	3
.sizeskip:	; データの書き出し
		add	ecx, 3
		
		shr	ecx, 2
		repnz	movsd
		; クローズ処理
		; (何もしない。手抜き。(^^;)
		popa
		ret
saveindexupdate: ; 内部セーブデータ情報と選択メニューの更新
		pusha
		; セーブデータ選択メニューの初期化
		mov	ecx, 0
		mov	ebx, savedatamenu
		call	menu_clear
		; savedatatempの内容:
		; 記録番号,名前,回数,時間(h,m,s)
		; フロア,ダンジョン名,ダンジョンサイズ(x,y)
		mov	dword [savedatatemp+0x004], SavNameLen; プレイヤー名
		mov	eax, 0
		mov	edx, 0
		mov	ecx, 0
		mov	ebx, savedatamenu
.lop:		inc	eax
		call	savedataopen
		mov	dword [savedatatemp+0x000], eax
		push	eax
		push	ecx
		mov	eax, [SavPlayCount]
		push	edx
		mov	[savedatatemp+0x008], eax
		mov	eax, [SavToTime]
		mov	edx, 0
		mov	ecx, 60
		div	ecx
		mov	[savedatatemp+0x014], edx
		mov	edx, 0
		div	ecx
		mov	[savedatatemp+0x00C], eax
		mov	[savedatatemp+0x010], edx
		mov	eax, [SavFloor]
		inc	eax
		pop	edx
		mov	[savedatatemp+0x018], eax
		mov	eax, [SavDungeonNum]
		pop	ecx
		mov	dword [savedatatemp+0x01C], eax; ダンジョン番号
		cmp	eax, 1
		jb	.nosave
		mov	esi, savedatamenusrc
		jmp	.yesave
.nosave:	mov	esi, savedatanosrc
.yesave:	mov	edi, cnvftemp
		call	printf_conv
		call	menu_additem
		call	printf_conv
		call	menu_additem
		call	printf_conv
		call	menu_additem
		pop	eax
		cmp	eax, 3
		jb	.lop
		popa
		ret
fileresize:	; ファイルサイズ変更(変更完了を待つ)
		; in:	eax	ファイルスロット
		;	ecx	変更後ファイルサイズ
		push	ebx
		push	eax
		push	edx
		; ハンドル検索
		mov	edx, 0
.lop:		cmp	[mmt_fileid + edx*4], eax
		je	.ext
		inc	edx
		cmp	edx, 4
		jb	.lop
		; 見つからないことは無い…はず
		int	3
.ext:		; マッピングを解除する
		push	eax
		mov	ebx, _fileunmapper
		mov	eax, [mmt_limit + edx*4]
		mov	[ebx + 0x008], eax
		mov	eax, [mmt_base + edx*4]
		mov	[ebx + 0x00C], eax
		mov	[ebx + 0x010], ds
		call	0xC7:0
		pop	eax
		; 変更準備
		mov	ebx, _fileresize
		push	eax
		push	ecx
		push	edx
		mov	[ebx + 0x008], eax
		mov	[ebx + 0x00C], ecx
		mov	edx, .fileresized
		call	addjob
		mov	[ebx + 0x014], eax
		push	ebx
		call	0xC7:0
		pop	ebx
		; 変更完了待ち
.sleep:		call	sleep
		cmp	dword [ebx + 0x014], 0
		jne	.sleep
		pop	edx
		pop	ecx
		pop	eax
		mov	[mmt_fsize + edx*4], ecx
		; マッピングを元に戻す
		mov	ebx, _filesetmapper
		mov	[ebx + 0x08], eax
		mov	eax, [mmt_limit + edx*4]
		mov	[ebx + 0x0C], eax
		mov	eax, [mmt_base + edx*4]
		mov	[ebx + 0x10], eax
		mov	eax, [mmt_writable + edx*4]
		mov	[ebx + 0x18], eax
		call	0xC7:0
		
		pop	edx
		pop	eax
		pop	ebx
		ret
.fileresized:	; ファイルサイズ変更完了の割り込み
		; in:	eax	エラーコード
		;	edx	スロット
		/* このリサイズ処理は同時使用を検出できない */
		cmp	eax, 0
		jne	.resizerr
		mov	dword [_fileresize + 0x014], 0
		ret
.resizerr:	mov	ebp, 0x55818000
		int	3
		
filelocalopen:	; アプリ関連ファイル準備(OS側で読み込み?)
		; in:	edx	ファイル名(ASCIIZ)
		;	eax	ファイルスロット
		;	edi	マッピングオフセット
		;	ebx	b3-b0:属性(R/RW),b4=1:ファイルが見つからない場合に作成する
		push	eax
		push	ecx
		push	edx
		push	ebx
		push	eax
		; ファイル名をクリア
		mov	ebx, 12
		mov	al, " "
.clr:		mov	[_filename + ebx-1], al
		dec	ebx
		jnz	.clr
		; ファイル名をセット
.lop:		mov	al, [edx]
		inc	edx
		cmp	al, 0
		je	.fend
		cmp	al, "."
		jne	.fext
		mov	ebx, 8
.fext:		mov	[ebx + _filename], al
		inc	ebx
		jmp	.lop
.fend:		pop	eax
		pop	ebx
		; ハンドルの初期化
		; 空きハンドルの検索
		mov	ecx, 0
.lops:		cmp	[mmt_fileid + ecx*4], eax
		je	.exts
		cmp	dword [mmt_fileid + ecx*4], 0
		je	.exts
		inc	ecx
		cmp	ecx, 4
		jb	.lops
		jmp	.ret
.exts:		; ハンドル確保(初期化)
		push	ebx
		and	bl, 0x0F
		mov	[mmt_fileid + ecx*4], eax
		mov	[mmt_base + ecx*4], edi
		mov	dword [mmt_limit + ecx*4], 260*1024
		mov	dword [mmt_fsize + ecx*4], 0
		mov	[mmt_writable + ecx*4], bl
		mov	dword [mmt_errcode + ecx*4], 0x10	; オープン準備中
		pop	ebx
		add	edi, [mmt_limit + ecx*4]
		mov	byte [_filelocalopen + 0x10], 0
		test	ebx, 0x10
		jz	.skpm
		mov	byte [_filelocalopen + 0x10], 1
.skpm:		; BG処理登録
		push	ebx
		mov	ebx, _filelocalopen
		mov	edx, fileopened
		mov	[ebx + 0x08], eax
		mov	[ebx + 0x14], eax
		call	addjob
		; オープン実行
		mov	[_sbcmd +0x20], eax
		call	0xC7:0
		pop	ebx
.ret:		pop	edx
		pop	ecx
		pop	eax
		ret
fileopened:	; ファイル準備完了後の処理
		; in:	eax	エラーコード
		;	edx	引数2(スロット)
		
		; ハンドル検索
		mov	ecx, 0
.lop:		cmp	[mmt_fileid + ecx*4], edx
		je	.ext
		inc	ecx
		cmp	ecx, 4
		jb	.lop
		; 見つからないことは無い…はず
		int	3
.ext:		cmp	eax, 0
		mov	[mmt_errcode + ecx*4], eax
		je	.ok
		; オープン失敗
		ret
.ok:		; 情報取得&格納
		mov	ebx, _filesize
		mov	[ebx + 0x08], edx
		call	0xC7:0
		mov	eax, [filesize]
		mov	[mmt_fsize + ecx*4], eax
		mov	ebx, _filesetmapper
		mov	[ebx + 0x08], edx
		mov	eax, [mmt_limit + ecx*4]
		mov	[ebx + 0x0C], eax
		mov	esi, [mmt_base + ecx*4]
		mov	[ebx + 0x10], esi
		mov	edi, [mmt_writable + ecx*4]
		mov	[ebx + 0x18], edi
		call	0xC7:0

		ret

GpRedraw:	; 画面更新呼び出し
		
		
		; アニメーション更新
		;call	anime
		mov	ecx, [puttern_offset]
		mov	edx, [puttern_offset+4]
		cmp	ecx, [puttern_offsetb]
		jne	.px_1
		cmp	edx, [puttern_offsetb+4]
		je	.px_2
.px_1:		mov	byte [screen_update + 0], 0
		mov	[puttern_offsetb], ecx
		mov	[puttern_offsetb+4], edx
.px_2:		test	byte [screen_mode], 1
		jz	.p0_r
		cmp	byte [screen_update + 0], 1
		;je	.p0_r
		; 16x16パターンマップレイア1
		; puttern_offset
		mov	ebx, GPXSIZE|GPYSIZE<<8
		mov	esi, ecx
		mov	edi, edx
		and	ecx, 15
		jz	.p0_1
		inc	bl
.p0_1:		and	edx, 15
		jz	.p0_2
		inc	bh
.p0_2:		shr	esi, 4
		shr	edi, 4
		neg	ecx
		neg	edx
		sub	esi, (GPXSIZE>>1)-1
		sub	edi, (GPYSIZE>>1)-1
.p0_y:		push	ecx
		push	ebx
		push	esi
.p0_x:		call	getpm
		push	edi
		push	ebx
		mov	edi, vram_ptnb
		mov	ebx, palettetablebg
		call	bitmap_copy2
		pop	ebx
		pop	edi
		inc	esi
		add	ecx, 16
		dec	bl
		jnz	.p0_x
		pop	esi
		pop	ebx
		pop	ecx
		inc	edi
		add	edx, 16
		dec	bh
		jnz	.p0_y
		mov	byte [screen_update + 0], 1
.p0_r:		; スプライト描画更新
		; スプライトオフセットは変更されるとupdchkにひっかかるためチェックしない
		test	byte [screen_mode], 2
		jz	.o0_r
		cmp	byte [screen_update + 1], 1
		je	.o0_r
		call	OAM_decode
		mov	byte [screen_update + 1], 1
.o0_r:		; 16x16パターンマップレイア2
		test	byte [screen_mode], 4
		jz	.p1_r
		cmp	byte [screen_update + 2], 1
		je	.p1_r

		mov	byte [screen_update + 2], 1
.p1_r:		;mov	ecx, [puttern_offset]
		;mov	edx, [puttern_offset+4]
		; 半透明ディザリング模様のトグル
		test	byte [fasthalf], 1
		jz	.hskp
		mov	byte [toumei_flag], 0
.hskp:		; 重ね合わせと拡大転送
		mov	eax, [scopyvalue]
		; フィルタが「デフォルト」で
		; 等倍の場合は専用高速転送する。
		or	eax, eax
		jnz	.hnot
		cmp	dword [winsizex], VGXSIZE
		jne	.hnot
		cmp	dword [winsizey], VGYSIZE
		jne	.hnot
		call	bitblt_normal
		jmp	.hret
.hnot:		call	near [scopytable + eax*4]
.hret:		test	byte [redraw_init], 1
		jz	.ret
		call	GpFlush
.ret:		ret
;   Layer-1:	vram		パターンマップ地面用/
;   Layer-2:	vram_oamb	地面上スプライト(背景)
;   Layer-3:	vram_ptnf	パターンマップ屋根用
;   Layer-4:	vram_oamf	飛行中スプライト(前景)
;   Layer-5:	vram_back	ピクセルマップ(マップ用)
;   Layer-6:	vram_fore	ピクセルマップ(文字用)
bitblt_normal:	; 等倍専用半透明同時高速版
		mov	ecx, VGXSIZE*VGYSIZE
		mov	ah, [toumei_flag]
		xor	byte [toumei_flag], 1
.pm_y:		mov	ebx, VGXSIZE
.pm_l:		dec	ecx
		mov	al, [vram_fore + ecx]
		test	al, 0x80
		jz	.pm_d
		mov	al, [vram_back + ecx]
		test	al, 0x80
		jz	.pm_d
		test	al, 0x40
		jnz	.pm_s
		test	ah, 1
		jnz	.pm_d
.pm_s:		mov	al, [vram_oamf + ecx]
		test	al, 0x80
		jz	.pm_d
	;	mov	al, [vram_ptnf + ecx]
	;	test	al, 0x80
	;	jz	.pm_d
		mov	al, [vram_oamb + ecx]
		test	al, 0x80
		jz	.pm_d
		mov	al, [vram_ptnb + ecx]
		test	al, 0x80
		jz	.pm_d
		mov	al, [vram + ecx]
.pm_d:		and	al, 0x0F
		xor	ah, 1
		mov	[vram_screen + ecx], al
		jecxz	.pm_e
		dec	ebx
		jnz	.pm_l
		xor	ah, 1
		jmp	.pm_y
.pm_e:		jmp	GpFlush
stretch_normal:	; 画面拡大合成転送(そんなに高速ではない版)
		; ディザ補完:無,半透明補完:拡大対応
		; VGA:	7.0fps
		; SVGA:	5.3fps
		; XGA:	3.7fps
		; 画面拡大転送
		mov	edx, 0	/*/; Y座標整数部 ;/*/
		mov	ecx, 0	/*/; Y座標小数部 ;/*/
		mov	ebx, 0	/*/; 表示上のY座標 ;/*/
		mov	edi, 0	/*/; dist ofs ;/*/
		;mov	[temp_y], edx
		xor	byte [toumei_flag], 1
		mov	eax, [winsizey]
.cp_y:		; ライン毎にアドレス計算
		push	eax
		push	edx
		mov	eax, [byteperline] ;VGXSIZE
		mul	edx
		mov	esi, eax
		mov	ah, bl
		shr	ah, 1
		xor	ah, [toumei_flag]
		; 1ラインの拡大縮小転送
		push	ecx
		push	ebx
		mov	edx, 0	/*/; X座標整数部 ;/*/
		mov	ecx, 0	/*/; X座標小数部 ;/*/
		mov	ebx, [winsizex]
.cp_x:		mov	al, [vram_fore+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_back+esi+edx]
		test	al, 0x80
		jz	.cp_d
		test	al, 0x40
		jnz	.cp_s
		test	ah, 1
		jnz	.cp_d
.cp_s:		mov	al, [vram_oamf+esi+edx]
		test	al, 0x80
		jz	.cp_d
	;	mov	al, [vram_ptnf+esi+edx]
	;	test	al, 0x80
	;	jz	.cp_d
		mov	al, [vram_oamb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_ptnb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram+esi+edx]
.cp_d:		and	al, 0x0F
		xor	ah, 1
		mov	[vram_screen+edi], al
		inc	edi
		add	ecx, [StretchXRate+12]
		adc	edx, [StretchXRate+ 8]
		dec	ebx
		jnz	.cp_x
		pop	ebx
		pop	ecx
		pop	edx
		pop	eax
		add	ecx, [StretchYRate+12]
		adc	edx, [StretchYRate+ 8]
		inc	ebx ; dword [temp_y]
		dec	eax
		jnz	.cp_y
		jmp	GpFlush
stretch_scanli:	; 画面拡大合成転送(スキャンライン風高速版)
		; ディザ補完:無,半透明補完:拡大半対応
		; VGA:	10.2fps
		; SVGA:	 9.1fps
		; XGA:	 8.2fps
		; 画面拡大転送
		mov	edx, 0	/*/; Y座標整数部 ;/*/
		mov	ecx, 0	/*/; Y座標小数部 ;/*/
		mov	ebx, 0	/*/; 更新ライン ;/*/
		mov	edi, 0	/*/; dist ofs ;/*/
		;mov	[temp_y], edx
		mov	byte [temp_x], -1
		xor	byte [toumei_flag], 1
		mov	eax, [winsizey]
.cp_y:		; ライン毎にアドレス計算
		cmp	[temp_x], edx
		jne	.cp_b
		; 同じラインの時はスキップ
		; (=疑似スキャンラインエフェクト)
		add	edi, [winsizex]
		jmp	.cp_k
.cp_b:		push	eax
		push	edx
		push	edx
		mov	eax, [byteperline] ;VGXSIZE
		mov	[temp_x], edx
		mul	edx
		mov	esi, eax
		pop	edx
		mov	ah, dl
		xor	ah, [toumei_flag]
		; 1ラインの拡大縮小転送
		push	ecx
		push	ebx
		mov	edx, 0	/*/; X座標整数部 ;/*/
		mov	ecx, 0	/*/; X座標小数部 ;/*/
		mov	ebx, [winsizex]
.cp_x:		mov	al, [vram_fore+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_back+esi+edx]
		test	al, 0x80
		jz	.cp_d
		test	al, 0x40
		jnz	.cp_s
		test	ah, 1
		jnz	.cp_d
.cp_s:		mov	al, [vram_oamf+esi+edx]
		test	al, 0x80
		jz	.cp_d
	;	mov	al, [vram_ptnf+esi+edx]
	;	test	al, 0x80
	;	jz	.cp_d
		mov	al, [vram_oamb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_ptnb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram+esi+edx]
.cp_d:		and	al, 0x0F
		xor	ah, 1
		mov	[vram_screen+edi], al
		inc	edi
		add	ecx, [StretchXRate+12]
		adc	edx, [StretchXRate+ 8]
		dec	ebx
		jnz	.cp_x
		pop	ebx
		pop	ecx
		pop	edx
		pop	eax
		; 1ライン更新
		call	GpFlushLine
.cp_k:		add	ecx, [StretchYRate+12]
		adc	edx, [StretchYRate+ 8]
		inc	ebx ; dword [temp_y]
		dec	eax
		jnz	.cp_y
		ret
stretch_inter1:	; 画面拡大合成転送(インタレース風高速版1)
		; ディザ補完:無,半透明補完:拡大半対応
		; 表示上のトップフィールドとボトムフィールドを交互に更新
		; VGA:	0.2fps
		; SVGA:	0.1fps
		; XGA:	0.2fps
		; 画面拡大転送
		mov	edx, 0	/*/; Y座標整数部 ;/*/
		mov	ecx, 0	/*/; Y座標小数部 ;/*/
		mov	ebx, 0	/*/; 表示上のY座標 ;/*/
		mov	edi, 0	/*/; dist ofs ;/*/
		mov	al, [fps_count]
		and	al, 1
		mov	[temp_y], al
		mov	byte [temp_x], -1
		mov	eax, [winsizey]
		jnz	.cp_y
		xor	byte [toumei_flag], 1
.cp_y:		cmp	[temp_x], edx
		jne	.cp_b
		; 同じラインの時はコピー
		push	esi
		push	ecx
		lea	esi, [edi + vram_screen]
		add	edi, vram_screen
		mov	ecx, [winsizex]
		
		sub	esi, ecx
		repnz	movsb
		pop	ecx
		pop	esi
		sub	edi, vram_screen
		jmp	.cp_k
.cp_b:		push	eax
		push	edx
		; ライン毎にアドレス計算
		mov	eax, [byteperline] ;VGXSIZE
		mov	[temp_x], edx
		mul	edx
		mov	esi, eax
		mov	ah, byte ds:[esp]
		xor	ah, [toumei_flag]
		; 1ラインの拡大縮小転送
		push	ecx
		push	ebx
		mov	edx, 0	/*/; X座標整数部 ;/*/
		mov	ecx, 0	/*/; X座標小数部 ;/*/
		mov	ebx, [winsizex]
.cp_x:		mov	al, [vram_fore+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_back+esi+edx]
		test	al, 0x80
		jz	.cp_d
		test	al, 0x40
		jnz	.cp_s
		test	ah, 1
		jnz	.cp_d
.cp_s:		mov	al, [vram_oamf+esi+edx]
		test	al, 0x80
		jz	.cp_d
	;	mov	al, [vram_ptnf+esi+edx]
	;	test	al, 0x80
	;	jz	.cp_d
		mov	al, [vram_oamb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_ptnb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram+esi+edx]
.cp_d:		and	al, 0x0F
		xor	ah, 1
		mov	[vram_screen+edi], al
		inc	edi
		add	ecx, [StretchXRate+12]
		adc	edx, [StretchXRate+ 8]
		dec	ebx
		jnz	.cp_x
		pop	ebx
		pop	ecx
		pop	edx
		pop	eax
.cp_k:		xor	byte [temp_y], 1
		jz	.cp_g
		call	GpFlushLine
.cp_g:		add	ecx, [StretchYRate+12]
		adc	edx, [StretchYRate+ 8]
		inc	ebx ; dword [temp_y]
		dec	eax
		jnz	.cp_y
		mov	byte [redraw_init], 0
		ret
stretch_inter2:	; 画面拡大合成転送(インタレース風高速版2
		; ディザ補完:無,半透明補完:拡大半対応
		; 仮想上のトップフィールドとボトムフィールドを交互に更新
		; VGA:	0.2fps
		; SVGA:	0.1fps
		; XGA:	0.2fps
		; 画面拡大転送
		mov	edx, 0	/*/; Y座標整数部 ;/*/
		mov	ecx, 0	/*/; Y座標小数部 ;/*/
		mov	ebx, 0	/*/; 表示上のY座標 ;/*/
		mov	edi, 0	/*/; dist ofs ;/*/
		mov	al, [fps_count]
		and	al, 1
		mov	[temp_y], al
		mov	byte [temp_x], -1
		mov	eax, [winsizey]
		jnz	.cp_y
		xor	byte [toumei_flag], 1
.cp_y:		cmp	[temp_x], edx
		jne	.cp_b
		test	byte [temp_y], 1
		jz	.cp_a
		; 同じラインの時はコピー
		push	esi
		push	ecx
		lea	esi, [edi + vram_screen]
		add	edi, vram_screen
		mov	ecx, [winsizex]
		sub	esi, ecx
		repnz	movsb
		pop	ecx
		pop	esi
		sub	edi, vram_screen
		jmp	.cp_k
.cp_a:		add	edi, [winsizex]
		jmp	.cp_g
.cp_b:		push	eax
		push	edx
		; ライン毎にアドレス計算
		mov	eax, [byteperline] ;VGXSIZE
		mov	[temp_x], edx
		mul	edx
		mov	esi, eax
		mov	ah, [toumei_flag]
		xor	byte [temp_y], 1
		; 1ラインの拡大縮小転送
		push	ecx
		push	ebx
		mov	edx, 0	/*/; X座標整数部 ;/*/
		mov	ecx, 0	/*/; X座標小数部 ;/*/
		mov	ebx, [winsizex]
.cp_x:		mov	al, [vram_fore+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_back+esi+edx]
		test	al, 0x80
		jz	.cp_d
		test	al, 0x40
		jnz	.cp_s
		test	ah, 1
		jnz	.cp_d
.cp_s:		mov	al, [vram_oamf+esi+edx]
		test	al, 0x80
		jz	.cp_d
	;	mov	al, [vram_ptnf+esi+edx]
	;	test	al, 0x80
	;	jz	.cp_d
		mov	al, [vram_oamb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_ptnb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram+esi+edx]
.cp_d:		and	al, 0x0F
		xor	ah, 1
		mov	[vram_screen+edi], al
		inc	edi
		add	ecx, [StretchXRate+12]
		adc	edx, [StretchXRate+ 8]
		dec	ebx
		jnz	.cp_x
		pop	ebx
		pop	ecx
		pop	edx
		pop	eax
.cp_k:		test	byte [temp_y], 1
		jz	.cp_g
;flushlines_temp
		call	GpFlushLine
.cp_g:		add	ecx, [StretchYRate+12]
		adc	edx, [StretchYRate+ 8]
		inc	ebx ; dword [temp_y]
		dec	eax
		jnz	.cp_y
		mov	byte [redraw_init], 0
		ret
stretch_dbscan:	; 画面拡大合成転送(ダブルスキャン風高速版)
		; ディザ補完:無,半透明補完:拡大対応
		; VGA:	9.8fps
		; SVGA:	8.0fps
		; XGA:	6.8fps
		; 画面拡大転送
		mov	edx, 0	/*/; Y座標整数部 ;/*/
		mov	ecx, 0	/*/; Y座標小数部 ;/*/
		mov	edi, 0	/*/; dist ofs ;/*/
		;mov	[temp_y], edx
		mov	byte [temp_x], -1
		xor	byte [toumei_flag], 1
		mov	eax, [winsizey]
.cp_y:		; ライン毎にアドレス計算
		cmp	[temp_x], edx
		jne	.cp_b
		; 同じラインの時はコピー
		push	esi
		push	ecx
		lea	esi, [edi + vram_screen]
		add	edi, vram_screen
		mov	ecx, [winsizex]
		
		sub	esi, ecx
		repnz	movsb
		pop	ecx
		pop	esi
		sub	edi, vram_screen
		jmp	.cp_k
.cp_b:		push	eax
		push	edx
		mov	eax, [byteperline] ;VGXSIZE
		mov	[temp_x], edx
		mul	edx
		mov	esi, eax
		mov	ah, byte ds:[esp]
		xor	ah, [toumei_flag]
		; 1ラインの拡大縮小転送
		push	ecx
		push	ebx
		mov	edx, 0	/*/; X座標整数部 ;/*/
		mov	ecx, 0	/*/; X座標小数部 ;/*/
		mov	ebx, [winsizex]
.cp_x:		mov	al, [vram_fore+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_back+esi+edx]
		test	al, 0x80
		jz	.cp_d
		test	al, 0x40
		jnz	.cp_s
		test	ah, 1
		jnz	.cp_d
.cp_s:		mov	al, [vram_oamf+esi+edx]
		test	al, 0x80
		jz	.cp_d
	;	mov	al, [vram_ptnf+esi+edx]
	;	test	al, 0x80
	;	jz	.cp_d
		mov	al, [vram_oamb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram_ptnb+esi+edx]
		test	al, 0x80
		jz	.cp_d
		mov	al, [vram+esi+edx]
.cp_d:		and	al, 0x0F
		xor	ah, 1
		mov	[vram_screen+edi], al
		inc	edi
		add	ecx, [StretchXRate+12]
		adc	edx, [StretchXRate+ 8]
		dec	ebx
		jnz	.cp_x
		pop	ebx
		pop	ecx
		pop	edx
		pop	eax
.cp_k:		add	ecx, [StretchYRate+12]
		adc	edx, [StretchYRate+ 8]
		;inc	dword [temp_y]
		dec	eax
		jnz	.cp_y
		;jmp	GpFlush
GpFlush:	; OSに全領域の再描画を依頼する
		push	ebx
		mov	ebx, us_redraw
		call	0xC7:0
		pop	ebx
		mov	byte [redraw_init], 0
		ret
GpFlushLine:	; OSに1ライン分だけ再描画を依頼する
		; in:	ebx	ライン座標(y)
		push	ebx
		mov	[us_redraw_line + 0x010], ebx
		mov	ebx, us_redraw_line
		mov	dword [ebx + 0x018], 1
		call	0xC7:0
		pop	ebx
		ret
GpFlushLines:	; OSに数ライン分だけ再描画を依頼する
		; in:	ebx	開始ライン座標(y)
		;	ecx	ライン数
		push	ebx
		mov	[us_redraw_line + 0x010], ebx
		mov	ebx, us_redraw_line
		mov	[ebx + 0x018], ecx
		call	0xC7:0
		pop	ebx
		ret
PC98Check:	; PC98チェック
		test	byte [townschk+1], 3
		jnz	.iret
		/* ジョイスティックコネクタはサウンド機能が内臓の機種にはないらしい。
		 * サウンドボードPC-9801-26/73/86にはコネクタが1つ以上あるようだ。 
		*/
		mov	al, 0
		mov	byte [townschk+1], 2
		/* 拡張サウンドボード(YM2608)とサウンドボート(YM2203)の判別方法はあるが
		 * サウンドボードの有無の判別は(普通の)方法が分からないので、
		 * SSG音源メモリが使えるかどうかで判別する。
		 * もちろん他の機種で実行した場合は影響があるかもしれない。
		 */
		push	edx
		push	ecx
		push	eax
		mov	edx, 0x0188	/* デフォルト */
		mov	ah, 11
		call	ssgin
		xor	al, 0xA5
		call	ssgout
		mov	cl, al
		mov	ah, 12
		xor	al, 0xA5
		call	ssgout	/* なんとなくキャッシュ防止してみる */
		mov	ah, 11
		call	ssgin
		cmp	al, cl
		pop	eax
		pop	ecx
		pop	edx
		jne	.iret
		mov	al, 1
		or	byte [townschk+1], 1
.iret:		ret
PC98PadInput:	; MSX互換パッド情報の取得
		; in:	ポート	[UsePadFlags+4]
		; out:	パッド情報	[msxpad_status]とeax
		test	byte [townschk+1], 3
		jnz	.chkskp
		call	PC98Check
.chkskp:	mov	eax, 0
		test	byte [townschk+1], 1
		jz	.ret
		push	edx
		mov	edx, 0x0188
		mov	al, 0x8F
		test	byte [UsePadFlags+4], 1
		jz	.porta
		or	al, 0x40
.porta:		mov	ah, 0x0F
		call	ssgout
		mov	ah, 0x0E
		call	ssgin
		mov	dl, al
		mov	ah, 0
		and	al, 0x30
		and	dl, 0x0F
		shl	al, 2
		test	dl, 0x03
		jnz	.notsel
		or	al, 0x23
.notsel:	test	dl, 0x0C
		jnz	.notrun
		or	al, 0x1C
.notrun:	or	al, dl
		xor	al, 0xCF
		pop	edx
.ret:		mov	[msxpad_status], eax
		ret
ssgout:		; in:	dx	ポートアドレス
		;	ah	アドレス
		;	al	データ
		xchg	al, ah
		out	dx, al
		inc	edx
		inc	edx
		xchg	al, ah
		out	dx, al
		dec	edx
		dec	edx
		ret
ssgin:		; in:	dx	ポートアドレス
		;	ah	アドレス
		; out:	al	データ
		mov	al, ah
		out	dx, al
		inc	edx
		inc	edx
		in	al, dx
		dec	edx
		dec	edx
		ret
TownsCheck:	; FM TOWNSチェック
		; サンプリングレジスタによるチェック
		; 最低でも5.5125kHzらしいので
		; 確実に1/60秒以上のウェイトを入れて読み出す。
		; 0x04E8にデータを出力しているので
		; 他機種で誤動作する可能性がなくはない。
		cmp	byte [padbusy], 0
		jne	.iret
		test	byte [townschk], 3
		jnz	.iret
		inc	byte [padbusy]
		mov	byte [townschk], 2
		push	dword [vsync_flags]
		call	vsync_init
		push	edx
		push	eax
		mov	eax, 0
		mov	dx, 0x04E8
		out	dx, al
		in	al, dx
		in	al, dx
		push	eax
		mov	eax, 0
		call	vsync_nodraw
		mov	eax, 5	; 1/19200秒以上のウェイト(ここでは1/60秒)
		call	vsync_nodraw
		pop	eax
		mov	ah, al
		in	al, dx
		and	ax, 0x0101
		xor	al, ah
		//mov	[used_townspad], al
		or	byte [townschk], al
		mov	dl, al
		pop	eax
		mov	al, dl
		pop	edx
		pop	dword [vsync_flags]
		dec	byte [padbusy]
.iret:		ret
TownsPadInput2:	; TOWNSパッド情報の取得
		/* 2人同時プレイには対応しなくていいので
		 * 指定されたどちらかのポートを読み込む。
		 * 6ボタンパッドだとOS側のマウスルーチン
		 * (COM出力)によって誤動作する可能性が
		 * あるが、6ボタンパッドを持っている人は
		 * ほぼいないらしいので、放っておく(^^;。
		 */
		; in:	[UsePadFlags+4]	ポート番号
		; out:	eax	入力状態(b=1:ON)
		; 変換後:b0~:上下左右,RUN,SELECT,A,B (8bit)
		; 	RUN/SELECT時の誤動作防止をする。
		test	byte [townschk], 3
		jnz	.chkskp
		call	TownsCheck
.chkskp:	mov	eax, 0
		test	byte [townschk], 1
		jz	.ret
		push	edx
		mov	dx, 0x04D0
		test	byte [UsePadFlags+4], 1
		jz	.skp
		mov	dl, 0xD2
.skp:		mov	ah, 0
		in	al, dx
		mov	dl, al
		and	al, 0x30
		and	dl, 0x0F
		shl	al, 2
		test	dl, 0x03	; SELECT
		jnz	.notsel
		or	al, 0x23
.notsel:	test	dl, 0x0C	; RUN
		jnz	.notrun
		or	al, 0x1C
.notrun:	or	al, dl
		xor	al, 0xCF
		pop	edx
.ret:		mov	[msxpad_status], eax
		ret
TownsPadInput6:	; TOWNSパッド情報の取得
		; (左ポート固定)
		; out:	eax	パッド情報(b0-3:上下左右,b4-5:RUN,SELECT,b6-7:A,Bボタン)
		test	byte [townschk], 3
		jnz	.chkskp
		call	TownsCheck
.chkskp:	mov	eax, 0
		test	byte [townschk], 1
		jz	.ret
		; TOWNSチェックでエラーの場合と
		; 機種未チェックの場合はパッド入力無しとする。
		push	edx
		push	ecx
		cli	// 割り込み禁止
		/* Kによると割り込み禁止状態にしてチェックしないと
		 * マウスのタイミングがずれたりするらしい。
		 * 超短い時間ならCLI-STIを使用していいとの事。
		 * でも禁止した直後にマウスの割り込みきたら
		 * ズタズタになりそうな気がするが、気にしない。
		 * 多分、大丈夫なのだろう。
		 * が、pokonのコンソール上でmouseportコマンドを使用すると
		 * ポートを変更できるような記述があるので…両方見る?
		 * やっぱりTRIG出力は両ポートともONらしいので2ボタンパッドに
		 * このルーチンは必要ないはず。
		 */
		; 現在のマウスポートのCOM出力のチェックして
		mov	dx, 0x04D2
		in	al, dx
		shr	al, 1
		and	al, 0xE0
		or	al, 0x0F
		mov	cl, al
		mov	dx, 0x04D6
		out	dx, al
		; PADポートのCOM出力をオフで入力。
		mov	dx, 0x04D0
		mov	ah, al
		in	al, dx
		mov	dx, 0x04D6
		xchg	al, ah
		xor	al, 0x10
		out	dx, al
		; PADポートのCOM出力をオンで入力。
		mov	dx, 0x04D0
		in	al, dx	// いずれ6ボタンに対応するつもり。
		mov	dx, 0x04D6
		mov	ch, al
		mov	al, cl
		; マウスポートのCOM出力を戻す。
		sti	// 割り込み許可
		out	dx, al
		mov	al, ch
		; マウスポートのTRIG出力はする。そして
		; COM出力は変更するとマウスの動作に支障が
		; でる可能性があるので変更しないようにする。
		; 結果、こうすると支障がでない…はず。
		; 結果:	ah:COM出力なしでのPAD状態
		;	al:COM出力ありでのPAD状態
		; 変換前:b6:COM入力,b5:TRIG2,b4:TRIG1,b3:RIGHT,b2:LEFT,b1:BACK,b0:FWD入力
		; /* COM出力有り状態の時はb3-b0がTRIG6,5,4,3だろうか */
		; 変換後:b0~:上下左右,RUN,SELECT,A,B,C,D,E,F (12bit)
		; 	RUN/SELECT時の誤動作防止をする。
		; 6ボタンパッドの仕様を知らないので2ボタンパッドの情報のみで更新
		mov	ch, ah
		and	ah, 0x30
		and	ch, 0x0F
		shl	ah, 2
		and	al, 0x0F
		or	ah, ch
		test	ch, 0x03	; SELECT
		jnz	.notsel
		or	ah, 0x23
.notsel:	test	ch, 0x0C	; RUN
		jnz	.notrun
		or	ah, 0x1C
.notrun:	xor	al, 0x0F
		xor	ah, 0xCF
		pop	ecx
		xchg	al, ah
		pop	edx
.ret:		mov	dword [msxpad_status], eax
		ret
getpm:		; パターンマップ配列の値の取得
		; in:	esi,edi	マップ座標
		; out:	ax	値
		;push	edi
		;push	esi
		cmp	esi, [psize]
		jnb	.ng
		cmp	edi, [psize+4]
		jnb	.ng
		push	edx
		push	eax
		mov	eax, [psize]
		shl	eax, 1
		mul	edi
		mov	dx, [ptnmap + eax + esi*2]
		pop	eax
		mov	ax, dx
		pop	edx
		;pop	esi
		;pop	edi
		ret
.ng:		mov	ax, 0
		ret
setpm:		; パターンマップ配列の値の設定
		; in:	esi,edi	マップ座標
		;	ax	値
		cmp	esi, [psize]
		jnb	.ng
		cmp	edi, [psize+4]
		jnb	.ng
		push	edx
		push	eax
		mov	eax, [psize]
		mul	edi
		lea	edx, [eax + esi]
		pop	eax
		mov	[ptnmap + edx*2], ax
		pop	edx
		;bpmupd
		ret
.ng:		int	3
menu_clear:	; メニューバッファの初期化
		; in:	ebx	メニューデータバッファ
		;	ecx	(最大半角数)
		push	eax
		lea	eax, [ebx + 0x10]
		mov	[ebx + 0x004], ecx
		mov	dword [ebx + 0x008], eax
	;	mov	dword [ebx + 0x00C], 0x0000
		pop	eax
		ret
menu_additem:	; メニューの追加
		; in:	eax	選択時の返り値
		;	edi	文字列
		;	edx	opt(=0)
		;	ebx	メニューデータバッファ
		;	文字列は内部にコピーされる。
		push	ecx
		push	edi
		push	esi
		mov	esi, edi
		mov	edi, [ebx + 0x008]
		mov	ecx, [esi]
		mov	[edi], eax
		mov	[edi+4], edx
		mov	[edi+8], ecx
		add	ecx, 3
		add	esi, 4
		shr	ecx, 2
		add	edi, 12
		
		repnz	movsd
		pop	esi
		mov	[ebx + 0x008], edi
		mov	dword [edi +8], 0
		mov	dword [edi], -1
		pop	edi
		pop	ecx
		ret
bitmap_initpal:	; パレット変換テーブルの初期化
		; in:	ah=>al	透明色と解釈する色番号
		;	ebx	パレット変換テーブル
		push	edx
		mov	dword [ebx], 0x03020100
		mov	dword [ebx+4], 0x07060504
		mov	dword [ebx+8], 0x0B0A0908
		mov	dword [ebx+12], 0x0F0E0D0C
		;mov	dword [ebx], 0x03020100
		;mov	dword [ebx+4], 0x00060504
		;mov	dword [ebx+8], 0x03020107
		;mov	dword [ebx+12], 0x08060504
		movzx	edx, ah
		and	edx, 0x0F
		mov	byte [ebx+edx], al
		ror	eax, 16
		movzx	edx, ah
		and	edx, 0x0F
		mov	byte [ebx+edx], al
		rol	eax, 16
		pop	edx
		ret
bitmap_inipal2:	; パレット変換テーブルの初期化(暗くする)
		; in:	ah=>al	透明色と解釈する色番号
		;	ebx	作成するパレット変換テーブル
		push	ebx
		mov	dword [ebx], 0x03020100
		mov	dword [ebx+4], 0x00060504
		mov	dword [ebx+8], 0x03020107
		mov	dword [ebx+12], 0x08060504
		movzx	edx, ah
		and	edx, 0x0F
		mov	byte [ebx+edx], al
		ror	eax, 16
		movzx	edx, ah
		and	edx, 0x0F
		mov	byte [ebx+edx], al
		rol	eax, 16
		pop	edx
		ret
bitmap_regist2:	; BMP形式データを直接転送(bitblt)
		; in:	edi	BMPデータの先頭アドレス
		;	ebx	登録するパターン番号
		;	ds:edx	パラメータのアドレス
		;	+0x0000	2dword	BMP画像内での左上の点の座標(x, y)
		;	+0x0008	2dword	BMP画像の大きさ(幅, 高さ)
		;	+0x0010	dword	描画先の左上の点のセグメントオフセット(gbox+64,つまりグラフィックバッファの先頭)
		;	+0x0014	dword	描画先へのBMP画像の描画の関するフラグ(b0=1:StretchBlt,拡大縮小機能を利用し、描画先BMP画像サイズパラメータバッファが存在する)
		;	+0x0018	2dword	描画先の大きさ(バイト単位の幅,高さ)
		;	+0x0020	2dword	描画先の座標(x, y)
		;	+0x0028	2dword	描画先のBMP画像領域のサイズ(option)
		;	+0x0030	4dword	reserved	
		; out:	ebx	次のパターン番号
		; ファイルサイズチェック
		cmp	ecx, 0x76
		jnb	.fok
		ret
.fok:		; ファイルヘッダチェック
		push	eax
		push	ecx
		push	edx
		push	esi
		push	edi
		cmp	word [edi], "BM"
		jne	.notbmp0
		cmp	dword [edi + _biSize], 40
		jne	.notbmp1
		mov	esi, [edi + _bfOffBits]
		mov	ecx, [edi + _biWidth]
		mov	edx, [edi + _biHeight]
		cmp	word [edi + _biBitCount], 4
		jne	.notbmp2
		mov	eax, [edi + _biClrUsed]
		or	eax, eax
		jnz	.ok
		mov	eax, 16
.ok:		lea	eax, [eax*4 + _bmiColors]
		or	esi, esi
		jz	.eskp
		cmp	eax, esi
		jne	.notbmp3
.eskp:		add	esi, edi
		mov	eax, ecx
		add	eax, 7
		shr	eax, 1
		and	eax, -4
		add	edi, eax
		dec	edx
		pop	edi
		pop	esi
		pop	edx
		pop	ecx
		pop	eax
		ret
.notbmp0:	mov	eax, 0x11223300
		int	3
.notbmp1:	mov	eax, 0x11223301
		int	3
.notbmp2:	mov	eax, 0x11223302
		int	3
.notbmp3:	mov	eax, 0x11223303
		int	3
bitmap_regist:	; BMP形式データを16x16パターンデータとして登録する
		; in:	edi	BMPデータの先頭アドレス
		;	ebx	先頭パターン番号
		;	ecx	BMPデータサイズ
		; out:	ebx	次の割り当て可能なパターン番号
		; 割り当ての例)(□=16x16)
		; 0 1 2 3 4 5 6 7	0 1 2 3 4
		; □□□□□□□□	□□□□□
		; 8 9 A B C D E F	5 6 7 8 9
		; □□□□□□□□	□□□□□
		; 1011121314151617	A B C D E
		; □□□□□□□□	□□□□□
		; ファイルサイズチェック
		
		cmp	ecx, 0x76
		jnb	.fok
		ret
.fok:		; ファイルヘッダチェック
		push	eax
		push	ecx
		push	edx
		push	esi
		push	edi
		cmp	word [edi], "BM"
		jne	.notbmp0
		cmp	dword [edi + _biSize], 40
		jne	.notbmp1
		mov	esi, [edi + _bfOffBits]
		mov	ecx, [edi + _biWidth]
		mov	edx, [edi + _biHeight]
		cmp	word [edi + _biBitCount], 4
		jne	.notbmp2
		mov	eax, [edi + _biClrUsed]
		or	eax, eax
		jnz	.ok
		mov	eax, 16
.ok:		lea	eax, [eax*4 + _bmiColors]
		or	esi, esi
		jz	.eskp
		cmp	eax, esi
		jne	.notbmp3
.eskp:		add	esi, edi
		mov	eax, ecx
		add	eax, 7
		shr	eax, 1
		and	eax, -4
		mov	edi, eax
		dec	edx
		; 縦の位置を計算
.lopy:		push	eax
		push	edx
		push	ecx
		mul	edx
		add	eax, esi
.lopx:		sub	ecx, 16
		jl	.ext
		mov	[putterntable1 + ebx*8 +0], eax
		mov	[putterntable1 + ebx*8 +4], edi
		inc	ebx
		add	eax, 8
		jmp	.lopx
.ext:		pop	ecx
		pop	edx
		pop	eax
		sub	edx, 16
		cmp	edx, 15
		jnl	.lopy
		pop	edi
		pop	esi
		pop	edx
		pop	ecx
		pop	eax
		ret
.notbmp0:	mov	eax, 0x11223300
		int	3
.notbmp1:	mov	eax, 0x11223301
		int	3
.notbmp2:	mov	eax, 0x11223302
		int	3
.notbmp3:	mov	eax, 0x11223303
		int	3
int3:	; デバッグ用レジスタ値表示
		pusha
		cli
		mov	[debug_stack], esp
		mov	esp, debug_stack
		pushf
		push	gs
		push	fs
		push	es
		push	ds
		push	ss
		push	cs
		pusha
		mov	eax, [debug_stack]
		sti
		mov	esp, eax
		add	eax, 0x24
		mov	edi, debugregsrc
		mov	[reg32+12], eax
		mov	eax, ss:[eax -4]
		mov	ecx, 0
		mov	[debug_stack], eax
		mov	edx, 32
.lop:		call	printf
		add	edx, 16
		cmp	dword [edi], 0
		jne	.lop
		popa
		ret

[SECTION .data]
_data:
debugregsrc:	; 
dd	0x0017,	"INT 03:デバッグ割り込み"
dd	0x0015,	"CS:%4h EIP:%8h SS:%4h", reg16, reg16+28, reg16+4
dd	0x001B,	"DS:%4h ES:%4h FS:%4h GS:%4h", reg16+8, reg16+12, reg16+16, reg16+20
dd	0x000F,	"EAX:%8h ECX:%8h", reg32+28, reg32+24
dd	0x000F,	"EDX:%8h EBX:%8h", reg32+20, reg32+16
dd	0x000F,	"ESP:%8h EBP:%8h", reg32+12, reg32+ 8
dd	0x000F,	"ESI:%8h EDI:%8h", reg32+ 4, reg32
dd	0x000A,	"EFLAGS:%8h", reg16+24
dd	0x0000
		alignb	8
windowptn:	; ウィンドウの枠の描画データ (8x8)
; 0:透明,1:枠,2:半透明
; 角丸ウィンドウ
/*┌*/;	dd	0x00000000,0x00000000,0x00000333,0x00003311,0x00031112,0x00331222,0x00311222,0x00312222
/*┬*/;	dd	0x00000000,0x00000000,0x33333333,0x11111111,0x22222222,0x22222222,0x22222222,0x22222222
/*┐*/;	dd	0x00000000,0x00000000,0x33300000,0x11333000,0x21113000,0x22213300,0x22211300,0x22221300
/*├*/;	dd	0x00312222,0x00312222,0x00312222,0x00312222,0x00312222,0x00312222,0x00312222,0x00312222
/*┤*/;	dd	0x22221300,0x22221300,0x22221300,0x22221300,0x22221300,0x22221300,0x22221300,0x22221300
/*└*/;	dd	0x00312222,0x00311222,0x00331222,0x00031112,0x00033311,0x00000333,0x00000000,0x00000000
/*┴*/;	dd	0x22222222,0x22222222,0x22222222,0x22222222,0x11111111,0x33333333,0x00000000,0x00000000
/*┘*/;	dd	0x22221300,0x22211300,0x22213300,0x21113000,0x11333000,0x33300000,0x00000000,0x00000000
; 鋭角ウィンドウ
	dd	0x03333333,0x33111111,0x31122222,0x31222222,0x31222222,0x31222222,0x31222222,0x31222222
	dd	0x33333333,0x11111111,0x22222222,0x22222222,0x22222222,0x22222222,0x22222222,0x22222222
	dd	0x33333330,0x11111133,0x22222113,0x22222213,0x22222213,0x22222213,0x22222213,0x22222213
	dd	0x31222222,0x31222222,0x31222222,0x31222222,0x31222222,0x31222222,0x31222222,0x31222222
	dd	0x22222213,0x22222213,0x22222213,0x22222213,0x22222213,0x22222213,0x22222213,0x22222213
	dd	0x31222222,0x31222222,0x31222222,0x31222222,0x31222222,0x31122222,0x33111111,0x03333333
	dd	0x22222222,0x22222222,0x22222222,0x22222222,0x22222222,0x22222222,0x11111111,0x33333333
	dd	0x22222213,0x22222213,0x22222213,0x22222213,0x22222213,0x22222113,0x11111133,0x33333330
	
; 外部ファイルリスト
SaveFileName	dd	"MAZE?.SAV",0
BGMDLLName	dd	"BGM.DLL", 0,0
BMPDLLName	dd	"PICTURE0.BIN",0
TITLEFileName	dd	"MAZETITLE.BMP"
MENUBGFileName	dd	"MAZEMENU.BMP",0
PTNDATFileName	dd	"MAZEPTN.BMP",0
PTNCHRFileName	dd	"MAZECHR.BMP",0
; メッセージなど
loadingmsg	dd	0x000E,	"Now Loading..."
defaultname	dd	0x000A,	"名無しさん  "
pushwaitmsg	dd	0x0012,	"PUSH ENTER BUTTON!"
undercursor	dd	0x0001,	"-"
nosoundmsg	dd	0x0017,	"まだ実装されていません。"
noitemmsg	dd	0x0015,	"アイテムを持っていません。"
notnextmsg	dd	0x0017,	"ココは階段ではありません。"
overflowmsg	dd	0x001B,	"セーブデータバッファが足りません。"
name1stmsg	dd	0x0016,	"名前を入力して下さい。"
		dd	0x001C,	"名前は全角6文字まで可能です。"
nameokmsg1	dd	0x000E,	"名前は『%S』で", name_strofs
		dd	0x0010,	"よろしいですか?"
nameingmsg1	dd	0x001E,	"Home:文字入力バーを左、End:右に、"
		dd	0x001B,	"Enter:入力、Ctrl:前の画面へ、"
nameleftmsg	dd	0x0007,	"◁:Home"	// 挿入位置左へ(編集文字列中)
namerightmsg	dd	0x0007,	"End :▷"	// 挿入位置右へ
nameprevmsg	dd	0x0008,	"◁:~Home"	// 入力ページ前へ(画数,読み仮名)
namenextmsg	dd	0x0008,	"^End :▷"	// 入力ページ次へ
floornamemsg://	dd	0x0002,	"%s", SavDungeonNum, dungeonnametable
resttownmsg	dd	0x0002,	"%s", SavDungeonNum, dungeonnametable
		dd	0x0004,	"%4nF", savedatatemp+24
statusbardata:	dd	0x0019,	"%3nF%7n(%6n歩)%3n:%2N:%2N"
		dd	savedatatemp+24 /* フロア */
	;	dd	savedatatemp, savedatatemp+4 /* HP/HPMAX */
	;	dd	save_read, save_write	/* セーブデータユーザーエリアポインタ for DEBUG */
		dd	maze_turns, maze_turns+4 /* 歩いた距離 */
	;	dd	savedatatemp+16	/* ゴールド */
		dd	time_temp, time_temp+4, time_temp+8	/* 時間 */
	;	dd	0x001D,	"%2nF HP%3n/%3n%6nG%3n:%2N:%2N"
	;	dd	0x0023,	"%2nF Lv%2n HP%3n/%3n%3nG%3n:%2N:%2N"
rankcaptionmsg	dd	0x0013,	"*** ハイスコア ランキング***"
//ranktitlemsg	dd	0x0000,	"位  登録者名    挑戦   スコア    ダンジョン"
rankdatasrc	//dd	0x0020,	"  1.abcdefabcdef  0回目 12345点"
		//dd	0x0020,	"    10分 2秒     0歩 やさしい  "
		dd	0x0012,	"%3n.%S%3n回目%6n点", rnk_Num, rnk_NameLen, rnk_PlayCnt, rnk_Score
rankdatasrc2:	dd	0x0011,	"%6n分%2n秒%6歩 %s", rnk_Min, rnk_Sec, rnk_WalkCnt, rnk_DungeonNum, DunShortNames

mainmenu:	
;	height	width	lastofs	selected
;dd	0x0005,	0x000C,	0x0000,	0x0000
dd	0x0000,	0x0000,	0x0001,	0x0000	/* ウィンドウの大きさは自動的に決定 */
; 	ret		opt	len	string
dd	m_savedata,	0x0000,	0x000C,	"冒険を始める"
dd	m_ranking,	0x0000,	0x000C,	"ランキングを見る"
dd	m_sound,	0x0000,	0x0008,	"サウンドルーム"
dd	m_help,		0x0000,	0x000A,	"説明を見る"
dd	m_config,	0x0000,	0x000C,	"設定を変える"
dd	0x0001,		0x0000,	0x0006, "終わる"
dd	-1,		0x0000,	0x0000
inputpagemenu:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	m_setpage,	0x0000,	0x0008,	"ひらがな"
dd	m_setpage,	0x0001,	0x0008,	"カタカナ"
dd	m_setpage,	0x0002,	0x000A,	"全角英記号"
dd	m_setpage,	0x0003,	0x000A,	"半角英記号"
dd	m_inpsubmenu,	0x0000,	0x0004,	"漢字"
//dd	m_setcode,	0x0007,	0x000C,	"直接コード指定"
dd	1,		0x0000,	0x0004,	"終了"
dd	-1,		0x0000,	0x0000
m_inpsubmenu:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	m_setpage,	0x0004,	0x0006,	"音検索"
dd	m_setpage,	0x0005, 0x0006,	"訓検索"
dd	m_setpage,	0x0006,	0x0008,	"画数検索"
dd	-1,		0x0000,	0x0000
m_yesnomenu:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	-2,	0x0000,	0x0004,	"はい"
dd	-1,	0x0000,	0x0006,	"いいえ"
dd	-1,	0x0000,	0x0000
nextfloormenu:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	0,	0x0000, 0x0006,	"すすむ"
dd	-1,	0x0000,	0x0006,	"やめる"
dd	-1,	0x0000,	0x0000

;menucursor	dd	0x0002, "⇨▷"
menudelete	dd	0x0002,	" "
;menucursor	dd	0x0002, "▷"
;menucursor	dd	0x0002,	"▷"	//◁▷
menucursor	dd	0x0002,	"> "
;dungeonnamesrc:	; ダンジョン名の作成用
;dd	0x000B,	"%3nx%3n迷路", savedatatemp+32, savedatatemp+36
savedatamenusrc: ; セーブデータ用
dd	0x000C,	"%1N:%Sの冒険", savedatatemp, savedatatemp+4
dd	0x0012,	"%6n回目%4n:%2N:%2N", savedatatemp+8, savedatatemp+12, savedatatemp+16, savedatatemp+20
dd	0x0007,	"%5nF %s", savedatatemp+24, savedatatemp+28, dungeonnametable
savedatanosrc:	; 空きセーブデータ用
dd	0x0006,	"%1N:%s", savedatatemp, savedatatemp+28, dungeonnametable
dd	0x0001, 0
dd	0x0001, 0
entermenusrc:	; セーブデータサブメニュー用
dd	m_newgame,	0x000A,	"記録を作る"		/* 記録を作る。名前をつけて"最初から"状態にする。実行は続きからを選ぶようにする。 */
dd	m_loadgame,	0x000C,	"冒険を始める"		/* 記録を再開する。新規作成後のプレイもこれを選択する。 */
dd	m_leavegame,	0x000A,	"あきらめる"		/* 冒険を中止して、家の中(仮)に戻る。その際、アイテムやお金などはほぼ無くなる予定。 */
dd	m_datadelete,	0x000A,	"記録を消す"		/* 一度作成したファイルは初期化されるだけで、消されない。 */
//dd	m_filedelete,	0x000A,	"ファイルを消す"
dd	m_datacopy,	0x000E,	"記録をコピーする"	/* 空き場所を検索できれば簡単に実現できる。それとも上書きOKにしちゃうかw */
dd	m_dataname,	0x000C,	"名前を変える"		/* 記録のプレイヤー名を無条件に変える。ランキングには影響しない。 */
dd	m_datareview,	0x000A,	"冒険を見る"		/* 対応の予定は無し。実現できそうな感じは無くはないけど…。 */
dd	0x0000,		0x0000
configmenusrc:
dd	m_config2,	0x000F,	">設定サイズ:%nx%n", ScreenSize, ScreenSize+4
dd	m_config2,	0x000F,	"<現行サイズ:%nx%n", winsizex, winsizey
dd	m_config1,	0x000B,	"画面フィルタ:%s", scopyvalue, scopynames
dd	m_config3,	0x000B,	"ウィンドウ枠:%s", usewindow, inusenames
dd	m_config4,	0x000B,	"文字描画:%s", propttemp, proptnames
dd	m_config5,	0x0009,	"半透明:%s", fasthalf, fasthalfnames
dd	m_config6,	0x0008,	"パッド:%s", UsePadFlags, userpadnames
dd	m_config7,	0x000C,	"パッドコネクタ:%s", UsePadFlags+4, userpadpnames
dd	m_config_back,	0x0010,	"以前の設定に戻す"
dd	0x0000,		0x0000
;/* 以下のサブルーチンはメニューから呼ばれて処理する。
; * ・EAXに特定の数値を入れて呼び出される。
; * ・メニュー初期化時にも呼ばれ、メニューに追加できるか判断する必要がある。
; */
gamemenusrc:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	m_itemmenu,	0x0083,	0x0004,	"アイテム"
dd	m_mapmenu,	0x0082,	0x0004,	"設定"
dd	m_nextmenu,	0x0081,	0x0004,	"階段"
dd	0,		0x0080,	0x0004,	"中断"
dd	m_help,		0x0000,	0x0004,	"説明"
dd	-1,		0x0000,	0x0000
mapmenusrc:
dd	am_dispchange,	0x0000,	0x000B,	"マップ表示:%s", amstyle_temp +0, doesnames
dd	am_dispchange,	0x0001,	0x000B,	"壁枠描画:%s", amstyle_temp +4, doesnames
dd	am_dispchange,	0x0002,	0x000B,	"道半透明:%s", amstyle_temp +8, doesnames
dd	am_dispsize,	0x0000,	0x0010,	"描画サイズ:%3nx%3n", MapperDot, MapperDot
dd	0,		0x0000,	0x0000
bgmmenusrc:
;dd	snd_bgmdevice,	0x0000,	0x0000,	"BGM音源:%s", bgmdevnum, devnametable
;dd	snd_sedevice,	0x0000,	0x0000,	"SE音源:%s", seqdevnum, devnametable
;dd	snd_bgmtimer,	0x0000,	0x0000,	"更新周波数:%3nHz", bgmsnd
; 簡易(手抜き)ヘルプメッセージ
helpmenusrc:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	1,		help_1,	0x0008,	"基本操作"
dd	1,		help_2, 0x000C,	"文字入力操作"
dd	1,		help_3,	0x0009,	"パッド操作"
dd	-1,		0x0000,	0x0004,	"戻る"
dd	-1,		0x0000,	0x0000
help_1:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	-1,		0x0000,	0x0010,	"<基本操作の説明>"
dd	-1,		0x0000,	0x0011,	" ↑↓←→キー:移動"
dd	-1,		0x0000,	0x0014,	" CTRL+↑↓←→:ダッシュ"
dd	-1,		0x0000,	0x0018,	" SHIFT+↑↓←→:方向転換"
dd	-1,		0x0000,	0x0011,	" ENTER:決定 攻撃"
dd	-1,		0x0000,	0x0011,	" CTRL:キャンセル"
dd	-1,		0x0000,	0x0013,	" BS:キャンセル マップ表示"
dd	-1,		0x0000,	0x0017,	" CTRLチョイ押し:メニューを開く"
dd	-1,		0x0000,	0x0016,	" SHIFTチョイ押し:方向転換"
dd	-1,		0x0000,	0x0018,	" 中断:メニュー開き中断を選択"
dd	-1,		0x0000,	0x0000
help_2:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	-1,		0x0000,	0x0014,	"<文字入力操作の説明>"
dd	-1,		0x0000,	0x0015,	" ↑↓←→キー:カーソル移動"
dd	-1,		0x0000,	0x0011,	" ENTER:入力 決定"
dd	-1,		0x0000,	0x0011,	" CTRL:キャンセル 戻る"
dd	-1,		0x0000,	0x0015,	" HOME:挿入位置を左へ"
dd	-1,		0x0000,	0x0015,	" END :挿入位置を右へ"
dd	-1,		0x0000,	0x000D,	" その他:未定"
dd	-1,		0x0000,	0x0000
help_3:
dd	0x0000,	0x0000,	0x0000,	0x0000
dd	-1,		0x0000,	0x0011,	"<パッド操作の説明>"
dd	-1,		0x0000,	0x0016,	" ↑↓←→キー: カーソル/移動"
dd	-1,		0x0000,	0x0017,	" RUNボタン+移動: 向き変更"
dd	-1,		0x0000,	0x0017,	" Bボタン+移動キー: 高速移動"
dd	-1,		0x0000,	0x0011,	" Aボタン: 決定/選択"
dd	-1,		0x0000,	0x0012,	" Bボタン: キャンセル/戻る"
dd	-1,		0x0000,	0x0015,	" SELECTボタン: マップ画面"
dd	-1,		0x0000,	0x0000
; "%n"の場合:パラメータが指定するアドレスに直接数値が入る。
; "%s"の場合:パラメータが指定するアドレスには文字列へのポインタが入る。
dungeonmapstable: dd	8, 0, 0, .02, .03, .04, .05, .06, custommazedata, 0
/* フロア単位のダンジョンのサイズ */
dungeonmapskip	equ	16
.02:	; やさしい迷路
;	StFloor,EdFloor,Width,	Height,	
dd	1,	4,	25,	15
dd	5,	9,	29,	21
dd	10,	10,	31,	31
dd	0,	0,	0,	0
.03:	; ふつうな迷路
dd	1,	4,	29,	29
dd	5,	19,	41,	31
dd	20,	24,	45,	41
dd	25,	25,	51,	39
dd	0,	0,	0,	0
.04:	; 少し広い迷路
dd	1,	19,	41,	31
dd	20,	39,	51,	39
dd	40,	49,	63,	47
dd	50,	50,	71,	51
dd	0,	0,	0,	0
.05:	; かなり広い迷路
dd	1,	24,	63,	47
dd	25,	49,	95,	63
dd	50,	59,	127,	127
dd	60,	60,	255,	255
dd	0,	0,	0,	0
.06:	; おまけダンジョン
dd	1,	3,	15,	15
dd	4,	6,	25,	25
dd	7,	9,	31,	31
dd	10,	14,	41,	41
dd	15,	19,	51,	51
dd	20,	24,	61,	61
dd	25,	29,	71,	71
dd	30,	34,	81,	81
dd	35,	39,	91,	91
dd	40,	44,	101,	101
dd	45,	49,	111,	111
dd	50,	52,	121,	121
dd	53,	54,	127,	127
dd	55,	59,	143,	143
dd	60,	69,	159,	159
dd	70,	79,	175,	175
dd	80,	89,	191,	191
dd	90,	99,	223,	223
dd	100,	100,	255,	255
dd	0,	0,	0,	0
DunShortNames:	dd	8, .00, .01, .02, .03, .04, .05, .06, .07, 0
.00:	dd	0x000A,	"データ無し"
.01:	dd	0x000A,	"休憩所    "
.02:	dd	0x000A,	"やさしい  "
.03:	dd	0x000A,	"ふつう    "
.04:	dd	0x000A,	"むずかしい"
.05:	dd	0x000A,	"もっと広い"
.06:	dd	0x000A,	"おまけ    "
.07:	dd	0x000A,	"OSASK v4.8"
dungeonnametable: dd	8, .00, .01, .02, .03, .04, .05, .06, .07, 0
.00:	dd	0x0012,	"データがありません"
.01:	dd	0x0006,	"休憩所"	// ダンジョンにいない状態
.02:	dd	0x000C,	"やさしい迷路"
.03:	dd	0x000C,	"ふつうな迷路"
.04:	dd	0x000C,	"少し広い迷路"
.05:	dd	0x000E,	"かなり広い迷路"
.06:	dd	0x000D,	"おまけダンジョン"
.07:	dd	0x000C,	"カスタム迷路"
inusenames:	dd	3, .00, .01, .02, 0
.01:	dd	0x0004,	"有り"
.02:	dd	0x0004,	"無し"
.00:	dd	0x0004,	"自動"
donotnames:	dd	2, .00, .01, 0
.00:	dd	0x0004,	"する"
.01:	dd	0x0006,	"しない"
doesnames:	dd	2, .00, .01, 0
.00:	dd	0x0006,	"しない"
.01:	dd	0x0004,	"する"
scopynames:	dd	6, .00, .02, .03, .04, .05, .06, 0
.00:	dd	0x0006,	"デフォルト"
.01:	dd	0x0008,	"粗い拡大"
.02:	dd	0x000B,	"インタレース拡大1"
.03:	dd	0x000B,	"インタレース拡大2"
.04:	dd	0x000B,	"スキャンライン拡大"
.05:	dd	0x000D,	"ダブルスキャン拡大"
.06:	dd	0x000C,	"きっちり拡大"
scopytable:	dd	stretch_dbscan	; 標準
dd	stretch_inter1, stretch_inter2, stretch_scanli
dd	stretch_dbscan, stretch_normal, 0
proptnames:	dd	4, .00, .01, .02, .03, /*.04, .05, /*//*.06, .07, /**/0
.00:	dd	0x0008,	"シンプル"	//  8x16, 16x16
.01:	dd	0x0006,	"影付き"	//  8x16, 16x16
.02:	dd	0x0008,	"高さ半分"	//  8x 8, 16x 8
.03:	dd	0x000A,	"影付き半高"	//  8x 8, 16x 8
/*.04:	dd	0x0004,	"幅倍"		// 16x16, 32x16
.05:	dd	0x000A,	"影付き倍幅"	// 16x16, 32x16
.06:	dd	0x0004,	"16x8"		// 16x 8, 32x 8
.07:	dd	0x0004,	"影付16x8"	// 16x 8, 32x 8
*/
fasthalfnames:	dd	2, .00, .01, 0
.00:	dd	0x0004,	"交互"
.01:	dd	0x0004,	"固定"
userpadnames:	dd	3, .00, .01, .02, .05, 0
.00:	dd	0x000A,	"使用しない"
.01:	dd	0x000F,	"TOWNS2ボタンパッド"
.02:	dd	0x0010,	"PC98MSX互換パッド"
.05:	dd	0x000F,	"TOWNS6ボタンパッド"
userpadpnames:	dd	2, .00, .01, 0
.00:	dd	0x0006,	"左ポート"	/* FM TOWNS以外では"PortA"や"Port2"などの方がいいだろう */
.01:	dd	0x0006,	"右ポート"	/* USBポート番号を指定するのにも使うかもしれない?(それだと2ポートじゃ足らないねぇ) */
userpadtable:
dd	0		/* 使用しない */
dd	TownsPadInput2	/* FM TOWNS 2ボタンパッド */
dd	PC98PadInput	/* PC98 音源ボード接続MSX互換パッド */
dd	TownsPadInput6	/* FM TOWNS 6ボタンパッド */
pageofstable:	dd	7, .00, .01, .02, .03, .04, .05, .06, 0
.00:	dd	"あいうえおかきくけこ"	/* ひらがな */
	dd	"さしすせそたちつてと"
	dd	"なにぬねのはひふへほ"
	dd	"まみむめもやゆよをん"
	dd	"らりるれろわ   ー"
	dd	"ぁぃぅぇぉゃゅょっゎ"
	dd	"ゕゖ   ゐゑゔ  "
	dd	"がぎぐげご"
	dd	"ざじずぜぞだぢづでど"
	dd	"ばびぶべぼぱぴぷぺぽ"
	dd	0
.01:	dd	"アイウエオカキクケコ"	/* カタカナ */
	dd	"サシスセソタチツテト"
	dd	"ナニヌネノハヒフエホ"
	dd	"マミムメモヤユヨヲン"
	dd	"ラリルレロワ   ー"
	dd	"ァィゥェォャュョッヮ"
	dd	"ヵヶヰヱヴ  "
	dd	"ガギグゲゴ"
	dd	"ザジズゼゾダヂヅデド"
	dd	"バビブベボパピプペポ"
	dd	"ア イ ウ エ オ カ キ ク ケ コ "
	dd	"サ シ ス セ ソ タ チ ツ テ ト "
	dd	"ナ ニ ヌ ネ ノ ハ ヒ フ ヘ ホ "
	dd	"マ ミ ム メ モ ヤ ユ ヨ ヲ ン "
	dd	"ラ リ ル レ ロ ワ ゙ ゚   ー "
	dd	"ァ ィ ゥ ェ ォ ャ ュ ョ ッ ` "
	dd	0
.02:	dd	"0123456789"	/* 英数字/記号 */
	dd	"ABCDEFGHIJ"
	dd	"KLMNOPQRST"
	dd	"UVWXYZ    "
	dd	"abcdefghij"
	dd	"klmnopqrst"
	dd	"uvwxyz    "
	dd	"、。‐.,・:;?!"
	dd	"_― ̄~…%※/\♪"
	dd	"♂♀☆★+-±×÷="
	dd	"(){}○¥「」『』"
	dd	"←→↑↓◇◁▷△▽@"
	dd	0
.03:	dd	"0 1 2 3 4 5 6 7 8 9 "	/* 半角記号 */
	dd	"A B C D E F G H I J "
	dd	"K L M N O P Q R S T "
	dd	"U V W X Y Z         "
	dd	"a b c d e f g h i j "
	dd	"k l m n o p q r s t "
	dd	"u v w x y z         "
	dd	"、 。 ー . , ・ : ; ? ! "
	dd	"_ | ~ [ ] % * / # ' "
	dd	"# $ &     + - < > = "
	dd	"^ ` { }   \ 「 」   @ "
	dd	0

.04:	dd	"アイウエオカキクケコ"	/* カタカナ */
	dd	"サシスセソタチツテト"
	dd	"ナニヌネノハヒフエホ"
	dd	"マミムメモヤユヨ  "
	dd	"ラリルレロワ    "
	dd	0
.05:	dd	"あいうえおかきくけこ"	/* ひらがな */
	dd	"さしすせそたちつてと"
	dd	"なにぬねのはひふへほ"
	dd	"まみむめもやゆよ  "
	dd	"らりるれろわ    "
	dd	0
.06:	dd	"①②③④⑤⑥⑦⑧⑨⑩"	/* 一時的な画数指定用 */
	dd	"⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳"
	dd	"㉑㉒", 0 /* "㉓㉔㉕㉖㉗㉘㉙㉚"
	dd	"㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵"
	dd	"㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿"
	dd	0	*/
kanjichi:	dd	48
#define	CVK(High, Low)	(High-1)*94 + Low-1
	dd	CVK(16, 1), CVK(16,42), CVK(17, 6), CVK(17,33), CVK(17,87)//あ
	dd	CVK(18,28), CVK(20,75), CVK(22,69), CVK(23,21), CVK(24,35)//か
	dd	CVK(26,19), CVK(27,37), CVK(31,58), CVK(32, 4), CVK(33,25)//さ
	dd	CVK(34,30), CVK(35,45), CVK(36,37), CVK(36,66), CVK(37,38)//た
	dd	CVK(38,64), CVK(38,83), CVK(39, 8), CVK(39, 9), CVK(39,21)//な
	dd	CVK(39,35), CVK(40,59), CVK(41,52), CVK(42,26), CVK(42,61)//は
	dd	CVK(43,64), CVK(44, 3), CVK(44,19), CVK(44,29), CVK(44,46)//ま
	dd	CVK(44,73), CVK(44,91),	CVK(45,29), CVK(45,69), 0	  //や
	dd	CVK(45,69), CVK(45,88), CVK(46,60), CVK(46,65), CVK(47, 4)//ら
	dd	CVK(47,33), CVK(47,51), 0, 0, 0		//わ
kanjijpn:	dd	48	/* 音読み・訓読み存在フラグとしても使用 */
	dd	 .a,  .i,  .u,  .e,  .o
	dd	.ka, .ki, .ku, .ke, .ko
	dd	.sa, .si, .su, .se, .so
	dd	.ta, .ti, .tu, .te, .to
	dd	.na, .ni, .nu, .ne, .no
	dd	.ha, .hi, .hu, .he, .ho
	dd	.ma, .mi, .mu, .me, .mo
	dd	.ya, .yu, .yo,   0,   0
	dd	.ra, .ri, .ru, .re, .ro
	dd	.wa,   0,   0,   0,   0
.a:	dw	"上会充合在当有明空荒"
	dw	"悪開相間青赤紅銅呆章"
	dw	"晶照輝祥朗朱朝浅麻字"
	dw	"足畔遊与辺従温頭新厚"
	dw	"集純穴孔兄姉暴危油天"
	dw	"甘文礼紋彩怪歩非嵐争"
	dw	"現主哀淡", 0
.i:	dw	"入井出生行忌言容居要"
	dw	"家怒厳勢征戦池勇功石"
	dw	"泉至板徒格市五慈糸愛"
	dw	"犬祈命今未戒卑色彩岩"
	dw	"祝", 0
.u:	dw	"打生得植討享憂上魚牛"
	dw	"氏歌内映美馬巧海恨怨"
	dw	"占愁", 0
.e:	dw	"重得笑栄伯偉豪", 0
.o:	dw	"士央尾終居落雄老押郎"
	dw	"緒及扇皇大巨太王公犯"
	dw	"丘陸沖翁奥怒厳行長修"
	dw	"治幼教恐夫乙音踊弟男"
	dw	"同想阿親凡俺愚女驚", 0
.ka:	dw	"代交彼変狩香飼勝克掛"
	dw	"貝反輝鉤影景重賢頭数"
	dw	"量稼風方片形敵象刀曽"
	dw	"角門金悲哀要必鐘兜神"
	dw	"雷空辛鳥体仮軽川革河"
	dw	"冠", 0
.ki:	dw	"切木利来決黄極樹妃岸"
	dw	"築北衣甲牙厳仁君清聖"
	dw	"刑究", 0
.ku:	dw	"奇組来茎草腐種鎖串薬"
	dw	"砕口国与雲比暗蔵位狂"
	dw	"車紅黒玄鉄加", 0
.ke:	dw	"毛獣険", 0
.ko:	dw	"子小込児超越娘恋神河"
	dw	"凍氷心志快言琴寿理好"
	dw	"細維殺衣恐壊", 0
.sa:	dw	"下冷咲覚茶幸栄盛魚雀"
	dw	"叫酒定聖悟智了真寂侍"
	dw	"沢", 0
.si:	dw	"占死知強幸塩鹿屍茂繁"
	dw	"静下親科忍芝渋島僕白"
	dw	"尻記印城銀", 0
.su:	dw	"好住直巣済州統磨澄末"
	dw	"季杉少優勝卓介助資健"
	dw	"筋進奨雀砂全術鋭", 0
.se:	dw	"攻零", 0
.so:	dw	"反殺沿育外供苑仙空", 0
.ta:	dw	"田立足建経出平高宝財"
	dw	"巧工丈健武剛猛岳竹助"
	dw	"正直唯忠達竜龍貴谷種"
	dw	"楽頼玉珠球魂霊卵民保"
	dw	"樽", 0
.ti:	dw	"千血小近親力父秩", 0
.tu:	dw	"連終築番司月作造創伝"
	dw	"土統慎鼓努務勉集綱角"
	dw	"翼局罪爪冷剛強壮面辛"
	dw	"貫兵", 0
.te:	dw	"手照出輝", 0
.to:	dw	"戸飛富研任貴遠享時処"
	dw	"所年殿弔友共伴朝那供"
	dw	"智豊囚虎鳥泥", 0
.na:	dw	"名成無直治中仲永長流"
	dw	"和等何鈍凡浪涙均也業", 0
.ni:	dw	"荷新西鈍庭", 0
.nu:	dw	"貫温主布沼", 0
.ne:	dw	"音根猫狙", 0
.no:	dw	"乗野延望希宣則信喜登"
	dw	"昇式法師教紀範規記呪", 0
.ha:	dw	"刃羽果映晴葉栄恥歯化"
	dw	"場灰計量博鋼育烈運箱"
	dw	"初始一柱蓮外勢旗蜂花"
	dw	"華甚英母婆侍浜早林原"
	dw	"針治", 0
.hi:	dw	"日火氷冷秘陽秀光東久"
	dw	"聖左羊英一人独等均瞳"
	dw	"丁平開閃広洋裕博", 0
.hu:	dw	"吹増伏老笛深袋房防双"
	dw	"二札豚淵太船文史冬古", 0
.he:	dw	"経可紅蛇", 0
.ho:	dw	"誉賞葬朗星細骨炎洞堀"
	dw	"滅", 0
.ma:	dw	"巻真間増舞益参前任牧"
	dw	"正将優勝政交呪斗叉町"
	dw	"街祭全的愛学眼幻守護"
	dw	"衛迷丸円希周", 0
.mi:	dw	"三己充見実磨帝右巫水"
	dw	"湖自乱道皆港南源宮都", 0
.mu:	dw	"六向骸虫結娘宗村紫室", 0
.me:	dw	"女目眼恵", 0
.mo:	dw	"持若母盛用望最玩下元"
	dw	"本基物者百守森両師", 0
.ya:	dw	"矢家屋谷刃宅優社康安"
	dw	"休奴宿敗破山闇槍和柔", 0
.yu:	dw	"行結維夕紫雪豊弓夢", 0
.yo:	dw	"世良喜夜依横邪由吉義"
	dw	"蘇頼鎧喜万", 0
.ra:	dw	"等", 0
.ri:	dw	"令霊", 0
.ru:	dw	0
.re:	dw	0
.ro:	dw	0
.wa:	dw	"我判若弁業災渡私航笑"
	dw	"悪", 0
.end:	dw	-1
	alignb	4
kanjilines:	dd	22
dd	.01, .02, .03, .04, .05
dd	.06, .07, .08, .09, .10
dd	.11, .12, .13, .14, .15
dd	.16, .17, .18, .19, .20
dd	.21, .22,   0,   0,   0
dd	  0,   0,   0,   0,   0
dd	  0,   0,   0
/* 結構間違っているような気がするが、そのまま。 */
/* かなり少ないけど、気にしない。 */
.01:	dw	"一乙", 0
.02:	dw	"丁了人入刀力十二", 0
.03:	dw	"下三上丈万与久丸也凡刃千叉土士夕大女子小山川工己弓々口及才", 0
.04:	dw	"不中五井介今仁内元公六円凶切化巨厄双反友太天少幻心戸手文斗方日月木比毛水火爪父片牛犬王牙込辺区夫氏弔孔", 0
.05:	dw	"犯丘世主仙代令史司台右因冬外央奴尻左市布平幼広必打旧札本末未正民永氷玉甘生用田甲由白目矢石礼穴立玄母巧迅弁", 0
.06:	dw	"両争交仮会全伝光充共刑印危吉叫向合同名団在地壮好安守年式当成早有死気灰糸羊羽肉自至色虫血行邦芝任休朱百池", 0
.07:	dw	"我赤良串乱亜位何作住体伯伴児兵冷初判利助努吹呆妖完対局尾巫希形忌志快戒攻杉来決狂男花見角言足防条町谷芸弟辛克沖忍社坊沙卵臣村", 0
.08:	dw	"油奇周呪命国実宝定岩府彼所斧昇明果東武歩毒泥法炎物的直知祈空者英邪金長門阿非青沼迷居和茂林岸玩沿季岳夜若茎始押姉治板郎刹供狙奈宗育忠学参征虎牧幸享卓径延房侍依河苑", 0
.09:	dw	"屍城独乗信保前南厚咲変封巻律怒持映星柱泉海洞狩界相砂祝神紅美草計軍重面革音風飛香荒屋洋造建紀室侯浅柔勇哀派要砕思連卑恨栄宣皆孤則皇帝研政怨幽甚科茶冠", 0
.10:	dw	"秩家進倍冥凍剛容将島師修恐恵恋扇時格核根殺流涙烈珠疾真秘紋財酒閃馬骨高鬼破原部都竜庭宮純畔針記俺討笑悟陣娘荷勉翁畜祥浪恥党益華浜航烏徒朗陛", 0
.11:	dw	"祭健康敗組唯兜宿巣強得悪教族望済深清猫猛球現理眼章笛経術袋陸魚鳥黄黒険終雪運道遊堀務野船達密蛇規貫悠渋第寂基淡彩細脳豚偵婆鹿盛曽麻雀掛紺堂", 0
.12:	dw	"登港街偉善場奥嵐悲最晶晴森温湖無琴等結統葬葉落蛮象超軽開間陽集雄雲番搭朝植創渡貴蓮量覚越勝淵富裕援鈍博遠喜隊筋歯紫景斐智", 0
.13:	dw	"極勢夢愛慈戦数暗楽殿漢源漠滅照福義聖鉄雷鼓飼賊資続禁電新誉愚豊奨想業罪蜂愁塩裔零慎盟鉤", 0
.14:	dw	"増槍歌獄種精豪踊銀銃魂銅蜜静旗綱腐緒僕察歴罰維", 0
.15:	dw	"権影敵範舞蔵輝鋭霊澄箱魅賞稼暴横憂", 0
.16:	dw	"骸築壊樹獣磨薬賢頭龍樽鋼頼繁隷親衛", 0
.17:	dw	"翼闇優瞳厳", 0
.18:	dw	"鎧騎鎖", 0
.19:	dw	"羅覇蘇", 0
.20:	dw	"護鐘", 0
.21:	dw	"魔", 0
.22:	dw	"驚", 0
.end:	dw	-1
	alignb	4
displaytable:	; 解像度変更テーブル/*/;なんとなく/*/
//dd	192, 168	/*/; 3/4倍 /*/
//dd	240, 160	/*/; GBA /*/
//dd	256, 192	/*/; QQXGA /*/
dd	VGXSIZE, VGYSIZE
dd	(VGXSIZE*3)>>1,(VGYSIZE*3)>>1
dd	VGXSIZE<<1, VGYSIZE<<1
dd	256, 224	/*/; 等倍 /*/
dd	256, 448	/*/; 縦2倍 /*/
dd	320, 224	/*/; QVGA-/*/
dd	320, 240	/*/; QVGA /*/
dd	320, 256
dd	320, 400	/*/; 変則的解像度 /*/
dd	320, 448	/*/; 変則的解像度 /*/
dd	320, 480	/*/; 変則的解像度 /*/
dd	384, 336	/*/; 1.5倍 /*/
dd	480, 320	/*/; GBAx2 /*/
dd	480, 448	/*/; SVHS/SVCD相当 /*/
dd	480, 480	/*/; SVHS/SVCD /*/
dd	512, 224	/*/; 横2倍 /*/
dd	512, 240
dd	512, 256
dd	512, 384	/*/; QXGA /*/
dd	512, 448	/*/; 2倍 /*/
dd	640, 224	/*/; 変則的解像度 /*/
dd	640, 350	/*/; PCAT /*/
dd	640, 400	/*/; PC98 /*/
dd	640, 448	/*/; 推奨 /*/
dd	640, 480	/*/; VGA /*/
dd	640, 512
dd	720, 448	/*/; NTSC /*/
dd	720, 480	/*/; BTSC /*/
dd	720, 576	/*/; PAL /*/
dd	768, 448	/*/; TOWNS /*/
dd	768, 512	/*/; TOWNS /*/
dd	768, 672	/*/; 3倍 /*/
dd	800, 600	/*/; SVGA? /*/
dd	1024, 448	/*/; 変則的解像度 /*/
dd	1024, 512	/*/; TOWNS仮想解像度 /*/
dd	1024, 768	/*/; XGA /*/
dd	1152, 864	/*/; XGA+? /*/
/*// フルスクリーンモードは最低限640x480には対応しているので
  // その解像度まで拡大できるようにしておくべきだろう。
  // OSASKが画面拡大縮小に対応すればそれに丸投げできる。
  // (半透明ディザが16色のままでは粗くなってしまうだろうけど。)
//*/
displaytableend:
displaytablesize	equ	(displaytableend - displaytable)
MapperColorInit:	; マップ表示色初期化用
db	0xFF,0xFF,0x8E,0x0E,0x84,0x00,0x80,0x0F
db	0x0B,0x03,0x0E,0x09,0xFF,0xFF,0xFF,0xFF
; キーパッドエミュレーション用デフォルトキー設定
keypad_emutable:
KeyPadTableInit	dd	AR_UP, AR_DOWN, AR_LEFT, AR_RIGHT
		dd	KY_SHIFT, KY_BS, KY_ENTER, KY_CTRL
		dd	0, 0, 0, 0, 0, 0, 0, 0
/*
keypad_emutable	dd	KY_UP, KY_DOWN, KY_LEFT, KY_RIGHT
		dd	KY_SPACE, KY_CTRL, KY_ENTER, KY_BS
		dd	KY_SHIFT, KY_ESC, 0, 0, 0, 0, 0, 0
*/
; 以下使用するAPI群
us_setbgmtimer	dd	0x78, 0x01, BGM_SLOT
dd	0x78, 0x12, BGM_SLOT, 0, 0, 0, 0x0000
//us_settimer	dd	0x78, 0x20, TIMER_SLOT, 0x0000
us_getbgmtimer	dd	0x78, 0x82, TIMER_SLOT, BGM_SLOT, 0, 0, 0, 0x0000
us_settimer	dd	0x78, 0x81, BGM_SLOT, TIMER_SLOT, 0, 0, 0, 0x0000
us_line		dd	0x54, 0x0000, gbox, 00, 00, 00, 00, 00, 0
us_redraw	dd	0x58, 0x4001, gbox, 0, 0, 00, 00	; 全領域用
us_redraw_2	dd	0x58, 0x4001, gbox, 0, 0, 00, 00	; 全領域用
us_redraw_3	dd	0x58, 0x4001, gbox, 0, 0, 00, 00, 0	; 全領域用
us_redraw_line	dd	0x58, 0x4001, gbox, 0, 0, 00, 1, 0	; 1ライン用
us_sjisdecode	dd	0xEC, 0x0001, 00, 00, 15, sjistemp, 15, 0x4e00, 0x400, 0x0000
us_print	dd	0x114,0x5100, vram_font, 15, (VGXSIZE<<8)|0xFF, 1, 0, 0xC0, 0, 8, sjistemp, 0x00F, 0x0000
api_sleep	dd	0x18, 0x0001, 0, 0, 0
us_waitsignal	dd	0x18, 0x0000, 0, 0, 0
us_ret		dd	0x18, 0x0080, 0, 1, 0
us_sti		dd	0x18, 0x0000, 0, 1, 0
us_cli		dd	0x18, 0x0000, 0,-1, 0
us_libclose	dd	0x08, 0, 0
us_maxwinsize	dd	0x14, 0x10, win_maxsize, 0x00F, 0
us_newselector	dd	0xF0, 0x0000 /* opt */, 0x0200 /* sel */, 0xC0FA /* ar */, 00 /* limit */, 00, 0x08 /* source */, 0x0000
us_windowclose	dd	0x24, 0x0000, window, 0x0000
us_windowctrl	dd	0x3C, 0x0000, window, 0x0000
us_windowopen:
dd	0x20, window, WINDOW_SLOT|1|2, 00, 00, 0x3301, SIG_WINDOW, 0, 0
us_windowtitle1:
dd	0x28, 0x1000, wtitle, 0, WINDOWTITLELEN, 1, 0, 0, window, 0xC0, 0
us_windowtitle2:
dd	0x40, 0x1000, 0, 0, wtitle, 7, 0, 0, WINDOWTITLELEN, WINDOWTITLE
us_windowgbox:
dd	0x30, 0x9001, gbox, 0x01, 0x08, 00, 00, 0, 0, window
dd	0x68, 0, 0x200, 0x12|MO_LEVEL, window, 1, MO_MOVE, 0
dd	0x68, 0, 0x200, 0x20|MO_LEVEL, window, 1, MO_LEFT, 0
dd	0x68, 0, 0x200, 0x30|MO_LEVEL, window, 1, MO__LEFT, 0
dd	0x68, 0, 0x200, 0x21|MO_LEVEL, window, 1, MO_RIGHT, 0
dd	0x68, 0, 0x200, 0x31|MO_LEVEL, window, 1, MO__RIGHT, 0
dd	0x68, 0, 0x200, 0x22|MO_LEVEL, window, 1, MO_CENTER, 0
dd	0x68, 0, 0x200, 0x32|MO_LEVEL, window, 1, MO__CENTER, 0
dd 0x68,KY_RAWS, 0x100, 0x1000|KY_RAW, window, 1, KY_RAW, 0
dd 0x68,KY_RAWS, 0x100, 0x5000|KY_RAW, window, 1, KY_RELEASE|KY_RAW, 0
dd	0x68, 0, 0x100, 0x1020, window, 1, KY_SPACE, 0
dd	0x68, 0, 0x100, 0x5020, window, 1, KY_RELEASE|KY_SPACE, 0
dd	0x68,127,0x100, 0x1080, window, 1, 0x80, 0
dd	0x68,127,0x100, 0x2080, window, 1, 0x80, 0
dd	0x68,127,0x100, 0x5080, window, 1, KY_RELEASE|0x80, 0
dd	0x68,127,0x100, 0x6080, window, 1, KY_RELEASE|0x80, 0
dd	0x68, 0, 0, 0, 0, 0, 0
dd	0x00
init:
dd	0x04, work
dd	0x60, SIGBUFFERSIZE, signalbuffer, 0, REWIND
dd	0x10, SignalHandler, 7
getrandseed:
dd	0x118, 0, 0
dd	0x70, TIMER_SLOT
dd	0x70, BGM_SLOT
dd	0x80, BEEP_SLOT, 0
dd	0x68, 0, 0x010, TIMER_SLOT, 0, 1, SIG_TIMER, 0
dd	0x68, 0, 0x010, BGM_SLOT, 0, 1, SIG_BGM, 0
dd	0x68, 0, 0, 0, 0, 0, 0
dd	0x00
_loadfont1:
dd	0xE0, 0xC0FFFFFF, 0, 1, SIG_NOERROR+ 0x00, 0x00
_loadfont2:
dd	0xE0, 1, USFONT_SLOT, 0x80, userfont, 0x000F
dd	0xE8, 0, FONT_SLOT+0x00, USFONT_SLOT, 0x060, 0, 0x0080
dd	0xE8, 0, FONT_SLOT+0x10, 0x21, 0x01000000, 0, 0
dd	0xE8, 0, FONT_SLOT+0x50, 0, 0, 0, 0
dd	0x00
_filelocalopen:
dd	0xA0, 12, FILE_SLOT
dd	0xAC, 0, FILE_SLOT, _sbend -_sbcmd, _sbcmd, 0x000F, 0x00
_sbcmd:	dd	-0xFD, 12
_filename:	resb	12
dd	-0xFE, 2, 0x7F000001, SIG_NOERROR+0x10, 0
_sbend:
_filesize:	dd	0xC8, -0xFD, FILE_SLOT, 16, filesize, 0x00F, 0x00
_filesetmapper:	dd	0xC0, 0, FILE_SLOT, 260*1024, 00, 0x00F, 5, 0x00
_fileunmapper:	dd	0xC4, 0, 00, 00, 0x00F, 0x00
_fileresize:	dd	0x120,0, FILE_SLOT, 00, 1, SIG_NOERROR+0x20, 0x00, 0
//#include "userfonts.h"
userfont:
#include "bgmdata.nak"
[SECTION .bss]
		alignb	8
signalbuffer	resb	SIGBUFFERSIZE
sig_ptr		resd	1
ReturnSignal	resd	2 ; 最大8つの平行処理可能 (b4:flag,b3-b0:code)
sjistemp	resd	61
cnvftemp	resd	16
RetSigJump	resd	8
RetSigSlot	resd	8
BGM_WORK	resb	BGM_WORK_SIZE
work		resb	256
window		resb	128
wtitle		resb	64 + 256*8
BGM_BGM		resd	BGM_DEVICE_SIZE>>2
BGM_SEQ		resd	BGM_DEVICE_SIZE>>2
oam_index	resb	8 * OAM_DSP_MAX	; スプライト表示
oam_puttern	resb	4 * OAM_PTN_MAX	; スプライトパターン登録
oam_color	resb	16* OAM_PAL_MAX	; スプライトパレットテーブル
MapperPtnData	resd	(16*16) *32>>2	; マップ表示用パターン格納場所
putterntable1	resd	2048*2	; パターン用 (ポインタ,ライン幅)
tmpketa		resd	1
dungeonname	resd	7
savedatatemp	resd	16
savedatamenu	resd	128
entermenu	resd	128
//dugeonofstable	resd	128
settingmenu	resd	128
configmenu	resd	128
kanjichidata	resw	400
		alignb	8
filesize	resd	4
byteperline	resd	2
chara_anime	resd	1
toumei_flag	resd	1	; 透明ディザの反転フラグ

winposx		resd	1
winposy		resd	1
wincolor	resd	1
winsignal	resd	1
winsize:
winsizex	resd	1
winsizey	resd	1
startpoint	resd	2

fps_remain	resd	1
fps_flush	resd	1
fps_count	resd	1
time_sec	resd	1
time_temp	resd	4

time_tmp	resd	1
timer_count	resd	1
mobstatus	resd	1
keystatus	resd	1
printcolor	resd	4	; 色情報(文字色,影色,背景色)

keymatrix	resb	KY_ALL

townschk	resd	1	; 各機種チェック用
vsync_flags	resd	1
keypad_status	resd	1	; キーボードでパッド操作用
mospad_status	resd	1
mo_lastpress	resd	2
mo_tmppos	resd	2

mo_lpbutton	resd	1
mo_dushf	resd	1
temp_x		resd	1
temp_y		resd	1
screen_update	resd	1	; 各種更新フラグ(B0:BACK PMAP,B1:OAM,B2:FORE PMAP)
window_status	resd	1	; ウィンドウ制御情報
win_maxsize	resd	2

StretchXRate	resd	4
StretchYRate	resd	4

mmt_fileid	resd	4	; ファイルID&マップフラグ
mmt_fsize	resd	4	; ファイルサイズ
mmt_base	resd	4	; マップされたアドレスの先頭
mmt_limit	resd	4	; マップされたサイズ
mmt_writable	resd	4	; マップ属性(ファイル内ページ)
mmt_errcode	resd	4	; ファイルエラーコード

printflags	resd	1	; 文字修飾などの情報
printcache	resd	3	; 色変換キャッシュ(8bpp用)
printsize	resd	1	; フォント縦サイズ(=8 or 16)
printcall	resd	1	; 転送用
printbyteline	resd	1	; ライン幅
printbase	resd	1	; ベースアドレス

bgmdllversion	resd	1	; BGM.DLLのバージョン
bgmdllrevsion	resd	1	; BGM.DLLのりビジョン
puttern_offsetb	resd	2	; 動き検出用

screen_mode	resd	1	; スクリーンモード
addjobings	resd	1	; 残BG処理数
mazesize	resd	2	; 迷路マップサイズ
psize		resd	2	; パターンマップサイズ
puttern_offset	resd	2	; パターンマップ表示開始座標(下位4bit:パターン内部)

oamoffset	resd	4	; スプライトオフセット(ピクセル単位)

windowcache	resb	16	; 色変換用のデータ(16色)
palettetablebg	resb	16	; 背景用パレット変換
palettetablefg	resb	16	; 合成用パレット変換

reg32		resd	8
reg16		resd	7
debug_stack	resd	1

screen_copy	resd	1	; スクリーン拡大転送ルーチンへのポインタ(offset, ...))
redraw_init	resd	1	; 画面状態変更後の再初期化
flushlines_temp	resd	2	; 複数ライン描画用

name_strleft	resd	1	; 名前入力用
name_strtop	resd	1
name_strwidth	resd	1
name_strheight	resd	1
name_inpleft	resd	1
name_inptop	resd	1
name_inpwidth	resd	1
name_inpheight	resd	1

name_msgleft	resd	1
name_msgtop	resd	1
name_msgwidth	resd	1
name_msgheight	resd	1
name_maxlen	resd	1
name_strofs	resd	1
name_strloc	resd	1
name_stemp	resd	1

name_pagenum	resd	1
name_pagedata	resd	1
name_pageloc	resd	1
name_pagemax	resd	1
name_1stmsg	resd	1
name_2ndmsg	resd	1
name_sdivx	resd	1	; 文字間のピクセル数(マウス用)
name_sdivy	resd	1	

name_pageend	resd	1	; 選択エリアの文字数(マウス用)
name_sheight	resd	1	
name_sleft	resd	1	; 選択エリアの文字開始位置(マウス用)
name_stop	resd	1	
name_lcenter	resd	1	; X軸中心の空きエリア関係
name_mcenter	resd	1
name_rcenter	resd	1
name_cache	resd	1	; カーソルの位置の文字(SJIS)

menu_oldflag	resd	1
menu_oldmenu	resd	1
menu_oldleft	resd	1
menu_oldtop	resd	1

getlastkey	resd	16	; キーバッファ

getlastkeyread	resd	1
getlastkeywrite	resd	1
name_pageold	resd	1
nowsavenumber	resd	1	; セーブデータメモリにあるセーブデータの番号(0:更新しなくてよいか無効のデータ,1~3:データ1~3)
save_read	resd	1	; 読み込みポインタ
keypad_emu	resd	1	; キーパッド設定
oldpad_status	resd	1
padload_status	resd	1
padload_remain	resd	1

MapperLeft	resd	1	; マップ表示描画領域の左上の座標
MapperTop	resd	1
MapperWidth	resd	1	; マップ表示描画領域のサイズ
MapperHeight	resd	1
MapperOffset	resd	2	; マップ表示のスクロール用

rnk_NameLen	resd	4	; ランキングデータ表示用
rnk_Min		resd	1
rnk_Sec		resd	1
rnk_Num		resd	1
locate_anime	resd	1
rnk_DungeonNum	resd	1
rnk_PlayCnt	resd	1
rnk_Floors	resd	1
rnk_WalkCnt	resd	1
rnk_TotalTime	resd	1
MapperFlag	resd	1
rnk_Score	resd	1
rnk_CRC32	resd	1

winclosehandler	resd	2
bgmlibcall	resb	1
padbusy		resb	1
		alignb	8
IndexDataBegin:	; 共通データ情報(ランキングなど)構造体の定義
; 共通ヘッダ	32byte
PlyAppName	resb	8	; ASCIIZ
PlyAppVersion	resd	1	; バージョン(low16:Major,high16:Min)
PlyAppRevsion	resd	1	; サブバージョン
PlyProtect1	resd	1	; プロテクト情報
PlyProtect2	resd	1	; 
PlyHeaderSize	resd	1	; 予約
PlyDataCRC32	resd	1
; アプリケーションデータ
; セーブデータ共通の設定
ConfigCopyBegin:
ScreenSize	resd	2	; 表示画面のサイズ
UsePadFlags	resd	2	; 操作用のパッド設定
scopyvalue	resd	1	; 画面拡大転送
usewindow	resd	1	; ウィンドウ枠の有無(フルスクリーン用)
propttemp	resd	1	; 文字修飾などの情報
fasthalf	resd	1	; 半透明常時処理フラグ
dispresonum	resd	1	; 解像度番号

PlySndTimer	resd	1	; 周波数:μ秒単位(60Hz→60000000)
PlyBGMDevice	resd	1	; BGM/SEデバイスの設定
PlySEQDevice	resd	1
PlyBGMPort	resd	2	; BGM用FM/MIDI音源のポート(各ベースポート,データポート)
PlySEQPort	resd	2	; SE用FM/MIDI音源のポート
		resd	0
KeyPadTable	resd	16	; キーパッドエミュレーション用キー設定
ConfigCopyEnd:
ConfigCopySize	equ	ConfigCopyEnd - ConfigCopyBegin
; ランキングデータ	64byte/rank 
RankingData	resd	16*RANKDATA_MAX
IndexDataEnd:	resb	ConfigCopySize	; 「元に戻す」用
IndexDataSize	equ	IndexDataEnd-IndexDataBegin
		alignb	8
SaveDataBegin:	; セーブデータ本体構造体の定義	8KB
; ゲーム基本状態	32byte
SavAppName	resb	8	; アプリ名
SavAppVersion	resd	1	; バージョン
SavAppRevsion	resd	1	; サブバージョン
SavProtect1	resd	1	; プロテクト情報
SavProtect2	resd	1
SavHeaderSize	resd	1	; 本体情報へのポインタ(ヘッダサイズ)
SavDataCRC32	resd	1
; セーブデータ基本情報	160byte
SaveCopyBegin:
SavNameLen	resd	1	; プレイヤー名
SavPlayerName	resd	7	; 最大28バイト
SavDungeonNum	resd	1	; 挑戦中のダンジョン番号
SavDungeonOpt	resd	1	; ダンジョン進行度
SavToTime	resd	1	; プレイ時間(秒単位)
SavNwTime	resd	1
SavPlayCount	resd	1	; 挑戦回数
SavFloor	resd	3	; フロア情報
SavMapSize	resd	2	; ダンジョンサイズ
SavToWalkCount	resd	1	; 歩いた距離
SavNwWalkCount	resd	1

MapperDot	resd	1	; マップ表示のパターンサイズ
MapperStyle	resd	3	; マップ表示のスタイル設定
MapperColor	resd	4	; マップ表示色設定
/* reserved */	resd	13	; 拡張用
SavPadCount	resd	1	; ちょい押し検出用
save_write	resd	1	; 書き込みポインタ
SavRandSeed	resd	1	; 乱数種
SaveCopyEnd:
SaveCopySize	equ	SaveCopyEnd - SaveCopyBegin
; セーブデータ本体情報
SavDataArea	resd	(SAVEDATASIZE>>2)-52	; セーブデータエリア
SaveDataEnd:	
SaveDataSize	equ	SaveDataEnd-SaveDataBegin
//global		SavDataArea, signalbuffer
; Windows Bitmap File Header
_bfType		equ	0x00
_bfSize		equ	0x02
_bfOffBits	equ	0x0A
_biSize		equ	0x0E
_biWidth	equ	0x12
_biHeight	equ	0x16
_biPlanes	equ	0x1A
_biBitCount	equ	0x1C
_biCompression	equ	0x1E
_biSizeImage	equ	0x22
_biClrUsed	equ	0x2E
_biClrImportant	equ	0x32
_bmiColors	equ	0x36
; 合成モード使用時の複数レイアの合成の仕組み
;(矢印の方向はデータや命令等が移動する方向、参照方向ではない)
; ┌─────┐ 展開	┌─────────┐
; │背景レイア│←───┤パターンの展開処理│←パターンRAM
; └─┬───┘(オフ可)└─────────┘		の変更
;   │ 合成┌──────────┐	┌───┐
;   │┌──┤背景キャッシュレイア│←┤スプラ│
;   ││  └──────────┘	│イトの│←スプライトRAM
;  転││合成┌──────────┐	│展開 │	の変更(命令)
;  送││ ┌┤前景キャッシュレイア│←┤ 処理│
;   ││ │└──────────┘	└───┘
;   ││合│成┌──────┐ 描画	┌───────┐
;   ││┌┼─┤半透明レイア│←┬──┤ウィンドウ描画│←命令
;   ││││合└──────┘ │消	└──────┬┘
;優  ││││成┌─────┐  ↓去	┌────┐ │
;先  ││││┌┤透明レイア│←────┤文字描画│←┘
;度: │││││└─────┘	 描画	└────┘←命令
; (低)↓↓↓↓↓(高)
; ┌──────┐ 転送	┌──────┐  _______
; │画面合成処理├──→│VRAMバッファ├→│OSが画面更新│
; └──────┘	└──────┘   ̄ ̄ ̄ ̄ ̄ ̄ ̄
; スプレイトの同期レイア
; ・画面上の座標:連動無し。常に画面上では同じ位置に表示される。スプライトVRAMオフセット値変更なども影響を受けない。(→主人公など)
; ・背景パターン連動:背景のスクロールに連動してスクロールするスプライト。(→階段やアイテム、敵キャラクタなど)
; ・独立スプライト空間連動1(通常):独立してスクロールできるスプライト。(→多重スクロール用など)
; ・独立スプライト空間連動2:独立してスクロールできるスプライト。(→多重スクロール用など)
; ・透明レイアの拡大時に専用の補完フィルタを通す様にすれば文字をきれいにできそう

;   ・でも、描画時に補完して描画した方が速いだろう。
;   ・その場合は透明レイアが表示サイズ必要になってしまう。
; ・半透明レイアは補完しなくてもいいだろう。
; ・前景スプライト展開先のレイアをキャッシュとして設けて、RAM変更時にだけキャッシュを更新して、
;  合成にはこのキャッシュを使用する様にすれば全レイアの合成が1度に行える。
;  ・実は別々に合成したほうがCPU内部キャッシュやメモリウェイトがかからず高速なのかもしれない、又は高速化が可能なのかもしれない。
;  ・現在は合成(BG-L,L1,L2)と拡大を同時に行っている。
;  ・両方のルーチンを作って初回起動時にベンチマークを行って使用するルーチンを決めたほうがいいのかなぁ。
; ・VRAMバッファへ転送するより、画像描画ファンクションを利用して(グラフィックボックスを利用せずに)ウィンドウに直接描画したほうが高速だろう。
////
; ・グラフィックボックスフラッシュよりウィンドウへの画像描画の方が高速なのか
; ・IRQシグナルやハンドラを(デバイスドライバ用などに限定して)実装できないか
; ・また、(これもデバドラ用に)DMAアクセスファンクションなども
; ・KANJIMAP.TXT には丸付き数字の21~50はあるが、①~⑳がどこにも無い。
////
; ・gboxとそのメモリ(.bss)を外部obj化したらオフセット0にマップされた。
;  (gboxはメインルーチンの.dataから参照しているから別セッション(しかも.bss)に対応していない?)
#include "main.nak"
/*
SavRandSeed	resd	1	; 乱数初期化用
SavRandOption	resd	1
SavRandCount	resd	1
; ダンジョン番号,ダンジョン名,	フロア数(max)	迷路サイズ
; 0000h	未初期化・データ破損
; 0001h	最初から
; 0002h	ちょっと迷路のダンジョン      10( 10)	15x15~	25x25
; 0003h	迷路のダンジョン	      25(100)	31x31~	71x51
; 0004h	もっと迷路のダンジョン	      60(100)	51x31~	99x99
; 0005h	超迷路のダンジョン	     100(100)  129x129~255x255
; 0006h	おまけのダンジョン	      ∞( ∞)	 9x 9~	255x255
; 0007h	カスタムダンジョン	       5(100)	 9x 9~	255x255
; 草番号,アイテム名,	効果
; 0000h	アイテム無し	
; 0001h	薬草		HP回復+50,満腹度+5%
; 0002h	回復草		HP回復+150,満腹度+5%
; 0003h	混乱草		混乱10ターン,満腹度+5%
; 0004h	睡眠草		睡眠5ターン,満腹度+5%
; 0005h	ワープ草	位置変更,満腹度+5%
; 0006h	目潰し草	画面を真っ黒にする20ターン,満腹度+5%
; 0007h	目薬草		見えないものが見える∞ターン,満腹度+5%
; 0008h	毒消し草	力が元に戻る,満腹度+5%
; 0009h	毒草		攻撃力が下がる,満腹度+5%
; 000Ah	力の種		力の最大値と力が上がる,満腹度+5%
; 000Bh	無力草		攻撃力が0になる30ターン,満腹度+5%
; 000Ch	不幸の種	レベルが下がる,満腹度+5%
; 000Dh	幸せの種	レベルが上がる,満腹度+5%
; 000Eh	胃拡張の種	最大満腹度+10%,満腹度+5%
; 000Fh	胃縮小の種	最大満腹度-10%,満腹度+5%

; 武器番号,武器名,	基礎強度
; 0040h	ダミー
; 0041h	つるはし	 1
; 0042h	こん棒		 3
; 0043h	金の剣		 5
; 0044h	銅の剣		 7
; 0045h	鉄の斧		 9
; 0046h	鋼鉄の剣	11
; 0047h	チタンの斧	13
; 0048h	正義の剣	15
; 0049h	メタルの斧	18
; 004Ah	炎の剣		 6
; 004Bh	氷の剣		 6
; 004Ch	妖剣かまいたち	 5
; 004Dh	剛剣かまいたち	 8
; 004Eh	魔法の槍	12
; 004Fh	回復の槍	-5
; 防具番号,防具名,	基礎強度
; 0080h	ダミー
; 0081h	ハラモチの盾	 2
; 0082h	皮の盾		 3
; 0083h	青銅の盾	 6
; 0084h	鉄の盾		 9
; 0085h	鋼鉄の盾	11
; 0086h	チタンの盾	13
; 0087h	メタルの盾	18
; 矢番号,名前,		基礎強度
; 00C1h	木の矢		 5
; 00C2h	鉄の矢		10
; 00C3h	メタルの矢	15
; 00C4h	銀の矢		 8(貫通)
; 00C5h	金の矢		12(貫通)
; 魔法番号,魔法名	効果範囲,効果
; 0100h	ダミー		なし
; 0101h	火		前1	軽いダメージ
; 0102h	水		周囲1	軽いダメージ
; 0103h	風		部屋	軽いダメージ
; 0104h	地		フロア	軽いダメージ
; 0105h	炎		前2	重いダメージ
; 0106h	洪水		周囲3	重いダメージ
; 0107h	かまいたち	部屋	重いダメージ
; 0108h	地震		フロア	重いダメージ
; 0109h	武器締め	武器	装備武器+1~+4
; 010Ah	防具締め	防具	装備武器+1~+4
; 010Bh	メッキ		アイテム武器防具錆ない,呪い回復,アイテム祝福?
; 010Ch	縛り		周囲1	動き停止
; 010Dh	金縛り		部屋	動き停止

; モンスター番号,名前,	HP, 攻撃力, 防御力, 経験値,出現階層,出現Point,アイテム出現率
; 0000h	ダミー
; 0001h	お化けなめくじ	10	 4	 2	 4    1~ 9F	1	 16/256
; 0002h	お化けなめくじ	25	15	12	30   10~19F	1	 32/256
; 0003h	お化けなめくじ	50	30	24	80   15~39F	1	  0/256
; 0004h	お化けなめくじ 100     120     100     120   30~49F	1	 40/256
; 0005h	お化けなめくじ 250     200     150     500   50F~	1	 10/256
;
; 

*/
/*
; キーパッドのエミュレーションに使用するボタンのデフォルト
; 上下左右,RUN,SELECT,A,B,…
KeyPad_TypeA:	dd	AR_UP, AR_DOWN, AR_LEFT, AR_RIGHT
		dd	KY_SHIFT, KY_BS, KY_ENTER, KY_CTRL
		dd	0, 0, 0, 0, 0, 0, 0, 0 /*/; ボタン数拡張用 /*/
KeyPad_TypeB:	dd	AR_UP, AR_DOWN, AR_LEFT, AR_RIGHT
		dd	"A", "S", "Z", "X"
		dd	0, 0, 0, 0, 0, 0, 0, 0
KeyPad_TypeC:	dd	"W", "X", "A", "D"
		dd	KY_SHIFT, KY_BS, KY_ENTER, KY_CTRL
		dd	0, 0, 0, 0, 0, 0, 0, 0
*/		
/*	スプライトインデックスデータの内容
X	dw	0
Y	dw	0
SPtn	dw	0
SPal	dw	0
X,Y:	b15-0:	表示先座標
SPtn:	b11-0:	パターン番号
	b12,13:	=1で水平,垂直方向2倍拡大
	b15-14:	オフセットアドレス参照先フラグ
		00	常に画面左上を原点とする
		01	パターンマップの左上を原点とする。=地上に張り付く
		10	背景スプライトオフセットを使用する。
		11	前景スプライトオフセットを使用する。(10とは別の空間かも知れない)
SPal:	b7-0:	スプライトパレット番号
	b13-12:	スプライト表示レイア指定
		00	表示しない
		01	表示しない
		10	背景スプライトレイア
		11	前景スプライトレイア
	b15-14:	拡張用予約
		ALL	16色パレットを使用する
*/
/* 	スプライトパターンデータの内容
pnum	dw	0
width	db	0
height	db	0
pnum:	b11-0:	基本パターン番号
	b15:	パターン番号連続タイプ
		0	連続するパターン番号
		1	bmp形式のパターン番号連続
width,height:	ピクセル単位パターンサイズ(0=256ドット)
*/


[リロード]   [トップ] [一覧] [単語検索] [最終更新]   [最終更新のRSS]