filename | test/pvr.c |
changeset | 190:f7653df5e832 |
prev | 185:6755a04c447f |
next | 213:da6b1904f67b |
author | nkeynes |
date | Fri Aug 04 01:38:30 2006 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | Add more tile list limit tests Implement tile list limits in the ta core. Rename TA_TILEEND to TA_LISTEND |
view | annotate | diff | log | raw |
1 /**
2 * $Id: pvr.c,v 1.2 2006-08-02 04:13:15 nkeynes Exp $
3 *
4 * PVR support code
5 *
6 * Copyright (c) 2006 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include "lib.h"
20 #include "pvr.h"
22 #define PVR_BASE 0xA05F8000
23 #define PVR_RESET (PVR_BASE+0x008)
24 #define TA_INIT (PVR_BASE+0x144)
25 #define TA_TILESTART (PVR_BASE+0x124)
26 #define TA_OBJSTART (PVR_BASE+0x128)
27 #define TA_TILEEND (PVR_BASE+0x12C)
28 #define TA_OBJEND (PVR_BASE+0x130)
29 #define TA_TILEPOSN (PVR_BASE+0x134)
30 #define TA_OBJPOSN (PVR_BASE+0x138)
31 #define TA_SIZE (PVR_BASE+0x13C)
32 #define TA_TILECFG (PVR_BASE+0x140)
33 #define TA_PLISTSTART (PVR_BASE+0x164)
36 void ta_dump_regs( FILE *f )
37 {
38 fprintf( stderr, "TA Object start[128]: %08X posn[138]: %08X end[130]: %08X\n",
39 long_read(TA_OBJSTART), long_read(TA_OBJPOSN), long_read(TA_OBJEND) );
40 fprintf( stderr, "TA OPB start[124]: %08X posn[134]: %08X end[12c]: %08X init: %08X\n",
41 long_read(TA_TILESTART), long_read(TA_TILEPOSN), long_read(TA_TILEEND),
42 long_read(TA_PLISTSTART) );
43 fprintf( stderr, "TA Tilesize: %08X config: %08X\n", long_read(TA_SIZE), long_read(TA_TILECFG) );
44 }
47 void ta_init( struct ta_config *config )
48 {
49 long_write( PVR_RESET, 1 );
50 long_write( PVR_RESET, 0 );
52 long_write( TA_SIZE, config->grid_size );
53 long_write( TA_OBJSTART, config->obj_start & 0x00FFFFFF );
54 long_write( TA_OBJEND, config->obj_end & 0x00FFFFFF );
55 long_write( TA_TILESTART, config->tile_start & 0x00FFFFFF );
56 long_write( TA_TILEEND, config->tile_end & 0x00FFFFFF );
57 long_write( TA_PLISTSTART, config->plist_start & 0x00FFFFFF );
58 long_write( TA_TILECFG, config->ta_cfg );
59 long_write( TA_INIT, 0x80000000 );
60 }
62 int pvr_get_objbuf_size( )
63 {
64 return long_read( TA_OBJPOSN ) - long_read( TA_OBJSTART );
65 }
67 int pvr_get_plist_posn( )
68 {
69 unsigned int addr = long_read( TA_TILEPOSN ) << 2;
70 return addr;
71 }
73 void pvr_dump_objbuf( FILE *f )
74 {
75 unsigned int start = long_read( TA_OBJSTART );
76 unsigned int posn = long_read( TA_OBJPOSN );
77 unsigned int end = long_read( TA_OBJEND );
78 char *buf;
79 unsigned int length;
80 if( start < posn ) {
81 buf = (char *)(0xA5000000+start);
82 length = posn-start;
83 } else {
84 buf = (char *)(0xA5000000+end);
85 length = start-posn;
86 }
88 fprintf( f, "Obj buffer: %08X - %08X - %08X\n", start, posn, end );
89 fwrite_dump( f, buf, length );
90 }
92 void pvr_dump_tilebuf( FILE *f )
93 {
94 unsigned int start = long_read( TA_TILESTART );
95 unsigned int posn = long_read( TA_TILEPOSN );
96 unsigned int end = long_read( TA_TILEEND );
97 char *buf;
98 unsigned int length;
99 if( start < posn ) {
100 buf = (char *)(0xA5000000+start);
101 length = posn-start;
102 } else {
103 buf = (char *)(0xA5000000+end);
104 length = start-posn;
105 }
107 fprintf( f, "Tile buffer: %08X - %08X - %08X\n", start, posn, end );
108 fwrite_dump( f, buf, length );
109 }
111 /************** Stolen from TATEST *************/
113 static unsigned int three_d_params[] = {
114 0x80a8, 0x15d1c951, /* M (Unknown magic value) */
115 0x80a0, 0x00000020, /* M */
116 0x8008, 0x00000000, /* TA out of reset */
117 0x8048, 0x00000009, /* alpha config */
118 0x8068, 0x02800000, /* pixel clipping x */
119 0x806c, 0x01e00000, /* pixel clipping y */
120 0x8110, 0x00093f39, /* M */
121 0x8098, 0x00800408, /* M */
122 0x804c, 0x000000a0, /* display align (640*2)/8 */
123 0x8078, 0x3f800000, /* polygon culling (1.0f) */
124 0x8084, 0x00000000, /* M */
125 0x8030, 0x00000101, /* M */
126 0x80b0, 0x007f7f7f, /* Fog table color */
127 0x80b4, 0x007f7f7f, /* Fog vertex color */
128 0x80c0, 0x00000000, /* color clamp min */
129 0x80bc, 0xffffffff, /* color clamp max */
130 0x8080, 0x00000007, /* M */
131 0x8074, 0x00000001, /* cheap shadow */
132 0x807c, 0x0027df77, /* M */
133 0x8008, 0x00000001, /* TA reset */
134 0x8008, 0x00000000, /* TA out of reset */
135 0x80e4, 0x00000000, /* stride width */
136 0x6884, 0x00000000, /* Disable all interrupt events */
137 0x6930, 0x00000000,
138 0x6938, 0x00000000,
139 0x6900, 0xffffffff, /* Clear all pending int events */
140 0x6908, 0xffffffff,
141 0x6930, 0x002807ec, /* Re-enable some events */
142 0x6938, 0x0000000e,
143 0x80b8, 0x0000ff07, /* fog density */
144 0x80b4, 0x007f7f7f, /* fog vertex color */
145 0x80b0, 0x007f7f7f, /* fog table color */
146 0x8108, 0x00000003 /* 32bit palette */
147 };
149 static unsigned int scrn_params[] = {
150 0x80e8, 0x00160000, /* screen control */
151 0x8044, 0x00800000, /* pixel mode (vb+0x11) */
152 0x805c, 0x00000000, /* Size modulo and display lines (vb+0x17) */
153 0x80d0, 0x00000100, /* interlace flags */
154 0x80d8, 0x020c0359, /* M */
155 0x80cc, 0x001501fe, /* M */
156 0x80d4, 0x007e0345, /* horizontal border */
157 0x80dc, 0x00240204, /* vertical position */
158 0x80e0, 0x07d6c63f, /* sync control */
159 0x80ec, 0x000000a4, /* horizontal position */
160 0x80f0, 0x00120012, /* vertical border */
161 0x80c8, 0x03450000, /* set to same as border H in 80d4 */
162 0x8068, 0x027f0000, /* (X resolution - 1) << 16 */
163 0x806c, 0x01df0000, /* (Y resolution - 1) << 16 */
164 0x804c, 0x000000a0, /* display align */
165 0x8118, 0x00008040, /* M */
166 0x80f4, 0x00000401, /* anti-aliasing */
167 0x8048, 0x00000009, /* alpha config */
168 0x7814, 0x00000000, /* More interrupt control stuff (so it seems)*/
169 0x7834, 0x00000000,
170 0x7854, 0x00000000,
171 0x7874, 0x00000000,
172 0x78bc, 0x4659404f,
173 0x8040, 0x00000000 /* border color */
174 };
176 static void set_regs(unsigned int *values, int cnt)
177 {
178 volatile unsigned char *regs = (volatile unsigned char *)(void *)0xa05f0000;
179 unsigned int r, v;
181 while(cnt--) {
182 r = *values++;
183 v = *values++;
184 *(volatile unsigned int *)(regs+r) = v;
185 }
186 }
188 int pvr_check_cable()
189 {
190 volatile unsigned int *porta = (unsigned int *)0xff80002c;
192 /* PORT8 and PORT9 is input */
193 *porta = (*porta & ~0xf0000) | 0xa0000;
195 /* Return PORT8 and PORT9 */
196 return ((*(volatile unsigned short *)(porta+1))>>8)&3;
197 }
198 void pvr_init_video(int cabletype, int mode, int res)
199 {
200 volatile unsigned int *videobase=(volatile unsigned int *)(void*)0xa05f8000;
201 static int bppshifttab[]= { 1,1,0,2 };
202 int shift, lines, modulo, words_per_line, vpos;
203 int laceoffset=0, voffset=0;
204 unsigned int videoflags, attribs;
205 unsigned int hvcounter = (res<2? 0x01060359 : 0x020c0359);
207 mode &= 3;
208 shift = bppshifttab[mode];
210 videobase[8/4]=0;
211 videobase[0x40/4]=0;
213 /* Select pixel clock and colour mode */
214 mode = (mode<<2)|1;
215 lines = 240;
216 if(!(cabletype&2)) {
218 /* VGA mode */
220 if(res < 2)
221 mode |= 2; /* doublescan */
223 hvcounter = 0x020c0359;
225 lines <<= 1;
226 mode |= 0x800000; /* fast pixel clock */
227 }
228 videobase[0x44/4]=mode;
230 /* Set video base address. Short fields will be offset by
231 640 pixels, regardless of horizontal resolution. */
232 videobase[0x50/4]=0;
233 videobase[0x54/4]=640<<shift;
235 /* Set screen size, modulo, and interlace flag */
236 videoflags = 1<<8;
237 if(res==0)
238 words_per_line=(320/4)<<shift;
239 else
240 words_per_line=(640/4)<<shift;
241 modulo = 1;
243 if(!(cabletype&2))
244 {
245 if(res==0)
246 /* VGA lores -> skip 320 pixels to keep modulo at 640 pixels */
247 modulo += words_per_line;
248 } else {
249 if(res!=1)
250 /* NTSC lores -> skip 320 pixels to keep modulo at 640 pixels */
251 /* _or_ NTSC hires -> skip every other line due to interlace */
252 modulo += words_per_line;
254 if(res==2)
255 /* interlace mode */
256 videoflags |= 1<<4;
258 /* enable NTSC */
259 videoflags |= 1<<6;
260 }
262 /* Write screen size and modulo */
263 videobase[0x5c/4]=(((modulo<<10)+lines-1)<<10)+words_per_line-1;
265 /* Enable video (lace, NTSC) */
266 videobase[0xd0/4]=videoflags;
268 /* Screen and border position */
270 if(!(cabletype&2))
271 /* VGA */
272 voffset += 36;
273 else
274 voffset += 18;
276 vpos=(voffset<<16)|(voffset+laceoffset);
278 videobase[0xf0/4]=vpos; /* V start */
279 videobase[0xdc/4]=vpos+lines; /* start and end border */
280 videobase[0xec/4]=0xa4; /* Horizontal pos */
281 videobase[0xd8/4]=hvcounter; /* HV counter */
282 videobase[0xd4/4]=0x007e0345; /* Horizontal border */
284 /* Select horizontal pixel doubling for lowres */
285 if(res==0)
286 attribs=((22<<8)+1)<<8;
287 else
288 attribs=22<<16;
289 videobase[0xe8/4]=attribs;
291 /* Set up vertical blank event */
292 vpos = 260;
293 if(!(cabletype&2))
294 vpos = 510;
295 videobase[0xcc/4]=(0x21<<16)|vpos;
297 /* Select RGB/CVBS */
298 if(cabletype&1)
299 mode = 3;
300 else
301 mode = 0;
302 *(volatile unsigned int *)(void*)0xa0702c00 = mode << 8;
304 return;
305 }
307 void pvr_init()
308 {
309 volatile unsigned int *vbl = (volatile unsigned int *)(void *)0xa05f810c;
311 set_regs(three_d_params, sizeof(three_d_params)/sizeof(three_d_params[0])/2);
312 while (!(*vbl & 0x01ff));
313 while (*vbl & 0x01ff);
314 set_regs(scrn_params, sizeof(scrn_params)/sizeof(scrn_params[0])/2);
315 pvr_init_video(pvr_check_cable(), 1, 2);
316 }
.