Merge branch 'master' into dc11-serial

This commit is contained in:
folkert van heusden 2024-05-09 20:00:36 +02:00
commit 7ed8e46b56
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
26 changed files with 282 additions and 157 deletions

View file

@ -110,7 +110,7 @@ void console_esp32::panel_update_thread()
int run_mode = current_PSW >> 14; int run_mode = current_PSW >> 14;
uint16_t current_PC = c->getPC(); uint16_t current_PC = c->getPC();
uint32_t full_addr = b->calculate_physical_address(run_mode, current_PC, false, false, true, i_space); uint32_t full_addr = b->getMMU()->calculate_physical_address(c, run_mode, current_PC, false, false, true, i_space);
uint16_t current_instr = b->read_word(current_PC); uint16_t current_instr = b->read_word(current_PC);

View file

@ -44,6 +44,7 @@
#include "kw11-l.h" #include "kw11-l.h"
#include "loaders.h" #include "loaders.h"
#include "memory.h" #include "memory.h"
#include "tm-11.h"
#include "tty.h" #include "tty.h"
#include "utils.h" #include "utils.h"
#include "version.h" #include "version.h"
@ -364,6 +365,9 @@ void setup() {
tty_ = new tty(cnsl, b); tty_ = new tty(cnsl, b);
b->add_tty(tty_); b->add_tty(tty_);
Serial.println(F("* Adding TM-11"));
b->add_tm11(new tm_11(b));
Serial.println(F("* Starting KW11-L")); Serial.println(F("* Starting KW11-L"));
b->getKW11_L()->begin(cnsl); b->getKW11_L()->begin(cnsl);

View file

@ -65,3 +65,18 @@ lib_deps = greiman/SdFat@^2.1.2
build_flags = -std=gnu++17 -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_SPIRAM_USE_MALLOC build_flags = -std=gnu++17 -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_SPIRAM_USE_MALLOC
build_unflags = -std=gnu++11 build_unflags = -std=gnu++11
extra_scripts = pre:prepare.py extra_scripts = pre:prepare.py
[env:lolin_s2_mini]
platform = espressif32
board = lolin_s2_mini
build_src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<build> -<player.cpp> -<SHAdisplay/> -<console_shabadge.cpp>
framework = arduino
monitor_speed = 115200
upload_speed = 1000000
board_build.filesystem = littlefs
lib_deps = greiman/SdFat@^2.1.2
adafruit/Adafruit NeoPixel
bblanchon/ArduinoJson@^6.19.4
build_flags = -std=gnu++17 -DESP32=1 -ggdb3 -D_GLIBCXX_USE_C99 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue -DCONFIG_SPIRAM_USE_MALLOC
build_unflags = -std=gnu++11
extra_scripts = pre:prepare.py

1
RP2040/breakpoint.cpp Symbolic link
View file

@ -0,0 +1 @@
../breakpoint.cpp

1
RP2040/breakpoint.h Symbolic link
View file

@ -0,0 +1 @@
../breakpoint.h

1
RP2040/breakpoint_and.cpp Symbolic link
View file

@ -0,0 +1 @@
../breakpoint_and.cpp

1
RP2040/breakpoint_and.h Symbolic link
View file

@ -0,0 +1 @@
../breakpoint_and.h

View file

@ -0,0 +1 @@
../breakpoint_memory.cpp

1
RP2040/breakpoint_memory.h Symbolic link
View file

@ -0,0 +1 @@
../breakpoint_memory.h

1
RP2040/breakpoint_or.cpp Symbolic link
View file

@ -0,0 +1 @@
../breakpoint_or.cpp

1
RP2040/breakpoint_or.h Symbolic link
View file

@ -0,0 +1 @@
../breakpoint_or.h

View file

@ -0,0 +1 @@
../breakpoint_parser.cpp

1
RP2040/breakpoint_parser.h Symbolic link
View file

@ -0,0 +1 @@
../breakpoint_parser.h

View file

@ -0,0 +1 @@
../breakpoint_register.cpp

View file

@ -0,0 +1 @@
../breakpoint_register.h

1
RP2040/mmu.cpp Symbolic link
View file

@ -0,0 +1 @@
../mmu.cpp

1
RP2040/mmu.h Symbolic link
View file

@ -0,0 +1 @@
../mmu.h

18
cpu.cpp
View file

@ -18,6 +18,12 @@
#define IS_0(x, wm) ((wm) == wm_byte ? ((x) & 0xff) == 0 : (x) == 0) #define IS_0(x, wm) ((wm) == wm_byte ? ((x) & 0xff) == 0 : (x) == 0)
// see https://retrocomputing.stackexchange.com/questions/6960/what-was-the-clock-speed-and-ips-for-the-original-pdp-11
constexpr const double pdp11_clock_cycle = 150; // ns, for the 11/70
constexpr const double pdp11_MHz = 1000.0 / pdp11_clock_cycle;
constexpr const double pdp11_avg_cycles_per_instruction = (1 + 5) / 2.0;
constexpr const double pdp11_estimated_mips = pdp11_MHz / pdp11_avg_cycles_per_instruction;
cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event) cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event)
{ {
reset(); reset();
@ -97,15 +103,15 @@ std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(c
double mips = t_diff ? instr_count / double(t_diff) : 0; double mips = t_diff ? instr_count / double(t_diff) : 0;
// see https://retrocomputing.stackexchange.com/questions/6960/what-was-the-clock-speed-and-ips-for-the-original-pdp-11
constexpr double pdp11_clock_cycle = 150; // ns, for the 11/70
constexpr double pdp11_MHz = 1000.0 / pdp11_clock_cycle;
constexpr double pdp11_avg_cycles_per_instruction = (1 + 5) / 2.0;
constexpr double pdp11_estimated_mips = pdp11_MHz / pdp11_avg_cycles_per_instruction;
return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time }; return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time };
} }
uint32_t cpu::get_effective_run_time(const uint64_t instruction_count) const
{
// division is to go from ns to ms
return instruction_count * pdp11_avg_cycles_per_instruction * pdp11_clock_cycle / 1000000l;
}
void cpu::add_to_stack_trace(const uint16_t p) void cpu::add_to_stack_trace(const uint16_t p)
{ {
auto da = disassemble(p); auto da = disassemble(p);

2
cpu.h
View file

@ -133,6 +133,8 @@ public:
uint64_t get_instructions_executed_count() const; uint64_t get_instructions_executed_count() const;
uint64_t get_wait_time() const { return wait_time; } uint64_t get_wait_time() const { return wait_time; }
std::tuple<double, double, uint64_t, uint32_t, double> get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_1s) const; std::tuple<double, double, uint64_t, uint32_t, double> get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_1s) const;
// how many ms would've really passed when executing `instruction_count` instructions
uint32_t get_effective_run_time(const uint64_t instruction_count) const;
bool get_debug() const { return debug_mode; } bool get_debug() const { return debug_mode; }
void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); } void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); }

View file

@ -78,14 +78,57 @@ std::optional<disk_backend *> select_nbd_server(console *const cnsl)
} }
#endif #endif
std::optional<std::string> select_host_file(console *const c) void start_disk(console *const cnsl)
{ {
for(;;) { #if IS_POSIX
return;
#else
static bool disk_started = false;
if (disk_started)
return;
#if defined(ESP32)
cnsl->put_string_lf(format("MISO: %d", int(MISO)));
cnsl->put_string_lf(format("MOSI: %d", int(MOSI)));
cnsl->put_string_lf(format("SCK : %d", int(SCK )));
cnsl->put_string_lf(format("SS : %d", int(SS )));
#endif
#if defined(SHA2017)
if (SD.begin(21, SD_SCK_MHZ(10)))
disk_started = true;
else
SD.initErrorHalt();
#elif !defined(BUILD_FOR_RP2040)
if (SD.begin(SS, SD_SCK_MHZ(15)))
disk_started = true;
else {
auto err = SD.sdErrorCode();
if (err)
cnsl->put_string_lf(format("SDerror: 0x%x, data: 0x%x", err, SD.sdErrorData()));
else
cnsl->put_string_lf("Failed to initialize SD card");
}
#endif
#endif
}
void ls_l(console *const cnsl)
{
start_disk(cnsl);
#if IS_POSIX || defined(_WIN32)
cnsl->put_string_lf("Files in current directory: ");
#else
cnsl->put_string_lf("Files on SD-card:");
#endif
#if defined(linux) #if defined(linux)
DIR *dir = opendir("."); DIR *dir = opendir(".");
if (!dir) { if (!dir) {
c->put_string_lf("Cannot access directory"); cnsl->put_string_lf("Cannot access directory");
return { }; return;
} }
dirent *dr = nullptr; dirent *dr = nullptr;
@ -93,7 +136,7 @@ std::optional<std::string> select_host_file(console *const c)
struct stat st { }; struct stat st { };
if (stat(dr->d_name, &st) == 0) if (stat(dr->d_name, &st) == 0)
c->put_string_lf(format("%s\t\t%ld", dr->d_name, st.st_size)); cnsl->put_string_lf(format("%s\t\t%ld", dr->d_name, st.st_size));
} }
closedir(dir); closedir(dir);
@ -106,9 +149,9 @@ std::optional<std::string> select_host_file(console *const c)
break; break;
if (!entry.isDirectory()) { if (!entry.isDirectory()) {
c->put_string(entry.name()); cnsl->put_string(entry.name());
c->put_string("\t\t"); cnsl->put_string("\t\t");
c->put_string_lf(format("%ld", entry.size())); cnsl->put_string_lf(format("%ld", entry.size()));
} }
entry.close(); entry.close();
@ -117,16 +160,20 @@ std::optional<std::string> select_host_file(console *const c)
#else #else
SD.ls("/", LS_DATE | LS_SIZE | LS_R); SD.ls("/", LS_DATE | LS_SIZE | LS_R);
#endif #endif
}
c->flush_input(); std::optional<std::string> select_host_file(console *const cnsl)
{
for(;;) {
cnsl->flush_input();
std::string selected_file = c->read_line("Enter filename (or empty to abort): "); std::string selected_file = cnsl->read_line("Enter filename (or empty to abort): ");
if (selected_file.empty()) if (selected_file.empty())
return { }; return { };
c->put_string("Opening file: "); cnsl->put_string("Opening file: ");
c->put_string_lf(selected_file.c_str()); cnsl->put_string_lf(selected_file.c_str());
bool can_open_file = false; bool can_open_file = false;
@ -143,41 +190,19 @@ std::optional<std::string> select_host_file(console *const c)
if (can_open_file) if (can_open_file)
return selected_file; return selected_file;
c->put_string_lf("open failed"); cnsl->put_string_lf("open failed");
ls_l(cnsl);
} }
} }
// disk image files // disk image files
std::optional<disk_backend *> select_disk_file(console *const c) std::optional<disk_backend *> select_disk_file(console *const cnsl)
{ {
#if IS_POSIX || defined(_WIN32) start_disk(cnsl);
c->put_string_lf("Files in current directory: ");
#else
c->put_string_lf(format("MISO: %d", int(MISO)));
c->put_string_lf(format("MOSI: %d", int(MOSI)));
c->put_string_lf(format("SCK : %d", int(SCK )));
c->put_string_lf(format("SS : %d", int(SS )));
c->put_string_lf("Files on SD-card:");
#if defined(SHA2017)
if (!SD.begin(21, SD_SCK_MHZ(10)))
SD.initErrorHalt();
#elif !defined(BUILD_FOR_RP2040)
if (!SD.begin(SS, SD_SCK_MHZ(15))) {
auto err = SD.sdErrorCode();
if (err)
c->put_string_lf(format("SDerror: 0x%x, data: 0x%x", err, SD.sdErrorData()));
else
c->put_string_lf("Failed to initialize SD card");
return { };
}
#endif
#endif
for(;;) { for(;;) {
auto selected_file = select_host_file(c); auto selected_file = select_host_file(cnsl);
if (selected_file.has_value() == false) if (selected_file.has_value() == false)
break; break;
@ -189,8 +214,8 @@ std::optional<disk_backend *> select_disk_file(console *const c)
#endif #endif
if (!temp->begin(false)) { if (!temp->begin(false)) {
c->put_string("Cannot use: "); cnsl->put_string("Cannot use: ");
c->put_string_lf(selected_file.value().c_str()); cnsl->put_string_lf(selected_file.value().c_str());
delete temp; delete temp;
@ -987,6 +1012,19 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
continue; continue;
} }
else if (parts[0] == "bic" && parts.size() == 2) {
auto rc = load_tape(b, parts[1].c_str());
if (rc.has_value()) {
c->setPC(rc.value());
cnsl->put_string_lf("BIC/LDA file loaded");
}
else {
cnsl->put_string_lf("BIC/LDA failed to load");
}
continue;
}
else if (parts[0] == "lt") { else if (parts[0] == "lt") {
if (parts.size() == 2) if (parts.size() == 2)
tm11_load_tape(cnsl, b, parts[1]); tm11_load_tape(cnsl, b, parts[1]);
@ -995,6 +1033,11 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
continue; continue;
} }
else if (cmd == "dir" || cmd == "ls") {
ls_l(cnsl);
continue;
}
else if (cmd == "ult") { else if (cmd == "ult") {
tm11_unload_tape(b); tm11_unload_tape(b);
@ -1038,28 +1081,30 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
" follows v/p (virtual/physical), all octal values, mmr0-3 and psw are", " follows v/p (virtual/physical), all octal values, mmr0-3 and psw are",
" registers", " registers",
"trace/t - toggle tracing", "trace/t - toggle tracing",
"setll - set loglevel: terminal,file", "setll x,y - set loglevel: terminal,file",
"setsl - set syslog target: requires a hostname and a loglevel", "setsl x,y - set syslog target: requires a hostname and a loglevel",
"turbo - toggle turbo mode (cannot be interrupted)", "turbo - toggle turbo mode (cannot be interrupted)",
"debug - enable CPU debug mode", "debug - enable CPU debug mode",
"bt - show backtrace - need to enable debug first", "bt - show backtrace - need to enable debug first",
"strace - start tracing from address - invoke without address to disable", "strace x - start tracing from address - invoke without address to disable",
"trl - set trace run-level (0...3), empty for all", "trl x - set trace run-level (0...3), empty for all",
"regdump - dump register contents", "regdump - dump register contents",
"mmudump - dump MMU settings (PARs/PDRs)", "mmudump - dump MMU settings (PARs/PDRs)",
"mmures - resolve a virtual address", "mmures x - resolve a virtual address",
"qi - show queued interrupts", "qi - show queued interrupts",
"setpc - set PC to value", "setpc x - set PC to value",
"setmem - set memory (a=) to value (v=), both in octal, one byte", "setmem ... - set memory (a=) to value (v=), both in octal, one byte",
"toggle - set switch (s=, 0...15 (decimal)) of the front panel to state (t=, 0 or 1)", "toggle ... - set switch (s=, 0...15 (decimal)) of the front panel to state (t=, 0 or 1)",
"cls - clear screen", "cls - clear screen",
"lt - load tape (parameter is filename)", "dir - list files",
"bic x - run BIC/LDA file",
"lt x - load tape (parameter is filename)",
"ult - unload tape", "ult - unload tape",
"stats - show run statistics", "stats - show run statistics",
"ramsize - set ram size (page count (8 kB))", "ramsize x - set ram size (page count (8 kB), decimal)",
"bl - set bootload (rl02 or rk05)", "bl - set bootloader (rl02 or rk05)",
#if IS_POSIX #if IS_POSIX
"ser - serialize state to a file", "ser x - serialize state to a file",
// "dser - deserialize state from a file", // "dser - deserialize state from a file",
#endif #endif
"dp - disable panel", "dp - disable panel",
@ -1068,11 +1113,11 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
"startnet - start network", "startnet - start network",
"chknet - check network status", "chknet - check network status",
#if defined(CONSOLE_SERIAL_RX) #if defined(CONSOLE_SERIAL_RX)
"serspd - set serial speed in bps (8N1 are default)", "serspd x - set serial speed in bps (8N1 are default)",
#endif #endif
#endif #endif
"cfgdisk - configure disk", "cfgdisk - configure disk",
"log - log a message to the logfile", "log ... - log a message to the logfile",
nullptr nullptr
}; };

View file

@ -62,28 +62,40 @@ void kw11_l::reset()
lf_csr = 0; lf_csr = 0;
} }
void kw11_l::do_interrupt()
{
set_lf_crs_b7();
if (get_lf_crs() & 64)
b->getCpu()->queue_interrupt(6, 0100);
}
void kw11_l::operator()() void kw11_l::operator()()
{ {
set_thread_name("kek:kw-11l"); set_thread_name("kek:kw-11l");
TRACE("Starting KW11-L thread"); TRACE("Starting KW11-L thread");
uint64_t prev_cycle_count = b->getCpu()->get_instructions_executed_count();
uint64_t interval_prev_cycle_count = prev_cycle_count;
while(!stop_flag) { while(!stop_flag) {
if (*cnsl->get_running_flag()) { if (*cnsl->get_running_flag()) {
set_lf_crs_b7(); myusleep(1000000 / 100); // 100 Hz
if (get_lf_crs() & 64) uint64_t current_cycle_count = b->getCpu()->get_instructions_executed_count();
b->getCpu()->queue_interrupt(6, 0100); uint32_t took_ms = b->getCpu()->get_effective_run_time(current_cycle_count - prev_cycle_count);
// TODO: depending on cpu cycles processed if (took_ms >= 1000 / 50 || current_cycle_count - interval_prev_cycle_count == 0) {
#if defined(ESP32) do_interrupt();
myusleep(1000000 / 20); // 50ms
#else prev_cycle_count = current_cycle_count;
myusleep(1000000 / 50); // 20ms }
#endif
interval_prev_cycle_count = current_cycle_count;
} }
else { else {
myusleep(1000000 / 10); // 100ms myusleep(1000000 / 10); // 10 Hz
} }
} }

View file

@ -28,6 +28,8 @@ private:
uint8_t get_lf_crs(); uint8_t get_lf_crs();
void set_lf_crs_b7(); void set_lf_crs_b7();
void do_interrupt();
public: public:
kw11_l(bus *const b); kw11_l(bus *const b);
virtual ~kw11_l(); virtual ~kw11_l();

11
mmu.cpp
View file

@ -48,6 +48,11 @@ uint16_t mmu::read_par(const uint32_t a, const int run_mode)
return t; return t;
} }
void mmu::setMMR0_as_is(uint16_t value)
{
MMR0 = value;
}
void mmu::setMMR0(uint16_t value) void mmu::setMMR0(uint16_t value)
{ {
value &= ~(3 << 10); // bit 10 & 11 always read as 0 value &= ~(3 << 10); // bit 10 & 11 always read as 0
@ -350,7 +355,7 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const
temp |= d << 4; temp |= d << 4;
setMMR0(temp); setMMR0_as_is(temp);
TRACE("MMR0: %06o", temp); TRACE("MMR0: %06o", temp);
} }
@ -389,7 +394,7 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const
temp &= ~(3 << 5); temp &= ~(3 << 5);
temp |= run_mode << 5; temp |= run_mode << 5;
setMMR0(temp); setMMR0_as_is(temp);
} }
if (is_write) if (is_write)
@ -427,7 +432,7 @@ uint32_t mmu::calculate_physical_address(cpu *const c, const int run_mode, const
temp &= ~(1 << 4); temp &= ~(1 << 4);
temp |= d << 4; temp |= d << 4;
setMMR0(temp); setMMR0_as_is(temp);
} }
if (is_write) if (is_write)

1
mmu.h
View file

@ -99,6 +99,7 @@ public:
uint16_t getMMR3() const { return MMR3; } uint16_t getMMR3() const { return MMR3; }
uint16_t getMMR(int nr) const { const uint16_t *const mmrs[] { &MMR0, &MMR1, &MMR2, &MMR3 }; return *mmrs[nr]; } uint16_t getMMR(int nr) const { const uint16_t *const mmrs[] { &MMR0, &MMR1, &MMR2, &MMR3 }; return *mmrs[nr]; }
void setMMR0_as_is(uint16_t value);
void setMMR0(const uint16_t value); void setMMR0(const uint16_t value);
void setMMR1(const uint16_t value); void setMMR1(const uint16_t value);
void setMMR2(const uint16_t value); void setMMR2(const uint16_t value);

View file

@ -139,12 +139,18 @@ void rk05::write_word(const uint16_t addr, const uint16_t v)
if (func == 0) { // controller reset if (func == 0) { // controller reset
TRACE("RK05 invoke %d (controller reset)", func); TRACE("RK05 invoke %d (controller reset)", func);
registers[(RK05_ERROR - RK05_BASE) / 2] = 0;
} }
else if (func == 1) { // write else if (func == 1) { // write
*disk_write_acitivity = true; *disk_write_acitivity = true;
TRACE("RK05 drive %d position sec %d surf %d cyl %d, reclen %zo, WRITE to %o, mem: %o", device, sector, surface, cylinder, reclen, diskoffb, memoff); TRACE("RK05 drive %d position sec %d surf %d cyl %d, reclen %zo, WRITE to %o, mem: %o", device, sector, surface, cylinder, reclen, diskoffb, memoff);
if (device >= fhs.size()) {
registers[(RK05_ERROR - RK05_BASE) / 2] |= 128; // non existing disk
registers[(RK05_CS - RK05_BASE) / 2] |= 3 << 14; // an error occured
}
else {
uint32_t work_reclen = reclen; uint32_t work_reclen = reclen;
uint32_t work_memoff = memoff; uint32_t work_memoff = memoff;
uint32_t work_diskoffb = diskoffb; uint32_t work_diskoffb = diskoffb;
@ -158,8 +164,12 @@ void rk05::write_word(const uint16_t addr, const uint16_t v)
for(size_t i=0; i<cur; i++) for(size_t i=0; i<cur; i++)
xfer_buffer[i] = b->readUnibusByte(work_memoff++); xfer_buffer[i] = b->readUnibusByte(work_memoff++);
if (!fhs.at(device)->write(work_diskoffb, cur, xfer_buffer, 512)) if (!fhs.at(device)->write(work_diskoffb, cur, xfer_buffer, 512)) {
DOLOG(ll_error, true, "RK05(%d) write error %s to %u len %u", device, strerror(errno), work_diskoffb, cur); DOLOG(ll_error, true, "RK05(%d) write error %s to %u len %u", device, strerror(errno), work_diskoffb, cur);
registers[(RK05_ERROR - RK05_BASE) / 2] |= 32; // non existing sector
registers[(RK05_CS - RK05_BASE) / 2] |= 3 << 14; // an error occured
break;
}
work_diskoffb += cur; work_diskoffb += cur;
@ -178,6 +188,7 @@ void rk05::write_word(const uint16_t addr, const uint16_t v)
} }
registers[(RK05_DA - RK05_BASE) / 2] = sector | (surface << 4) | (cylinder << 5); registers[(RK05_DA - RK05_BASE) / 2] = sector | (surface << 4) | (cylinder << 5);
}
*disk_write_acitivity = false; *disk_write_acitivity = false;
} }
@ -186,6 +197,11 @@ void rk05::write_word(const uint16_t addr, const uint16_t v)
TRACE("RK05 drive %d position sec %d surf %d cyl %d, reclen %zo, READ from %o, mem: %o", device, sector, surface, cylinder, reclen, diskoffb, memoff); TRACE("RK05 drive %d position sec %d surf %d cyl %d, reclen %zo, READ from %o, mem: %o", device, sector, surface, cylinder, reclen, diskoffb, memoff);
if (device >= fhs.size()) {
registers[(RK05_ERROR - RK05_BASE) / 2] |= 128; // non existing disk
registers[(RK05_CS - RK05_BASE) / 2] |= 3 << 14; // an error occured
}
else {
uint32_t temp_diskoffb = diskoffb; uint32_t temp_diskoffb = diskoffb;
uint32_t temp_reclen = reclen; uint32_t temp_reclen = reclen;
@ -195,6 +211,8 @@ void rk05::write_word(const uint16_t addr, const uint16_t v)
if (!fhs.at(device)->read(temp_diskoffb, cur, xfer_buffer, 512)) { if (!fhs.at(device)->read(temp_diskoffb, cur, xfer_buffer, 512)) {
DOLOG(ll_error, true, "RK05 read error %s from %u len %u", strerror(errno), temp_diskoffb, cur); DOLOG(ll_error, true, "RK05 read error %s from %u len %u", strerror(errno), temp_diskoffb, cur);
registers[(RK05_ERROR - RK05_BASE) / 2] |= 32; // non existing sector
registers[(RK05_CS - RK05_BASE) / 2] |= 3 << 14; // an error occured
break; break;
} }
@ -220,6 +238,7 @@ void rk05::write_word(const uint16_t addr, const uint16_t v)
} }
registers[(RK05_DA - RK05_BASE) / 2] = sector | (surface << 4) | (cylinder << 5); registers[(RK05_DA - RK05_BASE) / 2] = sector | (surface << 4) | (cylinder << 5);
}
*disk_read_acitivity = false; *disk_read_acitivity = false;
} }

View file

@ -1,4 +1,4 @@
// (C) 2018-2023 by Folkert van Heusden // (C) 2018-2024 by Folkert van Heusden
// Released under MIT license // Released under MIT license
#include <errno.h> #include <errno.h>