この世の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しかないので止めました。