mirror of
https://github.com/libretro/beetle-wswan-libretro.git
synced 2024-11-30 11:41:36 +00:00
Cleanups
This commit is contained in:
parent
0889b15c0b
commit
b8709827d4
@ -96,271 +96,276 @@ static uint32 last_ts;
|
||||
|
||||
void WSwan_SoundUpdate(void)
|
||||
{
|
||||
int32 run_time;
|
||||
int32 run_time;
|
||||
|
||||
//printf("%d\n", v30mz_timestamp);
|
||||
//printf("%02x %02x\n", control, noise_control);
|
||||
run_time = v30mz_timestamp - last_ts;
|
||||
//printf("%d\n", v30mz_timestamp);
|
||||
//printf("%02x %02x\n", control, noise_control);
|
||||
run_time = v30mz_timestamp - last_ts;
|
||||
|
||||
for(unsigned int ch = 0; ch < 4; ch++)
|
||||
{
|
||||
// Channel is disabled?
|
||||
if(!(control & (1 << ch)))
|
||||
continue;
|
||||
|
||||
if(ch == 1 && (control & 0x20)) // Direct D/A mode?
|
||||
{
|
||||
int32 neoval = (volume[ch] - 0x80) * voice_volume;
|
||||
|
||||
VoiceSynth.offset(v30mz_timestamp, neoval - last_v_val, sbuf[0]);
|
||||
VoiceSynth.offset(v30mz_timestamp, neoval - last_v_val, sbuf[1]);
|
||||
|
||||
last_v_val = neoval;
|
||||
}
|
||||
else if(ch == 2 && (control & 0x40) && sweep_value) // Sweep
|
||||
{
|
||||
uint32 tmp_pt = 2048 - period[ch];
|
||||
uint32 meow_timestamp = v30mz_timestamp - run_time;
|
||||
uint32 tmp_run_time = run_time;
|
||||
|
||||
while(tmp_run_time)
|
||||
for(unsigned int ch = 0; ch < 4; ch++)
|
||||
{
|
||||
int32 sub_run_time = tmp_run_time;
|
||||
// Channel is disabled?
|
||||
if(!(control & (1 << ch)))
|
||||
continue;
|
||||
|
||||
if(sub_run_time > sweep_8192_divider)
|
||||
sub_run_time = sweep_8192_divider;
|
||||
if(ch == 1 && (control & 0x20)) // Direct D/A mode?
|
||||
{
|
||||
int32 neoval = (volume[ch] - 0x80) * voice_volume;
|
||||
|
||||
sweep_8192_divider -= sub_run_time;
|
||||
if(sweep_8192_divider <= 0)
|
||||
{
|
||||
sweep_8192_divider += 8192;
|
||||
sweep_counter--;
|
||||
if(sweep_counter <= 0)
|
||||
{
|
||||
sweep_counter = sweep_step + 1;
|
||||
period[ch] = (period[ch] + (int8)sweep_value) & 0x7FF;
|
||||
}
|
||||
}
|
||||
VoiceSynth.offset(v30mz_timestamp, neoval - last_v_val, sbuf[0]);
|
||||
VoiceSynth.offset(v30mz_timestamp, neoval - last_v_val, sbuf[1]);
|
||||
|
||||
meow_timestamp += sub_run_time;
|
||||
if(tmp_pt > 4)
|
||||
{
|
||||
period_counter[ch] -= sub_run_time;
|
||||
while(period_counter[ch] <= 0)
|
||||
{
|
||||
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
|
||||
last_v_val = neoval;
|
||||
}
|
||||
else if(ch == 2 && (control & 0x40) && sweep_value) // Sweep
|
||||
{
|
||||
uint32 tmp_pt = 2048 - period[ch];
|
||||
uint32 meow_timestamp = v30mz_timestamp - run_time;
|
||||
uint32 tmp_run_time = run_time;
|
||||
|
||||
MK_SAMPLE_CACHE;
|
||||
SYNCSAMPLE(meow_timestamp + period_counter[ch]);
|
||||
period_counter[ch] += tmp_pt;
|
||||
}
|
||||
}
|
||||
tmp_run_time -= sub_run_time;
|
||||
while(tmp_run_time)
|
||||
{
|
||||
int32 sub_run_time = tmp_run_time;
|
||||
|
||||
if(sub_run_time > sweep_8192_divider)
|
||||
sub_run_time = sweep_8192_divider;
|
||||
|
||||
sweep_8192_divider -= sub_run_time;
|
||||
if(sweep_8192_divider <= 0)
|
||||
{
|
||||
sweep_8192_divider += 8192;
|
||||
sweep_counter--;
|
||||
if(sweep_counter <= 0)
|
||||
{
|
||||
sweep_counter = sweep_step + 1;
|
||||
period[ch] = (period[ch] + (int8)sweep_value) & 0x7FF;
|
||||
}
|
||||
}
|
||||
|
||||
meow_timestamp += sub_run_time;
|
||||
if(tmp_pt > 4)
|
||||
{
|
||||
period_counter[ch] -= sub_run_time;
|
||||
while(period_counter[ch] <= 0)
|
||||
{
|
||||
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
|
||||
|
||||
MK_SAMPLE_CACHE;
|
||||
SYNCSAMPLE(meow_timestamp + period_counter[ch]);
|
||||
period_counter[ch] += tmp_pt;
|
||||
}
|
||||
}
|
||||
tmp_run_time -= sub_run_time;
|
||||
}
|
||||
}
|
||||
else if(ch == 3 && (noise_control & 0x10)) //(control & 0x80)) // Noise
|
||||
{
|
||||
uint32 tmp_pt = 2048 - period[ch];
|
||||
|
||||
period_counter[ch] -= run_time;
|
||||
while(period_counter[ch] <= 0)
|
||||
{
|
||||
// Yay, random numbers, so let's use totally wrong numbers to make them!
|
||||
const int bstab1[8] = { 14, 13, 12, 14, 12, 13, 14, 14 };
|
||||
const int bstab2[8] = { 13, 12, 9, 12, 1, 1, 5, 11 };
|
||||
//const int bstab1[8] = { 14, 13, 12, 14, 10, 9, 8, 13 };
|
||||
//const int bstab2[8] = { 13, 12, 9, 12, 1, 6, 4, 11 };
|
||||
nreg = (~((nreg << 1) | ( ((nreg >> bstab1[noise_control & 0x7]) & 1) ^ ((nreg >> bstab2[noise_control & 0x7]) & 1)))) & 0x7FFF;
|
||||
if(control & 0x80)
|
||||
{
|
||||
MK_SAMPLE_CACHE_NOISE;
|
||||
SYNCSAMPLE_NOISE(v30mz_timestamp + period_counter[ch]);
|
||||
}
|
||||
else if(tmp_pt > 4)
|
||||
{
|
||||
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
|
||||
MK_SAMPLE_CACHE;
|
||||
SYNCSAMPLE(v30mz_timestamp + period_counter[ch]);
|
||||
}
|
||||
period_counter[ch] += tmp_pt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 tmp_pt = 2048 - period[ch];
|
||||
|
||||
if(tmp_pt > 4)
|
||||
{
|
||||
period_counter[ch] -= run_time;
|
||||
while(period_counter[ch] <= 0)
|
||||
{
|
||||
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
|
||||
|
||||
MK_SAMPLE_CACHE;
|
||||
SYNCSAMPLE(v30mz_timestamp + period_counter[ch]); // - period_counter[ch]);
|
||||
period_counter[ch] += tmp_pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ch == 3 && (noise_control & 0x10)) //(control & 0x80)) // Noise
|
||||
{
|
||||
uint32 tmp_pt = 2048 - period[ch];
|
||||
|
||||
period_counter[ch] -= run_time;
|
||||
while(period_counter[ch] <= 0)
|
||||
{
|
||||
// Yay, random numbers, so let's use totally wrong numbers to make them!
|
||||
const int bstab1[8] = { 14, 13, 12, 14, 12, 13, 14, 14 };
|
||||
const int bstab2[8] = { 13, 12, 9, 12, 1, 1, 5, 11 };
|
||||
//const int bstab1[8] = { 14, 13, 12, 14, 10, 9, 8, 13 };
|
||||
//const int bstab2[8] = { 13, 12, 9, 12, 1, 6, 4, 11 };
|
||||
nreg = (~((nreg << 1) | ( ((nreg >> bstab1[noise_control & 0x7]) & 1) ^ ((nreg >> bstab2[noise_control & 0x7]) & 1)))) & 0x7FFF;
|
||||
if(control & 0x80)
|
||||
{
|
||||
MK_SAMPLE_CACHE_NOISE;
|
||||
SYNCSAMPLE_NOISE(v30mz_timestamp + period_counter[ch]);
|
||||
}
|
||||
else if(tmp_pt > 4)
|
||||
{
|
||||
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
|
||||
MK_SAMPLE_CACHE;
|
||||
SYNCSAMPLE(v30mz_timestamp + period_counter[ch]);
|
||||
}
|
||||
period_counter[ch] += tmp_pt;
|
||||
int32 tmphv = HyperVoice;
|
||||
|
||||
if(tmphv - last_hv_val)
|
||||
{
|
||||
WaveSynth.offset_inline(v30mz_timestamp, tmphv - last_hv_val, sbuf[0]);
|
||||
WaveSynth.offset_inline(v30mz_timestamp, tmphv - last_hv_val, sbuf[1]);
|
||||
last_hv_val = tmphv;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 tmp_pt = 2048 - period[ch];
|
||||
|
||||
if(tmp_pt > 4)
|
||||
{
|
||||
period_counter[ch] -= run_time;
|
||||
while(period_counter[ch] <= 0)
|
||||
{
|
||||
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
|
||||
|
||||
MK_SAMPLE_CACHE;
|
||||
SYNCSAMPLE(v30mz_timestamp + period_counter[ch]); // - period_counter[ch]);
|
||||
period_counter[ch] += tmp_pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int32 tmphv = HyperVoice;
|
||||
|
||||
if(tmphv - last_hv_val)
|
||||
{
|
||||
WaveSynth.offset_inline(v30mz_timestamp, tmphv - last_hv_val, sbuf[0]);
|
||||
WaveSynth.offset_inline(v30mz_timestamp, tmphv - last_hv_val, sbuf[1]);
|
||||
last_hv_val = tmphv;
|
||||
}
|
||||
}
|
||||
last_ts = v30mz_timestamp;
|
||||
last_ts = v30mz_timestamp;
|
||||
}
|
||||
|
||||
void WSwan_SoundWrite(uint32 A, uint8 V)
|
||||
{
|
||||
WSwan_SoundUpdate();
|
||||
WSwan_SoundUpdate();
|
||||
|
||||
if(A >= 0x80 && A <= 0x87)
|
||||
{
|
||||
int ch = (A - 0x80) >> 1;
|
||||
|
||||
if(A & 1)
|
||||
period[ch] = (period[ch] & 0x00FF) | ((V & 0x07) << 8);
|
||||
else
|
||||
period[ch] = (period[ch] & 0x0700) | ((V & 0xFF) << 0);
|
||||
}
|
||||
else if(A >= 0x88 && A <= 0x8B)
|
||||
{
|
||||
volume[A - 0x88] = V;
|
||||
}
|
||||
else if(A == 0x8C)
|
||||
sweep_value = V;
|
||||
else if(A == 0x8D)
|
||||
{
|
||||
sweep_step = V;
|
||||
sweep_counter = sweep_step + 1;
|
||||
sweep_8192_divider = 8192;
|
||||
}
|
||||
else if(A == 0x8E)
|
||||
{
|
||||
noise_control = V;
|
||||
if(V & 0x8) nreg = 1;
|
||||
//printf("NOISECONTROL: %02x\n", V);
|
||||
}
|
||||
else if(A == 0x90)
|
||||
{
|
||||
for(int n = 0; n < 4; n++)
|
||||
if(!(control & (1 << n)) && (V & (1 << n)))
|
||||
if(A >= 0x80 && A <= 0x87)
|
||||
{
|
||||
period_counter[n] = 0;
|
||||
sample_pos[n] = 0x1F;
|
||||
int ch = (A - 0x80) >> 1;
|
||||
|
||||
if(A & 1)
|
||||
period[ch] = (period[ch] & 0x00FF) | ((V & 0x07) << 8);
|
||||
else
|
||||
period[ch] = (period[ch] & 0x0700) | ((V & 0xFF) << 0);
|
||||
}
|
||||
control = V;
|
||||
//printf("Sound Control: %02x\n", V);
|
||||
}
|
||||
else if(A == 0x91)
|
||||
{
|
||||
output_control = V & 0xF;
|
||||
//printf("%02x, %02x\n", V, (V >> 1) & 3);
|
||||
}
|
||||
else if(A == 0x92)
|
||||
nreg = (nreg & 0xFF00) | (V << 0);
|
||||
else if(A == 0x93)
|
||||
nreg = (nreg & 0x00FF) | ((V & 0x7F) << 8);
|
||||
else if(A == 0x94)
|
||||
{
|
||||
voice_volume = V & 0xF;
|
||||
//printf("%02x\n", V);
|
||||
}
|
||||
else switch(A)
|
||||
{
|
||||
case 0x8F: SampleRAMPos = V; break;
|
||||
case 0x95: HyperVoice = V; break; // Pick a port, any port?!
|
||||
//default: printf("%04x:%02x\n", A, V); break;
|
||||
}
|
||||
WSwan_SoundUpdate();
|
||||
else if(A >= 0x88 && A <= 0x8B)
|
||||
{
|
||||
volume[A - 0x88] = V;
|
||||
}
|
||||
else if(A == 0x8C)
|
||||
sweep_value = V;
|
||||
else if(A == 0x8D)
|
||||
{
|
||||
sweep_step = V;
|
||||
sweep_counter = sweep_step + 1;
|
||||
sweep_8192_divider = 8192;
|
||||
}
|
||||
else if(A == 0x8E)
|
||||
{
|
||||
noise_control = V;
|
||||
if(V & 0x8) nreg = 1;
|
||||
//printf("NOISECONTROL: %02x\n", V);
|
||||
}
|
||||
else if(A == 0x90)
|
||||
{
|
||||
for(int n = 0; n < 4; n++)
|
||||
if(!(control & (1 << n)) && (V & (1 << n)))
|
||||
{
|
||||
period_counter[n] = 0;
|
||||
sample_pos[n] = 0x1F;
|
||||
}
|
||||
control = V;
|
||||
//printf("Sound Control: %02x\n", V);
|
||||
}
|
||||
else if(A == 0x91)
|
||||
{
|
||||
output_control = V & 0xF;
|
||||
//printf("%02x, %02x\n", V, (V >> 1) & 3);
|
||||
}
|
||||
else if(A == 0x92)
|
||||
nreg = (nreg & 0xFF00) | (V << 0);
|
||||
else if(A == 0x93)
|
||||
nreg = (nreg & 0x00FF) | ((V & 0x7F) << 8);
|
||||
else if(A == 0x94)
|
||||
{
|
||||
voice_volume = V & 0xF;
|
||||
//printf("%02x\n", V);
|
||||
}
|
||||
else switch(A)
|
||||
{
|
||||
case 0x8F: SampleRAMPos = V; break;
|
||||
case 0x95: HyperVoice = V; break; // Pick a port, any port?!
|
||||
//default: printf("%04x:%02x\n", A, V); break;
|
||||
}
|
||||
WSwan_SoundUpdate();
|
||||
}
|
||||
|
||||
uint8 WSwan_SoundRead(uint32 A)
|
||||
{
|
||||
WSwan_SoundUpdate();
|
||||
WSwan_SoundUpdate();
|
||||
|
||||
if(A >= 0x80 && A <= 0x87)
|
||||
{
|
||||
int ch = (A - 0x80) >> 1;
|
||||
if(A >= 0x80 && A <= 0x87)
|
||||
{
|
||||
int ch = (A - 0x80) >> 1;
|
||||
|
||||
if(A & 1)
|
||||
return(period[ch] >> 8);
|
||||
else
|
||||
return(period[ch]);
|
||||
}
|
||||
else if(A >= 0x88 && A <= 0x8B)
|
||||
return(volume[A - 0x88]);
|
||||
else switch(A)
|
||||
{
|
||||
default: printf("SoundRead: %04x\n", A); return(0);
|
||||
case 0x8C: return(sweep_value);
|
||||
case 0x8D: return(sweep_step);
|
||||
case 0x8E: return(noise_control);
|
||||
case 0x8F: return(SampleRAMPos);
|
||||
case 0x90: return(control);
|
||||
case 0x91: return(output_control | 0x80);
|
||||
case 0x92: return((nreg >> 0) & 0xFF);
|
||||
case 0x93: return((nreg >> 8) & 0xFF);
|
||||
case 0x94: return(voice_volume);
|
||||
}
|
||||
if(A & 1)
|
||||
return(period[ch] >> 8);
|
||||
else
|
||||
return(period[ch]);
|
||||
}
|
||||
else if(A >= 0x88 && A <= 0x8B)
|
||||
return(volume[A - 0x88]);
|
||||
else switch(A)
|
||||
{
|
||||
default:
|
||||
printf("SoundRead: %04x\n", A);
|
||||
break;
|
||||
case 0x8C: return(sweep_value);
|
||||
case 0x8D: return(sweep_step);
|
||||
case 0x8E: return(noise_control);
|
||||
case 0x8F: return(SampleRAMPos);
|
||||
case 0x90: return(control);
|
||||
case 0x91: return(output_control | 0x80);
|
||||
case 0x92: return((nreg >> 0) & 0xFF);
|
||||
case 0x93: return((nreg >> 8) & 0xFF);
|
||||
case 0x94: return(voice_volume);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int32 WSwan_SoundFlush(int16 *SoundBuf, const int32 MaxSoundFrames)
|
||||
{
|
||||
int32 FrameCount = 0;
|
||||
int32 FrameCount = 0;
|
||||
|
||||
WSwan_SoundUpdate();
|
||||
WSwan_SoundUpdate();
|
||||
|
||||
if(SoundBuf)
|
||||
{
|
||||
for(int y = 0; y < 2; y++)
|
||||
{
|
||||
sbuf[y]->end_frame(v30mz_timestamp);
|
||||
FrameCount = sbuf[y]->read_samples(SoundBuf + y, MaxSoundFrames, true);
|
||||
}
|
||||
}
|
||||
if(SoundBuf)
|
||||
{
|
||||
for(int y = 0; y < 2; y++)
|
||||
{
|
||||
sbuf[y]->end_frame(v30mz_timestamp);
|
||||
FrameCount = sbuf[y]->read_samples(SoundBuf + y, MaxSoundFrames, true);
|
||||
}
|
||||
}
|
||||
|
||||
last_ts = 0;
|
||||
last_ts = 0;
|
||||
|
||||
return(FrameCount);
|
||||
return(FrameCount);
|
||||
}
|
||||
|
||||
// Call before wsRAM is updated
|
||||
void WSwan_SoundCheckRAMWrite(uint32 A)
|
||||
{
|
||||
if((A >> 6) == SampleRAMPos)
|
||||
WSwan_SoundUpdate();
|
||||
if((A >> 6) == SampleRAMPos)
|
||||
WSwan_SoundUpdate();
|
||||
}
|
||||
|
||||
static void RedoVolume(void)
|
||||
{
|
||||
double eff_volume = 1.0 / 4;
|
||||
double eff_volume = 1.0 / 4;
|
||||
|
||||
WaveSynth.volume(eff_volume);
|
||||
NoiseSynth.volume(eff_volume);
|
||||
VoiceSynth.volume(eff_volume);
|
||||
WaveSynth.volume(eff_volume);
|
||||
NoiseSynth.volume(eff_volume);
|
||||
VoiceSynth.volume(eff_volume);
|
||||
}
|
||||
|
||||
void WSwan_SoundInit(void)
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
sbuf[i] = new Blip_Buffer();
|
||||
unsigned i;
|
||||
for(i = 0; i < 2; i++)
|
||||
{
|
||||
sbuf[i] = new Blip_Buffer();
|
||||
|
||||
sbuf[i]->set_sample_rate(0 ? 0 : 44100, 60);
|
||||
sbuf[i]->clock_rate((long)(3072000));
|
||||
sbuf[i]->bass_freq(20);
|
||||
}
|
||||
sbuf[i]->set_sample_rate(0 ? 0 : 44100, 60);
|
||||
sbuf[i]->clock_rate((long)(3072000));
|
||||
sbuf[i]->bass_freq(20);
|
||||
}
|
||||
|
||||
RedoVolume();
|
||||
RedoVolume();
|
||||
}
|
||||
|
||||
void WSwan_SoundKill(void)
|
||||
@ -378,10 +383,11 @@ void WSwan_SoundKill(void)
|
||||
|
||||
bool WSwan_SetSoundRate(uint32 rate)
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
sbuf[i]->set_sample_rate(rate?rate:44100, 60);
|
||||
unsigned i;
|
||||
for(i = 0; i < 2; i++)
|
||||
sbuf[i]->set_sample_rate(rate?rate:44100, 60);
|
||||
|
||||
return(TRUE);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
int WSwan_SoundStateAction(StateMem *sm, int load, int data_only)
|
||||
@ -414,29 +420,31 @@ int WSwan_SoundStateAction(StateMem *sm, int load, int data_only)
|
||||
|
||||
void WSwan_SoundReset(void)
|
||||
{
|
||||
memset(period, 0, sizeof(period));
|
||||
memset(volume, 0, sizeof(volume));
|
||||
voice_volume = 0;
|
||||
sweep_step = 0;
|
||||
sweep_value = 0;
|
||||
noise_control = 0;
|
||||
control = 0;
|
||||
output_control = 0;
|
||||
unsigned y;
|
||||
|
||||
sweep_8192_divider = 8192;
|
||||
sweep_counter = 0;
|
||||
SampleRAMPos = 0;
|
||||
memset(period_counter, 0, sizeof(period_counter));
|
||||
memset(sample_pos, 0, sizeof(sample_pos));
|
||||
nreg = 1;
|
||||
memset(period, 0, sizeof(period));
|
||||
memset(volume, 0, sizeof(volume));
|
||||
voice_volume = 0;
|
||||
sweep_step = 0;
|
||||
sweep_value = 0;
|
||||
noise_control = 0;
|
||||
control = 0;
|
||||
output_control = 0;
|
||||
|
||||
memset(sample_cache, 0, sizeof(sample_cache));
|
||||
memset(last_val, 0, sizeof(last_val));
|
||||
last_v_val = 0;
|
||||
sweep_8192_divider = 8192;
|
||||
sweep_counter = 0;
|
||||
SampleRAMPos = 0;
|
||||
memset(period_counter, 0, sizeof(period_counter));
|
||||
memset(sample_pos, 0, sizeof(sample_pos));
|
||||
nreg = 1;
|
||||
|
||||
HyperVoice = 0;
|
||||
last_hv_val = 0;
|
||||
memset(sample_cache, 0, sizeof(sample_cache));
|
||||
memset(last_val, 0, sizeof(last_val));
|
||||
last_v_val = 0;
|
||||
|
||||
for(int y = 0; y < 2; y++)
|
||||
sbuf[y]->clear();
|
||||
HyperVoice = 0;
|
||||
last_hv_val = 0;
|
||||
|
||||
for(y = 0; y < 2; y++)
|
||||
sbuf[y]->clear();
|
||||
}
|
||||
|
@ -60,524 +60,510 @@ extern uint16 WSButtonStatus;
|
||||
|
||||
void WSwan_writemem20(uint32 A, uint8 V)
|
||||
{
|
||||
uint32 offset, bank;
|
||||
uint32 offset = A & 0xffff;
|
||||
uint32 bank = (A>>16) & 0xF;
|
||||
|
||||
offset = A & 0xffff;
|
||||
bank = (A>>16) & 0xF;
|
||||
if(!bank) /*RAM*/
|
||||
{
|
||||
WSwan_SoundCheckRAMWrite(offset);
|
||||
wsRAM[offset] = V;
|
||||
|
||||
if(!bank) /*RAM*/
|
||||
{
|
||||
WSwan_SoundCheckRAMWrite(offset);
|
||||
wsRAM[offset] = V;
|
||||
WSWan_TCacheInvalidByAddr(offset);
|
||||
|
||||
WSWan_TCacheInvalidByAddr(offset);
|
||||
|
||||
if(offset>=0xfe00) /*WSC palettes*/
|
||||
WSwan_GfxWSCPaletteRAMWrite(offset, V);
|
||||
}
|
||||
else if(bank == 1) /* SRAM */
|
||||
{
|
||||
if(sram_size)
|
||||
{
|
||||
wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)] = V;
|
||||
}
|
||||
}
|
||||
if(offset>=0xfe00) /*WSC palettes*/
|
||||
WSwan_GfxWSCPaletteRAMWrite(offset, V);
|
||||
}
|
||||
else if(bank == 1) /* SRAM */
|
||||
{
|
||||
if(sram_size)
|
||||
wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)] = V;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8 WSwan_readmem20(uint32 A)
|
||||
{
|
||||
uint32 offset, bank;
|
||||
uint8 bank_num;
|
||||
uint32 offset = A & 0xFFFF;
|
||||
uint32 bank = (A >> 16) & 0xF;
|
||||
|
||||
offset = A & 0xFFFF;
|
||||
bank = (A >> 16) & 0xF;
|
||||
|
||||
switch(bank)
|
||||
{
|
||||
case 0: return wsRAM[offset];
|
||||
case 1: if(sram_size)
|
||||
{
|
||||
return wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)];
|
||||
}
|
||||
else
|
||||
return(0);
|
||||
switch(bank)
|
||||
{
|
||||
case 0:
|
||||
return wsRAM[offset];
|
||||
case 1:
|
||||
if(sram_size)
|
||||
return wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)];
|
||||
return(0);
|
||||
case 2:
|
||||
case 3:
|
||||
return wsCartROM[offset+((BankSelector[bank]&((rom_size>>16)-1))<<16)];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
case 3: return wsCartROM[offset+((BankSelector[bank]&((rom_size>>16)-1))<<16)];
|
||||
bank_num = ((BankSelector[0] & 0xF) << 4) | (bank & 0xf);
|
||||
bank_num &= (rom_size >> 16) - 1;
|
||||
|
||||
default:
|
||||
{
|
||||
uint8 bank_num = ((BankSelector[0] & 0xF) << 4) | (bank & 0xf);
|
||||
bank_num &= (rom_size >> 16) - 1;
|
||||
return(wsCartROM[(bank_num << 16) | offset]);
|
||||
}
|
||||
}
|
||||
return(wsCartROM[(bank_num << 16) | offset]);
|
||||
}
|
||||
|
||||
static void ws_CheckDMA(void)
|
||||
{
|
||||
if(DMAControl & 0x80)
|
||||
{
|
||||
while(DMALength)
|
||||
{
|
||||
WSwan_writemem20(DMADest, WSwan_readmem20(DMASource));
|
||||
if(DMAControl & 0x80)
|
||||
{
|
||||
while(DMALength)
|
||||
{
|
||||
WSwan_writemem20(DMADest, WSwan_readmem20(DMASource));
|
||||
|
||||
DMASource++; // = ((DMASource + 1) & 0xFFFF) | (DMASource & 0xFF0000);
|
||||
//if(!(DMASource & 0xFFFF)) puts("Warning: DMA source bank crossed.");
|
||||
DMADest = ((DMADest + 1) & 0xFFFF) | (DMADest & 0xFF0000);
|
||||
DMALength--;
|
||||
}
|
||||
}
|
||||
DMAControl &= ~0x80;
|
||||
DMASource++; // = ((DMASource + 1) & 0xFFFF) | (DMASource & 0xFF0000);
|
||||
//if(!(DMASource & 0xFFFF)) puts("Warning: DMA source bank crossed.");
|
||||
DMADest = ((DMADest + 1) & 0xFFFF) | (DMADest & 0xFF0000);
|
||||
DMALength--;
|
||||
}
|
||||
}
|
||||
DMAControl &= ~0x80;
|
||||
}
|
||||
|
||||
void WSwan_CheckSoundDMA(void)
|
||||
{
|
||||
if(SoundDMAControl & 0x80)
|
||||
{
|
||||
if(SoundDMALength)
|
||||
{
|
||||
uint8 zebyte = WSwan_readmem20(SoundDMASource);
|
||||
if(SoundDMAControl & 0x80)
|
||||
{
|
||||
if(SoundDMALength)
|
||||
{
|
||||
uint8 zebyte = WSwan_readmem20(SoundDMASource);
|
||||
|
||||
if(SoundDMAControl & 0x08)
|
||||
zebyte ^= 0x80;
|
||||
if(SoundDMAControl & 0x08)
|
||||
zebyte ^= 0x80;
|
||||
|
||||
if(SoundDMAControl & 0x10)
|
||||
WSwan_SoundWrite(0x95, zebyte); // Pick a port, any port?!
|
||||
else
|
||||
WSwan_SoundWrite(0x89, zebyte);
|
||||
if(SoundDMAControl & 0x10)
|
||||
WSwan_SoundWrite(0x95, zebyte); // Pick a port, any port?!
|
||||
else
|
||||
WSwan_SoundWrite(0x89, zebyte);
|
||||
|
||||
SoundDMASource++; // = ((SoundDMASource + 1) & 0xFFFF) | (SoundDMASource & 0xFF0000);
|
||||
//if(!(SoundDMASource & 0xFFFF)) puts("Warning: Sound DMA source bank crossed.");
|
||||
SoundDMALength--;
|
||||
}
|
||||
if(!SoundDMALength)
|
||||
SoundDMAControl &= ~0x80;
|
||||
}
|
||||
SoundDMASource++; // = ((SoundDMASource + 1) & 0xFFFF) | (SoundDMASource & 0xFF0000);
|
||||
//if(!(SoundDMASource & 0xFFFF)) puts("Warning: Sound DMA source bank crossed.");
|
||||
SoundDMALength--;
|
||||
}
|
||||
if(!SoundDMALength)
|
||||
SoundDMAControl &= ~0x80;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 WSwan_readport(uint32 number)
|
||||
{
|
||||
number &= 0xFF;
|
||||
number &= 0xFF;
|
||||
|
||||
if(number >= 0x80 && number <= 0x9F)
|
||||
return(WSwan_SoundRead(number));
|
||||
else if(number <= 0x3F || (number >= 0xA0 && number <= 0xAF) || (number == 0x60))
|
||||
return(WSwan_GfxRead(number));
|
||||
else if((number >= 0xBA && number <= 0xBE) || (number >= 0xC4 && number <= 0xC8))
|
||||
return(WSwan_EEPROMRead(number));
|
||||
else if(number >= 0xCA && number <= 0xCB)
|
||||
return(WSwan_RTCRead(number));
|
||||
else switch(number)
|
||||
{
|
||||
//default: printf("Read: %04x\n", number); break;
|
||||
case 0x40: return(DMASource >> 0);
|
||||
case 0x41: return(DMASource >> 8);
|
||||
case 0x42: return(DMASource >> 16);
|
||||
if(number >= 0x80 && number <= 0x9F)
|
||||
return(WSwan_SoundRead(number));
|
||||
else if(number <= 0x3F || (number >= 0xA0 && number <= 0xAF) || (number == 0x60))
|
||||
return(WSwan_GfxRead(number));
|
||||
else if((number >= 0xBA && number <= 0xBE) || (number >= 0xC4 && number <= 0xC8))
|
||||
return(WSwan_EEPROMRead(number));
|
||||
else if(number >= 0xCA && number <= 0xCB)
|
||||
return(WSwan_RTCRead(number));
|
||||
else switch(number)
|
||||
{
|
||||
//default: printf("Read: %04x\n", number); break;
|
||||
case 0x40: return(DMASource >> 0);
|
||||
case 0x41: return(DMASource >> 8);
|
||||
case 0x42: return(DMASource >> 16);
|
||||
|
||||
case 0x43: return(DMADest >> 16);
|
||||
case 0x44: return(DMADest >> 0);
|
||||
case 0x45: return(DMADest >> 8);
|
||||
case 0x43: return(DMADest >> 16);
|
||||
case 0x44: return(DMADest >> 0);
|
||||
case 0x45: return(DMADest >> 8);
|
||||
|
||||
case 0x46: return(DMALength >> 0);
|
||||
case 0x47: return(DMALength >> 8);
|
||||
case 0x46: return(DMALength >> 0);
|
||||
case 0x47: return(DMALength >> 8);
|
||||
|
||||
case 0x48: return(DMAControl);
|
||||
case 0x48: return(DMAControl);
|
||||
|
||||
case 0xB0:
|
||||
case 0xB2:
|
||||
case 0xB6: return(WSwan_InterruptRead(number));
|
||||
case 0xB0:
|
||||
case 0xB2:
|
||||
case 0xB6: return(WSwan_InterruptRead(number));
|
||||
|
||||
case 0xC0: return(BankSelector[0] | 0x20);
|
||||
case 0xC1: return(BankSelector[1]);
|
||||
case 0xC2: return(BankSelector[2]);
|
||||
case 0xC3: return(BankSelector[3]);
|
||||
case 0xC0: return(BankSelector[0] | 0x20);
|
||||
case 0xC1: return(BankSelector[1]);
|
||||
case 0xC2: return(BankSelector[2]);
|
||||
case 0xC3: return(BankSelector[3]);
|
||||
|
||||
case 0x4a: return(SoundDMASource >> 0);
|
||||
case 0x4b: return(SoundDMASource >> 8);
|
||||
case 0x4c: return(SoundDMASource >> 16);
|
||||
case 0x4e: return(SoundDMALength >> 0);
|
||||
case 0x4f: return(SoundDMALength >> 8);
|
||||
case 0x52: return(SoundDMAControl);
|
||||
case 0x4a: return(SoundDMASource >> 0);
|
||||
case 0x4b: return(SoundDMASource >> 8);
|
||||
case 0x4c: return(SoundDMASource >> 16);
|
||||
case 0x4e: return(SoundDMALength >> 0);
|
||||
case 0x4f: return(SoundDMALength >> 8);
|
||||
case 0x52: return(SoundDMAControl);
|
||||
|
||||
case 0xB1: return(CommData);
|
||||
case 0xB1: return(CommData);
|
||||
|
||||
case 0xb3:
|
||||
{
|
||||
uint8 ret = CommControl & 0xf0;
|
||||
case 0xb3:
|
||||
{
|
||||
uint8 ret = CommControl & 0xf0;
|
||||
|
||||
if(CommControl & 0x80)
|
||||
ret |= 0x4; // Send complete
|
||||
if(CommControl & 0x80)
|
||||
ret |= 0x4; // Send complete
|
||||
|
||||
return(ret);
|
||||
}
|
||||
case 0xb5:
|
||||
{
|
||||
uint8 ret = (ButtonWhich << 4) | ButtonReadLatch;
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
case 0xb5:
|
||||
{
|
||||
uint8 ret = (ButtonWhich << 4) | ButtonReadLatch;
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
if(number >= 0xC8)
|
||||
return(0xD0 | language);
|
||||
if(number >= 0xC8)
|
||||
return(0xD0 | language);
|
||||
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void WSwan_writeport(uint32 IOPort, uint8 V)
|
||||
{
|
||||
IOPort &= 0xFF;
|
||||
IOPort &= 0xFF;
|
||||
|
||||
if(IOPort >= 0x80 && IOPort <= 0x9F)
|
||||
{
|
||||
WSwan_SoundWrite(IOPort, V);
|
||||
}
|
||||
else if((IOPort >= 0x00 && IOPort <= 0x3F) || (IOPort >= 0xA0 && IOPort <= 0xAF) || (IOPort == 0x60))
|
||||
{
|
||||
WSwan_GfxWrite(IOPort, V);
|
||||
}
|
||||
else if((IOPort >= 0xBA && IOPort <= 0xBE) || (IOPort >= 0xC4 && IOPort <= 0xC8))
|
||||
WSwan_EEPROMWrite(IOPort, V);
|
||||
else if(IOPort >= 0xCA && IOPort <= 0xCB)
|
||||
WSwan_RTCWrite(IOPort, V);
|
||||
else switch(IOPort)
|
||||
{
|
||||
//default: printf("%04x %02x\n", IOPort, V); break;
|
||||
if(IOPort >= 0x80 && IOPort <= 0x9F)
|
||||
WSwan_SoundWrite(IOPort, V);
|
||||
else if((IOPort >= 0x00 && IOPort <= 0x3F) || (IOPort >= 0xA0 && IOPort <= 0xAF) || (IOPort == 0x60))
|
||||
WSwan_GfxWrite(IOPort, V);
|
||||
else if((IOPort >= 0xBA && IOPort <= 0xBE) || (IOPort >= 0xC4 && IOPort <= 0xC8))
|
||||
WSwan_EEPROMWrite(IOPort, V);
|
||||
else if(IOPort >= 0xCA && IOPort <= 0xCB)
|
||||
WSwan_RTCWrite(IOPort, V);
|
||||
else switch(IOPort)
|
||||
{
|
||||
//default: printf("%04x %02x\n", IOPort, V); break;
|
||||
|
||||
case 0x40: DMASource &= 0xFFFF00; DMASource |= (V << 0); break;
|
||||
case 0x41: DMASource &= 0xFF00FF; DMASource |= (V << 8); break;
|
||||
case 0x42: DMASource &= 0x00FFFF; DMASource |= ((V & 0x0F) << 16); break;
|
||||
case 0x40: DMASource &= 0xFFFF00; DMASource |= (V << 0); break;
|
||||
case 0x41: DMASource &= 0xFF00FF; DMASource |= (V << 8); break;
|
||||
case 0x42: DMASource &= 0x00FFFF; DMASource |= ((V & 0x0F) << 16); break;
|
||||
|
||||
case 0x43: DMADest &= 0x00FFFF; DMADest |= ((V & 0x0F) << 16); break;
|
||||
case 0x44: DMADest &= 0xFFFF00; DMADest |= (V << 0); break;
|
||||
case 0x45: DMADest &= 0xFF00FF; DMADest |= (V << 8); break;
|
||||
case 0x43: DMADest &= 0x00FFFF; DMADest |= ((V & 0x0F) << 16); break;
|
||||
case 0x44: DMADest &= 0xFFFF00; DMADest |= (V << 0); break;
|
||||
case 0x45: DMADest &= 0xFF00FF; DMADest |= (V << 8); break;
|
||||
|
||||
case 0x46: DMALength &= 0xFF00; DMALength |= (V << 0); break;
|
||||
case 0x47: DMALength &= 0x00FF; DMALength |= (V << 8); break;
|
||||
case 0x46: DMALength &= 0xFF00; DMALength |= (V << 0); break;
|
||||
case 0x47: DMALength &= 0x00FF; DMALength |= (V << 8); break;
|
||||
|
||||
case 0x48: DMAControl = V;
|
||||
//if(V&0x80)
|
||||
// printf("DMA%02x: %08x %08x %08x\n", V, DMASource, DMADest, DMALength);
|
||||
ws_CheckDMA();
|
||||
break;
|
||||
case 0x48: DMAControl = V;
|
||||
//if(V&0x80)
|
||||
// printf("DMA%02x: %08x %08x %08x\n", V, DMASource, DMADest, DMALength);
|
||||
ws_CheckDMA();
|
||||
break;
|
||||
|
||||
case 0x4a: SoundDMASource &= 0xFFFF00; SoundDMASource |= (V << 0); break;
|
||||
case 0x4b: SoundDMASource &= 0xFF00FF; SoundDMASource |= (V << 8); break;
|
||||
case 0x4c: SoundDMASource &= 0x00FFFF; SoundDMASource |= (V << 16); break;
|
||||
//case 0x4d: break; // Unused?
|
||||
case 0x4e: SoundDMALength &= 0xFF00; SoundDMALength |= (V << 0); break;
|
||||
case 0x4f: SoundDMALength &= 0x00FF; SoundDMALength |= (V << 8); break;
|
||||
//case 0x50: break; // Unused?
|
||||
//case 0x51: break; // Unused?
|
||||
case 0x52: SoundDMAControl = V;
|
||||
//if(V & 0x80) printf("Sound DMA: %02x, %08x %08x\n", V, SoundDMASource, SoundDMALength);
|
||||
break;
|
||||
case 0x4a: SoundDMASource &= 0xFFFF00; SoundDMASource |= (V << 0); break;
|
||||
case 0x4b: SoundDMASource &= 0xFF00FF; SoundDMASource |= (V << 8); break;
|
||||
case 0x4c: SoundDMASource &= 0x00FFFF; SoundDMASource |= (V << 16); break;
|
||||
//case 0x4d: break; // Unused?
|
||||
case 0x4e: SoundDMALength &= 0xFF00; SoundDMALength |= (V << 0); break;
|
||||
case 0x4f: SoundDMALength &= 0x00FF; SoundDMALength |= (V << 8); break;
|
||||
//case 0x50: break; // Unused?
|
||||
//case 0x51: break; // Unused?
|
||||
case 0x52: SoundDMAControl = V;
|
||||
//if(V & 0x80) printf("Sound DMA: %02x, %08x %08x\n", V, SoundDMASource, SoundDMALength);
|
||||
break;
|
||||
|
||||
case 0xB0:
|
||||
case 0xB2:
|
||||
case 0xB6: WSwan_InterruptWrite(IOPort, V); break;
|
||||
case 0xB0:
|
||||
case 0xB2:
|
||||
case 0xB6: WSwan_InterruptWrite(IOPort, V); break;
|
||||
|
||||
case 0xB1: CommData = V; break;
|
||||
case 0xB3: CommControl = V & 0xF0; break;
|
||||
case 0xB1: CommData = V; break;
|
||||
case 0xB3: CommControl = V & 0xF0; break;
|
||||
|
||||
case 0xb5: ButtonWhich = V >> 4;
|
||||
ButtonReadLatch = 0;
|
||||
case 0xb5: ButtonWhich = V >> 4;
|
||||
ButtonReadLatch = 0;
|
||||
|
||||
if(ButtonWhich & 0x4) /*buttons*/
|
||||
ButtonReadLatch |= ((WSButtonStatus >> 8) << 1) & 0xF;
|
||||
if(ButtonWhich & 0x4) /*buttons*/
|
||||
ButtonReadLatch |= ((WSButtonStatus >> 8) << 1) & 0xF;
|
||||
|
||||
if(ButtonWhich & 0x2) /* H/X cursors */
|
||||
ButtonReadLatch |= WSButtonStatus & 0xF;
|
||||
if(ButtonWhich & 0x2) /* H/X cursors */
|
||||
ButtonReadLatch |= WSButtonStatus & 0xF;
|
||||
|
||||
if(ButtonWhich & 0x1) /* V/Y cursors */
|
||||
ButtonReadLatch |= (WSButtonStatus >> 4) & 0xF;
|
||||
break;
|
||||
if(ButtonWhich & 0x1) /* V/Y cursors */
|
||||
ButtonReadLatch |= (WSButtonStatus >> 4) & 0xF;
|
||||
break;
|
||||
|
||||
case 0xC0: BankSelector[0] = V & 0xF; break;
|
||||
case 0xC1: BankSelector[1] = V; break;
|
||||
case 0xC2: BankSelector[2] = V; break;
|
||||
case 0xC3: BankSelector[3] = V; break;
|
||||
}
|
||||
case 0xC0: BankSelector[0] = V & 0xF; break;
|
||||
case 0xC1: BankSelector[1] = V; break;
|
||||
case 0xC2: BankSelector[2] = V; break;
|
||||
case 0xC3: BankSelector[3] = V; break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WANT_DEBUGGER
|
||||
static void GetAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint8 *Buffer)
|
||||
{
|
||||
if(!strcmp(name, "ram"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
Address &= wsRAMSize - 1;
|
||||
*Buffer = wsRAM[Address];
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "physical"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
Address &= 0xFFFFF;
|
||||
*Buffer = WSwan_readmem20(Address);
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "cs") || !strcmp(name, "ds") || !strcmp(name, "ss") || !strcmp(name, "es"))
|
||||
{
|
||||
uint32 segment;
|
||||
uint32 phys_address;
|
||||
if(!strcmp(name, "ram"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
Address &= wsRAMSize - 1;
|
||||
*Buffer = wsRAM[Address];
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "physical"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
Address &= 0xFFFFF;
|
||||
*Buffer = WSwan_readmem20(Address);
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "cs") || !strcmp(name, "ds") || !strcmp(name, "ss") || !strcmp(name, "es"))
|
||||
{
|
||||
uint32 segment;
|
||||
uint32 phys_address;
|
||||
|
||||
if(!strcmp(name, "cs"))
|
||||
segment = v30mz_get_reg(NEC_PS);
|
||||
else if(!strcmp(name, "ss"))
|
||||
segment = v30mz_get_reg(NEC_SS);
|
||||
else if(!strcmp(name, "ds"))
|
||||
segment = v30mz_get_reg(NEC_DS0);
|
||||
else if(!strcmp(name, "es"))
|
||||
segment = v30mz_get_reg(NEC_DS1);
|
||||
if(!strcmp(name, "cs"))
|
||||
segment = v30mz_get_reg(NEC_PS);
|
||||
else if(!strcmp(name, "ss"))
|
||||
segment = v30mz_get_reg(NEC_SS);
|
||||
else if(!strcmp(name, "ds"))
|
||||
segment = v30mz_get_reg(NEC_DS0);
|
||||
else if(!strcmp(name, "es"))
|
||||
segment = v30mz_get_reg(NEC_DS1);
|
||||
|
||||
phys_address = (Address + (segment << 4)) & 0xFFFFF;
|
||||
phys_address = (Address + (segment << 4)) & 0xFFFFF;
|
||||
|
||||
GetAddressSpaceBytes("physical", phys_address, Length, Buffer);
|
||||
}
|
||||
GetAddressSpaceBytes("physical", phys_address, Length, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void PutAddressSpaceBytes(const char *name, uint32 Address, uint32 Length, uint32 Granularity, bool hl, const uint8 *Buffer)
|
||||
{
|
||||
if(!strcmp(name, "ram"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
Address &= wsRAMSize - 1;
|
||||
wsRAM[Address] = *Buffer;
|
||||
WSWan_TCacheInvalidByAddr(Address);
|
||||
if(Address >= 0xfe00)
|
||||
WSwan_GfxWSCPaletteRAMWrite(Address, *Buffer);
|
||||
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "physical"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
uint32 offset, bank;
|
||||
|
||||
Address &= 0xFFFFF;
|
||||
|
||||
offset = Address & 0xFFFF;
|
||||
bank = (Address >> 16) & 0xF;
|
||||
|
||||
switch(bank)
|
||||
if(!strcmp(name, "ram"))
|
||||
{
|
||||
case 0: wsRAM[offset & (wsRAMSize - 1)] = *Buffer;
|
||||
WSWan_TCacheInvalidByAddr(offset & (wsRAMSize - 1));
|
||||
if(Address >= 0xfe00)
|
||||
WSwan_GfxWSCPaletteRAMWrite(offset & (wsRAMSize - 1), *Buffer);
|
||||
break;
|
||||
case 1: if(sram_size)
|
||||
wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)] = *Buffer;
|
||||
break;
|
||||
case 2:
|
||||
case 3: wsCartROM[offset+((BankSelector[bank]&((rom_size>>16)-1))<<16)] = *Buffer;
|
||||
break;
|
||||
while(Length--)
|
||||
{
|
||||
Address &= wsRAMSize - 1;
|
||||
wsRAM[Address] = *Buffer;
|
||||
WSWan_TCacheInvalidByAddr(Address);
|
||||
if(Address >= 0xfe00)
|
||||
WSwan_GfxWSCPaletteRAMWrite(Address, *Buffer);
|
||||
|
||||
default:
|
||||
{
|
||||
uint8 bank_num = ((BankSelector[0] & 0xF) << 4) | (bank & 0xf);
|
||||
bank_num &= (rom_size >> 16) - 1;
|
||||
wsCartROM[(bank_num << 16) | offset] = *Buffer;
|
||||
}
|
||||
break;
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "physical"))
|
||||
{
|
||||
while(Length--)
|
||||
{
|
||||
uint32 offset, bank;
|
||||
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "cs") || !strcmp(name, "ds") || !strcmp(name, "ss") || !strcmp(name, "es"))
|
||||
{
|
||||
uint32 segment;
|
||||
uint32 phys_address;
|
||||
Address &= 0xFFFFF;
|
||||
|
||||
if(!strcmp(name, "cs"))
|
||||
segment = v30mz_get_reg(NEC_PS);
|
||||
else if(!strcmp(name, "ss"))
|
||||
segment = v30mz_get_reg(NEC_SS);
|
||||
else if(!strcmp(name, "ds"))
|
||||
segment = v30mz_get_reg(NEC_DS0);
|
||||
else if(!strcmp(name, "es"))
|
||||
segment = v30mz_get_reg(NEC_DS1);
|
||||
offset = Address & 0xFFFF;
|
||||
bank = (Address >> 16) & 0xF;
|
||||
|
||||
phys_address = (Address + (segment << 4)) & 0xFFFFF;
|
||||
switch(bank)
|
||||
{
|
||||
case 0: wsRAM[offset & (wsRAMSize - 1)] = *Buffer;
|
||||
WSWan_TCacheInvalidByAddr(offset & (wsRAMSize - 1));
|
||||
if(Address >= 0xfe00)
|
||||
WSwan_GfxWSCPaletteRAMWrite(offset & (wsRAMSize - 1), *Buffer);
|
||||
break;
|
||||
case 1: if(sram_size)
|
||||
wsSRAM[(offset | (BankSelector[1] << 16)) & (sram_size - 1)] = *Buffer;
|
||||
break;
|
||||
case 2:
|
||||
case 3: wsCartROM[offset+((BankSelector[bank]&((rom_size>>16)-1))<<16)] = *Buffer;
|
||||
break;
|
||||
|
||||
PutAddressSpaceBytes("physical", phys_address, Length, Granularity, hl, Buffer);
|
||||
}
|
||||
default:
|
||||
{
|
||||
uint8 bank_num = ((BankSelector[0] & 0xF) << 4) | (bank & 0xf);
|
||||
bank_num &= (rom_size >> 16) - 1;
|
||||
wsCartROM[(bank_num << 16) | offset] = *Buffer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Address++;
|
||||
Buffer++;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(name, "cs") || !strcmp(name, "ds") || !strcmp(name, "ss") || !strcmp(name, "es"))
|
||||
{
|
||||
uint32 segment;
|
||||
uint32 phys_address;
|
||||
|
||||
if(!strcmp(name, "cs"))
|
||||
segment = v30mz_get_reg(NEC_PS);
|
||||
else if(!strcmp(name, "ss"))
|
||||
segment = v30mz_get_reg(NEC_SS);
|
||||
else if(!strcmp(name, "ds"))
|
||||
segment = v30mz_get_reg(NEC_DS0);
|
||||
else if(!strcmp(name, "es"))
|
||||
segment = v30mz_get_reg(NEC_DS1);
|
||||
|
||||
phys_address = (Address + (segment << 4)) & 0xFFFFF;
|
||||
|
||||
PutAddressSpaceBytes("physical", phys_address, Length, Granularity, hl, Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 WSwan_MemoryGetRegister(const unsigned int id, char *special, const uint32 special_len)
|
||||
{
|
||||
uint32 ret = 0;
|
||||
uint32 ret = 0;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case MEMORY_GSREG_ROMBBSLCT:
|
||||
ret = BankSelector[0];
|
||||
switch(id)
|
||||
{
|
||||
case MEMORY_GSREG_ROMBBSLCT:
|
||||
ret = BankSelector[0];
|
||||
|
||||
if(special)
|
||||
{
|
||||
trio_snprintf(special, special_len, "((0x%02x * 0x100000) %% 0x%08x) + 20 bit address = 0x%08x + 20 bit address", BankSelector[0], rom_size, (BankSelector[0] * 0x100000) & (rom_size - 1));
|
||||
}
|
||||
break;
|
||||
if(special)
|
||||
{
|
||||
trio_snprintf(special, special_len, "((0x%02x * 0x100000) %% 0x%08x) + 20 bit address = 0x%08x + 20 bit address", BankSelector[0], rom_size, (BankSelector[0] * 0x100000) & (rom_size - 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case MEMORY_GSREG_BNK1SLCT:
|
||||
ret = BankSelector[1];
|
||||
break;
|
||||
case MEMORY_GSREG_BNK1SLCT:
|
||||
ret = BankSelector[1];
|
||||
break;
|
||||
|
||||
case MEMORY_GSREG_BNK2SLCT:
|
||||
ret = BankSelector[2];
|
||||
break;
|
||||
case MEMORY_GSREG_BNK2SLCT:
|
||||
ret = BankSelector[2];
|
||||
break;
|
||||
|
||||
case MEMORY_GSREG_BNK3SLCT:
|
||||
ret = BankSelector[3];
|
||||
break;
|
||||
}
|
||||
case MEMORY_GSREG_BNK3SLCT:
|
||||
ret = BankSelector[3];
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void WSwan_MemorySetRegister(const unsigned int id, uint32 value)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case MEMORY_GSREG_ROMBBSLCT:
|
||||
BankSelector[0] = value;
|
||||
break;
|
||||
switch(id)
|
||||
{
|
||||
case MEMORY_GSREG_ROMBBSLCT:
|
||||
BankSelector[0] = value;
|
||||
break;
|
||||
|
||||
case MEMORY_GSREG_BNK1SLCT:
|
||||
BankSelector[1] = value;
|
||||
break;
|
||||
case MEMORY_GSREG_BNK1SLCT:
|
||||
BankSelector[1] = value;
|
||||
break;
|
||||
|
||||
case MEMORY_GSREG_BNK2SLCT:
|
||||
BankSelector[2] = value;
|
||||
break;
|
||||
case MEMORY_GSREG_BNK2SLCT:
|
||||
BankSelector[2] = value;
|
||||
break;
|
||||
|
||||
case MEMORY_GSREG_BNK3SLCT:
|
||||
BankSelector[3] = value;
|
||||
break;
|
||||
}
|
||||
case MEMORY_GSREG_BNK3SLCT:
|
||||
BankSelector[3] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void WSwan_MemoryKill(void)
|
||||
{
|
||||
if((sram_size || eeprom_size) && !SkipSL)
|
||||
{
|
||||
std::vector<PtrLengthPair> EvilRams;
|
||||
if((sram_size || eeprom_size) && !SkipSL)
|
||||
{
|
||||
std::vector<PtrLengthPair> EvilRams;
|
||||
|
||||
if(eeprom_size)
|
||||
EvilRams.push_back(PtrLengthPair(wsEEPROM, eeprom_size));
|
||||
if(eeprom_size)
|
||||
EvilRams.push_back(PtrLengthPair(wsEEPROM, eeprom_size));
|
||||
|
||||
if(sram_size)
|
||||
EvilRams.push_back(PtrLengthPair(wsSRAM, sram_size));
|
||||
if(sram_size)
|
||||
EvilRams.push_back(PtrLengthPair(wsSRAM, sram_size));
|
||||
|
||||
MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, EvilRams);
|
||||
}
|
||||
MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, EvilRams);
|
||||
}
|
||||
|
||||
if(wsSRAM)
|
||||
{
|
||||
free(wsSRAM);
|
||||
wsSRAM = NULL;
|
||||
}
|
||||
if(wsSRAM)
|
||||
free(wsSRAM);
|
||||
wsSRAM = NULL;
|
||||
}
|
||||
|
||||
void WSwan_MemoryInit(bool lang, bool IsWSC, uint32 ssize, bool SkipSaveLoad)
|
||||
{
|
||||
const uint16 byear = MDFN_GetSettingUI("wswan.byear");
|
||||
const uint8 bmonth = MDFN_GetSettingUI("wswan.bmonth");
|
||||
const uint8 bday = MDFN_GetSettingUI("wswan.bday");
|
||||
const uint8 sex = MDFN_GetSettingI("wswan.sex");
|
||||
const uint8 blood = MDFN_GetSettingI("wswan.blood");
|
||||
const uint16 byear = MDFN_GetSettingUI("wswan.byear");
|
||||
const uint8 bmonth = MDFN_GetSettingUI("wswan.bmonth");
|
||||
const uint8 bday = MDFN_GetSettingUI("wswan.bday");
|
||||
const uint8 sex = MDFN_GetSettingI("wswan.sex");
|
||||
const uint8 blood = MDFN_GetSettingI("wswan.blood");
|
||||
|
||||
language = lang;
|
||||
SkipSL = SkipSaveLoad;
|
||||
language = lang;
|
||||
SkipSL = SkipSaveLoad;
|
||||
|
||||
wsRAMSize = 65536;
|
||||
sram_size = ssize;
|
||||
wsRAMSize = 65536;
|
||||
sram_size = ssize;
|
||||
|
||||
#ifdef WANT_DEBUGGER
|
||||
{
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "physical", "CPU Physical", 20);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ram", "RAM", (int)(log(wsRAMSize) / log(2)));
|
||||
#ifdef WANT_DEBUGGER
|
||||
{
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "physical", "CPU Physical", 20);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ram", "RAM", (int)(log(wsRAMSize) / log(2)));
|
||||
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "cs", "Code Segment", 16);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ss", "Stack Segment", 16);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ds", "Data Segment", 16);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "es", "Extra Segment", 16);
|
||||
}
|
||||
#endif
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "cs", "Code Segment", 16);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ss", "Stack Segment", 16);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "ds", "Data Segment", 16);
|
||||
ASpace_Add(GetAddressSpaceBytes, PutAddressSpaceBytes, "es", "Extra Segment", 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
// WSwan_EEPROMInit() will also clear wsEEPROM
|
||||
WSwan_EEPROMInit(MDFN_GetSettingS("wswan.name").c_str(), byear, bmonth, bday, sex, blood);
|
||||
// WSwan_EEPROMInit() will also clear wsEEPROM
|
||||
WSwan_EEPROMInit(MDFN_GetSettingS("wswan.name").c_str(), byear, bmonth, bday, sex, blood);
|
||||
|
||||
if(sram_size)
|
||||
{
|
||||
wsSRAM = (uint8*)malloc(sram_size);
|
||||
memset(wsSRAM, 0, sram_size);
|
||||
}
|
||||
|
||||
if((sram_size || eeprom_size) && !SkipSL)
|
||||
{
|
||||
FILE *savegame_fp;
|
||||
|
||||
savegame_fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb");
|
||||
if(savegame_fp)
|
||||
{
|
||||
if(eeprom_size)
|
||||
gzread(savegame_fp, wsEEPROM, eeprom_size);
|
||||
if(sram_size)
|
||||
gzread(savegame_fp, wsSRAM, sram_size);
|
||||
gzclose(savegame_fp);
|
||||
}
|
||||
}
|
||||
{
|
||||
wsSRAM = (uint8*)malloc(sram_size);
|
||||
memset(wsSRAM, 0, sram_size);
|
||||
}
|
||||
|
||||
MDFNMP_AddRAM(wsRAMSize, 0x00000, wsRAM);
|
||||
if((sram_size || eeprom_size) && !SkipSL)
|
||||
{
|
||||
FILE *savegame_fp;
|
||||
|
||||
if(sram_size)
|
||||
MDFNMP_AddRAM(sram_size, 0x10000, wsSRAM);
|
||||
savegame_fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb");
|
||||
if(savegame_fp)
|
||||
{
|
||||
if(eeprom_size)
|
||||
gzread(savegame_fp, wsEEPROM, eeprom_size);
|
||||
if(sram_size)
|
||||
gzread(savegame_fp, wsSRAM, sram_size);
|
||||
gzclose(savegame_fp);
|
||||
}
|
||||
}
|
||||
|
||||
MDFNMP_AddRAM(wsRAMSize, 0x00000, wsRAM);
|
||||
|
||||
if(sram_size)
|
||||
MDFNMP_AddRAM(sram_size, 0x10000, wsSRAM);
|
||||
}
|
||||
|
||||
void WSwan_MemoryReset(void)
|
||||
{
|
||||
memset(wsRAM, 0, 65536);
|
||||
memset(wsRAM, 0, 65536);
|
||||
|
||||
wsRAM[0x75AC] = 0x41;
|
||||
wsRAM[0x75AD] = 0x5F;
|
||||
wsRAM[0x75AE] = 0x43;
|
||||
wsRAM[0x75AF] = 0x31;
|
||||
wsRAM[0x75B0] = 0x6E;
|
||||
wsRAM[0x75B1] = 0x5F;
|
||||
wsRAM[0x75B2] = 0x63;
|
||||
wsRAM[0x75B3] = 0x31;
|
||||
wsRAM[0x75AC] = 0x41;
|
||||
wsRAM[0x75AD] = 0x5F;
|
||||
wsRAM[0x75AE] = 0x43;
|
||||
wsRAM[0x75AF] = 0x31;
|
||||
wsRAM[0x75B0] = 0x6E;
|
||||
wsRAM[0x75B1] = 0x5F;
|
||||
wsRAM[0x75B2] = 0x63;
|
||||
wsRAM[0x75B3] = 0x31;
|
||||
|
||||
memset(BankSelector, 0, sizeof(BankSelector));
|
||||
ButtonWhich = 0;
|
||||
ButtonReadLatch = 0;
|
||||
DMASource = 0;
|
||||
DMADest = 0;
|
||||
DMALength = 0;
|
||||
DMAControl = 0;
|
||||
memset(BankSelector, 0, sizeof(BankSelector));
|
||||
ButtonWhich = 0;
|
||||
ButtonReadLatch = 0;
|
||||
DMASource = 0;
|
||||
DMADest = 0;
|
||||
DMALength = 0;
|
||||
DMAControl = 0;
|
||||
|
||||
SoundDMASource = 0;
|
||||
SoundDMALength = 0;
|
||||
SoundDMAControl = 0;
|
||||
SoundDMASource = 0;
|
||||
SoundDMALength = 0;
|
||||
SoundDMAControl = 0;
|
||||
|
||||
CommControl = 0;
|
||||
CommData = 0;
|
||||
CommControl = 0;
|
||||
CommData = 0;
|
||||
}
|
||||
|
||||
int WSwan_MemoryStateAction(StateMem *sm, int load, int data_only)
|
||||
|
Loading…
Reference in New Issue
Block a user