DC11 framework
This commit is contained in:
parent
ae0672da11
commit
c656e3609e
5 changed files with 132 additions and 19 deletions
|
@ -29,6 +29,7 @@ add_executable(
|
||||||
console_ncurses.cpp
|
console_ncurses.cpp
|
||||||
console_posix.cpp
|
console_posix.cpp
|
||||||
cpu.cpp
|
cpu.cpp
|
||||||
|
dc11.cpp
|
||||||
debugger.cpp
|
debugger.cpp
|
||||||
disk_backend.cpp
|
disk_backend.cpp
|
||||||
disk_backend_file.cpp
|
disk_backend_file.cpp
|
||||||
|
|
37
bus.cpp
37
bus.cpp
|
@ -8,6 +8,7 @@
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "gen.h"
|
#include "gen.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "dc11.h"
|
||||||
#include "kw11-l.h"
|
#include "kw11-l.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
@ -41,6 +42,7 @@ bus::~bus()
|
||||||
delete tty_;
|
delete tty_;
|
||||||
delete mmu_;
|
delete mmu_;
|
||||||
delete m;
|
delete m;
|
||||||
|
delete dc11_;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_POSIX
|
#if IS_POSIX
|
||||||
|
@ -69,7 +71,7 @@ json_t *bus::serialize() const
|
||||||
if (rk05_)
|
if (rk05_)
|
||||||
json_object_set(j_out, "rk05", rk05_->serialize());
|
json_object_set(j_out, "rk05", rk05_->serialize());
|
||||||
|
|
||||||
// TODO: tm11
|
// TODO: tm11, dc11
|
||||||
|
|
||||||
return j_out;
|
return j_out;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +124,7 @@ bus *bus::deserialize(const json_t *const j, console *const cnsl, std::atomic_ui
|
||||||
b->add_rk05(rk05_);
|
b->add_rk05(rk05_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: tm11
|
// TODO: tm11, dc11
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -156,6 +158,8 @@ void bus::reset()
|
||||||
tty_->reset();
|
tty_->reset();
|
||||||
if (kw11_l_)
|
if (kw11_l_)
|
||||||
kw11_l_->reset();
|
kw11_l_->reset();
|
||||||
|
if (dc11_)
|
||||||
|
dc11_->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus::add_KW11_L(kw11_l *const kw11_l_)
|
void bus::add_KW11_L(kw11_l *const kw11_l_)
|
||||||
|
@ -206,6 +210,12 @@ void bus::add_tty(tty *const tty_)
|
||||||
this->tty_ = tty_;
|
this->tty_ = tty_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bus::add_DC11(dc11 *const dc11_)
|
||||||
|
{
|
||||||
|
delete this->dc11_;
|
||||||
|
this->dc11_ = dc11_;
|
||||||
|
}
|
||||||
|
|
||||||
void bus::init()
|
void bus::init()
|
||||||
{
|
{
|
||||||
mmu_->setMMR0(0);
|
mmu_->setMMR0(0);
|
||||||
|
@ -457,29 +467,20 @@ uint16_t bus::read(const uint16_t addr_in, const word_mode_t word_mode, const rm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tm11 && a >= TM_11_BASE && a < TM_11_END && !peek_only) {
|
if (tm11 && a >= TM_11_BASE && a < TM_11_END && !peek_only)
|
||||||
DOLOG(debug, false, "READ-I/O TM11 register %d", (a - TM_11_BASE) / 2);
|
|
||||||
|
|
||||||
return word_mode == wm_byte ? tm11->readByte(a) : tm11->readWord(a);
|
return word_mode == wm_byte ? tm11->readByte(a) : tm11->readWord(a);
|
||||||
}
|
|
||||||
|
|
||||||
if (rk05_ && a >= RK05_BASE && a < RK05_END && !peek_only) {
|
|
||||||
DOLOG(debug, false, "READ-I/O RK05 register %d", (a - RK05_BASE) / 2);
|
|
||||||
|
|
||||||
|
if (rk05_ && a >= RK05_BASE && a < RK05_END && !peek_only)
|
||||||
return word_mode == wm_byte ? rk05_->readByte(a) : rk05_->readWord(a);
|
return word_mode == wm_byte ? rk05_->readByte(a) : rk05_->readWord(a);
|
||||||
}
|
|
||||||
|
|
||||||
if (rl02_ && a >= RL02_BASE && a < RL02_END && !peek_only) {
|
|
||||||
DOLOG(debug, false, "READ-I/O RL02 register %d", (a - RL02_BASE) / 2);
|
|
||||||
|
|
||||||
|
if (rl02_ && a >= RL02_BASE && a < RL02_END && !peek_only)
|
||||||
return word_mode == wm_byte ? rl02_->readByte(a) : rl02_->readWord(a);
|
return word_mode == wm_byte ? rl02_->readByte(a) : rl02_->readWord(a);
|
||||||
}
|
|
||||||
|
|
||||||
if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END && !peek_only) {
|
|
||||||
DOLOG(debug, false, "READ-I/O TTY register %d", (a - PDP11TTY_BASE) / 2);
|
|
||||||
|
|
||||||
|
if (tty_ && a >= PDP11TTY_BASE && a < PDP11TTY_END && !peek_only)
|
||||||
return word_mode == wm_byte ? tty_->readByte(a) : tty_->readWord(a);
|
return word_mode == wm_byte ? tty_->readByte(a) : tty_->readWord(a);
|
||||||
}
|
|
||||||
|
if (dc11_ && a >= DC11_BASE && a < DC11_END && !peek_only)
|
||||||
|
return word_mode == wm_byte ? dc11_->read_byte(a) : dc11_->read_word(a);
|
||||||
|
|
||||||
// LO size register field must be all 1s, so subtract 1
|
// LO size register field must be all 1s, so subtract 1
|
||||||
uint32_t system_size = m->get_memory_size() / 64 - 1;
|
uint32_t system_size = m->get_memory_size() / 64 - 1;
|
||||||
|
|
4
bus.h
4
bus.h
|
@ -9,6 +9,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "gen.h"
|
#include "gen.h"
|
||||||
|
#include "dc11.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "rk05.h"
|
#include "rk05.h"
|
||||||
#include "rl02.h"
|
#include "rl02.h"
|
||||||
|
@ -77,6 +78,7 @@ private:
|
||||||
kw11_l *kw11_l_ { nullptr };
|
kw11_l *kw11_l_ { nullptr };
|
||||||
mmu *mmu_ { nullptr };
|
mmu *mmu_ { nullptr };
|
||||||
memory *m { nullptr };
|
memory *m { nullptr };
|
||||||
|
dc11 *dc11_ { nullptr };
|
||||||
|
|
||||||
uint16_t microprogram_break_register { 0 };
|
uint16_t microprogram_break_register { 0 };
|
||||||
|
|
||||||
|
@ -113,6 +115,7 @@ public:
|
||||||
void add_rl02 (rl02 *const rl02_ );
|
void add_rl02 (rl02 *const rl02_ );
|
||||||
void add_tty (tty *const tty_ );
|
void add_tty (tty *const tty_ );
|
||||||
void add_KW11_L(kw11_l *const kw11_l_);
|
void add_KW11_L(kw11_l *const kw11_l_);
|
||||||
|
void add_DC11 (dc11 *const dc11_ );
|
||||||
|
|
||||||
memory *getRAM() { return m; }
|
memory *getRAM() { return m; }
|
||||||
cpu *getCpu() { return c; }
|
cpu *getCpu() { return c; }
|
||||||
|
@ -121,6 +124,7 @@ public:
|
||||||
mmu *getMMU() { return mmu_; }
|
mmu *getMMU() { return mmu_; }
|
||||||
rk05 *getRK05() { return rk05_; }
|
rk05 *getRK05() { return rk05_; }
|
||||||
rl02 *getRL02() { return rl02_; }
|
rl02 *getRL02() { return rl02_; }
|
||||||
|
dc11 *getDC11() { return dc11_; }
|
||||||
|
|
||||||
uint16_t read (const uint16_t a, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only=false, const d_i_space_t s = i_space);
|
uint16_t read (const uint16_t a, const word_mode_t word_mode, const rm_selection_t mode_selection, const bool peek_only=false, const d_i_space_t s = i_space);
|
||||||
uint16_t readByte(const uint16_t a) { return read(a, wm_byte, rm_cur); }
|
uint16_t readByte(const uint16_t a) { return read(a, wm_byte, rm_cur); }
|
||||||
|
|
65
dc11.cpp
Normal file
65
dc11.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// (C) 2024 by Folkert van Heusden
|
||||||
|
// Released under MIT license
|
||||||
|
|
||||||
|
#include "bus.h"
|
||||||
|
#include "dc11.h"
|
||||||
|
|
||||||
|
|
||||||
|
dc11::dc11(bus *const b): b(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
dc11::~dc11()
|
||||||
|
{
|
||||||
|
stop_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dc11::reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t dc11::read_byte(const uint16_t addr)
|
||||||
|
{
|
||||||
|
uint16_t v = read_word(addr & ~1);
|
||||||
|
|
||||||
|
if (addr & 1)
|
||||||
|
return v >> 8;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t dc11::read_word(const uint16_t addr)
|
||||||
|
{
|
||||||
|
const int reg = (addr - DC11_BASE) / 2;
|
||||||
|
|
||||||
|
uint16_t vtemp = registers[reg];
|
||||||
|
|
||||||
|
DOLOG(debug, false, "DC11: read register %06o (%d): %06o", addr, reg, vtemp);
|
||||||
|
|
||||||
|
return vtemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dc11::write_byte(const uint16_t addr, const uint8_t v)
|
||||||
|
{
|
||||||
|
uint16_t vtemp = registers[(addr - DC11_BASE) / 2];
|
||||||
|
|
||||||
|
if (addr & 1) {
|
||||||
|
vtemp &= ~0xff00;
|
||||||
|
vtemp |= v << 8;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vtemp &= ~0x00ff;
|
||||||
|
vtemp |= v;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_word(addr, vtemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dc11::write_word(const uint16_t addr, uint16_t v)
|
||||||
|
{
|
||||||
|
const int reg = (addr - DC11_BASE) / 2;
|
||||||
|
|
||||||
|
DOLOG(debug, false, "DC11: set register %06o (%d) to %o", addr, reg, v);
|
||||||
|
|
||||||
|
registers[reg] = v;
|
||||||
|
}
|
42
dc11.h
Normal file
42
dc11.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// (C) 2024 by Folkert van Heusden
|
||||||
|
// Released under MIT license
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "gen.h"
|
||||||
|
#include "bus.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#define DC11_RCSR 0174000 // receiver status register
|
||||||
|
#define DC11_BASE DC11_RCSR
|
||||||
|
#define DC11_END (DC11_RCSR + 2)
|
||||||
|
|
||||||
|
class bus;
|
||||||
|
|
||||||
|
class dc11
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bus *const b { nullptr };
|
||||||
|
|
||||||
|
uint16_t registers[4] { };
|
||||||
|
std::atomic_bool stop_flag { false };
|
||||||
|
|
||||||
|
public:
|
||||||
|
dc11(bus *const b);
|
||||||
|
virtual ~dc11();
|
||||||
|
|
||||||
|
#if IS_POSIX
|
||||||
|
// json_t *serialize();
|
||||||
|
// static tty *deserialize(const json_t *const j, bus *const b, console *const cnsl);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
uint8_t read_byte(const uint16_t addr);
|
||||||
|
uint16_t read_word(const uint16_t addr);
|
||||||
|
|
||||||
|
void write_byte(const uint16_t addr, const uint8_t v);
|
||||||
|
void write_word(const uint16_t addr, uint16_t v);
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue