C4004fam — Esp32 Devkit C V4 simulation

An interactive Esp32 Devkit C V4 circuit simulation you can run free in your browser on Velxio, by alireza-cs94.

Components

Sketch code

#include <Arduino.h>
#include "MCS4Bus.hpp"
#include "Intel4004.hpp"
#include "Intel4001.hpp"
#include "Intel4002.hpp"
#include "Intel4003.hpp"
#include "GPIODevice.hpp"
#include "Assembler4004.hpp"

// -----------------------------------------------------------------------
// Reads two decimal numbers of ANY length from the Serial Monitor and
// adds them using the 4004's own decimal-arithmetic mechanism: for each
// digit position (least significant first), it runs
//     LDM a_digit; XCH R0; LDM b_digit; ADD R0; DAA
// on the real CPU core. ADD produces a raw 4-bit sum (which can exceed
// 9), and DAA decimal-adjusts it back into a single digit, setting the
// carry flag if a decimal carry needs to ripple into the next digit -
// exactly like doing long addition by hand. Requires the DAA fix that
// makes it actually set carry on overflow (see Intel4004.cpp).
//
// HOW TO USE: rename this file to .ino (and rename whichever file
// currently has setup()/loop() to something else - only one .ino with
// setup()/loop() can be active at a time). Upload, then open Serial
// Monitor at 115200 baud with "Newline" line ending set.
// -----------------------------------------------------------------------

MCS4Bus bus;
Intel4004 cpu;
Intel4001* rom0;
Intel4002* ram0;
GPIODevice* led0;
Assembler4004 asm4;

String readDigits(const char* prompt) {
  Serial.println(prompt);
  while (!Serial.available()) {
    delay(10);
  }
  String line = Serial.readStringUntil('\n');
  line.trim();

  // Strip anything that isn't a digit (handles stray spaces, minus signs, etc.)
  String clean = "";
  for (unsigned int i = 0; i < line.length(); i++) {
    if (isdigit(line[i])) clean += line[i];
  }
  if (clean.length() == 0) clean = "0";

  Serial.print("  got: ");
  Serial.println(clean);
  return clean;
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  static uint8_t emptyROM[256] = { 0 };
  led0 = new GPIODevice(2);
  rom0 = new Intel4001(emptyROM, led0);
  ram0 = new Intel4002();

  bus.romChips[0] = rom0;
  bus.ramChips[0] = ram0;
  bus.ioPorts[0] = led0;
  cpu.attachBus(&bus);

  Serial.println("===== Intel4004 Serial Adder (any length) =====");
  Serial.println("Adds two decimal numbers of any size, one digit at a time,");
  Serial.println("using the 4004's own ADD + DAA decimal-carry mechanism.");
}

void loop() {
  String a = readDigits("Enter first number:");
  String b = readDigits("Enter second number:");

  int len = max(a.length(), b.length());
  // Left-pad the shorter number with zeros so both are the same length.
  while ((int)a.length() < len) a = "0" + a;
  while ((int)b.length() < len) b = "0" + b;

  String resultDigits = "";
  cpu.reset();  // carry = 0 going into the least-significant digit

  for (int i = len - 1; i >= 0; i--) {
    int digitA = a[i] - '0';
    int digitB = b[i] - '0';

    String src =
      "  LDM " + String(digitA) + "\n"
                                  "  XCH R0\n"
                                  "  LDM "
      + 

More projects by alireza-cs94