openMSX
CanonWordProcessor.cc
Go to the documentation of this file.
1// EC701 - Japanese Word Processor Unit (Konami)
2// Reverse engineered by Albert Beevendorp.
3// Probably identical to Canon VWU-100.
4//
5// Select register in range 0xbff8-0xbfff (0xbfff used by software).
6// This select the memory visible in area 0x4000-0x7fff.
7// The value written here is inverted, then:
8// bit 5-3 = chip select:
9// 000: program ROM (lower 16 kB)
10// 100: dictionary ROM 0-128 kB
11// 101: dictionary ROM 128-256 kB
12// 110: dictionary ROM 256-384 kB
13// others: not mapped (reads as 0xc0)
14// bit 2-0 = block select within dictionary ROM
15//
16// Area 0x8000-0xbff7 reads from program ROM (upper 16 kB)
17//
18// Also check the electrical schema on:
19// http://d4.princess.ne.jp/msx/other/ec700/index.htm
20
21#include "CanonWordProcessor.hh"
22#include "MSXException.hh"
23#include "CacheLine.hh"
24#include "serialize.hh"
25
26namespace openmsx {
27
29 : MSXDevice(config)
30 , programRom (strCat(config.getAttributeValue("id"), "_program"), "rom", config, "program")
31 , dictionaryRom(strCat(config.getAttributeValue("id"), "_dictionary"), "rom", config, "dictionary")
32{
33 if (programRom.size() != 32*1024) {
34 throw MSXException("Program ROM must be 32kB.");
35 }
36 if (dictionaryRom.size() != 3*128*1024) {
37 throw MSXException("Dictionary ROM must be 3x 128kB.");
38 }
39 reset(EmuTime::dummy());
40}
41
42void CanonWordProcessor::reset(EmuTime::param time)
43{
44 writeMem(0xbfff, 0xff, time);
45}
46
47byte CanonWordProcessor::readMem(word address, EmuTime::param time)
48{
49 return peekMem(address, time);
50}
51
52byte CanonWordProcessor::peekMem(word address, EmuTime::param /*time*/) const
53{
54 if ((0xbff8 <= address) && (address <= 0xbfff)) {
55 return 0xc0; // select area, does NOT read from ROM
56 } else {
57 if (const auto* a = readHelper(address)) {
58 return *a;
59 }
60 return 0xc0;
61 }
62}
63
65{
66 if ((start & CacheLine::HIGH) == (0xbfff & CacheLine::HIGH)) {
67 return nullptr; // select register
68 } else {
69 return readHelper(start);
70 }
71}
72
73const byte* CanonWordProcessor::readHelper(word address) const
74{
75 if ((0x4000 <= address) && (address <= 0x7fff)) {
76 auto chip = (select & 0b00'111'000) >> 3;
77 auto bank = (select & 0b00'011'111);
78 address &= 0x3fff;
79 switch (chip) {
80 case 0b000:
81 return &programRom[address];
82 case 0b100: case 0b101: case 0b110:
83 return &dictionaryRom[0x4000 * bank + address];
84 // note: according to the schematic on
85 // http://d4.princess.ne.jp/msx/other/ec700/index.htm, the
86 // outputs of IC5's 3-to-8 decoder for '001' '010' '011' and
87 // '111' are unconnected
88 }
89 return nullptr; // unmapped, but reads as 0xc0 instead of 0xff ??
90 } else {
91 // 0x8000 - 0xbfff
92 return &programRom[0x4000 + (address & 0x3fff)];
93 }
94}
95
96void CanonWordProcessor::writeMem(word address, byte value, EmuTime::param /*time*/)
97{
98 if ((0xbff8 <= address) && (address <= 0xbfff)) {
99 select = ~value; // invert !!
100 invalidateDeviceRCache(0x4000, 0x4000);
101 }
102}
103
105{
106 return nullptr;
107}
108
109template<typename Archive>
110void CanonWordProcessor::serialize(Archive& ar, unsigned /*version*/)
111{
112 ar.template serializeBase<MSXDevice>(*this);
113 ar.serialize("select", select);
114}
117
118} // namespace openmsx
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.
byte * getWriteCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
CanonWordProcessor(const DeviceConfig &config)
void reset(EmuTime::param time) override
This method is called on reset.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
void serialize(Archive &ar, unsigned version)
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
const byte * getReadCacheLine(word start) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition: MSXDevice.hh:34
void invalidateDeviceRCache()
Definition: MSXDevice.hh:211
auto size() const
Definition: Rom.hh:36
constexpr unsigned HIGH
Definition: CacheLine.hh:10
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021
std::string strCat(Ts &&...ts)
Definition: strCat.hh:542