1.はじめに
実のところ、現在(2023/3末まで)は職業訓練校に通っており、そこで、まあなんというかおよそ30年ぶりにプログラムというものに手を出している。
「組み込みプログラミング技術科」という半年在籍する科で、組み込み関係のPLCとかワンボードマイコンとかアセンブラとかC言語とか、そんなものを日々こねくっている。
内容的には未経験者向けの授業で、自分にとっては一度通ってきたところなので実習で空いた時間にプログラムを魔改造していろいろ試して経験値を少しずつ積んでいる。
あまりにも久し振りではあったが、プログラムをする感覚を取り戻すのにそれほどの時間は必要としなかったのは、意外だった。
そこで、12月末に行われたアセンブラの習得度テストで「自由製作」というのがあったので、授業で習ったことを全部ぶち込んで、非常に原始的なゲームを作ってみた。
2.ゲームの内容
前章で「非常に原始的な」と書いた。
そのゲームの名称は「酔っ払いゲーム」。多くの記事で、当時はそのように呼ばれていたと記憶している。
マイコンBASICマガジンという、ユーザが投稿したプログラムを掲載する雑誌があったのだが、その雑誌にも掲載されたことがあると記憶している。その他の雑誌にも、幾度となく掲載されていたと思う。
フラフラと動くキャラクターを、ワンキーでコントロールして左右にぶつからないように歩かせる、所謂「ワンキー・ゲーム」である。
ハードウェア構成としては、H8マイコンのキットに内包されているタクトスイッチを使用し、追加でLED8個を必要とする。
LEDの接続先はP1ポート、タクトスイッチはP4ポート。LEDの極性を逆にすると、点灯と消灯の論理がネガティブになる。
写真は、現在実施しているC言語の実習のために使っているハードウェア。
H8のキットによっては、LEDが基板上に実装されているものもあるらしい。しらんけど。
3.とりあえずソース
タイマーはWAITループでも良かったと思うけれども、授業で習った難しい方がポイント高いと思ったので、無駄にITUループを使用してる。何のポイントが高いか知らんけど、授業で習ったことを全部ぶち込むという趣旨には合っている。
製作時間が短かったので、行き当たりばったりで作った部分が残っていてまあまあ目立つけど、そこはご了承願いたい。
ちゃんと動くし。
.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月の締めくくりにチームを組んでのロボット制御が出来るのか、本当に不安。