vchip8/test_main.cpp

138 lines
3.4 KiB
C++

#include "Vcpu.h"
#include "Vcpu_cpu.h"
#include "verilated.h"
Vcpu *top;
void dump_regs(void)
{
printf("-> regs:\n");
for (int i = 0; i < 8; i++)
printf(" %i: 0x%02x\n", i, top->v->vr[i]);
}
void step(void)
{
top->cpu_clock = 0;
top->eval();
top->cpu_clock = 1;
top->eval();
}
void step3(void)
{
step(); step(); step();
}
void run_instruction(uint16_t instruction)
{
top->v->ram[0] = instruction >> 8;
top->v->ram[1] = instruction & 0xFF;
top->v->pc = 0;
}
void reset(void)
{
top->reset = 0;
step3(); step3();
top->reset = 1;
}
void test_alu_instruction(uint8_t x, uint8_t y, uint16_t ins, uint8_t expected)
{
printf("INS %04x: ", ins);
reset();
top->v->vr[1] = x;
top->v->vr[2] = y;
run_instruction(ins);
step3();
if (top->v->vr[1] != expected)
printf(" FAIL! Expected %02x, got %02x.\n", expected, top->v->vr[1]);
else
printf(" OK.\n");
}
void test_alu_instruction_vf(uint8_t x, uint8_t y, uint16_t ins, uint8_t expected, uint8_t evf)
{
printf("INS %04x: ", ins);
reset();
top->v->vr[1] = x;
top->v->vr[2] = y;
run_instruction(ins);
step3();
if (top->v->vr[1] != expected)
printf(" FAIL! Expected %02x, got %02x.\n", expected, top->v->vr[1]);
else
{
if (top->v->vr[15] != evf)
printf(" FAIL! Expected VF %02x, got %02x.\n", evf, top->v->vr[15]);
else
printf(" OK.\n");
}
}
int main(int argc, char **argv)
{
Verilated::commandArgs(argc, argv);
top = new Vcpu;
// LD
printf("LD ");
test_alu_instruction(0x00, 0x45, 0x8120, 0x45);
// OR
printf("OR ");
test_alu_instruction(0x0F, 0xF0, 0x8121, 0xFF);
// AND
printf("AND ");
test_alu_instruction(0xF0, 0x45, 0x8122, 0x40);
// XOR
printf("XOR ");
test_alu_instruction(0xFF, 0x11, 0x8123, 0xEE);
// ADD
printf("ADD (no carry) ");
test_alu_instruction_vf(0x10, 0x25, 0x8124, 0x35, 0x00);
printf("ADD (with carry) ");
test_alu_instruction_vf(0xF0, 0x43, 0x8124, 0x33, 0x01);
// SUB
printf("SUB (no borrow) ");
test_alu_instruction_vf(0x45, 0x15, 0x8125, 0x30, 0x01);
printf("SUB (zero, no borrow) ");
test_alu_instruction_vf(0x45, 0x45, 0x8125, 0x00, 0x01);
printf("SUB (borrow) ");
test_alu_instruction_vf(0x15, 0x45, 0x8125, 0xD0, 0x00);
// SHR
printf("SHR (one) ");
test_alu_instruction_vf(0x45, 0x00, 0x8126, 0x45>>1, 0x01);
printf("SHR (zero) ");
test_alu_instruction_vf(0x44, 0x00, 0x8126, 0x44>>1, 0x00);
// SUBN
printf("SUBN (no borrow) ");
test_alu_instruction_vf(0x15, 0x45, 0x8127, 0x30, 0x01);
printf("SUBN (zero, no borrow) ");
test_alu_instruction_vf(0x45, 0x45, 0x8127, 0x00, 0x01);
printf("SUBN (borrow) ");
test_alu_instruction_vf(0x45, 0x15, 0x8127, 0xD0, 0x00);
// SHL
printf("SHL (one) ");
test_alu_instruction_vf(0xA4, 0x00, 0x812E, (0xA4<<1)&0xFF, 0x01);
printf("SHL (zero) ");
test_alu_instruction_vf(0x24, 0x00, 0x812E, (0x24<<1)&0xFF, 0x00);
printf("PC increment: ");
reset();
run_instruction(0x0000); // NOP
step3();
if (top->v->pc != 0x2)
printf(" FAIL!\n");
else
printf(" OK.\n");
printf("JMP imm INS 1456: ");
reset();
run_instruction(0x1456);
step3();
if (top->v->pc != 0x456)
printf(" FAIL!\n");
else
printf(" OK.\n");
}