MSXHawk: keyboard

This commit is contained in:
alyosha-tas 2020-01-28 07:50:29 -05:00
parent ce79ec83d7
commit 0c46a6908f
9 changed files with 167 additions and 66 deletions

View File

@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// <param name="sound">Mapper number to load core with</param>
/// <returns>0 on success, negative value on failure.</returns>
[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);
/// <summary>
/// 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);
/// <summary>
/// Read the RAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">ram address</param>
[DllImport("MSXHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte MSX_getram(IntPtr core, int addr);
#endregion

View File

@ -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;

View File

@ -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)

View File

@ -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"
}
};
}

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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++;

View File

@ -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++;