GBHawk: more transformation work

This commit is contained in:
alyosha-tas 2020-03-24 19:44:11 -04:00
parent 373a05dcb4
commit 79fecef41b
9 changed files with 1564 additions and 1379 deletions

View File

@ -1,442 +0,0 @@
#include <iostream>
#include <cstdint>
#include <iomanip>
#include <string>
using namespace std;
namespace GBHawk
{
class AY_3_8910
{
public:
#pragma region AY_3_8910
AY_3_8910()
{
Reset();
}
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;
// non stated if only on frame boundaries
bool sound_out_A;
bool sound_out_B;
bool sound_out_C;
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;
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
};
uint8_t ReadReg()
{
return Register[port_sel];
}
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;
}
}
}
void 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) && (num_samples < 4500))
{
samples[num_samples * 2] = sampleclock;
samples[num_samples * 2 + 1] = current_sample - old_sample;
num_samples++;
old_sample = current_sample;
}
}
#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
};
}

View File

@ -4,7 +4,7 @@
#include <string>
#include "LR35902.h"
#include "AY_3_8910.h"
#include "GBAudio.h"
#include "TMS9918A.h"
#include "Memory.h"
@ -21,13 +21,12 @@ namespace GBHawk
cpu.mem_ctrl = &MemMap;
vdp.IRQ_PTR = &cpu.FlagI;
vdp.SHOW_BG = vdp.SHOW_SPRITES = true;
psg.Clock_Divider = 16;
sl_case = 0;
};
TMS9918A vdp;
Z80A cpu;
AY_3_8910 psg;
LR35902 cpu;
GBAudio psg;
MemoryManager MemMap;
uint8_t sl_case = 0;
@ -44,14 +43,6 @@ namespace GBHawk
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)
{
MemMap.psg_pntr->Register[0xE] = controller_2;
}
else
{
MemMap.psg_pntr->Register[0xE] = controller_1;
}
MemMap.controller_byte_1 = controller_1;
MemMap.controller_byte_2 = controller_2;
@ -62,83 +53,6 @@ namespace GBHawk
uint32_t scanlinesPerFrame = 262;
vdp.SpriteLimit = true;
psg.num_samples = 0;
psg.sampleclock = 0;
for (uint32_t i = 0; i < scanlinesPerFrame; i++)
{
vdp.ScanLine = i;
vdp.RenderScanline(i);
if (vdp.ScanLine == 192)
{
vdp.InterruptPendingSet(true);
if (vdp.EnableInterrupts()) { cpu.FlagI = true; }
}
switch (sl_case)
{
case 0:
for (int i = 0; i < 14; i++)
{
cpu.ExecuteOne(16);
psg.sampleclock+=16;
psg.generate_sound();
}
cpu.ExecuteOne(4);
psg.sampleclock += 4;
sl_case = 1;
break;
case 1:
cpu.ExecuteOne(12);
psg.sampleclock += 12;
psg.generate_sound();
for (int i = 0; i < 13; i++)
{
cpu.ExecuteOne(16);
psg.sampleclock += 16;
psg.generate_sound();
}
cpu.ExecuteOne(8);
psg.sampleclock += 8;
sl_case = 2;
break;
case 2:
cpu.ExecuteOne(8);
psg.sampleclock += 8;
psg.generate_sound();
for (int i = 0; i < 13; i++)
{
cpu.ExecuteOne(16);
psg.sampleclock += 16;
psg.generate_sound();
}
cpu.ExecuteOne(12);
psg.sampleclock += 12;
sl_case = 3;
break;
case 3:
cpu.ExecuteOne(4);
psg.sampleclock += 4;
psg.generate_sound();
for (int i = 0; i < 14; i++)
{
cpu.ExecuteOne(16);
psg.sampleclock += 16;
psg.generate_sound();
}
sl_case = 0;
break;
}
}
return MemMap.lagged;
}
@ -150,15 +64,21 @@ namespace GBHawk
std::memcpy(dst, src, sizeof uint32_t * 256 * 192);
}
uint32_t GetAudio(int32_t* dest, int32_t* n_samp)
uint32_t GetAudio(int32_t* dest_L, int32_t* n_samp_L, int32_t* dest_R, int32_t* n_samp_R)
{
int32_t* src = psg.samples;
int32_t* dst = dest;
int32_t* src = psg.samples_L;
int32_t* dst = dest_L;
std::memcpy(dst, src, sizeof int32_t * psg.num_samples * 2);
n_samp[0] = psg.num_samples;
std::memcpy(dst, src, sizeof int32_t * psg.num_samples_L * 2);
n_samp_L[0] = psg.num_samples_L;
return psg.sampleclock;
src = psg.samples_R;
dst = dest_R;
std::memcpy(dst, src, sizeof int32_t * psg.num_samples_R * 2);
n_samp_R[0] = psg.num_samples_R;
return psg.master_audio_clock;
}
#pragma region State Save / Load
@ -189,11 +109,7 @@ namespace GBHawk
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];
return cpu.PeekMemory(addr);
}
uint8_t GetVRAM(uint32_t addr)
@ -257,11 +173,15 @@ namespace GBHawk
}
else if (t == 1)
{
memcpy(d, cpu.NMI_event, l);
memcpy(d, cpu.Un_halt_event, l);
}
else if (t == 2)
{
memcpy(d, cpu.IRQ_event, l);
}
else
{
memcpy(d, cpu.IRQ_event, l);
memcpy(d, cpu.Un_halt_event, l);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -53,9 +53,9 @@ GBHawk_EXPORT void GB_get_video(GBCore* p, uint32_t* dest)
}
// send audio data to external audio provider
GBHawk_EXPORT uint32_t GB_get_audio(GBCore* p, int32_t* dest, int32_t* n_samp)
GBHawk_EXPORT uint32_t GB_get_audio(GBCore* p, int32_t* dest_L, int32_t* n_samp_L, int32_t* dest_R, int32_t* n_samp_R)
{
return p->GetAudio(dest, n_samp);
return p->GetAudio(dest_L, n_samp_L, dest_R, n_samp_R);
}
#pragma region State Save / Load

View File

@ -151,7 +151,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="AY_3_8910.h" />
<ClInclude Include="GBAudio.h" />
<ClInclude Include="Core.h" />
<ClInclude Include="GBHawk.h" />
<ClInclude Include="Memory.h" />

View File

@ -11,10 +11,7 @@ namespace GBHawk
{
void LR35902::WriteMemory(uint32_t addr, uint8_t value)
{
if ((addr & 0xFFFF) >= 0xFFFC)
{
mem_ctrl->MemoryWrite(addr, value);
}
mem_ctrl->MemoryWrite(addr, value);
}
uint8_t LR35902::ReadMemory(uint32_t addr)
@ -22,6 +19,11 @@ namespace GBHawk
return mem_ctrl->HardwareRead(addr);
}
uint8_t LR35902::PeekMemory(uint32_t addr)
{
return mem_ctrl->HardwareRead(addr);
}
uint8_t LR35902::SpeedFunc(uint32_t addr)
{
return mem_ctrl->HardwareRead(addr);

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
#include "Memory.h"
#include "LR35902.h"
#include "TMS9918A.h"
#include "AY_3_8910.h"
#include "GBAudio.h"
using namespace std;
@ -14,216 +14,12 @@ namespace GBHawk
{
uint8_t MemoryManager::HardwareRead(uint32_t port)
{
port &= 0xFF;
if (port == 0x98) // VDP
{
return vdp_pntr->ReadData();
}
else if (port == 0x99) // VDP
{
return vdp_pntr->ReadVdpStatus();
}
else if (port == 0xA2)
{
if (psg_pntr->port_sel == 0xE) { lagged = false; }
return psg_pntr->ReadReg();
}
else if (port == 0xA8)
{
return PortA8;
}
else if (port == 0xA9)
{
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;
}
void MemoryManager::HardwareWrite(uint32_t port, uint8_t value)
{
port &= 0xFF;
if (port == 0x98) // VDP
{
vdp_pntr->WriteVdpData(value);
}
else if(port == 0x99) // VDP
{
vdp_pntr->WriteVdpControl(value);
}
else if (port == 0xA0)
{
psg_pntr->port_sel = (value & 0xF);
}
else if (port == 0xA1)
{
psg_pntr->WriteReg(value);
// update controller port data if port F is written to
if (psg_pntr->port_sel == 0xF)
{
if ((psg_pntr->Register[0xF] & 0x40) > 0)
{
psg_pntr->Register[0xE] = controller_byte_2;
}
else
{
psg_pntr->Register[0xE] = controller_byte_1;
}
}
}
else if (port == 0xA8)
{
PortA8 = value;
remap();
}
else if (port == 0xAA)
{
kb_rows_sel = value & 0xF;
remap();
}
}
void MemoryManager::remap()
{
if ((PortA8 & 3) == 0)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &bios_rom[(0x400 * i)];
cpu_pntr->MemoryMapMask[i] = 0;
}
}
else if ((PortA8 & 3) == 1)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &rom_1[(0x400 * i)];
cpu_pntr->MemoryMapMask[i] = 0;
}
}
else if ((PortA8 & 3) == 2)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &rom_2[(0x400 * i)];
cpu_pntr->MemoryMapMask[i] = 0;
}
}
else if ((PortA8 & 3) == 3)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i] = &ram[(0x400 * i)];
cpu_pntr->MemoryMapMask[i] = 0xFF;
}
}
if (((PortA8 >> 2) & 3) == 0)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &basic_rom[(0x400 * i)];
cpu_pntr->MemoryMapMask[i + 16] = 0;
}
}
else if (((PortA8 >> 2) & 3) == 1)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &rom_1[0x4000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 16] = 0;
}
}
else if (((PortA8 >> 2) & 3) == 2)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &rom_2[0x4000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 16] = 0;
}
}
else if (((PortA8 >> 2) & 3) == 3)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 16] = &ram[0x4000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 16] = 0xFF;
}
}
if (((PortA8 >> 4) & 3) == 0)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &unmapped[0];
cpu_pntr->MemoryMapMask[i + 32] = 0;
}
}
else if (((PortA8 >> 4) & 3) == 1)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &rom_1[0x8000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 32] = 0;
}
}
else if (((PortA8 >> 4) & 3) == 2)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &rom_2[0x8000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 32] = 0;
}
}
else if (((PortA8 >> 4) & 3) == 3)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 32] = &ram[0x8000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 32] = 0xFF;
}
}
if (((PortA8 >> 6) & 3) == 0)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &unmapped[0];
cpu_pntr->MemoryMapMask[i + 48] = 0;
}
}
else if (((PortA8 >> 6) & 3) == 1)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &rom_1[0xC000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 48] = 0;
}
}
else if (((PortA8 >> 6) & 3) == 2)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &rom_2[0xC000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 48] = 0;
}
}
else if (((PortA8 >> 6) & 3) == 3)
{
for (uint32_t i = 0; i < 16; i++)
{
cpu_pntr->MemoryMap[i + 48] = &ram[0xC000 + (0x400 * i)];
cpu_pntr->MemoryMapMask[i + 48] = 0xFF;
}
}
}
}

View File

@ -7,17 +7,17 @@ using namespace std;
namespace GBHawk
{
class Z80A;
class LR35902;
class TMS9918A;
class AY_3_8910;
class GBAudio;
class MemoryManager
{
public:
TMS9918A* vdp_pntr = nullptr;
AY_3_8910* psg_pntr = nullptr;
Z80A* cpu_pntr = nullptr;
GBAudio* psg_pntr = nullptr;
LR35902* cpu_pntr = nullptr;
uint8_t* rom_1 = nullptr;
uint8_t* rom_2 = nullptr;
uint8_t* bios_rom = nullptr;
@ -54,8 +54,6 @@ namespace GBHawk
void HardwareWrite(uint32_t addr, uint8_t value);
void remap();
// NOTE: only called from source when both are available and of correct size (0x4000)
void Load_BIOS(uint8_t* bios, uint8_t* basic)
{
@ -82,8 +80,6 @@ namespace GBHawk
// default memory map setup
PortA8 = 0;
remap();
}
void MemoryWrite(uint32_t addr, uint8_t value)
@ -128,8 +124,6 @@ namespace GBHawk
std::memcpy(&ram, loader, 0x10000); loader += 0x10000;
std::memcpy(&cart_ram, loader, 0x8000); loader += 0x8000;
remap();
return loader;
}