カピバラ父さんのプログラミング処方箋~白帯処理

プレイヤーが過ってCOPYキーを押すと、白帯が出てゲームプログラムが止まってしまうというのは問題です。

また、本体のINTERRUPTスイッチについても、故意に押される可能性があります。

コマンドプロンプト画面ならまだいいのですが、ゲームに使う縦256ドット解像度画面で白帯が出ると見苦しいので、 初期化処理の一環として対策します。

Copyキー、Interruptスイッチ禁止と復元

COPYキーが押されると、X68000の規定ではtrap #12の例外が発生します。

「trap」とか「例外」とか知らない用語に身構えたかもしれませんが、 実は既に使っているIOCSコールはtrap #15の例外です。

余談ですがついでに言うと、trap #11はSTOPキー、 trap #10は電源スイッチやソフトウェアリセットなどを捕捉します。

話を戻しますが、COPYキーが押されたときに白帯が出てしまうのは、trap #12の例外処理で、 プリンタ接続を確認しようとして応答がないときです。そこで、例外処理そのものを無害な処理に 置き換えるという方針で対策できます。

【COPYキー無効化処理】

_INTVCS   equ  $ff25

	pea	COPY_rte(pc)
	move	#32+12,-(sp)	* trap 12 COPY key
	DOS	_INTVCS
	addq.l	#6,sp
	lea	vctCOPY(pc),a0
	move.l	d0,(a0)

	:
	
COPY_rte:
	rte

vctCOPY:	.dc.l	0

DOSコール INTVCSは、ベクタと言う、例外処理の飛び先テーブルを書き換えるシステムコールです。

このプログラムでは、COPY_rteに書いてある、rte命令だけの処理に飛ぶようにしています。

rteは、例外処理を終える命令です。サブルーチンから帰るときのrtsと混同しないように注意してください。

DOSコールの戻り値は、書き換え前の飛び先アドレス(通常のCOPYキー動作)です。復元するときに必要なので、vctCOPYに保存し、以下のように使います。

【COPYキー復元処理】

	move.l	vctCOPY(pc),-(sp)
	move	#32+12,-(sp)	* trap 12 COPY key
	DOS	_INTVCS
	addq.l	#6,sp

Interruptスイッチについて方法は同じで、NMIという例外処理を、規定の白帯処理から 無害な処理に置き換えます。

【Interruptスイッチ処理】

	* 無効化 *
	pea	NMI_rte(pc)
	move	#31,-(sp)	* NMI
	DOS	_INTVCS
	addq.l	#6,sp
	lea	vctNMI(pc),a0
	move.l	d0,(a0)
	

	* 復元 *
	move.l	vctNMI(pc),-(sp)
	move	#31,-(sp)	* NMI
	DOS	_INTVCS
	addq.l	#6,sp
	
NMI_rte:
	move.b	#4,$e8e007	* NMI clear
	rte
vctNMI:		.dc.l	0

Interruptキーの処理に限って、システムポート$e8e007に4を書きます。 これは、INTERRUPTスイッチの検出をリセットする規定の手続きです。

COPYキーの活用

とりあえずCOPYキーとInterruptスイッチを黙らせることはできました。 でも、せっかくなら何か意味のある使い方をしたいものです。

そこで、COPYキーの処理をひと工夫してみます。

COPY_rte:
	btst.b	#0,$80e		* SHIFT key
	beq	@f
		bsr	QUIT
	@@:
	rte

quit_flag:	.dc.w	0

QUIT:
	move.l	a0,-(sp)
	lea	quit_flag(pc),a0
	move	#-1,(a0)
	movea.l	(sp)+,a0
	rts

quit_flagという、初期値0のフラグ変数を確保しました。

QUITというサブルーチンも定義し、プログラムのどこからでも、 bsr QUITと呼び出せば、quit_flagが-1に書き換えられるようにします。

そして、COPYキーが押されたときの処理については、 SHIFTキーと一緒に押された場合に、QUITサブルーチンを呼ぶようにします。

$80eは、IOCSのワークエリアで、キーボードのキーの押し下げ状態を 保持しているところを覗き見ています。BITSNSというIOCSコールに関連する場所です。

これによって、「SHIFTキーを押しながらCOPYキーを押すと、quit_flagがセットされる」 という動作になります。

quit_flagを何に使うかは、このあとのお楽しみにしておきましょう。


プログラミング処方箋へ

Copyright©2026 カピバラ父さん