MSXKanji.cc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "MSXKanji.hh"
  2. #include "MSXException.hh"
  3. #include "serialize.hh"
  4. namespace openmsx {
  5. MSXKanji::MSXKanji(const DeviceConfig& config)
  6. : MSXDevice(config)
  7. , rom(getName(), "Kanji ROM", config)
  8. , isLascom(config.getChildData("type", {}) == "lascom")
  9. {
  10. int size = rom.getSize();
  11. if ((size != 0x20000) && (size != 0x40000)) {
  12. throw MSXException("MSXKanji: wrong kanji ROM, it should be either 128kB or 256kB.");
  13. }
  14. reset(EmuTime::dummy());
  15. }
  16. void MSXKanji::reset(EmuTime::param /*time*/)
  17. {
  18. adr1 = 0x00000; // TODO check this
  19. adr2 = 0x20000; // TODO check this
  20. }
  21. void MSXKanji::writeIO(word port, byte value, EmuTime::param /*time*/)
  22. {
  23. switch (port & 0x03) {
  24. case 0:
  25. adr1 = (adr1 & 0x1f800) | ((value & 0x3f) << 5);
  26. break;
  27. case 1:
  28. adr1 = (adr1 & 0x007e0) | ((value & 0x3f) << 11);
  29. break;
  30. case 2:
  31. adr2 = (adr2 & 0x3f800) | ((value & 0x3f) << 5);
  32. break;
  33. case 3:
  34. adr2 = (adr2 & 0x207e0) | ((value & 0x3f) << 11);
  35. break;
  36. }
  37. }
  38. byte MSXKanji::readIO(word port, EmuTime::param time)
  39. {
  40. byte result = peekIO(port, time);
  41. switch (port & 0x03) {
  42. case 0:
  43. if (!isLascom) {
  44. break;
  45. }
  46. // fall-through
  47. case 1:
  48. adr1 = (adr1 & ~0x1f) | ((adr1 + 1) & 0x1f);
  49. break;
  50. case 3:
  51. adr2 = (adr2 & ~0x1f) | ((adr2 + 1) & 0x1f);
  52. break;
  53. }
  54. return result;
  55. }
  56. byte MSXKanji::peekIO(word port, EmuTime::param /*time*/) const
  57. {
  58. byte result = 0xff;
  59. switch (port & 0x03) {
  60. case 0:
  61. if (!isLascom) {
  62. break;
  63. }
  64. // fall-through
  65. case 1:
  66. result = rom[adr1];
  67. break;
  68. case 3:
  69. if (rom.getSize() == 0x40000) { // temp workaround
  70. result = rom[adr2];
  71. }
  72. break;
  73. }
  74. return result;
  75. }
  76. template<typename Archive>
  77. void MSXKanji::serialize(Archive& ar, unsigned /*version*/)
  78. {
  79. ar.template serializeBase<MSXDevice>(*this);
  80. ar.serialize("adr1", adr1);
  81. ar.serialize("adr2", adr2);
  82. }
  83. INSTANTIATE_SERIALIZE_METHODS(MSXKanji);
  84. REGISTER_MSXDEVICE(MSXKanji, "Kanji");
  85. /*
  86. This really works!
  87. 10 DIM A(32)
  88. 20 FOR I=0 TO 4095
  89. 30 OUT &HD8, I MOD 64: OUT &HD9, I\64
  90. 40 FOR J=0 TO 31: A(J)=INP(&HD9): NEXT
  91. 50 FOR J=0 TO 7
  92. 60 PRINT RIGHT$("0000000"+BIN$(A(J)), 8);
  93. 70 PRINT RIGHT$("0000000"+BIN$(A(J+8)), 8)
  94. 80 NEXT
  95. 90 FOR J=16 TO 23
  96. 100 PRINT RIGHT$("0000000"+BIN$(A(J)), 8);
  97. 110 PRINT RIGHT$("0000000"+BIN$(A(J+8)), 8)
  98. 120 NEXT
  99. 130 PRINT
  100. 140 NEXT
  101. */
  102. } // namespace openmsx