diff --git a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
index 75dcdadaab..c0a683a06c 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
@@ -27,5 +27,17 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// 0 on success, negative value on failure.
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int MSX_load(IntPtr core, byte[] romdata, uint length, int mapper);
+
+ ///
+ /// Advance a frame and send controller data.
+ ///
+ /// opaque state pointer
+ /// controller data for player 1
+ /// controller data for player 2
+ /// length of romdata in bytes
+ /// 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);
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
index d3f85c7dcf..a20cc9c4bb 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
@@ -21,29 +21,10 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
public bool FrameAdvance(IController controller, bool render, bool rendersound)
{
_controller = controller;
- _lagged = true;
+
_frame++;
- /*
- if (Tracer.Enabled)
- {
- }
- else
- {
-
- }
- */
- if (_lagged)
- {
- _lagCount++;
- _isLag = true;
- }
- else
- {
- _isLag = false;
- }
-
- return true;
+ return LibMSX.MSX_frame_advance(MSX_Pntr, 0, 0, true, true);
}
public int Frame => _frame;
@@ -155,11 +136,6 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
public int VsyncNumerator => _frameHz;
public int VsyncDenominator => 1;
- public static readonly uint[] color_palette_BW = { 0xFFFFFFFF, 0xFFAAAAAA, 0xFF555555, 0xFF000000 };
- public static readonly uint[] color_palette_Gr = { 0xFFA4C505, 0xFF88A905, 0xFF1D551D, 0xFF052505 };
-
- public uint[] color_palette = new uint[4];
-
#endregion
}
}
diff --git a/libHawk/MSXHawk/MSXHawk/Core.h b/libHawk/MSXHawk/MSXHawk/Core.h
index 779863d937..3e8c433c90 100644
--- a/libHawk/MSXHawk/MSXHawk/Core.h
+++ b/libHawk/MSXHawk/MSXHawk/Core.h
@@ -10,11 +10,6 @@
namespace MSXHawk
{
- //class Z80A;
- //class VDP;
- //class SN76489sms;
- //class MemoryManager;
-
class MSXCore
{
public:
@@ -26,13 +21,63 @@ namespace MSXHawk
cpu.mem_ctrl = &MemMap;
};
- Z80A* aaa;
-
void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
{
MemMap.Load_ROM(ext_rom, ext_rom_size, ext_rom_mapper);
}
+ bool FrameAdvance(uint8_t controller_1, uint8_t controller_2, bool render, bool rendersound)
+ {
+ MemMap.controller_byte_1 = controller_1;
+ MemMap.controller_byte_2 = controller_2;
+ MemMap.lagged = true;
+
+ int scanlinesPerFrame = 262;
+ vdp.SpriteLimit = true;
+ for (int i = 0; i < scanlinesPerFrame; i++)
+ {
+ vdp.ScanLine = i;
+
+ vdp.RenderCurrentScanline(render);
+
+ vdp.ProcessFrameInterrupt();
+ vdp.ProcessLineInterrupt();
+
+ for (int j = 0; j < vdp.IPeriod; j++)
+ {
+ cpu.ExecuteOne();
+
+ psg.generate_sound();
+ /*
+ s_L = psg.current_sample_L;
+ s_R = psg.current_sample_R;
+
+ if (s_L != old_s_L)
+ {
+ blip_L.AddDelta(sampleclock, s_L - old_s_L);
+ old_s_L = s_L;
+ }
+
+ if (s_R != old_s_R)
+ {
+ blip_R.AddDelta(sampleclock, s_R - old_s_R);
+ old_s_R = s_R;
+ }
+
+ sampleclock++;
+ */
+ }
+
+ if (vdp.ScanLine == scanlinesPerFrame - 1)
+ {
+ vdp.ProcessGGScreen();
+ //vdp.ProcessOverscan();
+ }
+ }
+
+ return MemMap.lagged;
+ }
+
VDP vdp;
Z80A cpu;
SN76489sms psg;
diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
index 62efc8e921..2e30e62d82 100644
--- a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
+++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
@@ -29,3 +29,9 @@ MSXHAWK_EXPORT void MSX_load(MSXCore* p, uint8_t* rom, unsigned int size, int ma
p->Load_ROM(rom, size, mapper);
}
+// advance a frame
+MSXHAWK_EXPORT void MSX_frame_advance(MSXCore* p, uint8_t ctrl1, uint8_t ctrl2, bool render, bool sound)
+{
+ p->FrameAdvance(ctrl1, ctrl2, render, sound);
+}
+
diff --git a/libHawk/MSXHawk/MSXHawk/Memory.cpp b/libHawk/MSXHawk/MSXHawk/Memory.cpp
index 5e29d5c2cf..2c36592775 100644
--- a/libHawk/MSXHawk/MSXHawk/Memory.cpp
+++ b/libHawk/MSXHawk/MSXHawk/Memory.cpp
@@ -5,11 +5,93 @@
#include "Memory.h"
#include "Z80A.h"
+#include "VDP.h"
+#include "PSG.h"
using namespace std;
namespace MSXHawk
{
+ uint8_t MemoryManager::HardwareRead(uint32_t port)
+ {
+ port &= 0xFF;
+ if (port < 0x40) // General IO ports
+ {
+
+ switch (port)
+ {
+ case 0x00: return ReadPort0();
+ case 0x01: return Port01;
+ case 0x02: return Port02;
+ case 0x03: return Port03;
+ case 0x04: return Port04;
+ case 0x05: return Port05;
+ case 0x06: return 0xFF;
+ case 0x3E: return Port3E;
+ default: return 0xFF;
+ }
+ }
+ if (port < 0x80) // VDP Vcounter/HCounter
+ {
+ if ((port & 1) == 0)
+ return vdp_pntr->ReadVLineCounter();
+ else
+ return vdp_pntr->ReadHLineCounter();
+ }
+ if (port < 0xC0) // VDP data/control ports
+ {
+ if ((port & 1) == 0)
+ return vdp_pntr->ReadData();
+ else
+ return vdp_pntr->ReadVdpStatus();
+ }
+ switch (port)
+ {
+ case 0xC0:
+ case 0xDC: return ReadControls1();
+ case 0xC1:
+ case 0xDD: return ReadControls2();
+ case 0xDE: return PortDEEnabled ? PortDE : 0xFF;
+ case 0xF2: return 0xFF;
+ default: return 0xFF;
+ }
+ }
+
+ void MemoryManager::HardwareWrite(uint32_t port, uint8_t value)
+ {
+ port &= 0xFF;
+ if (port < 0x40) // general IO ports
+ {
+ switch (port & 0xFF)
+ {
+ case 0x01: Port01 = value; break;
+ case 0x02: Port02 = value; break;
+ case 0x03: Port03 = value; break;
+ case 0x04: /*Port04 = value*/; break; // receive port, not sure what writing does
+ case 0x05: Port05 = (uint8_t)(value & 0xF8); break;
+ case 0x06: psg_pntr->Set_Panning(value); break;
+ case 0x3E: Port3E = value; break;
+ case 0x3F: Port3F = value; break;
+ }
+ }
+ else if (port < 0x80) // PSG
+ {
+ psg_pntr->WriteReg(value);
+ }
+ else if (port < 0xC0) // VDP
+ {
+ if ((port & 1) == 0)
+ {
+ vdp_pntr->WriteVdpData(value);
+ }
+ else
+ {
+ vdp_pntr->WriteVdpControl(value);
+ }
+ }
+ else if (port == 0xDE && PortDEEnabled) PortDE = value;
+ }
+
void MemoryManager::remap_ROM_0()
{
// 0x0000 - 0x03FF always maps to start of ROM
diff --git a/libHawk/MSXHawk/MSXHawk/Memory.h b/libHawk/MSXHawk/MSXHawk/Memory.h
index b02747874c..8ecef841d9 100644
--- a/libHawk/MSXHawk/MSXHawk/Memory.h
+++ b/libHawk/MSXHawk/MSXHawk/Memory.h
@@ -28,8 +28,25 @@ namespace MSXHawk
uint32_t rom_mapper;
uint8_t ram[0x2000];
+ bool PortDEEnabled = false;
+ bool lagged;
+ bool start_pressed;
+
+ uint8_t controller_byte_1, controller_byte_2;
+
+ uint8_t Port01 = 0xFF;
+ uint8_t Port02 = 0xFF;
+ uint8_t Port03 = 0x00;
+ uint8_t Port04 = 0xFF;
+ uint8_t Port05 = 0x00;
+ uint8_t Port3E = 0xAF;
+ uint8_t Port3F = 0xFF;
+ uint8_t PortDE = 0x00;
+
uint8_t cart_ram[0x8000];
+ uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
+
void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
{
rom = ext_rom;
@@ -47,15 +64,17 @@ namespace MSXHawk
remap_RAM();
}
- uint8_t HardwareRead(uint32_t value)
- {
- return 0;
- }
+ uint8_t HardwareRead(uint32_t value);
- void HardwareWrite(uint32_t addr, uint8_t value)
- {
+ void HardwareWrite(uint32_t addr, uint8_t value);
- }
+ void remap_ROM_0();
+
+ void remap_ROM_1();
+
+ void remap_ROM_2();
+
+ void remap_RAM();
void MemoryWrite(uint32_t addr, uint8_t value)
{
@@ -81,14 +100,51 @@ namespace MSXHawk
}
}
- uint8_t reg_FFFC, reg_FFFD, reg_FFFE, reg_FFFF;
+ uint8_t ReadPort0()
+ {
+ lagged = false;
- void remap_ROM_0();
+ uint8_t value = 0xFF;
+ if (start_pressed)
+ {
+ value ^= 0x80;
+ }
- void remap_ROM_1();
+ return value;
+ }
- void remap_ROM_2();
+ uint8_t ReadControls1()
+ {
+ lagged = false;
+ uint8_t value = 0xFF;
- void remap_RAM();
+ value &= ~(controller_byte_1 & 0xCF);
+ value &= ~(controller_byte_2 & 0x30);
+
+ return value;
+ }
+
+ uint8_t ReadControls2()
+ {
+ lagged = false;
+ uint8_t value = 0xFF;
+
+ value &= ~(controller_byte_2 & 0xF);
+
+ if ((Port3F & 0x0F) == 5)
+ {
+ if (Port3F >> 4 == 0x0F)
+ {
+ value |= 0xC0;
+ }
+
+ else
+ {
+ value &= 0x3F;
+ }
+ }
+
+ return value;
+ }
};
}
\ No newline at end of file