H8アセンブラでゲームを作ってみた

# 1．はじめに
実のところ、現在(2023/3末まで)は職業訓練校に通っており、そこで、まあなんというかおよそ30年ぶりにプログラムというものに手を出している。
「組み込みプログラミング技術科」という半年在籍する科で、組み込み関係のPLCとかワンボードマイコンとかアセンブラとかC言語とか、そんなものを日々こねくっている。
内容的には未経験者向けの授業で、自分にとっては一度通ってきたところなので実習で空いた時間にプログラムを魔改造していろいろ試して経験値を少しずつ積んでいる。
あまりにも久し振りではあったが、プログラムをする感覚を取り戻すのにそれほどの時間は必要としなかったのは、意外だった。
そこで、12月末に行われたアセンブラの習得度テストで<strong>「自由製作」</strong>というのがあったので、授業で習ったことを全部ぶち込んで、非常に原始的なゲームを作ってみた。

# 2.ゲームの内容
前章で「非常に原始的な」と書いた。
そのゲームの名称は<strong>「酔っ払いゲーム」</strong>。多くの記事で、当時はそのように呼ばれていたと記憶している。
マイコンBASICマガジンという、ユーザが投稿したプログラムを掲載する雑誌があったのだが、その雑誌にも掲載されたことがあると記憶している。その他の雑誌にも、幾度となく掲載されていたと思う。
フラフラと動くキャラクターを、ワンキーでコントロールして左右にぶつからないように歩かせる、所謂「ワンキー・ゲーム」である。
ハードウェア構成としては、H8マイコンのキットに内包されているタクトスイッチを使用し、追加でLED8個を必要とする。
LEDの接続先はP1ポート、タクトスイッチはP4ポート。LEDの極性を逆にすると、点灯と消灯の論理がネガティブになる。
![FB_IMG_1677075310325_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20524/6ab2b070-992a-f7ca-c8a4-0146ec2575e3.jpeg)
写真は、現在実施しているC言語の実習のために使っているハードウェア。
H8のキットによっては、LEDが基板上に実装されているものもあるらしい。<strong>しらんけど</strong>。

# 3.とりあえずソース
タイマーはWAITループでも良かったと思うけれども、授業で習った難しい方がポイント高いと思ったので、無駄にITUループを使用してる。何のポイントが高いか知らんけど、授業で習ったことを全部ぶち込むという趣旨には合っている。
製作時間が短かったので、行き当たりばったりで作った部分が残っていてまあまあ目立つけど、そこはご了承願いたい。
ちゃんと動くし。:laughing:

---
	.CPU	300HA
	.SECTION RESET,DATA,LOCATE=H'000000
	.DATA.L H'100

	.SECTION ROM,CODE,LOCATE=H'000100

    TSTR	.EQU	H'FFFF60
    TCR0	.EQU	H'FFFF64
    TSR0	.EQU	H'FFFF67
    P1DR	.EQU	H'FFFFC2
    P1DDR	.EQU	H'FFFFC0
    P2DR	.EQU	H'FFFFC3
    P2DDR	.EQU	H'FFFFC1
    P2PCR	.EQU	H'FFFFD8
    P4DR	.EQU	H'FFFFC7
    P4DDR	.EQU	H'FFFFC5
    P4PCR	.EQU	H'FFFFDA
    P5DR	.EQU	H'FFFFCA
    P5DDR	.EQU	H'FFFFC8

	MOV.L	#H'FFFF00,ER7

	JSR		@INIT

    ;----------GAME DEMO
    DEMOS:
    	JSR		@OVER
    	JSR		@DEMO
    	JSR		@CNTD
    	JSR		@PRE

    ;----------GAME MAIN
    START:
    	JSR		@ITUW

    	BTST	#7,R0H
    	BEQ		DEMOS
    	BTST	#0,R0H
    	BEQ		DEMOS
    	BTST	#4,@P4DR
    	BEQ		SW1
    	ROTL.B	R0H
    	JMP		@SW2
	
    SW1:
    	ROTR.B	R0H
    SW2:
    	MOV.B	#B'01111110,R2L
    	AND		R0H,R2L
    	MOV.B	R2L,@P1DR
    	BTST	#1,@P5DR
    	BEQ		LED1
	
    LED0:
    	MOV.B	#H'01,R0L
    	MOV.B	R0L,@P5DR
    	JMP		@START
    LED1:
    	MOV.B	#H'02,R0L
    	MOV.B	R0L,@P5DR
    	JMP		@START

    ;----------SUBROUTINE
    ;----------GAME OVER EFFECT
    OVER:
    	MOV.B	#B'00000000,R0L
    	MOV.B	R0L,@P1DR
    	JSR		@ITUW
    	MOV.B	#B'01010101,R0L
    	MOV.B	R0L,@P1DR
    	JSR		@ITUW
    	MOV.B	#B'10101010,R0L
    	MOV.B	R0L,@P1DR
    	JSR		@ITUW
    	MOV.B	#B'00000000,R0L
    	MOV.B	R0L,@P1DR
    	JSR		@ITUW
    	JSR		@ITUW
    	MOV.B	#B'11111111,R0L
    	MOV.B	R0L,@P1DR
    	RTS

    ;----------GAME DEMO ROUTINE
    DEMO:
    	JSR		@DIFF
    	MOV.B	R0H,@P1DR
    	MOV.B	#H'01,R0L
    	MOV.B	R0L,@P5DR

    LRT:
    	MOV.B	#B'01111110,R2L
    	AND		R0H,R2L
    	MOV.B	R2L,@P1DR
    	MOV.B	#H'01,R0L
    	MOV.B	R0L,@P5DR
    	BTST	#5,@P4DR
    	BEQ		SWOUTL
    	BTST	#6,@P4DR
    	BEQ		DEMO
    	BTST	#6,R0H
    	BEQ		RRT
    	ROTL.B	R0H
    	JSR		@ITUW
    	JMP		@LRT
    RRT:
    	MOV.B	#B'01111110,R2L
    	AND		R0H,R2L
    	MOV.B	R2L,@P1DR
    	MOV.B	#H'02,R0L
    	MOV.B	R0L,@P5DR
    	BTST	#5,@P4DR
    	BEQ		SWOUTR
    	BTST	#6,@P4DR
    	BEQ		DEMO
    	BTST	#1,R0H
    	BEQ		LRT
    	ROTR.B	R0H
    	JSR		@ITUW
    	JMP		@RRT
    SWOUTL:
    	ROTR.B	R0H
    	JMP		@SWOUT
    SWOUTR:
    	ROTL.B	R0H
    SWOUT:
    	RTS	

    ;----------DIFFICULTY SETTING
    DIFF:
    	BTST	#6,@P4DR
    	BNE		DIFFE
    	JSR		@ITUW

    	MOV.B	R3L,R3H
    	AND		#B'11111110,R3H
    	BEQ		DIFF2

    	MOV.B	R3L,R3H
    	AND		#B'11111101,R3H
    	BEQ		DIFF3
	
    DIFF1:
    	MOV.B	#B'00000001,R3L		;Difficulty=1
    	MOV.B	#B'11111110,R0H
    	JMP		@DIFFE
    DIFF2:
    	MOV.B	#B'00000010,R3L		;Difficulty=2
    	MOV.B	#B'11111100,R0H
    	JMP		@DIFFE
    DIFF3:
    	MOV.B	#B'00000011,R3L		;Difficulty=3
    	MOV.B	#B'11111000,R0H
    DIFFE:
    	RTS

    ;----------COUNT DOWN
    CNTD:
    	MOV.B	#B'11111111,R0L
    	MOV.B	R0L,@P1DR
    CNTR:
    	SHLR	R0L
    	BTST	#0,@P1DR
    	BEQ		CNTB
    	MOV.B	R0L,@P1DR
    	JSR		@ITUW
    	JMP		@CNTR	
    CNTB:
    	MOV.B	R0H,@P1DR
    	RTS
	
    ;----------START VIEW
    PRE:
    	MOV.B	#B'01111110,R2L
    	AND		R0H,R2L
    	MOV.B	R2L,@P1DR
    	JSR		@ITUW
    	MOV.B	#B'11111111,R2L
    	MOV.B	R2L,@P1DR
    	JSR		@ITUW
    	MOV.B	#B'01111110,R2L
    	AND		R0H,R2L
    	MOV.B	R2L,@P1DR
    	JSR		@ITUW
    	RTS
	
    ;----------WAIT ITU LOOP
    ITUW:
    	MOV.B	#B'00000011,R1H
    	MOV.B	R1H,@TCR0

    	MOV.B	#10,R1L		;WAIT 200msec
	
    	MOV.B	#B'00000001,R1H
    	MOV.B	R1H,@TSTR
    T1:
    	BTST	#2,@TSR0
    	BEQ		T1
	
    	BCLR	#2,@TSR0
    	DEC.B	R1L
    	BNE		T1	
    	RTS

    ;----------INITIALIZE
    INIT:
    	MOV.B	#H'00,R0H
    	MOV.B	#H'FF,R0L
    	MOV.B	R0H,@P2DDR
    	MOV.B	R0L,@P2PCR
    	MOV.B	R0H,@P4DDR
    	MOV.B	R0L,@P4PCR

    	MOV.B	#H'FF,R0H
    	MOV.B	R0H,@P1DDR
    	MOV.B	#H'03,R0L
    	MOV.B	R0L,@P5DDR
	
    	MOV.B	#H'FC,R0H
    	MOV.B	R0H,@P1DR
    	MOV.B	#H'00,R0L
    	MOV.B	R0L,@P5DR
	
    	MOV.B	#B'00000010,R3L	;DifficultyValue=2
    	MOV.B	#B'11111100,R0H	;DifficultyValue=0xFC
    	RTS
	
    	.END
---

# 4.どのように動くのか
動画を撮影していたので、それを見て欲しい。
難易度の設定と、ゲーム開始直前の開始位置の表示を実装していなかったタイミングでの動画なので全機能が見られるわけではないけれども、ゲームの流れはおわかりいただけると思う。

https://youtu.be/JVvD_BY1z2A

# 5.操作方法
操作は、基板に実装されているタクトスイッチで行う。
電源ONでDEMO動作。
DEMO動作中にS3を押下することで、往復するLEDの点灯が●●→●●●→●→●●と変更される。これがゲームの難易度になる。ゲーム性を考慮して、難易度は3までとした。難易度のデフォルトは2。
DEMO動作中にS2を押下することでカウントダウン動作。その後、ゲームの開始位置を表示し点滅した後に、ゲームが開始される。
ゲームが開始すると、LEDがLED#0とLED#7の間で左ROLLする。S1を押下すると、右ROLLする。S1から手を離すと、左ROLLに戻る。
DEMO動作中にS2を押下した際に表示されていたLEDが、ゲームのスタート位置となる。
ROLLしているLEDがLED#0かLED#7に到達するとゲームオーバーで、電源ON時の動作に戻る。

# 6.最後に
ゲーム中のS1押下で左右ROLLをトグル動作で切り替えることも考えたが、スイッチのチャタリングがひどかったことと、それを含めて仕様を検討して製作期間内にプログラムを完成させることが難しいと判断したので、今回の仕様に落ち着かせた。

最初の方に、職業訓練は未経験者向けと書いたけれども、自分が所属している10月生の中で、きちんと理解してついてきている人は皆無であると感じてる。
この課題を提出したアセンブラの自由製作で、本当に自由に制作したのは自分一人だったし、辛うじて制作した他の一人は授業で習った内容を少しいじっただけのものを提出していた。
他の人たちは、自由製作の手前の課題でいっぱいいっぱいで、自由製作までたどり着けていなかった。
1月末のC言語の習得度テストも、合格は自分を含めた二人だけ。自分以外の一人は頑張っている感じだけれども、実際の理解度は正直なところ及第点に及んでいないと思うし、手数を試すよりもすぐに先生に聞いてしまうので、伸びしろがあまりないように思う。
今(2月)はH8マイコンのC言語の開発環境で勉強しているけど、先生が用意しておいたサンプルのソースに手を加えて完成させるということも、他の多くの人たちは満足に出来ていない。
これで果たして、3月の締めくくりにチームを組んでのロボット制御が出来るのか、本当に不安。:sweat_smile: