sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
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
15
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
26static short int X, Y;
27static const short int MX = 80, MY = 40;
28static u32 bgcolor, fontcolor, cursorcolor;
29static short int cursor;
30
31static u32 defcols[16];
32
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
53static int debug_detect_signal()
54{
55 char romname[14];
56 GetRomName(romname);
57 return ((romname[4] == 'E') ? 1 : 0);
58}
59
60static 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
70static 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
87static inline void Dma02Wait(void)
88{
89 while ((*R_EE_D2_CHCR & 0x100) != 0); // Wait until STR bit of D2_CHCR = 0
90}
91
92static 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
116
117static 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
124void scr_setbgcolor(u32 color)
125{
126 bgcolor = color;
127}
128
129void scr_setfontcolor(u32 color)
130{
131 fontcolor = color;
132}
133
134static 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
147void scr_change_defaultcolor(int index, u32 color) {
148 defcols[index] = color;
149}
150
151void 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
163void scr_setcursorcolor(u32 color)
164{
165 cursorcolor = color;
166}
167
168static 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
178void 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
215extern const u8 msx[];
216
217static 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
227void 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
256void scr_clearchar(int X, int Y)
257{
258 scr_putchar(X * 8, Y * 8, bgcolor, ' ');
259}
260
261void 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
268void 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
276void 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
326void 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
334int scr_getX()
335{
336 return X;
337}
338
339int scr_getY()
340{
341 return Y;
342}
343
344void scr_clear()
345{
346 int y;
347 for (y = 0; y < MY; y++)
348 scr_clearline(y);
349 scr_setXY(0, 0);
350}
351
352void scr_setCursor(int enable)
353{
354 cursor = enable;
355}
#define R_EE_D_CTRL
Definition ee_regs.h:449
#define R_EE_D2_CHCR
Definition ee_regs.h:385
#define R_EE_D2_ASR0
Definition ee_regs.h:393
#define R_EE_GS_DISPLAY2
Definition ee_regs.h:588
#define R_EE_D2_TADR
Definition ee_regs.h:391
#define R_EE_D_RBSR
Definition ee_regs.h:457
#define R_EE_D2_ASR1
Definition ee_regs.h:395
#define R_EE_D_SQWC
Definition ee_regs.h:455
#define R_EE_GS_PMODE
Definition ee_regs.h:568
#define R_EE_GS_CSR
Definition ee_regs.h:598
#define R_EE_D_PCR
Definition ee_regs.h:453
#define R_EE_D_RBOR
Definition ee_regs.h:459
#define R_EE_D_STAT
Definition ee_regs.h:451
#define R_EE_D2_QWC
Definition ee_regs.h:389
#define R_EE_D2_MADR
Definition ee_regs.h:387
#define R_EE_GS_DISPFB2
Definition ee_regs.h:586
char * GetRomName(char *romname)
Definition rom0_info.c:67