Search
lxdream.org :: lxdream/test/pvr.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/pvr.c
changeset 185:6755a04c447f
next190:f7653df5e832
author nkeynes
date Tue Jul 11 01:35:27 2006 +0000 (14 years ago)
permissions -rw-r--r--
last change First commit of system test framework. 3 initial test cases (incomplete):
testide, testmath, and testta
view annotate diff log raw
     1 /**
     2  * $Id: pvr.c,v 1.1 2006-07-11 01:35:23 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)
    37 void ta_init( unsigned int hres, unsigned int vres,
    38 	      unsigned int polybuf, unsigned int polybuflen,
    39 	      unsigned int tilebuf, unsigned int tilebuflen )
    40 {
    41     unsigned int hsegs = ((hres+31) / 32)-1;
    42     unsigned int vsegs = ((vres+31) / 32)-1;
    43     unsigned int size = (vsegs<<16)|hsegs;
    45     fprintf(stderr, "Setting tilemap: %08X\n", size);
    47     long_write( PVR_RESET, 1 );
    48     long_write( PVR_RESET, 0 );
    50     long_write( TA_SIZE, size );
    51     long_write( TA_OBJSTART, polybuf & 0x00FFFFFF );
    52     long_write( TA_OBJEND, (polybuf + polybuflen) & 0x00FFFFFF );
    53     long_write( TA_TILESTART, (tilebuf + tilebuflen) & 0x00FFFFFF );
    54     long_write( TA_TILEEND, tilebuf & 0x00FFFFFF );
    55     long_write( TA_PLISTSTART, (tilebuf + tilebuflen) & 0x00FFFFFF );
    56     long_write( TA_TILECFG, 0x00100002 );
    57     long_write( TA_INIT, 0x80000000 );
    58 }
    60 void ta_dump_regs( FILE *f )
    61 {
    62     fprintf( stderr, "TA Object start[128]: %08X posn[138]: %08X end[130]: %08X\n",
    63 	     long_read(TA_OBJSTART), long_read(TA_OBJPOSN), long_read(TA_OBJEND) );
    64     fprintf( stderr, "TA OPB start[124]: %08X posn[134]: %08X end[12c]: %08X init: %08X\n",
    65 	     long_read(TA_TILESTART), long_read(TA_TILEPOSN), long_read(TA_TILEEND),
    66 	     long_read(TA_PLISTSTART) );
    67     fprintf( stderr, "TA Tilesize: %08X  config: %08X\n",  long_read(TA_SIZE), long_read(TA_TILECFG) );
    68 }
    70 int pvr_get_objbuf_size( )
    71 {
    72     return long_read( TA_OBJPOSN ) - long_read( TA_OBJSTART );
    73 }
    75 void pvr_dump_objbuf( FILE *f )
    76 {
    77     unsigned int start = long_read( TA_OBJSTART );
    78     unsigned int posn = long_read( TA_OBJPOSN );
    79     unsigned int end = long_read( TA_OBJEND );
    80     char *buf;
    81     unsigned int length;
    82     if( start < posn ) {
    83 	buf = (char *)(0xA5000000+start);
    84 	length = posn-start;
    85     } else {
    86 	buf = (char *)(0xA5000000+end);
    87 	length = start-posn;
    88     }
    90     fprintf( f, "Obj buffer: %08X - %08X - %08X\n", start, posn, end );
    91     fwrite_dump( f, buf, length );
    92 }
    94 void pvr_dump_tilebuf( FILE *f )
    95 {
    96     unsigned int start = long_read( TA_TILESTART );
    97     unsigned int posn = long_read( TA_TILEPOSN );
    98     unsigned int end = long_read( TA_TILEEND );
    99     char *buf;
   100     unsigned int length;
   101     if( start < posn ) {
   102 	buf = (char *)(0xA5000000+start);
   103 	length = posn-start;
   104     } else {
   105 	buf = (char *)(0xA5000000+end);
   106 	length = start-posn;
   107     }
   109     fprintf( f, "Tile buffer: %08X - %08X - %08X\n", start, posn, end );
   110     fwrite_dump( f, buf, length );
   111 }
   113 /************** Stolen from TATEST *************/
   115 static unsigned int three_d_params[] = {
   116         0x80a8, 0x15d1c951,     /* M (Unknown magic value) */
   117         0x80a0, 0x00000020,     /* M */
   118         0x8008, 0x00000000,     /* TA out of reset */
   119         0x8048, 0x00000009,     /* alpha config */
   120         0x8068, 0x02800000,     /* pixel clipping x */
   121         0x806c, 0x01e00000,     /* pixel clipping y */
   122         0x8110, 0x00093f39,     /* M */
   123         0x8098, 0x00800408,     /* M */
   124         0x804c, 0x000000a0,     /* display align (640*2)/8 */
   125         0x8078, 0x3f800000,     /* polygon culling (1.0f) */
   126         0x8084, 0x00000000,     /* M */
   127         0x8030, 0x00000101,     /* M */
   128         0x80b0, 0x007f7f7f,     /* Fog table color */
   129         0x80b4, 0x007f7f7f,     /* Fog vertex color */
   130         0x80c0, 0x00000000,     /* color clamp min */
   131         0x80bc, 0xffffffff,     /* color clamp max */
   132         0x8080, 0x00000007,     /* M */
   133         0x8074, 0x00000001,     /* cheap shadow */
   134         0x807c, 0x0027df77,     /* M */
   135         0x8008, 0x00000001,     /* TA reset */
   136         0x8008, 0x00000000,     /* TA out of reset */
   137         0x80e4, 0x00000000,     /* stride width */
   138         0x6884, 0x00000000,     /* Disable all interrupt events */
   139         0x6930, 0x00000000,
   140         0x6938, 0x00000000,
   141         0x6900, 0xffffffff,     /* Clear all pending int events */
   142         0x6908, 0xffffffff,
   143         0x6930, 0x002807ec,     /* Re-enable some events */
   144         0x6938, 0x0000000e,
   145         0x80b8, 0x0000ff07,     /* fog density */
   146         0x80b4, 0x007f7f7f,     /* fog vertex color */
   147         0x80b0, 0x007f7f7f,     /* fog table color */
   148         0x8108, 0x00000003      /* 32bit palette  */
   149 };
   151 static unsigned int scrn_params[] = {
   152         0x80e8, 0x00160000,     /* screen control */
   153         0x8044, 0x00800000,     /* pixel mode (vb+0x11) */
   154         0x805c, 0x00000000,     /* Size modulo and display lines (vb+0x17) */
   155         0x80d0, 0x00000100,     /* interlace flags */
   156         0x80d8, 0x020c0359,     /* M */
   157         0x80cc, 0x001501fe,     /* M */
   158         0x80d4, 0x007e0345,     /* horizontal border */
   159         0x80dc, 0x00240204,     /* vertical position */
   160         0x80e0, 0x07d6c63f,     /* sync control */
   161         0x80ec, 0x000000a4,     /* horizontal position */
   162         0x80f0, 0x00120012,     /* vertical border */
   163         0x80c8, 0x03450000,     /* set to same as border H in 80d4 */
   164         0x8068, 0x027f0000,     /* (X resolution - 1) << 16 */
   165         0x806c, 0x01df0000,     /* (Y resolution - 1) << 16 */
   166         0x804c, 0x000000a0,     /* display align */
   167         0x8118, 0x00008040,     /* M */
   168         0x80f4, 0x00000401,     /* anti-aliasing */
   169         0x8048, 0x00000009,     /* alpha config */
   170         0x7814, 0x00000000,     /* More interrupt control stuff (so it seems)*/
   171         0x7834, 0x00000000,
   172         0x7854, 0x00000000,
   173         0x7874, 0x00000000,
   174         0x78bc, 0x4659404f,
   175         0x8040, 0x00000000      /* border color */
   176 };
   178 static void set_regs(unsigned int *values, int cnt)
   179 {
   180   volatile unsigned char *regs = (volatile unsigned char *)(void *)0xa05f0000;
   181   unsigned int r, v;
   183   while(cnt--) {
   184     r = *values++;
   185     v = *values++;
   186     *(volatile unsigned int *)(regs+r) = v;
   187   }
   188 }
   190 int pvr_check_cable()
   191 {
   192   volatile unsigned int *porta = (unsigned int *)0xff80002c;
   194   /* PORT8 and PORT9 is input */
   195   *porta = (*porta & ~0xf0000) | 0xa0000;
   197   /* Return PORT8 and PORT9 */
   198   return ((*(volatile unsigned short *)(porta+1))>>8)&3;
   199 }
   200 void pvr_init_video(int cabletype, int mode, int res)
   201 {
   202   volatile unsigned int *videobase=(volatile unsigned int *)(void*)0xa05f8000;
   203   static int bppshifttab[]= { 1,1,0,2 };
   204   int shift, lines, modulo, words_per_line, vpos;
   205   int laceoffset=0, voffset=0;
   206   unsigned int videoflags, attribs;
   207   unsigned int hvcounter = (res<2? 0x01060359 : 0x020c0359);
   209   mode &= 3;
   210   shift = bppshifttab[mode];
   212   videobase[8/4]=0;
   213   videobase[0x40/4]=0;
   215   /* Select pixel clock and colour mode */
   216   mode = (mode<<2)|1;
   217   lines = 240;
   218   if(!(cabletype&2)) {
   220     /* VGA mode */
   222     if(res < 2)
   223       mode |= 2; /* doublescan */
   225     hvcounter = 0x020c0359;
   227     lines <<= 1;
   228     mode |= 0x800000; /* fast pixel clock */
   229   }
   230   videobase[0x44/4]=mode;
   232   /* Set video base address.  Short fields will be offset by
   233      640 pixels, regardless of horizontal resolution.       */
   234   videobase[0x50/4]=0;
   235   videobase[0x54/4]=640<<shift;
   237   /* Set screen size, modulo, and interlace flag */
   238   videoflags = 1<<8;
   239   if(res==0)
   240     words_per_line=(320/4)<<shift;
   241   else
   242     words_per_line=(640/4)<<shift;
   243   modulo = 1;
   245   if(!(cabletype&2))
   246   {
   247     if(res==0)
   248       /* VGA lores -> skip 320 pixels to keep modulo at 640 pixels */
   249       modulo += words_per_line;
   250   } else {
   251     if(res!=1)
   252       /* NTSC lores -> skip 320 pixels to keep modulo at 640 pixels */
   253       /* _or_ NTSC hires -> skip every other line due to interlace  */
   254       modulo += words_per_line;
   256     if(res==2)
   257       /* interlace mode */
   258       videoflags |= 1<<4;
   260     /* enable NTSC */
   261     videoflags |= 1<<6;
   262   }
   264   /* Write screen size and modulo */
   265   videobase[0x5c/4]=(((modulo<<10)+lines-1)<<10)+words_per_line-1;
   267   /* Enable video (lace, NTSC) */
   268   videobase[0xd0/4]=videoflags;
   270   /* Screen and border position */
   272   if(!(cabletype&2))
   273     /* VGA */
   274     voffset += 36;
   275   else
   276     voffset += 18;
   278   vpos=(voffset<<16)|(voffset+laceoffset);
   280   videobase[0xf0/4]=vpos;       /* V start              */
   281   videobase[0xdc/4]=vpos+lines; /* start and end border */
   282   videobase[0xec/4]=0xa4;       /* Horizontal pos       */
   283   videobase[0xd8/4]=hvcounter;  /* HV counter           */
   284   videobase[0xd4/4]=0x007e0345; /* Horizontal border    */
   286   /* Select horizontal pixel doubling for lowres */
   287   if(res==0)
   288     attribs=((22<<8)+1)<<8;
   289   else
   290     attribs=22<<16;
   291   videobase[0xe8/4]=attribs;
   293   /* Set up vertical blank event */
   294   vpos = 260;
   295   if(!(cabletype&2))
   296     vpos = 510;
   297   videobase[0xcc/4]=(0x21<<16)|vpos;
   299   /* Select RGB/CVBS */
   300   if(cabletype&1)
   301     mode = 3;
   302   else
   303     mode = 0;
   304   *(volatile unsigned int *)(void*)0xa0702c00 = mode << 8;
   306   return;
   307 }
   309 void pvr_init()
   310 {
   311   volatile unsigned int *vbl = (volatile unsigned int *)(void *)0xa05f810c;
   313   set_regs(three_d_params, sizeof(three_d_params)/sizeof(three_d_params[0])/2);
   314   while (!(*vbl & 0x01ff));
   315   while (*vbl & 0x01ff);
   316   set_regs(scrn_params, sizeof(scrn_params)/sizeof(scrn_params[0])/2);
   317   pvr_init_video(pvr_check_cable(), 1, 2);
   318 }
.