From c79c32e3add26ac405d9863c8231655498e26dc7 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 22 Apr 2024 22:22:59 +0200 Subject: [PATCH 01/16] reduced disassembly line length --- debugger.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 3cac428..857c02a 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -499,27 +499,13 @@ int disassemble(cpu *const c, console *const cnsl, const uint16_t pc, const bool work_values.c_str() ); else - result = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s (%s), instr: %s: %s - MMR0/1/2/3: %s/%s/%s/%s", + result = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s (%s), instr: %s: %s", registers[0].c_str(), registers[1].c_str(), registers[2].c_str(), registers[3].c_str(), registers[4].c_str(), registers[5].c_str(), registers[6].c_str(), pc, psw.c_str(), data["psw-value"][0].c_str(), instruction_values.c_str(), - instruction.c_str(), - MMR0.c_str(), MMR1.c_str(), MMR2.c_str(), MMR3.c_str() + instruction.c_str() ); -#if defined(COMPARE_OUTPUT) - { - std::string temp = format("R0: %s, R1: %s, R2: %s, R3: %s, R4: %s, R5: %s, SP: %s, PC: %06o, PSW: %s, instr: %s", - registers[0].c_str(), registers[1].c_str(), registers[2].c_str(), registers[3].c_str(), registers[4].c_str(), registers[5].c_str(), registers[6].c_str(), pc, - psw.c_str(), - data["instruction-values"][0].c_str() - ); - - FILE *fh = fopen("compare.dat", "a+"); - fprintf(fh, "%s\n", temp.c_str()); - fclose(fh); - } -#endif if (cnsl) cnsl->debug(result); @@ -530,7 +516,7 @@ int disassemble(cpu *const c, console *const cnsl, const uint16_t pc, const bool for(auto sp_val : data["sp"]) sp += (sp.empty() ? "" : ",") + sp_val; - DOLOG(debug, false, "SP: %s", sp.c_str()); + DOLOG(debug, false, "SP: %s, MMR0/1/2/3: %s/%s/%s/%s", sp.c_str(), MMR0.c_str(), MMR1.c_str(), MMR2.c_str(), MMR3.c_str()); #if 0 if (c->getPSW_runmode() == 3) { From 8173fa792ac650bb60ba0be030b3149619c870fd Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 23 Apr 2024 16:00:00 +0200 Subject: [PATCH 02/16] set_thread_name --- kw11-l.cpp | 2 ++ main.cpp | 2 ++ tty.cpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/kw11-l.cpp b/kw11-l.cpp index 61f41d0..9081eb3 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -47,6 +47,8 @@ kw11_l::~kw11_l() void kw11_l::operator()() { + set_thread_name("kek:kw-11l"); + DOLOG(debug, true, "Starting KW11-L thread"); while(!stop_flag) { diff --git a/main.cpp b/main.cpp index 56ca2fd..f935b58 100644 --- a/main.cpp +++ b/main.cpp @@ -263,6 +263,8 @@ int run_cpu_validation(const std::string & filename) void get_metrics(cpu *const c) { + set_thread_name("kek:metrics"); + uint64_t previous_instruction_count = c->get_instructions_executed_count(); uint64_t previous_ts = get_us(); uint64_t previous_idle_time = c->get_wait_time(); diff --git a/tty.cpp b/tty.cpp index ed5bb3f..312cba6 100644 --- a/tty.cpp +++ b/tty.cpp @@ -130,6 +130,8 @@ uint16_t tty::readWord(const uint16_t addr) void tty::operator()() { + set_thread_name("kek:tty"); + while(!stop_flag) { if (c->poll_char()) { #if defined(BUILD_FOR_RP2040) From 4d9077df2dd14746065119d2980fa1623f38be97 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 23 Apr 2024 16:14:18 +0200 Subject: [PATCH 03/16] attribute tweak --- bus.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/bus.cpp b/bus.cpp index ef194a2..6913a36 100644 --- a/bus.cpp +++ b/bus.cpp @@ -626,8 +626,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c uint32_t io_base = get_io_base(); bool is_io = m_offset >= io_base; - [[unlikely]] - if (trap_on_failure) { + if (trap_on_failure) [[unlikely]] { { auto rc = get_trap_action(run_mode, d, apf, is_write); auto trap_action = rc.first; @@ -674,8 +673,7 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c } } - [[unlikely]] - if (m_offset >= n_pages * 8192l && !is_io) { + if (m_offset >= n_pages * 8192l && !is_io) [[unlikely]] { DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192l); DOLOG(debug, false, "TRAP(04) (throw 6) on address %06o", a); From 4264236495b7fafe18d852ba903d836957ff01c5 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 23 Apr 2024 16:14:25 +0200 Subject: [PATCH 04/16] logging tweak --- log.cpp | 4 ++-- log.h | 12 ++++++++++-- utils.cpp | 12 ++++++++++++ utils.h | 1 + 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/log.cpp b/log.cpp index a8053a5..2e8ba8e 100644 --- a/log.cpp +++ b/log.cpp @@ -136,9 +136,9 @@ void dolog(const log_level_t ll, const char *fmt, ...) const char *const ll_names[] = { "emerg ", "alert ", "crit ", "error ", "warning", "notice ", "info ", "debug ", "none " }; - asprintf(&ts_str, "%04d-%02d-%02d %02d:%02d:%02d.%06d] %s ", + asprintf(&ts_str, "%04d-%02d-%02d %02d:%02d:%02d.%06d %s|%s] ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, int(now % 1000000), - ll_names[ll]); + ll_names[ll], get_thread_name().c_str()); if (ll <= log_level_file && is_file == false) send_syslog(ll, str); diff --git a/log.h b/log.h index c58e9f5..c94e3c4 100644 --- a/log.h +++ b/log.h @@ -21,11 +21,19 @@ void dolog(const log_level_t ll, const char *fmt, ...); #ifdef TURBO #define DOLOG(ll, always, fmt, ...) do { } while(0) #else +#if defined(ESP32) #define DOLOG(ll, always, fmt, ...) do { \ extern log_level_t log_level_file, log_level_screen; \ \ - [[unlikely]] \ - if (always || ll <= log_level_file || ll <= log_level_screen) \ + if (always || ll <= log_level_file || ll <= log_level_screen) \ + dolog(ll, fmt, ##__VA_ARGS__); \ + } while(0) +#else +#define DOLOG(ll, always, fmt, ...) do { \ + extern log_level_t log_level_file, log_level_screen; \ + \ + if (always || ll <= log_level_file || ll <= log_level_screen) [[unlikely]] \ dolog(ll, fmt, ##__VA_ARGS__); \ } while(0) #endif +#endif diff --git a/utils.cpp b/utils.cpp index e57b908..77300ce 100644 --- a/utils.cpp +++ b/utils.cpp @@ -163,6 +163,18 @@ void set_thread_name(std::string name) #endif } +std::string get_thread_name() +{ +#ifdef linux + char buffer[16 + 1] { }; + pthread_getname_np(pthread_self(), buffer, sizeof buffer); + + return buffer; +#else + return pcTaskGetName(xTaskGetCurrentTaskHandle()); +#endif +} + ssize_t WRITE(int fd, const char *whereto, size_t len) { ssize_t cnt=0; diff --git a/utils.h b/utils.h index 9b1b781..be27c83 100644 --- a/utils.h +++ b/utils.h @@ -18,6 +18,7 @@ unsigned long get_ms(); uint64_t get_us(); void myusleep(uint64_t us); +std::string get_thread_name(); void set_thread_name(std::string name); ssize_t WRITE(int fd, const char *whereto, size_t len); From 846de6cac793c71c57166641ec3d106554d770ac Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 23 Apr 2024 21:30:27 +0200 Subject: [PATCH 05/16] RL02 verification code --- .gitignore | 2 +- tests/addressing.mac | 7 -- tests/mfpi.mac | 65 ----------- tests/mtpi.mac | 62 ----------- tests/rl02test.mac | 138 ++++++++++++++++++++++++ tests/test.mac | 50 --------- tests/test1.mac | 33 ------ tests/test1l.mac | 33 ------ tests/test2.mac | 16 --- tests/test3.mac | 33 ------ tests/test3l.mac | 33 ------ tests/test4.mac | 27 ----- tests/test5.mac | 19 ---- tests/test5d.mac | 19 ---- tests/test6.mac | 19 ---- tests/test7.mac | 8 -- tests/test8.mac | 5 - tests/test9.mac | 4 - tests/tester-adc-sbc.mac | 110 ------------------- tests/tester-addressing.mac | 195 --------------------------------- tests/tester-bge.mac | 50 --------- tests/tester-mov.mac | 66 ------------ tests/tester-psw.mac | 208 ------------------------------------ tests/tester-tst.mac | 66 ------------ tests/tester.mac | 121 --------------------- 25 files changed, 139 insertions(+), 1250 deletions(-) delete mode 100644 tests/addressing.mac delete mode 100644 tests/mfpi.mac delete mode 100644 tests/mtpi.mac create mode 100644 tests/rl02test.mac delete mode 100644 tests/test.mac delete mode 100644 tests/test1.mac delete mode 100644 tests/test1l.mac delete mode 100644 tests/test2.mac delete mode 100644 tests/test3.mac delete mode 100644 tests/test3l.mac delete mode 100644 tests/test4.mac delete mode 100644 tests/test5.mac delete mode 100644 tests/test5d.mac delete mode 100644 tests/test6.mac delete mode 100644 tests/test7.mac delete mode 100644 tests/test8.mac delete mode 100644 tests/test9.mac delete mode 100644 tests/tester-adc-sbc.mac delete mode 100644 tests/tester-addressing.mac delete mode 100644 tests/tester-bge.mac delete mode 100644 tests/tester-mov.mac delete mode 100644 tests/tester-psw.mac delete mode 100644 tests/tester-tst.mac delete mode 100644 tests/tester.mac diff --git a/.gitignore b/.gitignore index 54b2cd8..1a6ce2f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ tests/*.lst tests/*.bin *.log work/ -tests/ +tests-work/ build/ diff --git a/tests/addressing.mac b/tests/addressing.mac deleted file mode 100644 index cbbdb85..0000000 --- a/tests/addressing.mac +++ /dev/null @@ -1,7 +0,0 @@ - .LINK 3326 - MOV #1000,SP -start: MOV #177564,016327 - - TRAP 7 - - make_raw diff --git a/tests/mfpi.mac b/tests/mfpi.mac deleted file mode 100644 index 2dfadcf..0000000 --- a/tests/mfpi.mac +++ /dev/null @@ -1,65 +0,0 @@ -; make sure current run-mode is kernel and previous is user - MOV #0177776,R0 - MOV #030000,(R0) - NOP - -; initialize kernel- and user stackpointers -; kernel - MOV #1000,R6 -;; user -; MOV #0177717,R0 -; MOV #1000,(R0) - -; user: 060000-080000 will be mapped to physical address 020000 - MOV #0177646,R0 -; 020000 / 0100 (0100 => 64 decimal) - MOV #0200,(R0) - NOP - -; user: make sure write- and read-access is possible - MOV #0177606,R0 - MOV #077406,(R0) - -; kernel: flat mapping -; 0-010000 -> 0 - MOV #0172340,R0 - MOV #0000,(R0) -; 060000-0100000 -> 060000 - MOV #0172346,R0 - MOV #0600,(R0) - NOP - -; kernel: make sure write- and read-access is possible -; 0-010000 - MOV #0172300,R0 - MOV #077406,(R0) -; 060000-0100000 - MOV #0172306,R0 - MOV #077406,(R0) - -; place a value at 020000 kernelspace which is -; 060000 in userspace - MOV #020000,R0 - MOV #01234,(R0) - -; MRR0 - MOV #0177572,R0 -; enable MMU traps - BIS #512,(R0) -; enable MMU - BIS #1,(R0) - -; get word from 060000 in userspace and put that on -; the kernel stack - MOV #060000,R0 - MFPI (R0) - NOP - -; check for 01234 - MOV (SP)+,R0 - CMP #01234,R0 - NOP - - HALT - - make_raw diff --git a/tests/mtpi.mac b/tests/mtpi.mac deleted file mode 100644 index 4da27b1..0000000 --- a/tests/mtpi.mac +++ /dev/null @@ -1,62 +0,0 @@ -; make sure current run-mode is kernel and previous is user - MOV #0177776,R0 - MOV #030000,(R0) - NOP - -; initialize kernel- and user stackpointers -; kernel - MOV #1000,R6 -;; user -; MOV #0177717,R0 -; MOV #1000,(R0) - -; user: 020000-040000 will be mapped to physical address 060000 - MOV #0177642,R0 -; 060000 / 0100 (0100 => 64 decimal) - MOV #0600,(R0) - NOP - -; user: make sure write- and read-access is possible - MOV #0177602,R0 - MOV #077406,(R0) - -; kernel: flat mapping -; 0-010000 -> 0 - MOV #0172340,R0 - MOV #0000,(R0) -; 060000-0100000 -> 060000 - MOV #0172346,R0 - MOV #0600,(R0) - NOP - -; kernel: make sure write- and read-access is possible -; 0-010000 - MOV #0172300,R0 - MOV #077406,(R0) -; 060000-0100000 - MOV #0172306,R0 - MOV #077406,(R0) - -; MRR0 - MOV #0177572,R0 -; enable MMU traps - BIS #512,(R0) -; enable MMU - BIS #1,(R0) - -; write word on stack that will be checked for to be at the -; remapped address - MOV #01234,-(SP) -; this address in kernel space should be 060000 in userspace - MOV #020000,R0 - MTPI (R0) - NOP - -; check for 01234 at 060000 in kernel space - MOV #060000,R0 - CMP #01234,(R0) - NOP - - HALT - - make_raw diff --git a/tests/rl02test.mac b/tests/rl02test.mac new file mode 100644 index 0000000..802b8b3 --- /dev/null +++ b/tests/rl02test.mac @@ -0,0 +1,138 @@ +; this is part of KEK, the PDP11/70 emulator + + .link 1000 +start: + mov #start, sp + + clr r1 ; cyl + clr r2 ; head + clr r3 ; sector + +write_loop: + jsr pc,reg_to_r0 + jsr pc,set_buffer + jsr pc,write_sector + jsr pc,next_sector + cmp #1,r0 + beq init_check_loop + jmp write_loop + +init_check_loop: + clr r1 + clr r2 + clr r3 + +check_loop: + jsr pc,reg_to_r0 + jsr pc,read_sector + jsr pc,chk_buffer + cmp #0, r0 + bne finished_failure + jsr pc,next_sector + cmp #1, r0 + beq finished_success + jmp check_loop + +finished_success: + mov #123,R0 + halt + +finished_failure: + clr R0 + halt + +write_sector: + mov #buffer,0174402 ; bus address + mov r0,0174404 ; disk address + mov #-0200,0174406 ; word count (128 = 256 bytes) + mov #012,0174400 ; go! +write_wait: + bit #0200,0174400 + beq write_wait + rts pc + +read_sector: + mov #buffer,0174402 ; bus address + mov r0,0174404 ; disk address + mov #-0200,0174406 ; word count (128) + mov #014,0174400 ; go! +read_wait: + bit #0200,0174400 + beq read_wait + rts pc + +set_buffer: +; fill allmost all bytes with a pattern unique for this sector + mov R0,-(SP) + mov R5,-(SP) + mov #0125,R0 + mov #buffer,R5 +sb_loop: + movb r1,(r5)+ + movb r2,(r5)+ + movb r3,(r5)+ + sob r0, sb_loop + mov (SP)+,R5 + mov (SP)+,R0 + rts pc + +; see if the pattern is (still) there +; return 0 if ok, else !0 +chk_buffer: + mov R5,-(SP) + mov #0125,R0 + mov #buffer,R5 +cb_loop: + cmpb r1,(r5)+ + bne fail + cmpb r2,(r5)+ + bne fail + cmpb r3,(r5)+ + bne fail + sob r0, cb_loop +fail: + mov (SP)+,R5 + rts pc + +reg_to_r0: + mov r4,-(sp) +; cylinder + mov r1,r4 + bic #0177000,r4 + ash #7,r4 + mov r4,r0 +; head + mov r2,r4 + bic #0177776,r4 + ash #6,r4 + add r4,r0 +; sector + mov r3,r4 + bic #0177700,r4 + add r4,r0 + mov (sp)+,r4 + rts pc + +; sets r0 to 1 for wrap, else 0 +next_sector: + clr r0 + inc r3 + cmp r3,#050 + blt ns_finished +; sector wrap + clr r3 + inc r2 + cmp r2,#02 + blt ns_finished + clr r2 + inc r1 + cmp r1,#01000 + blt ns_finished + clr r1 + mov #1,r0 +ns_finished: + rts pc + +buffer: +; 256 bytes(!) buffer + .blkw 0200 diff --git a/tests/test.mac b/tests/test.mac deleted file mode 100644 index 8620c4f..0000000 --- a/tests/test.mac +++ /dev/null @@ -1,50 +0,0 @@ -; in simh: -; simh> set console telnet=3333 -; then invoke telnet to port 3333 on the simh systm -; simh> load test.bin -; simh> run - - -; initialize stack pointer -start: MOV #1000, R6 - -; store pointer to text in R0 -loop: MOV #text, R0 - CALL printstart - JMP loop - -; store copy of R0 on the stack -printstart: MOV R0,-(SP) -; store PSW (status register) on stack - MOV R1,-(SP) - MFPS R1 - MOV R1,-(SP) - -; string ends with 0x00 -print: TSTB (R0) - BEQ pdone - -; put character in tty buffer - MOVB (R0), @#TTYTX - -; wait for it to be transmitted -waittx: TSTB @#TTYST - BPL waittx - - INC R0 - JMP print - -; retrieve stored r0, r1 and psw from stack -pdone: MOV (SP)+,R1 - MTPS R1 - MOV (SP)+,R1 - - MOV (SP)+,R0 - RET - - make_raw - -text: .ASCII "test\r\n\x00" - -TTYST = 177564 -TTYTX = 177566 diff --git a/tests/test1.mac b/tests/test1.mac deleted file mode 100644 index b0347f2..0000000 --- a/tests/test1.mac +++ /dev/null @@ -1,33 +0,0 @@ -label: CLC - MOV #0.,R0 - ASR R0 ; - NOP - - CLC - MOV #0,R1 - ASRB R1 ; - NOP - - CLC - MOV #117400,R2 - ASR R2 ; - NOP - - CLC - MOV #117400,R3 - ASRB R3 ; - NOP - - CLC - MOV #77776,R4 - ASR R4 ; - NOP - - CLC - MOV #77776,R5 - ASRB R5 ; - NOP - - HALT - - make_raw diff --git a/tests/test1l.mac b/tests/test1l.mac deleted file mode 100644 index 5768f1c..0000000 --- a/tests/test1l.mac +++ /dev/null @@ -1,33 +0,0 @@ -label: CLC - MOV #0.,R0 - ASL R0 ; - NOP - - CLC - MOV #0,R1 - ASLB R1 ; - NOP - - CLC - MOV #117400,R2 - ASL R2 ; - NOP - - CLC - MOV #117400,R3 - ASLB R3 ; - NOP - - CLC - MOV #77776,R4 - ASL R4 ; - NOP - - CLC - MOV #77776,R5 - ASLB R5 ; - NOP - - HALT - - make_raw diff --git a/tests/test2.mac b/tests/test2.mac deleted file mode 100644 index 767a8df..0000000 --- a/tests/test2.mac +++ /dev/null @@ -1,16 +0,0 @@ - mov #1000,SP - - mov #trapfunc, @#034 - -traploop: SEC - SEN - SEV - TRAP 0 - JMP traploop - -trapfunc: - NOP - NOP - RTT - - make_raw diff --git a/tests/test3.mac b/tests/test3.mac deleted file mode 100644 index 2e8ae91..0000000 --- a/tests/test3.mac +++ /dev/null @@ -1,33 +0,0 @@ -label: SEC - MOV #0.,R0 - ROR R0 ; - NOP - - SEC - MOV #0,R1 - RORB R1 ; - NOP - - SEC - MOV #117400,R2 - ROR R2 ; - NOP - - SEC - MOV #117400,R3 - RORB R3 ; - NOP - - SEC - MOV #1,R4 - ROR R4 ; - NOP - - SEC - MOV #1,R5 - RORB R5 ; - NOP - - HALT - - make_raw diff --git a/tests/test3l.mac b/tests/test3l.mac deleted file mode 100644 index fcb2e6b..0000000 --- a/tests/test3l.mac +++ /dev/null @@ -1,33 +0,0 @@ -label: SEC - MOV #0.,R0 - ROL R0 ; - NOP - - SEC - MOV #0,R1 - ROLB R1 ; - NOP - - SEC - MOV #117400,R2 - ROL R2 ; - NOP - - SEC - MOV #117400,R3 - ROLB R3 ; - NOP - - SEC - MOV #1,R4 - ROL R4 ; - NOP - - SEC - MOV #1,R5 - ROLB R5 ; - NOP - - HALT - - make_raw diff --git a/tests/test4.mac b/tests/test4.mac deleted file mode 100644 index e31c865..0000000 --- a/tests/test4.mac +++ /dev/null @@ -1,27 +0,0 @@ -label: MOV #0.,R0 - NEG R0 ; 0 - NOP - - MOV #0,R1 - NEGB R1 ; 0 - NOP - - MOV #117400,R2 - NEG R2 ; 060400 - NOP - - MOV #117400,R3 - NEGB R3 ; 117400 - NOP - - MOV #1,R4 - NEG R4 ; 177777 - NOP - - MOV #1,R5 - NEGB R5 ; 000377 - NOP - - HALT - - make_raw diff --git a/tests/test5.mac b/tests/test5.mac deleted file mode 100644 index f12483b..0000000 --- a/tests/test5.mac +++ /dev/null @@ -1,19 +0,0 @@ -label: MOV #0.,R0 - INC R0 - NOP - - MOV #0,R1 - INCB R1 - NOP - - MOV #117400,R2 - INC R2 - NOP - - MOV #117400,R3 - INCB R3 - NOP - - HALT - - make_raw diff --git a/tests/test5d.mac b/tests/test5d.mac deleted file mode 100644 index bfeaafc..0000000 --- a/tests/test5d.mac +++ /dev/null @@ -1,19 +0,0 @@ -label: MOV #0.,R0 - DEC R0 - NOP - - MOV #0,R1 - DECB R1 - NOP - - MOV #117400,R2 - DEC R2 - NOP - - MOV #117400,R3 - DECB R3 - NOP - - HALT - - make_raw diff --git a/tests/test6.mac b/tests/test6.mac deleted file mode 100644 index 85bc7fe..0000000 --- a/tests/test6.mac +++ /dev/null @@ -1,19 +0,0 @@ -label: MOV #0.,R0 - COM R0 ; 65535 - NOP - - MOV #0,R1 - COMB R1 ; 255 - NOP - - MOV #117400,R2 - COM R2 ; 24831 - NOP - - MOV #117400,R3 - COMB R3 ; 40959 - NOP - - HALT - - make_raw diff --git a/tests/test7.mac b/tests/test7.mac deleted file mode 100644 index 730eca4..0000000 --- a/tests/test7.mac +++ /dev/null @@ -1,8 +0,0 @@ -label: MOV #2000,SP - NOP - INC SP - NOP - DEC SP - NOP - - make_raw diff --git a/tests/test8.mac b/tests/test8.mac deleted file mode 100644 index 7fccbcd..0000000 --- a/tests/test8.mac +++ /dev/null @@ -1,5 +0,0 @@ - NOP -label: .DW 077700 - NOP - - make_raw diff --git a/tests/test9.mac b/tests/test9.mac deleted file mode 100644 index b27eed7..0000000 --- a/tests/test9.mac +++ /dev/null @@ -1,4 +0,0 @@ - .DW 072527 - .DW 000000 - - make_raw diff --git a/tests/tester-adc-sbc.mac b/tests/tester-adc-sbc.mac deleted file mode 100644 index d51a99b..0000000 --- a/tests/tester-adc-sbc.mac +++ /dev/null @@ -1,110 +0,0 @@ -.EXTERN ALL - -test_adc: - MOV #what_adc,R0 - CALL print_start - -; initial value - MOV #32769.,R0 -; number of additions - MOV #257.,R1 - -test_adc_loop: - ADD #1003.,R0 - ADC R0 - - MFPS R2 - BIC #65520.,R2 - ADD R2,R0 - - DEC R1 - TST R1 - BNE test_adc_loop - - CMP #29424.,R0 - BNE test_adc_failed - -; test 8 bit - MOV #32769.,R0 - MOV #257.,R1 - -test_adc_loop8b: - ADD #13.,R0 - ADCB R0 - - MFPS R2 - BIC #65520.,R2 - ADD R2,R0 - - DEC R1 - TST R1 - BNE test_adc_loop8b - - CMP #36878.,R0 - BNE test_adc_failed - - RET - -test_adc_failed: - MOV #adc_fail_text,R0 - CALL print_start - RET - -adc_fail_text: - .ASCII "ADC handling FAIL\r\n\x00" -.EVEN - -test_sbc: -; initial value - MOV #32769.,R0 -; number of additions - MOV #257.,R1 - -test_sbc_loop: - SUB #1003.,R0 - SBC R0 - - MFPS R2 - BIC #65520.,R2 - SUB R2,R0 - - DEC R1 - TST R1 - BNE test_sbc_loop - - CMP #36106.,R0 - BNE test_sbc_failed - -; test 8 bit - MOV #32769.,R0 - MOV #257.,R1 - -test_sbc_loop8b: - SUB #13.,R0 - SBCB R0 - - MFPS R2 - BIC #65520.,R2 - SUB R2,R0 - - DEC R1 - TST R1 - BNE test_sbc_loop8b - - CMP #28652.,R0 - BNE test_sbc_failed - - RET - -test_sbc_failed: - MOV #sbc_fail_text,R0 - CALL print_start - RET - -sbc_fail_text: - .ASCII "SBC handling FAIL\r\n\x00" - -what_adc: - .ASCII "ADC/SBC test\r\n\x00" - -.EVEN diff --git a/tests/tester-addressing.mac b/tests/tester-addressing.mac deleted file mode 100644 index 593ed52..0000000 --- a/tests/tester-addressing.mac +++ /dev/null @@ -1,195 +0,0 @@ -.EXTERN ALL - -test_addr_0: - MOV #what_address,R0 - CALL print_start - -; address mode 0 -; b1010101001010101 -; 16 bit put/get - MOV #43605.,R0 - CMP #43605.,R0 - BEQ test_addr_0a_ok - MOV #1.,R0 - JMP test_addr_fail - -test_addr_0a_ok: -; 8 bit put / 16 bit get, should sign extend - MOVB #240.,R0 - CMP #65520.,R0 - BEQ test_addr_0b_ok - MOV #2.,R0 - JMP test_addr_fail - -test_addr_0b_ok: -; 8 bit put / 16 bit get, should sign extend - MOVB #127.,R0 - CMP #127.,R0 - BEQ test_addr_0c_ok - MOV #3.,R0 - JMP test_addr_fail - -test_addr_0c_ok: -test_addr_1: -; address mode 1 -; indirect get 16 bit - MOV #v1234,R0 - MOV (R0),R1 - CMP #1234.,R1 - BEQ test_addr_1a_ok - MOV #4.,R0 - JMP test_addr_fail - -test_addr_1a_ok: -; indirect get 8 bit, sign extended - MOV #v1234,R0 - MOVB (R0),R1 - CMP #65490.,R1 - BEQ test_addr_1b_ok - MOV #5.,R0 - JMP test_addr_fail - -test_addr_1b_ok: -; indirect get 16 bit - MOV #v1234,R0 - MOVB (R0),R1 - CMP #1234.,R1 - BNE test_addr_1c_ok - MOV #6.,R0 - JMP test_addr_fail - -test_addr_1c_ok: -test_addr_2: -; address mode 2 -; value did not change - MOV #v1234,R0 - MOV (R0)+,R1 - CMP #1234.,R1 - BEQ test_addr_2a1_ok - MOV #7.,R0 - JMP test_addr_fail -; -test_addr_2a1_ok: -; address increased 2 bytes - MOV #v1234after,R2 - CMP R0,R2 - BEQ test_addr_2a2_ok - MOV #8.,R0 - JMP test_addr_fail - -test_addr_2a2_ok: -; value did not change - MOV #v1234,R0 - MOVB (R0)+,R1 - CMPB #210.,R1 - BEQ test_addr_2b1_ok - MOV #9.,R0 - JMP test_addr_fail - -test_addr_2b1_ok: -; test if this pdp-11 has the hw-bug - MOV #v1234,R0 - MOV (R0)+,R0 - CMP #1234.,R0 - BEQ test_addr_2b2_ok - MOV #10.,R0 - JMP test_addr_fail - -test_addr_2b2_ok: -test_addr_3: -; verify contents of addr1234 first - MOV addr1234,r0 - CMP #1234.,(R0) - BEQ test_addr_3b_verify_ok - MOV #12.,R0 - JMP test_addr_fail - -test_addr_3b_verify_ok: - MOV @(R0)+,R1 - MOV #v1234after,R2 - CMP R0,R2 - BEQ test_addr_3b2_ok - MOV #13.,R0 - JMP test_addr_fail - -test_addr_3b2_ok: -test_addr_4: - - ; TODO -; address mode 4 -; value did not change - MOV #v1234,R0 - MOV -(R0),R1 - CMP #4455.,R1 - BEQ test_addr_4a1_ok - MOV #14.,R0 - JMP test_addr_fail -; -test_addr_4a1_ok: -; address drecreased 2 bytes - MOV #v4455before,R2 - CMP R0,R2 - BEQ test_addr_4a2_ok - MOV #15.,R0 - JMP test_addr_fail - -test_addr_4a2_ok: -; value did not change - MOV #v1234,R0 - MOVB -(R0),R1 - CMPB #17.,R1 - BEQ test_addr_4a3_ok - MOV #16.,R0 - JMP test_addr_fail - -test_addr_4a3_ok: -test_addr_5: -; TODO - - -test_addr_6: - MOV #v1234,R0 - MOV 2(R0),R1 - CMP #4321.,R1 - BEQ test_addr_6_ok - MOV #17.,R0 - JMP test_addr_fail - -test_addr_6_ok: -test_addr_7: -; index deferred - MOV #addr1234,R0 - MOV @2(R0),R1 - CMP #4321.,R1 - BEQ test_addr_7_ok - MOV #18.,R0 - JMP test_addr_fail - -test_addr_7_ok: - RET - -test_addr_fail: - CALL print_binary - - MOV #test_addr_fail_txt,R0 - CALL print_start - RET - -test_addr_fail_txt: - .ASCII "addressing handling FAIL\r\n\x00" - -what_address: - .ASCII "addressing tests\r\n\x00" - -.EVEN - -v4455before: DW 4455. -v1234: DW 1234. -v1234after: DW 4321. - -addr1234: DW v1234 -addr1234after: DW v1234after - -test_addr: - CALL test_addr_0 - RET diff --git a/tests/tester-bge.mac b/tests/tester-bge.mac deleted file mode 100644 index d8c913f..0000000 --- a/tests/tester-bge.mac +++ /dev/null @@ -1,50 +0,0 @@ -.EXTERN ALL - -test_bge: - MOV #what_bge,R0 - CALL print_start - -test_bge_1: -; initialize flags - MOV #8.,R0 - MTPS R0 - -; should not jump - BGE test_bge_1_fail - JMP test_bge_2 - -test_bge_1_fail: - MOV #1.,R0 - JMP test_bge_fail - -test_bge_2: - MOV #10.,R0 - MTPS R0 - BGE test_bge_2_ok - - MOV #2.,R0 - JMP test_bge_fail - -test_bge_2_ok: - RET - -test_bge_fail: -; print test number - CALL print_binary - -; flags are always (for this tester) in R2 - MOV R2,R0 - CALL print_binary - - MOV #test_bge_fail_txt,R0 - CALL print_start - RET - -test_bge_fail_txt: - .ASCII "BGE handling FAIL\r\n\x00" - - -what_bge: - .ASCII "BGE test\r\n\x00" - -.EVEN diff --git a/tests/tester-mov.mac b/tests/tester-mov.mac deleted file mode 100644 index 58ac6b1..0000000 --- a/tests/tester-mov.mac +++ /dev/null @@ -1,66 +0,0 @@ -.EXTERN ALL - -test_mov: - MOV #what_mov,R0 - CALL print_start - -; test if flags are set when moving value - -; clear N, Z, set V and C - MOV #3,R0 - MTPS R0 - - MOV #0,R0 -; get flag-register - MFPS R1 -; mask off upper bits of byte - BIC #65520.,R1 -; only Z and CARRY must be set - CMP #5.,R1 - BEQ test_mov_t1_ok -; test 1 failed - MOV #1.,R0 - JMP test_mov_fail - -test_mov_t1_ok: -test_mov_t2: -; clear all flags - MOV #0,R0 - MTPS R0 - - MOV #32768.,R0 -; get flag-register - MFPS R1 -; mask off upper bits of byte - BIC #65520.,R1 -; only N must be set - CMPB #8.,R1 - BEQ test_mov_t2_ok -; test 2 failed - MOV #2.,R0 - JMP test_mov_fail - -test_mov_t2_ok: - - RET - -test_mov_fail: -; print test number - CALL print_binary - -; flags are always in R1 - MOV R1,R0 - CALL print_binary - - MOV #test_mov_fail_txt,R0 - CALL print_start - RET - -test_mov_fail_txt: - .ASCII "MOV handling FAIL\r\n\x00" - - -what_mov: - .ASCII "MOV flag test\r\n\x00" - -.EVEN diff --git a/tests/tester-psw.mac b/tests/tester-psw.mac deleted file mode 100644 index 8126fdc..0000000 --- a/tests/tester-psw.mac +++ /dev/null @@ -1,208 +0,0 @@ -.EXTERN ALL - -psw_store_retrieve: - MOV #what_psw,R0 - CALL print_start - -; set PSW to all bits set - MOV #65535,R1 - MTPS R1 -; clear PSW status bits - CLC - CLV - CLZ - CLN -; retrieve PSW and verify the flags are 0 - MFPS R2 - -; clear currently non-relevant psw-bits - BIC #240.,R2 - - TSTB R2 - BNE psw_store_retrieve_fail - - RET - -psw_store_retrieve_fail: - MOV R2,R0 - CALL print_binary - - MOV #psw_store_retrieve_fail_text, R0 - CALL print_start - RET - -clear_flags: - CLC - CLV - CLZ - CLN - RET - -psw_flags_trigger: -; test zero bit - CALL clear_flags - MOV #32768.,R1 - TSTB R1 - BEQ psw_trigger_1_next -; store test number - MOV #1.,R2 - JMP psw_trigger_fail - -psw_trigger_1_next: - CALL clear_flags - MOV #128.,R1 - TSTB R1 - BNE psw_trigger_2_next - MOV #2.,R2 - JMP psw_trigger_fail - -psw_trigger_2_next: - CALL clear_flags -; test overflow bit (overflow) - MOV #127.,R1 - INCB R1 - BVS psw_trigger_3_next - MOV #3.,R2 - JMP psw_trigger_fail - -; test overflow bit (underflow) -psw_trigger_3_next: - CALL clear_flags - MOV #-128.,R1 - DECB R1 - BVS psw_trigger_4_next - MOV #4.,R2 - JMP psw_trigger_fail - -psw_trigger_4_next: - CALL clear_flags -; test minus bit - MOV #127.,R1 - INCB R1 - BMI psw_trigger_5_next - MOV #5.,R2 - JMP psw_trigger_fail - -psw_trigger_5_next: - CALL clear_flags - MOV #128.,R1 - DECB R1 - BPL psw_trigger_6_next - MOV #6.,R2 - JMP psw_trigger_fail - -psw_trigger_6_next: - CALL clear_flags -; carry flag test - MOV #128.,R1 - ASLB R1 - BCS psw_trigger_7_next - MOV #7.,R2 - JMP psw_trigger_fail - -psw_trigger_7_next: - CALL clear_flags - MOV #64.,R1 - ASLB R1 - BCC psw_trigger_8_next - MOV #8.,R2 - JMP psw_trigger_fail - -psw_trigger_8_next: -; 16 bit tests - -; test zero bit - CALL clear_flags - MOV #0,R1 - TST R1 - BEQ psw_trigger_1_next16b -; store test number - MOV #9.,R2 - JMP psw_trigger_fail - -psw_trigger_1_next16b: - CALL clear_flags - MOV #32768.,R1 - TST R1 - BNE psw_trigger_2_next16b - MOV #10.,R2 - JMP psw_trigger_fail - -psw_trigger_2_next16b: - CALL clear_flags -; test overflow bit (overflow) - MOV #32767.,R1 - INC R1 - BVS psw_trigger_3_next16b - MOV #11.,R2 - JMP psw_trigger_fail - -; test overflow bit (underflow) -psw_trigger_3_next16b: - CALL clear_flags - MOV #-32768.,R1 - DEC R1 - BVS psw_trigger_4_next16b - MOV #12.,R2 - JMP psw_trigger_fail - -psw_trigger_4_next16b: - CALL clear_flags -; test minus bit - MOV #32767.,R1 - INC R1 - BMI psw_trigger_5_next16b - MOV #13.,R2 - JMP psw_trigger_fail - -psw_trigger_5_next16b: - CALL clear_flags - MOV #32768.,R1 - DEC R1 - BPL psw_trigger_6_next16b - MOV #14.,R2 - JMP psw_trigger_fail - -psw_trigger_6_next16b: - CALL clear_flags -; carry flag test - MOV #32768.,R1 - ASL R1 - BCS psw_trigger_7_next16b - MOV #15.,R2 - JMP psw_trigger_fail - -psw_trigger_7_next16b: - CALL clear_flags - MOV #16384.,R1 - ASL R1 - BCC psw_trigger_8_next16b - MOV #16.,R2 - JMP psw_trigger_fail - -psw_trigger_8_next16b: - RET - -psw_trigger_fail: - CALL clear_flags -; emit test number - MOV R2,R0 - CALL print_binary -; emit flags - MFPS R0 - CALL print_binary -; emit text - MOV #psw_trigger_fail_text,R0 - CALL print_start - RET - -psw_store_retrieve_fail_text: - .ASCII "MFPS / MTPS handling FAIL\r\n\x00" - -psw_trigger_fail_text: - .ASCII "PSW trigger fail\r\n\x00" - -what_psw: - .ASCII "PSW handling test\r\n\x00" - -.EVEN diff --git a/tests/tester-tst.mac b/tests/tester-tst.mac deleted file mode 100644 index 6bcdd38..0000000 --- a/tests/tester-tst.mac +++ /dev/null @@ -1,66 +0,0 @@ -.EXTERN ALL - -test_tst: - MOV #what_tst,R0 - CALL print_start - -test_tst_1: -; initialize flags - MOV #15.,R0 - MTPS R0 - -; test TST when value is 0 - MOV #0,R1 - TST R1 -; retrieve flags - MFPS R2 -; mask off upper bits of byte - BIC #65520.,R2 - CMP #4.,R2 - BEQ test_tst_1_ok - - MOV #1.,R0 - JMP test_tst_fail - -test_tst_1_ok: -test_tst_2: -; initialize flags - MOV #15.,R0 - MTPS R0 - -; test TST when value is !0 - MOV #32768.,R1 - TST R1 -; retrieve flags - MFPS R2 -; mask off upper bits of byte - BIC #65520.,R2 - CMP #8.,R2 - BEQ test_tst_2_ok - - MOV #2.,R0 - JMP test_tst_fail - -test_tst_2_ok: - RET - -test_tst_fail: -; print test number - CALL print_binary - -; flags are always (for this tester) in R2 - MOV R2,R0 - CALL print_binary - - MOV #test_tst_fail_txt,R0 - CALL print_start - RET - -test_tst_fail_txt: - .ASCII "TST handling FAIL\r\n\x00" - - -what_tst: - .ASCII "TST test\r\n\x00" - -.EVEN diff --git a/tests/tester.mac b/tests/tester.mac deleted file mode 100644 index b616237..0000000 --- a/tests/tester.mac +++ /dev/null @@ -1,121 +0,0 @@ -; in simh: -; simh> set console telnet=3333 -; then invoke telnet to port 3333 on the simh systm -; simh> load test.bin -; simh> run - -.EXTERN ALL - -; initialize stack pointer -start: MOV #1000, R6 - JMP go - -.INCLUDE "tester-psw.mac" -.INCLUDE "tester-adc-sbc.mac" -.INCLUDE "tester-addressing.mac" -.INCLUDE "tester-mov.mac" -.INCLUDE "tester-tst.mac" -.INCLUDE "tester-bge.mac" - -go: MOV #textstart, R0 - CALL print_start - - CALL psw_store_retrieve - - CALL psw_flags_trigger - - CALL test_adc - - CALL test_sbc - - CALL test_addr - - CALL test_mov - - CALL test_tst - - CALL test_bge - - MOV #textfin, R0 - CALL print_start - TRAP 7 - -; store copy of R0 on the stack -print_start: MOV R0,-(SP) -; store PSW (status register) on stack - MFPS -(SP) - -; string ends with 0x00 -print: TSTB (R0) - BEQ pdone - -; put character in tty buffer - MOVB (R0), @#TTYTX - -; wait for it to be transmitted -waittx: TSTB @#TTYST - BPL waittx - - INC R0 - JMP print - -; retrieve stored r0, r1 and psw from stack -pdone: MTPS (SP)+ - - MOV (SP)+,R0 - RET - -print_binary: - MFPS -(SP) - MOV R0,-(SP) - MOV R1,-(SP) -; 16 bits in a word - MOV #16.,R1 - -print_bit: - ASL R0 - BCS print_1 -waittx0: - TSTB @#TTYST - BPL waittx0 - MOVB #48., @#TTYTX - BR print_next_bit -print_1: -waittx1: - TSTB @#TTYST - BPL waittx1 - MOVB #49., @#TTYTX - BR print_next_bit - -print_next_bit: -; keep track of the number of bits emitted - DEC R1 - TST R1 - BNE print_bit - -; emit seperator -bit_seperator: - TSTB @#TTYST - BPL bit_seperator - MOVB #32., @#TTYTX -; for some reason the last character is not printed in simh unless repeated -bit_seperator2: - TSTB @#TTYST - BPL bit_seperator2 - MOVB #32., @#TTYTX - - MOV (SP)+,R1 - MOV (SP)+,R0 - MTPS (SP)+ - RET - - make_raw - -textstart: .ASCII "tester running...\r\n\x00" -textfin: .ASCII "tester finished\r\n\x00" -.EVEN - -textbuffer: .BLKB 256. - -TTYST = 177564 -TTYTX = 177566 From 4039c8f2742bff7764ef2cd25c77ac9a864e4b5c Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 23 Apr 2024 21:48:45 +0200 Subject: [PATCH 06/16] comments --- tests/rl02test.mac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/rl02test.mac b/tests/rl02test.mac index 802b8b3..91e78b1 100644 --- a/tests/rl02test.mac +++ b/tests/rl02test.mac @@ -116,15 +116,19 @@ reg_to_r0: ; sets r0 to 1 for wrap, else 0 next_sector: clr r0 +; inc sector inc r3 +; sector 40(dec)? cmp r3,#050 blt ns_finished ; sector wrap clr r3 +; next head inc r2 cmp r2,#02 blt ns_finished clr r2 +; next track inc r1 cmp r1,#01000 blt ns_finished From 82c7541686155649cd4ab72143eb3a98a6dde58d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Tue, 23 Apr 2024 22:01:30 +0200 Subject: [PATCH 07/16] fill buffer with data from memory before writing it to disk --- rl02.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rl02.cpp b/rl02.cpp index a11a03e..f34a562 100644 --- a/rl02.cpp +++ b/rl02.cpp @@ -213,6 +213,15 @@ void rl02::writeWord(const uint16_t addr, uint16_t v) while(count > 0) { uint32_t cur = std::min(uint32_t(sizeof xfer_buffer), count); + for(uint32_t i=0; ireadUnibusByte(memory_address++); + xfer_buffer[i++] = b->readUnibusByte(memory_address++); + + // update_bus_address(memory_address); + mpr[0]++; + } + if (!fhs.at(device)->write(temp_disk_offset, cur, xfer_buffer)) { DOLOG(ll_error, true, "RL02: write error, device %d, disk offset %u, read size %u, cylinder %d, head %d, sector %d", device, temp_disk_offset, cur, track, head, sector); break; From 31da4d3105a5296f52782003e88ffe5ef6e71b76 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Wed, 24 Apr 2024 22:44:52 +0200 Subject: [PATCH 08/16] tests --- BIC/ZRKJE0.BIC | Bin 0 -> 5610 bytes BIC/ZRKKF2.BIC | Bin 0 -> 14280 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 BIC/ZRKJE0.BIC create mode 100644 BIC/ZRKKF2.BIC diff --git a/BIC/ZRKJE0.BIC b/BIC/ZRKJE0.BIC new file mode 100644 index 0000000000000000000000000000000000000000..c6485a19d389897bca656c7c245bc0fc8b324f26 GIT binary patch literal 5610 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 Date: Wed, 24 Apr 2024 23:51:05 +0200 Subject: [PATCH 09/16] ncurses fixes --- console_ncurses.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/console_ncurses.cpp b/console_ncurses.cpp index ab26630..025a2ce 100644 --- a/console_ncurses.cpp +++ b/console_ncurses.cpp @@ -72,7 +72,7 @@ int console_ncurses::wait_for_char_ll(const short timeout) void console_ncurses::put_char_ll(const char c) { - if (c >= 32 || (c != 12 && c != 27 && c != 13)) { + if ((c >= 32 && c < 127) || c == 10) { std::unique_lock lck(ncurses_mutex); wprintw(w_main->win, "%c", c); @@ -213,22 +213,28 @@ void console_ncurses::panel_update_thread() werase(w_panel->win); } - // speed - uint64_t cur_instr_cnt = c->get_instructions_executed_count(); + { + std::unique_lock lck(ncurses_mutex); - mvwprintw(w_panel->win, 1, 1 + 39, "%8ld", (cur_instr_cnt - prev_instr_cnt) * refresh_rate); + // speed + uint64_t cur_instr_cnt = c->get_instructions_executed_count(); - prev_instr_cnt = cur_instr_cnt; + mvwprintw(w_panel->win, 1, 1 + 39, "%8ld", (cur_instr_cnt - prev_instr_cnt) * refresh_rate); - // ncurses - wmove(w_main->win, ty, tx); + prev_instr_cnt = cur_instr_cnt; - mydoupdate(); + // ncurses + wmove(w_main->win, ty, tx); + + mydoupdate(); + } } } void console_ncurses::refresh_virtual_terminal() { + std::unique_lock lck(ncurses_mutex); + wclear(w_main->win); for(int row=0; row Date: Thu, 25 Apr 2024 01:14:58 +0200 Subject: [PATCH 10/16] swapped file/screen for setll --- log.cpp | 2 +- log.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/log.cpp b/log.cpp index 2e8ba8e..d250081 100644 --- a/log.cpp +++ b/log.cpp @@ -66,7 +66,7 @@ void setloghost(const char *const host, const log_level_t ll) l_timestamp = false; } -void setll(const log_level_t ll_file, const log_level_t ll_screen) +void setll(const log_level_t ll_screen, const log_level_t ll_file) { log_level_file = ll_file; log_level_screen = ll_screen; diff --git a/log.h b/log.h index c94e3c4..50b6ce5 100644 --- a/log.h +++ b/log.h @@ -13,7 +13,7 @@ typedef enum { ll_emerg = 0, ll_alert, ll_critical, ll_error, warning, notice, i log_level_t parse_ll(const std::string & str); void setlogfile(const char *const lf, const log_level_t ll_file, const log_level_t ll_screen, const bool l_timestamp); void setloghost(const char *const host, const log_level_t ll); -void setll(const log_level_t ll_file, const log_level_t ll_screen); +void setll(const log_level_t ll_screen, const log_level_t ll_file); void setloguid(const int uid, const int gid); void closelog(); void dolog(const log_level_t ll, const char *fmt, ...); From 2c107865c00415265ed335a8498a01604905e4be Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 01:34:07 +0200 Subject: [PATCH 11/16] layout --- rk05.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rk05.h b/rk05.h index 68d03f1..7496063 100644 --- a/rk05.h +++ b/rk05.h @@ -36,7 +36,7 @@ private: std::atomic_bool *const disk_write_acitivity { nullptr }; uint32_t get_bus_address() const; - void update_bus_address(const uint16_t v); + void update_bus_address(const uint16_t v); public: rk05(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); @@ -44,7 +44,7 @@ public: void reset(); - uint8_t readByte(const uint16_t addr); + uint8_t readByte(const uint16_t addr); uint16_t readWord(const uint16_t addr); void writeByte(const uint16_t addr, const uint8_t v); From 54836067b5dcfccab1fd8f35f20d587343a10839 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 01:39:42 +0200 Subject: [PATCH 12/16] clean-up --- ESP32/device.h | 1 + device.h | 20 ++++++++++++++++++++ rk05.cpp | 2 +- rk05.h | 13 +++++++------ rl02.h | 13 +++++++------ tm-11.h | 17 ++++++++++------- 6 files changed, 46 insertions(+), 20 deletions(-) create mode 120000 ESP32/device.h create mode 100644 device.h diff --git a/ESP32/device.h b/ESP32/device.h new file mode 120000 index 0000000..41bf9d4 --- /dev/null +++ b/ESP32/device.h @@ -0,0 +1 @@ +../device.h \ No newline at end of file diff --git a/device.h b/device.h new file mode 100644 index 0000000..96638a3 --- /dev/null +++ b/device.h @@ -0,0 +1,20 @@ +#pragma once + + +class device +{ +public: + device() { + } + + virtual ~device() { + } + + virtual void reset() = 0; + + virtual uint8_t readByte(const uint16_t addr) = 0; + virtual uint16_t readWord(const uint16_t addr) = 0; + + virtual void writeByte(const uint16_t addr, const uint8_t v) = 0; + virtual void writeWord(const uint16_t addr, const uint16_t v) = 0; +}; diff --git a/rk05.cpp b/rk05.cpp index 14db320..8b1aaf8 100644 --- a/rk05.cpp +++ b/rk05.cpp @@ -109,7 +109,7 @@ void rk05::writeByte(const uint16_t addr, const uint8_t v) writeWord(addr, vtemp); } -void rk05::writeWord(const uint16_t addr, uint16_t v) +void rk05::writeWord(const uint16_t addr, const uint16_t v) { const int reg = (addr - RK05_BASE) / 2; diff --git a/rk05.h b/rk05.h index 7496063..7ba4682 100644 --- a/rk05.h +++ b/rk05.h @@ -9,6 +9,7 @@ #include #include +#include "device.h" #include "disk_backend.h" @@ -24,7 +25,7 @@ class bus; -class rk05 +class rk05 : public device { private: bus *const b { nullptr }; @@ -42,11 +43,11 @@ public: rk05(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); virtual ~rk05(); - void reset(); + void reset() override; - uint8_t readByte(const uint16_t addr); - uint16_t readWord(const uint16_t addr); + uint8_t readByte(const uint16_t addr) override; + uint16_t readWord(const uint16_t addr) override; - void writeByte(const uint16_t addr, const uint8_t v); - void writeWord(const uint16_t addr, uint16_t v); + void writeByte(const uint16_t addr, const uint8_t v) override; + void writeWord(const uint16_t addr, const uint16_t v) override; }; diff --git a/rl02.h b/rl02.h index 5d9fb1a..64bc4d6 100644 --- a/rl02.h +++ b/rl02.h @@ -9,6 +9,7 @@ #include #include +#include "device.h" #include "disk_backend.h" @@ -25,7 +26,7 @@ constexpr const int rl02_bytes_per_sector = 256; class bus; -class rl02 +class rl02 : public device { private: bus *const b; @@ -49,11 +50,11 @@ public: rl02(const std::vector & files, bus *const b, std::atomic_bool *const disk_read_acitivity, std::atomic_bool *const disk_write_acitivity); virtual ~rl02(); - void reset(); + void reset() override; - uint8_t readByte(const uint16_t addr); - uint16_t readWord(const uint16_t addr); + uint8_t readByte(const uint16_t addr) override; + uint16_t readWord(const uint16_t addr) override; - void writeByte(const uint16_t addr, const uint8_t v); - void writeWord(const uint16_t addr, const uint16_t v); + void writeByte(const uint16_t addr, const uint8_t v) override; + void writeWord(const uint16_t addr, const uint16_t v) override; }; diff --git a/tm-11.h b/tm-11.h index 421c2da..31801c8 100644 --- a/tm-11.h +++ b/tm-11.h @@ -1,4 +1,4 @@ -// (C) 2018-2023 by Folkert van Heusden +// (C) 2018-2024 by Folkert van Heusden // Released under MIT license #pragma once @@ -7,6 +7,8 @@ #include #include +#include "device.h" + #define TM_11_MTS 0172520 // status register #define TM_11_MTC 0172522 // command register #define TM_11_MTBRC 0172524 // byte record counter @@ -16,9 +18,10 @@ #define TM_11_BASE TM_11_MTS #define TM_11_END (TM_11_MTRD + 2) + class memory; -class tm_11 +class tm_11 : public device { private: memory *const m { nullptr }; @@ -31,11 +34,11 @@ public: tm_11(const std::string & file, memory *const m); virtual ~tm_11(); - void reset(); + void reset() override; - uint8_t readByte(const uint16_t addr); - uint16_t readWord(const uint16_t addr); + uint8_t readByte(const uint16_t addr) override; + uint16_t readWord(const uint16_t addr) override; - void writeByte(const uint16_t addr, const uint8_t v); - void writeWord(const uint16_t addr, uint16_t v); + void writeByte(const uint16_t addr, const uint8_t v) override; + void writeWord(const uint16_t addr, uint16_t v) override; }; From 9f2339cda73a62a27100277db6a54d233b8eb13d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 09:45:55 +0200 Subject: [PATCH 13/16] split bus class into a mmu class --- CMakeLists.txt | 1 + breakpoint_register.cpp | 8 +- bus.cpp | 310 +++++++++++++--------------------------- bus.h | 48 ++----- cpu.cpp | 32 ++--- debugger.cpp | 12 +- gen.h | 6 + main.cpp | 4 +- mmu.cpp | 160 +++++++++++++++++++++ mmu.h | 71 +++++++++ 10 files changed, 377 insertions(+), 275 deletions(-) create mode 100644 mmu.cpp create mode 100644 mmu.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a9016a5..bdb83e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable( log.cpp main.cpp memory.cpp + mmu.cpp rk05.cpp rl02.cpp terminal.cpp diff --git a/breakpoint_register.cpp b/breakpoint_register.cpp index 20b2cc2..9a94f63 100644 --- a/breakpoint_register.cpp +++ b/breakpoint_register.cpp @@ -48,16 +48,16 @@ std::optional breakpoint_register::is_triggered() const switch(reg) { case hr_mmr0: - v = b->getMMR0(); + v = b->getMMU()->getMMR0(); break; case hr_mmr1: - v = b->getMMR1(); + v = b->getMMU()->getMMR1(); break; case hr_mmr2: - v = b->getMMR2(); + v = b->getMMU()->getMMR2(); break; case hr_mmr3: - v = b->getMMR3(); + v = b->getMMU()->getMMR3(); break; case hr_psw: v = c->getPSW(); diff --git a/bus.cpp b/bus.cpp index 6913a36..41932b2 100644 --- a/bus.cpp +++ b/bus.cpp @@ -10,6 +10,7 @@ #include "cpu.h" #include "log.h" #include "memory.h" +#include "mmu.h" #include "tm-11.h" #include "tty.h" #include "utils.h" @@ -18,7 +19,6 @@ #include #endif -constexpr const int di_ena_mask[4] = { 4, 2, 0, 1 }; bus::bus() { @@ -38,6 +38,7 @@ bus::~bus() delete rk05_; delete rl02_; delete tty_; + delete mmu_; delete m; } @@ -57,9 +58,7 @@ void bus::reset() { m->reset(); - memset(pages, 0x00, sizeof pages); - - CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0; + mmu_->reset(); if (c) c->reset(); @@ -105,38 +104,18 @@ void bus::add_tty(tty *const tty_) void bus::init() { - MMR0 = 0; - MMR3 = 0; -} - -uint16_t bus::read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) -{ - int page = (a >> 1) & 7; - bool is_d = a & 16; - uint16_t t = pages[run_mode][is_d][page].pdr; - - if (!peek_only) - DOLOG(debug, false, "READ-I/O PDR run-mode %d: %c for %d: %o", run_mode, is_d ? 'D' : 'I', page, t); - - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; -} - -uint16_t bus::read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) -{ - int page = (a >> 1) & 7; - bool is_d = a & 16; - uint16_t t = pages[run_mode][is_d][page].par; - - if (!peek_only) - DOLOG(debug, false, "READ-I/O PAR run-mode %d: %c for %d: %o (phys: %07o)", run_mode, is_d ? 'D' : 'I', page, t, t * 64); - - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; + mmu_->setMMR0(0); + mmu_->setMMR3(0); } void bus::trap_odd(const uint16_t a) { - MMR0 &= ~(7 << 1); - MMR0 |= (a >> 13) << 1; + uint16_t temp = mmu_->getMMR0(); + + temp &= ~(7 << 1); + temp |= (a >> 13) << 1; + + mmu_->setMMR0(temp); c->trap(004); // invalid access } @@ -196,7 +175,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } if (a == ADDR_CPU_ERR) { // cpu error register - uint16_t temp = CPUERR & 0xff; + uint16_t temp = mmu_->getCPUERR() & 0xff; if (!peek_only) DOLOG(debug, false, "READ-I/O CPU error: %03o", temp); return temp; } @@ -222,6 +201,8 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm if (a == ADDR_PIR || a == ADDR_PIR + 1) { // PIR uint16_t temp = 0; + uint16_t PIR = mmu_->getPIR(); + if (word_mode == wm_word) temp = PIR; else @@ -262,17 +243,17 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm /// MMU /// if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) - return read_pdr(a, 1, word_mode, peek_only); + return mmu_->read_pdr(a, 1, word_mode, peek_only); else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) - return read_par(a, 1, word_mode, peek_only); + return mmu_->read_par(a, 1, word_mode, peek_only); else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) - return read_pdr(a, 0, word_mode, peek_only); + return mmu_->read_pdr(a, 0, word_mode, peek_only); else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) - return read_par(a, 0, word_mode, peek_only); + return mmu_->read_par(a, 0, word_mode, peek_only); else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) - return read_pdr(a, 3, word_mode, peek_only); + return mmu_->read_pdr(a, 3, word_mode, peek_only); else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) - return read_par(a, 3, word_mode, peek_only); + return mmu_->read_par(a, 3, word_mode, peek_only); /////////// if (a >= 0177740 && a <= 0177753) { // cache control register and others @@ -327,37 +308,37 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } if (a == ADDR_MMR0) { - uint8_t temp = MMR0; + uint8_t temp = mmu_->getMMR0(); if (!peek_only) DOLOG(debug, false, "READ-I/O MMR0 LO: %03o", temp); return temp; } if (a == ADDR_MMR0 + 1) { - uint8_t temp = MMR0 >> 8; + uint8_t temp = mmu_->getMMR0() >> 8; if (!peek_only) DOLOG(debug, false, "READ-I/O MMR0 HI: %03o", temp); return temp; } } else { if (a == ADDR_MMR0) { - uint16_t temp = MMR0; + uint16_t temp = mmu_->getMMR0(); if (!peek_only) DOLOG(debug, false, "READ-I/O MMR0: %06o", temp); return temp; } if (a == ADDR_MMR1) { // MMR1 - uint16_t temp = MMR1; + uint16_t temp = mmu_->getMMR1(); if (!peek_only) DOLOG(debug, false, "READ-I/O MMR1: %06o", temp); return temp; } if (a == ADDR_MMR2) { // MMR2 - uint16_t temp = MMR2; + uint16_t temp = mmu_->getMMR2(); if (!peek_only) DOLOG(debug, false, "READ-I/O MMR2: %06o", temp); return temp; } if (a == ADDR_MMR3) { // MMR3 - uint16_t temp = MMR3; + uint16_t temp = mmu_->getMMR3(); if (!peek_only) DOLOG(debug, false, "READ-I/O MMR3: %06o", temp); return temp; } @@ -375,7 +356,7 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } if (a == ADDR_CPU_ERR) { // cpu error register - uint16_t temp = CPUERR; + uint16_t temp = mmu_->getCPUERR(); if (!peek_only) DOLOG(debug, false, "READ-I/O CPUERR: %06o", temp); return temp; } @@ -464,49 +445,11 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm return temp; } -void bus::setMMR0(uint16_t value) -{ - value &= ~(3 << 10); // bit 10 & 11 always read as 0 - - if (value & 1) - value &= ~(7l << 13); // reset error bits - - if (MMR0 & 0160000) { - if ((value & 1) == 0) - value &= 254; // bits 7...1 are protected - } - -// TODO if bit 15/14/13 are set (either of them), then do not modify bit 1...7 - - MMR0 = value; -} - -void bus::setMMR0Bit(const int bit) -{ - assert(bit != 10 && bit != 11); - assert(bit < 16 && bit >= 0); - - MMR0 |= 1 << bit; -} - -void bus::clearMMR0Bit(const int bit) -{ - assert(bit != 10 && bit != 11); - assert(bit < 16 && bit >= 0); - - MMR0 &= ~(1 << bit); -} - -void bus::setMMR2(const uint16_t value) -{ - MMR2 = value; -} - void bus::check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write) { if (a & 1) { if (is_write) - pages[run_mode][space == d_space][a >> 13].pdr |= 1 << 7; + mmu_->set_page_trapped(run_mode, space == d_space, a >> 13); trap_odd(a); @@ -518,25 +461,25 @@ memory_addresses_t bus::calculate_physical_address(const int run_mode, const uin { const uint8_t apf = a >> 13; // active page field - if ((MMR0 & 1) == 0) { + if (mmu_->is_enabled() == false) { bool is_psw = a == ADDR_PSW; return { a, apf, a, is_psw, a, is_psw }; } - uint32_t physical_instruction = pages[run_mode][0][apf].par * 64; - uint32_t physical_data = pages[run_mode][1][apf].par * 64; + uint32_t physical_instruction = mmu_->get_physical_memory_offset(run_mode, 0, apf); + uint32_t physical_data = mmu_->get_physical_memory_offset(run_mode, 1, apf); uint16_t p_offset = a & 8191; // page offset physical_instruction += p_offset; physical_data += p_offset; - if ((MMR3 & 16) == 0) { // offset is 18bit + if ((mmu_->getMMR3() & 16) == 0) { // offset is 18bit physical_instruction &= 0x3ffff; physical_data &= 0x3ffff; } - if (get_use_data_space(run_mode) == false) + if (mmu_->get_use_data_space(run_mode) == false) physical_data = physical_instruction; uint32_t io_base = get_io_base(); @@ -568,14 +511,9 @@ void bus::mmudebug(const uint16_t a) } } -bool bus::get_use_data_space(const int run_mode) const -{ - return !!(MMR3 & di_ena_mask[run_mode]); -} - std::pair bus::get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write) { - const int access_control = pages[run_mode][d][apf].pdr & 7; + const int access_control = mmu_->get_access_control(run_mode, d, apf); trap_action_t trap_action = T_PROCEED; @@ -609,18 +547,18 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c { uint32_t m_offset = a; - if ((MMR0 & 1 /* mmu enabled */) || (is_write && (MMR0 & (1 << 8 /* maintenance check */)))) { + if (mmu_->is_enabled() || (is_write && (mmu_->getMMR0() & (1 << 8 /* maintenance check */)))) { const uint8_t apf = a >> 13; // active page field - bool d = space == d_space && get_use_data_space(run_mode) ? space == d_space : false; + bool d = space == d_space && mmu_->get_use_data_space(run_mode) ? space == d_space : false; uint16_t p_offset = a & 8191; // page offset - m_offset = pages[run_mode][d][apf].par * 64; // memory offset + m_offset = mmu_->get_physical_memory_offset(run_mode, d, apf); m_offset += p_offset; - if ((MMR3 & 16) == 0) // off is 18bit + if ((mmu_->getMMR3() & 16) == 0) // off is 18bit m_offset &= 0x3ffff; uint32_t io_base = get_io_base(); @@ -634,28 +572,32 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c if (trap_action != T_PROCEED) { if (is_write) - pages[run_mode][d][apf].pdr |= 1 << 7; + mmu_->set_page_trapped(run_mode, d, apf); - if ((MMR0 & 0160000) == 0) { - MMR0 &= ~((1l << 15) | (1 << 14) | (1 << 13) | (1 << 12) | (3 << 5) | (7 << 1) | (1 << 4)); + if (mmu_->is_locked() == false) { + uint16_t temp = mmu_->getMMR0(); + + temp &= ~((1l << 15) | (1 << 14) | (1 << 13) | (1 << 12) | (3 << 5) | (7 << 1) | (1 << 4)); if (is_write && access_control != 6) - MMR0 |= 1 << 13; // read-only + temp |= 1 << 13; // read-only // if (access_control == 0 || access_control == 4) - MMR0 |= 1l << 15; // not resident + temp |= 1l << 15; // not resident else - MMR0 |= 1 << 13; // read-only + temp |= 1 << 13; // read-only - MMR0 |= run_mode << 5; // TODO: kernel-mode or user-mode when a trap occurs in user-mode? + temp |= run_mode << 5; // TODO: kernel-mode or user-mode when a trap occurs in user-mode? - MMR0 |= apf << 1; // add current page + temp |= apf << 1; // add current page - MMR0 |= d << 4; + temp |= d << 4; + + mmu_->setMMR0(temp); + + DOLOG(debug, false, "MMR0: %06o", temp); } - DOLOG(debug, false, "MMR0: %06o", MMR0); - if (trap_action == T_TRAP_250) { DOLOG(debug, false, "Page access %d (for virtual address %06o): trap 0250", access_control, a); @@ -677,29 +619,33 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(debug, !peek_only, "bus::calculate_physical_address %o >= %o", m_offset, n_pages * 8192l); DOLOG(debug, false, "TRAP(04) (throw 6) on address %06o", a); - if ((MMR0 & 0160000) == 0) { - MMR0 &= 017777; - MMR0 |= 1l << 15; // non-resident + if (mmu_->is_locked() == false) { + uint16_t temp = mmu_->getMMR0(); - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + temp &= 017777; + temp |= 1l << 15; // non-resident - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; + temp &= ~14; // add current page + temp |= apf << 1; + + temp &= ~(3 << 5); + temp |= run_mode << 5; + + mmu_->setMMR0(temp); } if (is_write) - pages[run_mode][d][apf].pdr |= 1 << 7; + mmu_->set_page_trapped(run_mode, d, apf); c->trap(04); throw 6; } - uint16_t pdr_len = (pages[run_mode][d][apf].pdr >> 8) & 127; + uint16_t pdr_len = mmu_->get_pdr_len(run_mode, d, apf); uint16_t pdr_cmp = (a >> 6) & 127; - bool direction = pages[run_mode][d][apf].pdr & 8; + bool direction = mmu_->get_pdr_direction(run_mode, d, apf); // DOLOG(debug, false, "p_offset %06o pdr_len %06o direction %d, run_mode %d, apf %d, pdr: %06o", p_offset, pdr_len, direction, run_mode, apf, pages[run_mode][d][apf].pdr); @@ -708,28 +654,34 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c DOLOG(debug, false, "TRAP(0250) (throw 7) on address %06o", a); c->trap(0250); // invalid access - if ((MMR0 & 0160000) == 0) { - MMR0 &= 017777; - MMR0 |= 1 << 14; // length + if (mmu_->is_locked() == false) { + uint16_t temp = mmu_->getMMR0(); - MMR0 &= ~14; // add current page - MMR0 |= apf << 1; + temp &= 017777; + temp |= 1 << 14; // length - MMR0 &= ~(3 << 5); - MMR0 |= run_mode << 5; + temp &= ~14; // add current page + temp |= apf << 1; - MMR0 &= ~(1 << 4); - MMR0 |= d << 4; + temp &= ~(3 << 5); + temp |= run_mode << 5; + + temp &= ~(1 << 4); + temp |= d << 4; + + mmu_->setMMR0(temp); } if (is_write) - pages[run_mode][d][apf].pdr |= 1 << 7; + mmu_->set_page_trapped(run_mode, d, apf); throw 7; } } - DOLOG(debug, false, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff: %o, AC: %d, %s)", a, m_offset, run_mode, apf, pages[run_mode][d][apf].par * 64, p_offset, pages[run_mode][d][apf].pdr & 7, d ? "D" : "I"); + DOLOG(debug, false, "virtual address %06o maps to physical address %08o (run_mode: %d, apf: %d, par: %08o, poff: %o, AC: %d, %s)", a, m_offset, run_mode, apf, + mmu_->get_physical_memory_offset(run_mode, d, apf), + p_offset, mmu_->get_access_control(run_mode, d, apf), d ? "D" : "I"); } else { // DOLOG(debug, false, "no MMU (read physical address %08o)", m_offset); @@ -738,69 +690,6 @@ uint32_t bus::calculate_physical_address(const int run_mode, const uint16_t a, c return m_offset; } -void bus::clearMMR1() -{ - MMR1 = 0; -} - -void bus::addToMMR1(const int8_t delta, const uint8_t reg) -{ - assert(reg >= 0 && reg <= 7); - assert(delta >= -2 && delta <= 2); - - assert((getMMR0() & 0160000) == 0); // MMR1 should not be locked - -#if defined(ESP32) -// if (MMR1 > 255) -// esp_backtrace_print(32); -#else - if (MMR1 > 255) { - extern FILE *lfh; - fflush(lfh); - } - assert(MMR1 < 256); -#endif - - MMR1 <<= 8; - - MMR1 |= (delta & 31) << 3; - MMR1 |= reg; -} - -void bus::write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode) -{ - bool is_d = a & 16; - int page = (a >> 1) & 7; - - if (word_mode == wm_byte) { - assert(a != 0 || value < 256); - - update_word(&pages[run_mode][is_d][page].pdr, a & 1, value); - } - else { - pages[run_mode][is_d][page].pdr = value; - } - - pages[run_mode][is_d][page].pdr &= ~(32768 + 128 /*A*/ + 64 /*W*/ + 32 + 16); // set bit 4, 5 & 15 to 0 as they are unused and A/W are set to 0 by writes - - DOLOG(debug, false, "WRITE-I/O PDR run-mode %d: %c for %d: %o [%d]", run_mode, is_d ? 'D' : 'I', page, value, word_mode); -} - -void bus::write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode) -{ - bool is_d = a & 16; - int page = (a >> 1) & 7; - - if (word_mode == wm_byte) - update_word(&pages[run_mode][is_d][page].par, a & 1, value); - else - pages[run_mode][is_d][page].par = value; - - pages[run_mode][is_d][page].pdr &= ~(128 /*A*/ + 64 /*W*/); // reset PDR A/W when PAR is written to - - DOLOG(debug, false, "WRITE-I/O PAR run-mode %d: %c for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode == wm_byte ? value & 0xff : value, pages[run_mode][is_d][page].par * 64); -} - write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t space) { int run_mode = mode_selection == rm_cur ? c->getPSW_runmode() : c->getPSW_prev_runmode(); @@ -809,10 +698,10 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 bool is_data = space == d_space; - bool d = is_data && get_use_data_space(run_mode) ? is_data : false; + bool d = is_data && mmu_->get_use_data_space(run_mode) ? is_data : false; - if ((MMR0 & 1) == 1 && (addr_in & 1) == 0 && addr_in != ADDR_MMR0) - pages[run_mode][d][apf].pdr |= 64; // set 'W' (written to) bit + if (mmu_->is_enabled() && (addr_in & 1) == 0 /* TODO remove this? */ && addr_in != ADDR_MMR0) + mmu_->set_page_written_to(run_mode, d, apf); uint32_t m_offset = calculate_physical_address(run_mode, addr_in, true, true, false, space); @@ -862,7 +751,9 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 if (a == ADDR_MMR0 || a == ADDR_MMR0 + 1) { // MMR0 DOLOG(debug, false, "WRITE-I/O MMR0 register %s: %03o", a & 1 ? "MSB" : "LSB", value); - update_word(&MMR0, a & 1, value); + uint16_t temp = mmu_->getMMR0(); + update_word(&temp, a & 1, value); + mmu_->setMMR0(temp); return { false }; } @@ -922,19 +813,19 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 if (a == ADDR_CPU_ERR) { // cpu error register DOLOG(debug, false, "WRITE-I/O CPUERR: %06o", value); - CPUERR = 0; + mmu_->setCPUERR(0); return { false }; } if (a == ADDR_MMR3) { // MMR3 DOLOG(debug, false, "WRITE-I/O set MMR3: %06o", value); - MMR3 = value; + mmu_->setMMR3(value); return { false }; } if (a == ADDR_MMR0) { // MMR0 DOLOG(debug, false, "WRITE-I/O set MMR0: %06o", value); - setMMR0(value); + mmu_->setMMR0(value); return { false }; } @@ -950,7 +841,8 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 bits >>= 1; } - PIR = value; + mmu_->setPIR(value); + return { false }; } @@ -1001,31 +893,31 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 /// MMU /// // supervisor if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) { - write_pdr(a, 1, value, word_mode); + mmu_->write_pdr(a, 1, value, word_mode); return { false }; } if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) { - write_par(a, 1, value, word_mode); + mmu_->write_par(a, 1, value, word_mode); return { false }; } // kernel if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) { - write_pdr(a, 0, value, word_mode); + mmu_->write_pdr(a, 0, value, word_mode); return { false }; } if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) { - write_par(a, 0, value, word_mode); + mmu_->write_par(a, 0, value, word_mode); return { false }; } // user if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) { - write_pdr(a, 3, value, word_mode); + mmu_->write_pdr(a, 3, value, word_mode); return { false }; } if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) { - write_par(a, 3, value, word_mode); + mmu_->write_par(a, 3, value, word_mode); return { false }; } //// diff --git a/bus.h b/bus.h index fb3eac0..eab0947 100644 --- a/bus.h +++ b/bus.h @@ -8,9 +8,11 @@ #include #include -#include "tm-11.h" +#include "gen.h" +#include "mmu.h" #include "rk05.h" #include "rl02.h" +#include "tm-11.h" #if defined(BUILD_FOR_RP2040) #include "rp2040.h" @@ -70,12 +72,6 @@ class cpu; class memory; class tty; -typedef enum { d_space, i_space } d_i_space_t; - -typedef enum { wm_word = 0, wm_byte = 1 } word_mode_t; - -typedef enum { rm_prev, rm_cur } rm_selection_t; - typedef enum { T_PROCEED, T_ABORT_4, T_TRAP_250 } trap_action_t; typedef struct { @@ -87,10 +83,6 @@ typedef struct { bool physical_data_is_psw; } memory_addresses_t; -typedef struct { - uint16_t par, pdr; -} page_t; - typedef struct { bool is_psw; } write_rc_t; @@ -104,14 +96,11 @@ private: rl02 *rl02_ { nullptr }; tty *tty_ { nullptr }; + mmu *mmu_ { nullptr }; + int n_pages { DEFAULT_N_PAGES }; memory *m { nullptr }; - // 8 pages, D/I, 3 modes and 1 invalid mode - page_t pages[4][2][8]; - - uint16_t MMR0 { 0 }, MMR1 { 0 }, MMR2 { 0 }, MMR3 { 0 }, CPUERR { 0 }, PIR { 0 }, CSR { 0 }; - #if defined(BUILD_FOR_RP2040) SemaphoreHandle_t lf_csr_lock { xSemaphoreCreateBinary() }; #else @@ -124,11 +113,6 @@ private: uint16_t console_switches { 0 }; uint16_t console_leds { 0 }; - uint16_t read_pdr (const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); - uint16_t read_par (const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); - void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); - void write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); - public: bus(); ~bus(); @@ -153,9 +137,11 @@ public: void add_rl02(rl02 *const rl02_); void add_tty (tty *const tty_); - cpu *getCpu() { return this->c; } + cpu *getCpu() { return c; } - tty *getTty() { return this->tty_; } + tty *getTty() { return tty_; } + + mmu *getMMU() { return mmu_; } void init(); // invoked by 'RESET' command @@ -178,29 +164,15 @@ public: void writeUnibusByte(const uint32_t a, const uint8_t value); - uint16_t getMMR0() const { return MMR0; } - uint16_t getMMR1() const { return MMR1; } - uint16_t getMMR2() const { return MMR2; } - uint16_t getMMR3() const { return MMR3; } - uint16_t getMMR(int nr) const { const uint16_t *const mmrs[] { &MMR0, &MMR1, &MMR2, &MMR3 }; return *mmrs[nr]; } - bool isMMR1Locked() const { return !!(MMR0 & 0160000); } - void clearMMR1(); - void addToMMR1(const int8_t delta, const uint8_t reg); - void setMMR0(const uint16_t value); - void setMMR0Bit(const int bit); - void clearMMR0Bit(const int bit); - void setMMR2(uint16_t value); - void check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write); void trap_odd(const uint16_t a); - uint32_t get_io_base() const { return MMR0 & 1 ? (MMR3 & 16 ? 017760000 : 0760000) : 0160000; } + uint32_t get_io_base() const { return mmu_->getMMR0() & 1 ? (mmu_->getMMR3() & 16 ? 017760000 : 0760000) : 0160000; } bool is_psw(const uint16_t addr, const int run_mode, const d_i_space_t space) const; std::pair get_trap_action(const int run_mode, const bool d, const int apf, const bool is_write); uint32_t calculate_physical_address(const int run_mode, const uint16_t a, const bool trap_on_failure, const bool is_write, const bool peek_only, const d_i_space_t space); - bool get_use_data_space(const int run_mode) const; memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a) const; void check_address(const bool trap_on_failure, const bool is_write, const memory_addresses_t & addr, const word_mode_t word_mode, const bool is_data, const int run_mode); }; diff --git a/cpu.cpp b/cpu.cpp index 8ae9891..d5e9582 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -460,10 +460,10 @@ void cpu::queue_interrupt(const uint8_t level, const uint8_t vector) void cpu::addToMMR1(const gam_rc_t & g) { - if (!b->isMMR1Locked() && g.mmr1_update.has_value()) { + if (!b->getMMU()->isMMR1Locked() && g.mmr1_update.has_value()) { assert(g.mmr1_update.value().delta); - b->addToMMR1(g.mmr1_update.value().delta, g.mmr1_update.value().reg); + b->getMMU()->addToMMR1(g.mmr1_update.value().delta, g.mmr1_update.value().reg); } } @@ -472,7 +472,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t wo { gam_rc_t g { word_mode, mode_selection, i_space, mode, { }, { }, { }, { } }; - d_i_space_t isR7_space = reg == 7 ? i_space : (b->get_use_data_space(getPSW_runmode()) ? d_space : i_space); + d_i_space_t isR7_space = reg == 7 ? i_space : (b->getMMU()->get_use_data_space(getPSW_runmode()) ? d_space : i_space); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ always d_space here? TODO g.space = isR7_space; @@ -1737,8 +1737,8 @@ bool cpu::misc_operations(const uint16_t instr) // PUSH link pushStack(getRegister(link_reg)); - if (!b->isMMR1Locked()) { - b->addToMMR1(-2, 6); + if (!b->getMMU()->isMMR1Locked()) { + b->getMMU()->addToMMR1(-2, 6); addToMMR1(a); } @@ -1806,7 +1806,7 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt) setRegister(6, 04); } else { - b->clearMMR1(); + b->getMMU()->clearMMR1(); before_psw = getPSW(); @@ -2343,10 +2343,10 @@ std::map > cpu::disassemble(const uint16_t work_values_str.push_back(format("%06o", v)); out.insert({ "work-values", work_values_str }); - out.insert({ "MMR0", { format("%06o", b->getMMR0()) } }); - out.insert({ "MMR1", { format("%06o", b->getMMR1()) } }); - out.insert({ "MMR2", { format("%06o", b->getMMR2()) } }); - out.insert({ "MMR3", { format("%06o", b->getMMR3()) } }); + out.insert({ "MMR0", { format("%06o", b->getMMU()->getMMR0()) } }); + out.insert({ "MMR1", { format("%06o", b->getMMU()->getMMR1()) } }); + out.insert({ "MMR2", { format("%06o", b->getMMU()->getMMR2()) } }); + out.insert({ "MMR3", { format("%06o", b->getMMU()->getMMR3()) } }); return out; } @@ -2355,12 +2355,12 @@ void cpu::step() { it_is_a_trap = false; - if (!b->isMMR1Locked()) - b->clearMMR1(); + if (!b->getMMU()->isMMR1Locked()) + b->getMMU()->clearMMR1(); if (any_queued_interrupts && execute_any_pending_interrupt()) { - if (!b->isMMR1Locked()) - b->clearMMR1(); + if (!b->getMMU()->isMMR1Locked()) + b->getMMU()->clearMMR1(); } instruction_count++; @@ -2368,8 +2368,8 @@ void cpu::step() try { instruction_start = getPC(); - if (!b->isMMR1Locked()) - b->setMMR2(instruction_start); + if (!b->getMMU()->isMMR1Locked()) + b->getMMU()->setMMR2(instruction_start); uint16_t instr = b->readWord(instruction_start); diff --git a/debugger.cpp b/debugger.cpp index 857c02a..d78df6b 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -588,10 +588,10 @@ void dump_range_as_instructions(console *const cnsl, bus *const b, const uint16_ void mmu_dump(console *const cnsl, bus *const b, const bool verbose) { - uint16_t mmr0 = b->getMMR0(); - uint16_t mmr1 = b->getMMR1(); - uint16_t mmr2 = b->getMMR2(); - uint16_t mmr3 = b->getMMR3(); + uint16_t mmr0 = b->getMMU()->getMMR0(); + uint16_t mmr1 = b->getMMU()->getMMR1(); + uint16_t mmr2 = b->getMMU()->getMMR2(); + uint16_t mmr3 = b->getMMU()->getMMR3(); cnsl->put_string_lf(mmr0 & 1 ? "MMU enabled" : "MMU NOT enabled"); @@ -639,7 +639,7 @@ const char *trap_action_to_str(const trap_action_t ta) void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va) { int run_mode = b->getCpu()->getPSW_runmode(); - cnsl->put_string_lf(format("Run mode: %d, use data space: %d", run_mode, b->get_use_data_space(run_mode))); + cnsl->put_string_lf(format("Run mode: %d, use data space: %d", run_mode, b->getMMU()->get_use_data_space(run_mode))); auto data = b->calculate_physical_address(run_mode, va); @@ -648,7 +648,7 @@ void mmu_resolve(console *const cnsl, bus *const b, const uint16_t va) cnsl->put_string_lf(format("Phys. addr. instruction: %08o (psw: %d)", data.physical_instruction, data.physical_instruction_is_psw)); cnsl->put_string_lf(format("Phys. addr. data: %08o (psw: %d)", data.physical_data, data.physical_data_is_psw)); - uint16_t mmr3 = b->getMMR3(); + uint16_t mmr3 = b->getMMU()->getMMR3(); if (run_mode == 0) { dump_par_pdr(cnsl, b, ADDR_PDR_K_START, ADDR_PAR_K_START, "kernel i-space", 0, data.apf); diff --git a/gen.h b/gen.h index 6dda84e..73e00ad 100644 --- a/gen.h +++ b/gen.h @@ -6,3 +6,9 @@ typedef enum { EVENT_NONE = 0, EVENT_HALT, EVENT_INTERRUPT, EVENT_TERMINATE } stop_event_t; typedef enum { DT_RK05, DT_RL02, DT_TAPE } disk_type_t; + +typedef enum { d_space, i_space } d_i_space_t; + +typedef enum { wm_word = 0, wm_byte = 1 } word_mode_t; + +typedef enum { rm_prev, rm_cur } rm_selection_t; diff --git a/main.cpp b/main.cpp index f935b58..71fa638 100644 --- a/main.cpp +++ b/main.cpp @@ -122,7 +122,7 @@ int run_cpu_validation(const std::string & filename) { json_t *a_mmr0 = json_object_get(test, "mmr0-before"); assert(a_mmr0); - b->setMMR0(json_integer_value(a_mmr0)); + b->getMMU()->setMMR0(json_integer_value(a_mmr0)); } disassemble(c, nullptr, start_pc, false); @@ -209,7 +209,7 @@ int run_cpu_validation(const std::string & filename) json_t *a_mmr = json_object_get(test, format("mmr%d-after", r).c_str()); assert(a_mmr); uint16_t should_be_mmr = json_integer_value(a_mmr); - uint16_t is_mmr = b->getMMR(r); + uint16_t is_mmr = b->getMMU()->getMMR(r); if (should_be_mmr != is_mmr) { int is_d1 = is_mmr >> 11; if (is_d1 & 16) diff --git a/mmu.cpp b/mmu.cpp new file mode 100644 index 0000000..2cdb12c --- /dev/null +++ b/mmu.cpp @@ -0,0 +1,160 @@ +#include +#include + +#include "gen.h" +#include "log.h" +#include "mmu.h" +#include "utils.h" + + +mmu::mmu() +{ +} + +mmu::~mmu() +{ +} + +void mmu::reset() +{ + memset(pages, 0x00, sizeof pages); + + CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0; +} + +uint16_t mmu::read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) +{ + int page = (a >> 1) & 7; + bool is_d = a & 16; + uint16_t t = pages[run_mode][is_d][page].pdr; + + if (!peek_only) + DOLOG(debug, false, "MMU READ-I/O PDR run-mode %d: %c for %d: %o", run_mode, is_d ? 'D' : 'I', page, t); + + return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; +} + +uint16_t mmu::read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) +{ + int page = (a >> 1) & 7; + bool is_d = a & 16; + uint16_t t = pages[run_mode][is_d][page].par; + + if (!peek_only) + DOLOG(debug, false, "MMU READ-I/O PAR run-mode %d: %c for %d: %o (phys: %07o)", run_mode, is_d ? 'D' : 'I', page, t, t * 64); + + return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; +} + +void mmu::setMMR0(uint16_t value) +{ + value &= ~(3 << 10); // bit 10 & 11 always read as 0 + + if (value & 1) + value &= ~(7l << 13); // reset error bits + + if (MMR0 & 0160000) { + if ((value & 1) == 0) + value &= 254; // bits 7...1 are protected + } + +// TODO if bit 15/14/13 are set (either of them), then do not modify bit 1...7 + + MMR0 = value; +} + +void mmu::setMMR0Bit(const int bit) +{ + assert(bit != 10 && bit != 11); + assert(bit < 16 && bit >= 0); + + MMR0 |= 1 << bit; +} + +void mmu::clearMMR0Bit(const int bit) +{ + assert(bit != 10 && bit != 11); + assert(bit < 16 && bit >= 0); + + MMR0 &= ~(1 << bit); +} + +void mmu::setMMR2(const uint16_t value) +{ + MMR2 = value; +} + +void mmu::setMMR3(const uint16_t value) +{ + MMR3 = value; +} + +bool mmu::get_use_data_space(const int run_mode) const +{ + constexpr const int di_ena_mask[4] = { 4, 2, 0, 1 }; + + return !!(MMR3 & di_ena_mask[run_mode]); +} + +void mmu::clearMMR1() +{ + MMR1 = 0; +} + +void mmu::addToMMR1(const int8_t delta, const uint8_t reg) +{ + assert(reg >= 0 && reg <= 7); + assert(delta >= -2 && delta <= 2); + + assert((getMMR0() & 0160000) == 0); // MMR1 should not be locked + +#if defined(ESP32) +// if (MMR1 > 255) +// esp_backtrace_print(32); +#else + if (MMR1 > 255) { + extern FILE *lfh; + fflush(lfh); + } + assert(MMR1 < 256); +#endif + + MMR1 <<= 8; + + MMR1 |= (delta & 31) << 3; + MMR1 |= reg; +} + +void mmu::write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode) +{ + bool is_d = a & 16; + int page = (a >> 1) & 7; + + if (word_mode == wm_byte) { + assert(a != 0 || value < 256); + + update_word(&pages[run_mode][is_d][page].pdr, a & 1, value); + } + else { + pages[run_mode][is_d][page].pdr = value; + } + + pages[run_mode][is_d][page].pdr &= ~(32768 + 128 /*A*/ + 64 /*W*/ + 32 + 16); // set bit 4, 5 & 15 to 0 as they are unused and A/W are set to 0 by writes + + DOLOG(debug, false, "mmu WRITE-I/O PDR run-mode %d: %c for %d: %o [%d]", run_mode, is_d ? 'D' : 'I', page, value, word_mode); +} + +void mmu::write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode) +{ + bool is_d = a & 16; + int page = (a >> 1) & 7; + + if (word_mode == wm_byte) + update_word(&pages[run_mode][is_d][page].par, a & 1, value); + else + pages[run_mode][is_d][page].par = value; + + pages[run_mode][is_d][page].pdr &= ~(128 /*A*/ + 64 /*W*/); // reset PDR A/W when PAR is written to + + DOLOG(debug, false, "mmu WRITE-I/O PAR run-mode %d: %c for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode == wm_byte ? value & 0xff : value, pages[run_mode][is_d][page].par * 64); +} diff --git a/mmu.h b/mmu.h new file mode 100644 index 0000000..f508b69 --- /dev/null +++ b/mmu.h @@ -0,0 +1,71 @@ +#pragma once + +#include + + +typedef struct { + uint16_t par; + uint16_t pdr; +} page_t; + +class mmu +{ +private: + // 8 pages, D/I, 3 modes and 1 invalid mode + page_t pages[4][2][8]; + + uint16_t MMR0 { 0 }; + uint16_t MMR1 { 0 }; + uint16_t MMR2 { 0 }; + uint16_t MMR3 { 0 }; + uint16_t CPUERR { 0 }; + uint16_t PIR { 0 }; + uint16_t CSR { 0 }; + +public: + mmu(); + virtual ~mmu(); + + void reset(); + + bool is_enabled() const { return MMR0 & 1; } + bool is_locked() const { return !!(MMR0 & 0160000); } + + void set_page_trapped (const int run_mode, const bool d, const int apf) { pages[run_mode][d][apf].pdr |= 1 << 7; } + void set_page_written_to(const int run_mode, const bool d, const int apf) { pages[run_mode][d][apf].pdr |= 1 << 6; } + int get_access_control (const int run_mode, const bool d, const int apf) { return pages[run_mode][d][apf].pdr & 7; } + int get_pdr_len (const int run_mode, const bool d, const int apf) { return (pages[run_mode][d][apf].pdr >> 8) & 127; } + int get_pdr_direction (const int run_mode, const bool d, const int apf) { return pages[run_mode][d][apf].pdr & 8; } + uint32_t get_physical_memory_offset(const int run_mode, const bool d, const int apf) const { return pages[run_mode][d][apf].par * 64; } + bool get_use_data_space(const int run_mode) const; + + uint16_t getMMR0() const { return MMR0; } + uint16_t getMMR1() const { return MMR1; } + uint16_t getMMR2() const { return MMR2; } + uint16_t getMMR3() const { return MMR3; } + uint16_t getMMR(int nr) const { const uint16_t *const mmrs[] { &MMR0, &MMR1, &MMR2, &MMR3 }; return *mmrs[nr]; } + + void setMMR0(const uint16_t value); + void setMMR1(const uint16_t value); + void setMMR2(const uint16_t value); + void setMMR3(const uint16_t value); + + bool isMMR1Locked() const { return !!(MMR0 & 0160000); } + void clearMMR1(); + void addToMMR1(const int8_t delta, const uint8_t reg); + + void setMMR0Bit(const int bit); + void clearMMR0Bit(const int bit); + + uint16_t getCPUERR() const { return CPUERR; } + void setCPUERR(const uint16_t v) { CPUERR = v; } + + uint16_t getPIR() const { return PIR; }; + void setPIR(const uint16_t v) { PIR = v; } + + uint16_t read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); + uint16_t read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); + + void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); + void write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); +}; From 37e6d3056141432b191b1fd416ec67d318c4c5af Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 09:47:57 +0200 Subject: [PATCH 14/16] missing instantiating of mmu --- bus.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bus.cpp b/bus.cpp index 41932b2..d4f065f 100644 --- a/bus.cpp +++ b/bus.cpp @@ -24,6 +24,8 @@ bus::bus() { m = new memory(n_pages * 8192l); + mmu_ = new mmu(); + reset(); #if defined(BUILD_FOR_RP2040) From 4cfb01a014b2516583f371a0d1c73d9e28218f5d Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 12:28:09 +0200 Subject: [PATCH 15/16] shuffle --- bus.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bus.h b/bus.h index eab0947..dc85cee 100644 --- a/bus.h +++ b/bus.h @@ -154,15 +154,14 @@ public: uint16_t peekWord(const uint16_t a); uint8_t readUnibusByte(const uint32_t a); + void writeUnibusByte(const uint32_t a, const uint8_t value); write_rc_t write (const uint16_t a, const word_mode_t word_mode, uint16_t value, const rm_selection_t mode_selection, const d_i_space_t s = i_space); void writeByte(const uint16_t a, const uint8_t value) { write(a, wm_byte, value, rm_cur); } void writeWord(const uint16_t a, const uint16_t value, const d_i_space_t s = i_space); uint16_t readPhysical(const uint32_t a); - void writePhysical(const uint32_t a, const uint16_t value); - - void writeUnibusByte(const uint32_t a, const uint8_t value); + void writePhysical(const uint32_t a, const uint16_t value); void check_odd_addressing(const uint16_t a, const int run_mode, const d_i_space_t space, const bool is_write); void trap_odd(const uint16_t a); From 20fbb25aedbe25638e32de1dc0394ff7f3bbfc74 Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Thu, 25 Apr 2024 13:24:32 +0200 Subject: [PATCH 16/16] mmu is now of device type --- bus.cpp | 59 +++++++++++++++-------------------------- bus.h | 15 ----------- mmu.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------- mmu.h | 31 +++++++++++++++++++--- 4 files changed, 120 insertions(+), 67 deletions(-) diff --git a/bus.cpp b/bus.cpp index d4f065f..8198ae3 100644 --- a/bus.cpp +++ b/bus.cpp @@ -244,18 +244,17 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm } /// MMU /// - if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) - return mmu_->read_pdr(a, 1, word_mode, peek_only); - else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) - return mmu_->read_par(a, 1, word_mode, peek_only); - else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) - return mmu_->read_pdr(a, 0, word_mode, peek_only); - else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) - return mmu_->read_par(a, 0, word_mode, peek_only); - else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) - return mmu_->read_pdr(a, 3, word_mode, peek_only); - else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) - return mmu_->read_par(a, 3, word_mode, peek_only); + if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || + (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || + (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || + (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if (word_mode == wm_word) + return mmu_->readWord(a); + + return mmu_->readByte(a); + } /////////// if (a >= 0177740 && a <= 0177753) { // cache control register and others @@ -894,35 +893,19 @@ write_rc_t bus::write(const uint16_t addr_in, const word_mode_t word_mode, uint1 /// MMU /// // supervisor - if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) { - mmu_->write_pdr(a, 1, value, word_mode); - return { false }; - } - if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) { - mmu_->write_par(a, 1, value, word_mode); - return { false }; - } + if ((a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) || + (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) || + (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) || + (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) || + (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) || + (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END)) { + if (word_mode == wm_word) + mmu_->writeWord(a, value); + else + mmu_->writeByte(a, value); - // kernel - if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) { - mmu_->write_pdr(a, 0, value, word_mode); return { false }; } - if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) { - mmu_->write_par(a, 0, value, word_mode); - return { false }; - } - - // user - if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) { - mmu_->write_pdr(a, 3, value, word_mode); - return { false }; - } - if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) { - mmu_->write_par(a, 3, value, word_mode); - return { false }; - } - //// if (a >= 0177740 && a <= 0177753) { // cache control register and others // TODO diff --git a/bus.h b/bus.h index dc85cee..e61243a 100644 --- a/bus.h +++ b/bus.h @@ -38,21 +38,6 @@ #define ADDR_KW11P 0172540 #define ADDR_LP11CSR 0177514 // printer -#define ADDR_PDR_SV_START 0172200 -#define ADDR_PDR_SV_END 0172240 -#define ADDR_PAR_SV_START 0172240 -#define ADDR_PAR_SV_END 0172300 - -#define ADDR_PDR_K_START 0172300 -#define ADDR_PDR_K_END 0172340 -#define ADDR_PAR_K_START 0172340 -#define ADDR_PAR_K_END 0172400 - -#define ADDR_PDR_U_START 0177600 -#define ADDR_PDR_U_END 0177640 -#define ADDR_PAR_U_START 0177640 -#define ADDR_PAR_U_END 0177700 - #define ADDR_PSW 0177776 #define ADDR_STACKLIM 0177774 #define ADDR_KERNEL_R 0177700 diff --git a/mmu.cpp b/mmu.cpp index 2cdb12c..b0083ab 100644 --- a/mmu.cpp +++ b/mmu.cpp @@ -22,28 +22,22 @@ void mmu::reset() CPUERR = MMR0 = MMR1 = MMR2 = MMR3 = PIR = CSR = 0; } -uint16_t mmu::read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) +uint16_t mmu::read_pdr(const uint32_t a, const int run_mode) { int page = (a >> 1) & 7; bool is_d = a & 16; uint16_t t = pages[run_mode][is_d][page].pdr; - if (!peek_only) - DOLOG(debug, false, "MMU READ-I/O PDR run-mode %d: %c for %d: %o", run_mode, is_d ? 'D' : 'I', page, t); - - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; + return t; } -uint16_t mmu::read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only) +uint16_t mmu::read_par(const uint32_t a, const int run_mode) { int page = (a >> 1) & 7; bool is_d = a & 16; uint16_t t = pages[run_mode][is_d][page].par; - if (!peek_only) - DOLOG(debug, false, "MMU READ-I/O PAR run-mode %d: %c for %d: %o (phys: %07o)", run_mode, is_d ? 'D' : 'I', page, t, t * 64); - - return word_mode ? (a & 1 ? t >> 8 : t & 255) : t; + return t; } void mmu::setMMR0(uint16_t value) @@ -158,3 +152,71 @@ void mmu::write_par(const uint32_t a, const int run_mode, const uint16_t value, DOLOG(debug, false, "mmu WRITE-I/O PAR run-mode %d: %c for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode == wm_byte ? value & 0xff : value, pages[run_mode][is_d][page].par * 64); } + +uint16_t mmu::readWord(const uint16_t a) +{ + uint16_t v = 0; + + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) + v = read_pdr(a, 1); + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) + v = read_par(a, 1); + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) + v = read_pdr(a, 0); + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) + v = read_par(a, 0); + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) + v = read_pdr(a, 3); + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) + v = read_par(a, 3); + + return v; +} + +uint8_t mmu::readByte(const uint16_t addr) +{ + uint16_t v = readWord(addr); + + if (addr & 1) + return v >> 8; + + return v; +} + +void mmu::writeWord(const uint16_t a, const uint16_t value) +{ + // supervisor + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) + write_pdr(a, 1, value, wm_word); + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) + write_par(a, 1, value, wm_word); + // kernel + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) + write_pdr(a, 0, value, wm_word); + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) + write_par(a, 0, value, wm_word); + // user + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) + write_pdr(a, 3, value, wm_word); + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) + write_par(a, 3, value, wm_word); +} + +void mmu::writeByte(const uint16_t a, const uint8_t value) +{ + // supervisor + if (a >= ADDR_PDR_SV_START && a < ADDR_PDR_SV_END) + write_pdr(a, 1, value, wm_byte); + else if (a >= ADDR_PAR_SV_START && a < ADDR_PAR_SV_END) + write_par(a, 1, value, wm_byte); + // kernel + else if (a >= ADDR_PDR_K_START && a < ADDR_PDR_K_END) + write_pdr(a, 0, value, wm_byte); + else if (a >= ADDR_PAR_K_START && a < ADDR_PAR_K_END) + write_par(a, 0, value, wm_byte); + // user + else if (a >= ADDR_PDR_U_START && a < ADDR_PDR_U_END) + write_pdr(a, 3, value, wm_byte); + else if (a >= ADDR_PAR_U_START && a < ADDR_PAR_U_END) + write_par(a, 3, value, wm_byte); +} diff --git a/mmu.h b/mmu.h index f508b69..22ed44e 100644 --- a/mmu.h +++ b/mmu.h @@ -2,13 +2,30 @@ #include +#include "device.h" + +#define ADDR_PDR_SV_START 0172200 +#define ADDR_PDR_SV_END 0172240 +#define ADDR_PAR_SV_START 0172240 +#define ADDR_PAR_SV_END 0172300 + +#define ADDR_PDR_K_START 0172300 +#define ADDR_PDR_K_END 0172340 +#define ADDR_PAR_K_START 0172340 +#define ADDR_PAR_K_END 0172400 + +#define ADDR_PDR_U_START 0177600 +#define ADDR_PDR_U_END 0177640 +#define ADDR_PAR_U_START 0177640 +#define ADDR_PAR_U_END 0177700 + typedef struct { uint16_t par; uint16_t pdr; } page_t; -class mmu +class mmu : public device { private: // 8 pages, D/I, 3 modes and 1 invalid mode @@ -26,7 +43,7 @@ public: mmu(); virtual ~mmu(); - void reset(); + void reset() override; bool is_enabled() const { return MMR0 & 1; } bool is_locked() const { return !!(MMR0 & 0160000); } @@ -63,9 +80,15 @@ public: uint16_t getPIR() const { return PIR; }; void setPIR(const uint16_t v) { PIR = v; } - uint16_t read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); - uint16_t read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only); + uint16_t read_par(const uint32_t a, const int run_mode); + uint16_t read_pdr(const uint32_t a, const int run_mode); void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); void write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode); + + uint8_t readByte(const uint16_t addr) override; + uint16_t readWord(const uint16_t addr) override; + + void writeByte(const uint16_t addr, const uint8_t v) override; + void writeWord(const uint16_t addr, uint16_t v) override; };