More work

This commit is contained in:
Asnivor 2024-11-01 14:34:44 +00:00
parent c723d7379e
commit fed68d6987
4 changed files with 64 additions and 12 deletions

View File

@ -48,7 +48,12 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
public int CLOCK_WIDTH =>
((_regs[R_LCD_X_SIZE] & 0xFC) // topmost 6 bits of the X Size register
+ 4) // line latch pulse
* 6; // 6 clocks per pixel
* 6; // 6 clocks per pixel
/// <summary>
/// Y offset modifier used with Y_Scroll to determine the VRAM pointer
/// </summary>
public int Y_OFFSET => _regs[R_LCD_X_SIZE] > 0xC0 ? 0x30 : 0x60;
/// <summary>
/// Number of scanlines in a field
@ -82,6 +87,8 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
private int _lineCounter;
private int _field;
private ushort _vramByteBuffer;
private int _vramPointer;
private int _vramStartAddress;
/// <summary>
/// ASIC is clocked at the same rate as the CPU
@ -106,8 +113,29 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
// there is no DMA on this cycle so CPU can run freely
_sv._cpu.RDY = true;
bool lineEnd = _byteCounter == CLOCK_WIDTH - 1;
bool fieldEnd = _lineCounter == LINE_HEIGHT && lineEnd && _field == 0;
bool frameEnd = _lineCounter == LINE_HEIGHT && lineEnd && _field == 1;
// vram pointer
if (fieldEnd)
{
// Y_Scroll offset added to the VRAM pointer at the start of the field (could be frame)
_vramStartAddress = (_regs[R_Y_SCROLL] * Y_OFFSET) & 0x1FFF;
if (_vramStartAddress == 0x1FE0)
_vramStartAddress = 0;
}
if (_byteCounter == 0)
{
// new scanline
_vramPointer = _vramStartAddress + (_regs[R_X_SCROLL] >> 2);
}
// ASIC reads a byte from VRAM
byte data = 0xff; //todo
byte data = _sv.ReadVRAM((ushort) _vramPointer);
_vramPointer++;
// shift the last read byte in the buffer and add the new byte to the start
_vramByteBuffer = (ushort) ((_vramByteBuffer << 8) | data);
@ -121,10 +149,7 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
// Field1: bits 1-3-5-7
byte lData = _field == 0
? (byte) ((b & 0b0000_0001) | ((b & 0b0000_0100) >> 1) | ((b & 0b0001_0000) >> 2) | ((b & 0b0100_0000) >> 3))
: (byte) ((b & 0b0000_0010) >> 1 | ((b & 0b0000_1000) >> 2) | ((b & 0b0010_0000) >> 3) | ((b & 0b1000_0000) >> 4));
bool lineEnd = _byteCounter == CLOCK_WIDTH - 1;
bool frameEnd = _lineCounter == LINE_HEIGHT && lineEnd && _field == 1;
: (byte) ((b & 0b0000_0010) >> 1 | ((b & 0b0000_1000) >> 2) | ((b & 0b0010_0000) >> 3) | ((b & 0b1000_0000) >> 4));
// send 1/2 byte to the LCD
Screen.PixelClock(lData, _field, lineEnd, frameEnd);
@ -137,6 +162,11 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
_byteCounter = 0;
_lineCounter++;
// setup start address
_vramStartAddress += Y_OFFSET & 0x1FFF;
if (_vramStartAddress == 0x1FE0)
_vramStartAddress = 0;
if (_lineCounter == LINE_HEIGHT)
{
// end of field
@ -395,7 +425,7 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
Screen.DisplayEnable = value.Bit(3);
// banking
_sv.BankSelect = value >> 5;
_sv.BankSelect = (value >> 5);
// writing to this register resets the LCD rendering system and makes it start rendering from the upper left corner, regardless of the bit pattern.
Screen.ResetPosition();
@ -546,6 +576,8 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
ser.Sync(nameof(_lineCounter), ref _lineCounter);
ser.Sync(nameof(_field), ref _field);
ser.Sync(nameof(_vramByteBuffer), ref _vramByteBuffer);
ser.Sync(nameof(_vramPointer), ref _vramPointer);
ser.Sync(nameof(_vramStartAddress), ref _vramStartAddress);
Screen.SyncState(ser);
ser.EndSection();

View File

@ -10,6 +10,8 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
/// </summary>
private byte[] _rom = new byte[0x20000];
public int CartROMSize => _rom.Length;
public SVCart(byte[] rom)
{
if (_rom.Length != rom.Length)

View File

@ -11,12 +11,18 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
/// <summary>
/// 8K of VRAM which the CPU can access with 0 wait states
/// </summary>
public byte[] VRAM = new byte[0x2000];
public byte[] VRAM = new byte[0x2000];
/// <summary>
/// Bank select index
/// </summary>
public int BankSelect;
public int BankSelect
{
get { return _bankSelect % (_cartridge.CartROMSize / 0x4000); }
set { _bankSelect = value; }
}
private int _bankSelect;
/// <summary>
/// True when the CPU is accessing memory
@ -63,6 +69,7 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
// 0: first 16k
// 1: 2nd 16k
// 2: 3rd 16k
// etc..
result = _cartridge.ReadByte((ushort) ((address % 0x4000) + (BankSelect * 0x4000)));
break;
@ -71,7 +78,7 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
case 6:
case 7:
// fixed to the last 16K in the cart address space
result = _cartridge.ReadByte((ushort) ((address % 0x4000) + (3 * 0x4000)));
result = _cartridge.ReadByte((ushort) ((address % 0x4000) + (_cartridge.CartROMSize - 0x4000)));
break;
}
@ -115,6 +122,7 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
// 0: first 16k
// 1: 2nd 16k
// 2: 3rd 16k
// etc..
_cartridge.WriteByte((ushort) ((address % 0x4000) + (BankSelect * 0x4000)), value);
break;
@ -123,9 +131,19 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
case 6:
case 7:
// fixed to the last 16K in the cart address space
_cartridge.WriteByte((ushort) ((address % 0x4000) + (3 * 0x4000)), value);
_cartridge.WriteByte((ushort) ((address % 0x4000) + (_cartridge.CartROMSize - 0x4000)), value);
break;
}
}
/// <summary>
/// ASIC is connected directly to VRAM
/// 8bit data bus
/// 12bit addr bus
/// </summary>
public byte ReadVRAM(ushort address)
{
return VRAM[address & 0x0FFF];
}
}
}

View File

@ -7,7 +7,7 @@ namespace BizHawk.Emulation.Cores.Consoles.SuperVision
private void SyncState(Serializer ser)
{
ser.BeginSection("SuperVision");
ser.Sync(nameof(BankSelect), ref BankSelect);
ser.Sync(nameof(BankSelect), ref _bankSelect);
ser.Sync(nameof(_frameClock), ref _frameClock);
ser.Sync(nameof(_frame), ref _frame);