rdramgclr.c 6.61 KB
/*
 * rdramgclr - clear the framebuffer to set value
 * 
 * defaults to clearing the cfb to (0, 200, 200, 1) (Rob's favorite color)
 * and the z buffer to max value
 * 
 * arguments:
 *     -c color - color to clear to
 *     -z zvalue - z value to clear to
 *     -f framebuf_addr - override cfb address from .rdram file (verifinfo struct)
 *     -d zbuf_addr - override bif address from .rdram file (verifinfo struct)
 * 
 * 
 * XXX - only knows about 16 bit color buffer now, get format from .rdram file
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <mbi.h>
#include <verify.h>

#include "rdram.h"

#define HEIGHT 240
#define WIDTH  320

#define DEFAULT_CFB_ADDR    0x000b0000
#define DEFAULT_CFB_VALUE   0x00c8c807	    /* (0,200,200,1) */
#define DEFAULT_ZB_ADDR     0x00100000
#define DEFAULT_ZB_VALUE    0x3ffff0

static unsigned char *mainaddr, *hiddenaddr;
static long mainsize, hiddensize;

static int height = HEIGHT;
static int width = WIDTH;

static unsigned char hiddenmask[] = {
    ~0xc0, 
    ~0x30,
    ~0x0c, 
    ~0x03 
};

static int hiddenshift[] = {
    6,
    4, 
    2, 
    0
};

char *UsageStr = "Usage: rdramgclr <-c color> <-z zvalue> <-f framebuf_addr> <-d depthbuf_addr> file\n";


extern unsigned int quiet_mode;

/*
 * writecolor
 *   r, g, b, a - all 8 bits
 *     (a is really cvg and only 3 bits)
 *   format - G_IM_FMT_RGBA, G_IM_FMT_CI, G_IM_FMT_IA
 *   size - G_IM_SIZ_32b, G_IM_SIZ_16b, G_IM_SIZ_8b
 *   base - base address of color buffer (a byte address)
 *   offset - pixel offset into color buffer (ie units is # of pixels)
 * 
 * XXX assert that base is on x word boundary
 */
static void
writecolor(unsigned char r, unsigned char g, unsigned char b, unsigned char a,
unsigned char format, unsigned char size,
unsigned long base, unsigned long offset)
{
    unsigned char *addr;
    unsigned char hidden;
    
    
    switch (format) {
    case G_IM_FMT_RGBA:
	switch (size) {
	case G_IM_SIZ_32b:
	    addr = mainaddr + base + (offset*4);
	    *addr++ = r;
	    *addr++ = g;
	    *addr++ = b;
	    *addr = a << 5;
	    break;
	    
	case G_IM_SIZ_16b:
	    addr = mainaddr + base + (offset*2);
	    *addr++ = (r & 0xf8) | (g >> 5);
	    *addr = ( (g & 0x18) << 3) | ((b & 0xf8) >> 2) | ((a & 0x4) >> 2);
	    /* now for the hidden part */
	    addr = hiddenaddr + (base / HIDDEN_FACTOR) + (offset / 4);
	    hidden = *addr;
	    hidden &= hiddenmask[offset % 4];
	    hidden |= ((a & 0x3) << hiddenshift[offset % 4]);
	    *addr = hidden;
	    break;
	
	default:
	    fprintf(stderr, "memspan write: RGB size of %d not supported\n", format);
	    break;
	}
	break;
	
    default:
	fprintf(stderr, "memspan write: format not supported (%d)\n", format);
	break;
    }
}

/*
 * writez
 *   z - 18 bits of info
 *   base - base address of z buffer (a byte address)
 *   offset - pixel offset into z buffer (ie units is # of pixels)
 * 
 * XXX check order & endian of hidden bits
 */
static void
writez(unsigned long z, unsigned long base, unsigned long offset)
{
    unsigned char *addr;
    unsigned char c;
    
    addr = mainaddr + base + (offset*2);
    *addr++ = (z >> 10) & 0xff;
    *addr++ = (z >> 2) & 0xff;
    /* now for hidden part */
    addr = hiddenaddr + (base / HIDDEN_FACTOR) + (offset / 4);
    c = *addr;
    c &= hiddenmask[offset % 4];
    c |= ((z & 0x3) << hiddenshift[offset % 4]);
    *addr = c;
}


main(int argc, char *argv[])
{
    int i, j, c;
    unsigned char r, g, b, a;
    unsigned long color;
    unsigned long z;
    unsigned long cfbaddr, zaddr;
    int usezaddr, usecfbaddr;
    VerifyInfo		*vp;
    extern char *optarg;
    extern int optind;
    int rdram_size = 0;
    
    color = DEFAULT_CFB_VALUE;
    z = DEFAULT_ZB_VALUE;
    usezaddr = usecfbaddr = FALSE;
    
    while ((c = getopt(argc, argv, "c:z:f:d:m:qh")) != EOF) {
	switch (c) {
	case 'c':
	    color = strtol(optarg, NULL, 0);
	    break;
	
	case 'z':
	    z = strtol(optarg, NULL, 0);
	    break;
	
	case 'f':
	    cfbaddr = strtol(optarg, NULL, 0);
	    usecfbaddr = TRUE;
	    break;
	
	case 'd':
	    zaddr = strtol(optarg, NULL, 0);
	    usezaddr = TRUE;
	    break;
	
	case 'q':
	    quiet_mode = 1;
	    break;
	
	case 'h':
	    printf(UsageStr);
	    exit(0);
	    break;
       
        case 'm':
            rdram_size = strtoul(optarg, NULL, 0);
            if (rdram_size > 4)
                 rdram_size = 0; 
            break;
	
	default:
	    break;
	}
    }
    
    if (optind == argc) {
	printf(UsageStr);
	exit(1);
    }

    if (rdram_size != 0) {
         /* Let's expand your rdram to your specified number */
         
         struct stat statbuf;
         int fd;
         char filename[1024];

         sprintf(filename, "%s.rdram", argv[optind]);
         if (stat(filename, &statbuf) == -1) {
            fprintf(stderr, "Could not stat <%s>\n", filename);
            return 0;
         }

         if (statbuf.st_size < (TOTAL_MEMORY_SIZE*rdram_size)) {
            if ((fd = open(filename, (O_RDWR | O_CREAT), 0644)) == -1) {
                fprintf(stderr, "Could not open <%s>\n", filename);
                return 0;
             }

             filename[0]='\0'; 
             lseek(fd, TOTAL_MEMORY_SIZE*rdram_size-1, SEEK_SET);
             write(fd, filename, 1);
             close(fd);
         }
    }

    if (!rdraminit(argv[optind], RDRAM_RW, RDRAM_NEEDHIDDEN, rdram_size,
		&mainaddr, &mainsize, &hiddenaddr, &hiddensize))
	exit(1);

    vp = (VerifyInfo *)(mainaddr + VERIFY_INFO_PHYSADDR);
    
    if (!usecfbaddr)
	cfbaddr = ntohl(vp->frameBuffer0Addr);
    else 
	vp->frameBuffer0Addr = htonl(cfbaddr);
		
    if (!usezaddr)
	zaddr = ntohl(vp->zBufferAddr);
    else 
	vp->zBufferAddr = htonl(zaddr);
	
/* for old files */
if (ntohl(vp->frameBufferFormat) == 0 &&  ntohl(vp->frameBufferSize == 0)) {
    vp->frameBufferFormat = htonl(G_IM_FMT_RGBA);
    vp->frameBufferSize = htonl(G_IM_SIZ_16b);
}

    width = ntohs(vp->width);
    height = ntohs(vp->height);
/*
*/

    if (!quiet_mode)
    {
      fprintf(stderr, "cfbaddr 0x%x,  zaddr 0x%x\n", cfbaddr, zaddr);
      fprintf(stderr, "clear color 0x%x,  clear z 0x%x\n", color, z);
      fprintf(stderr, "format %d, size %d\n", vp->frameBufferFormat, vp->frameBufferSize);
      fprintf(stderr, "width %d, height %d\n", width, height);
    }
    
    r = (color >> 24) & 0xff;
    g = (color >> 16) & 0xff;
    b = (color >>  8) & 0xff;
    a = (color) & 0xff;
    
    for (i = 0; i < height; i++) {
	for (j = 0; j < width; j++) {
	    writecolor(r, g, b, a, ntohl(vp->frameBufferFormat), 
                ntohl(vp->frameBufferSize),
		cfbaddr, (i * width) + j);
		
	    writez(z, zaddr, (i * width) + j);
	}
    }
    
}