MSXHawk: Refactor and start work on SCC
This commit is contained in:
parent
0cd769222b
commit
f32961001e
Binary file not shown.
|
@ -1246,7 +1246,7 @@ D2560E3B7D4E137BDBBA8426030D2F44 Rotors (1984)(ASCII)(JP) MSX JP
|
|||
324E6E87465ECF49AF0C613A87467E10 R-Type v2 (1988)(IREM)(JP)[a] MSX JP
|
||||
0F03B2306E11C5182351DB3B7AA30533 Saimazoom (2005)(Karoshi)[RK708] MSX
|
||||
B0D4FB9A9A88FB65C12D2B567B567171 Saimazoom (2005)(Karoshi)[RK708EN] MSX
|
||||
EC869B375D7517A7BA6161B10F5DEE06 Salamander - Operation X (1987)(Konami)(JP)[RC-758] MSX JP
|
||||
EC869B375D7517A7BA6161B10F5DEE06 Salamander - Operation X (1987)(Konami)(JP)[RC-758] MSX mapper=2 JP
|
||||
59767E46E226F5C69469694817839189 Salamander - Operation X (1987)(Konami)(JP)[SCC][RC-758] MSX JP
|
||||
0DA25C28FCE818D6FA7231CB6A914783 Salamander - Operation X (1988)(Zemina)(KR)[RC-758] MSX KR
|
||||
305BF5B78B03D28B92DEF20AD89A4E4B Sangokushi. Romance of Three Kingdoms (1986)(Koei)(JP) MSX JP
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace MSXHawk
|
|||
uint32_t noise = 0x1;
|
||||
|
||||
int32_t old_sample;
|
||||
int32_t current_sample;
|
||||
|
||||
// non stated if only on frame boundaries
|
||||
bool sound_out_A;
|
||||
|
@ -51,11 +52,6 @@ namespace MSXHawk
|
|||
|
||||
uint8_t Clock_Divider;
|
||||
|
||||
int32_t current_sample;
|
||||
uint32_t sampleclock;
|
||||
uint32_t num_samples;
|
||||
int32_t samples[9000] = {};
|
||||
|
||||
void Reset()
|
||||
{
|
||||
clock_A = clock_B = clock_C = 0x1000;
|
||||
|
@ -168,7 +164,7 @@ namespace MSXHawk
|
|||
}
|
||||
}
|
||||
|
||||
void generate_sound()
|
||||
bool generate_sound()
|
||||
{
|
||||
// there are 8 cpu cycles for every psg cycle
|
||||
clock_A--;
|
||||
|
@ -282,13 +278,9 @@ namespace MSXHawk
|
|||
|
||||
current_sample *= 2;
|
||||
|
||||
if ((current_sample != old_sample) && (num_samples < 4500))
|
||||
{
|
||||
samples[num_samples * 2] = sampleclock;
|
||||
samples[num_samples * 2 + 1] = current_sample - old_sample;
|
||||
num_samples++;
|
||||
old_sample = current_sample;
|
||||
}
|
||||
if (current_sample != old_sample) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "Z80A.h"
|
||||
#include "AY_3_8910.h"
|
||||
#include "SCC.h"
|
||||
#include "TMS9918A.h"
|
||||
#include "Memory.h"
|
||||
|
||||
|
@ -18,19 +19,31 @@ namespace MSXHawk
|
|||
MemMap.cpu_pntr = &cpu;
|
||||
MemMap.vdp_pntr = &vdp;
|
||||
MemMap.psg_pntr = &psg;
|
||||
MemMap.SCC_1_pntr = &SCC_1;
|
||||
MemMap.SCC_2_pntr = &SCC_2;
|
||||
cpu.mem_ctrl = &MemMap;
|
||||
vdp.IRQ_PTR = &cpu.FlagI;
|
||||
vdp.SHOW_BG = vdp.SHOW_SPRITES = true;
|
||||
psg.Clock_Divider = 16;
|
||||
sl_case = 0;
|
||||
SCC_1.page_pointer = &MemMap.SCC_1_page[0];
|
||||
SCC_2.page_pointer = &MemMap.SCC_2_page[0];
|
||||
};
|
||||
|
||||
TMS9918A vdp;
|
||||
Z80A cpu;
|
||||
AY_3_8910 psg;
|
||||
SCC SCC_1;
|
||||
SCC SCC_2;
|
||||
MemoryManager MemMap;
|
||||
|
||||
uint8_t sl_case = 0;
|
||||
bool new_sample = false;
|
||||
|
||||
// combine audio from all sources
|
||||
uint32_t sampleclock;
|
||||
uint32_t num_samples;
|
||||
int32_t samples[9000] = {};
|
||||
|
||||
void Load_BIOS(uint8_t* bios, uint8_t* basic)
|
||||
{
|
||||
|
@ -65,8 +78,8 @@ namespace MSXHawk
|
|||
uint32_t scanlinesPerFrame = 262;
|
||||
vdp.SpriteLimit = true;
|
||||
|
||||
psg.num_samples = 0;
|
||||
psg.sampleclock = 0;
|
||||
num_samples = 0;
|
||||
sampleclock = 0;
|
||||
|
||||
for (uint32_t i = 0; i < scanlinesPerFrame; i++)
|
||||
{
|
||||
|
@ -87,55 +100,76 @@ namespace MSXHawk
|
|||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
cpu.ExecuteOne(16);
|
||||
psg.sampleclock+=16;
|
||||
psg.generate_sound();
|
||||
sampleclock+=16;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
}
|
||||
cpu.ExecuteOne(4);
|
||||
psg.sampleclock += 4;
|
||||
sampleclock += 4;
|
||||
sl_case = 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cpu.ExecuteOne(12);
|
||||
psg.sampleclock += 12;
|
||||
psg.generate_sound();
|
||||
sampleclock += 12;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
cpu.ExecuteOne(16);
|
||||
psg.sampleclock += 16;
|
||||
psg.generate_sound();
|
||||
sampleclock += 16;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
}
|
||||
cpu.ExecuteOne(8);
|
||||
psg.sampleclock += 8;
|
||||
sampleclock += 8;
|
||||
sl_case = 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cpu.ExecuteOne(8);
|
||||
psg.sampleclock += 8;
|
||||
psg.generate_sound();
|
||||
sampleclock += 8;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
cpu.ExecuteOne(16);
|
||||
psg.sampleclock += 16;
|
||||
psg.generate_sound();
|
||||
sampleclock += 16;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
}
|
||||
cpu.ExecuteOne(12);
|
||||
psg.sampleclock += 12;
|
||||
sampleclock += 12;
|
||||
sl_case = 3;
|
||||
break;
|
||||
case 3:
|
||||
cpu.ExecuteOne(4);
|
||||
psg.sampleclock += 4;
|
||||
psg.generate_sound();
|
||||
sampleclock += 4;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
cpu.ExecuteOne(16);
|
||||
psg.sampleclock += 16;
|
||||
psg.generate_sound();
|
||||
sampleclock += 16;
|
||||
new_sample |= psg.generate_sound();
|
||||
new_sample |= SCC_1.generate_sound();
|
||||
//new_sample |= SCC_2.generate_sound();
|
||||
if (new_sample) { Add_Audio_Sample(); }
|
||||
}
|
||||
sl_case = 0;
|
||||
break;
|
||||
|
@ -145,6 +179,23 @@ namespace MSXHawk
|
|||
return MemMap.lagged;
|
||||
}
|
||||
|
||||
void Add_Audio_Sample()
|
||||
{
|
||||
if (num_samples < 4500)
|
||||
{
|
||||
samples[num_samples * 2] = sampleclock;
|
||||
samples[num_samples * 2 + 1] = psg.current_sample - psg.old_sample;
|
||||
samples[num_samples * 2 + 1] += SCC_1.current_sample - SCC_1.old_sample;
|
||||
//samples[num_samples * 2 + 1] = SCC_2.current_sample - SCC_2.old_sample;
|
||||
num_samples++;
|
||||
psg.old_sample = psg.current_sample;
|
||||
SCC_1.old_sample = SCC_1.current_sample;
|
||||
//SCC_2.old_sample = SCC_2.current_sample;
|
||||
|
||||
new_sample = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GetVideo(uint32_t* dest)
|
||||
{
|
||||
uint32_t* src = vdp.FrameBuffer;
|
||||
|
@ -155,13 +206,13 @@ namespace MSXHawk
|
|||
|
||||
uint32_t GetAudio(int32_t* dest, int32_t* n_samp)
|
||||
{
|
||||
int32_t* src = psg.samples;
|
||||
int32_t* src = samples;
|
||||
int32_t* dst = dest;
|
||||
|
||||
std::memcpy(dst, src, sizeof int32_t * psg.num_samples * 2);
|
||||
n_samp[0] = psg.num_samples;
|
||||
std::memcpy(dst, src, sizeof int32_t * num_samples * 2);
|
||||
n_samp[0] = num_samples;
|
||||
|
||||
return psg.sampleclock;
|
||||
return sampleclock;
|
||||
}
|
||||
|
||||
int GetMessageLength()
|
||||
|
@ -182,8 +233,11 @@ namespace MSXHawk
|
|||
saver = vdp.SaveState(saver);
|
||||
saver = cpu.SaveState(saver);
|
||||
saver = psg.SaveState(saver);
|
||||
saver = SCC_1.SaveState(saver);
|
||||
saver = SCC_2.SaveState(saver);
|
||||
saver = MemMap.SaveState(saver);
|
||||
|
||||
*saver = (uint8_t)(new_sample ? 1 : 0); saver++;
|
||||
*saver = sl_case; saver++;
|
||||
}
|
||||
|
||||
|
@ -192,8 +246,11 @@ namespace MSXHawk
|
|||
loader = vdp.LoadState(loader);
|
||||
loader = cpu.LoadState(loader);
|
||||
loader = psg.LoadState(loader);
|
||||
loader = SCC_1.LoadState(loader);
|
||||
loader = SCC_2.LoadState(loader);
|
||||
loader = MemMap.LoadState(loader);
|
||||
|
||||
new_sample = *loader == 1; loader++;
|
||||
sl_case = *loader; loader++;
|
||||
}
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Core.h" />
|
||||
<ClInclude Include="SCC.h" />
|
||||
<ClInclude Include="Memory.h" />
|
||||
<ClInclude Include="TMS9918A.h" />
|
||||
<ClInclude Include="AY_3_8910.h" />
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Z80A.h"
|
||||
#include "TMS9918A.h"
|
||||
#include "AY_3_8910.h"
|
||||
#include "SCC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -300,6 +301,72 @@ namespace MSXHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (rom_mapper_1 == 2) // konami mapper with SCC
|
||||
{
|
||||
if (base_addr == 0)
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
if (SCC_1_enabled)
|
||||
{
|
||||
return &unmapped[0];
|
||||
}
|
||||
return &rom_1[rom1_konami_page_2 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_1[rom1_konami_page_3 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
else if (base_addr == 0x4000)
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
return &rom_1[(0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_1[rom1_konami_page_1 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
else if (base_addr == 0x8000)
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
if (SCC_1_enabled)
|
||||
{
|
||||
if (segment < 6)
|
||||
{
|
||||
return &unmapped[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return &SCC_1_page[0];
|
||||
}
|
||||
}
|
||||
return &rom_1[rom1_konami_page_2 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_1[rom1_konami_page_3 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
return &rom_1[(0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_1[rom1_konami_page_1 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return &unmapped[0];
|
||||
|
@ -363,9 +430,126 @@ namespace MSXHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (rom_mapper_2 == 2) // konami mapper with SCC
|
||||
{
|
||||
if (base_addr == 0)
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
if (SCC_2_enabled)
|
||||
{
|
||||
return &unmapped[0];
|
||||
}
|
||||
return &rom_2[rom2_konami_page_2 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_2[rom2_konami_page_3 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
else if (base_addr == 0x4000)
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
return &rom_2[(0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_2[rom2_konami_page_1 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
else if (base_addr == 0x8000)
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
if (SCC_2_enabled)
|
||||
{
|
||||
if (segment < 6)
|
||||
{
|
||||
return &unmapped[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return &SCC_2_page[0];
|
||||
}
|
||||
}
|
||||
return &rom_2[rom2_konami_page_2 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_2[rom2_konami_page_3 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (segment < 8)
|
||||
{
|
||||
return &rom_2[(0x400 * segment)];
|
||||
}
|
||||
else
|
||||
{
|
||||
segment -= 8;
|
||||
return &rom_2[rom2_konami_page_1 * 0x2000 + (0x400 * segment)];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return &unmapped[0];
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::MemoryWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
// Konami addresses without SCC
|
||||
if (rom_mapper_1 == 1)
|
||||
{
|
||||
if (addr >= 0x6000 && addr < 0x8000 && slot_1_has_rom == 1) { rom1_konami_page_1 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
if (addr >= 0x8000 && addr < 0xA000 && slot_2_has_rom == 1) { rom1_konami_page_2 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
if (addr >= 0xA000 && addr < 0xC000 && slot_2_has_rom == 1) { rom1_konami_page_3 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
}
|
||||
if (rom_mapper_2 == 1)
|
||||
{
|
||||
if (addr >= 0x6000 && addr < 0x8000 && slot_1_has_rom == 2) { rom2_konami_page_1 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
if (addr >= 0x8000 && addr < 0xA000 && slot_2_has_rom == 2) { rom2_konami_page_2 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
if (addr >= 0xA000 && addr < 0xC000 && slot_2_has_rom == 2) { rom2_konami_page_3 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
}
|
||||
|
||||
// Konami addresses with SCC
|
||||
if (rom_mapper_1 == 2)
|
||||
{
|
||||
if (addr >= 0x5000 && addr < 0x5800 && slot_1_has_rom == 1) { rom1_konami_page_0 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
if (addr >= 0x7000 && addr < 0x7800 && slot_1_has_rom == 1) { rom1_konami_page_1 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
if (addr >= 0x9000 && addr < 0x9800 && slot_2_has_rom == 1)
|
||||
{
|
||||
if ((value & 0xFF) == 0x3F) { SCC_1_enabled = true; }
|
||||
else { SCC_1_enabled = false; }
|
||||
rom1_konami_page_2 = (uint8_t)(value & rom_size_1); remap();
|
||||
}
|
||||
if (addr >= 0x9800 && addr < 0xA000 && slot_2_has_rom == 1 && SCC_1_enabled)
|
||||
{
|
||||
SCC_1_pntr->WriteReg(value & 0xFF);
|
||||
}
|
||||
if (addr >= 0xB000 && addr < 0xB800 && slot_2_has_rom == 1) { rom1_konami_page_3 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
}
|
||||
if (rom_mapper_2 == 2)
|
||||
{
|
||||
if (addr >= 0x5000 && addr < 0x5800 && slot_1_has_rom == 2) { rom2_konami_page_0 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
if (addr >= 0x7000 && addr < 0x7800 && slot_1_has_rom == 2) { rom2_konami_page_1 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
if (addr >= 0x9000 && addr < 0x9800 && slot_2_has_rom == 2)
|
||||
{
|
||||
if ((value & 0xFF) == 0x3F) { SCC_2_enabled = true; }
|
||||
else { SCC_2_enabled = false; }
|
||||
rom2_konami_page_2 = (uint8_t)(value & rom_size_2); remap();
|
||||
}
|
||||
if (addr >= 0x9800 && addr < 0xA000 && slot_2_has_rom == 1 && SCC_2_enabled)
|
||||
{
|
||||
SCC_2_pntr->WriteReg(value & 0xFF);
|
||||
}
|
||||
if (addr >= 0xB000 && addr < 0xB800 && slot_2_has_rom == 2) { rom2_konami_page_3 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace MSXHawk
|
|||
class Z80A;
|
||||
class TMS9918A;
|
||||
class AY_3_8910;
|
||||
class SCC;
|
||||
|
||||
class MemoryManager
|
||||
{
|
||||
|
@ -17,6 +18,8 @@ namespace MSXHawk
|
|||
|
||||
TMS9918A* vdp_pntr = nullptr;
|
||||
AY_3_8910* psg_pntr = nullptr;
|
||||
SCC* SCC_1_pntr = nullptr;
|
||||
SCC* SCC_2_pntr = nullptr;
|
||||
Z80A* cpu_pntr = nullptr;
|
||||
uint8_t* rom_1 = nullptr;
|
||||
uint8_t* rom_2 = nullptr;
|
||||
|
@ -44,6 +47,16 @@ namespace MSXHawk
|
|||
uint8_t ram[0x10000] = {};
|
||||
uint8_t cart_ram[0x8000] = {};
|
||||
uint8_t unmapped[0x400] = {};
|
||||
uint8_t SCC_1_page[0x400] = {};
|
||||
uint8_t SCC_2_page[0x400] = {};
|
||||
|
||||
// mapper support and variables
|
||||
uint8_t slot_0_has_rom, slot_1_has_rom, slot_2_has_rom, slot_3_has_rom;
|
||||
uint8_t rom1_konami_page_0, rom1_konami_page_1, rom1_konami_page_2, rom1_konami_page_3;
|
||||
uint8_t rom2_konami_page_0, rom2_konami_page_1, rom2_konami_page_2, rom2_konami_page_3;
|
||||
|
||||
bool SCC_1_enabled = false;
|
||||
bool SCC_2_enabled = false;
|
||||
|
||||
MemoryManager()
|
||||
{
|
||||
|
@ -59,6 +72,8 @@ namespace MSXHawk
|
|||
|
||||
void HardwareWrite(uint32_t addr, uint8_t value);
|
||||
|
||||
void MemoryWrite(uint32_t addr, uint8_t value);
|
||||
|
||||
void remap();
|
||||
|
||||
uint8_t* remap_rom1(uint32_t, uint32_t);
|
||||
|
@ -83,20 +98,24 @@ namespace MSXHawk
|
|||
memcpy(rom_1, ext_rom_1, ext_rom_size_1);
|
||||
memcpy(rom_2, ext_rom_2, ext_rom_size_2);
|
||||
|
||||
rom_size_1 = ext_rom_size_1 / 0x400 - 1;
|
||||
rom_mapper_1 = ext_rom_mapper_1;
|
||||
|
||||
rom_size_2 = ext_rom_size_2 / 0x400 - 1;
|
||||
rom_mapper_2 = ext_rom_mapper_2;
|
||||
|
||||
if (rom_mapper_1 == 1)
|
||||
// page size 0x2000 for konami games
|
||||
if (rom_mapper_1 == 1 || rom_mapper_1 == 2) { rom_size_1 = ext_rom_size_1 / 0x2000 - 1; }
|
||||
if (rom_mapper_2 == 1 || rom_mapper_2 == 2) { rom_size_2 = ext_rom_size_2 / 0x2000 - 1; }
|
||||
|
||||
|
||||
if (rom_mapper_1 == 1 || rom_mapper_1 == 2)
|
||||
{
|
||||
rom1_konami_page_0 = 0;
|
||||
rom1_konami_page_1 = 1;
|
||||
rom1_konami_page_2 = 2;
|
||||
rom1_konami_page_3 = 3;
|
||||
}
|
||||
if (rom_mapper_2 == 1)
|
||||
if (rom_mapper_2 == 1 || rom_mapper_2 == 2)
|
||||
{
|
||||
rom2_konami_page_0 = 0;
|
||||
rom2_konami_page_1 = 1;
|
||||
rom2_konami_page_2 = 2;
|
||||
rom2_konami_page_3 = 3;
|
||||
|
@ -108,28 +127,6 @@ namespace MSXHawk
|
|||
remap();
|
||||
}
|
||||
|
||||
// mapper support and variables
|
||||
uint8_t slot_0_has_rom, slot_1_has_rom, slot_2_has_rom, slot_3_has_rom;
|
||||
uint8_t rom1_konami_page_1, rom1_konami_page_2, rom1_konami_page_3;
|
||||
uint8_t rom2_konami_page_1, rom2_konami_page_2, rom2_konami_page_3;
|
||||
|
||||
void MemoryWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
if (rom_mapper_1 == 1)
|
||||
{
|
||||
if (addr >= 0x6000 && addr < 0x8000 && slot_1_has_rom == 1) { rom1_konami_page_1 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
if (addr >= 0x8000 && addr < 0xA000 && slot_2_has_rom == 1) { rom1_konami_page_2 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
if (addr >= 0xA000 && addr < 0xC000 && slot_2_has_rom == 1) { rom1_konami_page_3 = (uint8_t)(value & rom_size_1); remap(); }
|
||||
}
|
||||
|
||||
if (rom_mapper_2 == 1)
|
||||
{
|
||||
if (addr >= 0x6000 && addr < 0x8000 && slot_1_has_rom == 2) { rom2_konami_page_1 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
if (addr >= 0x8000 && addr < 0xA000 && slot_2_has_rom == 2) { rom2_konami_page_2 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
if (addr >= 0xA000 && addr < 0xC000 && slot_2_has_rom == 2) { rom2_konami_page_3 = (uint8_t)(value & rom_size_2); remap(); }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region State Save / Load
|
||||
|
||||
uint8_t* SaveState(uint8_t* saver)
|
||||
|
@ -137,6 +134,8 @@ namespace MSXHawk
|
|||
*saver = (uint8_t)(PortDEEnabled ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(lagged ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(start_pressed ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(SCC_1_enabled ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(SCC_2_enabled ? 1 : 0); saver++;
|
||||
|
||||
*saver = kb_rows_sel; saver++;
|
||||
*saver = PortA8; saver++;
|
||||
|
@ -150,15 +149,19 @@ namespace MSXHawk
|
|||
*saver = slot_2_has_rom; saver++;
|
||||
*saver = slot_3_has_rom; saver++;
|
||||
|
||||
*saver = rom1_konami_page_0; saver++;
|
||||
*saver = rom1_konami_page_1; saver++;
|
||||
*saver = rom1_konami_page_2; saver++;
|
||||
*saver = rom1_konami_page_3; saver++;
|
||||
*saver = rom2_konami_page_0; saver++;
|
||||
*saver = rom2_konami_page_1; saver++;
|
||||
*saver = rom2_konami_page_2; saver++;
|
||||
*saver = rom2_konami_page_3; saver++;
|
||||
|
||||
std::memcpy(saver, &ram, 0x10000); saver += 0x10000;
|
||||
std::memcpy(saver, &cart_ram, 0x8000); saver += 0x8000;
|
||||
std::memcpy(saver, &SCC_1_page, 0x400); saver += 0x400;
|
||||
std::memcpy(saver, &SCC_2_page, 0x400); saver += 0x400;
|
||||
|
||||
return saver;
|
||||
}
|
||||
|
@ -168,6 +171,8 @@ namespace MSXHawk
|
|||
PortDEEnabled = *loader == 1; loader++;
|
||||
lagged = *loader == 1; loader++;
|
||||
start_pressed = *loader == 1; loader++;
|
||||
SCC_1_enabled = *loader == 1; loader++;
|
||||
SCC_2_enabled = *loader == 1; loader++;
|
||||
|
||||
kb_rows_sel = *loader; loader++;
|
||||
PortA8 = *loader; loader++;
|
||||
|
@ -181,15 +186,19 @@ namespace MSXHawk
|
|||
slot_2_has_rom = *loader; loader++;
|
||||
slot_3_has_rom = *loader; loader++;
|
||||
|
||||
rom1_konami_page_0 = *loader; loader++;
|
||||
rom1_konami_page_1 = *loader; loader++;
|
||||
rom1_konami_page_2 = *loader; loader++;
|
||||
rom1_konami_page_3 = *loader; loader++;
|
||||
rom2_konami_page_0 = *loader; loader++;
|
||||
rom2_konami_page_1 = *loader; loader++;
|
||||
rom2_konami_page_2 = *loader; loader++;
|
||||
rom2_konami_page_3 = *loader; loader++;
|
||||
|
||||
std::memcpy(&ram, loader, 0x10000); loader += 0x10000;
|
||||
std::memcpy(&cart_ram, loader, 0x8000); loader += 0x8000;
|
||||
std::memcpy(&SCC_1_page, loader, 0x400); loader += 0x400;
|
||||
std::memcpy(&SCC_2_page, loader, 0x400); loader += 0x400;
|
||||
|
||||
remap();
|
||||
|
||||
|
|
|
@ -0,0 +1,437 @@
|
|||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace MSXHawk
|
||||
{
|
||||
class SCC
|
||||
{
|
||||
public:
|
||||
|
||||
#pragma region SCC
|
||||
|
||||
SCC()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
uint8_t* page_pointer = nullptr;
|
||||
|
||||
bool A_on, B_on, C_on;
|
||||
bool A_up, B_up, C_up;
|
||||
bool A_noise, B_noise, C_noise;
|
||||
bool env_vol_A, env_vol_B, env_vol_C;
|
||||
|
||||
uint8_t env_shape;
|
||||
uint8_t port_sel;
|
||||
uint8_t vol_A, vol_B, vol_C;
|
||||
uint8_t Register[16] = {};
|
||||
|
||||
uint32_t psg_clock;
|
||||
uint32_t sq_per_A, sq_per_B, sq_per_C;
|
||||
uint32_t clock_A, clock_B, clock_C;
|
||||
|
||||
uint32_t env_per;
|
||||
uint32_t env_clock;
|
||||
|
||||
int32_t env_E;
|
||||
int32_t E_up_down;
|
||||
|
||||
uint32_t noise_clock;
|
||||
uint32_t noise_per;
|
||||
uint32_t noise = 0x1;
|
||||
|
||||
int32_t old_sample;
|
||||
int32_t current_sample;
|
||||
|
||||
// non stated if only on frame boundaries
|
||||
bool sound_out_A;
|
||||
bool sound_out_B;
|
||||
bool sound_out_C;
|
||||
|
||||
uint8_t Clock_Divider;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
clock_A = clock_B = clock_C = 0x1000;
|
||||
noise_clock = 0x20;
|
||||
port_sel = 0;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
Register[i] = 0x0;
|
||||
}
|
||||
sync_psg_state();
|
||||
}
|
||||
|
||||
short Sample()
|
||||
{
|
||||
return current_sample;
|
||||
}
|
||||
|
||||
const uint32_t VolumeTable[16] =
|
||||
{
|
||||
0x0000, 0x0055, 0x0079, 0x00AB, 0x00F1, 0x0155, 0x01E3, 0x02AA,
|
||||
0x03C5, 0x0555, 0x078B, 0x0AAB, 0x0F16, 0x1555, 0x1E2B, 0x2AAA
|
||||
};
|
||||
|
||||
// returns do not occur in this iplementation, they come from the core
|
||||
uint8_t ReadReg()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void sync_psg_state()
|
||||
{
|
||||
sq_per_A = (Register[0] & 0xFF) | (((Register[1] & 0xF) << 8));
|
||||
if (sq_per_A == 0)
|
||||
{
|
||||
sq_per_A = 0x1000;
|
||||
}
|
||||
|
||||
sq_per_B = (Register[2] & 0xFF) | (((Register[3] & 0xF) << 8));
|
||||
if (sq_per_B == 0)
|
||||
{
|
||||
sq_per_B = 0x1000;
|
||||
}
|
||||
|
||||
sq_per_C = (Register[4] & 0xFF) | (((Register[5] & 0xF) << 8));
|
||||
if (sq_per_C == 0)
|
||||
{
|
||||
sq_per_C = 0x1000;
|
||||
}
|
||||
|
||||
env_per = (Register[11] & 0xFF) | (((Register[12] & 0xFF) << 8));
|
||||
if (env_per == 0)
|
||||
{
|
||||
env_per = 0x10000;
|
||||
}
|
||||
|
||||
env_per *= 2;
|
||||
|
||||
A_on = (Register[7] & 0x1) > 0;
|
||||
B_on = (Register[7] & 0x2) > 0;
|
||||
C_on = (Register[7] & 0x4) > 0;
|
||||
A_noise = (Register[7] & 0x8) > 0;
|
||||
B_noise = (Register[7] & 0x10) > 0;
|
||||
C_noise = (Register[7] & 0x20) > 0;
|
||||
|
||||
noise_per = Register[6] & 0x1F;
|
||||
if (noise_per == 0)
|
||||
{
|
||||
noise_per = 0x20;
|
||||
}
|
||||
|
||||
uint8_t shape_select = Register[13] & 0xF;
|
||||
|
||||
if (shape_select < 4) { env_shape = 0; }
|
||||
else if (shape_select < 8) { env_shape = 1; }
|
||||
else { env_shape = 2 + (shape_select - 8); }
|
||||
|
||||
vol_A = Register[8] & 0xF;
|
||||
env_vol_A = ((Register[8] >> 4) & 0x1) > 0;
|
||||
|
||||
vol_B = Register[9] & 0xF;
|
||||
env_vol_B = ((Register[9] >> 4) & 0x1) > 0;
|
||||
|
||||
vol_C = Register[10] & 0xF;
|
||||
env_vol_C = ((Register[10] >> 4) & 0x1) > 0;
|
||||
}
|
||||
|
||||
void WriteReg(uint8_t value)
|
||||
{
|
||||
value &= 0xFF;
|
||||
|
||||
if (port_sel != 0xE) { Register[port_sel] = value; }
|
||||
|
||||
|
||||
sync_psg_state();
|
||||
|
||||
if (port_sel == 13)
|
||||
{
|
||||
env_clock = env_per;
|
||||
|
||||
if (env_shape == 0 || env_shape == 2 || env_shape == 3 || env_shape == 4 || env_shape == 5)
|
||||
{
|
||||
env_E = 15;
|
||||
E_up_down = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
env_E = 0;
|
||||
E_up_down = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool generate_sound()
|
||||
{
|
||||
// there are 8 cpu cycles for every psg cycle
|
||||
clock_A--;
|
||||
clock_B--;
|
||||
clock_C--;
|
||||
|
||||
noise_clock--;
|
||||
env_clock--;
|
||||
|
||||
// clock noise
|
||||
if (noise_clock == 0)
|
||||
{
|
||||
noise = (noise >> 1) ^ (((noise & 0x1) > 0) ? 0x10004 : 0);
|
||||
noise_clock = noise_per;
|
||||
}
|
||||
|
||||
if (env_clock == 0)
|
||||
{
|
||||
env_clock = env_per;
|
||||
|
||||
env_E += E_up_down;
|
||||
|
||||
if (env_E == 16 || env_E == -1)
|
||||
{
|
||||
// we just completed a period of the envelope, determine what to do now based on the envelope shape
|
||||
if (env_shape == 0 || env_shape == 1 || env_shape == 3 || env_shape == 9)
|
||||
{
|
||||
E_up_down = 0;
|
||||
env_E = 0;
|
||||
}
|
||||
else if (env_shape == 5 || env_shape == 7)
|
||||
{
|
||||
E_up_down = 0;
|
||||
env_E = 15;
|
||||
}
|
||||
else if (env_shape == 4 || env_shape == 8)
|
||||
{
|
||||
if (env_E == 16)
|
||||
{
|
||||
env_E = 15;
|
||||
E_up_down = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
env_E = 0;
|
||||
E_up_down = 1;
|
||||
}
|
||||
}
|
||||
else if (env_shape == 2)
|
||||
{
|
||||
env_E = 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
env_E = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clock_A == 0)
|
||||
{
|
||||
A_up = !A_up;
|
||||
clock_A = sq_per_A;
|
||||
}
|
||||
|
||||
if (clock_B == 0)
|
||||
{
|
||||
B_up = !B_up;
|
||||
clock_B = sq_per_B;
|
||||
}
|
||||
|
||||
if (clock_C == 0)
|
||||
{
|
||||
C_up = !C_up;
|
||||
clock_C = sq_per_C;
|
||||
}
|
||||
|
||||
sound_out_A = (((noise & 0x1) > 0) | A_noise) & (A_on | A_up);
|
||||
sound_out_B = (((noise & 0x1) > 0) | B_noise) & (B_on | B_up);
|
||||
sound_out_C = (((noise & 0x1) > 0) | C_noise) & (C_on | C_up);
|
||||
|
||||
// now calculate the volume of each channel and add them together
|
||||
current_sample = 0;
|
||||
|
||||
if (env_vol_A)
|
||||
{
|
||||
current_sample = (sound_out_A ? VolumeTable[env_E] : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
current_sample = (sound_out_A ? VolumeTable[vol_A] : 0);
|
||||
}
|
||||
|
||||
if (env_vol_B)
|
||||
{
|
||||
current_sample += (sound_out_B ? VolumeTable[env_E] : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
current_sample += (sound_out_B ? VolumeTable[vol_B] : 0);
|
||||
}
|
||||
|
||||
if (env_vol_C)
|
||||
{
|
||||
current_sample += (sound_out_C ? VolumeTable[env_E] : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
current_sample += (sound_out_C ? VolumeTable[vol_C] : 0);
|
||||
}
|
||||
|
||||
current_sample *= 2;
|
||||
|
||||
if (current_sample != old_sample) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region State Save / Load
|
||||
|
||||
uint8_t* SaveState(uint8_t* saver)
|
||||
{
|
||||
*saver = (uint8_t)(A_on ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(B_on ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(C_on ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(A_up ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(B_up ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(C_up ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(A_noise ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(B_noise ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(C_noise ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(env_vol_A ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(env_vol_B ? 1 : 0); saver++;
|
||||
*saver = (uint8_t)(env_vol_C ? 1 : 0); saver++;
|
||||
|
||||
*saver = env_shape; saver++;
|
||||
*saver = port_sel; saver++;
|
||||
*saver = vol_A; saver++;
|
||||
*saver = vol_B; saver++;
|
||||
*saver = vol_C; saver++;
|
||||
|
||||
for (int i = 0; i < 16; i++) { *saver = Register[i]; saver++; }
|
||||
|
||||
*saver = (uint8_t)(psg_clock & 0xFF); saver++; *saver = (uint8_t)((psg_clock >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((psg_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((psg_clock >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(sq_per_A & 0xFF); saver++; *saver = (uint8_t)((sq_per_A >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((sq_per_A >> 16) & 0xFF); saver++; *saver = (uint8_t)((sq_per_A >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(sq_per_B & 0xFF); saver++; *saver = (uint8_t)((sq_per_B >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((sq_per_B >> 16) & 0xFF); saver++; *saver = (uint8_t)((sq_per_B >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(sq_per_C & 0xFF); saver++; *saver = (uint8_t)((sq_per_C >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((sq_per_C >> 16) & 0xFF); saver++; *saver = (uint8_t)((sq_per_C >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(clock_A & 0xFF); saver++; *saver = (uint8_t)((clock_A >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((clock_A >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_A >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(clock_B & 0xFF); saver++; *saver = (uint8_t)((clock_B >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((clock_B >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_B >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(clock_C & 0xFF); saver++; *saver = (uint8_t)((clock_C >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((clock_C >> 16) & 0xFF); saver++; *saver = (uint8_t)((clock_C >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(env_per & 0xFF); saver++; *saver = (uint8_t)((env_per >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((env_per >> 16) & 0xFF); saver++; *saver = (uint8_t)((env_per >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(env_clock & 0xFF); saver++; *saver = (uint8_t)((env_clock >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((env_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((env_clock >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(env_E & 0xFF); saver++; *saver = (uint8_t)((env_E >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((env_E >> 16) & 0xFF); saver++; *saver = (uint8_t)((env_E >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(E_up_down & 0xFF); saver++; *saver = (uint8_t)((E_up_down >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((E_up_down >> 16) & 0xFF); saver++; *saver = (uint8_t)((E_up_down >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(noise_clock & 0xFF); saver++; *saver = (uint8_t)((noise_clock >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((noise_clock >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise_clock >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(noise_per & 0xFF); saver++; *saver = (uint8_t)((noise_per >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((noise_per >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise_per >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(noise & 0xFF); saver++; *saver = (uint8_t)((noise >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((noise >> 16) & 0xFF); saver++; *saver = (uint8_t)((noise >> 24) & 0xFF); saver++;
|
||||
|
||||
*saver = (uint8_t)(old_sample & 0xFF); saver++; *saver = (uint8_t)((old_sample >> 8) & 0xFF); saver++;
|
||||
*saver = (uint8_t)((old_sample >> 16) & 0xFF); saver++; *saver = (uint8_t)((old_sample >> 24) & 0xFF); saver++;
|
||||
|
||||
return saver;
|
||||
}
|
||||
|
||||
uint8_t* LoadState(uint8_t* loader)
|
||||
{
|
||||
A_on = *loader == 1; loader++;
|
||||
B_on = *loader == 1; loader++;
|
||||
C_on = *loader == 1; loader++;
|
||||
A_up = *loader == 1; loader++;
|
||||
B_up = *loader == 1; loader++;
|
||||
C_up = *loader == 1; loader++;
|
||||
A_noise = *loader == 1; loader++;
|
||||
B_noise = *loader == 1; loader++;
|
||||
C_noise = *loader == 1; loader++;
|
||||
env_vol_A = *loader == 1; loader++;
|
||||
env_vol_B = *loader == 1; loader++;
|
||||
env_vol_C = *loader == 1; loader++;
|
||||
|
||||
env_shape = *loader; loader++;
|
||||
port_sel = *loader; loader++;
|
||||
vol_A = *loader; loader++;
|
||||
vol_B = *loader; loader++;
|
||||
vol_C = *loader; loader++;
|
||||
|
||||
for (int i = 0; i < 16; i++) { Register[i] = *loader; loader++; }
|
||||
|
||||
psg_clock = *loader; loader++; psg_clock |= (*loader << 8); loader++;
|
||||
psg_clock |= (*loader << 16); loader++; psg_clock |= (*loader << 24); loader++;
|
||||
|
||||
sq_per_A = *loader; loader++; sq_per_A |= (*loader << 8); loader++;
|
||||
sq_per_A |= (*loader << 16); loader++; sq_per_A |= (*loader << 24); loader++;
|
||||
|
||||
sq_per_B = *loader; loader++; sq_per_B |= (*loader << 8); loader++;
|
||||
sq_per_B |= (*loader << 16); loader++; sq_per_B |= (*loader << 24); loader++;
|
||||
|
||||
sq_per_C = *loader; loader++; sq_per_C |= (*loader << 8); loader++;
|
||||
sq_per_C |= (*loader << 16); loader++; sq_per_C |= (*loader << 24); loader++;
|
||||
|
||||
clock_A = *loader; loader++; clock_A |= (*loader << 8); loader++;
|
||||
clock_A |= (*loader << 16); loader++; clock_A |= (*loader << 24); loader++;
|
||||
|
||||
clock_B = *loader; loader++; clock_B |= (*loader << 8); loader++;
|
||||
clock_B |= (*loader << 16); loader++; clock_B |= (*loader << 24); loader++;
|
||||
|
||||
clock_C = *loader; loader++; clock_C |= (*loader << 8); loader++;
|
||||
clock_C |= (*loader << 16); loader++; clock_C |= (*loader << 24); loader++;
|
||||
|
||||
env_per = *loader; loader++; env_per |= (*loader << 8); loader++;
|
||||
env_per |= (*loader << 16); loader++; env_per |= (*loader << 24); loader++;
|
||||
|
||||
env_clock = *loader; loader++; env_clock |= (*loader << 8); loader++;
|
||||
env_clock |= (*loader << 16); loader++; env_clock |= (*loader << 24); loader++;
|
||||
|
||||
env_E = *loader; loader++; env_E |= (*loader << 8); loader++;
|
||||
env_E |= (*loader << 16); loader++; env_E |= (*loader << 24); loader++;
|
||||
|
||||
E_up_down = *loader; loader++; E_up_down |= (*loader << 8); loader++;
|
||||
E_up_down |= (*loader << 16); loader++; E_up_down |= (*loader << 24); loader++;
|
||||
|
||||
noise_clock = *loader; loader++; noise_clock |= (*loader << 8); loader++;
|
||||
noise_clock |= (*loader << 16); loader++; noise_clock |= (*loader << 24); loader++;
|
||||
|
||||
noise_per = *loader; loader++; noise_per |= (*loader << 8); loader++;
|
||||
noise_per |= (*loader << 16); loader++; noise_per |= (*loader << 24); loader++;
|
||||
|
||||
noise = *loader; loader++; noise |= (*loader << 8); loader++;
|
||||
noise |= (*loader << 16); loader++; noise |= (*loader << 24); loader++;
|
||||
|
||||
old_sample = *loader; loader++; old_sample |= (*loader << 8); loader++;
|
||||
old_sample |= (*loader << 16); loader++; old_sample |= (*loader << 24); loader++;
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
};
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Computers.MSX
|
||||
|
@ -16,7 +17,13 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
SyncSettings = (MSXSyncSettings)syncSettings ?? new MSXSyncSettings();
|
||||
|
||||
RomData = new byte[rom.Length];
|
||||
|
||||
|
||||
// look up game in db before transforming ROM
|
||||
var hash_md5 = MD5Checksum.ComputePrefixedHex(rom);
|
||||
var gi = Database.CheckDatabase(hash_md5);
|
||||
var dict = gi.GetOptions();
|
||||
string s_mapper;
|
||||
|
||||
for (int i = 0; i < rom.Length; i++)
|
||||
{
|
||||
RomData[i] = rom[i];
|
||||
|
@ -38,8 +45,25 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
}
|
||||
else
|
||||
{
|
||||
mapper_1 = 1;
|
||||
Console.WriteLine("Konami Mapper");
|
||||
// Assume default konami style mapper
|
||||
if (gi == null)
|
||||
{
|
||||
|
||||
}
|
||||
else if (!dict.TryGetValue("mapper", out s_mapper))
|
||||
{
|
||||
mapper_1 = 1;
|
||||
Console.WriteLine("Using Konami Mapper");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_mapper == "2")
|
||||
{
|
||||
mapper_1 = 2;
|
||||
Console.WriteLine("Using Konami Mapper with SCC");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if the original was not 64 or 48 k, move it (may need to do this case by case)
|
||||
|
@ -135,7 +159,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
}
|
||||
|
||||
private IntPtr MSX_Pntr { get; set; } = IntPtr.Zero;
|
||||
private byte[] MSX_core = new byte[0x20000];
|
||||
private byte[] MSX_core = new byte[0x28000];
|
||||
public static byte[] Bios = null;
|
||||
public static byte[] Basic;
|
||||
|
||||
|
|
Loading…
Reference in New Issue