Alt8800 — 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.

Sketch code

#include <Arduino.h>
#include "I8080.h"

I8080 cpu;
static int passed = 0, failed = 0;

void check(bool ok, const char* name) {
  if (ok) {
    Serial.printf("[PASS] %s\n", name);
    passed++;
  } else {
    Serial.printf("[FAIL] %s\n", name);
    failed++;
  }
}

bool runSafe(I8080& c, const uint8_t* p, size_t n, const char* testName, uint32_t maxSteps = 200) {
  c.reset();
  c.load(p, 0, n);
  for (uint32_t steps = 0; steps < maxSteps; ++steps) {
    if (c.halted) return true;
    c.step();
  }
  Serial.printf("[TIMEOUT] %s PC=%04X SP=%04X A=%02X F=%02X\n",
                testName, c.PC, c.SP, c.A, c.F);
  return false;
}

void testDataTransfer() {
  Serial.println("Running: data transfer");
  Serial.flush();

  const uint8_t program[] = {
    0x01, 0x34, 0x12,  // LXI B,1234H
    0x11, 0x78, 0x56,  // LXI D,5678H
    0x21, 0x00, 0x20,  // LXI H,2000H
    0x22, 0x00, 0x30,  // SHLD 3000H
    0x2A, 0x00, 0x30,  // LHLD 3000H
    0x76               // HLT
  };

  bool stopped = runSafe(
    cpu,
    program,
    sizeof(program),
    "data transfer");

  check(
    stopped && cpu.B == 0x12 && cpu.C == 0x34 && cpu.D == 0x56 && cpu.E == 0x78 && cpu.H == 0x20 && cpu.L == 0x00 && cpu.memory[0x3000] == 0x00 && cpu.memory[0x3001] == 0x20,
    "data transfer and direct memory");
}

void testPairMath() {
  Serial.println("Running: pair arithmetic");
  // I8080 c;
  // Remove this:
  // I8080 c;

  // Use this:
  I8080& c = cpu;
  const uint8_t p[] = { 0x01, 0xFF, 0xFF, 0x21, 0x01, 0x00, 0x09, 0x76 };
  bool stopped = runSafe(c, p, sizeof(p), "pair arithmetic");
  check(stopped && c.H == 0x00 && c.L == 0x00 && (c.F & 1), "16-bit pair arithmetic and carry");
}

void testRotateSpecial() {
  Serial.println("Running: rotates");
  // I8080 c;
  // Remove this:
  // I8080 c;

  // Use this:
  I8080& c = cpu;
  const uint8_t p[] = { 0x3E, 0x81, 0x07, 0x0F, 0x17, 0x1F, 0x2F, 0x37, 0x3F, 0x76 };
  bool stopped = runSafe(c, p, sizeof(p), "rotates");
  check(stopped && c.A == 0x7E, "rotates and accumulator specials");
}

void testPSWOLD() {
  Serial.println("Running: PSW");
  // I8080 c;
  // Remove this:
  // I8080 c;

  // Use this:
  I8080& c = cpu;
  const uint8_t p[] = { 0x31, 0x00, 0x40, 0x3E, 0x80, 0xC6, 0x80, 0xF5, 0x3E, 0x00, 0xF1, 0x76 };
  bool stopped = runSafe(c, p, sizeof(p), "PSW");
  Serial.printf(
    "PSW result: A=%02X F=%02X SP=%04X\n",
    c.A, c.F, c.SP);

  Serial.printf(
    "Flags: S=%d Z=%d AC=%d P=%d C=%d\n",
    (c.F & 0x80) != 0,
    (c.F & 0x40) != 0,
    (c.F & 0x10) != 0,
    (c.F & 0x04) != 0,
    (c.F & 0x01) != 0);

  check(
    stopped && c.A == 0x00 && (c.F & 0x40) && (c.F & 0x01) && !(c.F & 0x10) && !(c.F & 0x80),
    "PUSH/POP PSW");
}

void testPSW() {
  Serial.println("Running: PSW");
  I8080& c = cpu;

  const uint8_t p[] = {
    0x3E, 0x80,  // MVI A,80H
    0xC6, 0x80,  // ADI 80H => A=00, flags should be Z/P/C
    0x76         // HLT
  };

  bool stopped = runSafe(c, p, sizeof(p), "ADI");

  Serial.printf(
    "ADI resul

More projects by alireza-cs94