From 1e195243be4929aa5fd0cedd93f817ed5fe07a64 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Wed, 15 Jan 2020 14:25:24 -0500 Subject: [PATCH] MSXHawk: frameadvance, no video or sound yet --- .../Computers/MSX/LibMSX.cs | 12 +++ .../Computers/MSX/MSX.IEmulator.cs | 28 +------ libHawk/MSXHawk/MSXHawk/Core.h | 59 +++++++++++-- libHawk/MSXHawk/MSXHawk/MSXHawk.cpp | 6 ++ libHawk/MSXHawk/MSXHawk/Memory.cpp | 82 +++++++++++++++++++ libHawk/MSXHawk/MSXHawk/Memory.h | 80 +++++++++++++++--- 6 files changed, 222 insertions(+), 45 deletions(-) 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