ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
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 <stdio.h>
17 #include <tamtypes.h>
18 #include <sifcmd.h>
19 #include <kernel.h>
20 #include <osd_config.h>
21 #include <stdarg.h>
22 #include <debug.h>
23 
24 static short int X = 0, Y = 0;
25 static short int MX=80, MY=40;
26 static u32 bgcolor = 0;
27 
28 struct t_setupscr
29 {
30  u64 dd0[6];
31  u32 dw0[2];
32  u64 dd1[1];
33  u16 dh[4];
34  u64 dd2[21];
35 };
36 
38 {
39  u64 dd0[4];
40  u32 dw0[1];
41  u16 x,y;
42  u64 dd1[1];
43  u32 dw1[2];
44  u64 dd2[5];
45 };
46 
47 // from gsKit
48 static int debug_detect_signal()
49 {
50  char romname[14];
51  GetRomName(romname);
52  return((romname[4] == 'E') ? 1 : 0);
53 }
54 
55 static void Init_GS( int interlace, int omode, int ffmd)
56 {
57  // Reset GS
58  *(vu64 *)0x12001000 = 0x200;
59  // Mask interrupts
60  GsPutIMR(0xff00);
61  // Configure GS CRT
62  SetGsCrt(interlace, omode, ffmd);
63 }
64 
65 static void SetVideoMode(void)
66 {
67  unsigned dma_addr;
68  unsigned val1;
69  unsigned val2;
70  unsigned val3;
71  unsigned val4;
72  unsigned val4_lo;
73 
74 /* DISPLAY1 0x0983227c001bf9ff
75  DX = 0x27C (636)
76  DY = 0x032 (50)
77 
78  MAGH = 0x03 (4x)
79  MAGV = 0x01 (2x)
80 
81  DW = 0x9FF (2560)
82  DH = 0x1BF (447) */
83 
84  asm volatile (" .set push \n"
85  " .set noreorder \n"
86  " lui %4, 0x001b \n"
87  " lui %5, 0x0983 \n"
88  " lui %0, 0x1200 \n"
89  " ori %4, %4, 0xf9ff \n"
90  " ori %5, %5, 0x227c \n"
91  " li %1, 0xff62 \n"
92  " dsll32 %4, %4, 0 \n"
93  " li %3, 0x1400 \n"
94  " sd %1, 0(%0) \n"
95  " or %4, %4, %5 \n"
96  " sd %3, 0x90(%0) \n"
97  " sd %4, 0xa0(%0) \n"
98  " .set pop \n"
99  : "=&r" (dma_addr), "=&r" (val1), "=&r" (val2),
100  "=&r" (val3), "=&r" (val4), "=&r" (val4_lo) );
101 }
102 
103 static inline void Dma02Wait(void)
104 {
105  unsigned dma_addr;
106  unsigned status;
107 
108  asm volatile (" .set push \n"
109  " .set noreorder \n"
110  " lui %0, 0x1001 \n"
111  " lw %1, -0x6000(%0) \n"
112  "1: andi %1, %1, 0x100 \n" // Wait until STR bit of D2_CHCR = 0
113  " nop \n"
114  " nop \n"
115  " nop \n"
116  " nop \n"
117  " bnel %1, $0, 1b \n"
118  " lw %1, -0x6000(%0) \n"
119  " .set pop \n"
120  : "=&r" (dma_addr), "=&r" (status) );
121 }
122 
123 static void DmaReset(void)
124 {
125  unsigned dma_addr;
126  unsigned temp, temp2;
127 
128  // This appears to have been based on code from Sony that initializes DMA channels 0-9, in bulk.
129  asm volatile (" .set push \n"
130  " .set noreorder \n"
131  " lui %0, 0x1001 \n"
132  " sw $0, -0x5f80(%0) \n" // D2_SADR = 0. Documented to not exist, but is done.
133  " sw $0, -0x6000(%0) \n" // D2_CHCR = 0
134  " sw $0, -0x5fd0(%0) \n" // D2_TADR = 0
135  " sw $0, -0x5ff0(%0) \n" // D2_MADR = 0
136  " sw $0, -0x5fb0(%0) \n" // D2_ASR1 = 0
137  " sw $0, -0x5fc0(%0) \n" // D2_ASR0 = 0
138  " lui %1, 0 \n"
139  " ori %1, %1, 0xff1f \n"
140  " sw %1, -0x1ff0(%0) \n" // Clear all interrupt status under D_STAT, other than SIF0, SIF1 & SIF2.
141  " lw %1, -0x1ff0(%0) \n"
142  " lui %2, 0xff1f \n"
143  " and %1, %1, %2 \n" // Clear all interrupt masks under D_STAT, other SIF0, SIF1 & SIF2. Writing a 1 reverses the bit.
144  " sw %1, -0x1ff0(%0) \n"
145  " sw $0, -0x2000(%0) \n" // D_CTRL = 0
146  " sw $0, -0x1fe0(%0) \n" // D_PCR = 0
147  " sw $0, -0x1fd0(%0) \n" // D_SQWC = 0
148  " sw $0, -0x1fb0(%0) \n" // D_RBOR = 0
149  " sw $0, -0x1fc0(%0) \n" // D_RBSR = 0
150  " lw %1, -0x2000(%0) \n"
151  " ori %1, %1, 1 \n" // D_CTRL (DMAE 1)
152  " sw %1, -0x2000(%0) \n"
153  " .set pop \n"
154  : "=&r" (dma_addr), "=&r" (temp), "=&r" (temp2) );
155 }
156 
163 static inline void progdma( void *addr, int size)
164 {
165  unsigned dma_addr;
166  unsigned temp;
167 
168  asm volatile (" .set push \n"
169  " .set noreorder \n"
170  " lui %0, 0x1001 \n"
171  " sw %3, -0x5fe0(%0) \n" //D2_QWC
172  " sw %2, -0x5ff0(%0) \n" //D2_MADR
173  " li %1, 0x101 \n" //STR 1, DIR 1
174  " sw %1, -0x6000(%0) \n" //D2_CHCR
175  " .set pop \n"
176  : "=&r" (dma_addr), "=&r" (temp)
177  : "r" (addr), "r" (size) );
178 }
179 
180 void scr_setbgcolor(u32 color)
181 {
182  bgcolor = color;
183 }
184 
185 void init_scr(void)
186 {
187  static struct t_setupscr setupscr __attribute__ (( aligned (16) )) = {
188  { 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)
189  { 27648, 30976 }, { 0x18 }, //XYOFFSET_1 (OFX 1728.0, OFY 1936.0)
190  { 0, 639, 0, 223 }, //SCISSOR_1 (SCAX0 0, SCAX1 639, SCAY0 0, SCAY1 223)
191  { 0x40, 1, 0x1a, 1, 0x46, 0, 0x45, 0x70000, //PRMODECONT (AC PRIM), COLCLAMP (CLAMP 1), DTHE (DTHE 0)
192  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)
193  0x87009400, 5, 0x70000, 0x47 } //XYZ2 (Z 0, Y 2160.0, X 2368.0), TEST_1 (ZTST GREATER, ZTE 1)
194  };
195 
196  X = Y = 0;
197  DmaReset();
198 
199  Init_GS( 1, debug_detect_signal() == 1 ? 3 : 2, 0); // Interlaced, NTSC/PAL and FIELD mode
200 
201  SetVideoMode();
202  Dma02Wait();
203  progdma( &setupscr, 15);
204  Dma02Wait();
205 }
206 
207 extern u8 msx[];
208 
209 void
210 scr_putchar( int x, int y, u32 color, int ch)
211 {
212  static struct t_setupchar setupchar __attribute__((aligned(16))) = {
213  { 0x1000000000000004, 0xE, 0xA000000000000, 0x50 }, //GIFtag (REGS: A+D, NREG 1, FLG PACKED, NLOOP 4), BITBLTBUF (DPSM PSMCT32, DBW 10, DBP 0)
214  { 0 }, 100, 100, { 0x51 }, //TRXPOS (DSAX 100, DSAY 100)
215  { 8, 8 }, //TRXREG (RRW 8, RRH 8)
216  { 0x52, 0, 0x53, 0x800000000008010, 0} //TRXDIR (XDIR Host -> Local), GIFtag (FLG IMAGE, EOP, NLOOP 16)
217  };
218  /* charmap must be aligned to a 16-bye boundary. */
219  static u32 charmap[64] __attribute__((aligned(16)));
220  int i, j, l;
221  u8 *font;
222  u32 pixel;
223 
224  ((struct t_setupchar*)UNCACHED_SEG(&setupchar))->x = x;
225  ((struct t_setupchar*)UNCACHED_SEG(&setupchar))->y = y;
226 
227  progdma(&setupchar, 6);
228 
229  font = &msx[ ch * 8];
230  for (i=l=0; i < 8; i++, l+= 8, font++)
231  {
232  for (j=0; j < 8; j++)
233  {
234  pixel = ((*font & (128 >> j))) ? color : bgcolor;
235  *(u32*)UNCACHED_SEG(&charmap[ l + j]) = pixel;
236  }
237  }
238 
239  Dma02Wait();
240 
241  progdma(charmap, (8*8*4) / 16);
242  Dma02Wait();
243 }
244 
245 static void clear_line( int Y)
246 {
247  int i;
248  for (i=0; i < MX; i++)
249  scr_putchar( i*8 , Y * 8, bgcolor, ' ');
250 }
251 
252 void scr_printf(const char *format, ...)
253 {
254  va_list opt;
255  char buff[2048], c;
256  int i, bufsz, j;
257 
258 
259  va_start(opt, format);
260  bufsz = vsnprintf(buff, sizeof(buff), format, opt);
261 
262  for (i = 0; i < bufsz; i++)
263  {
264  c = buff[i];
265  switch (c)
266  {
267  case '\n':
268  X = 0;
269  Y ++;
270  if (Y == MY)
271  Y = 0;
272  clear_line(Y);
273  break;
274  case '\t':
275  for (j = 0; j < 5; j++) {
276  scr_putchar( X*7 , Y * 8, 0xffffff, ' ');
277  X++;
278  }
279  break;
280  default:
281  scr_putchar( X*7 , Y * 8, 0xffffff, c);
282  X++;
283  if (X == MX)
284  {
285  X = 0;
286  Y++;
287  if (Y == MY)
288  Y = 0;
289  clear_line(Y);
290  }
291  }
292  }
293  scr_putchar( X*7 , Y * 8, 0xffffff, 219);
294  va_end(opt);
295 }
296 
297 void scr_setXY(int x, int y)
298 {
299  if( x<MX && x>=0 ) X=x;
300  if( y<MY && y>=0 ) Y=y;
301 }
302 
303 int scr_getX()
304 {
305  return X;
306 }
307 
308 int scr_getY()
309 {
310  return Y;
311 }
312 
313 void scr_clear()
314 {
315  int y;
316  for(y=0;y<MY;y++)
317  clear_line(y);
318  scr_setXY(0,0);
319 }
void SetGsCrt(s16 interlace, s16 pal_ntsc, s16 field)
#define UNCACHED_SEG(x)
Definition: kernel.h:35
u64 GsPutIMR(u64 imr)
s32 x
Definition: libmouse.c:34
s32 y
Definition: libmouse.c:34
char * GetRomName(char *romname)
static void Init_GS(int interlace, int omode, int ffmd)
Definition: scr_printf.c:55
void init_scr(void)
Definition: scr_printf.c:185
int scr_getX()
Definition: scr_printf.c:303
static short int X
Definition: scr_printf.c:24
static void clear_line(int Y)
Definition: scr_printf.c:245
void scr_setXY(int x, int y)
Definition: scr_printf.c:297
static short int MY
Definition: scr_printf.c:25
static short int Y
Definition: scr_printf.c:24
static void SetVideoMode(void)
Definition: scr_printf.c:65
int scr_getY()
Definition: scr_printf.c:308
static void progdma(void *addr, int size)
Definition: scr_printf.c:163
void scr_setbgcolor(u32 color)
Definition: scr_printf.c:180
void scr_printf(const char *format,...)
Definition: scr_printf.c:252
void scr_clear()
Definition: scr_printf.c:313
void scr_putchar(int x, int y, u32 color, int ch)
Definition: scr_printf.c:210
static short int MX
Definition: scr_printf.c:25
static int debug_detect_signal()
Definition: scr_printf.c:48
static void DmaReset(void)
Definition: scr_printf.c:123
static void Dma02Wait(void)
Definition: scr_printf.c:103
static u32 bgcolor
Definition: scr_printf.c:26
u8 msx[]
Definition: font.c:18
u64 dd1[1]
Definition: scr_printf.c:42
u64 dd0[4]
Definition: scr_printf.c:39
u32 dw0[1]
Definition: scr_printf.c:40
u64 dd2[5]
Definition: scr_printf.c:44
u32 dw1[2]
Definition: scr_printf.c:43
u32 dw0[2]
Definition: scr_printf.c:31
u64 dd1[1]
Definition: scr_printf.c:32
u64 dd0[6]
Definition: scr_printf.c:30
u16 dh[4]
Definition: scr_printf.c:33
u64 dd2[21]
Definition: scr_printf.c:34
unsigned int u32
Definition: tamtypes.h:30
unsigned short u16
Definition: tamtypes.h:24
volatile u64 vu64
Definition: tamtypes.h:39
unsigned char u8
Definition: tamtypes.h:23
unsigned long u64
Definition: tamtypes.h:34