/* 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; }
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; }
/* 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; }