; 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] ; 画面関係メモリ 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, "*** ハイスコア ランキング***" 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 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_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 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_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 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 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 ; 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]