8080マイコンをつくろう!(TK−80完全復活!)
なんと8080です!
もちろん、BASICからCP/Mまで、できます!
36年の時を経ていまよみがえる8080CPUマイコン組立キット!
なんたってはるか昔の生産中止品を集めて作る組立キットです。
生産前から堂々予告です。
入手できなくなったら即生産終了!売り切れ御免!
[第43回]
●インベーダーゲームプログラム
このところ「マイコン独立大作戦」システムのプログラム作成に没頭しております。
もうあと一息というところまできているのですが、なにしろ入力と出力というコンピュータシステムとしては根幹の部分をひっくり返してしまうわけですので、ちょいとしたバグのせいで丸っと一日つぶれてしまうことなどがあって、なかなかに大変です。
そのため早朝から深夜までバグ捜しに没頭することとなってしまい、ホームページの更新にまで手が回りません。
あともう少しですので、気長にお付き合いいただきますようお願いいたします。
さて今回は久しぶりのND8080です。
ND8080につきましてはましては最後に書きましたのが昨年6月ですから、それからもう半年以上が経ってしまいました。
幸いお蔭様にてND8080組立キットは予想外にご好評をいただきまして、その後は一時ほどではありませんが、時々ご注文をいただきずっと提供を続けております。
8080も8224も8228もなんとか手当てしてきましたがいつまでも続けられるものではありませんので、もしご興味がおありでしたら、入手不能になります前にぜひご購入いただきますようお勧めいたします。
前振りが長くなってしまいました。
つい一週間ほど前にND8080組立キットをご購入いただいたお客様からメールをいただきました。
もう組み立ててしまって、さっそくゲームプログラムを作られたとのことで、メールに添付してお送りいただきました。
えっ。
お届けして、まだ一週間も経っていませんのに…。
さっそく拝見させていただきましたら、なんと、これはすごい。
せっかくお送りいただきましたので、しばし「マイコン独立大作戦」のプログラム開発作業の手を休めまして、ゲームプログラムを入力し、さっそく実行させていただきました。
いただいたメールには「カシオのプログラム電卓で数字を使ったインベーダーゲーム」と説明されていますので、もとはカシオの電卓用のゲームだったということでしょうか。
なかなかによくできていると思います。
8000番地からプログラムを実行すると左端から数字インベーダーが右端の陣地めがけて進軍してきます。

[3]のキーを押すと右端の陣地の数字がカウントアップします。
敵の先頭の数値に合わせて(上の写真では2)、そこで[WRITE INC]を押すとその数字が敵をめがけて発射され、先頭の敵を破壊します。
まごまごしていると敵はどんどん数を増して陣地に近づいてきます。

右端の陣地まで敵に攻め込まれたらそこでゲームオーバーです。

GAMEOVERの文字が点滅するとともに、やっつけた敵の数が表示されます。

ちょいと慣れてきたので、26匹もやっつけました。

メールにはバイナリファイルだけではなくてソースプログラムも添付されていました。
ソースプログラムには丁寧にプログラムの説明まで入っておりました。
これは8080プログラムを学ぼうとされる方にとって、とてもよい参考プログラムになると思いましたので、プログラムの公開をお願いしましたところ、ご快諾いただきました。
随分長いプログラムです。
これだけのものを数日間で書き上げられたとは、とても思えません。
メールには8080のアセンブラは初めてです、と書いてありました。
もう、脱帽です。
マシン語のプログラムはソースリストよりもアドレスとマシン語があわせて出力されたアセンブルリストのほうが理解しやすいと思いますので、先にアセンブルリストを掲載します。
ND8080組立キットに付属の8080アセンブラで出力されたリストです。
2017/2/5 18: INVDER.ASM
END=98A9
ORG $8000
DP1=$83F8
WAIT27=$02EF
INKEY=$0223
INPUT=$0216
SCR00=$9000
SCR01=$9001
SCR02=$9002
SCR03=$9003
SCR04=$9004
SCR05=$9005
SCR06=$9006
SCR07=$9007
WAITCNT=$9010
CNT1=$9011
WAITENEMY_CNT=$9012
WAITENEMY_MAX=$9013
RAND256=$9014
ENEMY_MAX=$9015
WAITMISL_CNT=$9016
WAITMISL_MAX=$9017
MISL_POS=$9018
MISL_CHR=$9019
SCORE=$901A
DISP_CNT=$901B
8000 00 START: NOP
;スタックの初期化
8001 21FFFF LXI H,$FFFF
8004 F9 SPHL
;画面エリアの初期化
8005 3E08 MVI A,08 ;Screen Clear
8007 210090 LXI H,SCR00 ;SCR(1-8)=SP
800A 3620 START1: MVI M,20
800C 23 INX H
800D 3D DCR A
800E C20A80 JNZ START1
;自機の初期化
8011 210790 LXI H,SCR07 ;SCR(7)='0'
8014 3630 MVI M,30
;敵の移動速度の初期化
8016 211290 LXI H,WAITENEMY_CNT ;WAITENEMY_CNT=0
8019 3600 MVI M,00
801B 211390 LXI H,WAITENEMY_MAX ;WAITENEMY_MAX=80
801E 36F0 MVI M,F0
;敵の前線位置の初期化
8020 211590 LXI H,ENEMY_MAX ;ENEMY_MAX=0
8023 3600 MVI M,00
;ミサイルの移動速度の初期化
8025 211690 LXI H,WAITMISL_CNT
8028 3600 MVI M,00
802A 211790 LXI H,WAITMISL_MAX
802D 3610 MVI M,10
;ミサイルの位置の初期化
802F 211890 LXI H,MISL_POS
8032 3600 MVI M,00
;スコア
8034 211A90 LXI H,SCORE
8037 3600 MVI M,00
;------
;メイン
;------
8039 00 MAIN: NOP
803A CD4980 CALL MISL
803D CDCC80 CALL ENEMY
8040 CD5581 CALL KEYINP
8043 CDB282 CALL DISPALL
8046 C33980 JMP MAIN
;------------------
;ミサイルの移動処理
;------------------
8049 00 MISL: NOP
;ミサイルが発射されたか
804A 3A1890 LDA MISL_POS ;IF MISL_POS=0 THEN MISL_END
804D B7 ORA A
804E CACB80 JZ MISL_END
;待ち時間内か調べる
8051 211790 LXI H,WAITMISL_MAX
8054 3A1690 LDA WAITMISL_CNT
8057 3C INR A
8058 BE CMP M
8059 321690 STA WAITMISL_CNT
805C CA6280 JZ MISL_CHK ;IF WAITMISL_CNT = WAITMISL_MAX THEN MISL_END
805F C3CB80 JMP MISL_END
8062 00 MISL_CHK: NOP
;初期化
8063 3E00 MVI A,00
8065 321690 STA WAITMISL_CNT
;ミサイル表示を消す
8068 3A1890 LDA MISL_POS
806B FE08 CPI 08
806D CA7B80 JZ MISL_CHK1
8070 010000 LXI B,$0000 ;DSP(POS)=SP
8073 4F MOV C,A
8074 210090 LXI H,SCR00
8077 09 DAD B
8078 2B DCX H
8079 3620 MVI M,20
;ミサイル移動(仮)
807B 3A1890 MISL_CHK1: LDA MISL_POS ;#A=MISL_POS-1
807E 3D DCR A
;左端でないか
807F B7 ORA A ;IF #A=0 THEN MISL_CLEAR
8080 CAC280 JZ MISL_CLEAR
;移動先に敵がいないか :IF DSP(POS-1)<>ENEMY THEN MISL_MOV
8083 010000 LXI B,$0000
8086 4F MOV C,A
8087 210090 LXI H,SCR00
808A 09 DAD B
808B 2B DCX H
808C 7E MOV A,M
808D FE20 CPI 20
808F CA9580 JZ MISL_MOV
8092 C3AD80 JMP MISL_EXPL ;IF DSP(POS-1)=ENEMY THEN MISL_EXPL
8095 00 MISL_MOV: NOP
;ミサイルを1コマ左移動
8096 3A1890 LDA MISL_POS ;MISL_POS=MISL_POS-1
8099 3D DCR A
809A 321890 STA MISL_POS
;ミサイルの表示
809D 010000 LXI B,$0000 ;DSP(MISL_POS)=MISSILE
80A0 4F MOV C,A
80A1 210090 LXI H,SCR00
80A4 09 DAD B
80A5 2B DCX H
80A6 3A1990 LDA MISL_CHR
80A9 77 MOV M,A
;処理終了
80AA C3CB80 JMP MISL_END ;GOTO MISL_END
80AD 00 MISL_EXPL: NOP
;敵爆破
;画面クリア
80AE 3E20 MVI A,20
80B0 77 MOV M,A
;敵1機消滅
80B1 3A1590 LDA ENEMY_MAX
80B4 3D DCR A
80B5 321590 STA ENEMY_MAX
;得点
80B8 3A1A90 LDA SCORE
80BB 3C INR A
80BC 321A90 STA SCORE
;ミサイルクリア
80BF C3C280 JMP MISL_CLEAR
80C2 00 MISL_CLEAR: NOP
;ミサイルをクリア
80C3 3E00 MVI A,00 ;MISL_POS=0
80C5 321890 STA MISL_POS
;ミサイルをセット
; LDA MISL_CHR
; STA SCR07
;処理終了
80C8 C3CB80 JMP MISL_END
80CB C9 MISL_END: RET
;------------------
;敵の発生と移動処理
;------------------
;待ち時間内か調べる
80CC 00 ENEMY: NOP
80CD 211390 LXI H,WAITENEMY_MAX
80D0 3A1290 LDA WAITENEMY_CNT
80D3 3C INR A
80D4 BE CMP M
80D5 CADE80 JZ ENEMY_CHK ;IF WAITENEMY_CNT = WAITENEMY_MAX THEN ENEMY_CHK
80D8 321290 STA WAITENEMY_CNT
80DB C35381 JMP ENEMY_END
;敵の勝利確認を行う
80DE 00 ENEMY_CHK: NOP
;初期化
80DF 3E00 MVI A,00 ;WAITENEMY_CNT=0
80E1 321290 STA WAITENEMY_CNT
;早くする
80E4 3A1390 LDA WAITENEMY_MAX
80E7 FE20 CPI 20
80E9 CAF380 JZ ENEMY_CHK1
80EC 3D DCR A
80ED 3D DCR A
80EE 3D DCR A
80EF 3D DCR A
80F0 321390 STA WAITENEMY_MAX
80F3 00 ENEMY_CHK1: NOP
;前線に敵がいる場合は敵の勝ち
80F4 3A1590 LDA ENEMY_MAX ;IF ENEMY_MAX=0 THEN ENEMY_APE
80F7 B7 ORA A
80F8 CA2B81 JZ ENEMY_APE
80FB 3C INR A
80FC CDD682 CALL GETCHR
80FF FE20 CPI 20 ;IF SCR(ENEMY_MAX+1)<>SP THEN ENEMY_VIC
8101 C24781 JNZ ENEMY_VIC
;敵の移動を行う
8104 3A1590 LDA ENEMY_MAX ;FOR I=1 TO 6
8107 B7 ORA A
8108 CA2B81 JZ ENEMY_APE
810B 321190 STA CNT1
810E 210090 LXI H,SCR00
8111 010000 LXI B,$0000
8114 4F MOV C,A
8115 09 DAD B
8116 2B DCX H
8117 44 MOV B,H
8118 4D MOV C,L
8119 23 INX H
811A 0A ENEMY_MOV: LDAX B ; SCR(#HL)=SCR(#BC)
811B 77 MOV M,A
811C 2B DCX H
811D 0B DCX B
811E 3A1190 LDA CNT1
8121 3D DCR A
8122 CA2B81 JZ ENEMY_APE
8125 321190 STA CNT1
8128 C31A81 JMP ENEMY_MOV ;NEXT
;敵発生
812B 00 ENEMY_APE: NOP
812C CDE282 CALL RAND
812F 3A1490 LDA RAND256
8132 E61F ANI 1F
8134 218098 LXI H,RNDTBL
8137 85 ADD L
8138 6F MOV L,A
8139 7E MOV A,M
813A 320090 STA SCR00
;
813D 3A1590 LDA ENEMY_MAX ;ENEMY_MAX = ENEMY_MAX + 1
8140 3C INR A
8141 321590 STA ENEMY_MAX
;
8144 C35381 JMP ENEMY_END
;敵の勝利処理
8147 00 ENEMY_VIC: NOP
8148 3A1590 LDA ENEMY_MAX
814B FE07 CPI 07
814D C25381 JNZ ENEMY_END
8150 CD0282 CALL GAMEOVER
;敵の処理終了
8153 00 ENEMY_END: NOP
8154 C9 RET
;--------
;キー入力
;--------
8155 00 KEYINP: NOP
8156 CD2302 CALL INKEY ;#A=INKEY
8159 4F MOV C,A ;#C=#A
815A 78 MOV A,B ;IF #B=FF THEN RET
815B FEFF CPI FF
815D C8 RZ
815E 79 MOV A,C ;#A=#C
815F FE03 CPI 03 ;[KEY_3]
8161 CA6A81 JZ KEYINP_UP
8164 FE15 CPI 15 ;[KEY_WRITE_INC]
8166 CA7981 JZ KEYINP_SH
8169 C9 RET
;<[KEY_3]の場合>
816A 00 KEYINP_UP: NOP
816B 210790 LXI H,SCR07 ;SCR(7)=SCR(7)+1
816E 7E MOV A,M
816F 3C INR A
8170 FE3A CPI 3A
8172 C27781 JNZ KEYINP_UP1
8175 3E30 MVI A,30
8177 77 KEYINP_UP1: MOV M,A
8178 C9 RET
;<[KEY_WRITE_INC]の場合>
8179 00 KEYINP_SH: NOP
;ミサイル発射中でないか
817A 3A1890 LDA MISL_POS ;IF MISL_POS<>0 THEN END
817D B7 ORA A
817E C2A881 JNZ KEYINP_END
;
8181 3E07 MVI A,07
8183 321190 STA CNT1
;
8186 010000 LXI B,$0000 ;
8189 3A1590 LDA ENEMY_MAX
818C 4F MOV C,A
818D 210090 LXI H,SCR00 ;POINT=SCR00+NEMY_MAX-1
8190 09 DAD B
8191 2B DCX H
8192 3A0790 LDA SCR07
8195 BE CMP M
8196 CA9C81 JZ KEYINP_HIT
8199 C3A881 JMP KEYINP_END
819C 00 KEYINP_HIT: NOP
;#A=CHRが記録されている
819D 321990 STA MISL_CHR ;MISL_CHR=CHR番号
;ミサイルの位置
81A0 3E08 MVI A,08
81A2 321890 STA MISL_POS
; MVI M,20 ;SCR(#HL)=SP
; LDA ENEMY_MAX ;ENEMY_MAX=ENEMY_MAX-1
; DCR A
; STA ENEMY_MAX
81A5 C3A881 JMP KEYINP_END
81A8 C9 KEYINP_END: RET
;
;[GameOver]表示
;
81A9 00 DISPGAMEOV: NOP
81AA 210090 LXI H,SCR00
81AD 3618 MVI M,18 ;G
81AF 23 INX H
81B0 3619 MVI M,19 ;A
81B2 23 INX H
81B3 361A MVI M,1A ;M
81B5 23 INX H
81B6 361B MVI M,1B ;E
81B8 23 INX H
81B9 361C MVI M,1C ;O
81BB 23 INX H
81BC 361D MVI M,1D ;V
81BE 23 INX H
81BF 361B MVI M,1B ;E
81C1 23 INX H
81C2 361E MVI M,1E ;R
81C4 23 INX H
81C5 CDB282 CALL DISPALL
81C8 C9 RET
;
;点数表示
;
81C9 00 POINT: NOP
;スクリーンの初期化
81CA 3E20 MVI A,20
81CC CD6C82 CALL FULLSCR
;10進表示処理
;[100桁]
81CF 0E30 MVI C,30
81D1 3A1A90 LDA SCORE
81D4 FE64 POINT1: CPI 64
81D6 DADF81 JC POINT2
81D9 0C INR C
81DA D664 SUI 64
81DC C3D481 JMP POINT1
;
81DF 00 POINT2: NOP
;100桁に表示
81E0 210590 LXI H,SCR05
81E3 71 MOV M,C
;
;[10桁]
81E4 0E30 MVI C,30
81E6 FE0A POINT3: CPI 0A
81E8 DAF181 JC POINT4
81EB 0C INR C
81EC D60A SUI 0A
81EE C3E681 JMP POINT3
;
81F1 00 POINT4: NOP
;10桁に表示
81F2 210690 LXI H,SCR06
81F5 71 MOV M,C
;
;[1桁]
81F6 0E30 MVI C,30
81F8 81 ADD C
81F9 4F MOV C,A
;1桁に表示
81FA 210790 LXI H,SCR07
81FD 71 MOV M,C
81FE CDB282 POINT_END: CALL DISPALL
8201 C9 RET
;
;GAME OVER 処理
;
8202 00 GAMEOVER: NOP
;自機破壊表現
8203 3E10 MVI A,10
8205 CD6C82 CALL FULLSCR
8208 CD9C82 CALL WAIT500
820B 3E11 MVI A,11
820D CD6C82 CALL FULLSCR
8210 CD9C82 CALL WAIT500
8213 3E12 MVI A,12
8215 CD6C82 CALL FULLSCR
8218 CD9C82 CALL WAIT500
821B 3E13 MVI A,13
821D CD6C82 CALL FULLSCR
8220 CD9C82 CALL WAIT500
8223 3E05 MVI A,05
8225 00 GAMEOVER1: NOP
8226 F5 PUSH PSW
8227 3E10 MVI A,10 ;_
8229 CD6C82 CALL FULLSCR
822C CDEF02 CALL WAIT27
822F 3E16 MVI A,16 ;u
8231 CD6C82 CALL FULLSCR
8234 CDEF02 CALL WAIT27
8237 3E17 MVI A,17 ;U
8239 CD6C82 CALL FULLSCR
823C CDEF02 CALL WAIT27
823F 3E16 MVI A,16 ;u
8241 CD6C82 CALL FULLSCR
8244 CDEF02 CALL WAIT27
8247 F1 POP PSW
8248 3D DCR A
8249 C22582 JNZ GAMEOVER1
824C 00 GAMEOVER2: NOP
;[GAME OVER]表示
824D CDA981 CALL DISPGAMEOV
;時間待ち
8250 CD8982 CALL WAIT5000
;キーチェック
8253 78 MOV A,B
8254 FEFF CPI FF
8256 C26882 JNZ GAMEOVER_END
;点数表示
8259 CDC981 CALL POINT
;時間待ち
825C CD8982 CALL WAIT5000
;キーチェック
825F 78 MOV A,B
8260 FEFF CPI FF
8262 C26882 JNZ GAMEOVER_END
8265 C34C82 JMP GAMEOVER2
8268 00 GAMEOVER_END:NOP
;何から何までリセット
8269 C30080 JMP $8000
826C 00 FULLSCR: NOP
826D 320090 STA SCR00
8270 320190 STA SCR01
8273 320290 STA SCR02
8276 320390 STA SCR03
8279 320490 STA SCR04
827C 320590 STA SCR05
827F 320690 STA SCR06
8282 320790 STA SCR07
8285 CDB282 CALL DISPALL
8288 C9 RET
8289 00 WAIT5000: NOP
828A 160A MVI D,0A ;#D=10
828C D5 WAIT5000_1: PUSH D
;時間待ち
828D CD9C82 CALL WAIT500
8290 D1 POP D
;キー入力ありか
8291 78 MOV A,B ;IF #B=FF THEN RETURN
8292 FEFF CPI FF
8294 C0 RNZ
8295 15 DCR D ;#D = #D - 1
8296 7A MOV A,D ;IF #D<>0 THEN WAIT5000_1
8297 B7 ORA A
8298 C28C82 JNZ WAIT5000_1
829B C9 RET
829C 00 WAIT500: NOP
829D 160A MVI D,0A ;#D=10
829F D5 WAIT500_1: PUSH D
;時間待ち
82A0 CDEF02 CALL WAIT27
;キー入力
82A3 CD2302 CALL INKEY
82A6 D1 POP D
;キー入力ありか
82A7 78 MOV A,B ;IF #B=FF THEN RETURN
82A8 FEFF CPI FF
82AA C0 RNZ
82AB 15 DCR D ;#D = #D - 1
82AC 7A MOV A,D ;IF #D<>0 THEN WAIT500_1
82AD B7 ORA A
82AE C29F82 JNZ WAIT500_1
82B1 C9 RET
;
;画面表示を行います
;
82B2 00 DISPALL: NOP
82B3 3E08 MVI A,08 ;CNT1=8
82B5 321190 STA CNT1
82B8 010090 LXI B,SCR00 ;#BC=SCR00
82BB 11F883 LXI D,DP1 ;#DE=DP1
82BE 0A DISPAL1: LDAX B ;#A=SCR00(n)
82BF 210098 LXI H,CHRTBL ;DP1(n) = CHRTBL(chr)
82C2 85 ADD L
82C3 6F MOV L,A
82C4 7E MOV A,M
; LDA DISP_CNT
; ORA A
; JZ DISPAL2
; MVI A,00
; STA DISP_CNT
; JMP DISPAL3
82C5 7E DISPAL2: MOV A,M
82C6 12 DISPAL3: STAX D
82C7 03 INX B ;#BC=#BC+1
82C8 13 INX D ;#DE=#DE+1
82C9 3A1190 LDA CNT1 ;CNT1=CNT1+1
82CC 3C INR A
82CD 321190 STA CNT1
82D0 FE00 CPI 00 ;IF CNT1<>0 THEN DISPAL1
82D2 C2BE82 JNZ DISPAL1
82D5 C9 RET
;
;指定位置(#A)のキャラクタを取得(#A)します
;
82D6 00 GETCHR: NOP
82D7 010000 LXI B,$0000
82DA 4F MOV C,A
82DB 210090 LXI H,SCR00
82DE 09 DAD B
82DF 2B DCX H
82E0 7E MOV A,M
82E1 C9 RET
;
;乱数を発生します
;
82E2 00 RAND: NOP
82E3 3A1490 LDA RAND256
82E6 47 MOV B,A
82E7 07 RLC
82E8 E6FE ANI FE
82EA 07 RLC
82EB E6FE ANI FE
82ED 07 RLC
82EE E6FE ANI FE
82F0 80 ADD B
82F1 80 ADD B
82F2 80 ADD B
82F3 80 ADD B
82F4 80 ADD B
82F5 C605 ADI 05
82F7 321490 STA RAND256
82FA C9 RET
;=================== 未作成 START ====================================
;掛算処理を行います
;※未作成
82FB 00 MULT: NOP
; A x A
; 1010
; x 1010
; --------
; 1010
; 1010
; --------
; 1100100
; =64h - 100
;
;#HL = #B x #C
82FC 210000 LXI H,$0000
82FF 110000 LXI D,$0000 ;#DE=#B
8302 58 MOV E,B
8303 00 MULT1: NOP
8304 79 MOV A,C
8305 E601 ANI 01
8307 CA0B83 JZ MULT2 ;IF Bit0=0 THEN MULT2
;
830A 19 DAD D ;#HL=#HL+#DE
;
830B 00 MULT2: NOP
830C 79 MOV A,C ;#C= 76543210 -> 1Bit
830D 0F RRC
830E 4F MOV C,A
830F B7 ORA A ;IF #C=0 THEN END
8310 E5 PUSH H ;#DE= <- 1Bit
8311 29 DAD H
8312 62 MOV H,D
8313 6B MOV L,E
8314 E1 POP H
8315 C30383 JMP MULT1
;
8318 00 MULT_END: NOP
8319 C9 RET
;割算の処理を行います
;※未作成
;#HL=#BC / #A
831A 00 DIV: NOP
; _________
; 1100) 0111000
;
831B 210000 LXI H,$0000
831E 67 MOV H,A
831F 00 DIV1: NOP
;HLとBCを比較
8320 00 HLCPBC: NOP
8321 78 MOV A,B
8322 BC CMP H
8323 CA2783 JZ HLCPBC_HS ;IF #H=#B THEN HLCPBC_HS
8326 C9 RET
8327 00 HLCPBC_HS: NOP
8328 79 MOV A,C
8329 BD CMP L
832A C9 RET
;================== 未作成 END =====================================
ORG $9800 ;下位のみの演算しか行ってないので[XX00]なければならない
9800 00 CHRTBL: DB 00;00
9801 00 DB 00;01
9802 00 DB 00;02
9803 00 DB 00;03
9804 00 DB 00;04
9805 00 DB 00;05
9806 00 DB 00;06
9807 00 DB 00;07
9808 00 DB 00;08
9809 00 DB 00;09
980A 00 DB 00;0A
980B 00 DB 00;0B
980C 00 DB 00;0C
980D 00 DB 00;0D
980E 00 DB 00;0E
980F 00 DB 00;0F
9810 08 DB 08;10 _
9811 5C DB 5C;11 o
9812 7E DB 7E;12 V
9813 3F DB 3F;13 O
9814 5E DB 5E;14
9815 7C DB 7C;15
9816 1C DB 1C;16 u
9817 3E DB 3E;17 U
9818 3D DB 3D;18 G
9819 77 DB 77;19 A
981A 37 DB 37;1A M
981B 79 DB 79;1B E
981C 3F DB 3F;1C O
981D 3E DB 3E;1D V
981E 77 DB 77;1E R
981F 00 DB 00;1F
9820 00 DB 00;20
9821 00 DB 00;21
9822 00 DB 00;22
9823 00 DB 00;23
9824 00 DB 00;24
9825 00 DB 00;25
9826 00 DB 00;26
9827 00 DB 00;27
9828 00 DB 00;28
9829 00 DB 00;29
982A 00 DB 00;2A
982B 00 DB 00;2B
982C 00 DB 00;2C
982D 00 DB 00;2D
982E 00 DB 00;2E
982F 00 DB 00;2F
9830 3F DB 3F;30 '0'
9831 06 DB 06;31 '1'
9832 5B DB 5B;32 '2'
9833 4F DB 4F;33 '3'
9834 66 DB 66;34 '4'
9835 6D DB 6D;35 '5'
9836 7D DB 7D;36 '6'
9837 27 DB 27;37 '7'
9838 7F DB 7F;38 '8'
9839 6F DB 6F;39 '9'
983A 00 DB 00;3A
983B 00 DB 00;3B
983C 00 DB 00;3C
983D 00 DB 00;3D
983E 00 DB 00;3E
983F 00 DB 00;3F
9840 00 DB 00;40
9841 00 DB 00;41
9842 00 DB 00;42
9843 00 DB 00;43
9844 00 DB 00;44
9845 00 DB 00;45
9846 00 DB 00;46
9847 00 DB 00;47
9848 00 DB 00;48
9849 00 DB 00;49
984A 00 DB 00;4A
984B 00 DB 00;4B
984C 00 DB 00;4C
984D 00 DB 00;4D
984E 00 DB 00;4E
984F 00 DB 00;4F
9850 00 DB 00;50
9851 00 DB 00;51
9852 00 DB 00;52
9853 00 DB 00;53
9854 00 DB 00;54
9855 00 DB 00;55
9856 00 DB 00;56
9857 00 DB 00;57
9858 00 DB 00;58
9859 00 DB 00;59
985A 00 DB 00;5A
985B 00 DB 00;5B
985C 00 DB 00;5C
985D 00 DB 00;5D
985E 00 DB 00;5E
985F 00 DB 00;5F
9860 00 DB 00;60
9861 00 DB 00;61
9862 00 DB 00;62
9863 00 DB 00;63
9864 00 DB 00;64
9865 00 DB 00;65
9866 00 DB 00;66
9867 00 DB 00;67
9868 00 DB 00;68
9869 00 DB 00;69
986A 00 DB 00;6A
986B 00 DB 00;6B
986C 00 DB 00;6C
986D 00 DB 00;6D
986E 00 DB 00;6E
986F 00 DB 00;6F
9870 00 DB 00;70
9871 00 DB 00;71
9872 00 DB 00;72
9873 00 DB 00;73
9874 00 DB 00;74
9875 00 DB 00;75
9876 00 DB 00;76
9877 00 DB 00;77
9878 00 DB 00;78
9879 00 DB 00;79
987A 00 DB 00;7A
987B 00 DB 00;7B
987C 00 DB 00;7C
987D 00 DB 00;7D
987E 00 DB 00;7E
987F 00 DB 00;7F
9880 30 RNDTBL: DB 30;00
9881 31 DB 31;01
9882 32 DB 32;02
9883 33 DB 33;03
9884 34 DB 34;04
9885 35 DB 35;05
9886 36 DB 36;06
9887 37 DB 37;07
9888 38 DB 38;08
9889 39 DB 39;09
988A 30 DB 30;10
988B 31 DB 31;11
988C 32 DB 32;12
988D 33 DB 33;13
988E 34 DB 34;14
988F 35 DB 35;15
9890 36 DB 36;16
9891 37 DB 37;17
9892 38 DB 38;18
9893 39 DB 39;19
9894 30 DB 30;10
9895 31 DB 31;11
9896 32 DB 32;12
9897 33 DB 33;13
9898 34 DB 34;14
9899 35 DB 35;15
989A 36 DB 36;16
989B 37 DB 37;17
989C 38 DB 38;18
989D 39 DB 39;19
989E 30 DB 30;20
989F 31 DB 31;21
98A0 32 DB 32;22
98A1 33 DB 33;23
98A2 34 DB 34;24
98A3 35 DB 35;25
98A4 36 DB 36;26
98A5 37 DB 37;27
98A6 38 DB 38;28
98A7 39 DB 39;29
98A8 30 DB 30;30
98A9 31 DB 31;31
;END
CHRTBL =9800 CNT1 =9011 DISPAL1 =82BE
DISPAL2 =82C5 DISPAL3 =82C6 DISPALL =82B2
DISPGAMEOV =81A9 DISP_CNT =901B DIV =831A
DIV1 =831F DP1 =83F8 ENEMY =80CC
ENEMY_APE =812B ENEMY_CHK =80DE ENEMY_CHK1 =80F3
ENEMY_END =8153 ENEMY_MAX =9015 ENEMY_MOV =811A
ENEMY_VIC =8147 FULLSCR =826C GAMEOVER =8202
GAMEOVER1 =8225 GAMEOVER2 =824C GAMEOVER_END =8268
GETCHR =82D6 HLCPBC =8320 HLCPBC_HS =8327
INKEY =0223 INPUT =0216 KEYINP =8155
KEYINP_END =81A8 KEYINP_HIT =819C KEYINP_SH =8179
KEYINP_UP =816A KEYINP_UP1 =8177 MAIN =8039
MISL =8049 MISL_CHK =8062 MISL_CHK1 =807B
MISL_CHR =9019 MISL_CLEAR =80C2 MISL_END =80CB
MISL_EXPL =80AD MISL_MOV =8095 MISL_POS =9018
MULT =82FB MULT1 =8303 MULT2 =830B
MULT_END =8318 POINT =81C9 POINT1 =81D4
POINT2 =81DF POINT3 =81E6 POINT4 =81F1
POINT_END =81FE RAND =82E2 RAND256 =9014
RNDTBL =9880 SCORE =901A SCR00 =9000
SCR01 =9001 SCR02 =9002 SCR03 =9003
SCR04 =9004 SCR05 =9005 SCR06 =9006
SCR07 =9007 START =8000 START1 =800A
WAIT27 =02EF WAIT500 =829C WAIT5000 =8289
WAIT5000_1 =828C WAIT500_1 =829F WAITCNT =9010
WAITENEMY_CNT=9012 WAITENEMY_MAX=9013 WAITMISL_CNT =9016
WAITMISL_MAX =9017
|
途中「未完成」のコメントがついているところがあります。
なかなかむつかしいとは思いますが、皆様もぜひ挑戦して未完成のところを補完してみられたらいかがでしょうか?
とてもよい勉強になると思います。
下にソースプログラムリストも掲載します。
下のリスト部分をコピーしてテキストエディタに貼り付けて保存したあと、ND8080組立キットやND80Z3.5組立キットに付属の8080アセンブラ(ASM80.COM)でアセンブルすると、ND8080で実行できるマシン語プログラムが作成されます。
Windowsのメモ帳(notepad)は文字化けの可能性があってお勧めできません。
フリーソフトの「TeraPad」がお勧めです。
ND8080だけではなくてND80Z3.5(ND80ZV)でも実行できます。
いずれの場合にも「TK−80モニタ」モードで実行します。
ORG $8000
DP1=$83F8
WAIT27=$02EF
INKEY=$0223
INPUT=$0216
SCR00=$9000
SCR01=$9001
SCR02=$9002
SCR03=$9003
SCR04=$9004
SCR05=$9005
SCR06=$9006
SCR07=$9007
WAITCNT=$9010
CNT1=$9011
WAITENEMY_CNT=$9012
WAITENEMY_MAX=$9013
RAND256=$9014
ENEMY_MAX=$9015
WAITMISL_CNT=$9016
WAITMISL_MAX=$9017
MISL_POS=$9018
MISL_CHR=$9019
SCORE=$901A
DISP_CNT=$901B
START: NOP
;スタックの初期化
LXI H,$FFFF
SPHL
;画面エリアの初期化
MVI A,08 ;Screen Clear
LXI H,SCR00 ;SCR(1-8)=SP
START1: MVI M,20
INX H
DCR A
JNZ START1
;自機の初期化
LXI H,SCR07 ;SCR(7)='0'
MVI M,30
;敵の移動速度の初期化
LXI H,WAITENEMY_CNT ;WAITENEMY_CNT=0
MVI M,00
LXI H,WAITENEMY_MAX ;WAITENEMY_MAX=80
MVI M,F0
;敵の前線位置の初期化
LXI H,ENEMY_MAX ;ENEMY_MAX=0
MVI M,00
;ミサイルの移動速度の初期化
LXI H,WAITMISL_CNT
MVI M,00
LXI H,WAITMISL_MAX
MVI M,10
;ミサイルの位置の初期化
LXI H,MISL_POS
MVI M,00
;スコア
LXI H,SCORE
MVI M,00
;------
;メイン
;------
MAIN: NOP
CALL MISL
CALL ENEMY
CALL KEYINP
CALL DISPALL
JMP MAIN
;------------------
;ミサイルの移動処理
;------------------
MISL: NOP
;ミサイルが発射されたか
LDA MISL_POS ;IF MISL_POS=0 THEN MISL_END
ORA A
JZ MISL_END
;待ち時間内か調べる
LXI H,WAITMISL_MAX
LDA WAITMISL_CNT
INR A
CMP M
STA WAITMISL_CNT
JZ MISL_CHK ;IF WAITMISL_CNT = WAITMISL_MAX THEN MISL_END
JMP MISL_END
MISL_CHK: NOP
;初期化
MVI A,00
STA WAITMISL_CNT
;ミサイル表示を消す
LDA MISL_POS
CPI 08
JZ MISL_CHK1
LXI B,$0000 ;DSP(POS)=SP
MOV C,A
LXI H,SCR00
DAD B
DCX H
MVI M,20
;ミサイル移動(仮)
MISL_CHK1: LDA MISL_POS ;#A=MISL_POS-1
DCR A
;左端でないか
ORA A ;IF #A=0 THEN MISL_CLEAR
JZ MISL_CLEAR
;移動先に敵がいないか :IF DSP(POS-1)<>ENEMY THEN MISL_MOV
LXI B,$0000
MOV C,A
LXI H,SCR00
DAD B
DCX H
MOV A,M
CPI 20
JZ MISL_MOV
JMP MISL_EXPL ;IF DSP(POS-1)=ENEMY THEN MISL_EXPL
MISL_MOV: NOP
;ミサイルを1コマ左移動
LDA MISL_POS ;MISL_POS=MISL_POS-1
DCR A
STA MISL_POS
;ミサイルの表示
LXI B,$0000 ;DSP(MISL_POS)=MISSILE
MOV C,A
LXI H,SCR00
DAD B
DCX H
LDA MISL_CHR
MOV M,A
;処理終了
JMP MISL_END ;GOTO MISL_END
MISL_EXPL: NOP
;敵爆破
;画面クリア
MVI A,20
MOV M,A
;敵1機消滅
LDA ENEMY_MAX
DCR A
STA ENEMY_MAX
;得点
LDA SCORE
INR A
STA SCORE
;ミサイルクリア
JMP MISL_CLEAR
MISL_CLEAR: NOP
;ミサイルをクリア
MVI A,00 ;MISL_POS=0
STA MISL_POS
;ミサイルをセット
; LDA MISL_CHR
; STA SCR07
;処理終了
JMP MISL_END
MISL_END: RET
;------------------
;敵の発生と移動処理
;------------------
;待ち時間内か調べる
ENEMY: NOP
LXI H,WAITENEMY_MAX
LDA WAITENEMY_CNT
INR A
CMP M
JZ ENEMY_CHK ;IF WAITENEMY_CNT = WAITENEMY_MAX THEN ENEMY_CHK
STA WAITENEMY_CNT
JMP ENEMY_END
;敵の勝利確認を行う
ENEMY_CHK: NOP
;初期化
MVI A,00 ;WAITENEMY_CNT=0
STA WAITENEMY_CNT
;早くする
LDA WAITENEMY_MAX
CPI 20
JZ ENEMY_CHK1
DCR A
DCR A
DCR A
DCR A
STA WAITENEMY_MAX
ENEMY_CHK1: NOP
;前線に敵がいる場合は敵の勝ち
LDA ENEMY_MAX ;IF ENEMY_MAX=0 THEN ENEMY_APE
ORA A
JZ ENEMY_APE
INR A
CALL GETCHR
CPI 20 ;IF SCR(ENEMY_MAX+1)<>SP THEN ENEMY_VIC
JNZ ENEMY_VIC
;敵の移動を行う
LDA ENEMY_MAX ;FOR I=1 TO 6
ORA A
JZ ENEMY_APE
STA CNT1
LXI H,SCR00
LXI B,$0000
MOV C,A
DAD B
DCX H
MOV B,H
MOV C,L
INX H
ENEMY_MOV: LDAX B ; SCR(#HL)=SCR(#BC)
MOV M,A
DCX H
DCX B
LDA CNT1
DCR A
JZ ENEMY_APE
STA CNT1
JMP ENEMY_MOV ;NEXT
;敵発生
ENEMY_APE: NOP
CALL RAND
LDA RAND256
ANI 1F
LXI H,RNDTBL
ADD L
MOV L,A
MOV A,M
STA SCR00
;
LDA ENEMY_MAX ;ENEMY_MAX = ENEMY_MAX + 1
INR A
STA ENEMY_MAX
;
JMP ENEMY_END
;敵の勝利処理
ENEMY_VIC: NOP
LDA ENEMY_MAX
CPI 07
JNZ ENEMY_END
CALL GAMEOVER
;敵の処理終了
ENEMY_END: NOP
RET
;--------
;キー入力
;--------
KEYINP: NOP
CALL INKEY ;#A=INKEY
MOV C,A ;#C=#A
MOV A,B ;IF #B=FF THEN RET
CPI FF
RZ
MOV A,C ;#A=#C
CPI 03 ;[KEY_3]
JZ KEYINP_UP
CPI 15 ;[KEY_WRITE_INC]
JZ KEYINP_SH
RET
;<[KEY_3]の場合>
KEYINP_UP: NOP
LXI H,SCR07 ;SCR(7)=SCR(7)+1
MOV A,M
INR A
CPI 3A
JNZ KEYINP_UP1
MVI A,30
KEYINP_UP1: MOV M,A
RET
;<[KEY_WRITE_INC]の場合>
KEYINP_SH: NOP
;ミサイル発射中でないか
LDA MISL_POS ;IF MISL_POS<>0 THEN END
ORA A
JNZ KEYINP_END
;
MVI A,07
STA CNT1
;
LXI B,$0000 ;
LDA ENEMY_MAX
MOV C,A
LXI H,SCR00 ;POINT=SCR00+NEMY_MAX-1
DAD B
DCX H
LDA SCR07
CMP M
JZ KEYINP_HIT
JMP KEYINP_END
KEYINP_HIT: NOP
;#A=CHRが記録されている
STA MISL_CHR ;MISL_CHR=CHR番号
;ミサイルの位置
MVI A,08
STA MISL_POS
; MVI M,20 ;SCR(#HL)=SP
; LDA ENEMY_MAX ;ENEMY_MAX=ENEMY_MAX-1
; DCR A
; STA ENEMY_MAX
JMP KEYINP_END
KEYINP_END: RET
;
;[GameOver]表示
;
DISPGAMEOV: NOP
LXI H,SCR00
MVI M,18 ;G
INX H
MVI M,19 ;A
INX H
MVI M,1A ;M
INX H
MVI M,1B ;E
INX H
MVI M,1C ;O
INX H
MVI M,1D ;V
INX H
MVI M,1B ;E
INX H
MVI M,1E ;R
INX H
CALL DISPALL
RET
;
;点数表示
;
POINT: NOP
;スクリーンの初期化
MVI A,20
CALL FULLSCR
;10進表示処理
;[100桁]
MVI C,30
LDA SCORE
POINT1: CPI 64
JC POINT2
INR C
SUI 64
JMP POINT1
;
POINT2: NOP
;100桁に表示
LXI H,SCR05
MOV M,C
;
;[10桁]
MVI C,30
POINT3: CPI 0A
JC POINT4
INR C
SUI 0A
JMP POINT3
;
POINT4: NOP
;10桁に表示
LXI H,SCR06
MOV M,C
;
;[1桁]
MVI C,30
ADD C
MOV C,A
;1桁に表示
LXI H,SCR07
MOV M,C
POINT_END: CALL DISPALL
RET
;
;GAME OVER 処理
;
GAMEOVER: NOP
;自機破壊表現
MVI A,10
CALL FULLSCR
CALL WAIT500
MVI A,11
CALL FULLSCR
CALL WAIT500
MVI A,12
CALL FULLSCR
CALL WAIT500
MVI A,13
CALL FULLSCR
CALL WAIT500
MVI A,05
GAMEOVER1: NOP
PUSH PSW
MVI A,10 ;_
CALL FULLSCR
CALL WAIT27
MVI A,16 ;u
CALL FULLSCR
CALL WAIT27
MVI A,17 ;U
CALL FULLSCR
CALL WAIT27
MVI A,16 ;u
CALL FULLSCR
CALL WAIT27
POP PSW
DCR A
JNZ GAMEOVER1
GAMEOVER2: NOP
;[GAME OVER]表示
CALL DISPGAMEOV
;時間待ち
CALL WAIT5000
;キーチェック
MOV A,B
CPI FF
JNZ GAMEOVER_END
;点数表示
CALL POINT
;時間待ち
CALL WAIT5000
;キーチェック
MOV A,B
CPI FF
JNZ GAMEOVER_END
JMP GAMEOVER2
GAMEOVER_END:NOP
;何から何までリセット
JMP $8000
FULLSCR: NOP
STA SCR00
STA SCR01
STA SCR02
STA SCR03
STA SCR04
STA SCR05
STA SCR06
STA SCR07
CALL DISPALL
RET
WAIT5000: NOP
MVI D,0A ;#D=10
WAIT5000_1: PUSH D
;時間待ち
CALL WAIT500
POP D
;キー入力ありか
MOV A,B ;IF #B=FF THEN RETURN
CPI FF
RNZ
DCR D ;#D = #D - 1
MOV A,D ;IF #D<>0 THEN WAIT5000_1
ORA A
JNZ WAIT5000_1
RET
WAIT500: NOP
MVI D,0A ;#D=10
WAIT500_1: PUSH D
;時間待ち
CALL WAIT27
;キー入力
CALL INKEY
POP D
;キー入力ありか
MOV A,B ;IF #B=FF THEN RETURN
CPI FF
RNZ
DCR D ;#D = #D - 1
MOV A,D ;IF #D<>0 THEN WAIT500_1
ORA A
JNZ WAIT500_1
RET
;
;画面表示を行います
;
DISPALL: NOP
MVI A,08 ;CNT1=8
STA CNT1
LXI B,SCR00 ;#BC=SCR00
LXI D,DP1 ;#DE=DP1
DISPAL1: LDAX B ;#A=SCR00(n)
LXI H,CHRTBL ;DP1(n) = CHRTBL(chr)
ADD L
MOV L,A
MOV A,M
; LDA DISP_CNT
; ORA A
; JZ DISPAL2
; MVI A,00
; STA DISP_CNT
; JMP DISPAL3
DISPAL2: MOV A,M
DISPAL3: STAX D
INX B ;#BC=#BC+1
INX D ;#DE=#DE+1
LDA CNT1 ;CNT1=CNT1+1
INR A
STA CNT1
CPI 00 ;IF CNT1<>0 THEN DISPAL1
JNZ DISPAL1
RET
;
;指定位置(#A)のキャラクタを取得(#A)します
;
GETCHR: NOP
LXI B,$0000
MOV C,A
LXI H,SCR00
DAD B
DCX H
MOV A,M
RET
;
;乱数を発生します
;
RAND: NOP
LDA RAND256
MOV B,A
RLC
ANI FE
RLC
ANI FE
RLC
ANI FE
ADD B
ADD B
ADD B
ADD B
ADD B
ADI 05
STA RAND256
RET
;=================== 未作成 START ====================================
;掛算処理を行います
;※未作成
MULT: NOP
; A x A
; 1010
; x 1010
; --------
; 1010
; 1010
; --------
; 1100100
; =64h - 100
;
;#HL = #B x #C
LXI H,$0000
LXI D,$0000 ;#DE=#B
MOV E,B
MULT1: NOP
MOV A,C
ANI 01
JZ MULT2 ;IF Bit0=0 THEN MULT2
;
DAD D ;#HL=#HL+#DE
;
MULT2: NOP
MOV A,C ;#C= 76543210 -> 1Bit
RRC
MOV C,A
ORA A ;IF #C=0 THEN END
PUSH H ;#DE= <- 1Bit
DAD H
MOV H,D
MOV L,E
POP H
JMP MULT1
;
MULT_END: NOP
RET
;割算の処理を行います
;※未作成
;#HL=#BC / #A
DIV: NOP
; _________
; 1100) 0111000
;
LXI H,$0000
MOV H,A
DIV1: NOP
;HLとBCを比較
HLCPBC: NOP
MOV A,B
CMP H
JZ HLCPBC_HS ;IF #H=#B THEN HLCPBC_HS
RET
HLCPBC_HS: NOP
MOV A,C
CMP L
RET
;================== 未作成 END =====================================
ORG $9800 ;下位のみの演算しか行ってないので[XX00]なければならない
CHRTBL: DB 00;00
DB 00;01
DB 00;02
DB 00;03
DB 00;04
DB 00;05
DB 00;06
DB 00;07
DB 00;08
DB 00;09
DB 00;0A
DB 00;0B
DB 00;0C
DB 00;0D
DB 00;0E
DB 00;0F
DB 08;10 _
DB 5C;11 o
DB 7E;12 V
DB 3F;13 O
DB 5E;14
DB 7C;15
DB 1C;16 u
DB 3E;17 U
DB 3D;18 G
DB 77;19 A
DB 37;1A M
DB 79;1B E
DB 3F;1C O
DB 3E;1D V
DB 77;1E R
DB 00;1F
DB 00;20
DB 00;21
DB 00;22
DB 00;23
DB 00;24
DB 00;25
DB 00;26
DB 00;27
DB 00;28
DB 00;29
DB 00;2A
DB 00;2B
DB 00;2C
DB 00;2D
DB 00;2E
DB 00;2F
DB 3F;30 '0'
DB 06;31 '1'
DB 5B;32 '2'
DB 4F;33 '3'
DB 66;34 '4'
DB 6D;35 '5'
DB 7D;36 '6'
DB 27;37 '7'
DB 7F;38 '8'
DB 6F;39 '9'
DB 00;3A
DB 00;3B
DB 00;3C
DB 00;3D
DB 00;3E
DB 00;3F
DB 00;40
DB 00;41
DB 00;42
DB 00;43
DB 00;44
DB 00;45
DB 00;46
DB 00;47
DB 00;48
DB 00;49
DB 00;4A
DB 00;4B
DB 00;4C
DB 00;4D
DB 00;4E
DB 00;4F
DB 00;50
DB 00;51
DB 00;52
DB 00;53
DB 00;54
DB 00;55
DB 00;56
DB 00;57
DB 00;58
DB 00;59
DB 00;5A
DB 00;5B
DB 00;5C
DB 00;5D
DB 00;5E
DB 00;5F
DB 00;60
DB 00;61
DB 00;62
DB 00;63
DB 00;64
DB 00;65
DB 00;66
DB 00;67
DB 00;68
DB 00;69
DB 00;6A
DB 00;6B
DB 00;6C
DB 00;6D
DB 00;6E
DB 00;6F
DB 00;70
DB 00;71
DB 00;72
DB 00;73
DB 00;74
DB 00;75
DB 00;76
DB 00;77
DB 00;78
DB 00;79
DB 00;7A
DB 00;7B
DB 00;7C
DB 00;7D
DB 00;7E
DB 00;7F
RNDTBL: DB 30;00
DB 31;01
DB 32;02
DB 33;03
DB 34;04
DB 35;05
DB 36;06
DB 37;07
DB 38;08
DB 39;09
DB 30;10
DB 31;11
DB 32;12
DB 33;13
DB 34;14
DB 35;15
DB 36;16
DB 37;17
DB 38;18
DB 39;19
DB 30;10
DB 31;11
DB 32;12
DB 33;13
DB 34;14
DB 35;15
DB 36;16
DB 37;17
DB 38;18
DB 39;19
DB 30;20
DB 31;21
DB 32;22
DB 33;23
DB 34;24
DB 35;25
DB 36;26
DB 37;27
DB 38;28
DB 39;29
DB 30;30
DB 31;31
;END
|
とても楽しく、参考になるプログラムをお送りいただき、公開をご快諾いただいた、熊本県のK様に厚く御礼申し上げます。
今後ともよろしくお願いいたします。
8080マイコンをつくろう![第43回]
2017.2.6upload
前へ
ホームページトップへ戻る