PS2SDK
PS2 Homebrew Libraries
scr_printf.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
16 #include <ctype.h>
17 #include <stdio.h>
18 #include <tamtypes.h>
19 #include <sifcmd.h>
20 #include <kernel.h>
21 #include <rom0_info.h>
22 #include <stdarg.h>
23 #include <debug.h>
24 #include <ee_regs.h>
25 
26 static short int X, Y;
27 static const short int MX = 80, MY = 40;
28 static u32 bgcolor, fontcolor, cursorcolor;
29 static short int cursor;
30 
31 static u32 defcols[16];
32 
33 struct t_setupscr
34 {
35  u64 dd0[6];
36  u32 dw0[2];
37  u64 dd1[1];
38  u16 dh[4];
39  u64 dd2[21];
40 };
41 
43 {
44  u64 dd0[4];
45  u32 dw0[1];
46  u16 x, y;
47  u64 dd1[1];
48  u32 dw1[2];
49  u64 dd2[5];
50 };
51 
52 // from gsKit
53 static int debug_detect_signal()
54 {
55  char romname[14];
56  GetRomName(romname);
57  return ((romname[4] == 'E') ? 1 : 0);
58 }
59 
60 static void Init_GS(int interlace, int omode, int ffmd)
61 {
62  // Reset GS
63  *R_EE_GS_CSR = 0x200;
64  // Mask interrupts
65  GsPutIMR(0xff00);
66  // Configure GS CRT
67  SetGsCrt(interlace, omode, ffmd);
68 }
69 
70 static void SetVideoMode(void)
71 {
72  /* DISPLAY1 0x0983227c001bf9ff
73  DX = 0x27C (636)
74  DY = 0x032 (50)
75 
76  MAGH = 0x03 (4x)
77  MAGV = 0x01 (2x)
78 
79  DW = 0x9FF (2560)
80  DH = 0x1BF (447) */
81 
82  *R_EE_GS_PMODE = 0xff62;
83  *R_EE_GS_DISPFB2 = 0x1400;
84  *R_EE_GS_DISPLAY2 = 0x001bf9ff0983227c;
85 }
86 
87 static inline void Dma02Wait(void)
88 {
89  while ((*R_EE_D2_CHCR & 0x100) != 0); // Wait until STR bit of D2_CHCR = 0
90 }
91 
92 static void DmaReset(void)
93 {
94  // This appears to have been based on code from Sony that initializes DMA channels 0-9, in bulk.
95  *((vu32 *)0x1000a080) = 0; // D2_SADR = 0. Documented to not exist, but is done.
96  *R_EE_D2_CHCR = 0;
97  *R_EE_D2_TADR = 0;
98  *R_EE_D2_MADR = 0;
99  *R_EE_D2_ASR1 = 0;
100  *R_EE_D2_ASR0 = 0;
101  *R_EE_D_STAT = 0xff1f; // Clear all interrupt status under D_STAT, other than SIF0, SIF1 & SIF2.
102  *R_EE_D_STAT &= 0xff1f << 16; // Clear all interrupt masks under D_STAT, other SIF0, SIF1 & SIF2. Writing a 1 reverses the bit.
103  *R_EE_D_CTRL = 0;
104  *R_EE_D_PCR = 0;
105  *R_EE_D_SQWC = 0;
106  *R_EE_D_RBOR = 0;
107  *R_EE_D_RBSR = 0;
108  *R_EE_D_CTRL |= 1; // (DMAE 1)
109 }
110 
117 static inline void progdma(const void *addr, int size)
118 {
119  *R_EE_D2_QWC = (u32)size; // D2_QWC
120  *R_EE_D2_MADR = (u32)addr; // D2_MADR
121  *R_EE_D2_CHCR = 0x101; // D2_CHCR = STR 1, DIR 1
122 }
123 
124 void scr_setbgcolor(u32 color)
125 {
126  bgcolor = color;
127 }
128 
129 void scr_setfontcolor(u32 color)
130 {
131  fontcolor = color;
132 }
133 
134 static int hex2int(char c)
135 {
136  if (c >= '0' && c <= '9')
137  return c - '0';
138 
139  c &= ~0x20; // a-f -> A-F
140 
141  if (c >= 'A' && c <= 'F')
142  return c - 'A' + 10;
143 
144  return -1;
145 }
146 
147 void scr_change_defaultcolor(int index, u32 color) {
148  defcols[index] = color;
149 }
150 
151 void scr_setfontcolorescape(char n1, char n2)
152 {
153  int bg = hex2int(n1);
154  int fg = hex2int(n2);
155 
156  if (bg >= 0)
157  bgcolor = defcols[bg];
158 
159  if (fg >= 0)
160  fontcolor = defcols[fg];
161 }
162 
163 void scr_setcursorcolor(u32 color)
164 {
165  cursorcolor = color;
166 }
167 
168 static const struct t_setupscr g_setupscr_template = {
169  {0x100000000000800E, 0xE, 0xA0000, 0x4C, 0x8C, 0x4E}, // GIFtag (REGS: A+D, NREG 1, FLG PACKED, EOP, NLOOP 14), FRAME_1 (PSM PSMCT32, FBW 10, FBP 0), ZBUF_1 (PSM PSMZ32, ZBP 140)
170  {27648, 30976},
171  {0x18}, // XYOFFSET_1 (OFX 1728.0, OFY 1936.0)
172  {0, 639, 0, 223}, // SCISSOR_1 (SCAX0 0, SCAX1 639, SCAY0 0, SCAY1 223)
173  {0x40, 1, 0x1a, 1, 0x46, 0, 0x45, 0x70000, // PRMODECONT (AC PRIM), COLCLAMP (CLAMP 1), DTHE (DTHE 0)
174  0x47, 0x30000, 0x47, 6, 0, 0x3F80000000000000, 1, 0x79006C00, 5, // TEST_1 (ZTST GREATER, ZTE 1), TEST_1 (ZTST ALWAYS, ZTE 1), PMODE (CRTMD 1, EN2 1), RGBAQ (Q 1.0, A 0, B 0, G 0, R 0), XYZ2 (Z 0.0, Y 1728.0, X 1936.0)
175  0x87009400, 5, 0x70000, 0x47} // XYZ2 (Z 0, Y 2160.0, X 2368.0), TEST_1 (ZTST GREATER, ZTE 1)
176 };
177 
178 void init_scr(void)
179 {
180  static struct t_setupscr setupscr __attribute__((aligned(16)));
181 
182  *((struct t_setupscr *)UNCACHED_SEG(&setupscr)) = g_setupscr_template;
183  X = Y = 0;
184  scr_setbgcolor(0);
185  scr_setfontcolor(0xffffff);
186  scr_setcursorcolor(0xffffff);
187  defcols[0] = 0x000000;
188  defcols[1] = 0xDA3700;
189  defcols[2] = 0xDD963A;
190  defcols[3] = 0x981788;
191  defcols[4] = 0x1F0FC5;
192  defcols[5] = 0xCCCCCC;
193  defcols[6] = 0x009CC1;
194  defcols[7] = 0x767676;
195  defcols[8] = 0xFF783B;
196  defcols[9] = 0xD6D661;
197  defcols[10] = 0x0CC616;
198  defcols[11] = 0x9E00B4;
199  defcols[12] = 0x5648E7;
200  defcols[13] = 0xF2F2F2;
201  defcols[14] = 0xA5F1F9;
202  defcols[15] = 0xFFFFFF;
203 
204  scr_setCursor(1);
205  DmaReset();
206 
207  Init_GS(1, debug_detect_signal() == 1 ? 3 : 2, 0); // Interlaced, NTSC/PAL and FIELD mode
208 
209  SetVideoMode();
210  Dma02Wait();
211  progdma(&setupscr, 15);
212  Dma02Wait();
213 }
214 
215 extern const u8 msx[];
216 
217 static const struct t_setupchar g_setupchar_template = {
218  {0x1000000000000004, 0xE, 0xA000000000000, 0x50}, // GIFtag (REGS: A+D, NREG 1, FLG PACKED, NLOOP 4), BITBLTBUF (DPSM PSMCT32, DBW 10, DBP 0)
219  {0},
220  100,
221  100,
222  {0x51}, // TRXPOS (DSAX 100, DSAY 100)
223  {8, 8}, // TRXREG (RRW 8, RRH 8)
224  {0x52, 0, 0x53, 0x800000000008010, 0} // TRXDIR (XDIR Host -> Local), GIFtag (FLG IMAGE, EOP, NLOOP 16)
225 };
226 
227 void scr_putchar(int x, int y, u32 color, int ch)
228 {
229  static struct t_setupchar setupchar __attribute__((aligned(16)));
230  /* charmap must be aligned to a 16-byte boundary. */
231  static u32 charmap[64] __attribute__((aligned(16)));
232  int i, j, l;
233  const u8 *font;
234  u32 pixel;
235 
236  *((struct t_setupchar *)UNCACHED_SEG(&setupchar)) = g_setupchar_template;
237  ((struct t_setupchar *)UNCACHED_SEG(&setupchar))->x = x;
238  ((struct t_setupchar *)UNCACHED_SEG(&setupchar))->y = y;
239 
240  progdma(&setupchar, 6);
241 
242  font = &msx[ch * 8];
243  for (i = l = 0; i < 8; i++, l += 8, font++) {
244  for (j = 0; j < 8; j++) {
245  pixel = ((*font & (128 >> j))) ? color : bgcolor;
246  *(u32 *)UNCACHED_SEG(&charmap[l + j]) = pixel;
247  }
248  }
249 
250  Dma02Wait();
251 
252  progdma(charmap, (8 * 8 * 4) / 16);
253  Dma02Wait();
254 }
255 
256 void scr_clearchar(int X, int Y)
257 {
258  scr_putchar(X * 8, Y * 8, bgcolor, ' ');
259 }
260 
261 void scr_clearline(int Y)
262 {
263  int i;
264  for (i = 0; i < MX; i++)
265  scr_putchar(i * 8, Y * 8, bgcolor, ' ');
266 }
267 
268 void scr_printf(const char *format, ...)
269 {
270  va_list opt;
271  va_start(opt, format);
272  scr_vprintf(format, opt);
273  va_end(opt);
274 }
275 
276 void scr_vprintf(const char *format, va_list opt)
277 {
278  char buff[2048];
279  int i, bufsz, j;
280 
281 
282  bufsz = vsnprintf(buff, sizeof(buff), format, opt);
283 
284  for (i = 0; i < bufsz; i++) {
285  char c;
286  c = buff[i];
287  switch (c) {
288  case '\n':
289  X = 0;
290  Y++;
291  if (Y == MY)
292  Y = 0;
293  scr_clearline(Y);
294  break;
295  case '\t':
296  for (j = 0; j < 5; j++) {
297  scr_putchar(X * 7, Y * 8, fontcolor, ' ');
298  X++;
299  }
300  break;
301  case '\r':
302  X = 0;
303  break;
304  case '\x1b': // color escape
305  if (i+2 < bufsz && isxdigit((unsigned char)buff[i+1]) && isxdigit((unsigned char)buff[i+2])) {
306  scr_setfontcolorescape(buff[i+1], buff[i+2]);
307  i+=2;
308  }
309  break;
310  default:
311  scr_putchar(X * 7, Y * 8, fontcolor, c);
312  X++;
313  if (X == MX) {
314  X = 0;
315  Y++;
316  if (Y == MY)
317  Y = 0;
318  scr_clearline(Y);
319  }
320  }
321  }
322  if (cursor)
323  scr_putchar(X * 7, Y * 8, cursorcolor, 219);
324 }
325 
326 void scr_setXY(int x, int y)
327 {
328  if (x < MX && x >= 0)
329  X = x;
330  if (y < MY && y >= 0)
331  Y = y;
332 }
333 
334 int scr_getX()
335 {
336  return X;
337 }
338 
339 int scr_getY()
340 {
341  return Y;
342 }
343 
344 void scr_clear()
345 {
346  int y;
347  for (y = 0; y < MY; y++)
348  scr_clearline(y);
349  scr_setXY(0, 0);
350 }
351 
352 void scr_setCursor(int enable)
353 {
354  cursor = enable;
355 }
kernel.h
R_EE_GS_PMODE
#define R_EE_GS_PMODE
Definition: ee_regs.h:567
R_EE_D_PCR
#define R_EE_D_PCR
Definition: ee_regs.h:452
rom0_info.h
R_EE_D2_MADR
#define R_EE_D2_MADR
Definition: ee_regs.h:386
R_EE_D_RBSR
#define R_EE_D_RBSR
Definition: ee_regs.h:456
GetRomName
char * GetRomName(char *romname)
R_EE_D_CTRL
#define R_EE_D_CTRL
Definition: ee_regs.h:448
R_EE_D2_ASR1
#define R_EE_D2_ASR1
Definition: ee_regs.h:394
ctype.h
__attribute__
typedef __attribute__
Definition: tlbfunc.c:60
t_setupscr
Definition: scr_printf.c:33
R_EE_GS_DISPFB2
#define R_EE_GS_DISPFB2
Definition: ee_regs.h:585
t_setupchar
Definition: scr_printf.c:42
R_EE_D_STAT
#define R_EE_D_STAT
Definition: ee_regs.h:450
tamtypes.h
stdio.h
progdma
static void progdma(const void *addr, int size)
Definition: scr_printf.c:117
R_EE_D2_CHCR
#define R_EE_D2_CHCR
Definition: ee_regs.h:384
__attribute__
Definition: gif_registers.h:38
R_EE_D_RBOR
#define R_EE_D_RBOR
Definition: ee_regs.h:458
R_EE_D2_QWC
#define R_EE_D2_QWC
Definition: ee_regs.h:388
R_EE_D_SQWC
#define R_EE_D_SQWC
Definition: ee_regs.h:454
R_EE_GS_CSR
#define R_EE_GS_CSR
Definition: ee_regs.h:597
R_EE_D2_TADR
#define R_EE_D2_TADR
Definition: ee_regs.h:390
ee_regs.h
R_EE_GS_DISPLAY2
#define R_EE_GS_DISPLAY2
Definition: ee_regs.h:587
R_EE_D2_ASR0
#define R_EE_D2_ASR0
Definition: ee_regs.h:392