openMSX
RomAscii16X.cc
Go to the documentation of this file.
1// ASCII-X 16kB cartridges
2//
3// Banks:
4// first 16kB: 0x4000 - 0x7FFF and 0xC000 - 0xFFFF
5// second 16kB: 0x8000 - 0xBFFF and 0x0000 - 0x3FFF
6//
7// Address to change banks:
8// first 16kB: 0x6000 - 0x6FFF, 0xA000 - 0xAFFF, 0xE000 - 0xEFFF, 0x2000 - 0x2FFF
9// second 16kB: 0x7000 - 0x7FFF, 0xB000 - 0xBFFF, 0xF000 - 0xFFFF, 0x3000 - 0x3FFF
10//
11// 12-bit bank number is composed by address bits 8-11 and the data bits.
12//
13// Backed by FlashROM.
14
15#include "RomAscii16X.hh"
16#include "narrow.hh"
17#include "outer.hh"
18#include "serialize.hh"
19
20namespace openmsx {
21
23 : MSXRom(config, std::move(rom_))
24 , debuggable(getMotherBoard(), getName())
25 , flash(rom, AmdFlashChip::S29GL064S70TFI040, {}, config)
26{
27}
28
29void RomAscii16X::reset(EmuTime::param /* time */)
30{
31 ranges::iota(bankRegs, word(0));
32
33 flash.reset();
34
35 invalidateDeviceRCache(); // flush all to be sure
36}
37
38unsigned RomAscii16X::getFlashAddr(word addr) const
39{
40 word bank = bankRegs[((addr >> 14) & 1) ^ 1];
41 return (bank << 14) | (addr & 0x3FFF);
42}
43
44byte RomAscii16X::readMem(word addr, EmuTime::param /* time */)
45{
46 return flash.read(getFlashAddr(addr));
47}
48
49byte RomAscii16X::peekMem(word addr, EmuTime::param /* time */) const
50{
51 return flash.peek(getFlashAddr(addr));
52}
53
54const byte* RomAscii16X::getReadCacheLine(word addr) const
55{
56 return flash.getReadCacheLine(getFlashAddr(addr));
57}
58
59void RomAscii16X::writeMem(word addr, byte value, EmuTime::param /* time */)
60{
61 flash.write(getFlashAddr(addr), value);
62
63 if ((addr & 0x3FFF) >= 0x2000) {
64 const word index = (addr >> 12) & 1;
65 bankRegs[index] = (addr & 0x0F00) | value;
66 invalidateDeviceRCache(0x4000 ^ (index << 14), 0x4000);
67 invalidateDeviceRCache(0xC000 ^ (index << 14), 0x4000);
68 }
69}
70
72{
73 return nullptr; // not cacheable
74}
75
77 const std::string& name_)
78 : SimpleDebuggable(motherBoard_, name_ + " regs", "ASCII16-X bank registers", 4)
79{
80}
81
82byte RomAscii16X::Debuggable::read(unsigned address)
83{
84 auto& outer = OUTER(RomAscii16X, debuggable);
85 word bank = outer.bankRegs[(address >> 1) & 1];
86 return narrow<byte>(address & 1 ? bank >> 8 : bank & 0xFF);
87}
88
89void RomAscii16X::Debuggable::write(unsigned address, byte value,
90 EmuTime::param /* time */)
91{
92 auto& outer = OUTER(RomAscii16X, debuggable);
93 word& bank = outer.bankRegs[(address >> 1) & 1];
94 if (address & 1) {
95 bank = (bank & 0x00FF) | narrow<word>((value << 8) & 0x0F00);
96 } else {
97 bank = (bank & 0x0F00) | value;
98 }
99
100 outer.invalidateDeviceRCache();
101}
102
103template<typename Archive>
104void RomAscii16X::serialize(Archive& ar, unsigned /*version*/)
105{
106 // skip MSXRom base class
107 ar.template serializeBase<MSXDevice>(*this);
108
109 ar.serialize("flash", flash,
110 "bankRegs", bankRegs);
111}
114
115} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
void write(size_t address, uint8_t value)
Definition AmdFlash.cc:456
const uint8_t * getReadCacheLine(size_t address) const
Definition AmdFlash.cc:444
uint8_t read(size_t address)
Definition AmdFlash.cc:432
uint8_t peek(size_t address) const
Definition AmdFlash.cc:186
void invalidateDeviceRCache()
Definition MSXDevice.hh:215
byte * getWriteCacheLine(word address) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
RomAscii16X(const DeviceConfig &config, Rom &&rom)
void reset(EmuTime::param time) override
This method is called on reset.
void serialize(Archive &ar, unsigned version)
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
constexpr void iota(ForwardIt first, ForwardIt last, T value)
Definition ranges.hh:322
STL namespace.
#define OUTER(type, member)
Definition outer.hh:42
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)