void rmEndFrame(void) { gsKit_set_finish(gsGlobal); rmFlush(); // Wait for draw ops to finish gsKit_finish(); if(!gsGlobal->FirstFrame) { SleepThread(); if(gsGlobal->DoubleBuffering == GS_SETTING_ON) { GS_SET_DISPFB2( gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, gsGlobal->Width / 64, gsGlobal->PSM, 0, 0 ); gsGlobal->ActiveBuffer ^= 1; gsGlobal->PrimContext ^= 1; } } gsKit_setactive(gsGlobal); }
//--------------------------------------------------------------------------- void g2_set_visible_frame(u8 frame) { GS_SET_DISPFB2( g2_frame_addr[frame]/8192, // Frame Buffer base pointer = Address/8192 cur_mode->width/64, // Buffer Width (Pixels/64) cur_mode->psm, // Pixel Storage Format 0, // Upper Left X in Buffer = 0 0 // Upper Left Y in Buffer = 0 ); g2_visible_frame = frame; }
void gsKit_sync_flip(GSGLOBAL *gsGlobal) { if(!gsGlobal->FirstFrame) { gsKit_vsync_wait(); if(gsGlobal->DoubleBuffering == GS_SETTING_ON) { GS_SET_DISPFB2( gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, gsGlobal->Width / 64, gsGlobal->PSM, 0, 0 ); gsGlobal->ActiveBuffer ^= 1; } } gsKit_setactive(gsGlobal); }
void gsKit_init_screen(GSGLOBAL *gsGlobal) { u64 *p_data; u64 *p_store; int size = 18; if((gsGlobal->Dithering == GS_SETTING_ON) && ((gsGlobal->PSM == GS_PSM_CT16) || (gsGlobal->PSM == GS_PSM_CT16S))) size = 19; gsKit_set_buffer_attributes(gsGlobal); #ifdef DEBUG printf("Screen Mode:\n"); printf("------------\n"); printf("Width : %d\n", gsGlobal->Width); printf("Height: %d\n", gsGlobal->Height); printf("StartX: %d\n", gsGlobal->StartX); printf("StartY: %d\n", gsGlobal->StartY); printf("MagH : %d\n", gsGlobal->MagH); printf("MagV : %d\n", gsGlobal->MagV); printf("DW : %d\n", gsGlobal->DW); printf("DH : %d\n", gsGlobal->DH); #endif GS_RESET(); __asm__("sync.p; nop;"); *GS_CSR = 0x00000000; // Clean CSR registers GsPutIMR(0x0000F700); // Unmasks all of the GS interrupts SetGsCrt(gsGlobal->Interlace, gsGlobal->Mode, gsGlobal->Field); gsGlobal->FirstFrame = GS_SETTING_ON; if(gsGlobal->ZBuffering == GS_SETTING_OFF) { gsGlobal->Test->ZTE = GS_SETTING_ON; gsGlobal->Test->ZTST = 1; } DIntr(); // disable interrupts GS_SET_PMODE( 0, // Read Circuit 1 1, // Read Circuit 2 0, // Use ALP Register for Alpha Blending 1, // Alpha Value of Read Circuit 2 for Output Selection 0, // Blend Alpha with output of Read Circuit 2 0x80); // Alpha Value = 1.0 GS_SET_DISPFB1( 0, // Frame Buffer Base Pointer (Address/2048) gsGlobal->Width / 64, // Buffer Width (Address/64) gsGlobal->PSM, // Pixel Storage Format 0, // Upper Left X in Buffer 0); GS_SET_DISPFB2( 0, // Frame Buffer Base Pointer (Address/2048) gsGlobal->Width / 64, // Buffer Width (Address/64) gsGlobal->PSM, // Pixel Storage Format 0, // Upper Left X in Buffer 0); // Upper Left Y in Buffer GS_SET_DISPLAY1(gsGlobal->StartX, // X position in the display area (in VCK unit gsGlobal->StartY, // Y position in the display area (in Raster u gsGlobal->MagH, // Horizontal Magnification gsGlobal->MagV, // Vertical Magnification gsGlobal->DW - 1, // Display area width gsGlobal->DH - 1); // Display area height GS_SET_DISPLAY2(gsGlobal->StartX, // X position in the display area (in VCK units) gsGlobal->StartY, // Y position in the display area (in Raster units) gsGlobal->MagH, // Horizontal Magnification gsGlobal->MagV, // Vertical Magnification gsGlobal->DW - 1, // Display area width gsGlobal->DH - 1); // Display area height GS_SET_BGCOLOR( gsGlobal->BGColor->Red, // Red gsGlobal->BGColor->Green, // Green gsGlobal->BGColor->Blue); // Blue EIntr(); //enable interrupts gsGlobal->CurrentPointer = 0; // reset vram pointer too // Context 1 gsGlobal->ScreenBuffer[0] = gsKit_vram_alloc( gsGlobal, gsKit_texture_size(gsGlobal->Width, gsGlobal->Height, gsGlobal->PSM), GSKIT_ALLOC_SYSBUFFER ); if(gsGlobal->DoubleBuffering == GS_SETTING_OFF) { gsGlobal->ScreenBuffer[1] = gsGlobal->ScreenBuffer[0]; } else // Context 2 gsGlobal->ScreenBuffer[1] = gsKit_vram_alloc( gsGlobal, gsKit_texture_size(gsGlobal->Width, gsGlobal->Height, gsGlobal->PSM), GSKIT_ALLOC_SYSBUFFER ); if(gsGlobal->ZBuffering == GS_SETTING_ON) gsGlobal->ZBuffer = gsKit_vram_alloc( gsGlobal, gsKit_texture_size(gsGlobal->Width, gsGlobal->Height, gsGlobal->PSMZ), GSKIT_ALLOC_SYSBUFFER ); // Z Buffer gsGlobal->TexturePointer = gsGlobal->CurrentPointer; // first useable address for textures p_data = p_store = (u64 *)gsGlobal->dma_misc; *p_data++ = GIF_TAG( size - 1, 1, 0, 0, 0, 1 ); *p_data++ = GIF_AD; *p_data++ = 1; *p_data++ = GS_PRMODECONT; *p_data++ = GS_SETREG_FRAME_1( gsGlobal->ScreenBuffer[0], gsGlobal->Width / 64, gsGlobal->PSM, 0 ); *p_data++ = GS_FRAME_1; *p_data++ = GS_SETREG_XYOFFSET_1( gsGlobal->OffsetX, gsGlobal->OffsetY); *p_data++ = GS_XYOFFSET_1; *p_data++ = GS_SETREG_SCISSOR_1( 0, gsGlobal->Width - 1, 0, gsGlobal->Height - 1 ); *p_data++ = GS_SCISSOR_1; *p_data++ = GS_SETREG_TEST( gsGlobal->Test->ATE, gsGlobal->Test->ATST, gsGlobal->Test->AREF, gsGlobal->Test->AFAIL, gsGlobal->Test->DATE, gsGlobal->Test->DATM, gsGlobal->Test->ZTE, gsGlobal->Test->ZTST ); *p_data++ = GS_TEST_1; *p_data++ = GS_SETREG_CLAMP(gsGlobal->Clamp->WMS, gsGlobal->Clamp->WMT, gsGlobal->Clamp->MINU, gsGlobal->Clamp->MAXU, gsGlobal->Clamp->MINV, gsGlobal->Clamp->MAXV); *p_data++ = GS_CLAMP_1; if(gsGlobal->ZBuffering == GS_SETTING_ON) { if((gsGlobal->PSM == GS_PSM_CT16) && (gsGlobal->PSMZ != GS_PSMZ_16)) gsGlobal->PSMZ = GS_PSMZ_16; // seems only non-S 16-bit z depth works with this mode if((gsGlobal->PSM != GS_PSM_CT16) && (gsGlobal->PSMZ == GS_PSMZ_16)) gsGlobal->PSMZ = GS_PSMZ_16S; // other depths don't seem to work with 16-bit non-S z depth *p_data++ = GS_SETREG_ZBUF_1( gsGlobal->ZBuffer / 8192, gsGlobal->PSMZ, 0 ); *p_data++ = GS_ZBUF_1; } if(gsGlobal->ZBuffering == GS_SETTING_OFF) { *p_data++ = GS_SETREG_ZBUF_1( NULL, gsGlobal->PSM, 1 ); *p_data++ = GS_ZBUF_1; } *p_data++ = GS_SETREG_COLCLAMP( 255 ); *p_data++ = GS_COLCLAMP; *p_data++ = GS_SETREG_FRAME_1( gsGlobal->ScreenBuffer[1], gsGlobal->Width / 64, gsGlobal->PSM, 0 ); *p_data++ = GS_FRAME_2; *p_data++ = GS_SETREG_XYOFFSET_1( gsGlobal->OffsetX, gsGlobal->OffsetY); *p_data++ = GS_XYOFFSET_2; *p_data++ = GS_SETREG_SCISSOR_1( 0, gsGlobal->Width - 1, 0, gsGlobal->Height - 1); *p_data++ = GS_SCISSOR_2; *p_data++ = GS_SETREG_TEST( gsGlobal->Test->ATE, gsGlobal->Test->ATST, gsGlobal->Test->AREF, gsGlobal->Test->AFAIL, gsGlobal->Test->DATE, gsGlobal->Test->DATM, gsGlobal->Test->ZTE, gsGlobal->Test->ZTST ); *p_data++ = GS_TEST_2; *p_data++ = GS_SETREG_CLAMP(gsGlobal->Clamp->WMS, gsGlobal->Clamp->WMT, gsGlobal->Clamp->MINU, gsGlobal->Clamp->MAXU, gsGlobal->Clamp->MINV, gsGlobal->Clamp->MAXV); *p_data++ = GS_CLAMP_2; if(gsGlobal->ZBuffering == GS_SETTING_ON) { *p_data++ = GS_SETREG_ZBUF_1( gsGlobal->ZBuffer / 8192, gsGlobal->PSMZ, 0 ); *p_data++ = GS_ZBUF_2; } if(gsGlobal->ZBuffering == GS_SETTING_OFF) { *p_data++ = GS_SETREG_ZBUF_1( NULL, gsGlobal->PSM, 1 ); *p_data++ = GS_ZBUF_2; } *p_data++ = GS_BLEND_BACK2FRONT; *p_data++ = GS_ALPHA_1; *p_data++ = GS_BLEND_BACK2FRONT; *p_data++ = GS_ALPHA_2; *p_data++ = GS_SETREG_DIMX(gsGlobal->DitherMatrix[0],gsGlobal->DitherMatrix[1], gsGlobal->DitherMatrix[2],gsGlobal->DitherMatrix[3],gsGlobal->DitherMatrix[4], gsGlobal->DitherMatrix[5],gsGlobal->DitherMatrix[6],gsGlobal->DitherMatrix[7], gsGlobal->DitherMatrix[8],gsGlobal->DitherMatrix[9],gsGlobal->DitherMatrix[10], gsGlobal->DitherMatrix[11],gsGlobal->DitherMatrix[12],gsGlobal->DitherMatrix[13], gsGlobal->DitherMatrix[14],gsGlobal->DitherMatrix[15]); // 4x4 dither matrix *p_data++ = GS_DIMX; if((gsGlobal->Dithering == GS_SETTING_ON) && ((gsGlobal->PSM == GS_PSM_CT16) || (gsGlobal->PSM == GS_PSM_CT16S))) { *p_data++ = 1; *p_data++ = GS_DTHE; } dmaKit_send_ucab(DMA_CHANNEL_GIF, p_store, size); dmaKit_wait_fast(); // do a single frame here to get rid whatever needs to be done during the first frame gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x00,0x00,0x00,0x00,0x00)); // clear the screen gsKit_queue_exec(gsGlobal); gsKit_sync_flip(gsGlobal); gsKit_queue_reset(gsGlobal->Os_Queue); }
void gsKit_display_buffer(GSGLOBAL *gsGlobal) { GS_SET_DISPFB2( gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, gsGlobal->Width / 64, gsGlobal->PSM, 0, 0 ); }
//--------------------------------------------------------------------------- int g2_init(g2_video_mode mode) { vmode_t *v; v = &(vmodes[mode]); cur_mode = v; g2_max_x = v->width - 1; g2_max_y = v->height - 1; g2_view_x0 = 0; g2_view_y0 = 0; g2_view_x1 = g2_max_x; g2_view_y1 = g2_max_y; gs_origin_x = 1024; gs_origin_y = 1024; gs_mem_current = 0; // nothing allocated yet g2_visible_frame = 0; // display frame 0 g2_active_frame = 0; // draw to frame 0 // - Initialize the DMA. // - Writes a 0 to most of the DMA registers. dma_reset(); // - Sets the RESET bit if the GS CSR register. GS_RESET(); #ifndef FLASH // - Can someone please tell me what the sync.p // instruction does. Synchronizes something :-) __asm__(" sync.p nop "); #endif // - Sets up the GS IMR register (i guess). // - The IMR register is used to mask and unmask certain interrupts, // for example VSync and HSync. We'll use this properly in Tutorial 2. // - Does anyone have code to do this without using the 0x71 syscall? // - I havn't gotten around to looking at any PS2 bios code yet. gs_set_imr(); // - Use syscall 0x02 to setup some video mode stuff. // - Pretty self explanatory I think. // - Does anyone have code to do this without using the syscall? It looks // like it should only set the SMODE2 register, but if I remove this syscall // and set the SMODE2 register myself, it donesn't work. What else does // syscall 0x02 do? gs_set_crtc(NON_INTERLACED, v->ntsc_pal, FRAME); // - I havn't attempted to understand what the Alpha parameters can do. They // have been blindly copied from the 3stars demo (although they don't seem // do have any impact in this simple 2D code. GS_SET_PMODE( 0, // ReadCircuit1 OFF 1, // ReadCircuit2 ON 1, // Use ALP register for Alpha Blending 1, // Alpha Value of ReadCircuit2 for output selection 0, // Blend Alpha with the output of ReadCircuit2 0xFF // Alpha Value = 1.0 ); /* // - Non needed if we use gs_set_crt() GS_SET_SMODE2( 0, // Non-Interlaced mode 1, // FRAME mode (read every line) 0 // VESA DPMS Mode = ON ??? please explain ??? ); */ GS_SET_DISPFB2( 0, // Frame Buffer base pointer = 0 (Address/8192) v->width/64, // Buffer Width (Pixels/64) v->psm, // Pixel Storage Format 0, // Upper Left X in Buffer = 0 0 // Upper Left Y in Buffer = 0 ); // Why doesn't (0, 0) equal the very top-left of the TV? GS_SET_DISPLAY2( 656, // X position in the display area (in VCK units) 36, // Y position in the display area (in Raster units) v->magh-1, // Horizontal Magnification - 1 0, // Vertical Magnification = 1x v->width*v->magh-1, // Display area width - 1 (in VCK units) (Width*HMag-1) v->height-1 // Display area height - 1 (in pixels) (Height-1) ); GS_SET_BGCOLOR( 0, // RED 0, // GREEN 0 // BLUE ); BEGIN_GS_PACKET(gs_dma_buf); GIF_TAG_AD(gs_dma_buf, 6, 1, 0, 0, 0); // Use drawing parameters from PRIM register GIF_DATA_AD(gs_dma_buf, prmodecont, 1); // Setup frame buffers. Point to 0 initially. GIF_DATA_AD(gs_dma_buf, frame_1, GS_FRAME( 0, // FrameBuffer base pointer = 0 (Address/8192) v->width/64, // Frame buffer width (Pixels/64) v->psm, // Pixel Storage Format 0)); // Save address and advance GS memory pointer by buffer size (in bytes) // Do this for both frame buffers. g2_frame_addr[0] = gs_mem_current; gs_mem_current += v->width * v->height * (v->bpp/8); g2_frame_addr[1] = gs_mem_current; gs_mem_current += v->width * v->height * (v->bpp/8); // Displacement between Primitive and Window coordinate systems. GIF_DATA_AD(gs_dma_buf, xyoffset_1, GS_XYOFFSET( gs_origin_x<<4, gs_origin_y<<4)); // Clip to frame buffer. GIF_DATA_AD(gs_dma_buf, scissor_1, GS_SCISSOR( 0, g2_max_x, 0, g2_max_y)); // Create a single 256x128 font buffer g2_fontbuf_addr = gs_mem_current; gs_mem_current += g2_fontbuf_w * g2_fontbuf_h * (v->bpp/8); // Create a texture buffer as big as the screen. // Just save the address advance GS memory pointer by buffer size (in bytes) // The TEX registers are set later, when drawing. g2_texbuf_addr = gs_mem_current; gs_mem_current += v->width * v->height * (v->bpp/8); // Setup test_1 register to allow transparent texture regions where A=0 GIF_DATA_AD(gs_dma_buf, test_1, GS_TEST( 1, // Alpha Test ON ATST_NOTEQUAL, 0x00, // Reject pixels with A=0 AFAIL_KEEP, // Don't update frame or Z buffers 0, 0, 0, 0)); // No Destination Alpha or Z-Buffer Tests // Setup the ALPHA_1 register to correctly blend edges of // pre-antialiased fonts using Alpha Blending stage. // The blending formula is // PIXEL=(SRC-FRAME)*SRC_ALPHA>>7+FRAME GIF_DATA_AD(gs_dma_buf, alpha_1, GS_ALPHA( 0, // A - source 1, // B - frame buffer 0, // C - alpha from source 1, // D - frame buffer 0)); // FIX - not needed SEND_GS_PACKET(gs_dma_buf); return(1); }