NES: add FDS "currently loaded disk side" as a memorydomain. very rudimentary; for deblugging purposes only.

FDS: add disk writing.  nothing's saved anywhere at end of session, so not at all permanent.  seems to work though.
This commit is contained in:
goyuken 2012-10-26 21:25:20 +00:00
parent e6058e6bd8
commit 06d131b777
3 changed files with 108 additions and 13 deletions

View File

@ -67,7 +67,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo
{ {
byte[] buf = new byte[65500]; byte[] buf = new byte[65500];
Buffer.BlockCopy(diskimage, 16 + side * 65500, buf, 0, 65500); Buffer.BlockCopy(diskimage, 16 + side * 65500, buf, 0, 65500);
diskdrive.InsertBrokenImage(buf, true); diskdrive.InsertBrokenImage(buf, false /*true*/);
}
public MemoryDomain GetDiskPeeker()
{
return new MemoryDomain("FDS SIDE", diskdrive.NumBytes, Endian.Little, diskdrive.PeekData, null);
} }
void SetIRQ() void SetIRQ()
@ -91,7 +96,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public override void WriteEXP(int addr, byte value) public override void WriteEXP(int addr, byte value)
{ {
//Console.WriteLine("W{0:x4}:{1:x2} {2:x4}", addr + 0x4000, value, NES.cpu.PC); //if (addr == 0x0025)
// Console.WriteLine("W{0:x4}:{1:x2} {2:x4}", addr + 0x4000, value, NES.cpu.PC);
if (addr >= 0x0040) if (addr >= 0x0040)
{ {

View File

@ -122,6 +122,23 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//File.WriteAllBytes("fdsdebug.bin", realside); //File.WriteAllBytes("fdsdebug.bin", realside);
} }
/// <summary>
/// memorydomain debugging
/// </summary>
public int NumBytes { get { return 65500; } }
/// <summary>
/// memorydomain debugging
/// </summary>
/// <param name="addr"></param>
/// <returns></returns>
public byte PeekData(int addr)
{
if (disk != null && disk.Length > addr)
return disk[addr];
else
return 0xff;
}
// all timings are in terms of PPU cycles (@5.37mhz) // all timings are in terms of PPU cycles (@5.37mhz)
int cycleswaiting = 0; int cycleswaiting = 0;
@ -142,22 +159,27 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void SetCycles() void SetCycles()
{ {
// these are mostly guesses
switch (state) switch (state)
{ {
case RamAdapterState.RUNNING: case RamAdapterState.RUNNING: // matches of-quoted 96khz data transfer rate
cycleswaiting = 56; //82; // time to read/write one bit
cycleswaiting = 56;
break; break;
case RamAdapterState.INSERTING: case RamAdapterState.INSERTING: // 298ms
cycleswaiting = 5000000; // time for the disk drive to engage on disk after inserting
cycleswaiting = 1600000;
break; break;
case RamAdapterState.SPINUP: case RamAdapterState.SPINUP: // 199ms
cycleswaiting = 2000; // time for motor to spinup and start
cycleswaiting = 1070000;
break; break;
case RamAdapterState.IDLE: case RamAdapterState.IDLE: // irrelevant
cycleswaiting = 50000; cycleswaiting = 50000;
break; break;
case RamAdapterState.RESET: case RamAdapterState.RESET: // 1200ms
cycleswaiting = 50000; // time for motor to re-park after reaching end of drive
cycleswaiting = 6443100;
break; break;
} }
} }
@ -166,7 +188,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public void Write4024(byte value) public void Write4024(byte value)
{ {
bytetransferflag = false; bytetransferflag = false;
//irq = false; //?? writereglatch = value;
} }
byte cached4025; byte cached4025;
@ -190,7 +212,21 @@ namespace BizHawk.Emulation.Consoles.Nintendo
if ((value & 2) != 0) if ((value & 2) != 0)
transferreset = true; transferreset = true;
if ((cached4025 & 0x40) == 0 && (value & 0x40) != 0) if ((cached4025 & 0x40) == 0 && (value & 0x40) != 0)
{
lookingforendofgap = true; lookingforendofgap = true;
if ((value & 4) == 0)
{
// write mode: reload and go
writeregpos = 0;
writereg = writereglatch;
bytetransferflag = true;
// irq?
Console.WriteLine("FDS: Startwrite @{0} Reload {1:x2}", diskpos, writereglatch);
}
}
irq = false; // ?? irq = false; // ??
cached4025 = value; cached4025 = value;
@ -240,6 +276,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
ret &= unchecked((byte)~0x01); ret &= unchecked((byte)~0x01);
if (!transferreset && (state == RamAdapterState.RUNNING || state == RamAdapterState.IDLE)) if (!transferreset && (state == RamAdapterState.RUNNING || state == RamAdapterState.IDLE))
ret &= unchecked((byte)~0x02); ret &= unchecked((byte)~0x02);
if (disk != null && state != RamAdapterState.INSERTING && !writeprotect)
ret &= unchecked((byte)~0x04);
return ret; return ret;
} }
@ -345,7 +383,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
if ((cached4025 & 0x80) != 0) if ((cached4025 & 0x80) != 0)
irq = true; irq = true;
lastreaddiskpos = diskpos; lastreaddiskpos = diskpos;
//Console.WriteLine("{0:x2} {1} @{2}", readreg, (cached4025 & 0x80) != 0 ? "RAISE" : " ", diskpos); Console.WriteLine("{0:x2} {1} @{2}", readreg, (cached4025 & 0x80) != 0 ? "RAISE" : " ", diskpos);
readreglatch = readreg; readreglatch = readreg;
//} //}
//else // when in CRC, don't send results back to user //else // when in CRC, don't send results back to user
@ -362,6 +400,52 @@ namespace BizHawk.Emulation.Consoles.Nintendo
void Write() void Write()
{ {
if (writeprotect)
{
diskpos++;
return;
}
bool bittowrite = false;
// the variable is named for its function in read mode; in write mode, when not set,
// write an endless stream of zeroes.
if (!lookingforendofgap)
{
bittowrite = false;
}
else
{
bittowrite = (writereg & (1 << writeregpos)) != 0;
writeregpos++;
if (writeregpos == 8)
{
writeregpos = 0;
writereg = writereglatch;
bytetransferflag = true;
if ((cached4025 & 0x80) != 0)
irq = true;
Console.WriteLine("FDS: Write @{0} Reload {1:x2}", diskpos + 1, writereglatch);
// it seems that after a successful CRC, the writereg is reset to 0 value. this is needed?
// TODO: actually write the CRC (2 bytes)
if ((cached4025 & 0x10) != 0)
{
Console.WriteLine("FDS: write clear CRC", readreg, diskpos);
cached4025 &= unchecked((byte)~0x10); // clear CRC reading
//writereg = 0; // don't do this
writereglatch = 0; //??
}
}
}
var tmp = disk[diskpos >> 3];
tmp &= unchecked((byte)~(1 << (diskpos & 7)));
if (bittowrite)
tmp |= (byte)(1 << (diskpos & 7));
disk[diskpos >> 3] = tmp;
diskpos++; diskpos++;
} }

View File

@ -406,6 +406,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo
domains.Add(WRAM); domains.Add(WRAM);
} }
if (board is FDS)
{
domains.Add((board as FDS).GetDiskPeeker());
}
memoryDomains = domains.AsReadOnly(); memoryDomains = domains.AsReadOnly();
} }