POC
This commit is contained in:
parent
72ee580d19
commit
93119054fa
6 changed files with 132 additions and 21 deletions
12
bus.cpp
12
bus.cpp
|
@ -269,7 +269,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
if (a == ADDR_KERNEL_SP) { // kernel SP
|
if (a == ADDR_KERNEL_SP) { // kernel SP
|
||||||
uint16_t temp = c->getStackPointer(0) & (word_mode == wm_byte ? 0xff : 0xffff);
|
uint16_t temp = c->get_stackpointer(0) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
TRACE("READ-I/O kernel SP: %06o", temp);
|
TRACE("READ-I/O kernel SP: %06o", temp);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
@ -279,12 +279,12 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
if (a == ADDR_SV_SP) { // supervisor SP
|
if (a == ADDR_SV_SP) { // supervisor SP
|
||||||
uint16_t temp = c->getStackPointer(1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
uint16_t temp = c->get_stackpointer(1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
TRACE("READ-I/O supervisor SP: %06o", temp);
|
TRACE("READ-I/O supervisor SP: %06o", temp);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
if (a == ADDR_USER_SP) { // user SP
|
if (a == ADDR_USER_SP) { // user SP
|
||||||
uint16_t temp = c->getStackPointer(3) & (word_mode == wm_byte ? 0xff : 0xffff);
|
uint16_t temp = c->get_stackpointer(3) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
TRACE("READ-I/O user SP: %06o", temp);
|
TRACE("READ-I/O user SP: %06o", temp);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
@ -625,7 +625,7 @@ bool bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t va
|
||||||
}
|
}
|
||||||
if (a == ADDR_KERNEL_SP) { // kernel SP
|
if (a == ADDR_KERNEL_SP) { // kernel SP
|
||||||
TRACE("WRITE-I/O kernel SP: %06o", value);
|
TRACE("WRITE-I/O kernel SP: %06o", value);
|
||||||
c->setStackPointer(0, value);
|
c->set_stackpointer(0, value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (a == ADDR_PC) { // PC
|
if (a == ADDR_PC) { // PC
|
||||||
|
@ -635,12 +635,12 @@ bool bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t va
|
||||||
}
|
}
|
||||||
if (a == ADDR_SV_SP) { // supervisor SP
|
if (a == ADDR_SV_SP) { // supervisor SP
|
||||||
TRACE("WRITE-I/O supervisor sp: %06o", value);
|
TRACE("WRITE-I/O supervisor sp: %06o", value);
|
||||||
c->setStackPointer(1, value);
|
c->set_stackpointer(1, value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (a == ADDR_USER_SP) { // user SP
|
if (a == ADDR_USER_SP) { // user SP
|
||||||
TRACE("WRITE-I/O user sp: %06o", value);
|
TRACE("WRITE-I/O user sp: %06o", value);
|
||||||
c->setStackPointer(3, value);
|
c->set_stackpointer(3, value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,13 @@
|
||||||
console_posix::console_posix(std::atomic_uint32_t *const stop_event): console(stop_event)
|
console_posix::console_posix(std::atomic_uint32_t *const stop_event): console(stop_event)
|
||||||
{
|
{
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1)
|
if (tcgetattr(STDIN_FILENO, &org_tty_opts) == -1 && errno != ENOTTY)
|
||||||
error_exit(true, "console_posix: tcgetattr failed");
|
error_exit(true, "console_posix: tcgetattr failed");
|
||||||
|
|
||||||
struct termios tty_opts_raw { };
|
struct termios tty_opts_raw { };
|
||||||
cfmakeraw(&tty_opts_raw);
|
cfmakeraw(&tty_opts_raw);
|
||||||
|
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw) == -1)
|
if (tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw) == -1 && errno != ENOTTY)
|
||||||
error_exit(true, "console_posix: tcsetattr failed");
|
error_exit(true, "console_posix: tcsetattr failed");
|
||||||
|
|
||||||
setvbuf(stdin, nullptr, _IONBF, 0);
|
setvbuf(stdin, nullptr, _IONBF, 0);
|
||||||
|
@ -37,7 +37,7 @@ console_posix::~console_posix()
|
||||||
stop_thread();
|
stop_thread();
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &org_tty_opts) == -1)
|
if (tcsetattr(STDIN_FILENO, TCSANOW, &org_tty_opts) == -1 && errno != ENOTTY)
|
||||||
error_exit(true, "~console_posix: tcsetattr failed");
|
error_exit(true, "~console_posix: tcsetattr failed");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,6 @@ int console_posix::wait_for_char_ll(const short timeout)
|
||||||
void console_posix::put_char_ll(const char c)
|
void console_posix::put_char_ll(const char c)
|
||||||
{
|
{
|
||||||
printf("%c", c);
|
printf("%c", c);
|
||||||
|
|
||||||
fflush(nullptr);
|
fflush(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
cpu.cpp
8
cpu.cpp
|
@ -98,9 +98,7 @@ uint64_t cpu::get_instructions_executed_count() const
|
||||||
std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_in) const
|
std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_in) const
|
||||||
{
|
{
|
||||||
uint64_t instr_count = instruction_count.has_value() ? instruction_count.value() : get_instructions_executed_count();
|
uint64_t instr_count = instruction_count.has_value() ? instruction_count.value() : get_instructions_executed_count();
|
||||||
|
|
||||||
uint64_t t_diff = t_diff_in.has_value() ? t_diff_in.value() : (get_us() - running_since - wait_time);
|
uint64_t t_diff = t_diff_in.has_value() ? t_diff_in.value() : (get_us() - running_since - wait_time);
|
||||||
|
|
||||||
double mips = t_diff ? instr_count / double(t_diff) : 0;
|
double mips = t_diff ? instr_count / double(t_diff) : 0;
|
||||||
|
|
||||||
return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time };
|
return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time };
|
||||||
|
@ -117,7 +115,6 @@ void cpu::add_to_stack_trace(const uint16_t p)
|
||||||
auto da = disassemble(p);
|
auto da = disassemble(p);
|
||||||
|
|
||||||
stacktrace.push_back({ p, da["instruction-text"][0] });
|
stacktrace.push_back({ p, da["instruction-text"][0] });
|
||||||
|
|
||||||
while (stacktrace.size() >= max_stacktrace_depth)
|
while (stacktrace.size() >= max_stacktrace_depth)
|
||||||
stacktrace.erase(stacktrace.begin());
|
stacktrace.erase(stacktrace.begin());
|
||||||
}
|
}
|
||||||
|
@ -136,11 +133,14 @@ std::vector<std::pair<uint16_t, std::string> > cpu::get_stack_trace() const
|
||||||
void cpu::reset()
|
void cpu::reset()
|
||||||
{
|
{
|
||||||
memset(regs0_5, 0x00, sizeof regs0_5);
|
memset(regs0_5, 0x00, sizeof regs0_5);
|
||||||
memset(sp, 0x00, sizeof sp);
|
memset(sp, 0x00, sizeof sp );
|
||||||
pc = 0;
|
pc = 0;
|
||||||
psw = 0; // 7 << 5;
|
psw = 0; // 7 << 5;
|
||||||
fpsr = 0;
|
fpsr = 0;
|
||||||
init_interrupt_queue();
|
init_interrupt_queue();
|
||||||
|
|
||||||
|
it_is_a_trap = false;
|
||||||
|
processing_trap_depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t cpu::get_register(const int nr) const
|
uint16_t cpu::get_register(const int nr) const
|
||||||
|
|
7
cpu.h
7
cpu.h
|
@ -179,8 +179,10 @@ public:
|
||||||
uint16_t getStackLimitRegister() { return stackLimitRegister; }
|
uint16_t getStackLimitRegister() { return stackLimitRegister; }
|
||||||
void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; }
|
void setStackLimitRegister(const uint16_t v) { stackLimitRegister = v; }
|
||||||
|
|
||||||
uint16_t getStackPointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; }
|
uint16_t get_stackpointer(const int which) const { assert(which >= 0 && which < 4); return sp[which]; }
|
||||||
uint16_t getPC() const { return pc; }
|
uint16_t getPC() const { return pc; }
|
||||||
|
void set_stackpointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; }
|
||||||
|
void setPC(const uint16_t value) { pc = value; }
|
||||||
|
|
||||||
void set_register(const int nr, const uint16_t value);
|
void set_register(const int nr, const uint16_t value);
|
||||||
void set_registerLowByte(const int nr, const word_mode_t word_mode, const uint16_t value);
|
void set_registerLowByte(const int nr, const word_mode_t word_mode, const uint16_t value);
|
||||||
|
@ -191,9 +193,6 @@ public:
|
||||||
void lowlevel_psw_set(const uint16_t value) { psw = value; }
|
void lowlevel_psw_set(const uint16_t value) { psw = value; }
|
||||||
uint16_t lowlevel_register_sp_get(const uint8_t nr) const { return sp[nr]; }
|
uint16_t lowlevel_register_sp_get(const uint8_t nr) const { return sp[nr]; }
|
||||||
|
|
||||||
void setStackPointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; }
|
|
||||||
void setPC(const uint16_t value) { pc = value; }
|
|
||||||
|
|
||||||
uint16_t get_register(const int nr) const;
|
uint16_t get_register(const int nr) const;
|
||||||
|
|
||||||
bool put_result(const gam_rc_t & g, const uint16_t value);
|
bool put_result(const gam_rc_t & g, const uint16_t value);
|
||||||
|
|
37
debugger.cpp
37
debugger.cpp
|
@ -729,6 +729,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
int32_t trace_start_addr = -1;
|
int32_t trace_start_addr = -1;
|
||||||
int n_single_step = 1;
|
int n_single_step = 1;
|
||||||
bool turbo = false;
|
bool turbo = false;
|
||||||
|
bool marker = false;
|
||||||
std::optional<int> t_rl; // trace runlevel
|
std::optional<int> t_rl; // trace runlevel
|
||||||
|
|
||||||
cpu *const c = b->getCpu();
|
cpu *const c = b->getCpu();
|
||||||
|
@ -739,6 +740,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
|
|
||||||
while(*stop_event != EVENT_TERMINATE) {
|
while(*stop_event != EVENT_TERMINATE) {
|
||||||
try {
|
try {
|
||||||
|
if (marker)
|
||||||
|
cnsl->put_string_lf("---");
|
||||||
|
|
||||||
std::string cmd = cnsl->read_line(format("%d", stop_event->load()));
|
std::string cmd = cnsl->read_line(format("%d", stop_event->load()));
|
||||||
auto parts = split(cmd, " ");
|
auto parts = split(cmd, " ");
|
||||||
auto kv = split(parts, "=");
|
auto kv = split(parts, "=");
|
||||||
|
@ -751,7 +755,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
|
|
||||||
*stop_event = EVENT_NONE;
|
*stop_event = EVENT_NONE;
|
||||||
}
|
}
|
||||||
else if (parts[0] == "single" || parts[0] == "s") {
|
else if (cmd == "marker")
|
||||||
|
marker = !marker;
|
||||||
|
else if (parts[0] == "single" || parts[0] == "s" || parts[0] == "step") {
|
||||||
single_step = true;
|
single_step = true;
|
||||||
|
|
||||||
if (parts.size() == 2)
|
if (parts.size() == 2)
|
||||||
|
@ -860,6 +866,32 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (parts[0] == "setstack") {
|
||||||
|
if (parts.size() == 3) {
|
||||||
|
int reg = std::stoi(parts.at(1));
|
||||||
|
uint16_t val = std::stoi(parts.at(2), nullptr, 8);
|
||||||
|
if (reg < 4) {
|
||||||
|
c->set_stackpointer(reg, val);
|
||||||
|
cnsl->put_string_lf(format("Set stack register %d to %06o", reg, val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cnsl->put_string_lf("setstack requires a register and an octal value");
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (parts[0] == "getstack") {
|
||||||
|
if (parts.size() == 2) {
|
||||||
|
int reg = std::stoi(parts.at(1));
|
||||||
|
cnsl->put_string_lf(format("REG %d = %06o", reg, c->get_stackpointer(reg)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cnsl->put_string_lf("getreg requires a stack register");
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (parts[0] == "setpsw") {
|
else if (parts[0] == "setpsw") {
|
||||||
if (parts.size() == 2) {
|
if (parts.size() == 2) {
|
||||||
uint16_t val = std::stoi(parts.at(1), nullptr, 8);
|
uint16_t val = std::stoi(parts.at(1), nullptr, 8);
|
||||||
|
@ -1031,6 +1063,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
else if (cmd == "reset" || cmd == "r") {
|
else if (cmd == "reset" || cmd == "r") {
|
||||||
*stop_event = EVENT_NONE;
|
*stop_event = EVENT_NONE;
|
||||||
b->reset();
|
b->reset();
|
||||||
|
cnsl->put_string_lf("resetted");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (cmd == "cfgdisk") {
|
else if (cmd == "cfgdisk") {
|
||||||
|
@ -1285,6 +1318,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
"getpc -",
|
"getpc -",
|
||||||
"setreg x y - set register x to value y (octal)",
|
"setreg x y - set register x to value y (octal)",
|
||||||
"getreg x -",
|
"getreg x -",
|
||||||
|
"setstack x y - set stack register x to value y (octal)",
|
||||||
|
"getstack x -",
|
||||||
"setpsw x - set PSW value y (octal)",
|
"setpsw x - set PSW value y (octal)",
|
||||||
"getpsw -",
|
"getpsw -",
|
||||||
"setmem ... - set memory (a=) to value (v=), both in octal, one byte",
|
"setmem ... - set memory (a=) to value (v=), both in octal, one byte",
|
||||||
|
|
78
run-json.py
Executable file
78
run-json.py
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#! /usr/bin/python3
|
||||||
|
|
||||||
|
import json
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
import sys
|
||||||
|
|
||||||
|
debug = False
|
||||||
|
|
||||||
|
def docmd(p, str):
|
||||||
|
p.stdin.write((str + "\n").encode('ascii'))
|
||||||
|
|
||||||
|
pl = None
|
||||||
|
while True:
|
||||||
|
line = p.stdout.readline()
|
||||||
|
line = line.decode('ascii', 'ignore').rstrip('\n').strip('\r')
|
||||||
|
if debug:
|
||||||
|
print(f'|{line}|')
|
||||||
|
|
||||||
|
if line == '---':
|
||||||
|
return pl
|
||||||
|
|
||||||
|
pl = line
|
||||||
|
|
||||||
|
process = Popen(['./build/kek', '-d', '-L', 'emergency,debug', '-t', '-l', sys.argv[2]], stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=0)
|
||||||
|
docmd(process, 'marker')
|
||||||
|
|
||||||
|
test_file = sys.argv[1]
|
||||||
|
j = json.loads(open(test_file, 'rb').read())
|
||||||
|
|
||||||
|
error_nr = 0
|
||||||
|
test_nr = 0
|
||||||
|
diffs = []
|
||||||
|
|
||||||
|
for set in j:
|
||||||
|
test_nr += 1
|
||||||
|
if not 'id' in set:
|
||||||
|
continue
|
||||||
|
name = set['id']
|
||||||
|
|
||||||
|
print(name)
|
||||||
|
|
||||||
|
# initialize
|
||||||
|
|
||||||
|
docmd(process, 'reset')
|
||||||
|
before = set['before']
|
||||||
|
|
||||||
|
before_mem = before['memory']
|
||||||
|
for m_entry in before_mem:
|
||||||
|
for key, val in m_entry.items():
|
||||||
|
addr = int(key, 8)
|
||||||
|
docmd(process, f'setmem a={addr:o} v={val & 255:o}')
|
||||||
|
docmd(process, f'setmem a={addr + 1:o} v={val >> 8:o}')
|
||||||
|
|
||||||
|
docmd(process, f'setpc {int(before["PC"]):o}')
|
||||||
|
docmd(process, f'setpsw {int(before["PSW"]):o}')
|
||||||
|
|
||||||
|
#for s in range(0, 2):
|
||||||
|
s = 0
|
||||||
|
for reg in range(0, 6):
|
||||||
|
key = f'reg-{reg}.{s}'
|
||||||
|
docmd(process, f'setreg {reg} {int(before[key]):o}')
|
||||||
|
|
||||||
|
docmd(process, f'setstack 0 {int(before["stack-0"]):o}')
|
||||||
|
docmd(process, f'setstack 1 {int(before["stack-1"]):o}')
|
||||||
|
docmd(process, f'setstack 2 {int(before["stack-2"]):o}')
|
||||||
|
docmd(process, f'setstack 3 {int(before["stack-3"]):o}')
|
||||||
|
|
||||||
|
# invoke!
|
||||||
|
docmd(process, 'step')
|
||||||
|
|
||||||
|
# check
|
||||||
|
|
||||||
|
process.stdin.write(("q\n").encode('ascii'))
|
||||||
|
process.terminate()
|
||||||
|
time.sleep(0.5)
|
||||||
|
process.kill()
|
||||||
|
|
||||||
|
sys.exit(1 if error_nr > 0 else 0)
|
Loading…
Add table
Reference in a new issue