Exemplo n.º 1
0
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);
}
Exemplo n.º 2
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);
}