summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2009-06-01 02:58:35 +0000
committerShawn Hoffman <godisgovernment@gmail.com>2009-06-01 02:58:35 +0000
commit7b43951b7e4ba33d3883ff68ba30d09562ed30cd (patch)
tree756d7958b3dc1e27c98b5ca257af2b98035f5846 /Source/Core
parent39b16ffafa27c8d637a13b39b55c613545c3745f (diff)
bunch of comments/unions in VI. No more UnknownVIRegs[0x1000]! :p some other misc stuff
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3302 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp6
-rw-r--r--Source/Core/Core/Src/Core.cpp1
-rw-r--r--Source/Core/Core/Src/HW/SI.cpp8
-rw-r--r--Source/Core/Core/Src/HW/VideoInterface.cpp965
-rw-r--r--Source/Core/Core/Src/HW/VideoInterface.h26
5 files changed, 766 insertions, 240 deletions
diff --git a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp
index bae4c17e3f..49a7ccd20b 100644
--- a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp
+++ b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp
@@ -69,12 +69,14 @@ void CBoot::EmulatedBIOS(bool _bDebug)
Memory::Write_U32(0x4c000064, 0x80000800); // write default FPU Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000C00); // write default Syscall Handler: rfi
Memory::Write_U32(0xc2339f3d, 0x8000001C); // game disc
- Memory::Write_U32(0x0D15EA5E, 0x80000020); // funny magic word for normal boot
+ Memory::Write_U32(0x0D15EA5E, 0x80000020); // booted from bootrom. 0xE5207C22 = booted from jtag
Memory::Write_U32(0x01800000, 0x80000028); // Physical Memory Size
// On any of the production boards, ikaruga fails to read the memcard the first time. It succeeds on the second time though.
// And (only sometimes?) with 0x00000003, the loading picture in the bottom right will become corrupt and
// the emu will slow to 7mhz...I don't think it ever actually progresses
+ // This seems to be caused by the initialization of the memcard going amiss (remember, this uses a dsp program!)
+ // so, probably some fault with dsp timing/emulation in general (endless dsp interrupts...)
Memory::Write_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see yagcd 4.2.1.1.2
Memory::Write_U32(((1 & 0x3f) << 26) | 2, 0x81300000); // HLE OSReport for Apploader
@@ -83,7 +85,7 @@ void CBoot::EmulatedBIOS(bool _bDebug)
// but it seems like the size can be variable. Compare with yagcd chap 13.
//
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
- u32 iAppLoaderOffset = 0x2440; // 0x1c40 (what is 0x1c40?)
+ u32 iAppLoaderOffset = 0x2440; // 0x1c40 - 2MB lower...perhaps used on early GCMs? MYSTERY OLD COMMENT
u32 iAppLoaderEntry = VolumeHandler::Read32(iAppLoaderOffset + 0x10);
u32 iAppLoaderSize = VolumeHandler::Read32(iAppLoaderOffset + 0x14);
if ((iAppLoaderEntry == (u32)-1) || (iAppLoaderSize == (u32)-1))
diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp
index 626be6d753..93a6fd4b0b 100644
--- a/Source/Core/Core/Src/Core.cpp
+++ b/Source/Core/Core/Src/Core.cpp
@@ -381,7 +381,6 @@ THREAD_RETURN EmuThread(void *pArg)
VideoInitialize.pSysMessage = Host_SysMessage;
VideoInitialize.pRequestWindowSize = NULL; //Callback_VideoRequestWindowSize;
VideoInitialize.pCopiedToXFB = Callback_VideoCopiedToXFB;
- VideoInitialize.pVIRegs = VideoInterface::m_UVIUnknownRegs;
VideoInitialize.pPeekMessages = NULL;
VideoInitialize.pUpdateFPSDisplay = NULL;
VideoInitialize.pCPFifo = (SCPFifoStruct*)&CommandProcessor::fifo;
diff --git a/Source/Core/Core/Src/HW/SI.cpp b/Source/Core/Core/Src/HW/SI.cpp
index 36aca1ee49..65a0f15d4e 100644
--- a/Source/Core/Core/Src/HW/SI.cpp
+++ b/Source/Core/Core/Src/HW/SI.cpp
@@ -131,7 +131,7 @@ union USIPoll
unsigned EN2 : 1; // does not affect communication RAM transfers
unsigned EN1 : 1;
unsigned EN0 : 1;
- unsigned Y : 10; // Polls per frame
+ unsigned Y : 8; // Polls per frame
unsigned X : 10; // Polls per X lines. begins at vsync, min 7, max depends on video mode
unsigned : 6;
};
@@ -395,7 +395,11 @@ void Write32(const u32 _iValue, const u32 _iAddress)
case SI_CHANNEL_3_IN_HI: g_Channel[3].m_InHi.Hex = _iValue; break;
case SI_CHANNEL_3_IN_LO: g_Channel[3].m_InLo.Hex = _iValue; break;
- case SI_POLL:
+ case SI_POLL:
+ DEBUG_LOG(SERIALINTERFACE, "Poll: X=%03d Y=%03d %s%s%s%s%s%s%s%s",
+ g_Poll.X, g_Poll.Y,
+ g_Poll.EN0 ? "EN0 ":" ", g_Poll.EN1 ? "EN1 ":" ", g_Poll.EN2 ? "EN2 ":" ", g_Poll.EN3 ? "EN3 ":" ",
+ g_Poll.VBCPY0 ? "VBCPY0 ":" ", g_Poll.VBCPY1 ? "VBCPY1 ":" ", g_Poll.VBCPY2 ? "VBCPY2 ":" ", g_Poll.VBCPY3 ? "VBCPY3 ":" ");
g_Poll.Hex = _iValue;
break;
diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp
index d500c85d19..133c46dac6 100644
--- a/Source/Core/Core/Src/HW/VideoInterface.cpp
+++ b/Source/Core/Core/Src/HW/VideoInterface.cpp
@@ -34,22 +34,66 @@ namespace VideoInterface
// VI Internal Hardware Addresses
enum
{
- VI_VERTICAL_TIMING = 0x0,
+ VI_VERTICAL_TIMING = 0x00,
VI_CONTROL_REGISTER = 0x02,
- VI_FRAMEBUFFER_TOP_HI = 0x01C,
- VI_FRAMEBUFFER_TOP_LO = 0x01E,
- VI_FRAMEBUFFER_BOTTOM_HI = 0x024,
- VI_FRAMEBUFFER_BOTTOM_LO = 0x026,
- VI_VERTICAL_BEAM_POSITION = 0x02C,
- VI_HORIZONTAL_BEAM_POSITION = 0x02e,
- VI_PRERETRACE = 0x030,
- VI_POSTRETRACE = 0x034,
- VI_DI2 = 0x038,
- VI_DI3 = 0x03C,
- VI_INTERLACE = 0x850,
- VI_HSCALEW = 0x048,
- VI_HSCALER = 0x04A,
- VI_FBWIDTH = 0x070,
+ VI_HORIZONTAL_TIMING_0_HI = 0x04,
+ VI_HORIZONTAL_TIMING_0_LO = 0x06,
+ VI_HORIZONTAL_TIMING_1_HI = 0x08,
+ VI_HORIZONTAL_TIMING_1_LO = 0x0a,
+ VI_VBLANK_TIMING_ODD_HI = 0x0c,
+ VI_VBLANK_TIMING_ODD_LO = 0x0e,
+ VI_VBLANK_TIMING_EVEN_HI = 0x10,
+ VI_VBLANK_TIMING_EVEN_LO = 0x12,
+ VI_BURST_BLANKING_ODD_HI = 0x14,
+ VI_BURST_BLANKING_ODD_LO = 0x16,
+ VI_BURST_BLANKING_EVEN_HI = 0x18,
+ VI_BURST_BLANKING_EVEN_LO = 0x1a,
+ VI_FB_LEFT_TOP_HI = 0x1c, // FB_LEFT_TOP is first half of XFB info
+ VI_FB_LEFT_TOP_LO = 0x1e,
+ VI_FB_RIGHT_TOP_HI = 0x20, // FB_RIGHT_TOP is only used in 3D mode
+ VI_FB_RIGHT_TOP_LO = 0x22,
+ VI_FB_LEFT_BOTTOM_HI = 0x24, // FB_LEFT_TOP is second half of XFB info
+ VI_FB_LEFT_BOTTOM_LO = 0x26,
+ VI_FB_RIGHT_BOTTOM_HI = 0x28, // FB_RIGHT_BOTTOM is only used in 3D mode
+ VI_FB_RIGHT_BOTTOM_LO = 0x2a,
+ VI_VERTICAL_BEAM_POSITION = 0x2c,
+ VI_HORIZONTAL_BEAM_POSITION = 0x2e,
+ VI_PRERETRACE_HI = 0x30,
+ VI_PRERETRACE_LO = 0x32,
+ VI_POSTRETRACE_HI = 0x34,
+ VI_POSTRETRACE_LO = 0x36,
+ VI_DISPLAY_INTERRUPT_2_HI = 0x38,
+ VI_DISPLAY_INTERRUPT_2_LO = 0x3a,
+ VI_DISPLAY_INTERRUPT_3_HI = 0x3c,
+ VI_DISPLAY_INTERRUPT_3_LO = 0x3e,
+ VI_DISPLAY_LATCH_0_HI = 0x40,
+ VI_DISPLAY_LATCH_0_LO = 0x42,
+ VI_DISPLAY_LATCH_1_HI = 0x44,
+ VI_DISPLAY_LATCH_1_LO = 0x46,
+ VI_HSCALEW = 0x48,
+ VI_HSCALER = 0x4a,
+ VI_FILTER_COEF_0_HI = 0x4c,
+ VI_FILTER_COEF_0_LO = 0x4e,
+ VI_FILTER_COEF_1_HI = 0x50,
+ VI_FILTER_COEF_1_LO = 0x52,
+ VI_FILTER_COEF_2_HI = 0x54,
+ VI_FILTER_COEF_2_LO = 0x56,
+ VI_FILTER_COEF_3_HI = 0x58,
+ VI_FILTER_COEF_3_LO = 0x5a,
+ VI_FILTER_COEF_4_HI = 0x5c,
+ VI_FILTER_COEF_4_LO = 0x5e,
+ VI_FILTER_COEF_5_HI = 0x60,
+ VI_FILTER_COEF_5_LO = 0x62,
+ VI_FILTER_COEF_6_HI = 0x64,
+ VI_FILTER_COEF_6_LO = 0x66,
+ VI_UNK_AA_REG_HI = 0x68,
+ VI_UNK_AA_REG_LO = 0x6a,
+ VI_CLOCK = 0x6c,
+ VI_DTV_STATUS = 0x6e,
+ VI_FBWIDTH = 0x70,
+ VI_BORDER_BLANK_END = 0x72, // Only used in debug video mode
+ VI_BORDER_BLANK_START = 0x74, // Only used in debug video mode
+ VI_INTERLACE = 0x850, // ??? MYSTERY OLD CODE
};
union UVIVerticalTimingRegister
@@ -57,9 +101,9 @@ union UVIVerticalTimingRegister
u16 Hex;
struct
{
- unsigned EQU : 4;
- unsigned ACV : 10;
- unsigned : 2;
+ unsigned EQU : 4; // Equalization pulse in half lines
+ unsigned ACV : 10; // Active Video (in full lines) ? other source says half lines
+ unsigned : 2;
};
UVIVerticalTimingRegister(u16 _hex) { Hex = _hex;}
UVIVerticalTimingRegister() { Hex = 0;}
@@ -70,19 +114,110 @@ union UVIDisplayControlRegister
u16 Hex;
struct
{
- unsigned ENB : 1;
- unsigned RST : 1;
- unsigned NIN : 1;
- unsigned DLR : 1;
- unsigned LE0 : 2;
+ unsigned ENB : 1; // Enables video timing generation and data request
+ unsigned RST : 1; // Clears all data requests and puts VI into its idle state
+ unsigned NIN : 1; // 0: Interlaced, 1: Non-Interlaced: top field drawn at field rate and bottom field is not displayed
+ unsigned DLR : 1; // Selects 3D Display Mode
+ unsigned LE0 : 2; // Display Latch; 0: Off, 1: On for 1 field, 2: On for 2 fields, 3: Always on
unsigned LE1 : 2;
- unsigned FMT : 2;
+ unsigned FMT : 2; // 0: NTSC, 1: PAL, 2: MPAL, 3: Debug
unsigned : 6;
};
UVIDisplayControlRegister(u16 _hex) { Hex = _hex;}
UVIDisplayControlRegister() { Hex = 0;}
};
+union UVIHorizontalTiming0
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned HLW : 9; // Halfline Width (W*16 = Width (720))
+ unsigned : 7;
+ unsigned HCE : 7; // Horizontal Sync Start to Color Burst End
+ unsigned : 1;
+ unsigned HCS : 7; // Horizontal Sync Start to Color Burst Start
+ unsigned : 1;
+ };
+};
+
+union UVIHorizontalTiming1
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned HSY : 7; // Horizontal Sync Width
+ unsigned HBE : 10; // Horizontal Sync Start to horizontal blank end
+ unsigned HBS : 10; // Half line to horizontal blanking start
+ unsigned : 5;
+ };
+};
+
+// Exists for both odd and even fields
+union UVIVBlankTimingRegister
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned PRB : 10; // Pre-blanking in half lines
+ unsigned : 6;
+ unsigned PSB : 10; // Post blanking in half lines
+ unsigned : 6;
+ };
+};
+
+// Exists for both odd and even fields
+union UVIBurstBlankingRegister
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned BS0 : 5; // Field x start to burst blanking start in halflines
+ unsigned BE0 : 11; // Field x start to burst blanking end in halflines
+ unsigned BS1 : 5; // Field x+2 start to burst blanking start in halflines
+ unsigned BE1 : 11; // Field x+2 start to burst blanking end in halflines
+ };
+};
+
+union UVIFBInfoRegister
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ // TODO: mask out lower 9bits/align to 9bits???
+ unsigned FBB : 24; // Base address of the framebuffer in external mem
+ // TODO: do XOFF/POFF exist in bottom reg?
+ unsigned XOFF : 4; // Horizontal Offset of the left-most pixel within the first word of the fetched picture
+ unsigned POFF : 1; // Page offest: 1: fb address is (address>>5)
+ unsigned CLRPOFF : 3; // ? setting bit 31 clears POFF
+ };
+};
+
// VI Interrupt Register
union UVIInterruptRegister
{
@@ -94,13 +229,31 @@ union UVIInterruptRegister
};
struct
{
- unsigned HCT : 11;
- unsigned : 5;
- unsigned VCT : 11;
- unsigned : 1;
- unsigned IR_MASK : 1;
- unsigned : 2;
- unsigned IR_INT : 1;
+ unsigned HCT : 11; // Horizontal Position
+ unsigned : 5;
+ unsigned VCT : 11; // Vertical Position
+ unsigned : 1;
+ unsigned IR_MASK : 1; // Interrupt Enable Bit
+ unsigned : 2;
+ unsigned IR_INT : 1; // Interrupt Status (1=Active) (Write to clear)
+ };
+};
+
+union UVILatchRegister
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned HCT : 11; // Horizontal Count
+ unsigned : 5;
+ unsigned VCT : 11; // Vertical Count
+ unsigned : 4;
+ unsigned TRG : 1; // Trigger Flag
};
};
@@ -109,8 +262,8 @@ union UVIHorizontalStepping
u16 Hex;
struct
{
- unsigned FbSteps : 8;
- unsigned FieldSteps : 8;
+ unsigned FbSteps : 8;
+ unsigned FieldSteps : 8;
};
};
@@ -119,16 +272,34 @@ union UVIHorizontalScaling
u16 Hex;
struct
{
- unsigned STP : 9;
+ unsigned STP : 9; // Horizontal stepping size (U1.8 Scaler Value) (0x160 Works for 320)
unsigned : 3;
- unsigned HS_EN : 1;
+ unsigned HS_EN : 1; // Enable Horizontal Scaling
unsigned : 3;
};
UVIHorizontalScaling(u16 _hex) { Hex = _hex;}
UVIHorizontalScaling() { Hex = 0;}
};
-union UVIFrameBufferAddress
+// Used for tables 0-2
+union UVIFilterCoefTable3
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned Tap0 : 10;
+ unsigned Tap1 : 10;
+ unsigned Tap2 : 10;
+ unsigned : 2;
+ };
+};
+// Used for tables 3-6
+union UVIFilterCoefTable4
{
u32 Hex;
struct
@@ -136,29 +307,69 @@ union UVIFrameBufferAddress
u16 Lo;
u16 Hi;
};
- UVIFrameBufferAddress(u16 _hex) { Hex = _hex;}
- UVIFrameBufferAddress() { Hex = 0;}
+ struct
+ {
+ unsigned Tap0 : 8;
+ unsigned Tap1 : 8;
+ unsigned Tap2 : 8;
+ unsigned Tap3 : 8;
+ };
+};
+struct SVIFilterCoefTables
+{
+ UVIFilterCoefTable3 Tables02[3];
+ UVIFilterCoefTable4 Tables36[4];
};
-// STATE_TO_SAVE
-static UVIVerticalTimingRegister m_VIVerticalTimingRegister;
-
-static UVIDisplayControlRegister m_VIDisplayControlRegister;
-
-// Framebuffers
-static UVIFrameBufferAddress m_FrameBufferTop; // normal framebuffer address
-static UVIFrameBufferAddress m_FrameBufferBottom;
-
-// VI Interrupt Registers
-static UVIInterruptRegister m_VIInterruptRegister[4];
+// Debug video mode only, probably never used in dolphin...
+union UVIBorderBlankRegister
+{
+ u32 Hex;
+ struct
+ {
+ u16 Lo;
+ u16 Hi;
+ };
+ struct
+ {
+ unsigned HBE656 : 10; // Border Horizontal Blank End
+ unsigned : 5;
+ unsigned BRDR_EN : 1; // Border Enable
+ unsigned HBS656 : 10; // Border Horizontal Blank start
+ unsigned : 6;
+ };
+};
-static UVIHorizontalStepping m_VIHorizontalStepping;
-static UVIHorizontalScaling m_VIHorizontalScaling;
-u8 m_UVIUnknownRegs[0x1000];
+// STATE_TO_SAVE
+// Registers listed in order:
+static UVIVerticalTimingRegister m_VerticalTimingRegister;
+static UVIDisplayControlRegister m_DisplayControlRegister;
+static UVIHorizontalTiming0 m_HTiming0;
+static UVIHorizontalTiming1 m_HTiming1;
+static UVIVBlankTimingRegister m_VBlankTimingOdd;
+static UVIVBlankTimingRegister m_VBlankTimingEven;
+static UVIBurstBlankingRegister m_BurstBlankingOdd;
+static UVIBurstBlankingRegister m_BurstBlankingEven;
+static UVIFBInfoRegister m_XFBInfoTop;
+static UVIFBInfoRegister m_XFBInfoBottom;
+static UVIFBInfoRegister m_3DFBInfoTop; // Start making your stereoscopic demos! :p
+static UVIFBInfoRegister m_3DFBInfoBottom;
+static u16 m_VBeamPos = 0;
+static u16 m_HBeamPos = 0;
+static UVIInterruptRegister m_InterruptRegister[4];
+static UVILatchRegister m_LatchRegister[2];
+static UVIHorizontalStepping m_HorizontalStepping;
+static UVIHorizontalScaling m_HorizontalScaling;
+static SVIFilterCoefTables m_FilterCoefTables;
+static u32 m_UnkAARegister = 0;// ??? 0x00FF0000
+static u16 m_Clock = 0; // 0: 27MHz, 1: 54MHz
+static u16 m_DTVStatus = 0;
+static u16 m_FBWidth = 0; // Only correct when scaling is enabled?
+static UVIBorderBlankRegister m_BorderHBlank;
+// 0xcc002076 - 0xcc00207f is full of 0x00FF: unknown
+// 0xcc002080 - 0xcc002100 even more unknown
-static u16 HorizontalBeamPos = 0;
-static u16 VerticalBeamPos = 0;
static u32 TicksPerFrame = 0;
static u32 LineCount = 0;
@@ -166,34 +377,85 @@ static u32 LinesPerField = 0;
static u64 LastTime = 0;
static u32 NextXFBRender = 0;
-// only correct when scaling is enabled?
-static u16 FbWidth = 0;
void DoState(PointerWrap &p)
{
- p.Do(m_VIVerticalTimingRegister);
- p.Do(m_VIDisplayControlRegister);
- p.Do(m_FrameBufferTop);
- p.Do(m_FrameBufferBottom);
- p.Do(m_VIInterruptRegister);
- p.DoArray(m_UVIUnknownRegs, 0x1000);
- p.Do(HorizontalBeamPos);
- p.Do(VerticalBeamPos);
+ p.Do(m_VerticalTimingRegister);
+ p.Do(m_DisplayControlRegister);
+ p.Do(m_HTiming0);
+ p.Do(m_HTiming1);
+ p.Do(m_VBlankTimingOdd);
+ p.Do(m_VBlankTimingEven);
+ p.Do(m_BurstBlankingOdd);
+ p.Do(m_BurstBlankingEven);
+ p.Do(m_XFBInfoTop);
+ p.Do(m_XFBInfoBottom);
+ p.Do(m_3DFBInfoTop);
+ p.Do(m_3DFBInfoBottom);
+ p.Do(m_VBeamPos);
+ p.Do(m_HBeamPos);
+ p.DoArray(m_InterruptRegister, 4);
+ p.DoArray(m_LatchRegister, 2);
+ p.Do(m_HorizontalStepping);
+ p.Do(m_HorizontalScaling);
+ p.Do(m_FilterCoefTables);
+ p.Do(m_UnkAARegister);
+ p.Do(m_Clock);
+ p.Do(m_DTVStatus);
+ p.Do(m_FBWidth);
+ p.Do(m_BorderHBlank);
+
p.Do(TicksPerFrame);
p.Do(LineCount);
p.Do(LinesPerField);
p.Do(LastTime);
- // p.Do(NextXFBRender); // Activate when changing saves next time.
+ p.Do(NextXFBRender);
+}
+
+void PreInit(bool _bNTSC)
+{
+ TicksPerFrame = 0;
+ LineCount = 0;
+ LastTime = 0;
+
+ Write16(0x0006, 0xcc002000);
+
+ if (_bNTSC)
+ Write16(0x0001, 0xcc002002);
+ else
+ Write16(0x0101, 0xcc002002);
+
+ Write16(0x4769, 0xcc002004);
+ Write16(0x01ad, 0xcc002006);
+ Write16(0x02ea, 0xcc002008);
+ Write16(0x5140, 0xcc00200a);
+ Write16(0x0005, 0xcc00200c);
+ Write16(0x01f6, 0xcc00200e);
+ Write16(0x0004, 0xcc002010);
+ Write16(0x01f7, 0xcc002012);
+ Write16(0x410c, 0xcc002014);
+ Write16(0x410c, 0xcc002016);
+ Write16(0x40ed, 0xcc002018);
+ Write16(0x40ed, 0xcc00201a);
+ Write16(0x1107, 0xcc002030);
+ Write16(0x01ae, 0xcc002032);
+ Write16(0x1001, 0xcc002034);
+ Write16(0x0001, 0xcc002036);
+ Write16(0x2828, 0xcc002048);
+ Write16(0x0000, 0xcc00206c);
+}
+
+void SetRegionReg(char _region)
+{
+ Write16((u16)_region, 0xcc00206e);
}
void Init()
{
for (int i = 0; i < 4; i++)
- m_VIInterruptRegister[i].Hex = 0x00;
+ m_InterruptRegister[i].Hex = 0;
- m_VIDisplayControlRegister.Hex = 0x0000;
- m_VIDisplayControlRegister.ENB = 0;
- m_VIDisplayControlRegister.FMT = 0;
+ m_DisplayControlRegister.Hex = 0;
NextXFBRender = 1;
}
@@ -203,73 +465,220 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
switch (_iAddress & 0xFFF)
{
case VI_VERTICAL_TIMING:
- _uReturnValue = m_VIVerticalTimingRegister.Hex;
+ _uReturnValue = m_VerticalTimingRegister.Hex;
return;
case VI_CONTROL_REGISTER:
- DEBUG_LOG(VIDEOINTERFACE, "VideoInterface(r16): VI_CONTROL_REGISTER 0x%08x", m_VIDisplayControlRegister.Hex);
- _uReturnValue = m_VIDisplayControlRegister.Hex;
+ _uReturnValue = m_DisplayControlRegister.Hex;
return;
- case VI_FRAMEBUFFER_TOP_HI:
- _uReturnValue = m_FrameBufferTop.Hi;
+ case VI_HORIZONTAL_TIMING_0_HI:
+ _uReturnValue = m_HTiming0.Hi;
+ break;
+ case VI_HORIZONTAL_TIMING_0_LO:
+ _uReturnValue = m_HTiming0.Lo;
+ break;
+
+ case VI_HORIZONTAL_TIMING_1_HI:
+ _uReturnValue = m_HTiming1.Hi;
+ break;
+ case VI_HORIZONTAL_TIMING_1_LO:
+ _uReturnValue = m_HTiming1.Lo;
+ break;
+
+ case VI_VBLANK_TIMING_ODD_HI:
+ _uReturnValue = m_VBlankTimingOdd.Hi;
+ break;
+ case VI_VBLANK_TIMING_ODD_LO:
+ _uReturnValue = m_VBlankTimingOdd.Lo;
+ break;
+
+ case VI_VBLANK_TIMING_EVEN_HI:
+ _uReturnValue = m_VBlankTimingEven.Hi;
+ break;
+ case VI_VBLANK_TIMING_EVEN_LO:
+ _uReturnValue = m_VBlankTimingEven.Lo;
+ break;
+
+ case VI_BURST_BLANKING_ODD_HI:
+ _uReturnValue = m_BurstBlankingOdd.Hi;
+ break;
+ case VI_BURST_BLANKING_ODD_LO:
+ _uReturnValue = m_BurstBlankingOdd.Lo;
+ break;
+
+ case VI_BURST_BLANKING_EVEN_HI:
+ _uReturnValue = m_BurstBlankingEven.Hi;
+ break;
+ case VI_BURST_BLANKING_EVEN_LO:
+ _uReturnValue = m_BurstBlankingEven.Lo;
+ break;
+
+ case VI_FB_LEFT_TOP_HI:
+ _uReturnValue = m_XFBInfoTop.Hi;
+ break;
+ case VI_FB_LEFT_TOP_LO:
+ _uReturnValue = m_XFBInfoTop.Lo;
break;
- case VI_FRAMEBUFFER_TOP_LO:
- _uReturnValue = m_FrameBufferTop.Lo;
+ case VI_FB_RIGHT_TOP_HI:
+ _uReturnValue = m_3DFBInfoTop.Hi;
+ break;
+ case VI_FB_RIGHT_TOP_LO:
+ _uReturnValue = m_3DFBInfoTop.Lo;
break;
- case VI_FRAMEBUFFER_BOTTOM_HI:
- _uReturnValue = m_FrameBufferBottom.Hi;
+ case VI_FB_LEFT_BOTTOM_HI:
+ _uReturnValue = m_XFBInfoBottom.Hi;
+ break;
+ case VI_FB_LEFT_BOTTOM_LO:
+ _uReturnValue = m_XFBInfoBottom.Lo;
break;
- case VI_FRAMEBUFFER_BOTTOM_LO:
- _uReturnValue = m_FrameBufferBottom.Lo;
+ case VI_FB_RIGHT_BOTTOM_HI:
+ _uReturnValue = m_3DFBInfoBottom.Hi;
+ break;
+ case VI_FB_RIGHT_BOTTOM_LO:
+ _uReturnValue = m_3DFBInfoBottom.Lo;
break;
case VI_VERTICAL_BEAM_POSITION:
- _uReturnValue = VerticalBeamPos;
+ _uReturnValue = m_VBeamPos;
return;
case VI_HORIZONTAL_BEAM_POSITION:
- _uReturnValue = HorizontalBeamPos;
+ _uReturnValue = m_HBeamPos;
return;
// RETRACE STUFF ...
- case VI_PRERETRACE:
- _uReturnValue = m_VIInterruptRegister[0].Hi;
+ case VI_PRERETRACE_HI:
+ _uReturnValue = m_InterruptRegister[0].Hi;
+ return;
+ case VI_PRERETRACE_LO:
+ _uReturnValue = m_InterruptRegister[0].Lo;
return;
- case VI_POSTRETRACE:
- _uReturnValue = m_VIInterruptRegister[1].Hi;
+ case VI_POSTRETRACE_HI:
+ _uReturnValue = m_InterruptRegister[1].Hi;
+ return;
+ case VI_POSTRETRACE_LO:
+ _uReturnValue = m_InterruptRegister[1].Lo;
return;
- case VI_DI2:
- _uReturnValue = m_VIInterruptRegister[2].Hi;
+ case VI_DISPLAY_INTERRUPT_2_HI:
+ _uReturnValue = m_InterruptRegister[2].Hi;
+ return;
+ case VI_DISPLAY_INTERRUPT_2_LO:
+ _uReturnValue = m_InterruptRegister[2].Lo;
return;
- case VI_DI3:
- _uReturnValue = m_VIInterruptRegister[3].Hi;
+ case VI_DISPLAY_INTERRUPT_3_HI:
+ _uReturnValue = m_InterruptRegister[3].Hi;
+ return;
+ case VI_DISPLAY_INTERRUPT_3_LO:
+ _uReturnValue = m_InterruptRegister[3].Lo;
return;
+ case VI_DISPLAY_LATCH_0_HI:
+ _uReturnValue = m_LatchRegister[0].Hi;
+ break;
+ case VI_DISPLAY_LATCH_0_LO:
+ _uReturnValue = m_LatchRegister[0].Lo;
+ break;
+
+ case VI_DISPLAY_LATCH_1_HI:
+ _uReturnValue = m_LatchRegister[1].Hi;
+ break;
+ case VI_DISPLAY_LATCH_1_LO:
+ _uReturnValue = m_LatchRegister[1].Lo;
+ break;
+
case VI_HSCALEW:
- _uReturnValue = m_VIHorizontalStepping.Hex;
+ _uReturnValue = m_HorizontalStepping.Hex;
break;
case VI_HSCALER:
- _uReturnValue = m_VIHorizontalScaling.Hex;
+ _uReturnValue = m_HorizontalScaling.Hex;
+ break;
+
+ case VI_FILTER_COEF_0_HI:
+ _uReturnValue = m_FilterCoefTables.Tables02[0].Hi;
+ break;
+ case VI_FILTER_COEF_0_LO:
+ _uReturnValue = m_FilterCoefTables.Tables02[0].Lo;
+ break;
+ case VI_FILTER_COEF_1_HI:
+ _uReturnValue = m_FilterCoefTables.Tables02[1].Hi;
+ break;
+ case VI_FILTER_COEF_1_LO:
+ _uReturnValue = m_FilterCoefTables.Tables02[1].Lo;
+ break;
+ case VI_FILTER_COEF_2_HI:
+ _uReturnValue = m_FilterCoefTables.Tables02[2].Hi;
+ break;
+ case VI_FILTER_COEF_2_LO:
+ _uReturnValue = m_FilterCoefTables.Tables02[2].Lo;
+ break;
+ case VI_FILTER_COEF_3_HI:
+ _uReturnValue = m_FilterCoefTables.Tables36[0].Hi;
+ break;
+ case VI_FILTER_COEF_3_LO:
+ _uReturnValue = m_FilterCoefTables.Tables36[0].Lo;
+ break;
+ case VI_FILTER_COEF_4_HI:
+ _uReturnValue = m_FilterCoefTables.Tables36[1].Hi;
+ break;
+ case VI_FILTER_COEF_4_LO:
+ _uReturnValue = m_FilterCoefTables.Tables36[1].Lo;
+ break;
+ case VI_FILTER_COEF_5_HI:
+ _uReturnValue = m_FilterCoefTables.Tables36[2].Hi;
+ break;
+ case VI_FILTER_COEF_5_LO:
+ _uReturnValue = m_FilterCoefTables.Tables36[2].Lo;
+ break;
+ case VI_FILTER_COEF_6_HI:
+ _uReturnValue = m_FilterCoefTables.Tables36[3].Hi;
+ break;
+ case VI_FILTER_COEF_6_LO:
+ _uReturnValue = m_FilterCoefTables.Tables36[3].Lo;
+ break;
+
+ case VI_UNK_AA_REG_HI:
+ _uReturnValue = (m_UnkAARegister & 0xffff0000) >> 16;
+ WARN_LOG(VIDEOINTERFACE, "(r16) unknown AA reg, not sure what it does :)");
+ break;
+ case VI_UNK_AA_REG_LO:
+ _uReturnValue = m_UnkAARegister & 0x0000ffff;
+ WARN_LOG(VIDEOINTERFACE, "(r16) unknown AA reg, not sure what it does :)");
+ break;
+
+ case VI_CLOCK:
+ _uReturnValue = m_Clock;
+ break;
+
+ case VI_DTV_STATUS:
+ _uReturnValue = m_DTVStatus;
break;
case VI_FBWIDTH:
- _uReturnValue = FbWidth;
+ _uReturnValue = m_FBWidth;
break;
- default:
- _uReturnValue = *(u16*)&m_UVIUnknownRegs[_iAddress & 0xFFF];
- return;
+ case VI_BORDER_BLANK_END:
+ _uReturnValue = m_BorderHBlank.Lo;
+ break;
+ case VI_BORDER_BLANK_START:
+ _uReturnValue = m_BorderHBlank.Hi;
+ break;
+
+ default:
+ ERROR_LOG(VIDEOINTERFACE, "(r16) unk reg %x", _iAddress & 0xfff);
+ _uReturnValue = 0x0;
+ break;
}
- _uReturnValue = 0x0;
+ DEBUG_LOG(VIDEOINTERFACE, "(r16): 0x%04x, 0x%08x", _uReturnValue, _iAddress);
}
void Write16(const u16 _iValue, const u32 _iAddress)
@@ -281,42 +690,100 @@ void Write16(const u16 _iValue, const u32 _iAddress)
switch (_iAddress & 0xFFF)
{
case VI_VERTICAL_TIMING:
- m_VIVerticalTimingRegister.Hex = _iValue;
+ m_VerticalTimingRegister.Hex = _iValue;
break;
case VI_CONTROL_REGISTER:
{
UVIDisplayControlRegister tmpConfig(_iValue);
- m_VIDisplayControlRegister.ENB = tmpConfig.ENB;
- m_VIDisplayControlRegister.NIN = tmpConfig.NIN;
- m_VIDisplayControlRegister.DLR = tmpConfig.DLR;
- m_VIDisplayControlRegister.LE0 = tmpConfig.LE0;
- m_VIDisplayControlRegister.LE1 = tmpConfig.LE1;
- m_VIDisplayControlRegister.FMT = tmpConfig.FMT;
+ m_DisplayControlRegister.ENB = tmpConfig.ENB;
+ m_DisplayControlRegister.NIN = tmpConfig.NIN;
+ m_DisplayControlRegister.DLR = tmpConfig.DLR;
+ m_DisplayControlRegister.LE0 = tmpConfig.LE0;
+ m_DisplayControlRegister.LE1 = tmpConfig.LE1;
+ m_DisplayControlRegister.FMT = tmpConfig.FMT;
if (tmpConfig.RST)
{
- m_VIDisplayControlRegister.RST = 0;
+ m_DisplayControlRegister.RST = 0;
}
UpdateTiming();
}
break;
- case VI_FRAMEBUFFER_TOP_HI:
- m_FrameBufferTop.Hi = _iValue;
+ case VI_HORIZONTAL_TIMING_0_HI:
+ m_HTiming0.Hi = _iValue;
+ break;
+ case VI_HORIZONTAL_TIMING_0_LO:
+ m_HTiming0.Lo = _iValue;
+ break;
+
+ case VI_HORIZONTAL_TIMING_1_HI:
+ m_HTiming1.Hi = _iValue;
+ break;
+ case VI_HORIZONTAL_TIMING_1_LO:
+ m_HTiming1.Lo = _iValue;
+ break;
+
+ case VI_VBLANK_TIMING_ODD_HI:
+ m_VBlankTimingOdd.Hi = _iValue;
+ break;
+ case VI_VBLANK_TIMING_ODD_LO:
+ m_VBlankTimingOdd.Lo = _iValue;
break;
- case VI_FRAMEBUFFER_TOP_LO:
- m_FrameBufferTop.Lo = _iValue;
+ case VI_VBLANK_TIMING_EVEN_HI:
+ m_VBlankTimingEven.Hi = _iValue;
+ break;
+ case VI_VBLANK_TIMING_EVEN_LO:
+ m_VBlankTimingEven.Lo = _iValue;
break;
- case VI_FRAMEBUFFER_BOTTOM_HI:
- m_FrameBufferBottom.Hi = _iValue;
+ case VI_BURST_BLANKING_ODD_HI:
+ m_BurstBlankingOdd.Hi = _iValue;
+ break;
+ case VI_BURST_BLANKING_ODD_LO:
+ m_BurstBlankingOdd.Lo = _iValue;
break;
- case VI_FRAMEBUFFER_BOTTOM_LO:
- m_FrameBufferBottom.Lo = _iValue;
+ case VI_BURST_BLANKING_EVEN_HI:
+ m_BurstBlankingEven.Hi = _iValue;
+ break;
+ case VI_BURST_BLANKING_EVEN_LO:
+ m_BurstBlankingEven.Lo = _iValue;
+ break;
+
+ case VI_FB_LEFT_TOP_HI:
+ m_XFBInfoTop.Hi = _iValue;
+ if (m_XFBInfoTop.CLRPOFF) m_XFBInfoTop.POFF = 0;
+ break;
+ case VI_FB_LEFT_TOP_LO:
+ m_XFBInfoTop.Lo = _iValue;
+ break;
+
+ case VI_FB_RIGHT_TOP_HI:
+ m_3DFBInfoTop.Hi = _iValue;
+ if (m_3DFBInfoTop.CLRPOFF) m_3DFBInfoTop.POFF = 0;
+ break;
+ case VI_FB_RIGHT_TOP_LO:
+ m_3DFBInfoTop.Lo = _iValue;
+ break;
+
+ case VI_FB_LEFT_BOTTOM_HI:
+ m_XFBInfoBottom.Hi = _iValue;
+ if (m_XFBInfoBottom.CLRPOFF) m_XFBInfoBottom.POFF = 0;
+ break;
+ case VI_FB_LEFT_BOTTOM_LO:
+ m_XFBInfoBottom.Lo = _iValue;
+ break;
+
+ case VI_FB_RIGHT_BOTTOM_HI:
+ m_3DFBInfoBottom.Hi = _iValue;
+ if (m_3DFBInfoBottom.CLRPOFF) m_3DFBInfoBottom.POFF = 0;
+ break;
+ case VI_FB_RIGHT_BOTTOM_LO:
+ m_3DFBInfoBottom.Lo = _iValue;
break;
case VI_VERTICAL_BEAM_POSITION:
@@ -328,72 +795,154 @@ void Write16(const u16 _iValue, const u32 _iAddress)
break;
// RETRACE STUFF ...
- case VI_PRERETRACE:
- m_VIInterruptRegister[0].Hi = _iValue;
+ case VI_PRERETRACE_HI:
+ m_InterruptRegister[0].Hi = _iValue;
+ UpdateInterrupts();
+ break;
+ case VI_PRERETRACE_LO:
+ m_InterruptRegister[0].Lo = _iValue;
UpdateInterrupts();
break;
- case VI_POSTRETRACE:
- m_VIInterruptRegister[1].Hi = _iValue;
+ case VI_POSTRETRACE_HI:
+ m_InterruptRegister[1].Hi = _iValue;
+ UpdateInterrupts();
+ break;
+ case VI_POSTRETRACE_LO:
+ m_InterruptRegister[1].Lo = _iValue;
UpdateInterrupts();
break;
- case VI_DI2:
- m_VIInterruptRegister[2].Hi = _iValue;
+ case VI_DISPLAY_INTERRUPT_2_HI:
+ m_InterruptRegister[2].Hi = _iValue;
+ UpdateInterrupts();
+ break;
+ case VI_DISPLAY_INTERRUPT_2_LO:
+ m_InterruptRegister[2].Lo = _iValue;
UpdateInterrupts();
break;
- case VI_DI3:
- m_VIInterruptRegister[3].Hi = _iValue;
+ case VI_DISPLAY_INTERRUPT_3_HI:
+ m_InterruptRegister[3].Hi = _iValue;
+ UpdateInterrupts();
+ break;
+ case VI_DISPLAY_INTERRUPT_3_LO:
+ m_InterruptRegister[3].Lo = _iValue;
UpdateInterrupts();
break;
+ case VI_DISPLAY_LATCH_0_HI:
+ m_LatchRegister[0].Hi = _iValue;
+ break;
+ case VI_DISPLAY_LATCH_0_LO:
+ m_LatchRegister[0].Lo = _iValue;
+ break;
+
+ case VI_DISPLAY_LATCH_1_HI:
+ m_LatchRegister[1].Hi = _iValue;
+ break;
+ case VI_DISPLAY_LATCH_1_LO:
+ m_LatchRegister[1].Lo = _iValue;
+ break;
+
case VI_HSCALEW:
- m_VIHorizontalStepping.Hex = _iValue;
+ m_HorizontalStepping.Hex = _iValue;
break;
case VI_HSCALER:
- m_VIHorizontalScaling.Hex = _iValue;
+ m_HorizontalScaling.Hex = _iValue;
+ break;
+
+ case VI_FILTER_COEF_0_HI:
+ m_FilterCoefTables.Tables02[0].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_0_LO:
+ m_FilterCoefTables.Tables02[0].Lo = _iValue;
+ break;
+ case VI_FILTER_COEF_1_HI:
+ m_FilterCoefTables.Tables02[1].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_1_LO:
+ m_FilterCoefTables.Tables02[1].Lo = _iValue;
+ break;
+ case VI_FILTER_COEF_2_HI:
+ m_FilterCoefTables.Tables02[2].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_2_LO:
+ m_FilterCoefTables.Tables02[2].Lo = _iValue;
+ break;
+ case VI_FILTER_COEF_3_HI:
+ m_FilterCoefTables.Tables36[0].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_3_LO:
+ m_FilterCoefTables.Tables36[0].Lo = _iValue;
+ break;
+ case VI_FILTER_COEF_4_HI:
+ m_FilterCoefTables.Tables36[1].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_4_LO:
+ m_FilterCoefTables.Tables36[1].Lo = _iValue;
+ break;
+ case VI_FILTER_COEF_5_HI:
+ m_FilterCoefTables.Tables36[2].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_5_LO:
+ m_FilterCoefTables.Tables36[2].Lo = _iValue;
+ break;
+ case VI_FILTER_COEF_6_HI:
+ m_FilterCoefTables.Tables36[3].Hi = _iValue;
+ break;
+ case VI_FILTER_COEF_6_LO:
+ m_FilterCoefTables.Tables36[3].Lo = _iValue;
+ break;
+
+ case VI_UNK_AA_REG_HI:
+ m_UnkAARegister = (m_UnkAARegister & 0x0000ffff) | (u32)(_iValue << 16);
+ WARN_LOG(VIDEOINTERFACE, "(w16) to unknown AA reg, not sure what it does :)");
+ break;
+ case VI_UNK_AA_REG_LO:
+ m_UnkAARegister = (m_UnkAARegister & 0xffff0000) | _iValue;
+ WARN_LOG(VIDEOINTERFACE, "(w16) to unknown AA reg, not sure what it does :)");
+ break;
+
+ case VI_CLOCK:
+ m_Clock = _iValue;
+ break;
+
+ case VI_DTV_STATUS:
+ m_DTVStatus = _iValue;
break;
case VI_FBWIDTH:
- FbWidth = _iValue;
+ m_FBWidth = _iValue;
+ break;
+
+ case VI_BORDER_BLANK_END:
+ m_BorderHBlank.Lo = _iValue;
+ break;
+ case VI_BORDER_BLANK_START:
+ m_BorderHBlank.Hi = _iValue;
break;
default:
- *(u16*)&m_UVIUnknownRegs[_iAddress & 0xFFF] = _iValue;
+ ERROR_LOG(VIDEOINTERFACE, "(w16) %04x to unk reg %x", _iValue, _iAddress & 0xfff);
break;
}
}
void Read32(u32& _uReturnValue, const u32 _iAddress)
{
- INFO_LOG(VIDEOINTERFACE, "(r32): 0x%08x", _iAddress);
+ u16 Hi = 0, Lo = 0;
+ Read16(Hi, _iAddress);
+ Read16(Lo, _iAddress + 2);
+ _uReturnValue = (Hi << 16) | Lo;
- if ((_iAddress & 0xFFF) < 0x20)
- {
- _uReturnValue = 0;
- return;
- }
- switch (_iAddress & 0xFFF)
- {
- case 0x000:
- case 0x004:
- case 0x008:
- case 0x00C:
- _uReturnValue = 0; //FL
- return;
-
- default:
- //_assert_(0);
- _uReturnValue = 0xAFFE;
- return;
- }
+ INFO_LOG(VIDEOINTERFACE, "(r32): 0x%08x, 0x%08x", _uReturnValue, _iAddress);
}
void Write32(const u32 _iValue, const u32 _iAddress)
{
- INFO_LOG(VIDEOINTERFACE, "(w32): 0x%08x, 0x%08x",_iValue,_iAddress);
+ INFO_LOG(VIDEOINTERFACE, "(w32): 0x%08x, 0x%08x", _iValue, _iAddress);
// Allow 32-bit writes to the VI: although this is officially not
// allowed, the hardware seems to accept it (for example, DesktopMan GC
@@ -404,10 +953,10 @@ void Write32(const u32 _iValue, const u32 _iAddress)
void UpdateInterrupts()
{
- if ((m_VIInterruptRegister[0].IR_INT & m_VIInterruptRegister[0].IR_MASK) ||
- (m_VIInterruptRegister[1].IR_INT & m_VIInterruptRegister[1].IR_MASK) ||
- (m_VIInterruptRegister[2].IR_INT & m_VIInterruptRegister[2].IR_MASK) ||
- (m_VIInterruptRegister[3].IR_INT & m_VIInterruptRegister[3].IR_MASK))
+ if ((m_InterruptRegister[0].IR_INT & m_InterruptRegister[0].IR_MASK) ||
+ (m_InterruptRegister[1].IR_INT & m_InterruptRegister[1].IR_MASK) ||
+ (m_InterruptRegister[2].IR_INT & m_InterruptRegister[2].IR_MASK) ||
+ (m_InterruptRegister[3].IR_INT & m_InterruptRegister[3].IR_MASK))
{
CPeripheralInterface::SetInterrupt(CPeripheralInterface::INT_CAUSE_VI, true);
}
@@ -421,81 +970,59 @@ void GenerateVIInterrupt(VIInterruptType _VIInterrupt)
{
switch(_VIInterrupt)
{
- case INT_PRERETRACE: m_VIInterruptRegister[0].IR_INT = 1; break;
- case INT_POSTRETRACE: m_VIInterruptRegister[1].IR_INT = 1; break;
- case INT_REG_2: m_VIInterruptRegister[2].IR_INT = 1; break;
- case INT_REG_3: m_VIInterruptRegister[3].IR_INT = 1; break;
+ case INT_PRERETRACE: m_InterruptRegister[0].IR_INT = 1; break;
+ case INT_POSTRETRACE: m_InterruptRegister[1].IR_INT = 1; break;
+ case INT_REG_2: m_InterruptRegister[2].IR_INT = 1; break;
+ case INT_REG_3: m_InterruptRegister[3].IR_INT = 1; break;
}
UpdateInterrupts();
// debug check
- if ((m_VIInterruptRegister[2].IR_MASK == 1) ||
- (m_VIInterruptRegister[3].IR_MASK == 1))
+ if ((m_InterruptRegister[2].IR_MASK == 1) ||
+ (m_InterruptRegister[3].IR_MASK == 1))
{
- PanicAlert("m_VIInterruptRegister[2 and 3] activated - Tell F|RES :)");
+ PanicAlert("m_InterruptRegister[2 and 3] activated - Tell F|RES :)");
}
}
-u8* GetFrameBufferPointer()
-{
- return Memory::GetPointer(VideoInterface::m_FrameBufferTop.Hex);
-}
-
-void PreInit(bool _bNTSC)
+u8* GetXFBPointerTop()
{
- TicksPerFrame = 0;
- LineCount = 0;
- LastTime = 0;
-
- Write16(0x4769, 0xcc002004);
- Write16(0x01ad, 0xcc002006);
- Write16(0x5140, 0xcc00200a);
- Write16(0x02ea, 0xcc002008);
- Write16(0x0006, 0xcc002000);
- Write16(0x01f6, 0xcc00200e);
- Write16(0x0005, 0xcc00200c);
- Write16(0x01f7, 0xcc002012);
- Write16(0x0004, 0xcc002010);
- Write16(0x410c, 0xcc002016);
- Write16(0x410c, 0xcc002014);
- Write16(0x40ed, 0xcc00201a);
- Write16(0x40ed, 0xcc002018);
- Write16(0x2828, 0xcc002048);
- Write16(0x0001, 0xcc002036);
- Write16(0x1001, 0xcc002034);
- Write16(0x01ae, 0xcc002032);
- Write16(0x1107, 0xcc002030);
- Write16(0x0000, 0xcc00206c);
-
- if (_bNTSC)
- Write16(0x0001, 0xcc002002); // STATUS REG
- else
- Write16(0x0101, 0xcc002002); // STATUS REG
+ if (m_XFBInfoTop.POFF)
+ return Memory::GetPointer(m_XFBInfoTop.FBB << 5);
+ else
+ return Memory::GetPointer(m_XFBInfoTop.FBB);
}
-void SetRegionReg(char _region)
+u8* GetXFBPointerBottom()
{
- Write16((u16)_region, 0xcc00206e);
+ if (m_XFBInfoBottom.POFF)
+ return Memory::GetPointer(m_XFBInfoBottom.FBB << 5);
+ else
+ return Memory::GetPointer(m_XFBInfoBottom.FBB);
}
void UpdateTiming()
{
- switch (m_VIDisplayControlRegister.FMT)
+ switch (m_DisplayControlRegister.FMT)
{
- case 0:
- case 2:
+ case 0: // NTSC
+ case 2: // MPAL
TicksPerFrame = SystemTimers::GetTicksPerSecond() / 30;
- LineCount = m_VIDisplayControlRegister.NIN ? 263 : 525;
+ LineCount = m_DisplayControlRegister.NIN ? 263 : 525;
LinesPerField = 263;
break;
- case 1:
+ case 1: // PAL
TicksPerFrame = SystemTimers::GetTicksPerSecond() / 25;
- LineCount = m_VIDisplayControlRegister.NIN ? 313 : 625;
+ LineCount = m_DisplayControlRegister.NIN ? 313 : 625;
LinesPerField = 313;
break;
+ case 3: // Debug
+ PanicAlert("Debug video mode not implemented");
+ break;
+
default:
PanicAlert("Unknown Video Format - CVideoInterface");
break;
@@ -508,13 +1035,13 @@ void Update()
{
LastTime += (TicksPerFrame / LineCount);
- VerticalBeamPos++;
- if (VerticalBeamPos > LineCount)
+ m_VBeamPos++;
+ if (m_VBeamPos > LineCount)
{
- VerticalBeamPos = 1;
+ m_VBeamPos = 1;
}
- if (VerticalBeamPos == NextXFBRender)
+ if (m_VBeamPos == NextXFBRender)
{
u8* xfbPtr = 0;
int yOffset = 0;
@@ -528,30 +1055,28 @@ void Update()
// TODO: proper VI regs typedef and logic for XFB to work.
// eg. Animal Crossing gc have smth in TFBL.XOF bitfield.
// "XOF - Horizontal Offset of the left-most pixel within the first word of the fetched picture."
- u32 addr = (m_FrameBufferTop.Hex & 0x00FFFFFF);
- if (m_FrameBufferTop.Hex & 0x10000000)
- addr = addr << 5;
- xfbPtr = Memory::GetPointer(addr);
+ xfbPtr = GetXFBPointerTop();
_dbg_assert_msg_(VIDEOINTERFACE, xfbPtr, "Bad top XFB address");
}
else
{
NextXFBRender = 1;
- // TODO: proper VI regs typedef and logic for XFB to work.
- u32 addr = (m_FrameBufferBottom.Hex & 0x00FFFFFF);
- // check the top buffer address not the bottom <- (mb2) why not on the bottom one?
- if (m_FrameBufferTop.Hex & 0x10000000)
- addr = addr << 5;
- xfbPtr = Memory::GetPointer(addr);
+ // Previously checked m_XFBInfoTop.POFF then used m_XFBInfoBottom.FBB, try reverting if there are problems
+ xfbPtr = GetXFBPointerBottom();
_dbg_assert_msg_(VIDEOINTERFACE, xfbPtr, "Bad bottom XFB address");
yOffset = -1;
}
+
Common::PluginVideo* video = CPluginManager::GetInstance().GetVideo();
+
if (xfbPtr && video->IsValid())
{
- int fbWidth = m_VIHorizontalStepping.FieldSteps * 16;
- int fbHeight = (m_VIHorizontalStepping.FbSteps / m_VIHorizontalStepping.FieldSteps) * m_VIVerticalTimingRegister.ACV;
- //LOGV(VIDEOINTERFACE,2,"(VI->XFBUpdate): ptr: %08x | %ix%i", (u32)xfbptr, fbWidth, fbHeight);
+ int fbWidth = m_HorizontalStepping.FieldSteps * 16;
+ int fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
+
+ DEBUG_LOG(VIDEOINTERFACE, "(VI->XFBUpdate): ptr: %p | %ix%i | xoff: %i",
+ xfbPtr, fbWidth, fbHeight, m_XFBInfoTop.XOFF);
+
if (Core::GetStartupParameter().bUseDualCore)
// scheduled on EmuThread in DC mode
video->Video_UpdateXFB(xfbPtr, fbWidth, fbHeight, yOffset, TRUE);
@@ -563,16 +1088,16 @@ void Update()
}
// check INT_PRERETRACE
- if (m_VIInterruptRegister[0].VCT == VerticalBeamPos)
+ if (m_InterruptRegister[0].VCT == m_VBeamPos)
{
- m_VIInterruptRegister[0].IR_INT = 1;
+ m_InterruptRegister[0].IR_INT = 1;
UpdateInterrupts();
}
// INT_POSTRETRACE
- if (m_VIInterruptRegister[1].VCT == VerticalBeamPos)
+ if (m_InterruptRegister[1].VCT == m_VBeamPos)
{
- m_VIInterruptRegister[1].IR_INT = 1;
+ m_InterruptRegister[1].IR_INT = 1;
UpdateInterrupts();
}
}
diff --git a/Source/Core/Core/Src/HW/VideoInterface.h b/Source/Core/Core/Src/HW/VideoInterface.h
index a1ac0bcdea..292629c1f5 100644
--- a/Source/Core/Core/Src/HW/VideoInterface.h
+++ b/Source/Core/Core/Src/HW/VideoInterface.h
@@ -30,6 +30,10 @@ namespace VideoInterface
INT_REG_3,
};
+ // For BIOS HLE
+ void PreInit(bool _bNTSC);
+ void SetRegionReg(char _region);
+
void Init();
void DoState(PointerWrap &p);
@@ -41,28 +45,20 @@ namespace VideoInterface
void GenerateVIInterrupt(VIInterruptType _VIInterrupt);
- // returns a pointer to the current visible framebuffer
- u8* GetFrameBufferPointer();
-
- // pre init
- void PreInit(bool _bNTSC);
+ // returns a pointer to the current visible xfb
+ u8* GetXFBPointerTop();
+ u8* GetXFBPointerBottom();
- void SetRegionReg(char _region);
-
- // VI Unknown Regs
- extern u8 m_UVIUnknownRegs[0x1000];
-
- // ??????
+ // Update and draw framebuffer(s)
void Update();
-
// UpdateInterrupts: check if we have to generate a new VI Interrupt
- void UpdateInterrupts();
+ void UpdateInterrupts();
- // ??????
+ // Change values pertaining to video mode
void UpdateTiming();
};
-#endif
+#endif // _VIDEOINTERFACE_H