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 
26 namespace 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.getSize() != 32*1024) {
34  throw MSXException("Program ROM must be 32kB.");
35  }
36  if (dictionaryRom.getSize() != 3*128*1024) {
37  throw MSXException("Dictionary ROM must be 3x 128kB.");
38  }
39  reset(EmuTime::dummy());
40 }
41 
42 void CanonWordProcessor::reset(EmuTime::param time)
43 {
44  writeMem(0xbfff, 0xff, time);
45 }
46 
47 byte CanonWordProcessor::readMem(word address, EmuTime::param time)
48 {
49  return peekMem(address, time);
50 }
51 
52 byte 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 
73 const 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 
96 void 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 
109 template<typename Archive>
110 void CanonWordProcessor::serialize(Archive& ar, unsigned /*version*/)
111 {
112  ar.template serializeBase<MSXDevice>(*this);
113  ar.serialize("select", select);
114 }
116 REGISTER_MSXDEVICE(CanonWordProcessor, "CanonWordProcessor");
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:33
void invalidateDeviceRCache()
Definition: MSXDevice.hh:210
unsigned getSize() const
Definition: Rom.hh:34
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:1009
std::string strCat(Ts &&...ts)
Definition: strCat.hh:549