Attempt further to discern MO6 meaning.

This commit is contained in:
Thomas Harte committed 2026-04-09 10:12:01 -04:00
1 parent d2090c5b8d
commit fe07d8c3b7
1 file changed
+55 -11
+55 -11
View File
@@ -19,6 +19,20 @@
namespace Thomson::MO5 {
//
// Notes on the layout of the standard MO ROM images:
//
// The MO5 images are 16kb in total, representing what should go into the
// final 16kb of the memory map.
//
// The MO6 images are 64kb in total:
//
// * the first 12kb is the BASIC 1 portion;
// * the next 12 kb is <something>, possibly the GUI?
// * what is possibly a 4kb gap then follows — it's less than 300 bytes of content, then filler — though it ends in C000 which could be a vector?;
// * there are then probably two meaningful pages of a full 16kb each (the first of which is definitely to do with BASIC 128, presumably the second also); and
// * the final 4kb is the monitor, which resides permanently at $f000–;
template <bool is_mo6>
struct MemoryMap {
public:
@@ -50,9 +64,12 @@ public:
}
void set_cartridge(const std::vector<uint8_t> &cartridge) {
cartridge_ = cartridge;
if constexpr (!is_mo6) {
set_rom(cartridge.begin(), cartridge.end());
cartridge_is_paged_ = true;
rom_.clear();
}
update_commutable_rom();
}
void set_floppy_rom(const std::vector<uint8_t> &rom) {
@@ -109,17 +126,33 @@ private:
const uint8_t *read_[0x10]{};
void update_commutable_rom() {
// TODO: this should be pageable.
// Commutable ROM: 0xb000 to 0xf000; if it's smaller than that then
// align it to end at 0xf000.
const size_t start = 0xf - (rom_.size() >> 12);
for(size_t c = 0xb; c < 0xf; c++) {
if(c >= start) {
set_read(c, rom_.data() + ((c - start) << 12));
} else {
set_read(c, nullptr);
const auto set_range = [&](const size_t start, const size_t length, const uint8_t *source) {
for(size_t c = 0x0; c < length; c++) {
set_read(c + start, source + (c << 12));
}
};
if(cartridge_is_paged_) {
// TODO: there's some sort of paging here, too.
set_range(0xb, 0x4, cartridge_.data());
return;
}
switch(paged_rom_) {
case PagedROM::FirstBank12kb:
set_read(0xb, nullptr);
set_range(0xc, 0x3, rom_.data());
break;
case PagedROM::SecondBank12kb:
set_read(0xb, nullptr);
set_range(0xc, 0x3, rom_.data() + 12*1024);
break;
case PagedROM::ThirdBank16kb:
set_range(0xb, 0x4, rom_.data() + 28*1024);
break;
case PagedROM::FourthBank16kb:
set_range(0xb, 0x4, rom_.data() + 44*1024);
break;
}
}
@@ -136,6 +169,17 @@ private:
std::array<uint8_t, 0x7c0> floppy_rom_;
std::array<uint8_t, 0x1000> monitor_;
std::vector<uint8_t> rom_;
std::vector<uint8_t> cartridge_;
// TODO: the following are entirely invented by me. Probably will need adjusting to
// whatever the hardware registers model, if I ever figure it out.
enum class PagedROM {
FirstBank12kb = 0,
SecondBank12kb = 1,
ThirdBank16kb = 2,
FourthBank16kb = 3,
} paged_rom_ = is_mo6 ? PagedROM::SecondBank12kb : PagedROM::FirstBank12kb;
bool cartridge_is_paged_ = false;
};
}