This commit is contained in:
Folkert van Heusden 2025-04-03 20:25:16 +02:00
parent 72ee580d19
commit 93119054fa
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
6 changed files with 132 additions and 21 deletions

12
bus.cpp
View file

@ -269,7 +269,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
return temp;
}
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);
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;
}
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);
return temp;
}
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);
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
TRACE("WRITE-I/O kernel SP: %06o", value);
c->setStackPointer(0, value);
c->set_stackpointer(0, value);
return false;
}
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
TRACE("WRITE-I/O supervisor sp: %06o", value);
c->setStackPointer(1, value);
c->set_stackpointer(1, value);
return false;
}
if (a == ADDR_USER_SP) { // user SP
TRACE("WRITE-I/O user sp: %06o", value);
c->setStackPointer(3, value);
c->set_stackpointer(3, value);
return false;
}

View file

@ -19,13 +19,13 @@
console_posix::console_posix(std::atomic_uint32_t *const stop_event): console(stop_event)
{
#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");
struct termios 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");
setvbuf(stdin, nullptr, _IONBF, 0);
@ -37,7 +37,7 @@ console_posix::~console_posix()
stop_thread();
#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");
#endif
}
@ -66,7 +66,6 @@ int console_posix::wait_for_char_ll(const short timeout)
void console_posix::put_char_ll(const char c)
{
printf("%c", c);
fflush(nullptr);
}

12
cpu.cpp
View file

@ -98,10 +98,8 @@ 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
{
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);
double mips = t_diff ? instr_count / double(t_diff) : 0;
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;
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);
stacktrace.push_back({ p, da["instruction-text"][0] });
while (stacktrace.size() >= max_stacktrace_depth)
stacktrace.erase(stacktrace.begin());
}
@ -136,11 +133,14 @@ std::vector<std::pair<uint16_t, std::string> > cpu::get_stack_trace() const
void cpu::reset()
{
memset(regs0_5, 0x00, sizeof regs0_5);
memset(sp, 0x00, sizeof sp);
memset(sp, 0x00, sizeof sp );
pc = 0;
psw = 0; // 7 << 5;
fpsr = 0;
init_interrupt_queue();
it_is_a_trap = false;
processing_trap_depth = 0;
}
uint16_t cpu::get_register(const int nr) const

7
cpu.h
View file

@ -179,8 +179,10 @@ public:
uint16_t getStackLimitRegister() { return stackLimitRegister; }
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; }
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_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; }
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;
bool put_result(const gam_rc_t & g, const uint16_t value);

View file

@ -729,6 +729,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
int32_t trace_start_addr = -1;
int n_single_step = 1;
bool turbo = false;
bool marker = false;
std::optional<int> t_rl; // trace runlevel
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) {
try {
if (marker)
cnsl->put_string_lf("---");
std::string cmd = cnsl->read_line(format("%d", stop_event->load()));
auto parts = split(cmd, " ");
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;
}
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;
if (parts.size() == 2)
@ -860,6 +866,32 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
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") {
if (parts.size() == 2) {
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") {
*stop_event = EVENT_NONE;
b->reset();
cnsl->put_string_lf("resetted");
continue;
}
else if (cmd == "cfgdisk") {
@ -1285,6 +1318,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
"getpc -",
"setreg x y - set register x to value y (octal)",
"getreg x -",
"setstack x y - set stack register x to value y (octal)",
"getstack x -",
"setpsw x - set PSW value y (octal)",
"getpsw -",
"setmem ... - set memory (a=) to value (v=), both in octal, one byte",

78
run-json.py Executable file
View 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)