1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

この記事誰得? 私しか得しないニッチな技術で記事投稿!

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

Last updated at Posted at 2023-02-22

1.はじめに

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

2.ゲームの内容

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

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.どのように動くのか

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

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:

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?