mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-17 03:29:12 +01:00
f72b756778
We now provide a double to the FPS counter and exact values to FIFO recording and frame dumping.
383 lines
8.1 KiB
C++
383 lines
8.1 KiB
C++
// Copyright 2008 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
class PointerWrap;
|
|
namespace MMIO
|
|
{
|
|
class Mapping;
|
|
}
|
|
|
|
namespace VideoInterface
|
|
{
|
|
// VI Internal Hardware Addresses
|
|
enum
|
|
{
|
|
VI_VERTICAL_TIMING = 0x00,
|
|
VI_CONTROL_REGISTER = 0x02,
|
|
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_BOTTOM 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
|
|
{
|
|
u16 Hex = 0;
|
|
struct
|
|
{
|
|
u16 EQU : 4; // Equalization pulse in half lines
|
|
u16 ACV : 10; // Active video in lines per field (seems always zero)
|
|
u16 : 2;
|
|
};
|
|
|
|
UVIVerticalTimingRegister() = default;
|
|
explicit UVIVerticalTimingRegister(u16 hex) : Hex{hex} {}
|
|
};
|
|
|
|
union UVIDisplayControlRegister
|
|
{
|
|
u16 Hex = 0;
|
|
struct
|
|
{
|
|
u16 ENB : 1; // Enables video timing generation and data request
|
|
u16 RST : 1; // Clears all data requests and puts VI into its idle state
|
|
u16 NIN : 1; // 0: Interlaced, 1: Non-Interlaced: top field drawn at field rate and bottom
|
|
// field is not displayed
|
|
u16 DLR : 1; // Selects 3D Display Mode
|
|
u16 LE0 : 2; // Display Latch; 0: Off, 1: On for 1 field, 2: On for 2 fields, 3: Always on
|
|
u16 LE1 : 2;
|
|
u16 FMT : 2; // 0: NTSC, 1: PAL, 2: MPAL, 3: Debug
|
|
u16 : 6;
|
|
};
|
|
|
|
UVIDisplayControlRegister() = default;
|
|
explicit UVIDisplayControlRegister(u16 hex) : Hex{hex} {}
|
|
};
|
|
|
|
union UVIHorizontalTiming0
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 HLW : 10; // Halfline Width (W*16 = Width (720))
|
|
u32 : 6;
|
|
u32 HCE : 7; // Horizontal Sync Start to Color Burst End
|
|
u32 : 1;
|
|
u32 HCS : 7; // Horizontal Sync Start to Color Burst Start
|
|
u32 : 1;
|
|
};
|
|
};
|
|
|
|
union UVIHorizontalTiming1
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 HSY : 7; // Horizontal Sync Width
|
|
u32 HBE640 : 10; // Horizontal Sync Start to horizontal blank end
|
|
u32 HBS640 : 10; // Half line to horizontal blanking start
|
|
u32 : 5;
|
|
};
|
|
};
|
|
|
|
// Exists for both odd and even fields
|
|
union UVIVBlankTimingRegister
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 PRB : 10; // Pre-blanking in half lines
|
|
u32 : 6;
|
|
u32 PSB : 10; // Post blanking in half lines
|
|
u32 : 6;
|
|
};
|
|
};
|
|
|
|
// Exists for both odd and even fields
|
|
union UVIBurstBlankingRegister
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 BS0 : 5; // Field x start to burst blanking start in halflines
|
|
u32 BE0 : 11; // Field x start to burst blanking end in halflines
|
|
u32 BS2 : 5; // Field x+2 start to burst blanking start in halflines
|
|
u32 BE2 : 11; // Field x+2 start to burst blanking end in halflines
|
|
};
|
|
};
|
|
|
|
union UVIFBInfoRegister
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
// TODO: mask out lower 9bits/align to 9bits???
|
|
u32 FBB : 24; // Base address of the framebuffer in external mem
|
|
// POFF only seems to exist in the top reg. XOFF, unknown.
|
|
u32 XOFF : 4; // Horizontal Offset of the left-most pixel within the first word of the fetched
|
|
// picture
|
|
u32 POFF : 1; // Page offest: 1: fb address is (address>>5)
|
|
u32 CLRPOFF : 3; // ? setting bit 31 clears POFF
|
|
};
|
|
};
|
|
|
|
// VI Interrupt Register
|
|
union UVIInterruptRegister
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 HCT : 11; // Horizontal Position
|
|
u32 : 5;
|
|
u32 VCT : 11; // Vertical Position
|
|
u32 : 1;
|
|
u32 IR_MASK : 1; // Interrupt Mask Bit
|
|
u32 : 2;
|
|
u32 IR_INT : 1; // Interrupt Status (1=Active, 0=Clear)
|
|
};
|
|
};
|
|
|
|
union UVILatchRegister
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 HCT : 11; // Horizontal Count
|
|
u32 : 5;
|
|
u32 VCT : 11; // Vertical Count
|
|
u32 : 4;
|
|
u32 TRG : 1; // Trigger Flag
|
|
};
|
|
};
|
|
|
|
union PictureConfigurationRegister
|
|
{
|
|
u16 Hex;
|
|
struct
|
|
{
|
|
u16 STD : 8;
|
|
u16 WPL : 7;
|
|
u16 : 1;
|
|
};
|
|
};
|
|
|
|
union UVIHorizontalScaling
|
|
{
|
|
u16 Hex = 0;
|
|
struct
|
|
{
|
|
u16 STP : 9; // Horizontal stepping size (U1.8 Scaler Value) (0x160 Works for 320)
|
|
u16 : 3;
|
|
u16 HS_EN : 1; // Enable Horizontal Scaling
|
|
u16 : 3;
|
|
};
|
|
|
|
UVIHorizontalScaling() = default;
|
|
explicit UVIHorizontalScaling(u16 hex) : Hex{hex} {}
|
|
};
|
|
|
|
// Used for tables 0-2
|
|
union UVIFilterCoefTable3
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 Tap0 : 10;
|
|
u32 Tap1 : 10;
|
|
u32 Tap2 : 10;
|
|
u32 : 2;
|
|
};
|
|
};
|
|
|
|
// Used for tables 3-6
|
|
union UVIFilterCoefTable4
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 Tap0 : 8;
|
|
u32 Tap1 : 8;
|
|
u32 Tap2 : 8;
|
|
u32 Tap3 : 8;
|
|
};
|
|
};
|
|
|
|
struct SVIFilterCoefTables
|
|
{
|
|
UVIFilterCoefTable3 Tables02[3];
|
|
UVIFilterCoefTable4 Tables36[4];
|
|
};
|
|
|
|
// Debug video mode only, probably never used in Dolphin...
|
|
union UVIBorderBlankRegister
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u16 Lo, Hi;
|
|
};
|
|
struct
|
|
{
|
|
u32 HBE656 : 10; // Border Horizontal Blank End
|
|
u32 : 11;
|
|
u32 HBS656 : 10; // Border Horizontal Blank start
|
|
u32 BRDR_EN : 1; // Border Enable
|
|
};
|
|
};
|
|
|
|
// ntsc-j and component cable bits
|
|
union UVIDTVStatus
|
|
{
|
|
u16 Hex;
|
|
struct
|
|
{
|
|
u16 component_plugged : 1;
|
|
u16 ntsc_j : 1;
|
|
u16 : 14;
|
|
};
|
|
};
|
|
|
|
union UVIHorizontalStepping
|
|
{
|
|
u16 Hex;
|
|
struct
|
|
{
|
|
u16 srcwidth : 10;
|
|
u16 : 6;
|
|
};
|
|
};
|
|
|
|
// For BS2 HLE
|
|
void Preset(bool _bNTSC);
|
|
|
|
void Init();
|
|
void DoState(PointerWrap& p);
|
|
|
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
|
|
|
// returns a pointer to the current visible xfb
|
|
u32 GetXFBAddressTop();
|
|
u32 GetXFBAddressBottom();
|
|
|
|
// Update and draw framebuffer
|
|
void Update(u64 ticks);
|
|
|
|
// UpdateInterrupts: check if we have to generate a new VI Interrupt
|
|
void UpdateInterrupts();
|
|
|
|
// Change values pertaining to video mode
|
|
void UpdateParameters();
|
|
|
|
double GetTargetRefreshRate();
|
|
u32 GetTargetRefreshRateNumerator();
|
|
u32 GetTargetRefreshRateDenominator();
|
|
|
|
u32 GetTicksPerSample();
|
|
u32 GetTicksPerHalfLine();
|
|
u32 GetTicksPerField();
|
|
|
|
// Get the aspect ratio of VI's active area.
|
|
// This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply the
|
|
// result by 1.33333..
|
|
float GetAspectRatio();
|
|
|
|
// Create a fake VI mode for a fifolog
|
|
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_stride, u32 fb_height);
|
|
|
|
} // namespace VideoInterface
|