ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
graph_mode.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <kernel.h>
3 #include <osd_config.h>
4 
5 #include <gs_privileged.h>
6 
7 #include <graph.h>
8 #include <graph_config.h>
9 
10 /* y offset is non-interlaced */
12 {
13 
14  { 0, 0, 0, 0, 0 }, // AUTO
15  { 652, 26, 2560, 224, 0x02 }, // NTSC-NI
16  { 680, 37, 2560, 256, 0x03 }, // PAL-NI
17  { 232, 35, 1440, 480, 0x50 }, // 480P
18  { 320, 64, 1312, 576, 0x53 }, // 576P only in bios>=220
19  { 420, 40, 1280, 720, 0x52 }, // 720P
20  { 300, 120, 1920, 540, 0x51 }, // 1080I
21  { 280, 18, 1280, 480, 0x1A }, // VGA 640x480@60
22  { 330, 18, 1280, 480, 0x1B }, // VGA 640x480@72
23  { 360, 18, 1280, 480, 0x1C }, // VGA 640x480@75
24  { 260, 18, 1280, 480, 0x1D }, // VGA 640x480@85
25  { 450, 25, 1600, 600, 0x2A }, // VGA 800x600@56
26  { 465, 25, 1600, 600, 0x2B }, // VGA 800x600@60
27  { 465, 25, 1600, 600, 0x2C }, // VGA 800x600@72
28  { 510, 25, 1600, 600, 0x2D }, // VGA 800x600@75
29  { 500, 25, 1600, 600, 0x2E }, // VGA 800x600@85
30  { 580, 30, 2048, 768, 0x3B }, // VGA 1024x768@60
31  { 266, 30, 1024, 768, 0x3C }, // VGA 1024x768@70
32  { 260, 30, 1024, 768, 0x3D }, // VGA 1024x768@75
33  { 290, 30, 1024, 768, 0x3E }, // VGA 1024x768@85
34  { 350, 40, 1280, 1024, 0x4A }, // VGA 1280x1024@60
35  { 350, 40, 1280, 1024, 0x4B }, // VGA 1280x1024@75
36 
37 };
38 
39 static float graph_width = 0.0f;
40 static float graph_height = 0.0f;
41 static float graph_aspect = 1.0f;
42 
43 static int graph_filter = 0;
44 static int graph_crtmode = 0;
45 static int graph_interlace = 0;
46 static int graph_ffmd = 0;
47 static int graph_x = 0;
48 static int graph_y = 0;
49 static int graph_magh = 0;
50 static int graph_magv = 0;
51 
52 static u64 graph_pmode = 0;
53 
54 // old bios has GCONT enabled
56 {
57 
58  0,
59  GS_SET_SMODE1(4,32,1,0,2,0,1,1,0,0,4,0,0,0,0,0,1,1,1,1,0), //0x02
60  GS_SET_SMODE1(4,32,1,0,3,0,1,1,0,0,4,0,0,0,0,0,1,1,1,1,0), //0x03
61  GS_SET_SMODE1(4,32,1,0,0,0,1,1,0,0,2,0,0,0,0,0,1,1,1,1,1), //0x50
62  GS_SET_SMODE1(4,32,1,0,0,0,1,1,0,1,2,0,0,0,0,0,1,1,1,1,1), //0x53
63  GS_SET_SMODE1(2,22,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1), //0x52
64  GS_SET_SMODE1(2,22,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,0), //0x51
65  GS_SET_SMODE1(2,15,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x1A
66  GS_SET_SMODE1(3,28,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x1B
67  GS_SET_SMODE1(3,28,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x1C
68  GS_SET_SMODE1(3,16,0,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x1D
69  GS_SET_SMODE1(3,16,0,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x2A
70  GS_SET_SMODE1(6,71,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x2B
71  GS_SET_SMODE1(5,74,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x2C
72  GS_SET_SMODE1(3,44,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x2D
73  GS_SET_SMODE1(3,25,0,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x2E
74  GS_SET_SMODE1(3,29,0,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,1,0,1), //0x3B
75  GS_SET_SMODE1(6,67,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1), //0x3C
76  GS_SET_SMODE1(3,35,1,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1), //0x3D
77  GS_SET_SMODE1(1, 7,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1), //0x3E
78  GS_SET_SMODE1(1, 8,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1), //0x4A
79  GS_SET_SMODE1(1,10,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,1), //0x4B
80 
81 };
82 
83 static inline int __udelay(unsigned int usecs)
84 {
85 
86  register unsigned int loops_total = 0;
87  register unsigned int loops_end = usecs * 148;
88 
89  if (usecs > loops_end)
90  {
91 
92  return -1;
93 
94  }
95 
96  asm volatile (".set noreorder\n\t"
97  "0:\n\t"
98  "beq %0,%2,0f\n\t"
99  "addiu %0,1\n\t"
100  "bne %0,%2,0b\n\t"
101  "addiu %0,1\n\t"
102  "0:\n\t"
103  ".set reorder\n\t"
104  :"=r" (loops_total)
105  :"0" (loops_total), "r" (loops_end));
106 
107  return 0;
108 
109 }
110 
112 {
113 
114  char romname[14];
115 
116  GetRomName((char *)romname);
117 
118  if (romname[4] == 'E')
119  {
120  return GRAPH_MODE_PAL;
121  }
122 
123  return GRAPH_MODE_NTSC;
124 
125 }
126 
127 int graph_set_mode(int interlace, int mode, int ffmd, int flicker_filter)
128 {
129 
130  char romname[14];
131 
132  // Reset GS.
133  *GS_REG_CSR = (u64)1<<9;
134 
135  // Clear GS CSR.
136  *GS_REG_CSR = GS_SET_CSR(0,0,0,0,0,0,0,0,0,0,0,0);
137 
138  // Unmask GS VSYNC Interrupt.
139  GsPutIMR(0x00007700);
140 
141  // Ensure registers are written prior to setting another mode.
142  asm volatile ("sync.p\n\t"
143  "nop\n\t");
144 
145  // If 576P is requested, check if bios supports it.
146  if (mode == GRAPH_MODE_HDTV_576P)
147  {
148 
149  GetRomName((char *)romname);
150 
151  if (strtol(romname,NULL,10) < 220) { mode = GRAPH_MODE_PAL; }
152 
153  }
154 
155  // 1080I is forced to be interlaced so correct value just in case.
157  {
158 
159  interlace = GRAPH_MODE_INTERLACED;
160 
161  }
162 
163  if (interlace == GRAPH_MODE_NONINTERLACED)
164  {
165 
166  flicker_filter = GRAPH_DISABLE;
167 
168  }
169 
170  // Set graph's mode, interlacing and field mode.
172  graph_interlace = interlace;
173  graph_ffmd = ffmd;
174  graph_filter = flicker_filter;
175 
176  // Set the requested mode.
178 
179  return 0;
180 
181 }
182 
183 int graph_set_screen(int x, int y, int width, int height)
184 {
185 
186  int dx,dy,dw,dh;
187 
188  graph_x = x;
189  graph_y = y;
190 
191  graph_width = (float)width;
192  graph_height = (float)height;
193 
194  // Check if the mode has been set
196  {
197 
198  return -1;
199 
200  }
201 
202  // Add X adjustment to default X offset
204 
205  // Get default Y offset
206  dy = graph_mode[graph_crtmode].y;
207 
208  // Get screen's width and height
211 
212  // Double Y offset for interlacing in FIELD mode
213  // Double screen's height parameter
215  {
216 
217  dy = (dy - 1) * 2;
218  dh = graph_mode[graph_crtmode].height * 2;
219 
220  }
221 
222  // Now add Y adjustment
223  dy += graph_y;
224 
225  // Determine magnification
226  graph_magh = dw / width;
227  graph_magv = dh / height;
228 
229  // Make sure it doesn't turn negative
230  if (graph_magh < 1)
231  {
232 
233  graph_magh = 1;
234 
235  }
236 
237  if (graph_magv < 1)
238  {
239 
240  graph_magv = 1;
241 
242  }
243 
244  // Set the display attributes but use the user defined height.
245  if (graph_filter)
246  {
247 
248  // For flicker filter, we need to get add an extra line.
249  *GS_REG_DISPLAY1 = GS_SET_DISPLAY(dx,dy,graph_magh-1,graph_magv-1,dw-1,height-1);
250  *GS_REG_DISPLAY2 = GS_SET_DISPLAY(dx,dy,graph_magh-1,graph_magv-1,dw-1,height-2);
251 
252  }
253  else
254  {
255 
256  *GS_REG_DISPLAY1 = GS_SET_DISPLAY(dx,dy,graph_magh-1,graph_magv-1,dw-1,height-1);
257  *GS_REG_DISPLAY2 = GS_SET_DISPLAY(dx,dy,graph_magh-1,graph_magv-1,dw-1,height-1);
258 
259  }
260 
261  return 0;
262 
263 }
264 
265 void graph_set_framebuffer_filtered(int fbp, int width, int psm, int x, int y)
266 {
267 
268  *GS_REG_DISPFB1 = GS_SET_DISPFB(fbp>>11,width>>6,psm,x,y);
269 
270  // For flicker filter, we need to offset the lines by 1 for the other read circuit.
271  *GS_REG_DISPFB2 = GS_SET_DISPFB(fbp>>11,width>>6,psm,x,y+1);
272 
273 }
274 
275 void graph_set_framebuffer(int context, int fbp, int width, int psm, int x, int y)
276 {
277 
278  if (context == 0)
279  {
280 
281  *GS_REG_DISPFB1 = GS_SET_DISPFB(fbp>>11,width>>6,psm,x,y);
282 
283  }
284  else
285  {
286 
287  // For flicker filter, we need to offset the lines by 1 for the other read circuit.
288  *GS_REG_DISPFB2 = GS_SET_DISPFB(fbp>>11,width>>6,psm,x,y);
289 
290  }
291 
292 }
293 
294 void graph_set_bgcolor(unsigned char r, unsigned char g, unsigned char b)
295 {
296 
297  *GS_REG_BGCOLOR = GS_SET_BGCOLOR(r,g,b);
298 
299 }
300 
301 void graph_set_output(int rc1, int rc2, int alpha_select, int alpha_output, int blend_method, unsigned char alpha)
302 {
303 
304  graph_pmode = GS_SET_PMODE(rc1, rc2, alpha_select, alpha_output, blend_method, alpha);
306 
307 }
308 
309 // Sets up the frame in rc1 to be blended with rc2 using a constant alpha value.
310 // By offsetting the frame a line in the rc2 display/dispfb registers, the odd
311 // numbered lines are more biased against the even lines, producing less jitter.
313 {
314 
315  if (graph_filter)
316  {
317 
319 
320  }
321  else
322  {
323 
324  graph_set_output(0,1,0,1,0,0x80);
325 
326  }
327 
328 }
329 
331 {
332 
333  graph_set_output(0,0,0,0,0,0);
334 
335 }
336 
337 void graph_set_smode1(char cmod, char gcont)
338 {
339 
340  u64 pmode_val;
341  u64 smode1_val;
342 
343  // Get the current values;
344  pmode_val = graph_pmode;
345  smode1_val = smode1_values[graph_crtmode];
346 
347  if (smode1_val == 0)
348  {
349 
350  return;
351 
352  }
353 
354  // If not VESA, set analog or digital output.
355  if ((graph_crtmode < 0x04) || (graph_crtmode > 0x50))
356  {
357 
358  smode1_val |= (u64)(gcont & 1) << 25;
359 
360  }
361 
362  // If mode is a TV mode, set carrier modulation.
363  if ((graph_crtmode < 0x04) && (cmod > 0x01) && (cmod < 0x04))
364  {
365 
366  smode1_val |= (u64)(cmod & 3) << 13;
367 
368  }
369 
370  // Turn off read circuits.
371  *GS_REG_PMODE = graph_pmode & ~3;
372 
373  // Disable PRST for TV modes and enable for all other modes.
374  *GS_REG_SMODE1 = smode1_val | (u64)1 << 16;
375 
376  asm volatile ("sync.l; sync.p;");
377 
378  // If VESA, 1080I, or 720P, disable bit PRST now and delay 2.5ms.
379  if ((graph_crtmode >= 0x1A) && (graph_crtmode != 0x50) && (graph_crtmode != 0x53))
380  {
381 
382  *GS_REG_SMODE1 = smode1_val & ~((u64)1 << 16);
383  __udelay(2500);
384 
385  }
386 
387  // Now disable both bits PRST & SINT.
388  *GS_REG_SMODE1 = smode1_val & ~((u64)1 << 16) & ~((u64)1 << 17);
389 
390  // Now enable read circuits.
391  *GS_REG_PMODE = pmode_val;
392 
393  asm volatile ("sync.l; sync.p;");
394 
395 }
396 
398 {
399 
400  // Get the tv screen type as defined in the osd configuration.
402  {
403 
404  graph_aspect = 1.78f;
405 
406  }
407  else
408  {
409 
410  graph_aspect = 1.33f;
411 
412  }
413 
414  // Return the current aspect ratio
416 
417  return graph_aspect;
418 
419 }
420 
421 int graph_get_config(char *config)
422 {
423 
425 
426 }
427 
428 int graph_shutdown(void)
429 {
430 
432 
433  // Reset GS.
434  *GS_REG_CSR = (u64)1<<9;
435 
436  // Clear GS CSR.
437  *GS_REG_CSR = GS_SET_CSR(0,0,0,0,0,0,0,0,0,0,0,0);
438 
439  // Reset the static variables.
440  graph_aspect = 1.0f;
441  graph_width = 0.0f;
442  graph_height = 0.0f;
443  graph_filter = 0;
444  graph_crtmode = 0;
445  graph_interlace = 0;
446  graph_ffmd = 0;
447  graph_x = 0;
448  graph_y = 0;
449  graph_magh = 0;
450  graph_magv = 0;
451 
452  return 0;
453 
454 }
u8 context
Definition: main.c:71
#define GRAPH_MODE_NTSC
Definition: graph.h:15
#define GRAPH_MODE_NONINTERLACED
Definition: graph.h:57
#define GRAPH_DISABLE
Definition: graph.h:67
#define GRAPH_MODE_AUTO
Definition: graph.h:13
#define GRAPH_MODE_HDTV_576P
Definition: graph.h:21
#define GRAPH_ENABLE
Definition: graph.h:68
#define GRAPH_MODE_HDTV_1080I
Definition: graph.h:25
#define GRAPH_RC1_ALPHA
Definition: graph.h:82
#define GRAPH_MODE_INTERLACED
Definition: graph.h:58
#define GRAPH_VALUE_ALPHA
Definition: graph.h:79
#define GRAPH_MODE_PAL
Definition: graph.h:17
#define GRAPH_BLEND_RC2
Definition: graph.h:86
#define GRAPH_MODE_FIELD
Definition: graph.h:60
int graph_make_config(int mode, int interlace, int ffmd, int x, int y, int flicker_filter, char *config)
Definition: graph_config.c:8
int graph_set_screen(int x, int y, int width, int height)
Definition: graph_mode.c:183
static float graph_height
Definition: graph_mode.c:40
void graph_set_bgcolor(unsigned char r, unsigned char g, unsigned char b)
Definition: graph_mode.c:294
static int graph_x
Definition: graph_mode.c:47
static u64 graph_pmode
Definition: graph_mode.c:52
void graph_set_output(int rc1, int rc2, int alpha_select, int alpha_output, int blend_method, unsigned char alpha)
Definition: graph_mode.c:301
static float graph_aspect
Definition: graph_mode.c:41
static int __udelay(unsigned int usecs)
Definition: graph_mode.c:83
static int graph_magv
Definition: graph_mode.c:50
void graph_enable_output(void)
Definition: graph_mode.c:312
int graph_get_config(char *config)
Definition: graph_mode.c:421
void graph_set_framebuffer_filtered(int fbp, int width, int psm, int x, int y)
Definition: graph_mode.c:265
static int graph_y
Definition: graph_mode.c:48
int graph_get_region(void)
Definition: graph_mode.c:111
int graph_shutdown(void)
Definition: graph_mode.c:428
static int graph_ffmd
Definition: graph_mode.c:46
static int graph_interlace
Definition: graph_mode.c:45
static int graph_crtmode
Definition: graph_mode.c:44
static int graph_magh
Definition: graph_mode.c:49
u64 smode1_values[22]
Definition: graph_mode.c:55
void graph_set_smode1(char cmod, char gcont)
Definition: graph_mode.c:337
static float graph_width
Definition: graph_mode.c:39
GRAPH_MODE graph_mode[22]
Definition: graph_mode.c:11
void graph_disable_output(void)
Definition: graph_mode.c:330
float graph_aspect_ratio(void)
Definition: graph_mode.c:397
int graph_set_mode(int interlace, int mode, int ffmd, int flicker_filter)
Definition: graph_mode.c:127
void graph_set_framebuffer(int context, int fbp, int width, int psm, int x, int y)
Definition: graph_mode.c:275
static int graph_filter
Definition: graph_mode.c:43
#define GS_REG_CSR
Definition: gs_privileged.h:45
#define GS_SET_DISPFB(FBP, FBW, PSM, DBX, DBY)
Definition: gs_privileged.h:70
#define GS_REG_DISPFB1
Definition: gs_privileged.h:29
#define GS_REG_BGCOLOR
Definition: gs_privileged.h:43
#define GS_REG_SMODE1
Definition: gs_privileged.h:17
#define GS_REG_DISPLAY1
Definition: gs_privileged.h:31
#define GS_SET_DISPLAY(DX, DY, MAGH, MAGV, DW, DH)
Definition: gs_privileged.h:75
#define GS_REG_PMODE
Definition: gs_privileged.h:15
#define GS_REG_DISPLAY2
Definition: gs_privileged.h:35
#define GS_REG_DISPFB2
Definition: gs_privileged.h:33
void SetGsCrt(s16 interlace, s16 pal_ntsc, s16 field)
u64 GsPutIMR(u64 imr)
#define GS_SET_SMODE1(rc, lc, t1248, slck, cmod, ex, prst, sint, xpck, pck2, spml, gcont, phs, pvs, pehs, pevs, clksel, nvck, slck2, vcksel, vhp)
Definition: libgs.h:1153
#define GS_SET_PMODE(enable_rc1, enable_rc2, mmod, amod, blend_style, blend_value)
Definition: libgs.h:1142
#define GS_SET_CSR(signal_evnt, finish_evnt, hsync_intrupt, vsync_intrupt, write_terminate, flush, reset, nfield, current_field, fifo_status, gs_rev_number, gs_id)
Definition: libgs.h:1249
#define GS_SET_BGCOLOR(r, g, b)
Definition: libgs.h:1243
s32 x
Definition: libmouse.c:34
s32 y
Definition: libmouse.c:34
int configGetTvScreenType(void)
@ TV_SCREEN_169
Definition: osd_config.h:58
char * GetRomName(char *romname)
s32 mode
Definition: rpc_client.c:15
int width
Definition: graph.h:91
int y
Definition: graph.h:90
int height
Definition: graph.h:91
int x
Definition: graph.h:90
#define NULL
Definition: tamtypes.h:91
unsigned long u64
Definition: tamtypes.h:34