openMSX
MSXKanji.cc
Go to the documentation of this file.
1#include "MSXKanji.hh"
2#include "MSXException.hh"
3#include "TclObject.hh"
4#include "one_of.hh"
5#include "serialize.hh"
6
7namespace openmsx {
8
10 : MSXDevice(config)
11 , rom(getName(), "Kanji ROM", config)
12 , isLascom(config.getChildData("type", {}) == "lascom")
13 , highAddressMask(config.getChildData("type", {}) == "hangul" ? 0x7F : 0x3F)
14{
15 auto size = rom.size();
16 if (size != one_of(0x20000u, 0x40000u)) {
17 throw MSXException("MSXKanji: wrong kanji ROM, it should be either 128kB or 256kB.");
18 }
19 if ((highAddressMask == 0x7F) && (size != 0x40000)) {
20 throw MSXException("MSXKanji: for hangul type, the font ROM must be 256kB.");
21 }
22
23 reset(EmuTime::dummy());
24}
25
26void MSXKanji::reset(EmuTime::param /*time*/)
27{
28 adr1 = 0x00000; // TODO check this
29 adr2 = 0x20000; // TODO check this
30}
31
32void MSXKanji::writeIO(word port, byte value, EmuTime::param /*time*/)
33{
34 switch (port & 0x03) {
35 case 0:
36 adr1 = (adr1 & 0x1f800) | ((value & 0x3f) << 5);
37 break;
38 case 1:
39 adr1 = (adr1 & 0x007e0) | ((value & highAddressMask) << 11);
40 break;
41 case 2:
42 adr2 = (adr2 & 0x3f800) | ((value & 0x3f) << 5);
43 break;
44 case 3:
45 adr2 = (adr2 & 0x207e0) | ((value & 0x3f) << 11);
46 break;
47 }
48}
49
50byte MSXKanji::readIO(word port, EmuTime::param time)
51{
52 byte result = peekIO(port, time);
53 switch (port & 0x03) {
54 case 0:
55 if (!isLascom) {
56 break;
57 }
58 [[fallthrough]];
59 case 1:
60 adr1 = (adr1 & ~0x1f) | ((adr1 + 1) & 0x1f);
61 break;
62 case 3:
63 adr2 = (adr2 & ~0x1f) | ((adr2 + 1) & 0x1f);
64 break;
65 }
66 return result;
67}
68
69byte MSXKanji::peekIO(word port, EmuTime::param /*time*/) const
70{
71 byte result = 0xff;
72 switch (port & 0x03) {
73 case 0:
74 if (!isLascom) {
75 break;
76 }
77 [[fallthrough]];
78 case 1:
79 result = rom[adr1 & (rom.size() - 1)]; // mask to be safe
80 break;
81 case 3:
82 if (rom.size() == 0x40000) { // temp workaround
83 result = rom[adr2];
84 }
85 break;
86 }
87 return result;
88}
89
91{
92 rom.getInfo(result);
93}
94
95template<typename Archive>
96void MSXKanji::serialize(Archive& ar, unsigned /*version*/)
97{
98 ar.template serializeBase<MSXDevice>(*this);
99 ar.serialize("adr1", adr1,
100 "adr2", adr2);
101}
104
105/*
106This really works!
107
10810 DIM A(32)
10920 FOR I=0 TO 4095
11030 OUT &HD8, I MOD 64: OUT &HD9, I\64
11140 FOR J=0 TO 31: A(J)=INP(&HD9): NEXT
11250 FOR J=0 TO 7
11360 PRINT RIGHT$("0000000"+BIN$(A(J)), 8);
11470 PRINT RIGHT$("0000000"+BIN$(A(J+8)), 8)
11580 NEXT
11690 FOR J=16 TO 23
117100 PRINT RIGHT$("0000000"+BIN$(A(J)), 8);
118110 PRINT RIGHT$("0000000"+BIN$(A(J+8)), 8)
119120 NEXT
120130 PRINT
121140 NEXT
122*/
123
124} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
Definition MSXDevice.hh:36
void reset(EmuTime::param time) override
This method is called on reset.
Definition MSXKanji.cc:26
void getExtraDeviceInfo(TclObject &result) const override
Definition MSXKanji.cc:90
void serialize(Archive &ar, unsigned version)
Definition MSXKanji.cc:96
MSXKanji(const DeviceConfig &config)
Definition MSXKanji.cc:9
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
Definition MSXKanji.cc:69
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
Definition MSXKanji.cc:50
void writeIO(word port, byte value, EmuTime::param time) override
Write a byte to a given IO port at a certain time to this device.
Definition MSXKanji.cc:32
void getInfo(TclObject &result) const
Add dict values with info to result.
Definition Rom.cc:382
auto size() const
Definition Rom.hh:36
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)