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