forked from dolphin-emu/fifoplayer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVideoInterface.h
357 lines (333 loc) · 9.28 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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#ifndef _VIDEOINTERFACE_H
#define _VIDEOINTERFACE_H
namespace VideoInterface
{
// NTSC is 60 FPS, right?
// Wrong, it's about 59.94 FPS. The NTSC engineers had to slightly lower
// the field rate from 60 FPS when they added color to the standard.
// This was done to prevent analog interference between the video and
// audio signals. PAL has no similar reduction; it is exactly 50 FPS.
//#define NTSC_FIELD_RATE (60.0f / 1.001f)
#define NTSC_FIELD_RATE 60
#define NTSC_LINE_COUNT 525
// These line numbers indicate the beginning of the "active video" in a frame.
// An NTSC frame has the lower field first followed by the upper field.
// TODO: Is this true for PAL-M? Is this true for EURGB60?
#define NTSC_LOWER_BEGIN 21
#define NTSC_UPPER_BEGIN 283
//#define PAL_FIELD_RATE 50.0f
#define PAL_FIELD_RATE 50
#define PAL_LINE_COUNT 625
// These line numbers indicate the beginning of the "active video" in a frame.
// A PAL frame has the upper field first followed by the lower field.
#define PAL_UPPER_BEGIN 23
#define PAL_LOWER_BEGIN 336
// 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 : 9; // Halfline Width (W*16 = Width (720))
u32 : 7;
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 : 9; // Horizontal Sync Start to horizontal blank end
u32 : 1;
u32 HBS640 : 9; // Half line to horizontal blanking start
u32 : 6;
};
};
// 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
{
#if BYTE_ORDER == BIG_ENDIAN
u32 CLRPOFF : 3; // ? setting bit 31 clears POFF
// POFF only seems to exist in the top reg. XOFF, unknown.
u32 POFF : 1; // Page offest: 1: fb address is (address>>5)
u32 XOFF : 4; // Horizontal Offset of the left-most pixel within the first word of the fetched picture
// TODO: mask out lower 9bits/align to 9bits???
u32 FBB : 24; // Base address of the framebuffer in external mem
#elif BYTE_ORDER == LITTLE_ENDIAN
// 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
#else
#error endianness undefined
#endif
};
};
// 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 UVIHorizontalStepping
{
u16 Hex;
struct
{
u16 FbSteps : 8;
u16 FieldSteps : 8;
};
};
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;
};
};
struct VIMemory
{
UVIVerticalTimingRegister vertical_timing;
UVIDisplayControlRegister display_control;
UVIHorizontalTiming0 htiming0;
UVIHorizontalTiming1 htiming1;
UVIVBlankTimingRegister vblank_timing_odd;
UVIVBlankTimingRegister vblank_timing_even;
UVIBurstBlankingRegister burst_blanking_odd;
UVIBurstBlankingRegister burst_blanking_even;
UVIFBInfoRegister xfb_info_top;
UVIFBInfoRegister xfb_info_top_3d; // Start making your stereoscopic demos! :p
UVIFBInfoRegister xfb_info_bottom;
UVIFBInfoRegister xfb_info_bottom_3d;
u16 vbeam_pos; // 0: Inactive
u16 hbeam_pos; // 0: Inactive
UVIInterruptRegister interrupt[4];
UVILatchRegister latch[2];
UVIHorizontalStepping horizontal_stepping;
UVIHorizontalScaling horizontal_scaling;
SVIFilterCoefTables filter_coef_tables;
u32 unk_aa;// ??? 0x00FF0000
u16 clock; // 0: 27MHz, 1: 54MHz
UVIDTVStatus dtv_status;
u16 fbwidth; // Only correct when scaling is enabled?
UVIBorderBlankRegister border_hblank;
};
};
#endif // _VIDEOINTERFACE_H