diff --git a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
index c78a0b8971..715c9787fa 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
@@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// Mapper number to load core with
/// 0 on success, negative value on failure.
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern bool MSX_frame_advance(IntPtr core, byte ctrl1, byte ctrl2, bool render, bool sound);
+ public static extern bool MSX_frame_advance(IntPtr core, byte ctrl1, byte ctrl2, byte[] kbrows, bool render, bool sound);
///
/// Get Video data
@@ -112,6 +112,13 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte MSX_getvram(IntPtr core, int addr);
+ ///
+ /// Read the RAM
+ ///
+ /// opaque state pointer
+ /// ram address
+ [DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern byte MSX_getram(IntPtr core, int addr);
#endregion
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
index 92121c4735..25f3e04d7e 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
@@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
}
public bool FrameAdvance(IController controller, bool render, bool rendersound)
- {
+ {
_controller = controller;
byte ctrl1_byte = 0xFF;
@@ -28,12 +28,14 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
if (_controller.IsPressed("P1 B2")) ctrl1_byte -= 0x20;
byte ctrl2_byte = 0xFF;
- if (_controller.IsPressed("P2 Up")) ctrl1_byte -= 0x01;
- if (_controller.IsPressed("P2 Down")) ctrl1_byte -= 0x02;
- if (_controller.IsPressed("P2 Left")) ctrl1_byte -= 0x04;
- if (_controller.IsPressed("P2 Right")) ctrl1_byte -= 0x08;
- if (_controller.IsPressed("P2 B1")) ctrl1_byte -= 0x10;
- if (_controller.IsPressed("P2 B2")) ctrl1_byte -= 0x20;
+ if (_controller.IsPressed("P2 Up")) ctrl2_byte -= 0x01;
+ if (_controller.IsPressed("P2 Down")) ctrl2_byte -= 0x02;
+ if (_controller.IsPressed("P2 Left")) ctrl2_byte -= 0x04;
+ if (_controller.IsPressed("P2 Right")) ctrl2_byte -= 0x08;
+ if (_controller.IsPressed("P2 B1")) ctrl2_byte -= 0x10;
+ if (_controller.IsPressed("P2 B2")) ctrl2_byte -= 0x20;
+
+ kb_rows_check(controller);
_frame++;
@@ -45,14 +47,102 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
{
tracecb = null;
}
-
+
LibMSX.MSX_settracecallback(MSX_Pntr, tracecb);
-
- LibMSX.MSX_frame_advance(MSX_Pntr, ctrl1_byte, ctrl2_byte, true, true);
-
+
+ LibMSX.MSX_frame_advance(MSX_Pntr, ctrl1_byte, ctrl2_byte, kb_rows, true, true);
+
return true;
}
+ public byte[] kb_rows = new byte[16];
+
+ public void kb_rows_check(IController controller)
+ {
+ for(int i = 0; i < 9; i++) { kb_rows[i] = 0; }
+
+ if (controller.IsPressed("7")) { kb_rows[0] |= 0x80; }
+ if (controller.IsPressed("6")) { kb_rows[0] |= 0x40; }
+ if (controller.IsPressed("5")) { kb_rows[0] |= 0x20; }
+ if (controller.IsPressed("4")) { kb_rows[0] |= 0x10; }
+ if (controller.IsPressed("3")) { kb_rows[0] |= 0x08; }
+ if (controller.IsPressed("2")) { kb_rows[0] |= 0x04; }
+ if (controller.IsPressed("1")) { kb_rows[0] |= 0x02; }
+ if (controller.IsPressed("0")) { kb_rows[0] |= 0x01; }
+
+ if (controller.IsPressed(";")) { kb_rows[1] |= 0x80; }
+ if (controller.IsPressed("[")) { kb_rows[1] |= 0x40; }
+ if (controller.IsPressed("@")) { kb_rows[1] |= 0x20; }
+ if (controller.IsPressed("$")) { kb_rows[1] |= 0x10; }
+ if (controller.IsPressed("^")) { kb_rows[1] |= 0x08; }
+ if (controller.IsPressed("-")) { kb_rows[1] |= 0x04; }
+ if (controller.IsPressed("9")) { kb_rows[1] |= 0x02; }
+ if (controller.IsPressed("8")) { kb_rows[1] |= 0x01; }
+
+ if (controller.IsPressed("B")) { kb_rows[2] |= 0x80; }
+ if (controller.IsPressed("A")) { kb_rows[2] |= 0x40; }
+
+ if (controller.IsPressed("/")) { kb_rows[2] |= 0x10; }
+ if (controller.IsPressed(".")) { kb_rows[2] |= 0x08; }
+ if (controller.IsPressed(",")) { kb_rows[2] |= 0x04; }
+ if (controller.IsPressed("]")) { kb_rows[2] |= 0x02; }
+ if (controller.IsPressed(":")) { kb_rows[2] |= 0x01; }
+
+ if (controller.IsPressed("J")) { kb_rows[3] |= 0x80; }
+ if (controller.IsPressed("I")) { kb_rows[3] |= 0x40; }
+ if (controller.IsPressed("H")) { kb_rows[3] |= 0x20; }
+ if (controller.IsPressed("G")) { kb_rows[3] |= 0x10; }
+ if (controller.IsPressed("F")) { kb_rows[3] |= 0x08; }
+ if (controller.IsPressed("E")) { kb_rows[3] |= 0x04; }
+ if (controller.IsPressed("D")) { kb_rows[3] |= 0x02; }
+ if (controller.IsPressed("C")) { kb_rows[3] |= 0x01; }
+
+ if (controller.IsPressed("R")) { kb_rows[4] |= 0x80; }
+ if (controller.IsPressed("Q")) { kb_rows[4] |= 0x40; }
+ if (controller.IsPressed("P")) { kb_rows[4] |= 0x20; }
+ if (controller.IsPressed("O")) { kb_rows[4] |= 0x10; }
+ if (controller.IsPressed("N")) { kb_rows[4] |= 0x08; }
+ if (controller.IsPressed("M")) { kb_rows[4] |= 0x04; }
+ if (controller.IsPressed("L")) { kb_rows[4] |= 0x02; }
+ if (controller.IsPressed("K")) { kb_rows[4] |= 0x01; }
+
+ if (controller.IsPressed("Z")) { kb_rows[5] |= 0x80; }
+ if (controller.IsPressed("Y")) { kb_rows[5] |= 0x40; }
+ if (controller.IsPressed("X")) { kb_rows[5] |= 0x20; }
+ if (controller.IsPressed("W")) { kb_rows[5] |= 0x10; }
+ if (controller.IsPressed("V")) { kb_rows[5] |= 0x08; }
+ if (controller.IsPressed("U")) { kb_rows[5] |= 0x04; }
+ if (controller.IsPressed("T")) { kb_rows[5] |= 0x02; }
+ if (controller.IsPressed("S")) { kb_rows[5] |= 0x01; }
+
+ if (controller.IsPressed("F3")) { kb_rows[6] |= 0x80; }
+ if (controller.IsPressed("F2")) { kb_rows[6] |= 0x40; }
+ if (controller.IsPressed("F1")) { kb_rows[6] |= 0x20; }
+ if (controller.IsPressed("KANA")) { kb_rows[6] |= 0x10; }
+ if (controller.IsPressed("CAP")) { kb_rows[6] |= 0x08; }
+ if (controller.IsPressed("GRAPH")) { kb_rows[6] |= 0x04; }
+ if (controller.IsPressed("CTRL")) { kb_rows[6] |= 0x02; }
+ if (controller.IsPressed("SHIFT")) { kb_rows[6] |= 0x01; }
+
+ if (controller.IsPressed("RET")) { kb_rows[7] |= 0x80; }
+ if (controller.IsPressed("SEL")) { kb_rows[7] |= 0x40; }
+ if (controller.IsPressed("BACK")) { kb_rows[7] |= 0x20; }
+ if (controller.IsPressed("STOP")) { kb_rows[7] |= 0x10; }
+ if (controller.IsPressed("TAB")) { kb_rows[7] |= 0x08; }
+ if (controller.IsPressed("ESC")) { kb_rows[7] |= 0x04; }
+ if (controller.IsPressed("F5")) { kb_rows[7] |= 0x02; }
+ if (controller.IsPressed("F4")) { kb_rows[7] |= 0x01; }
+
+ if (controller.IsPressed("RIGHT")) { kb_rows[8] |= 0x80; }
+ if (controller.IsPressed("DOWN")) { kb_rows[8] |= 0x40; }
+ if (controller.IsPressed("UP")) { kb_rows[8] |= 0x20; }
+ if (controller.IsPressed("LEFT")) { kb_rows[8] |= 0x10; }
+ if (controller.IsPressed("DEL")) { kb_rows[8] |= 0x08; }
+ if (controller.IsPressed("INS")) { kb_rows[8] |= 0x04; }
+ if (controller.IsPressed("HOME")) { kb_rows[8] |= 0x02; }
+ if (controller.IsPressed("SPACE")) { kb_rows[8] |= 0x01; }
+ }
+
public int Frame => _frame;
public string SystemId => "MSX";
@@ -151,6 +241,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
public int VirtualHeight => 192;
public int BufferWidth => 256;
public int BufferHeight => 192;
+
public int BackgroundColor => unchecked((int)0xFF000000);
public int VsyncNumerator => _frameHz;
public int VsyncDenominator => 1;
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IMemoryDomains.cs
index 7866cf4203..321e15070f 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IMemoryDomains.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IMemoryDomains.cs
@@ -30,6 +30,13 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
(addr) => LibMSX.MSX_getvram(MSX_Pntr, (int)(addr & 0x3FFF)),
(addr, value) => { },
1),
+ new MemoryDomainDelegate(
+ "RAM",
+ 0x10000,
+ MemoryDomain.Endian.Little,
+ (addr) => LibMSX.MSX_getram(MSX_Pntr, (int)(addr & 0xFFFF)),
+ (addr, value) => { },
+ 1)
};
if (SaveRAM != null)
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.Input.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.Input.cs
index 01f59e88c2..1dfa9a7e00 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.Input.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.Input.cs
@@ -14,7 +14,16 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
{
"Reset",
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 B1", "P1 B2",
- "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 B1", "P2 B2"
+ "P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 B1", "P2 B2",
+ "7", "6", "5", "4", "3", "2", "1", "0",
+ ";", "[", "@", "$", "^", "-", "9", "8",
+ "B", "A", "/", ".", ",", "]", ":",
+ "J", "I", "H", "G", "F", "E", "D", "C",
+ "R", "Q", "P", "O", "N", "M", "L", "K",
+ "Z", "Y", "X", "W", "V", "U", "T", "S",
+ "F3", "F2", "F1", "KANA", "CAP", "GRAPH", "CTRL", "SHIFT",
+ "RET", "SEL", "BACK", "STOP", "TAB", "ESC", "F5", "F4",
+ "RIGHT", "DOWN", "UP", "LEFT", "DEL", "INS", "HOME", "SPACE"
}
};
}
diff --git a/libHawk/MSXHawk/MSXHawk/Core.h b/libHawk/MSXHawk/MSXHawk/Core.h
index 669708b0cc..36afb5bda0 100644
--- a/libHawk/MSXHawk/MSXHawk/Core.h
+++ b/libHawk/MSXHawk/MSXHawk/Core.h
@@ -39,7 +39,7 @@ namespace MSXHawk
MemMap.Load_ROM(ext_rom_1, ext_rom_size_1, ext_rom_mapper_1, ext_rom_2, ext_rom_size_2, ext_rom_mapper_2);
}
- bool FrameAdvance(uint8_t controller_1, uint8_t controller_2, bool render, bool rendersound)
+ bool FrameAdvance(uint8_t controller_1, uint8_t controller_2, uint8_t* kb_rows_ptr, bool render, bool rendersound)
{
if ((MemMap.psg_pntr->Register[0xF] & 0x40) > 0)
{
@@ -52,6 +52,7 @@ namespace MSXHawk
MemMap.controller_byte_1 = controller_1;
MemMap.controller_byte_2 = controller_2;
+ MemMap.kb_rows = kb_rows_ptr;
MemMap.start_pressed = (controller_1 & 0x80) > 0;
MemMap.lagged = true;
@@ -91,7 +92,8 @@ namespace MSXHawk
return MemMap.lagged;
}
- void GetVideo(uint32_t* dest) {
+ void GetVideo(uint32_t* dest)
+ {
uint32_t* src = vdp.FrameBuffer;
uint32_t* dst = dest;
@@ -145,6 +147,11 @@ namespace MSXHawk
return vdp.VRAM[addr & 0x3FFF];
}
+ uint8_t GetRAM(uint32_t addr)
+ {
+ return MemMap.ram[addr & 0xFFFF];
+ }
+
#pragma endregion
#pragma region Tracer
diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
index 528b44c032..34c6809a5b 100644
--- a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
+++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
@@ -41,10 +41,9 @@ MSXHawk_EXPORT void MSX_load(MSXCore* p, uint8_t* rom_1, uint32_t size_1, uint32
}
// advance a frame
-MSXHawk_EXPORT bool MSX_frame_advance(MSXCore* p, uint8_t ctrl1, uint8_t ctrl2, bool render, bool sound)
+MSXHawk_EXPORT bool MSX_frame_advance(MSXCore* p, uint8_t ctrl1, uint8_t ctrl2, uint8_t* kbrows, bool render, bool sound)
{
- p->FrameAdvance(ctrl1, ctrl2, render, sound);
- return p->vdp.EnableInterrupts();
+ return p->FrameAdvance(ctrl1, ctrl2, kbrows, render, sound);
}
// send video data to external video provider
@@ -84,6 +83,11 @@ MSXHawk_EXPORT uint8_t MSX_getsysbus(MSXCore* p, uint32_t addr) {
MSXHawk_EXPORT uint8_t MSX_getvram(MSXCore* p, uint32_t addr) {
return p->GetVRAM(addr);
}
+
+MSXHawk_EXPORT uint8_t MSX_getram(MSXCore* p, uint32_t addr) {
+ return p->GetRAM(addr);
+}
+
#pragma endregion
diff --git a/libHawk/MSXHawk/MSXHawk/Memory.cpp b/libHawk/MSXHawk/MSXHawk/Memory.cpp
index ec89c9e5b3..62b67c3dd2 100644
--- a/libHawk/MSXHawk/MSXHawk/Memory.cpp
+++ b/libHawk/MSXHawk/MSXHawk/Memory.cpp
@@ -26,6 +26,7 @@ namespace MSXHawk
}
else if (port == 0xA2)
{
+ if (psg_pntr->port_sel == 0xE) { lagged = false; }
return psg_pntr->ReadReg();
}
else if (port == 0xA8)
@@ -34,7 +35,13 @@ namespace MSXHawk
}
else if (port == 0xA9)
{
- return 0xFF;
+ lagged = false;
+ return ~kb_rows[kb_rows_sel];
+ }
+ else if (port == 0xAA)
+ {
+ // TODO: casette, caps lamp, keyboard sound click
+ return kb_rows_sel;
}
return 0xFF;
@@ -78,6 +85,11 @@ namespace MSXHawk
PortA8 = value;
remap();
}
+ else if (port == 0xAA)
+ {
+ kb_rows_sel = value & 0xF;
+ remap();
+ }
}
void MemoryManager::remap()
diff --git a/libHawk/MSXHawk/MSXHawk/Memory.h b/libHawk/MSXHawk/MSXHawk/Memory.h
index d9c60d36e4..c3d864b04e 100644
--- a/libHawk/MSXHawk/MSXHawk/Memory.h
+++ b/libHawk/MSXHawk/MSXHawk/Memory.h
@@ -29,12 +29,16 @@ namespace MSXHawk
uint32_t rom_size_2;
uint32_t rom_mapper_2;
+ // controls are not stated
+ uint8_t controller_byte_1, controller_byte_2;
+ uint8_t* kb_rows;
+
// State
bool PortDEEnabled = false;
bool lagged;
bool start_pressed;
- uint8_t controller_byte_1, controller_byte_2;
+ uint8_t kb_rows_sel;
uint8_t PortA8 = 0x00;
uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
uint8_t ram[0x10000] = {};
@@ -87,40 +91,6 @@ namespace MSXHawk
}
- uint8_t ReadPort0()
- {
- lagged = false;
-
- uint8_t value = 0xFF;
- if (start_pressed)
- {
- value ^= 0x80;
- }
-
- return value;
- }
-
- uint8_t ReadControls1()
- {
- lagged = false;
- uint8_t value = 0xFF;
-
- value &= ~(controller_byte_1 & 0x3F);
- value &= ~(controller_byte_2 & 0xC0);
-
- return value;
- }
-
- uint8_t ReadControls2()
- {
- lagged = false;
- uint8_t value = 0xFF;
-
- value &= ~(controller_byte_2 & 0xF);
-
- return value;
- }
-
#pragma region State Save / Load
uint8_t* SaveState(uint8_t* saver)
@@ -129,8 +99,7 @@ namespace MSXHawk
*saver = (uint8_t)(lagged ? 1 : 0); saver++;
*saver = (uint8_t)(start_pressed ? 1 : 0); saver++;
- *saver = controller_byte_1; saver++;
- *saver = controller_byte_2; saver++;
+ *saver = kb_rows_sel; saver++;
*saver = PortA8; saver++;
*saver = reg_FFFC; saver++;
*saver = reg_FFFD; saver++;
@@ -149,8 +118,7 @@ namespace MSXHawk
lagged = *loader == 1; loader++;
start_pressed = *loader == 1; loader++;
- controller_byte_1 = *loader; loader++;
- controller_byte_2 = *loader; loader++;
+ kb_rows_sel = *loader; loader++;
PortA8 = *loader; loader++;
reg_FFFC = *loader; loader++;
reg_FFFD = *loader; loader++;
diff --git a/libHawk/MSXHawk/MSXHawk/TMS9918A.h b/libHawk/MSXHawk/MSXHawk/TMS9918A.h
index 298a0c4428..c31b76be4a 100644
--- a/libHawk/MSXHawk/MSXHawk/TMS9918A.h
+++ b/libHawk/MSXHawk/MSXHawk/TMS9918A.h
@@ -32,12 +32,12 @@ namespace MSXHawk
uint8_t StatusByte;
uint8_t VdpLatch;
uint8_t VdpBuffer;
+ uint8_t TmsMode;
uint8_t Registers[8] = {};
uint8_t VRAM[0x4000]; //16kb video RAM
int32_t ScanLine;
uint32_t VdpAddress;
- uint32_t TmsMode;
uint32_t ColorTableBase;
uint32_t PatternGeneratorBase;
uint32_t SpritePatternGeneratorBase;
@@ -373,7 +373,7 @@ namespace MSXHawk
}
}
- void RenderTmsSprites(int32_t scanLine)
+ inline void RenderTmsSprites(int32_t scanLine)
{
if (EnableDoubledSprites() == false)
{
@@ -537,6 +537,7 @@ namespace MSXHawk
*saver = StatusByte; saver++;
*saver = VdpLatch; saver++;
*saver = VdpBuffer; saver++;
+ *saver = TmsMode; saver++;
std::memcpy(saver, &Registers, 8); saver += 8;
std::memcpy(saver, &VRAM, 0x4000); saver += 0x4000;
@@ -547,9 +548,6 @@ namespace MSXHawk
*saver = (uint8_t)(VdpAddress & 0xFF); saver++; *saver = (uint8_t)((VdpAddress >> 8) & 0xFF); saver++;
*saver = (uint8_t)((VdpAddress >> 16) & 0xFF); saver++; *saver = (uint8_t)((VdpAddress >> 24) & 0xFF); saver++;
- *saver = (uint8_t)(TmsMode & 0xFF); saver++; *saver = (uint8_t)((TmsMode >> 8) & 0xFF); saver++;
- *saver = (uint8_t)((TmsMode >> 16) & 0xFF); saver++; *saver = (uint8_t)((TmsMode >> 24) & 0xFF); saver++;
-
*saver = (uint8_t)(ColorTableBase & 0xFF); saver++; *saver = (uint8_t)((ColorTableBase >> 8) & 0xFF); saver++;
*saver = (uint8_t)((ColorTableBase >> 16) & 0xFF); saver++; *saver = (uint8_t)((ColorTableBase >> 24) & 0xFF); saver++;
@@ -578,6 +576,7 @@ namespace MSXHawk
StatusByte = *loader; loader++;
VdpLatch = *loader; loader++;
VdpBuffer = *loader; loader++;
+ TmsMode = *loader; loader++;
std::memcpy(&Registers, loader, 8); loader += 8;
std::memcpy(&VRAM, loader, 0x4000); loader += 0x4000;
@@ -588,9 +587,6 @@ namespace MSXHawk
VdpAddress = *loader; loader++; VdpAddress |= (*loader << 8); loader++;
VdpAddress |= (*loader << 16); loader++; VdpAddress |= (*loader << 24); loader++;
- TmsMode = *loader; loader++; TmsMode |= (*loader << 8); loader++;
- TmsMode |= (*loader << 16); loader++; TmsMode |= (*loader << 24); loader++;
-
ColorTableBase = *loader; loader++; ColorTableBase |= (*loader << 8); loader++;
ColorTableBase |= (*loader << 16); loader++; ColorTableBase |= (*loader << 24); loader++;