この世のCPUを食べ尽くすのだ! 第4章 第2節
~あんたCPUなんか創ってどうするのよ?! Vol.3~
2018/10/8
技術書典5 け39
第4章 第2節 ラーメンタイマー
DEMOD: | ||||||
030: | 01 | ADD | A | 1 | ||
031: | E0 | JNC | DEMOC | |||
032: | 09 | |||||
; | ||||||
;ラーメンタイマー | ||||||
; | ||||||
033: | 70 | MOV | B | 0 | ||
034: | 96 | OUT | B | [6] | ||
035: | 7D | MOV | B | 0xD | ;3分 | |
LOOPD1: | ||||||
036: | 97 | OUT | B | [7] | ||
037: | 66 | IN | B | [6] | ||
038: | 9E | OUT | B | [0xE] | ||
039: | 51 | ADD | B | 1 | ||
03A: | 96 | OUT | B | [6] | ||
03B: | 71 | MOV | B | 1 | ||
03C: | 9F | OUT | B | [0xF] | ;分を出力 | |
03D: | 70 | MOV | B | 0 | ||
03E: | 94 | OUT | B | [4] | ||
03F: | 7A | MOV | B | 0xA | ;6回 | |
LOOPD2: | ||||||
040: | 95 | OUT | B | [5] | ||
041: | 64 | IN | B | [4] | ||
042: | 9E | OUT | B | [0xE] | ||
043: | 51 | ADD | B | 1 | ||
044: | 94 | OUT | B | [4] | ||
045: | 70 | MOV | B | 0 | ||
046: | 9F | OUT | B | [0xF] | ;10秒を出力 | |
047: | 70 | MOV | B | 0 | ||
048: | 92 | OUT | B | [2] | ||
049: | 76 | MOV | B | 0x6 | ;10回 | |
LOOPD3: | ||||||
04A: | 93 | OUT | B | [3] | ||
04B: | 78 | MOV | B | 8 | ;2回×0.5秒 | |
LOOPD4: | ||||||
04C: | 91 | OUT | B | [1] | ||
04D: | 9E | OUT | B | [0xE] | ||
04E: | 72 | MOV | B | 2 | ||
04F: | 9F | OUT | B | [0xF] | ;秒の点滅 | |
050: | 76 | MOV | B | 6 | ;10回 | |
051: | 3F | MOV | A | 0xF | ;初回は1回 | |
LOOPD5: | ||||||
052: | 01 | ADD | A | 1 | ||
053: | E2 | JNC | LOOPD5 | |||
054: | 05 | |||||
055: | 00 | ADD | A | 0 | ; NOP | |
056: | 30 | MOV | A | 0 | ;16回 | |
057: | 51 | ADD | B | 1 | ||
058: | E2 | JNC | LOOPD5 | |||
059: | 05 | |||||
05A: | 61 | IN | B | [1] | ||
05B: | 58 | ADD | B | 8 | ||
05C: | E0 | JNC | LABELD6 | |||
05D: | 06 | |||||
05E: | FC | JMP | LOOPD4 | |||
05F: | 04 | |||||
LABELD6: | ||||||
060: | 63 | IN | B | [3] | ||
061: | 51 | ADD | B | 1 | ||
062: | EA | JNC | LOOPD3 | |||
063: | 04 | |||||
064: | 65 | IN | B | [5] | ||
065: | 51 | ADD | B | 1 | ||
066: | E0 | JNC | LOOPD2 | |||
067: | 04 | |||||
068: | 67 | IN | B | [7] | ||
069: | 51 | ADD | B | 1 | ||
06A: | E6 | JNC | LOOPD1 | |||
06B: | 03 | |||||
06C: | 70 | MOV | B | 0 | ;3分経過 | |
06D: | 9E | OUT | B | [0xE] | ||
06E: | 9F | OUT | B | [0xF] | ||
06F: | 73 | MOV | B | 3 | ||
070: | 9E | OUT | B | [0xE] | ||
071: | 71 | MOV | B | 1 | ||
072: | 9F | OUT | B | [0xF] | ||
073: | 70 | MOV | B | 0 | ||
074: | 9E | OUT | B | [0xE] | ||
LOOPD7: | ||||||
075: | 2E | IN | A | [0xE] | ;任意のキー | |
076: | 01 | ADD | A | 1 | ;で終了 | |
077: | EB | JNC | LOOPD8 | |||
078: | 07 | |||||
079: | F5 | JMP | LOOPD7 | |||
07A: | 07 | |||||
LOOPD8: | ||||||
07B: | 2E | IN | A | [0xE] | ||
07C: | 01 | ADD | A | 1 | ||
07D: | EB | JNC | LOOPD8 | |||
07E: | 07 | |||||
07F: | F0 | JMP | INIT | |||
080: | 00 |
やることは単純ですが、TD4EX3ではクロック周波数を1kHzにしたために苦労しました。4ビットCPUであるTD4EX3では4ビットのカウンタしか作れないので、1秒をカウントするためには3重のループが必要になりました。しかも減算命令が無いので、インクリメントによるカウントを使っています。
例えば1分のループを3回繰り返して3分を測定する場合、初期値をDとし、ループを回るごとに1を加算してインクリメントを行い、3回目のループでキャリーが発生した時点で終了としています。
インクリメントするのではなくFを加算することで2の補数の-1を加算させ、デクリメントを行う方法も考えられますが、条件ジャンプ命令がJNCしかないので止めました。