[PCE] ADPCM playback more or less working correctly now

plus some cleanup
This commit is contained in:
beirich 2011-09-05 17:45:01 +00:00
parent 08ec88319f
commit a8aaaef45e
32 changed files with 452 additions and 405 deletions

View File

@ -1,4 +1,5 @@
using System;
using BizHawk.Emulation.Consoles.TurboGrafx;
// Do not modify this file directly! This is GENERATED code.
// Please open the CpuCoreGenerator solution and make your modifications there.
@ -43,6 +44,11 @@ namespace BizHawk.Emulation.CPUs.H6280
if (IRQ2Assert && FlagI == false && LagIFlag == false && (IRQControlByte & IRQ2Selector) == 0 && InBlockTransfer == false)
{
Console.WriteLine("============================================================");
Console.WriteLine(" ENTERING IRQ2");
Console.WriteLine(" 1802: {0:X2}, 1803: {1:X2}, && {2:X2}",PCEngine.CdIoPorts[2], PCEngine.CdIoPorts[3], PCEngine.CdIoPorts[2] & PCEngine.CdIoPorts[3]);
Console.WriteLine("============================================================");
WriteMemory((ushort)(S-- + 0x2100), (byte)(PC >> 8));
WriteMemory((ushort)(S-- + 0x2100), (byte)PC);
WriteMemory((ushort)(S-- + 0x2100), (byte)(P & (~0x10)));
@ -2307,7 +2313,7 @@ namespace BizHawk.Emulation.CPUs.H6280
}
}
}
ThinkAction();
ThinkAction(delta);
}
}
}

View File

@ -237,7 +237,7 @@ namespace BizHawk.Emulation.CPUs.H6280
public byte ReadIrqStatus()
{
byte status = 0;
if (IRQ2Assert) status |= 1;
if (IRQ2Assert) status |= 1;
if (IRQ1Assert) status |= 2;
if (TimerAssert) status |= 4;
return status;
@ -333,7 +333,7 @@ namespace BizHawk.Emulation.CPUs.H6280
public Func<int, byte> ReadMemory21;
public Action<int, byte> WriteMemory21;
public Action<int, byte> WriteVDC;
public Action ThinkAction = delegate { };
public Action<int> ThinkAction = delegate { };
public byte ReadMemory(ushort address)
{

View File

@ -5,20 +5,19 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
{
public sealed class ADPCM
{
public ushort adpcm_io_address;
public ushort adpcm_read_address;
public ushort adpcm_write_address;
public ushort adpcm_length;
public ushort IOAddress;
public ushort ReadAddress;
public ushort WriteAddress;
public ushort AdpcmLength;
public int adpcm_read_timer, adpcm_write_timer;
public byte adpcm_read_buffer, adpcm_write_buffer;
public bool adpcm_read_pending, adpcm_write_pending;
public int ReadTimer, WriteTimer;
public byte ReadBuffer, WriteBuffer;
public bool ReadPending, WritePending;
public byte[] RAM = new byte[0x10000];
public MetaspuSoundProvider SoundProvider = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V);
long LastThink;
float adpcm_playback_timer;
float Playback44khzTimer;
ScsiCDBus SCSI;
PCEngine pce;
@ -29,59 +28,40 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
SCSI = scsi;
}
static readonly int[] StepSize =
{
16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 140, 143,
157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
494, 544, 598, 658, 724, 796, 876, 963,1060,1166,1282,1411,
1552
};
static readonly int[] StepFactor = { -1, -1, -1, -1, 2, 4, 6, 8 };
int AddClamped(int num1, int num2, int min, int max)
{
int result = num1 + num2;
if (result < min) return min;
if (result > max) return max;
return result;
}
public void AdpcmControlWrite(byte value)
{
Log.Error("CD","ADPCM CONTROL WRITE {0:X2}",value);
//Log.Error("CD","ADPCM CONTROL WRITE {0:X2}",value);
if ((Port180D & 0x80) != 0 && (value & 0x80) == 0)
{
Log.Note("CD", "Reset ADPCM!");
adpcm_read_address = 0;
adpcm_write_address = 0;
adpcm_io_address = 0;
ReadAddress = 0;
WriteAddress = 0;
IOAddress = 0;
nibble = false;
playingSample = 0;
adpcm_playback_timer = 0;
Playback44khzTimer = 0;
magnitude = 0;
AdpcmIsPlaying = false;
}
if ((value & 8) != 0)
{
adpcm_read_address = adpcm_io_address;
ReadAddress = IOAddress;
if ((value & 4) == 0)
adpcm_read_address--;
ReadAddress--;
}
if ((Port180D & 2) == 0 && (value & 2) != 0)
{
adpcm_write_address = adpcm_io_address;
WriteAddress = IOAddress;
if ((value & 1) == 0)
adpcm_write_address--;
WriteAddress--;
}
if ((value & 0x10) != 0)
{
adpcm_length = adpcm_io_address;
Console.WriteLine("SET LENGTH={0:X4}", adpcm_length);
AdpcmLength = IOAddress;
//Console.WriteLine("SET LENGTH={0:X4}", adpcm_length);
}
if (AdpcmIsPlaying && (value & 0x20) == 0)
@ -89,12 +69,15 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
if (AdpcmIsPlaying == false && (value & 0x20) != 0)
{
Console.WriteLine("Start playing!");
if ((value & 0x40) == 0)
Console.WriteLine("a thing thats normally set is not set");
Console.WriteLine("Start playing! READ {0:X4} LENGTH {1:X4}", ReadAddress, AdpcmLength);
AdpcmIsPlaying = true;
nibble = false;
playingSample = 0;
adpcm_playback_timer = 0;
// nibble = true;
playingSample = 2048;
magnitude = 0;
Playback44khzTimer = 0;
}
Port180D = value;
@ -102,98 +85,34 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public bool AdpcmIsPlaying { get; private set; }
public bool AdpcmBusyWriting { get { return AdpcmCdDmaRequested; } }
public bool AdpcmBusyReading { get { return adpcm_read_pending; } }
Random rnd = new Random();
public bool AdpcmBusyReading { get { return ReadPending; } }
int playingSample;
int nextSampleTimer = 0;
bool nibble;
int magnitude;
void DecodeAdpcmSample()
public void Think(int cycles)
{
// get sample. it's one nibble.
byte sample;
if (nibble == false)
Playback44khzTimer -= cycles;
if (Playback44khzTimer < 0)
{
sample = (byte) (RAM[adpcm_read_address] >> 4);
nibble = true;
} else {
sample = (byte)(RAM[adpcm_read_address] & 0xF);
nibble = false;
adpcm_length--;
adpcm_read_address++;
}
bool positive = (sample & 8) == 0;
int mag = sample & 7;
int m = StepFactor[mag];
magnitude = AddClamped(magnitude, m, 0, 48);
int adjustment = StepSize[magnitude];
if (positive == false) adjustment *= -1;
playingSample = AddClamped(playingSample, adjustment, 0, 4095);
adpcm_length--;
}
void AdpcmEmitSample()
{
if (AdpcmIsPlaying == false)
SoundProvider.buffer.enqueue_sample(0, 0);
else
{
int rate = 16 - (Port180E & 0x0F);
float khz = 32 / rate;
if (nextSampleTimer == 0)
{
DecodeAdpcmSample();
nextSampleTimer = 4;
}
nextSampleTimer--;
if (adpcm_length == 0)
{
AdpcmIsPlaying = false;
}
short adjustedSample = (short)((playingSample - 2048) << 3);
SoundProvider.buffer.enqueue_sample(adjustedSample, adjustedSample);
}
}
public void Think()
{
int cycles = (int) (pce.Cpu.TotalExecutedCycles - LastThink);
LastThink = pce.Cpu.TotalExecutedCycles;
adpcm_playback_timer -= cycles;
if (adpcm_playback_timer < 0)
{
adpcm_playback_timer += 162.81f; // # of CPU cycles that translate to one 44100hz sample.
Playback44khzTimer += 162.81f; // # of CPU cycles that translate to one 44100hz sample.
AdpcmEmitSample();
}
if (adpcm_read_timer > 0) adpcm_read_timer -= cycles;
if (adpcm_write_timer > 0) adpcm_write_timer -= cycles;
if (ReadTimer > 0) ReadTimer -= cycles;
if (WriteTimer > 0) WriteTimer -= cycles;
if (adpcm_read_pending && adpcm_read_timer <= 0)
if (ReadPending && ReadTimer <= 0)
{
adpcm_read_buffer = RAM[adpcm_read_address++];
adpcm_read_pending = false;
if (adpcm_length > ushort.MinValue)
adpcm_length--;
ReadBuffer = RAM[ReadAddress++];
ReadPending = false;
if (AdpcmLength > ushort.MinValue)
AdpcmLength--;
}
if (adpcm_write_pending && adpcm_write_timer <= 0)
if (WritePending && WriteTimer <= 0)
{
RAM[adpcm_write_address++] = adpcm_write_buffer;
adpcm_write_pending = false;
if (adpcm_length < ushort.MaxValue)
adpcm_length++;
RAM[WriteAddress++] = WriteBuffer;
WritePending = false;
if (AdpcmLength < ushort.MaxValue)
AdpcmLength++;
}
if (AdpcmCdDmaRequested)
@ -201,7 +120,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
if (SCSI.REQ && SCSI.IO && !SCSI.CD && !SCSI.ACK)
{
byte dmaByte = SCSI.DataBits;
RAM[adpcm_write_address++] = dmaByte;
RAM[WriteAddress++] = dmaByte;
SCSI.ACK = false;
SCSI.REQ = false;
@ -226,21 +145,121 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
{
set
{
adpcm_write_buffer = value;
adpcm_write_timer = 24;
adpcm_write_pending = true;
WriteBuffer = value;
WriteTimer = 24;
WritePending = true;
}
get
{
adpcm_read_pending = true;
adpcm_read_timer = 24;
return adpcm_read_buffer;
ReadPending = true;
ReadTimer = 24;
return ReadBuffer;
}
}
public byte Port180B;
public byte Port180D;
public byte Port180E;
byte port180E;
public byte Port180E
{
get { return port180E; }
set
{
port180E = value;
float khz = 32 / (16 - (Port180E & 0x0F));
destSamplesPerSourceSample = 44.1f / khz;
}
}
// ***************************************************************************
// Playback Functions
// ***************************************************************************
static readonly int[] StepSize =
{
16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 140, 143,
157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
494, 544, 598, 658, 724, 796, 876, 963,1060,1166,1282,1411,
1552
};
static readonly int[] StepFactor = { -1, -1, -1, -1, 2, 4, 6, 8 };
int playingSample;
float nextSampleTimer = 0;
float destSamplesPerSourceSample;
bool nibble;
int magnitude;
int AddClamped(int num1, int num2, int min, int max)
{
int result = num1 + num2;
if (result < min) return min;
if (result > max) return max;
return result;
}
byte ReadNibble()
{
byte value;
if (nibble == false)
value = (byte)(RAM[ReadAddress] >> 4);
else
{
value = (byte)(RAM[ReadAddress] & 0xF);
AdpcmLength--;
ReadAddress++;
}
nibble ^= true;
return value;
}
void DecodeAdpcmSample()
{
// get sample. it's one nibble.
byte sample = ReadNibble();
bool positive = (sample & 8) == 0;
int mag = sample & 7;
int m = StepFactor[mag];
magnitude = AddClamped(magnitude, m, 0, 48);
int adjustment = StepSize[magnitude];
if (positive == false) adjustment *= -1;
playingSample = AddClamped(playingSample, adjustment, 0, 4095);
//Console.WriteLine("decode: {0:X} sample: {1} ad_ref_index: {2}", sample,playingSample, magnitude);
}
void AdpcmEmitSample()
{
if (AdpcmIsPlaying == false)
SoundProvider.buffer.enqueue_sample(0, 0);
else
{
int rate = 16 - (Port180E & 0x0F);
float khz = 32 / rate;
if (nextSampleTimer <= 0)
{
DecodeAdpcmSample();
nextSampleTimer += destSamplesPerSourceSample;
}
nextSampleTimer--;
if (AdpcmLength == 0)
{
AdpcmIsPlaying = false;
}
short adjustedSample = (short)((playingSample - 2048) << 3);
SoundProvider.buffer.enqueue_sample(adjustedSample, adjustedSample);
}
}
}
}

View File

@ -11,13 +11,14 @@
- Exile II .. seems to reset itself after playing the unskippable intro. :(
- Macross 2036.. seems impossible to start/play the game. :(
- Rayxanber 2 weird issues at the end of first level with cd audio player
- rtype, end of level 4 dies with unrecognized scsi command ff
- Startling Odyssey does the reset-at-new-game-screen thats rather odd :(
- Super Darius II : at 1st Boss, game freezes waiting for adpcm
- Ys 1, start new game, death by adpcm probably
- Ys 1, start new game, death by adpcm probably ** shit it works now.
card angels does poll subcode...
======= TurboGrafx compatibility issues =======

View File

@ -19,12 +19,13 @@
public ControllerDefinition ControllerDefinition { get { return PCEngineController; } }
public IController Controller { get; set; }
private int SelectedController;
private byte InputByte;
int SelectedController;
byte InputByte;
public bool SEL { get { return ((InputByte & 1) != 0) ;} }
public bool CLR { get { return ((InputByte & 2) != 0); } }
private void WriteInput(byte value)
void WriteInput(byte value)
{
bool prevSEL = SEL;
InputByte = value;
@ -36,7 +37,7 @@
SelectedController = (SelectedController + 1);
}
private byte ReadInput()
byte ReadInput()
{
byte value = 0x3F;

View File

@ -5,9 +5,9 @@
// The Populous HuCard is the only traditional HuCard to have battery-backed saveRAM
// built into it. There is 32k of save-RAM mapped at pages $40 - $44.
private byte[] PopulousRAM;
byte[] PopulousRAM;
private byte ReadMemoryPopulous(int addr)
byte ReadMemoryPopulous(int addr)
{
if (addr >= 0x80000 && addr < 0x88000)
return PopulousRAM[addr & 0x7FFF];
@ -35,7 +35,7 @@
return 0xFF;
}
private void WriteMemoryPopulous(int addr, byte value)
void WriteMemoryPopulous(int addr, byte value)
{
if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM.
Ram[addr & 0x1FFF] = value;

View File

@ -5,9 +5,9 @@
// Street Fighter 2 was a 20-megabit HuCard. The PCE has a maximum 8-megabit addressable ROM space.
// Therefore SF2 had a special mapper to make this work.
private byte SF2MapperLatch;
byte SF2MapperLatch;
private byte ReadMemorySF2(int addr)
byte ReadMemorySF2(int addr)
{
if (addr < 0x7FFFF) // read ROM
return RomData[addr];
@ -35,7 +35,7 @@
return 0xFF;
}
private void WriteMemorySF2(int addr, byte value)
void WriteMemorySF2(int addr, byte value)
{
if ((addr & 0x1FFC) == 0x1FF0)
{

View File

@ -5,7 +5,7 @@
// The SuperGrafx has 32K of RAM and a different port configuration to allow
// I/O access to VDC1, VDC2, and the VPC.
private byte ReadMemorySGX(int addr)
byte ReadMemorySGX(int addr)
{
if (addr < 0xFFFFF) // read ROM
return RomData[addr % RomLength];
@ -38,7 +38,7 @@
return 0xFF;
}
private void WriteMemorySGX(int addr, byte value)
void WriteMemorySGX(int addr, byte value)
{
if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM.
Ram[addr & 0x7FFF] = value;

View File

@ -2,7 +2,7 @@
{
public partial class PCEngine
{
private byte ReadMemoryCD(int addr)
byte ReadMemoryCD(int addr)
{
if (addr < 0xD0000) // read ROM
return RomData[addr % RomLength];
@ -41,7 +41,7 @@
return 0xFF;
}
private void WriteMemoryCD(int addr, byte value)
void WriteMemoryCD(int addr, byte value)
{
if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM.
Ram[addr & 0x1FFF] = value;

View File

@ -2,9 +2,9 @@
{
public partial class PCEngine
{
private byte IOBuffer;
byte IOBuffer;
private byte ReadMemory(int addr)
byte ReadMemory(int addr)
{
if (addr < 0xFFFFF) // read ROM
return RomData[addr % RomLength];
@ -37,7 +37,7 @@
return 0xFF;
}
private void WriteMemory(int addr, byte value)
void WriteMemory(int addr, byte value)
{
if (addr >= 0x1F0000 && addr < 0x1F8000) // write RAM.
Ram[addr & 0x1FFF] = value;

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
// ROM
public byte[] RomData;
public int RomLength;
private Disc disc;
Disc disc;
// Machine
public NecSystemType Type;
@ -31,14 +31,14 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public SoundMixer SoundMixer;
public MetaspuSoundProvider SoundSynchronizer;
private bool TurboGrafx { get { return Type == NecSystemType.TurboGrafx; } }
private bool SuperGrafx { get { return Type == NecSystemType.SuperGrafx; } }
private bool TurboCD { get { return Type == NecSystemType.TurboCD; } }
bool TurboGrafx { get { return Type == NecSystemType.TurboGrafx; } }
bool SuperGrafx { get { return Type == NecSystemType.SuperGrafx; } }
bool TurboCD { get { return Type == NecSystemType.TurboCD; } }
// BRAM
private bool BramEnabled = false;
private bool BramLocked = true;
private byte[] BRAM;
bool BramEnabled = false;
bool BramLocked = true;
byte[] BRAM;
// Memory system
public byte[] Ram; // PCE= 8K base ram, SGX= 64k base ram
@ -69,7 +69,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
Init(game, rom);
}
private void Init(GameInfo game, byte[] rom)
void Init(GameInfo game, byte[] rom)
{
Controller = NullController.GetNullController();
Cpu = new HuC6280();
@ -113,7 +113,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
SoundMixer = new SoundMixer(PSG, CDAudio, ADPCM.SoundProvider);
SoundSynchronizer = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V);
soundProvider = SoundSynchronizer;
Cpu.ThinkAction = () => { SCSI.Think(); ADPCM.Think(); };
Cpu.ThinkAction = (cycles) => { SCSI.Think(); ADPCM.Think(cycles); };
}
if (rom.Length == 0x60000)
@ -143,9 +143,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
{
BramEnabled = true;
BRAM = new byte[2048];
Console.WriteLine("ENABLE BRAM!");
// pre-format BRAM
// pre-format BRAM. damn are we helpful.
BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D;
BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80;
}
@ -199,9 +198,9 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
SetupMemoryDomains();
}
private int _lagcount = 0;
private bool lagged = true;
private bool islag = false;
int _lagcount = 0;
bool lagged = true;
bool islag = false;
public int Frame { get; set; }
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
public bool IsLagFrame { get { return islag; } }
@ -245,7 +244,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
get { return (IVideoProvider) VPC ?? VDC1; }
}
private ISoundProvider soundProvider;
ISoundProvider soundProvider;
public ISoundProvider SoundProvider
{
get { return soundProvider; }
@ -305,6 +304,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
writer.Write("SuperRAM ");
SuperRam.SaveAsHex(writer);
}
writer.Write("ADPCM_TEMP ");
ADPCM.RAM.SaveAsHex(writer);
}
writer.WriteLine("[/PCEngine]");
}
@ -331,6 +332,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
CDRam.ReadFromHex(args[1]);
else if (args[0] == "SuperRAM")
SuperRam.ReadFromHex(args[1]);
else if (args[0] == "ADPCM_TEMP")
ADPCM.RAM.ReadFromHex(args[1]);
else if (args[0] == "PopulousRAM" && PopulousRAM != null)
PopulousRAM.ReadFromHex(args[1]);
else if (args[0] == "[HuC6280]")
@ -455,7 +458,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
return buf;
}
private void SetupMemoryDomains()
void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>(10);
var MainMemoryDomain = new MemoryDomain("Main Memory", Ram.Length, Endian.Little,
@ -500,7 +503,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
memoryDomains = domains.AsReadOnly();
}
private IList<MemoryDomain> memoryDomains;
IList<MemoryDomain> memoryDomains;
public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } }
public MemoryDomain MainMemory { get { return memoryDomains[0]; } }

View File

@ -6,23 +6,23 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
{
public sealed class ScsiCDBus
{
private const int STATUS_GOOD = 0;
private const int STATUS_CHECK_CONDITION = 1;
private const int STATUS_CONDITION_MET = 2;
private const int STATUS_BUSY = 4;
private const int STATUS_INTERMEDIATE = 8;
const int STATUS_GOOD = 0;
const int STATUS_CHECK_CONDITION = 1;
const int STATUS_CONDITION_MET = 2;
const int STATUS_BUSY = 4;
const int STATUS_INTERMEDIATE = 8;
private const int SCSI_TEST_UNIT_READY = 0x00;
private const int SCSI_REQUEST_SENSE = 0x03;
private const int SCSI_READ = 0x08;
private const int SCSI_AUDIO_START_POS = 0xD8;
private const int SCSI_AUDIO_END_POS = 0xD9;
private const int SCSI_PAUSE = 0xDA;
private const int SCSI_READ_SUBCODE_Q = 0xDD;
private const int SCSI_READ_TOC = 0xDE;
const int SCSI_TEST_UNIT_READY = 0x00;
const int SCSI_REQUEST_SENSE = 0x03;
const int SCSI_READ = 0x08;
const int SCSI_AUDIO_START_POS = 0xD8;
const int SCSI_AUDIO_END_POS = 0xD9;
const int SCSI_PAUSE = 0xDA;
const int SCSI_READ_SUBCODE_Q = 0xDD;
const int SCSI_READ_TOC = 0xDE;
private bool bsy, sel, cd, io, msg, req, ack, atn, rst;
private bool signalsChanged;
bool bsy, sel, cd, io, msg, req, ack, atn, rst;
bool signalsChanged;
public bool BSY
{
@ -106,7 +106,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
public byte DataBits { get; set; } // data bits
private enum BusPhase
enum BusPhase
{
BusFree,
Command,
@ -117,14 +117,14 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
Status
}
private bool busPhaseChanged;
private BusPhase Phase = BusPhase.BusFree;
bool busPhaseChanged;
BusPhase Phase = BusPhase.BusFree;
private bool MessageCompleted;
private bool StatusCompleted;
private byte MessageValue;
bool MessageCompleted;
bool StatusCompleted;
byte MessageValue;
private QuickList<byte> CommandBuffer = new QuickList<byte>(10); // 10 = biggest command
QuickList<byte> CommandBuffer = new QuickList<byte>(10); // 10 = biggest command
public QuickQueue<byte> DataIn = new QuickQueue<byte>(2048); // one data sector
// ******** Data Transfer / READ command support ********
@ -138,7 +138,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
// ******** Resources ********
private PCEngine pce;
PCEngine pce;
public Disc disc;
// ******** Events ********
@ -218,7 +218,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
} while (signalsChanged || busPhaseChanged);
}
private void ResetDevice()
void ResetDevice()
{
CD = false;
IO = false;
@ -235,7 +235,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
pce.CDAudio.Stop();
}
private void ThinkCommandPhase()
void ThinkCommandPhase()
{
if (REQ && ACK)
{
@ -258,7 +258,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private void ThinkDataInPhase()
void ThinkDataInPhase()
{
if (REQ && ACK)
{
@ -286,13 +286,13 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private void ThinkDataOutPhase()
void ThinkDataOutPhase()
{
Console.WriteLine("*********** DATA OUT PHASE, DOES THIS HAPPEN? ****************");
SetPhase(BusPhase.BusFree);
}
private void ThinkMessageInPhase()
void ThinkMessageInPhase()
{
if (REQ && ACK)
{
@ -307,13 +307,13 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private void ThinkMessageOutPhase()
void ThinkMessageOutPhase()
{
Console.WriteLine("******* IN MESSAGE OUT PHASE. DOES THIS EVER HAPPEN? ********");
SetPhase(BusPhase.BusFree);
}
private void ThinkStatusPhase()
void ThinkStatusPhase()
{
if (REQ && ACK)
{
@ -329,13 +329,12 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
// returns true if command completed, false if more data bytes needed
private bool CheckCommandBuffer()
bool CheckCommandBuffer()
{
switch (CommandBuffer[0])
{
case SCSI_TEST_UNIT_READY:
if (CommandBuffer.Count < 6) return false;
Log.Note("CD", "Execute TEST_UNIT_READY");
SetStatusMessage(STATUS_GOOD, 0);
return true;
@ -371,12 +370,13 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
default:
Console.WriteLine("UNRECOGNIZED SCSI COMMAND! {0:X2}", CommandBuffer[0]);
SetStatusMessage(STATUS_GOOD, 0);
break;
}
return false;
}
private void CommandRead()
void CommandRead()
{
int sector = (CommandBuffer[1] & 0x1f) << 16;
sector |= CommandBuffer[2] << 8;
@ -395,16 +395,16 @@ throw new Exception("requesting 0 sectors read.............................");
pce.CDAudio.Stop();
}
private int audioStartLBA;
private int audioEndLBA;
int audioStartLBA;
int audioEndLBA;
private void CommandAudioStartPos()
void CommandAudioStartPos()
{
switch (CommandBuffer[9] & 0xC0)
{
case 0x00: // Set start offset in LBA units
audioStartLBA = (CommandBuffer[3] << 16) | (CommandBuffer[4] << 8) | CommandBuffer[5];
Console.WriteLine("Set Start LBA: "+audioStartLBA);
//Console.WriteLine("Set Start LBA: "+audioStartLBA);
break;
case 0x40: // Set start offset in MSF units
@ -412,13 +412,13 @@ throw new Exception("requesting 0 sectors read.............................");
byte s = CommandBuffer[3].BCDtoBin();
byte f = CommandBuffer[4].BCDtoBin();
audioStartLBA = Disc.ConvertMSFtoLBA(m, s, f);
Console.WriteLine("Set Start MSF: {0} {1} {2} lba={3}",m,s,f,audioStartLBA);
//Console.WriteLine("Set Start MSF: {0} {1} {2} lba={3}",m,s,f,audioStartLBA);
break;
case 0x80: // Set start offset in track units
byte trackNo = CommandBuffer[2].BCDtoBin();
audioStartLBA = disc.TOC.Sessions[0].Tracks[trackNo - 1].Indexes[1].aba - 150;
Console.WriteLine("Set Start track: {0} lba={1}", trackNo, audioStartLBA);
//Console.WriteLine("Set Start track: {0} lba={1}", trackNo, audioStartLBA);
break;
}
@ -438,13 +438,13 @@ throw new Exception("requesting 0 sectors read.............................");
// irq callback?
}
private void CommandAudioEndPos()
void CommandAudioEndPos()
{
switch (CommandBuffer[9] & 0xC0)
{
case 0x00: // Set end offset in LBA units
audioEndLBA = (CommandBuffer[3] << 16) | (CommandBuffer[4] << 8) | CommandBuffer[5];
Console.WriteLine("Set End LBA: " + audioEndLBA);
//Console.WriteLine("Set End LBA: " + audioEndLBA);
break;
case 0x40: // Set end offset in MSF units
@ -452,7 +452,7 @@ throw new Exception("requesting 0 sectors read.............................");
byte s = CommandBuffer[3].BCDtoBin();
byte f = CommandBuffer[4].BCDtoBin();
audioEndLBA = Disc.ConvertMSFtoLBA(m, s, f);
Console.WriteLine("Set End MSF: {0} {1} {2} lba={3}", m, s, f, audioEndLBA);
//Console.WriteLine("Set End MSF: {0} {1} {2} lba={3}", m, s, f, audioEndLBA);
break;
case 0x80: // Set end offset in track units
@ -461,7 +461,7 @@ throw new Exception("requesting 0 sectors read.............................");
audioEndLBA = disc.LBACount;
else
audioEndLBA = disc.TOC.Sessions[0].Tracks[trackNo - 1].Indexes[1].aba - 150;
Console.WriteLine("Set End track: {0} lba={1}", trackNo, audioEndLBA);
//Console.WriteLine("Set End track: {0} lba={1}", trackNo, audioEndLBA);
break;
}
@ -471,7 +471,7 @@ throw new Exception("requesting 0 sectors read.............................");
pce.CDAudio.Stop();
break;
case 1: // play in loop mode. I guess this constitues A-B looping
Console.WriteLine("DOING A-B LOOP. NOT SURE IF RIGHT.");
//Console.WriteLine("DOING A-B LOOP. NOT SURE IF RIGHT.");
pce.CDAudio.PlayStartingAtLba(audioStartLBA);
pce.CDAudio.EndLBA = audioEndLBA;
pce.CDAudio.PlayMode = CDAudio.PlaybackMode.LoopOnCompletion;
@ -483,7 +483,7 @@ throw new Exception("requesting 0 sectors read.............................");
pce.CDAudio.PlayMode = CDAudio.PlaybackMode.CallbackOnCompletion;
break;
case 3: // Play normal
Console.WriteLine("*** SET END POS, IN PLAY NORMAL MODE? STARTING AT _START_ POS. IS THAT RIGHT?");
//Console.WriteLine("*** SET END POS, IN PLAY NORMAL MODE? STARTING AT _START_ POS. IS THAT RIGHT?");
pce.CDAudio.PlayStartingAtLba(audioStartLBA);
pce.CDAudio.EndLBA = audioEndLBA;
pce.CDAudio.PlayMode = CDAudio.PlaybackMode.StopOnCompletion;
@ -492,7 +492,7 @@ throw new Exception("requesting 0 sectors read.............................");
SetStatusMessage(STATUS_GOOD, 0);
}
private void CommandPause()
void CommandPause()
{
// apparently pause means stop? I guess? Idunno.
pce.CDAudio.Stop();
@ -500,9 +500,12 @@ throw new Exception("requesting 0 sectors read.............................");
// TODO send error if already stopped.. or paused... or something.
}
private void CommandReadSubcodeQ()
void CommandReadSubcodeQ()
{
Console.WriteLine("poll subcode");
// TODO we are lacking some various things here. But we know when it gets used and it doesnt
// seem to be used that often.
var sectorEntry = disc.ReadLBA_SectorEntry(pce.CDAudio.CurrentSector);
DataIn.Clear();
@ -526,13 +529,13 @@ throw new Exception("requesting 0 sectors read.............................");
SetPhase(BusPhase.DataIn);
}
private void CommandReadTOC()
void CommandReadTOC()
{
switch (CommandBuffer[1])
{
case 0: // return number of tracks
{
Log.Error("CD","Execute READ_TOC : num of tracks");
//Log.Error("CD","Execute READ_TOC : num of tracks");
DataIn.Clear();
DataIn.Enqueue(0x01);
DataIn.Enqueue(((byte) disc.TOC.Sessions[0].Tracks.Count).BinToBCD());
@ -552,8 +555,8 @@ throw new Exception("requesting 0 sectors read.............................");
DataIn.Enqueue(f.BinToBCD());
SetPhase(BusPhase.DataIn);
Log.Error("CD","EXECUTE READ_TOC : length of disc, LBA {0}, m:{1},s:{2},f:{3}",
totalLbaLength, m, s, f);
//Log.Error("CD","EXECUTE READ_TOC : length of disc, LBA {0}, m:{1},s:{2},f:{3}",
//totalLbaLength, m, s, f);
break;
}
case 2: // Return starting position of specified track in MSF format
@ -581,8 +584,8 @@ throw new Exception("requesting 0 sectors read.............................");
DataIn.Enqueue(4);
SetPhase(BusPhase.DataIn);
Log.Error("CD", "EXECUTE READ_TOC : start pos of TRACK {4}, LBA {0}, m:{1},s:{2},f:{3}",
lbaPos, m, s, f, track);
//Log.Error("CD", "EXECUTE READ_TOC : start pos of TRACK {4}, LBA {0}, m:{1},s:{2},f:{3}",
//lbaPos, m, s, f, track);
break;
}
@ -592,7 +595,7 @@ throw new Exception("requesting 0 sectors read.............................");
}
}
private void SetStatusMessage(byte status, byte message)
void SetStatusMessage(byte status, byte message)
{
MessageValue = message;
StatusCompleted = false;
@ -601,7 +604,7 @@ throw new Exception("requesting 0 sectors read.............................");
SetPhase(BusPhase.Status);
}
private void SetPhase(BusPhase phase)
void SetPhase(BusPhase phase)
{
if (Phase == phase)
return;

View File

@ -3,7 +3,7 @@
// IRQ2 interrupts:
// 0x04 - INTA - ADPCM interrupt
// 0x08 - INTSTOP - Fire when end of CD-Audio playback reached when in STOP MODE 2.
// 0x10 - INTSUB - no idea yet
// 0x10 - INTSUB - something with subchannel
// 0x20 - INTM - Fires when data transfer is complete
// 0x40 - INTD - Fires when data transfer is ready
@ -11,11 +11,22 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
{
public partial class PCEngine
{
byte[] CdIoPorts = new byte[16];
public static byte[] CdIoPorts = new byte[16];
public byte IRQ2Control { get { return CdIoPorts[2]; } set { CdIoPorts[2] = value; } }
public byte IRQ2Monitor { get { return CdIoPorts[3]; } set { CdIoPorts[3] = value; } }
public byte Port1803
{
get { return CdIoPorts[3]; }
set
{
if (value != CdIoPorts[3])
Console.WriteLine("UPDATE 1803: From {0:X2} to {1:X2}", CdIoPorts[3], value);
CdIoPorts[3] = value;
}
}
void InitScsiBus()
{
SCSI = new ScsiCDBus(this, disc);
@ -24,18 +35,17 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
{
// set or clear Ready Bit
if (yes)
CdIoPorts[3] |= 0x40;
Port1803 |= 0x40;
else
CdIoPorts[3] &= 0xBF;
Port1803 &= 0xBF;
};
SCSI.DataTransferComplete = yes =>
{
if (yes)
CdIoPorts[3] |= 0x20; // Set "Complete"
Port1803 |= 0x20; // Set "Complete"
else
{
CdIoPorts[3] &= 0xBF; // Clear "ready"
Port1803 &= 0xBF; // Clear "ready"
}
};
@ -75,7 +85,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
if ((CdIoPorts[2] & 0x10) != 0) Log.Error("CD", "INTSUB enable");
if ((CdIoPorts[2] & 0x20) != 0) Log.Error("CD", "INTM enable");
if ((CdIoPorts[2] & 0x40) != 0) Log.Error("CD", "INTD enable");
if ((Cpu.IRQControlByte & 0x01) != 0) Log.Error("CD", "BTW, IRQ2 is not masked");
if ((Cpu.IRQControlByte & 0x01) == 0 &&
(CdIoPorts[2] & 0x7C) != 0) Log.Error("CD", "BTW, IRQ2 is not masked");
SCSI.Think();
RefreshIRQ2();
@ -87,7 +98,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
SCSI.Think();
if (SCSI.RST)
{
CdIoPorts[3] &= 0x8F; // Clear interrupt control bits
Port1803 &= 0x8F; // Clear interrupt control bits
RefreshIRQ2();
}
break;
@ -99,32 +110,29 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
case 0x1807: // BRAM Unlock
if (BramEnabled && (value & 0x80) != 0)
{
//Console.WriteLine("UNLOCK BRAM!");
BramLocked = false;
}
break;
case 0x1808: // ADPCM address LSB
ADPCM.adpcm_io_address &= 0xFF00;
ADPCM.adpcm_io_address |= value;
ADPCM.IOAddress &= 0xFF00;
ADPCM.IOAddress |= value;
if ((CdIoPorts[0x0D] & 0x10) != 0)
{
Console.WriteLine("doing silly thing");
ADPCM.adpcm_length = ADPCM.adpcm_io_address;
ADPCM.AdpcmLength = ADPCM.IOAddress;
}
Log.Error("CD", "adpcm address = {0:X4}", ADPCM.adpcm_io_address);
//Log.Error("CD", "adpcm address = {0:X4}", ADPCM.adpcm_io_address);
break;
case 0x1809: // ADPCM address MSB
ADPCM.adpcm_io_address &= 0x00FF;
ADPCM.adpcm_io_address |= (ushort)(value << 8);
ADPCM.IOAddress &= 0x00FF;
ADPCM.IOAddress |= (ushort)(value << 8);
if ((CdIoPorts[0x0D] & 0x10) != 0)
{
Console.WriteLine("doing silly thing");
ADPCM.adpcm_length = ADPCM.adpcm_io_address;
ADPCM.AdpcmLength = ADPCM.IOAddress;
}
Log.Error("CD", "adpcm address = {0:X4}", ADPCM.adpcm_io_address);
//Log.Error("CD", "adpcm address = {0:X4}", ADPCM.adpcm_io_address);
break;
case 0x180A: // ADPCM Memory Read/Write Port
@ -133,7 +141,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
case 0x180B: // ADPCM DMA Control
ADPCM.Port180B = value;
Log.Error("CD", "Write to ADPCM DMA Control [B] {0:X2}", value);
//Log.Error("CD", "Write to ADPCM DMA Control [B] {0:X2}", value);
if (ADPCM.AdpcmCdDmaRequested)
Console.WriteLine(" ADPCM DMA REQUESTED");
break;
@ -144,12 +152,12 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
case 0x180E: // ADPCM Playback Rate
ADPCM.Port180E = value;
Log.Error("CD", "Write to ADPCM Sample Rate [E] {0:X2}", value);
//Log.Error("CD", "Write to ADPCM Sample Rate [E] {0:X2}", value);
break;
case 0x180F: // Audio Fade Timer
CdIoPorts[0x0F] = value;
Log.Error("CD", "Write to CD Audio fade timer [F] {0:X2}", value);
//Log.Error("CD", "Write to CD Audio fade timer [F] {0:X2}", value);
// TODO ADPCM fades/vol control also.
switch (value)
@ -206,8 +214,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
if (BramEnabled)
BramLocked = true;
Log.Error("CD", "Read: 1803 {0:X2} (PC={1:X4})", CdIoPorts[3], Cpu.PC);
returnValue = CdIoPorts[3];
//Log.Error("CD", "Read: 1803 {0:X2} (PC={1:X4})", CdIoPorts[3], Cpu.PC);
returnValue = Port1803;
CdIoPorts[3] ^= 2;
return returnValue;
@ -216,19 +224,21 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
return CdIoPorts[4];
case 0x1805: // CD audio data Low
if ((CdIoPorts[0x3] & 0x2) == 0)
if ((Port1803 & 0x2) == 0)
sample = CDAudio.VolumeLeft;
else
sample = CDAudio.VolumeRight;
return (byte) sample;
case 0x1806: // CD audio data High
if ((CdIoPorts[0x3] & 0x2) == 0)
if ((Port1803 & 0x2) == 0)
sample = CDAudio.VolumeLeft;
else
sample = CDAudio.VolumeRight;
return (byte) (sample >> 8);
// wow, nothing ever reads 1807 yet
case 0x1808: // Auto Handshake Data Input
returnValue = SCSI.DataBits;
if (SCSI.REQ && SCSI.IO && !SCSI.CD)
@ -266,7 +276,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
return CdIoPorts[0x0D];
case 0x180F: // Audio Fade Timer
Log.Error("CD", "Read: 180F {0:X2} (PC={1:X4})", CdIoPorts[0xF], Cpu.PC);
//Log.Error("CD", "Read: 180F {0:X2} (PC={1:X4})", CdIoPorts[0xF], Cpu.PC);
return CdIoPorts[0x0F];
// These are some retarded version check
@ -285,7 +295,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public void RefreshIRQ2()
{
int mask = CdIoPorts[2] & CdIoPorts[3] & 0x7C;
int mask = CdIoPorts[2] & Port1803 & 0x7C;
Cpu.IRQ2Assert = (mask != 0);
}
}

View File

@ -79,7 +79,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private static readonly byte[] PalConvert = {0, 36, 72, 109, 145, 182, 218, 255};
static readonly byte[] PalConvert = {0, 36, 72, 109, 145, 182, 218, 255};
public void PrecomputePalette(int slot)
{

View File

@ -23,11 +23,12 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public int RCRCounter;
public int ActiveLine;
private byte[] PriorityBuffer = new byte[512];
private byte[] InterSpritePriorityBuffer = new byte[512];
public int HBlankCycles = 79;
public bool PerformSpriteLimit;
byte[] PriorityBuffer = new byte[512];
byte[] InterSpritePriorityBuffer = new byte[512];
public void ExecFrame(bool render)
{
if (MultiResHack > 0 && render)
@ -111,7 +112,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
RenderSpritesScanline();
}
private void RenderBackgroundScanline()
void RenderBackgroundScanline()
{
Array.Clear(PriorityBuffer, 0, FrameWidth);
@ -151,7 +152,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private byte[] heightTable = { 16, 32, 64, 64 };
byte[] heightTable = { 16, 32, 64, 64 };
public void RenderSpritesScanline()
{
@ -337,10 +338,10 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private int FramePitch = 256;
private int FrameWidth = 256;
private int FrameHeight = 240;
private int[] FrameBuffer = new int[256 * 240];
int FramePitch = 256;
int FrameWidth = 256;
int FrameHeight = 240;
int[] FrameBuffer = new int[256 * 240];
public int[] GetVideoBuffer()
{

View File

@ -52,29 +52,29 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public int DisplayStartLine { get { return (Registers[VPR] >> 8) + (Registers[VPR] & 0x1F); } }
private const int MAWR = 0; // Memory Address Write Register
private const int MARR = 1; // Memory Address Read Register
private const int VRR = 2; // VRAM Read Register
private const int VWR = 2; // VRAM Write Register
private const int CR = 5; // Control Register
private const int RCR = 6; // Raster Compare Register
private const int BXR = 7; // Background X-scroll Register
private const int BYR = 8; // Background Y-scroll Register
private const int MWR = 9; // Memory-access Width Register
private const int HSR = 10; // Horizontal Sync Register
private const int HDR = 11; // Horizontal Display Register
private const int VPR = 12; // Vertical synchronous register
private const int VDW = 13; // Vertical display register
private const int VCR = 14; // Vertical display END position register;
private const int DCR = 15; // DMA Control Register
private const int SOUR = 16; // Source address for DMA
private const int DESR = 17; // Destination address for DMA
private const int LENR = 18; // Length of DMA transfer. Writing this will initiate DMA.
private const int SATB = 19; // Sprite Attribute Table base location in VRAM
const int MAWR = 0; // Memory Address Write Register
const int MARR = 1; // Memory Address Read Register
const int VRR = 2; // VRAM Read Register
const int VWR = 2; // VRAM Write Register
const int CR = 5; // Control Register
const int RCR = 6; // Raster Compare Register
const int BXR = 7; // Background X-scroll Register
const int BYR = 8; // Background Y-scroll Register
const int MWR = 9; // Memory-access Width Register
const int HSR = 10; // Horizontal Sync Register
const int HDR = 11; // Horizontal Display Register
const int VPR = 12; // Vertical synchronous register
const int VDW = 13; // Vertical display register
const int VCR = 14; // Vertical display END position register;
const int DCR = 15; // DMA Control Register
const int SOUR = 16; // Source address for DMA
const int DESR = 17; // Destination address for DMA
const int LENR = 18; // Length of DMA transfer. Writing this will initiate DMA.
const int SATB = 19; // Sprite Attribute Table base location in VRAM
private const int RegisterSelect = 0;
private const int LSB = 2;
private const int MSB = 3;
const int RegisterSelect = 0;
const int LSB = 2;
const int MSB = 3;
public const byte StatusVerticalBlanking = 0x20;
public const byte StatusVramVramDmaComplete = 0x10;
@ -83,10 +83,10 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public const byte StatusSpriteOverflow = 0x02;
public const byte StatusSprite0Collision = 0x01;
private const int VramSize = 0x8000;
const int VramSize = 0x8000;
private HuC6280 cpu;
private VCE vce;
HuC6280 cpu;
VCE vce;
public int MultiResHack = 0;
@ -126,7 +126,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private void CompleteMSBWrite(int register)
void CompleteMSBWrite(int register)
{
switch (register)
{
@ -206,7 +206,8 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
internal void RunDmaForScanline()
{
// TODO: dont do this all in one scanline. I guess it can do about 227 words per scanline.
//Console.WriteLine("Doing some dma");
// TODO: to be honest, dont do it in a block per scanline. put it in the CPU think function.
Console.WriteLine("******************************* Doing some dma ******************************");
int advanceSource = (Registers[DCR] & 4) == 0 ? +1 : -1;
int advanceDest = (Registers[DCR] & 8) == 0 ? +1 : -1;
int wordsDone = 0;

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public VDC VDC1;
public VDC VDC2;
public VCE VCE;
private HuC6280 CPU;
public HuC6280 CPU;
public byte[] Registers = {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -114,20 +114,20 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
// And there are no homebrew SGX games I know of.
// Maybe we'll emulate it in the native-code version.
private const int RCR = 6;
private const int BXR = 7;
private const int BYR = 8;
private const int VDW = 13;
private const int DCR = 15;
const int RCR = 6;
const int BXR = 7;
const int BYR = 8;
const int VDW = 13;
const int DCR = 15;
private int EffectivePriorityMode = 0;
int EffectivePriorityMode = 0;
private int FrameHeight;
private int FrameWidth;
private int[] FrameBuffer;
int FrameHeight;
int FrameWidth;
int[] FrameBuffer;
private byte[] PriorityBuffer = new byte[512];
private byte[] InterSpritePriorityBuffer = new byte[512];
byte[] PriorityBuffer = new byte[512];
byte[] InterSpritePriorityBuffer = new byte[512];
public void ExecFrame(bool render)
{
@ -255,7 +255,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private void RenderScanLine()
void RenderScanLine()
{
if (VDC1.ActiveLine >= FrameHeight)
return;
@ -279,7 +279,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private void InitializeScanLine(int scanline)
void InitializeScanLine(int scanline)
{
// Clear priority buffer
Array.Clear(PriorityBuffer, 0, FrameWidth);
@ -289,7 +289,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
FrameBuffer[(scanline * FrameWidth) + i] = VCE.Palette[0];
}
private void RenderBackgroundScanline(VDC vdc, byte priority)
void RenderBackgroundScanline(VDC vdc, byte priority)
{
if (vdc.BackgroundEnabled == false)
return;
@ -318,9 +318,9 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
}
}
private static byte[] heightTable = { 16, 32, 64, 64 };
static byte[] heightTable = { 16, 32, 64, 64 };
private void RenderSpritesScanline(VDC vdc, byte lowPriority, byte highPriority)
void RenderSpritesScanline(VDC vdc, byte lowPriority, byte highPriority)
{
if (vdc.SpritesEnabled == false)
return;

View File

@ -16,7 +16,7 @@
public ControllerDefinition ControllerDefinition { get { return SmsController; } }
public IController Controller { get; set; }
private byte ReadControls1()
byte ReadControls1()
{
lagged = false;
byte value = 0xFF;
@ -34,7 +34,7 @@
return value;
}
private byte ReadControls2()
byte ReadControls2()
{
lagged = false;
byte value = 0xFF;
@ -64,7 +64,7 @@
return value;
}
private byte ReadPort0()
byte ReadPort0()
{
if (IsGameGear == false)
return 0xFF;

View File

@ -9,7 +9,7 @@
// Bank 2: Control Address $8000 - Maps $8000 - $BFFF
// System RAM is at $C000+ as in the Sega mapper.
private byte ReadMemoryCM(ushort address)
byte ReadMemoryCM(ushort address)
{
if (address < BankSize * 1) return RomData[(RomBank0 * BankSize) + address];
if (address < BankSize * 2) return RomData[(RomBank1 * BankSize) + (address & BankSizeMask)];
@ -18,7 +18,7 @@
return SystemRam[address & RamSizeMask];
}
private void WriteMemoryCM(ushort address, byte value)
void WriteMemoryCM(ushort address, byte value)
{
if (address >= 0xC000)
SystemRam[address & RamSizeMask] = value;
@ -28,7 +28,7 @@
else if (address == 0x8000) RomBank2 = (byte)(value % RomBanks);
}
private void InitCodeMastersMapper()
void InitCodeMastersMapper()
{
Cpu.ReadMemory = ReadMemoryCM;
Cpu.WriteMemory = WriteMemoryCM;

View File

@ -14,10 +14,10 @@
// $FFFE - Mapper slot 1 control
// $FFFF - Mapper slot 2 control
private const ushort BankSizeMask = 0x3FFF;
private const ushort RamSizeMask = 0x1FFF;
const ushort BankSizeMask = 0x3FFF;
const ushort RamSizeMask = 0x1FFF;
private byte ReadMemory(ushort address)
byte ReadMemory(ushort address)
{
if (address < 1024)
return RomData[address];
@ -37,7 +37,7 @@
return SystemRam[address & RamSizeMask];
}
private void WriteMemory(ushort address, byte value)
void WriteMemory(ushort address, byte value)
{
if (address >= 0xC000)
SystemRam[address & RamSizeMask] = value;
@ -68,7 +68,7 @@
}
}
private void InitSegaMapper()
void InitSegaMapper()
{
Cpu.ReadMemory = ReadMemory;
Cpu.WriteMemory = WriteMemory;
@ -80,9 +80,9 @@
// Mapper when loading a BIOS as a ROM
private bool BiosMapped { get { return (Port3E & 0x08) == 0; } }
bool BiosMapped { get { return (Port3E & 0x08) == 0; } }
private byte ReadMemoryBIOS(ushort address)
byte ReadMemoryBIOS(ushort address)
{
if (BiosMapped == false && address < BankSize * 3)
return 0x00;
@ -99,7 +99,7 @@
return SystemRam[address & RamSizeMask];
}
private void WriteMemoryBIOS(ushort address, byte value)
void WriteMemoryBIOS(ushort address, byte value)
{
if (address >= 0xC000)
SystemRam[address & RamSizeMask] = value;
@ -113,7 +113,7 @@
}
}
private void InitBiosMapper()
void InitBiosMapper()
{
Cpu.ReadMemory = ReadMemoryBIOS;
Cpu.WriteMemory = WriteMemoryBIOS;
@ -123,4 +123,4 @@
WriteMemory(0xFFFF, 2);
}
}
}
}

View File

@ -43,9 +43,9 @@ namespace BizHawk.Emulation.Consoles.Sega
public bool IsGameGear = false;
public bool HasYM2413 = false;
private int _lagcount = 0;
private bool lagged = true;
private bool islag = false;
int _lagcount = 0;
bool lagged = true;
bool islag = false;
public int Frame { get; set; }
public void ResetFrameCounter()
@ -55,10 +55,10 @@ namespace BizHawk.Emulation.Consoles.Sega
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
public bool IsLagFrame { get { return islag; } }
private byte Port01 = 0xFF;
private byte Port02 = 0xFF;
private byte Port3E = 0xAF;
private byte Port3F = 0xFF;
byte Port01 = 0xFF;
byte Port02 = 0xFF;
byte Port3E = 0xAF;
byte Port3F = 0xFF;
public DisplayType DisplayType { get; set; }
public bool DeterministicEmulation { get; set; }
@ -325,12 +325,12 @@ namespace BizHawk.Emulation.Consoles.Sega
public CoreInputComm CoreInputComm { get; set; }
public CoreOutputComm CoreOutputComm { get; private set; }
private ISoundProvider ActiveSoundProvider;
ISoundProvider ActiveSoundProvider;
public ISoundProvider SoundProvider { get { return ActiveSoundProvider; } }
public string SystemId { get { return "SMS"; } }
private string region = "Export";
string region = "Export";
public string Region
{
get { return region; }
@ -342,11 +342,11 @@ namespace BizHawk.Emulation.Consoles.Sega
}
}
private readonly string[] validRegions = { "Export", "Japan" };
readonly string[] validRegions = { "Export", "Japan" };
private IList<MemoryDomain> memoryDomains;
IList<MemoryDomain> memoryDomains;
private void SetupMemoryDomains()
void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>(3);
var MainMemoryDomain = new MemoryDomain("Main RAM", SystemRam.Length, Endian.Little,

View File

@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Consoles.Sega
{
public partial class VDP
{
private int[] PaletteTMS9918 = new int[]
int[] PaletteTMS9918 = new int[]
{
unchecked((int)0x00000000),
unchecked((int)0xFF000000),
@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Consoles.Sega
unchecked((int)0xFFFFFFFF)
};
private void RenderBackgroundM0()
void RenderBackgroundM0()
{
if (DisplayOn == false)
{
@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Consoles.Sega
}
}
private void RenderBackgroundM2()
void RenderBackgroundM2()
{
if (DisplayOn == false)
{
@ -98,7 +98,7 @@ namespace BizHawk.Emulation.Consoles.Sega
}
}
private void RenderTmsSprites()
void RenderTmsSprites()
{
if (DisplayOn == false) return;

View File

@ -3,7 +3,7 @@
public partial class VDP
{
// TODO: HCounter
private readonly byte[] VLineCounterTableNTSC192 =
readonly byte[] VLineCounterTableNTSC192 =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
@ -24,7 +24,7 @@
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
};
private readonly byte[] VLineCounterTableNTSC224 =
readonly byte[] VLineCounterTableNTSC224 =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
@ -45,7 +45,7 @@
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
};
private readonly byte[] VLineCounterTableNTSC240 =
readonly byte[] VLineCounterTableNTSC240 =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
@ -66,7 +66,7 @@
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
};
private readonly byte[] VLineCounterTablePAL192 =
readonly byte[] VLineCounterTablePAL192 =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
@ -91,7 +91,7 @@
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
private readonly byte[] VLineCounterTablePAL224 =
readonly byte[] VLineCounterTablePAL224 =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
@ -116,7 +116,7 @@
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
private readonly byte[] VLineCounterTablePAL240 =
readonly byte[] VLineCounterTablePAL240 =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,

View File

@ -18,24 +18,24 @@ namespace BizHawk.Emulation.Consoles.Sega
public byte[] Registers = new byte[] { 0x06, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 };
public byte StatusByte;
private bool VdpWaitingForLatchByte = true;
private byte VdpLatch;
private byte VdpBuffer;
private ushort VdpAddress;
private VdpCommand vdpCommand;
private int TmsMode = 4;
bool VdpWaitingForLatchByte = true;
byte VdpLatch;
byte VdpBuffer;
ushort VdpAddress;
VdpCommand vdpCommand;
int TmsMode = 4;
private bool VIntPending;
private bool HIntPending;
bool VIntPending;
bool HIntPending;
private VdpMode mode;
public VdpMode VdpMode { get { return mode; } }
private DisplayType DisplayType = DisplayType.NTSC;
private Z80A Cpu;
VdpMode mode;
DisplayType DisplayType = DisplayType.NTSC;
Z80A Cpu;
public int IPeriod = 228;
public VdpMode VdpMode { get { return mode; } }
int FrameHeight = 192;
public int ScanLine;
private int FrameHeight = 192;
public int[] FrameBuffer = new int[256*192];
public int[] GameGearFrameBuffer = new int[160*144];
@ -56,22 +56,22 @@ namespace BizHawk.Emulation.Consoles.Sega
public int SpriteTileBase { get { return (Registers[6] & 4) > 0 ? 256: 0; } }
public byte BackdropColor { get { return (byte)(16 + (Registers[7] & 15)); } }
private int NameTableBase;
private int ColorTableBase;
private int PatternGeneratorBase;
private int SpritePatternGeneratorBase;
private int TmsPatternNameTableBase;
private int TmsSpriteAttributeBase;
int NameTableBase;
int ColorTableBase;
int PatternGeneratorBase;
int SpritePatternGeneratorBase;
int TmsPatternNameTableBase;
int TmsSpriteAttributeBase;
// preprocessed state assist stuff.
public int[] Palette = new int[32];
public byte[] PatternBuffer = new byte[0x8000];
private byte[] ScanlinePriorityBuffer = new byte[256];
private byte[] SpriteCollisionBuffer = new byte[256];
byte[] ScanlinePriorityBuffer = new byte[256];
byte[] SpriteCollisionBuffer = new byte[256];
private static readonly byte[] SMSPalXlatTable = { 0, 85, 170, 255 };
private static readonly byte[] GGPalXlatTable = { 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 };
static readonly byte[] SMSPalXlatTable = { 0, 85, 170, 255 };
static readonly byte[] GGPalXlatTable = { 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 };
public VDP(Z80A cpu, VdpMode mode, DisplayType displayType)
{
@ -205,7 +205,7 @@ namespace BizHawk.Emulation.Consoles.Sega
return (1024 * (Registers[2] & 0x0C)) + 0x0700;
}
private void CheckVideoMode()
void CheckVideoMode()
{
if (Mode4Bit == false) // check old TMS modes
{
@ -259,7 +259,7 @@ namespace BizHawk.Emulation.Consoles.Sega
}
}
private void WriteRegister(int reg, byte data)
void WriteRegister(int reg, byte data)
{
Registers[reg] = data;
switch(reg)
@ -292,9 +292,9 @@ namespace BizHawk.Emulation.Consoles.Sega
}
}
private static readonly byte[] pow2 = {1, 2, 4, 8, 16, 32, 64, 128};
static readonly byte[] pow2 = {1, 2, 4, 8, 16, 32, 64, 128};
private void UpdatePatternBuffer(ushort address, byte value)
void UpdatePatternBuffer(ushort address, byte value)
{
// writing one byte affects 8 pixels due to stupid planar storage.
for (int i=0; i<8; i++)
@ -309,9 +309,9 @@ namespace BizHawk.Emulation.Consoles.Sega
}
}
private int lineIntLinesRemaining;
int lineIntLinesRemaining;
private void ProcessFrameInterrupt()
void ProcessFrameInterrupt()
{
if (ScanLine == FrameHeight + 1)
{
@ -323,7 +323,7 @@ namespace BizHawk.Emulation.Consoles.Sega
Cpu.Interrupt = true;
}
private void ProcessLineInterrupt()
void ProcessLineInterrupt()
{
if (ScanLine <= FrameHeight)
{

View File

@ -9,7 +9,7 @@ namespace BizHawk
// There is less overhead by not being dynamically resizable and stuff.
public sealed class QuickList<T> where T : struct
{
private T[] buffer;
T[] buffer;
public int Position;
public QuickList(int capacity)
@ -43,10 +43,10 @@ namespace BizHawk
// only intended to be used with value types. If used on references you may get GC issues.
public class QuickQueue<T> where T : struct
{
private T[] buffer;
private int head;
private int tail;
private int size;
T[] buffer;
int head;
int tail;
int size;
public QuickQueue(int capacity)
{
@ -101,7 +101,7 @@ namespace BizHawk
// .net has no built-in read only dictionary
public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey,TValue>
{
private IDictionary<TKey, TValue> dict;
IDictionary<TKey, TValue> dict;
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
{

View File

@ -39,8 +39,8 @@ namespace BizHawk.Emulation.Sound
public int PlayingTrack;
public int CurrentSector, SectorOffset; // Offset is in SAMPLES, not bytes. Sector is 588 samples long.
private int CachedSector;
private byte[] SectorCache = new byte[2352];
int CachedSector;
byte[] SectorCache = new byte[2352];
public int FadeOutOverFrames = 0;
public int FadeOutFramesRemaining = 0;
@ -70,6 +70,8 @@ namespace BizHawk.Emulation.Sound
public void PlayStartingAtLba(int lba)
{
var point = Disc.TOC.SeekPoint(lba);
if (point == null) return;
PlayingTrack = point.TrackNum;
StartLBA = lba;
EndLBA = point.Track.Indexes[1].aba + point.Track.length_aba - 150;
@ -120,7 +122,7 @@ namespace BizHawk.Emulation.Sound
FadeOutFramesRemaining = frames;
}
private void EnsureSector()
void EnsureSector()
{
if (CachedSector != CurrentSector)
{

View File

@ -147,13 +147,13 @@ namespace BizHawk.Emulation.Sound
MixSamples(samples, start, samples.Length - start);
}
private void MixSamples(short[] samples, int start, int len)
void MixSamples(short[] samples, int start, int len)
{
for (int i = 0; i < 6; i++)
MixChannel(samples, start, len, Channels[i]);
}
private void MixChannel(short[] samples, int start, int len, PSGChannel channel)
void MixChannel(short[] samples, int start, int len, PSGChannel channel)
{
if (channel.Enabled == false) return;
if (channel.DDA == false && channel.Volume == 0) return;
@ -268,7 +268,7 @@ namespace BizHawk.Emulation.Sound
}
}
private void LoadChannelStateText(TextReader reader, int channel)
void LoadChannelStateText(TextReader reader, int channel)
{
while (true)
{

View File

@ -21,8 +21,8 @@ namespace BizHawk.Emulation.Sound
public bool Left = true;
public bool Right = true;
private const int SampleRate = 44100;
private static byte[] LogScale = { 0, 10, 13, 16, 20, 26, 32, 40, 51, 64, 81, 102, 128, 161, 203, 255 };
const int SampleRate = 44100;
static byte[] LogScale = { 0, 10, 13, 16, 20, 26, 32, 40, 51, 64, 81, 102, 128, 161, 203, 255 };
public void Mix(short[] samples, int start, int len, int maxVolume)
{
@ -48,10 +48,10 @@ namespace BizHawk.Emulation.Sound
public Channel[] Channels = new Channel[4];
public byte PsgLatch;
private Queue<QueuedCommand> commands = new Queue<QueuedCommand>(256);
private int frameStartTime, frameStopTime;
Queue<QueuedCommand> commands = new Queue<QueuedCommand>(256);
int frameStartTime, frameStopTime;
private const int PsgBase = 111861;
const int PsgBase = 111861;
public SN76489()
{
@ -107,7 +107,7 @@ namespace BizHawk.Emulation.Sound
commands.Enqueue(new QueuedCommand {Value = value, Time = cycles-frameStartTime});
}
private void UpdateNoiseType(int value)
void UpdateNoiseType(int value)
{
Channels[3].NoiseType = (byte)(value & 0x07);
switch (Channels[3].NoiseType & 3)
@ -125,7 +125,7 @@ namespace BizHawk.Emulation.Sound
}
}
private void WritePsgDataImmediate(byte value)
void WritePsgDataImmediate(byte value)
{
switch (value & 0xF0)
{
@ -309,7 +309,7 @@ namespace BizHawk.Emulation.Sound
// Next step from A4 is A#4. A#4 = (440.00 * 1.05946...) = 466.163...
// Note that because frequencies must be integers, SMS games will be slightly out of pitch to a normally tuned instrument, especially at the low end.
private static readonly int[] frequencies =
static readonly int[] frequencies =
{
27, // A0
29, // A#0
@ -402,7 +402,7 @@ namespace BizHawk.Emulation.Sound
4435 // C#8
};
private static readonly string[] notes =
static readonly string[] notes =
{
"A0","A#0","B0",
"C1","C#1","D1","D#1","E1","F1","F#1","G1","G#1","A1","A#1","B1",

View File

@ -17,11 +17,11 @@ namespace BizHawk.Emulation.Sound
{
public ISoundProvider BaseSoundProvider;
private Queue<short> buffer = new Queue<short>(4096);
Queue<short> buffer = new Queue<short>(4096);
private const int SamplesInOneFrame = 1470;
private const int TargetExtraSamples = 882;
private const int MaxExcessSamples = 4096;
const int SamplesInOneFrame = 1470;
const int TargetExtraSamples = 882;
const int MaxExcessSamples = 4096;
public void DiscardSamples()
{

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Sound
{
}
private short[] pullBuffer = new short[1470];
short[] pullBuffer = new short[1470];
public void PullSamples(ISoundProvider source)
{
Array.Clear(pullBuffer, 0, 1470);

View File

@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Sound
public sealed class SoundMixer : ISoundProvider
{
private List<ISoundProvider> SoundProviders;
List<ISoundProvider> SoundProviders;
public SoundMixer(params ISoundProvider[] soundProviders)
{

View File

@ -11,8 +11,8 @@ namespace BizHawk
{
public struct Tuple<T1, T2> : IEquatable<Tuple<T1, T2>>
{
private readonly T1 first;
private readonly T2 second;
readonly T1 first;
readonly T2 second;
public T1 First { get { return first; } }
public T2 Second { get { return second; } }