ROMを作る

pp.121ff.、pp.240ff.

とてもテキストのような真似はできないのでマイコンで代用することにする。ついでにアセンブルもする。CPUと組み合わせたときにこれでうまくゆくかどうかはわからない。
f:id:ti-nspire:20201013111311p:plain:h250 f:id:ti-nspire:20201013110759j:plain:h250

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL

#define MOV_A(Im) ((0x3 << 4) | (Im)) // AレジスタにImを転送
#define MOV_B(Im) ((0x7 << 4) | (Im)) // BレジスタにImを転送
#define MOV_AB     (0x1 << 4)         // AレジスタにBレジスタを転送
#define MOV_BA     (0x4 << 4)         // BレジスタにAレジスタを転送
#define ADD_A(Im) ((0x0 << 4) | (Im)) // AレジスタにImを加算
#define ADD_B(Im) ((0x5 << 4) | (Im)) // BレジスタにImを加算
#define IN_A       (0x2 << 4)         // 入力ポートからAレジスタへ転送
#define IN_B       (0x6 << 4)         // 入力ポートからBレジスタへ転送
#define OUT(Im)   ((0xB << 4) | (Im)) // 出力ポートへImを転送
#define OUT_B      (0x9 << 4)         // 出力ポートへBレジスタを転送
#define JMP(Im)   ((0xF << 4) | (Im)) // Im番地へジャンプ
#define JNC(Im)   ((0xE << 4) | (Im)) // Cフラグが1ではないときにジャンプ

// アセンブルして排列に格納する。
volatile const uint8_t inst[16] = {
    OUT(0b0011),
    OUT(0b0110),
    OUT(0b1100),
    OUT(0b1000),
    OUT(0b1000),
    OUT(0b1100),
    OUT(0b0110),
    OUT(0b0011),
    OUT(0b0001),
    JMP(0),
};

// クロックのrising edgeのたびにアドレスに応じたデータを出力する。
ISR(INT0_vect){
    PORTB = inst[PINC & 0x0F];
}

int main(){
    DDRC &= ~0x0F; // PC3:0にアドレスを入力することにする。
    DDRB = 0xFF;   // PB7:0からデータを出力することにする。
    
    PORTC |= 0x0F; // PC3:0を内部プルアップする
    
    EIMSK |= (1 << INT0);                 // INT0 (外部割り込み要求0)を有効化する。
    EICRA |= (1 << ISC01) | (1 << ISC00); // rising edgeで割り込む。
    sei();                                // グローバル割り込みを有効化する。

    while(1);    
    return 0;
}