Good day
I have the following code.
void initUCode()
{
// ZF = 0, CF = 0
memcpy_P(ucode[FLAGS_Z0C0], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z0C0 = 0
// ZF = 0, CF = 1
memcpy_P(ucode[FLAGS_Z0C1], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z0C1 = 1
ucode[FLAGS_Z0C1][JC][2] = IOJ; //JC = 0111 JZ = 1000
// ZF = 1, CF = 0
memcpy_P(ucode[FLAGS_Z1C0], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z1C0 = 2
ucode[FLAGS_Z1C0][JZ][2] = IOJ;
// ZF = 1, CF = 1
memcpy_P(ucode[FLAGS_Z1C1], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z1C1 = 3
ucode[FLAGS_Z1C1][JC][2] = IOJ;
ucode[FLAGS_Z1C1][JZ][2] = IOJ;
}
After a lot of puzzling I finally figured out that the second block is overwriting the first block and the fourth block is overwriting the third block. How do I prevent this?
Here is the full code.
/**
* This sketch programs the microcode EEPROMs for the 8-bit breadboard computer
* It includes support for a flags register with carry and zero flags
* See this video for more: https://youtu.be/Zg1NdPKoosU
*/
#define SHIFT_DATA 2
#define SHIFT_CLK 3
#define SHIFT_LATCH 4
#define EEPROM_D0 5
#define EEPROM_D7 12
#define WRITE_EN 13
// Negative enabled control lines put out a 1 when disabled
// _ ______ _ ___
#define HLT 0b1101111110100111 // Halt clock
#define MICO 0b0001111110100011 // Memory address register in, Counter out
#define ROIICE 0b0100101110101111 // Ram out, Instruction in, Counter enable
#define IOMI 0b0001011110100111 // Instruction out, Memory in
#define IOAI 0b0101010110100111 // Instruction register out, A register in
#define IOJ 0b0101011110100101 // Instruction register out, Jump
#define AOOI 0b0101111010110111 // A register out, Output register in
#define ROAI 0b0100110110100111 // Ram out, A register in
#define ROBI 0b0100111110000111 // Ram out, B register in
#define AORI 0b0111111010100111 // A register out, Ram in
#define EOAIFI 0b0101110100100110 // Sum out, A register in, Flags in
#define EOAISUFI 0b0101110101100110 // Sum out, A register in, Subtract, Flags in
#define NOP 0b0101111110100111 // All controls off
#define FLAGS_Z0C0 0
#define FLAGS_Z0C1 1
#define FLAGS_Z1C0 2
#define FLAGS_Z1C1 3
#define JC 0b0111
#define JZ 0b1000
const PROGMEM uint16_t UCODE_TEMPLATE1[16][8] =
{
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 0000 - NOP
{ MICO, ROIICE, IOMI, ROAI, NOP, NOP, NOP, NOP }, // 0001 - LDA
{ MICO, ROIICE, IOMI, ROBI, EOAIFI, NOP, NOP, NOP }, // 0010 - ADD
{ MICO, ROIICE, IOMI, ROBI, EOAISUFI, NOP, NOP, NOP }, // 0011 - SUB
{ MICO, ROIICE, IOMI, AORI, NOP, NOP, NOP, NOP }, // 0100 - STA
{ MICO, ROIICE, IOAI, NOP, NOP, NOP, NOP, NOP }, // 0101 - LDI
{ MICO, ROIICE, IOJ, NOP, NOP, NOP, NOP, NOP }, // 0110 - JMP
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 0111 - JC
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 1000 - JZ
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 1001
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 1010
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 1011
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 1100
{ MICO, ROIICE, NOP, NOP, NOP, NOP, NOP, NOP }, // 1101
{ MICO, ROIICE, AOOI, NOP, NOP, NOP, NOP, NOP }, // 1110 - OUT
{ MICO, ROIICE, HLT, NOP, NOP, NOP, NOP, NOP }, // 1111 - HLT
};
uint16_t ucode[4][16][8];
void initUCode()
{
// ZF = 0, CF = 0
memcpy_P(ucode[FLAGS_Z0C0], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z0C0 = 0
//ZF = 0, CF = 1
memcpy_P(ucode[FLAGS_Z0C1], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z0C1 = 1
ucode[FLAGS_Z0C1][JC][2] = IOJ; //JC = 0111 JZ = 1000
// ZF = 1, CF = 0
memcpy_P(ucode[FLAGS_Z1C0], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z1C0 = 2
ucode[FLAGS_Z1C0][JZ][2] = IOJ;
// ZF = 1, CF = 1
memcpy_P(ucode[FLAGS_Z1C1], UCODE_TEMPLATE1, sizeof(UCODE_TEMPLATE1)); //FLAGS_Z1C1 = 3
ucode[FLAGS_Z1C1][JC][2] = IOJ;
ucode[FLAGS_Z1C1][JZ][2] = IOJ;
}
/*
* Output the address bits and outputEnable signal using shift registers.
*/
void setAddress(int address, bool outputEnable)
{
shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, (address >> 8) | (outputEnable ? 0x00 : 0x80));
shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address);
digitalWrite(SHIFT_LATCH, LOW);
digitalWrite(SHIFT_LATCH, HIGH);
digitalWrite(SHIFT_LATCH, LOW);
}
//Read a byte from the EEPROM at the specified address.
byte readEEPROM(int address)
{
for (int pin = EEPROM_D0; pin <= EEPROM_D7; pin += 1)
{
pinMode(pin, INPUT);
}
setAddress(address, /*outputEnable*/ true);
byte data = 0;
for (int pin = EEPROM_D7; pin >= EEPROM_D0; pin -= 1)
{
data = (data << 1) + digitalRead(pin);
}
return data;
}
//Write a byte to the EEPROM at the specified address.
void writeEEPROM(int address, byte data)
{
setAddress(address, /*outputEnable*/ false);
for (int pin = EEPROM_D0; pin <= EEPROM_D7; pin += 1)
{
pinMode(pin, OUTPUT);
}
for (int pin = EEPROM_D0; pin <= EEPROM_D7; pin += 1)
{
digitalWrite(pin, data & 1);
data = data >> 1;
}
digitalWrite(WRITE_EN, LOW);
delayMicroseconds(1);
digitalWrite(WRITE_EN, HIGH);
delay(10);
}
//Read the contents of the EEPROM and print them to the serial monitor.
void printContents(int start, int length)
{
for (int base = start; base < length; base += 16)
{
byte data[16];
for (int offset = 0; offset <= 15; offset += 1)
{
data[offset] = readEEPROM(base + offset);
}
char buf[80];
sprintf(buf, "%03x: %02x %02x %02x %02x %02x %02x %02x %02x, %02x %02x %02x %02x %02x %02x %02x %02x",
base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
Serial.println(buf);
}
}
void setup()
{
// put your setup code here, to run once:
initUCode();
pinMode(SHIFT_DATA, OUTPUT);
pinMode(SHIFT_CLK, OUTPUT);
pinMode(SHIFT_LATCH, OUTPUT);
digitalWrite(WRITE_EN, HIGH);
pinMode(WRITE_EN, OUTPUT);
Serial.begin(57600);
// Program data bytes
Serial.println("Programming EEPROM");
// Program the entire EEPROM
for (int address = 0; address < 1024; address += 1)
{
int flags = (address & 0b1100000000) >> 8;
int byte_sel = (address & 0b0010000000) >> 7;
int instruction = (address & 0b0001111000) >> 3;
int step = (address & 0b0000000111);
if (byte_sel)
{
writeEEPROM(address, ucode[flags][instruction][step]);
} else
{
writeEEPROM(address, ucode[flags][instruction][step] >> 8);
}
if (address % 64 == 0)
{
Serial.print(".");
}
}
Serial.println(" done");
//Read and print out the contents of the EEPROM
Serial.println("Reading EEPROM");
printContents(0, 1024);
}
void loop() {
// put your main code here, to run repeatedly:
}