OXYGENHUB
◆ main openmsx / src / MSXToshibaTcx200x.cc
3.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "MSXToshibaTcx200x.hh"
2
3
#include "CacheLine.hh"
4
#include "serialize.hh"
5
6
namespace openmsx {
7
8
// 7FFF is mapper control register
9
//
10
// x11xxxxx select SRAM in page 2 (8000H-87FFH, or perhaps mirrored in page 2), R/W
11
// x00xxxxx select ROM in page 2, R/W
12
// xxxxxx00 select ROM segment 0 in page 2 (screen copy, japanese word processor), R/W
13
// xxxxxx01 select ROM segment 1 in page 2 (japanese word processor), R/W
14
// xxxxxx10 select ROM segment 2 in page 2 (european word processor), R/W
15
// xxxxxx11 select ROM segment 3 in page 2 (japanese word processor), R/W
16
// kxxxxxxx COPY key, 0 is pressed (R)
17
18
// b6,b5 = SRAM select. Only pattern 00 and 11 are used, not sure what pattern 01 and 10 do
19
// Assumption that SRAM is only visible in page 2, because the ROM segment
20
// select is also for page 2 only
21
22
MSXToshibaTcx200x::MSXToshibaTcx200x(DeviceConfig& config)
23
	: MSXDevice(config)
24
	, rs232Rom(getName() + " RS232C ROM", "rom", config, "rs232")
25
	, wordProcessorRom(getName() + " Word Processor ROM", "rom", config, "wordpro")
26
	, sram(getName() + " SRAM", 0x800, config)
27
	, copyButtonPressed(getCommandController(), "copy_button_pressed",
28
                "pressed status of the COPY button", false)
29
{
30
	reset(EmuTime::dummy());
31
}
32
33
void MSXToshibaTcx200x::reset(EmuTime time)
34
{
35
	copyButtonPressed.setBoolean(false);
36
	writeMem(0x7FFF, 0, time);
37
}
38
39
bool MSXToshibaTcx200x::sramEnabled() const
40
{
41
	return (controlReg & 0b0110'0000) == 0b0110'0000;
42
	// note: we don't know what the hardware does if only one bit is on 1
43
}
44
45
byte MSXToshibaTcx200x::getSelectedSegment() const
46
{
47
	return controlReg & 0b0000'0011;
48
}
49
50
byte MSXToshibaTcx200x::peekMem(uint16_t address, EmuTime /*time*/) const
51
{
52
	if (address == 0x7FFF) {
53
		return byte(controlReg | ((copyButtonPressed.getBoolean() ? 0 : 1) << 7));
54
	} else if ((0x4000 <= address) && (address < 0x7FFF)) {
55
		return rs232Rom[address - 0x4000];
56
	} else if ((0x8000 <= address) && (address < 0xC000)) {
57
		if (sramEnabled()) {
58
			// TODO: assuming SRAM mirrors all over page 2. Not verified!
59
			return sram[address & (sram.size() - 1)];
60
		} else {
61
			return wordProcessorRom[(address - 0x8000) + getSelectedSegment() * 0x4000];
62
		}
63
	} else {
64
		return 0xFF;
65
	}
66
}
67
68
byte MSXToshibaTcx200x::readMem(uint16_t address, EmuTime time)
69
{
70
	return peekMem(address, time);
71
}
72
73
void MSXToshibaTcx200x::writeMem(uint16_t address, byte value, EmuTime /*time*/)
74
{
75
	if (address == 0x7FFF) {
76
		controlReg = value & 0b0110'0011; // TODO which bits can be read back?
77
		invalidateDeviceRWCache(0x8000, 0x4000);
78
	} else if ((0x8000 <= address) && (address < 0xC000) && sramEnabled()) {
79
		sram.write(address & (sram.size() - 1), value);
80
	}
81
}
82
83
const byte* MSXToshibaTcx200x::getReadCacheLine(uint16_t start) const
84
{
85
	if ((start & CacheLine::HIGH) == (0x7FFF & CacheLine::HIGH)) {
86
		return nullptr;
87
	} else if ((0x4000 <= start) && (start < 0x7FFF)) {
88
		return &rs232Rom[start - 0x4000];
89
	} else if ((0x8000 <= start) && (start < 0xC000)) {
90
		if (sramEnabled()) {
91
			return &sram[start & (sram.size() - 1)];
92
		} else {
93
			return &wordProcessorRom[(start - 0x8000) + getSelectedSegment() * 0x4000];
94
		}
95
	}
96
	return unmappedRead.data();
97
}
98
99
byte* MSXToshibaTcx200x::getWriteCacheLine(uint16_t start)
100
{
101
	if ((start & CacheLine::HIGH) == (0x7FFF & CacheLine::HIGH)) {
102
		return nullptr;
103
	} else if ((0x8000 <= start) && (start < 0xC000) && sramEnabled()) {
104
		return nullptr;
105
	} else {
106
		return unmappedWrite.data();
107
	}
108
}
109
110
template<typename Archive>
111
void MSXToshibaTcx200x::serialize(Archive& ar, unsigned /*version*/)
112
{
113
	ar.template serializeBase<MSXDevice>(*this);
114
	ar.serialize("sram", sram,
115
	             "controlReg", controlReg);
116
}
117
INSTANTIATE_SERIALIZE_METHODS(MSXToshibaTcx200x);
118
REGISTER_MSXDEVICE(MSXToshibaTcx200x, "ToshibaTcx200x");
119
120
} // namespace openmsx