MSXHawk:Start loading roms
This commit is contained in:
parent
4ed402fc59
commit
5152e47b5e
|
@ -27,9 +27,17 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
||||||
Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
|
Array.Resize(ref RomData, ((RomData.Length / BankSize) + 1) * BankSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we want all ROMS to be multiples of 64K for easy memory mapping later
|
||||||
|
if (RomData.Length != 0x10000)
|
||||||
|
{
|
||||||
|
Array.Resize(ref RomData, 0x10000);
|
||||||
|
}
|
||||||
|
|
||||||
Bios = comm.CoreFileProvider.GetFirmware("MSX", "bios", true, "BIOS Not Found, Cannot Load");
|
Bios = comm.CoreFileProvider.GetFirmware("MSX", "bios", true, "BIOS Not Found, Cannot Load");
|
||||||
Basic = comm.CoreFileProvider.GetFirmware("MSX", "basic", true, "BIOS Not Found, Cannot Load");
|
Basic = comm.CoreFileProvider.GetFirmware("MSX", "basic", true, "BIOS Not Found, Cannot Load");
|
||||||
|
|
||||||
|
Basic = new byte[0x4000];
|
||||||
|
|
||||||
MSX_Pntr = LibMSX.MSX_create();
|
MSX_Pntr = LibMSX.MSX_create();
|
||||||
|
|
||||||
LibMSX.MSX_load_bios(MSX_Pntr, Bios, Basic);
|
LibMSX.MSX_load_bios(MSX_Pntr, Bios, Basic);
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace MSXHawk
|
||||||
MemMap.vdp_pntr = &vdp;
|
MemMap.vdp_pntr = &vdp;
|
||||||
MemMap.psg_pntr = &psg;
|
MemMap.psg_pntr = &psg;
|
||||||
cpu.mem_ctrl = &MemMap;
|
cpu.mem_ctrl = &MemMap;
|
||||||
vdp.INT_FLAG = &cpu.FlagI;
|
vdp.IRQ_PTR = &cpu.FlagI;
|
||||||
vdp.SHOW_BG = vdp.SHOW_SPRITES = true;
|
vdp.SHOW_BG = vdp.SHOW_SPRITES = true;
|
||||||
psg.Clock_Divider = 16;
|
psg.Clock_Divider = 16;
|
||||||
};
|
};
|
||||||
|
@ -63,8 +63,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
vdp.InterruptPendingSet(true);
|
vdp.InterruptPendingSet(true);
|
||||||
|
|
||||||
if (vdp.EnableInterrupts())
|
if (vdp.EnableInterrupts()) { cpu.FlagI = true; }
|
||||||
cpu.NonMaskableInterruptset(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t j = 0; j < vdp.IPeriod; j++)
|
for (uint32_t j = 0; j < vdp.IPeriod; j++)
|
||||||
|
|
|
@ -41,9 +41,10 @@ MSXHawk_EXPORT void MSX_load(MSXCore* p, uint8_t* rom_1, uint32_t size_1, uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance a frame
|
// advance a frame
|
||||||
MSXHawk_EXPORT void 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, bool render, bool sound)
|
||||||
{
|
{
|
||||||
p->FrameAdvance(ctrl1, ctrl2, render, sound);
|
p->FrameAdvance(ctrl1, ctrl2, render, sound);
|
||||||
|
return p->vdp.EnableInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
// send video data to external video provider
|
// send video data to external video provider
|
||||||
|
|
|
@ -16,12 +16,21 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
port &= 0xFF;
|
port &= 0xFF;
|
||||||
|
|
||||||
if (port >= 0xA0 && port < 0xC0) // VDP data/control ports
|
if (port == 0x98) // VDP
|
||||||
{
|
{
|
||||||
if ((port & 1) == 0)
|
return vdp_pntr->ReadData();
|
||||||
return vdp_pntr->ReadData();
|
}
|
||||||
else
|
else if (port == 0x99) // VDP
|
||||||
return vdp_pntr->ReadVdpStatus();
|
{
|
||||||
|
return vdp_pntr->ReadVdpStatus();
|
||||||
|
}
|
||||||
|
else if (port == 0xA1)
|
||||||
|
{
|
||||||
|
// not readable
|
||||||
|
}
|
||||||
|
else if (port == 0xA8)
|
||||||
|
{
|
||||||
|
return PortA8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
@ -80,7 +89,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
cpu_pntr->MemoryMap[i] = &ram[0xC000 + (0x400 * i)];
|
cpu_pntr->MemoryMap[i] = &ram[(0x400 * i)];
|
||||||
cpu_pntr->MemoryMapMask[i] = 0xFF;
|
cpu_pntr->MemoryMapMask[i] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +106,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
cpu_pntr->MemoryMap[i + 16] = &rom_1[04000 + (0x400 * i)];
|
cpu_pntr->MemoryMap[i + 16] = &rom_1[0x4000 + (0x400 * i)];
|
||||||
cpu_pntr->MemoryMapMask[i + 16] = 0;
|
cpu_pntr->MemoryMapMask[i + 16] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +114,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
cpu_pntr->MemoryMap[i + 16] = &rom_2[04000 + (0x400 * i)];
|
cpu_pntr->MemoryMap[i + 16] = &rom_2[0x4000 + (0x400 * i)];
|
||||||
cpu_pntr->MemoryMapMask[i + 16] = 0;
|
cpu_pntr->MemoryMapMask[i + 16] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +122,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
cpu_pntr->MemoryMap[i + 16] = &ram[0x8000 + (0x400 * i)];
|
cpu_pntr->MemoryMap[i + 16] = &ram[0x4000 + (0x400 * i)];
|
||||||
cpu_pntr->MemoryMapMask[i + 16] = 0xFF;
|
cpu_pntr->MemoryMapMask[i + 16] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,7 +155,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
cpu_pntr->MemoryMap[i + 32] = &ram[0x4000 + (0x400 * i)];
|
cpu_pntr->MemoryMap[i + 32] = &ram[0x8000 + (0x400 * i)];
|
||||||
cpu_pntr->MemoryMapMask[i + 32] = 0xFF;
|
cpu_pntr->MemoryMapMask[i + 32] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +188,7 @@ namespace MSXHawk
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
cpu_pntr->MemoryMap[i + 48] = &ram[(0x400 * i)];
|
cpu_pntr->MemoryMap[i + 48] = &ram[0xC000 + (0x400 * i)];
|
||||||
cpu_pntr->MemoryMapMask[i + 48] = 0xFF;
|
cpu_pntr->MemoryMapMask[i + 48] = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ namespace MSXHawk
|
||||||
*saver = reg_FFFE; saver++;
|
*saver = reg_FFFE; saver++;
|
||||||
*saver = reg_FFFF; saver++;
|
*saver = reg_FFFF; saver++;
|
||||||
|
|
||||||
std::memcpy(saver, &ram, 0x2000); saver += 0x2000;
|
std::memcpy(saver, &ram, 0x10000); saver += 0x10000;
|
||||||
std::memcpy(saver, &cart_ram, 0x8000); saver += 0x8000;
|
std::memcpy(saver, &cart_ram, 0x8000); saver += 0x8000;
|
||||||
|
|
||||||
return saver;
|
return saver;
|
||||||
|
|
|
@ -17,8 +17,8 @@ namespace MSXHawk
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// external pointers to CPU
|
bool* IRQ_PTR = nullptr;
|
||||||
bool* INT_FLAG = nullptr;
|
|
||||||
// external flags to display background or sprites
|
// external flags to display background or sprites
|
||||||
bool SHOW_BG, SHOW_SPRITES;
|
bool SHOW_BG, SHOW_SPRITES;
|
||||||
bool SpriteLimit;
|
bool SpriteLimit;
|
||||||
|
@ -35,8 +35,7 @@ namespace MSXHawk
|
||||||
uint8_t Registers[8] = {};
|
uint8_t Registers[8] = {};
|
||||||
uint8_t VRAM[0x4000]; //16kb video RAM
|
uint8_t VRAM[0x4000]; //16kb video RAM
|
||||||
|
|
||||||
int32_t ScanLine;
|
int32_t ScanLine;
|
||||||
uint32_t IPeriod = 228;
|
|
||||||
uint32_t VdpAddress;
|
uint32_t VdpAddress;
|
||||||
uint32_t TmsMode;
|
uint32_t TmsMode;
|
||||||
uint32_t ColorTableBase;
|
uint32_t ColorTableBase;
|
||||||
|
@ -47,7 +46,9 @@ namespace MSXHawk
|
||||||
|
|
||||||
uint32_t FrameBuffer[192 * 256] = {};
|
uint32_t FrameBuffer[192 * 256] = {};
|
||||||
|
|
||||||
|
// constants after load, not stated
|
||||||
uint32_t BackgroundColor = 0;
|
uint32_t BackgroundColor = 0;
|
||||||
|
uint32_t IPeriod = 228;
|
||||||
|
|
||||||
uint32_t PaletteTMS9918[16] =
|
uint32_t PaletteTMS9918[16] =
|
||||||
{
|
{
|
||||||
|
@ -134,7 +135,7 @@ namespace MSXHawk
|
||||||
break;
|
break;
|
||||||
case 1: // Mode Control Register 2
|
case 1: // Mode Control Register 2
|
||||||
CheckVideoMode();
|
CheckVideoMode();
|
||||||
INT_FLAG[0] = (EnableInterrupts() && InterruptPendingGet());
|
IRQ_PTR[0] = (EnableInterrupts() && InterruptPendingGet());
|
||||||
break;
|
break;
|
||||||
case 2: // Name Table Base Address
|
case 2: // Name Table Base Address
|
||||||
TmsPatternNameTableBase = (Registers[2] << 10) & 0x3C00;
|
TmsPatternNameTableBase = (Registers[2] << 10) & 0x3C00;
|
||||||
|
@ -159,7 +160,7 @@ namespace MSXHawk
|
||||||
VdpWaitingForLatchByte = true;
|
VdpWaitingForLatchByte = true;
|
||||||
uint8_t returnValue = StatusByte;
|
uint8_t returnValue = StatusByte;
|
||||||
StatusByte &= 0x1F;
|
StatusByte &= 0x1F;
|
||||||
INT_FLAG[0] = false;
|
IRQ_PTR[0] = false;
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
@ -508,13 +509,83 @@ namespace MSXHawk
|
||||||
|
|
||||||
uint8_t* SaveState(uint8_t* saver)
|
uint8_t* SaveState(uint8_t* saver)
|
||||||
{
|
{
|
||||||
|
*saver = (uint8_t)(VdpWaitingForLatchInt ? 1 : 0); saver++;
|
||||||
|
*saver = (uint8_t)(VdpWaitingForLatchByte ? 1 : 0); saver++;
|
||||||
|
*saver = (uint8_t)(VIntPending ? 1 : 0); saver++;
|
||||||
|
*saver = (uint8_t)(HIntPending ? 1 : 0); saver++;
|
||||||
|
|
||||||
|
*saver = StatusByte; saver++;
|
||||||
|
*saver = VdpLatch; saver++;
|
||||||
|
*saver = VdpBuffer; saver++;
|
||||||
|
|
||||||
|
std::memcpy(saver, &Registers, 8); saver += 8;
|
||||||
|
std::memcpy(saver, &VRAM, 0x4000); saver += 0x4000;
|
||||||
|
|
||||||
|
*saver = (uint8_t)(ScanLine & 0xFF); saver++; *saver = (uint8_t)((ScanLine >> 8) & 0xFF); saver++;
|
||||||
|
*saver = (uint8_t)((ScanLine >> 16) & 0xFF); saver++; *saver = (uint8_t)((ScanLine >> 24) & 0xFF); saver++;
|
||||||
|
|
||||||
|
*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++;
|
||||||
|
|
||||||
|
*saver = (uint8_t)(PatternGeneratorBase & 0xFF); saver++; *saver = (uint8_t)((PatternGeneratorBase >> 8) & 0xFF); saver++;
|
||||||
|
*saver = (uint8_t)((PatternGeneratorBase >> 16) & 0xFF); saver++; *saver = (uint8_t)((PatternGeneratorBase >> 24) & 0xFF); saver++;
|
||||||
|
|
||||||
|
*saver = (uint8_t)(SpritePatternGeneratorBase & 0xFF); saver++; *saver = (uint8_t)((SpritePatternGeneratorBase >> 8) & 0xFF); saver++;
|
||||||
|
*saver = (uint8_t)((SpritePatternGeneratorBase >> 16) & 0xFF); saver++; *saver = (uint8_t)((SpritePatternGeneratorBase >> 24) & 0xFF); saver++;
|
||||||
|
|
||||||
|
*saver = (uint8_t)(TmsPatternNameTableBase & 0xFF); saver++; *saver = (uint8_t)((TmsPatternNameTableBase >> 8) & 0xFF); saver++;
|
||||||
|
*saver = (uint8_t)((TmsPatternNameTableBase >> 16) & 0xFF); saver++; *saver = (uint8_t)((TmsPatternNameTableBase >> 24) & 0xFF); saver++;
|
||||||
|
|
||||||
|
*saver = (uint8_t)(TmsSpriteAttributeBase & 0xFF); saver++; *saver = (uint8_t)((TmsSpriteAttributeBase >> 8) & 0xFF); saver++;
|
||||||
|
*saver = (uint8_t)((TmsSpriteAttributeBase >> 16) & 0xFF); saver++; *saver = (uint8_t)((TmsSpriteAttributeBase >> 24) & 0xFF); saver++;
|
||||||
|
|
||||||
return saver;
|
return saver;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* LoadState(uint8_t* loader)
|
uint8_t* LoadState(uint8_t* loader)
|
||||||
{
|
{
|
||||||
|
VdpWaitingForLatchInt = *loader == 1; loader++;
|
||||||
|
VdpWaitingForLatchByte = *loader == 1; loader++;
|
||||||
|
VIntPending = *loader == 1; loader++;
|
||||||
|
HIntPending = *loader == 1; loader++;
|
||||||
|
|
||||||
|
StatusByte = *loader; loader++;
|
||||||
|
VdpLatch = *loader; loader++;
|
||||||
|
VdpBuffer = *loader; loader++;
|
||||||
|
|
||||||
|
std::memcpy(&Registers, loader, 8); loader += 8;
|
||||||
|
std::memcpy(&VRAM, loader, 0x4000); loader += 0x4000;
|
||||||
|
|
||||||
|
ScanLine = *loader; loader++; ScanLine |= (*loader << 8); loader++;
|
||||||
|
ScanLine |= (*loader << 16); loader++; ScanLine |= (*loader << 24); loader++;
|
||||||
|
|
||||||
|
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++;
|
||||||
|
|
||||||
|
PatternGeneratorBase = *loader; loader++; PatternGeneratorBase |= (*loader << 8); loader++;
|
||||||
|
PatternGeneratorBase |= (*loader << 16); loader++; PatternGeneratorBase |= (*loader << 24); loader++;
|
||||||
|
|
||||||
|
SpritePatternGeneratorBase = *loader; loader++; SpritePatternGeneratorBase |= (*loader << 8); loader++;
|
||||||
|
SpritePatternGeneratorBase |= (*loader << 16); loader++; SpritePatternGeneratorBase |= (*loader << 24); loader++;
|
||||||
|
|
||||||
|
TmsPatternNameTableBase = *loader; loader++; TmsPatternNameTableBase |= (*loader << 8); loader++;
|
||||||
|
TmsPatternNameTableBase |= (*loader << 16); loader++; TmsPatternNameTableBase |= (*loader << 24); loader++;
|
||||||
|
|
||||||
|
TmsSpriteAttributeBase = *loader; loader++; TmsSpriteAttributeBase |= (*loader << 8); loader++;
|
||||||
|
TmsSpriteAttributeBase |= (*loader << 16); loader++; TmsSpriteAttributeBase |= (*loader << 24); loader++;
|
||||||
|
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -474,7 +474,7 @@ namespace MSXHawk
|
||||||
inline bool NonMaskableInterruptget() { return nonMaskableInterrupt; };
|
inline bool NonMaskableInterruptget() { return nonMaskableInterrupt; };
|
||||||
inline void NonMaskableInterruptset(bool value)
|
inline void NonMaskableInterruptset(bool value)
|
||||||
{
|
{
|
||||||
if (value && !nonMaskableInterrupt) nonMaskableInterruptPending = true;
|
if (value && !nonMaskableInterrupt) { nonMaskableInterruptPending = true; }
|
||||||
nonMaskableInterrupt = value;
|
nonMaskableInterrupt = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue