MSXHawk: Finish trace logger and add some memory domains

This commit is contained in:
alyosha-tas 2020-01-16 20:08:50 -05:00
parent 6637510379
commit c27bea3272
6 changed files with 107 additions and 57 deletions

View File

@ -10,6 +10,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// </summary> /// </summary>
public static class LibMSX public static class LibMSX
{ {
# region Core
/// <returns>opaque state pointer</returns> /// <returns>opaque state pointer</returns>
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr MSX_create(); public static extern IntPtr MSX_create();
@ -53,6 +54,29 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MSX_get_video(IntPtr core, int[] videobuf); public static extern void MSX_get_video(IntPtr core, int[] videobuf);
#endregion
#region Memory Domain Functions
/// <summary>
/// Read the system bus
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">system bus address</param>
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte MSX_getsysbus(IntPtr core, int addr);
/// <summary>
/// Read the VRAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">vram address</param>
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte MSX_getvram(IntPtr core, int addr);
#endregion
#region Tracer #region Tracer
/// <summary> /// <summary>
/// type of the cpu trace callback /// type of the cpu trace callback

View File

@ -16,25 +16,20 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
{ {
var domains = new List<MemoryDomain> var domains = new List<MemoryDomain>
{ {
new MemoryDomainDelegate("System Bus", 0x10000, MemoryDomain.Endian.Little, new MemoryDomainDelegate(
(addr) => "System Bus",
{ 0x10000,
if (addr < 0 || addr >= 65536) MemoryDomain.Endian.Little,
{ (addr) => LibMSX.MSX_getsysbus(MSX_Pntr, (int)(addr & 0xFFFF)),
throw new ArgumentOutOfRangeException(); (addr, value) => { },
} 1),
new MemoryDomainDelegate(
return 0; "VRAM",
}, 0x4000,
(addr, value) => MemoryDomain.Endian.Little,
{ (addr) => LibMSX.MSX_getvram(MSX_Pntr, (int)(addr & 0x3FFF)),
if (addr < 0 || addr >= 65536) (addr, value) => { },
{ 1),
throw new ArgumentOutOfRangeException();
}
}, 1)
}; };
if (SaveRAM != null) if (SaveRAM != null)

View File

@ -100,6 +100,24 @@ namespace MSXHawk
} }
} }
#pragma region Memory Domain Functions
uint8_t GetSysBus(uint32_t addr)
{
cpu.bank_num = cpu.bank_offset = addr & 0xFFFF;
cpu.bank_offset &= cpu.low_mask;
cpu.bank_num = (cpu.bank_num >> cpu.bank_shift)& cpu.high_mask;
return cpu.MemoryMap[cpu.bank_num][cpu.bank_offset];
}
uint8_t GetVRAM(uint32_t addr)
{
return vdp.VRAM[addr & 0x3FFF];
}
#pragma endregion
#pragma region Tracer #pragma region Tracer
void SetTraceCallback(void (*callback)(int)) void SetTraceCallback(void (*callback)(int))

View File

@ -11,6 +11,7 @@
using namespace MSXHawk; using namespace MSXHawk;
#pragma region Core
// Create pointer to a core instance // Create pointer to a core instance
MSXHAWK_EXPORT MSXCore* MSX_create() MSXHAWK_EXPORT MSXCore* MSX_create()
{ {
@ -45,6 +46,19 @@ MSXHAWK_EXPORT void MSX_get_video(MSXCore* p, uint32_t* dest)
MSXHAWK_EXPORT void MSX_settracecallback(MSXCore* p, void (*callback)(int)) { MSXHAWK_EXPORT void MSX_settracecallback(MSXCore* p, void (*callback)(int)) {
p->SetTraceCallback(callback); p->SetTraceCallback(callback);
} }
#pragma endregion
#pragma region Memory Domain Functions
MSXHAWK_EXPORT uint8_t MSX_getsysbus(MSXCore* p, uint32_t addr) {
return p->GetSysBus(addr);
}
MSXHAWK_EXPORT uint8_t MSX_getvram(MSXCore* p, uint32_t addr) {
return p->GetVRAM(addr);
}
#pragma endregion
#pragma region Tracer #pragma region Tracer

View File

@ -22,7 +22,7 @@ namespace MSXHawk
uint8_t VRAM[0x4000]; //16kb video RAM uint8_t VRAM[0x4000]; //16kb video RAM
uint8_t CRAM[64]; // SMS = 32 uint8_ts, GG = 64 uint8_ts CRAM uint8_t CRAM[64]; // SMS = 32 uint8_ts, GG = 64 uint8_ts CRAM
uint8_t Registers[16] = { 0x06, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t Registers[16] = { 0x06, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t Statusuint8_t; uint8_t StatusInt;
static void TO_REGS(uint8_t value) static void TO_REGS(uint8_t value)
{ {
@ -118,8 +118,8 @@ namespace MSXHawk
uint8_t ReadVdpStatus() uint8_t ReadVdpStatus()
{ {
VdpWaitingForLatchuint8_t = true; VdpWaitingForLatchuint8_t = true;
uint8_t returnValue = Statusuint8_t; uint8_t returnValue = StatusInt;
Statusuint8_t &= 0x1F; StatusInt &= 0x1F;
HIntPending = false; HIntPending = false;
VIntPending = false; VIntPending = false;
INT_FLAG[0] = false; INT_FLAG[0] = false;
@ -350,7 +350,7 @@ namespace MSXHawk
{ {
if (ScanLine == FrameHeight + 1) if (ScanLine == FrameHeight + 1)
{ {
Statusuint8_t |= 0x80; StatusInt |= 0x80;
VIntPending = true; VIntPending = true;
} }
@ -410,7 +410,7 @@ namespace MSXHawk
void SyncState(Serializer ser) void SyncState(Serializer ser)
{ {
ser.BeginSection(nameof(VDP)); ser.BeginSection(nameof(VDP));
ser.Sync(nameof(Statusuint8_t), ref Statusuint8_t); ser.Sync(nameof(StatusInt), ref StatusInt);
ser.Sync("WaitingForLatchuint8_t", ref VdpWaitingForLatchuint8_t); ser.Sync("WaitingForLatchuint8_t", ref VdpWaitingForLatchuint8_t);
ser.Sync("Latch", ref VdpLatch); ser.Sync("Latch", ref VdpLatch);
ser.Sync("ReadBuffer", ref VdpBuffer); ser.Sync("ReadBuffer", ref VdpBuffer);
@ -601,7 +601,7 @@ namespace MSXHawk
{ {
collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this
if (overflowHappens) if (overflowHappens)
Statusuint8_t |= 0x40; // Set Overflow bit StatusInt |= 0x40; // Set Overflow bit
if (SpriteLimit) if (SpriteLimit)
renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering
} }
@ -621,7 +621,7 @@ namespace MSXHawk
if (SpriteCollisionBuffer[x + xs] != 0) if (SpriteCollisionBuffer[x + xs] != 0)
{ {
if (collisionHappens) if (collisionHappens)
Statusuint8_t |= 0x20; // Set Collision bit StatusInt |= 0x20; // Set Collision bit
} }
else if (renderHappens && ScanlinePriorityBuffer[x + xs] == 0) else if (renderHappens && ScanlinePriorityBuffer[x + xs] == 0)
{ {
@ -681,7 +681,7 @@ namespace MSXHawk
{ {
collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this collisionHappens = false; // technically the VDP stops processing sprite past this so we would never set the collision bit for sprites past this
if (overflowHappens) if (overflowHappens)
Statusuint8_t |= 0x40; // Set Overflow bit StatusInt |= 0x40; // Set Overflow bit
if (SpriteLimit) if (SpriteLimit)
renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering renderHappens = false; // should be able to break/return, but to ensure this has no effect on sync we keep processing and disable rendering
} }
@ -701,7 +701,7 @@ namespace MSXHawk
if (SpriteCollisionBuffer[x + xs] != 0) if (SpriteCollisionBuffer[x + xs] != 0)
{ {
if (collisionHappens) if (collisionHappens)
Statusuint8_t |= 0x20; // Set Collision bit StatusInt |= 0x20; // Set Collision bit
} }
else if (renderHappens && ScanlinePriorityBuffer[x + xs] == 0) else if (renderHappens && ScanlinePriorityBuffer[x + xs] == 0)
{ {
@ -847,7 +847,7 @@ namespace MSXHawk
#pragma region ModeTMS #pragma region ModeTMS
uint32_t PaletteTMS9918[16] uint32_t PaletteTMS9918[16] =
{ {
0xFF000000, 0xFF000000,
0xFF000000, 0xFF000000,
@ -996,9 +996,9 @@ namespace MSXHawk
if (++NumSpritesOnScanline == 5) if (++NumSpritesOnScanline == 5)
{ {
Statusuint8_t &= 0xE0; // Clear FS0-FS4 bits StatusInt &= 0xE0; // Clear FS0-FS4 bits
Statusuint8_t |= (int8_t)i; // set 5th sprite index StatusInt |= (int8_t)i; // set 5th sprite index
Statusuint8_t |= 0x40; // set overflow bit StatusInt |= 0x40; // set overflow bit
break; break;
} }
@ -1020,7 +1020,7 @@ namespace MSXHawk
if (Color != 0 && (pv & (1 << (7 - (xp & 7)))) > 0) if (Color != 0 && (pv & (1 << (7 - (xp & 7)))) > 0)
{ {
if (SpriteCollisionBuffer[x + xp] != 0) if (SpriteCollisionBuffer[x + xp] != 0)
Statusuint8_t |= 0x20; // Set sprite collision flag StatusInt |= 0x20; // Set sprite collision flag
if (ScanlinePriorityBuffer[x + xp] == 0) if (ScanlinePriorityBuffer[x + xp] == 0)
{ {
@ -1069,9 +1069,9 @@ namespace MSXHawk
if (++NumSpritesOnScanline == 5) if (++NumSpritesOnScanline == 5)
{ {
Statusuint8_t &= 0xE0; // Clear FS0-FS4 bits StatusInt &= 0xE0; // Clear FS0-FS4 bits
Statusuint8_t |= (uint8_t)i; // set 5th sprite index StatusInt |= (uint8_t)i; // set 5th sprite index
Statusuint8_t |= 0x40; // set overflow bit StatusInt |= 0x40; // set overflow bit
break; break;
} }
@ -1090,7 +1090,7 @@ namespace MSXHawk
if (Color != 0 && (pv & (1 << (7 - ((xp / 2) & 7)))) > 0) // xp/2 is due to sprite magnification if (Color != 0 && (pv & (1 << (7 - ((xp / 2) & 7)))) > 0) // xp/2 is due to sprite magnification
{ {
if (SpriteCollisionBuffer[x + xp] != 0) if (SpriteCollisionBuffer[x + xp] != 0)
Statusuint8_t |= 0x20; // Set sprite collision flag StatusInt |= 0x20; // Set sprite collision flag
if (ScanlinePriorityBuffer[x + xp] == 0) if (ScanlinePriorityBuffer[x + xp] == 0)
{ {

View File

@ -4623,7 +4623,7 @@ namespace MSXHawk
return byte_code; return byte_code;
} }
string Result(string format, uint32_t addr) string Result(string format, uint32_t* addr)
{ {
//d immediately succeeds the opcode //d immediately succeeds the opcode
//n immediate succeeds the opcode and the displacement (if present) //n immediate succeeds the opcode and the displacement (if present)
@ -4633,19 +4633,19 @@ namespace MSXHawk
{ {
size_t str_loc = format.find("nn"); size_t str_loc = format.find("nn");
bank_num = bank_offset = addr & 0xFFFF; bank_num = bank_offset = addr[0] & 0xFFFF;
bank_offset &= low_mask; bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift) & high_mask; bank_num = (bank_num >> bank_shift) & high_mask;
addr++; addr[0]++;
val_char_1 = replacer; val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]); sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
string val1(val_char_1, 2); string val1(val_char_1, 2);
bank_num = bank_offset = addr & 0xFFFF; bank_num = bank_offset = addr[0] & 0xFFFF;
bank_offset &= low_mask; bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
addr++; addr[0]++;
val_char_2 = replacer; val_char_2 = replacer;
sprintf_s(val_char_2, 5, "%02X", MemoryMap[bank_num][bank_offset]); sprintf_s(val_char_2, 5, "%02X", MemoryMap[bank_num][bank_offset]);
@ -4660,10 +4660,10 @@ namespace MSXHawk
{ {
size_t str_loc = format.find("n"); size_t str_loc = format.find("n");
bank_num = bank_offset = addr & 0xFFFF; bank_num = bank_offset = addr[0] & 0xFFFF;
bank_offset &= low_mask; bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
addr++; addr[0]++;
val_char_1 = replacer; val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]); sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
@ -4677,32 +4677,30 @@ namespace MSXHawk
{ {
size_t str_loc = format.find("+d"); size_t str_loc = format.find("+d");
bank_num = bank_offset = addr & 0xFFFF; bank_num = bank_offset = addr[0] & 0xFFFF;
bank_offset &= low_mask; bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
addr++; addr[0]++;
val_char_1 = replacer; val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%u", MemoryMap[bank_num][bank_offset]); sprintf_s(val_char_1, 5, "%+04d", (int8_t)MemoryMap[bank_num][bank_offset]);
string val1(val_char_1, 2); string val1(val_char_1, 4);
format.erase(str_loc + 1, 1); format.erase(str_loc, 2);
format.insert(str_loc + 1, val1); format.insert(str_loc, val1);
} }
if (format.find("d") != string::npos) if (format.find("d") != string::npos)
{ {
size_t str_loc = format.find("d"); size_t str_loc = format.find("d");
bank_num = bank_offset = addr & 0xFFFF; bank_num = bank_offset = addr[0] & 0xFFFF;
bank_offset &= low_mask; bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask; bank_num = (bank_num >> bank_shift)& high_mask;
addr++; addr[0]++;
int8_t temp = (int8_t)MemoryMap[bank_num][bank_offset];
val_char_1 = replacer; val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%d", temp); sprintf_s(val_char_1, 5, "%+04d", (int8_t)MemoryMap[bank_num][bank_offset]);
string val1(val_char_1, 3); string val1(val_char_1, 4);
format.erase(str_loc, 1); format.erase(str_loc, 1);
format.insert(str_loc, val1); format.insert(str_loc, val1);
@ -4796,7 +4794,8 @@ namespace MSXHawk
default: format = mnemonics[A]; break; default: format = mnemonics[A]; break;
} }
string temp = Result(format, addr); uint32_t* addr_ptr = &addr;
string temp = Result(format, addr_ptr);
addr += extra_inc; addr += extra_inc;