/
VideoInterface.h
340 lines (308 loc) · 8.51 KB
/
VideoInterface.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// 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;
struct
{
u16 EQU : 4; // Equalization pulse in half lines
u16 ACV : 10; // Active video in lines per field (seems always zero)
u16 : 2;
};
UVIVerticalTimingRegister(u16 _hex) { Hex = _hex;}
UVIVerticalTimingRegister() { Hex = 0;}
};
union UVIDisplayControlRegister
{
u16 Hex;
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(u16 _hex) { Hex = _hex;}
UVIDisplayControlRegister() { Hex = 0;}
};
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;
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(u16 _hex) { Hex = _hex;}
UVIHorizontalScaling() { Hex = 0;}
};
// 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;
};
};
// urgh, ugly externs.
extern u32 TargetRefreshRate;
// For BS2 HLE
void Preset(bool _bNTSC);
void Init();
void SetRegionReg(char region);
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();
// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();
// Change values pertaining to video mode
void UpdateParameters();
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();
}