パチパチマイコンを作ろう!(その6)
ハードウェアが完成しました。タクトスイッチの入力と 7 セグの表示は問題なく動作しているようなので,これらを制御するプログラムを入力していきます。
256 バイトは意外と少ないよ
積んでいるメモリは物理的に 8KB (キロバイト)あるのですが,さすがにそこまでスイッチで入力するわけにも行かないので,アドレス指定は,256 バイトまでにしています。(アドレススイッチ 8 個)
256 バイトと言っても,スイッチパチパチで入力するのは,結構大変です。
しかも,メモリにはライトプロテクトがありませんので,入力ミスをして,実行させたプログラムが暴走すると,せっかく入力したプログラムが,あっという間に上書き破壊されてしまいます。(何回かやって泣きたくなった…)
それでも,ちょっとしたプログラムだと 256 バイトはすぐに使ってしまうんですね。
まずは,何かしら動作がわかるプログラムを作ってみました。
1 ;-*- coding: utf-8-unix -*- 2 3 .psize 0 4 5 MODE_STOP = 0 6 MODE_RUN = 1 7 MODE_END = 2 8 9 .text 10 11 ;=============================================================================== 12 ; エントリポイント 13 ;=============================================================================== 14 .org $0000 15 start: 16 0000 00 nop 17 0001 3100 01 ld sp,$0100 18 0004 ED56 im 1 19 20 0006 21F0 00 ld hl,intCounter+0 21 0009 11F1 00 ld de,intCounter+1 22 000c 010F 00 ld bc,16-1 23 000f 3600 ld (hl),0 24 0011 EDB0 ldir 25 26 0013 21F2 00 ld hl,secCounter 27 0016 3E10 ld a,$10 28 0018 77 ld (hl),a 29 0019 23 inc hl 30 001a 3E00 ld a,$00 31 001c 77 ld (hl),a 32 33 001d FB ei 34 1: 35 001e 18FE jr 1b 36 37 ;=============================================================================== 38 ; 7seg データ変換 39 ;=============================================================================== 40 get7segData: 41 0020 D9 exx 42 0021 E60F and %00001111 43 0023 21E0 00 ld hl,segmentTable 44 0026 85 add a,l 45 0027 6F ld l,a 46 0028 7E ld a,(hl) 47 0029 D9 exx 48 002a C9 ret 49 50 ;=============================================================================== 51 ; ジャンプテーブル 52 ;=============================================================================== 53 jumpTable: 54 002b 9C00 .word modeStop 55 002d A800 .word modeRun 56 002f DD00 .word modeEnd 57 58 ;=============================================================================== 59 ; 割り込みルーチン 60 ;=============================================================================== 61 0031 0000 0000 .org $0038 61 0000 00 62 interrupt: 63 0038 21F5 00 ld hl,buttonData 64 003b DB00 in a,($00) 65 003d 2F cpl 66 003e 5F ld e,a 67 003f AE xor (hl) 68 0040 A3 and e 69 0041 73 ld (hl),e 70 0042 23 inc hl 71 0043 77 ld (hl),a 72 73 0044 2156 00 ld hl,1f 74 0047 E5 push hl 75 76 0048 3AF4 00 ld a,(mode) 77 004b 07 rlca 78 004c 212B 00 ld hl,jumpTable 79 004f 85 add a,l 80 0050 6F ld l,a 81 0051 7E ld a,(hl) 82 0052 23 inc hl 83 0053 66 ld h,(hl) 84 0054 6F ld l,a 85 0055 E9 jp (hl) 86 1: 87 0056 3AF4 00 ld a,(mode) 88 0059 FE02 cp MODE_END 89 005b 2014 jr nz,2f 90 91 005d 21F0 00 ld hl,intCounter 92 0060 34 inc (hl) 93 0061 7E ld a,(hl) 94 0062 E602 and %00000010 95 0064 280B jr z,2f 96 97 0066 AF xor a 98 0067 D300 out ($00),a 99 0069 D301 out ($01),a 100 006b D302 out ($02),a 101 006d D303 out ($03),a 102 006f 1829 jr 9f 103 2: 104 0071 21F2 00 ld hl,secCounter 105 0074 7E ld a,(hl) 106 0075 23 inc hl 107 0076 5F ld e,a 108 0077 CD20 00 call get7segData 109 007a D300 out ($00),a 110 007c 7B ld a,e 111 007d 0F rrca 112 007e 0F rrca 113 007f 0F rrca 114 0080 0F rrca 115 0081 CD20 00 call get7segData 116 0084 D301 out ($01),a 117 118 0086 7E ld a,(hl) 119 0087 23 inc hl 120 0088 5F ld e,a 121 0089 CD20 00 call get7segData 122 008c F601 or %00000001 123 008e D302 out ($02),a 124 0090 7B ld a,e 125 0091 0F rrca 126 0092 0F rrca 127 0093 0F rrca 128 0094 0F rrca 129 0095 CD20 00 call get7segData 130 0098 D303 out ($03),a 131 9: 132 009a FB ei 133 009b C9 ret 134 135 ;=============================================================================== 136 ; 停止モード 137 ;=============================================================================== 138 modeStop: 139 009c 3AF6 00 ld a,(buttonEdge) 140 009f E601 and %00000001 141 00a1 C8 ret z 142 143 00a2 3E01 ld a,MODE_RUN 144 00a4 32F4 00 ld (mode),a 145 00a7 C9 ret 146 147 ;=============================================================================== 148 ; 実行モード 149 ;=============================================================================== 150 modeRun: 151 00a8 3AF6 00 ld a,(buttonEdge) 152 00ab E601 and %00000001 153 00ad 2806 jr z,1f 154 155 00af 3E00 ld a,MODE_STOP 156 00b1 32F4 00 ld (mode),a 157 00b4 C9 ret 158 1: 159 00b5 21F3 00 ld hl,minCounter 160 00b8 7E ld a,(hl) 161 00b9 2B dec hl 162 00ba B6 or (hl) 163 00bb 2006 jr nz,1f 164 165 00bd 3E02 ld a,MODE_END 166 00bf 32F4 00 ld (mode),a 167 00c2 C9 ret 168 1: 169 00c3 2B dec hl 170 00c4 34 inc (hl) 171 00c5 7E ld a,(hl) 172 00c6 FE4B cp 75 173 00c8 D8 ret c 174 175 00c9 3600 ld (hl),0 176 00cb 23 inc hl 177 178 00cc 7E ld a,(hl) 179 00cd D601 sub 1 180 00cf 27 daa 181 00d0 77 ld (hl),a 182 00d1 D0 ret nc 183 184 00d2 3659 ld (hl),$59 185 00d4 23 inc hl 186 187 00d5 7E ld a,(hl) 188 00d6 D601 sub 1 189 00d8 27 daa 190 00d9 77 ld (hl),a 191 00da D0 ret nc 192 193 00db 3659 ld (hl),$59 194 modeEnd: 195 00dd C9 ret 196 197 ;=============================================================================== 198 ; 7seg テーブル 199 ;=============================================================================== 200 00de 0000 .org $00E0 201 segmentTable: 202 00e0 FC .byte %11111100 ; 0 203 00e1 60 .byte %01100000 ; 1 204 00e2 DA .byte %11011010 ; 2 205 00e3 F2 .byte %11110010 ; 3 206 00e4 66 .byte %01100110 ; 4 207 00e5 B6 .byte %10110110 ; 5 208 00e6 BE .byte %10111110 ; 6 209 00e7 E4 .byte %11100100 ; 7 210 00e8 FE .byte %11111110 ; 8 211 00e9 F6 .byte %11110110 ; 9 212 00ea EE .byte %11101110 ; A 213 00eb 3E .byte %00111110 ; B 214 00ec 9C .byte %10011100 ; C 215 00ed 7A .byte %01111010 ; D 216 00ee 9E .byte %10011110 ; E 217 00ef 8E .byte %10001110 ; F 218 219 ;=============================================================================== 220 ; ワークエリア 221 ;=============================================================================== 222 .org $00F0 223 224 00f0 00 intCounter: .space 1 225 00f1 00 freqCounter: .space 1 226 00f2 00 secCounter: .space 1 227 00f3 00 minCounter: .space 1 228 00f4 00 mode: .space 1 229 00f5 00 buttonData: .space 1 230 00f6 00 buttonEdge: .space 1
- モード 1 の割り込みを使っているので,割り込みハンドラは,$0038 固定です。
- アセンブラは,gnu のアセンブラ(gas)です。
- 7seg の表示データは,BCD で格納しています。
やっぱり,タイマーですかね
お馴染みの(?)タイマーを作ります。
一応 7 セグで残りカウントが表示されるので,何か危ないものにも見えま………せんね。
時間は CPU のクロック(2.4576MHz)を分周して作ります。
このクロックを,カウンタ IC 2 個使ってカウントします。
32768 回カウントすると,13.33 ミリ秒,つまり 75Hz の信号になるので,これを CPU の割り込み信号として入力してやります。
CPU 側では,割り込みがかかるたびに,これをカウントし,75 回割り込みが入ると,1 秒になるわけです。
動作させるとこうなります
今のワンチップマイコンだと多分,制御部分はマイコン 1 個だけでできると思います。
プログラムもフラッシュが内蔵されているだろうから誤って消える心配もありません。
なんか,時間をかけて,たくさんの部品を使って,おまけにプログラムを暴走させて,入力を何回もやり直して作った割には,これかよ…。
って…,いいんです。
こんな古典的で初歩的な工作でも,完成した時はやっぱり嬉しいし,毎回何かしらの発見があるので,楽しいんです。
パチパチマイコンは,これで一応完成です。
これでも一応 8bit のコンピュータですが,次は,もう少しコンピュータっぽいものでも作ろうかな…と思います。(多分,また Z80 使うんだろうけど…)