/* Shut down the PVR chip from ready status, leaving it in 2D mode as it
   was before the init. */
int pvr_shutdown() {
    if(!pvr_state.valid)
        return -1;

    /* Set us invalid */
    pvr_state.valid = 0;

    /* Stop anything that might be going on */
    PVR_SET(PVR_RESET, PVR_RESET_ALL);
    PVR_SET(PVR_RESET, PVR_RESET_NONE);

    /* Unhook any int handlers */
    vblank_handler_remove(pvr_state.vbl_handle);
    asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEDONE, NULL);
    asic_evt_disable(ASIC_EVT_PVR_OPAQUEDONE, ASIC_IRQ_DEFAULT);
    asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEMODDONE, NULL);
    asic_evt_disable(ASIC_EVT_PVR_OPAQUEMODDONE, ASIC_IRQ_DEFAULT);
    asic_evt_set_handler(ASIC_EVT_PVR_TRANSDONE, NULL);
    asic_evt_disable(ASIC_EVT_PVR_TRANSDONE, ASIC_IRQ_DEFAULT);
    asic_evt_set_handler(ASIC_EVT_PVR_TRANSMODDONE, NULL);
    asic_evt_disable(ASIC_EVT_PVR_TRANSMODDONE, ASIC_IRQ_DEFAULT);
    asic_evt_set_handler(ASIC_EVT_PVR_PTDONE, NULL);
    asic_evt_disable(ASIC_EVT_PVR_PTDONE, ASIC_IRQ_DEFAULT);
    asic_evt_set_handler(ASIC_EVT_PVR_RENDERDONE, NULL);
    asic_evt_disable(ASIC_EVT_PVR_RENDERDONE, ASIC_IRQ_DEFAULT);

    /* Shut down PVR DMA */
    pvr_dma_shutdown();

    /* Invalidate our memory pool */
    pvr_mem_reset();

    /* Destroy the semaphore */
    sem_destroy((semaphore_t *)&pvr_state.ready_sem);
    mutex_destroy((mutex_t *)&pvr_state.dma_lock);

    /* Clear video memory */
    vid_empty();

    /* Reset the frame buffer offset */
    vid_waitvbl();
    vid_set_start(0);

    /* Return success */
    return 0;
}
Example #2
0
int main(int argc, char *argv[]) {

    if(argc < 2) {
        ds_printf("Usage: %s option args...\n\n"
                  "Options: \n"
                  " -m, --mode      - Set video mode\n"
                  " -l, --list      - Show list of video modes\n"
                  " -c, --clear     - Clear the display with color\n"
                  " -e, --empty     - Clear VRAM\n"
                  " -o, --border    - Set video border color\n\n"
                  "Arguments: \n"
                  " -d, --display   - Display mode from list\n"
                  " -p, --pixel     - Pixel mode from list\n"
                  " -r, --red       - Red color for clear screen\n"
                  " -g, --green     - green color for clear screen\n"
                  " -b, --blue      - Blue color for clear screen\n\n"
                  "Example: %s -m -d 1 -p 1\n", argv[0], argv[0]);
        return CMD_NO_ARG;
    }

    int mode = 0, list = 0, clear = 0, empty = 0, border = 0, display = 0, pixel = PM_RGB565;
    int r = 0, g = 0, b = 0;

    struct cfg_option options[] = {
        {"mode",   'm', NULL, CFG_BOOL, (void *) &mode,   0},
        {"clear",  'c', NULL, CFG_BOOL, (void *) &clear,  0},
        {"empty",  'e', NULL, CFG_BOOL, (void *) &empty,  0},
        {"border", 'o', NULL, CFG_BOOL, (void *) &border, 0},
        {"list",   'l', NULL, CFG_BOOL, (void *) &list,   0},
        {"pixel",  'p', NULL, CFG_INT,  (void *) &pixel,  0},
        {"display",'d', NULL, CFG_INT,  (void *) &display,0},
        {"red",    'r', NULL, CFG_INT,  (void *) &r,      0},
        {"green",  'g', NULL, CFG_INT,  (void *) &g,      0},
        {"blue",   'b', NULL, CFG_INT,  (void *) &b,      0},
        CFG_END_OF_LIST
    };

    CMD_DEFAULT_ARGS_PARSER(options);

    if(mode) {
        if(pixel == PM_RGB565) {
            SetVideoMode(display);
        } else {
            vid_set_mode(display, pixel);
        }
        return CMD_OK;
    }

    if(clear) {
        vid_clear(r, g, b);
        return CMD_OK;
    }

    if(empty) {
        vid_empty();
        return CMD_OK;
    }

    if(border) {
        vid_border_color(r, g, b);
        return CMD_OK;
    }

    if(list) {
        ds_printf(	" Pixel modes: \n"
                    "  0 - RGB555 pixel mode (15-bit)\n"
                    "  1 - RGB565 pixel mode (16-bit), default\n"
                    "  3 - RGB888 pixel mode (24-bit)\n\n");

        ds_printf(	" Display modes: \n"
                    "  1  - 320x240 VGA 60Hz \n"
                    "  2  - 320x240 NTSC 60Hz \n"
                    "  3  - 640x480 VGA 60Hz \n"
                    "  4  - 640x480 NTSC Interlaced 60Hz \n"
                    "  5  - 800x608 VGA 60Hz \n"
                    "  6  - 640x480 PAL Interlaced 50Hz \n"
                    "  7  - 256x256 PAL Interlaced 50Hz \n"
                    "  8  - 768x480 NTSC Interlaced 60Hz \n"
                    "  9  - 768x576 PAL Interlaced 50Hz \n"
                    "  10 - 768x480 PAL Interlaced 50Hz \n");
        ds_printf(	"  11 - 320x240 PAL 50Hz \n"
                    "  12 - 320x240 VGA 60Hz, 4FBs \n"
                    "  13 - 320x240 NTSC 60Hz, 4FBs \n"
                    "  14 - 640x480 VGA 60Hz, 4FBs \n"
                    "  15 - 640x480 NTSC IL 60Hz, 4FBs \n"
                    "  16 - 800x608 VGA 60Hz, 4FBs \n"
                    "  17 - 640x480 PAL IL 50Hz, 4FBs \n"
                    "  18 - 256x256 PAL IL 50Hz, 4FBs \n"
                    "  19 - 768x480 NTSC IL 60Hz, 4FBs \n"
                    "  20 - 768x576 PAL IL 50Hz, 4FBs \n"
                    "  21 - 768x480 PAL IL 50Hz, 4FBs \n"
                    "  22 - 320x240 PAL 50Hz, 4FBs \n\n");
        return CMD_OK;
    }

    ds_printf("DS_ERROR: There is no option.\n");
    return CMD_NO_ARG;
}
Example #3
0
/* Initialize the PVR chip to ready status, enabling the specified lists
   and using the specified parameters; note that bins and vertex buffers
   come from the texture memory pool! Expects that a 2D mode was 
   initialized already using the vid_* API. */
int pvr_init(pvr_init_params_t *params) {
	/* If we're already initialized, fail */
	if (pvr_state.valid == 1) {
		dbglog(DBG_WARNING, "pvr: pvr_init called twice!\n");
		return -1;
	}

	/* Make sure we got valid parameters */
	assert(params != NULL);

	/* Make sure that a video mode has been initialized */
	assert(vid_mode != NULL);
	assert(vid_mode->width != 0 && vid_mode->height != 0);

	/* Check for compatibility with 3D stuff */
	if ((vid_mode->width % 32) != 0) {
		dbglog(DBG_WARNING, "pvr: mode %dx%d isn't usable for 3D (width not multiples of 32)\n",
			vid_mode->width, vid_mode->height);
		return -1;
	}

	/* Clear out video memory */
	vid_empty();

	/* Reset all PVR systems (in case it's still doing something) */
	PVR_SET(PVR_RESET, PVR_RESET_ALL);
	PVR_SET(PVR_RESET, PVR_RESET_NONE);

	/* Start off with a nice empty structure */
	memset((void *)&pvr_state, 0, sizeof(pvr_state));

	// Enable DMA if the user wants that.
	pvr_state.dma_mode = params->dma_enabled;

	/* Everything's clear, do the initial buffer pointer setup */
	pvr_allocate_buffers(params);

	// Initialize tile matrices
	pvr_init_tile_matrices();

	// Setup all pipeline targets. Yes, this is redundant. :) I just
	// like to have it explicit.
	pvr_state.ram_target = 0;
	pvr_state.ta_target = 0;
	pvr_state.view_target = 0;
	
	pvr_state.list_reg_open = -1;

	// Sync all the hardware registers with our pipeline state.
	pvr_sync_view();
	pvr_sync_reg_buffer();

	// Clear out our stats
	pvr_state.vbl_count = 0;
	pvr_state.frame_last_time = 0;
	pvr_state.buf_start_time = 0;
	pvr_state.reg_start_time = 0;
	pvr_state.rnd_start_time = 0;
	pvr_state.frame_last_len = -1;
	pvr_state.buf_last_len = -1;
	pvr_state.reg_last_len = -1;
	pvr_state.rnd_last_len = -1;
	pvr_state.vtx_buf_used = 0;
	pvr_state.vtx_buf_used_max = 0;

	/* If we're on a VGA box, disable vertical smoothing */
	if (vid_mode->cable_type == CT_VGA) {
		dbglog(DBG_KDEBUG, "pvr: disabling vertical scaling for VGA\n");
		PVR_SET(PVR_SCALER_CFG, 0x400);
	} else {
		dbglog(DBG_KDEBUG, "pvr: enabling vertical scaling for non-VGA\n");
		PVR_SET(PVR_SCALER_CFG, 0x401);
	}

	/* Hook the PVR interrupt events on G2 */
	pvr_state.vbl_handle = vblank_handler_add(pvr_int_handler);
	asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEDONE, pvr_int_handler);		asic_evt_enable(ASIC_EVT_PVR_OPAQUEDONE, ASIC_IRQ_DEFAULT);
	asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEMODDONE, pvr_int_handler);	asic_evt_enable(ASIC_EVT_PVR_OPAQUEMODDONE, ASIC_IRQ_DEFAULT);
	asic_evt_set_handler(ASIC_EVT_PVR_TRANSDONE, pvr_int_handler);		asic_evt_enable(ASIC_EVT_PVR_TRANSDONE, ASIC_IRQ_DEFAULT);
	asic_evt_set_handler(ASIC_EVT_PVR_TRANSMODDONE, pvr_int_handler);	asic_evt_enable(ASIC_EVT_PVR_TRANSMODDONE, ASIC_IRQ_DEFAULT);
	asic_evt_set_handler(ASIC_EVT_PVR_PTDONE, pvr_int_handler);		asic_evt_enable(ASIC_EVT_PVR_PTDONE, ASIC_IRQ_DEFAULT);
	asic_evt_set_handler(ASIC_EVT_PVR_RENDERDONE, pvr_int_handler);		asic_evt_enable(ASIC_EVT_PVR_RENDERDONE, ASIC_IRQ_DEFAULT);

	/* 3d-specific parameters; these are all about rendering and
	   nothing to do with setting up the video; some stuff in here
	   is still unknown. */
   	PVR_SET(PVR_UNK_00A8, 0x15d1c951);		/* M (Unknown magic value) */
   	PVR_SET(PVR_UNK_00A0, 0x00000020);		/* M */
   	PVR_SET(PVR_FB_CFG_2, 0x00000009);		/* alpha config */
	PVR_SET(PVR_UNK_0110, 0x00093f39);		/* M */
	PVR_SET(PVR_UNK_0098, 0x00800408);		/* M */
	PVR_SET(PVR_TEXTURE_CLIP, 0x00000000);		/* texture clip distance */
	PVR_SET(PVR_SPANSORT_CFG, 0x00000101);		/* M */
	PVR_SET(PVR_FOG_TABLE_COLOR, 0x007f7f7f);	/* Fog table color */
	PVR_SET(PVR_FOG_VERTEX_COLOR, 0x007f7f7f);	/* Fog vertex color */
	PVR_SET(PVR_COLOR_CLAMP_MIN, 0x00000000);	/* color clamp min */
	PVR_SET(PVR_COLOR_CLAMP_MAX, 0xffffffff);	/* color clamp max */
	PVR_SET(PVR_UNK_0080, 0x00000007);		/* M */
	PVR_SET(PVR_CHEAP_SHADOW, 0x00000001);		/* cheap shadow */
	PVR_SET(PVR_UNK_007C, 0x0027df77);		/* M */
	PVR_SET(PVR_TEXTURE_MODULO, 0x00000000);	/* stride width */
	PVR_SET(PVR_FOG_DENSITY, 0x0000ff07);		/* fog density */
	PVR_SET(PVR_UNK_00C8, PVR_GET(0x00d4) << 16);	/* M */
	PVR_SET(PVR_UNK_0118, 0x00008040);		/* M */

	/* Initialize PVR DMA */
	pvr_state.dma_lock = mutex_create();
	pvr_dma_init();

	/* Setup our wait-ready semaphore */
	pvr_state.ready_sem = sem_create(0);

	/* Set us as valid and return success */
	pvr_state.valid = 1;

	/* Validate our memory pool */
	pvr_mem_reset();
/* This doesn't work right now... */
/*#ifndef NDEBUG
	dbglog(DBG_KDEBUG, "pvr: free memory is %08lx bytes\n",
		pvr_mem_available());
#endif*//* !NDEBUG */

	return 0;
}