自作CPU Advent Calendar 2022 11日目
CalicoCPU で動作する爆弾ゲームを作った。
爆弾ゲーム
爆弾の前にスイッチが何個か並んでいる。
そのうち1個だけ、押すと爆弾が爆発するスイッチがある。
- 複数人で遊ぶ場合
- まだ押されていないスイッチを順番に1個ずつ押していく。
- 爆弾を爆発させた人が負け。
- 1人で遊ぶ場合
- スイッチを押していく。
- 爆弾を爆発させたらゲームオーバー。
- 爆弾を爆発させずに押していないスイッチを1個だけにできたらクリア。
Octet Switch Board
8回路のディップスイッチで8桁の入力をする。
2進数を入力しやすいよう、ビットの対応は右から左になっている。
爆弾ゲーム
使い方
- レジスタを見ると爆破スイッチの位置がわかってしまうので、レジスタの表示を隠す。
- PORT0の下位ビットに 2-way Buzzer Board を、PORT1に Octet Switch Board を接続する。
- プログラムを実行する。「初期化中」を表すled1が点灯する。
- PORT1の入力を非0にする。爆破スイッチの位置の抽選が行われる。
- PORT1の入力を0にする。爆破スイッチの位置が決定し、ゲーム開始となる。
- PORT1に接続したスイッチを1個ずつONにしていく。
- 爆破スイッチをONにすると、「爆発」を表すled2が点灯し、ブザーが鳴る。
プログラム
MikeAssembler でアセンブルできる。
target calico
; PORT0 の0ビット目(ブザー)、2ビット目(初期化中)、3ビット目(爆発)を出力にする
MOVI A, 0xD
DRIVE 0, A
; 初期化中をHIGHにする
MOVI A, 4
OUT 0, A
; PORT1 の入力がゼロでなくなるまで待つ
MOVI C, init_wait_nonzero
MOVI D, init_wait_zero
init_wait_nonzero:
IN B, 1
JNZ B, D
JNZ C, C
; PORT1 の入力がゼロになるまで、爆破スイッチの位置をルーレットする
init_wait_zero:
ADDI A, 1
IN B, 1
JNZ B, D
; ルーレットの結果(Aレジスタ)を爆破スイッチの位置(Bレジスタ)に変換する
MOVI B, 1
MOVI D, init_no_shift_1
MOVI C, 1
AND C, A
JNZ C, D
SHL B, 1
init_no_shift_1:
MOVI3 D, init_no_shift_2
MOVI C, 2
AND C, A
JNZ C, D
SHL B, 2
init_no_shift_2:
MOVI3 D, init_no_shift_4
MOVI C, 4
AND C, A
JNZ C, D
SHL B, 4
init_no_shift_4:
; 初期化中表示をLOWにする
MOVI A, 0
OUT 0, A
; PORT1の爆破スイッチの位置がHIGHになるまで待機する
MOVI C, explode
MOVI D, game_loop
game_loop:
IN A, 1
AND A, B
JNZ A, C
JNZ D, D
explode:
; ブザーと爆発表示をHIGHにする
MOVI A, 9
OUT 0, A
MOVI C, explode_end
explode_end:
JNZ C, C
以下は、アセンブル結果のHEXデータである。
:100000002D162412A6E9585F9B31585F61E5C3A104
:10001000828A9F45E7C300A2828A9F43E9C300A466
:10002000828A9F472012A387E3C7FB1806021BDFC3
:060030002912A387B59B15
:00000001FF
実行結果
反省点
ディップスイッチは人間の手による操作がしにくく、中途半端に一旦ONになるなどの誤操作が発生した。
トグルスイッチなどの操作しやすいUIを用意したほうがいいかもしれない。
投稿者の人気記事
-
mikecat
さんが
2022/12/11
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する