nkeynes@100 | 1 | /**
|
nkeynes@108 | 2 | * $Id: ta.c,v 1.3 2006-03-15 13:16:50 nkeynes Exp $
|
nkeynes@100 | 3 | *
|
nkeynes@100 | 4 | * PVR2 Tile Accelerator support. In principle this does a lot more work
|
nkeynes@100 | 5 | * than is currently implemented - we cheat. A lot.
|
nkeynes@100 | 6 | *
|
nkeynes@100 | 7 | * Copyright (c) 2005 Nathan Keynes.
|
nkeynes@100 | 8 | *
|
nkeynes@100 | 9 | * This program is free software; you can redistribute it and/or modify
|
nkeynes@100 | 10 | * it under the terms of the GNU General Public License as published by
|
nkeynes@100 | 11 | * the Free Software Foundation; either version 2 of the License, or
|
nkeynes@100 | 12 | * (at your option) any later version.
|
nkeynes@100 | 13 | *
|
nkeynes@100 | 14 | * This program is distributed in the hope that it will be useful,
|
nkeynes@100 | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nkeynes@100 | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nkeynes@100 | 17 | * GNU General Public License for more details.
|
nkeynes@100 | 18 | */
|
nkeynes@100 | 19 |
|
nkeynes@100 | 20 | #include "pvr2/pvr2.h"
|
nkeynes@100 | 21 | #include "asic.h"
|
nkeynes@100 | 22 | #include "dream.h"
|
nkeynes@100 | 23 |
|
nkeynes@100 | 24 | /** Tile Accelerator */
|
nkeynes@100 | 25 |
|
nkeynes@100 | 26 | struct tacmd {
|
nkeynes@100 | 27 | uint32_t command;
|
nkeynes@100 | 28 | uint32_t param1;
|
nkeynes@100 | 29 | uint32_t param2;
|
nkeynes@100 | 30 | uint32_t texture;
|
nkeynes@100 | 31 | float alpha;
|
nkeynes@100 | 32 | float red;
|
nkeynes@100 | 33 | float green;
|
nkeynes@100 | 34 | float blue;
|
nkeynes@100 | 35 | };
|
nkeynes@100 | 36 |
|
nkeynes@100 | 37 | struct vertex_type1 {
|
nkeynes@100 | 38 | uint32_t command;
|
nkeynes@100 | 39 | float x, y, z;
|
nkeynes@100 | 40 | uint32_t blank, blank2;
|
nkeynes@100 | 41 | uint32_t col;
|
nkeynes@100 | 42 | float f;
|
nkeynes@100 | 43 | };
|
nkeynes@100 | 44 |
|
nkeynes@103 | 45 | struct pvr2_ta_status {
|
nkeynes@103 | 46 | uint32_t *length;
|
nkeynes@103 | 47 | unsigned int last_poly_type;
|
nkeynes@103 | 48 | } pvr2_ta_status = {NULL,0};
|
nkeynes@103 | 49 |
|
nkeynes@100 | 50 | /**
|
nkeynes@100 | 51 | * (Re)initialize the tile accelerator in preparation for the next scene.
|
nkeynes@100 | 52 | * Normally called immediately before commencing polygon transmission.
|
nkeynes@100 | 53 | */
|
nkeynes@100 | 54 | void pvr2_ta_init( void )
|
nkeynes@100 | 55 | {
|
nkeynes@103 | 56 | /* Set the buffer indexes */
|
nkeynes@103 | 57 | MMIO_WRITE( PVR2, TAOBJPOS, MMIO_READ( PVR2, TAOBJBASE ) );
|
nkeynes@103 | 58 | MMIO_WRITE( PVR2, TAOBJPPOS, MMIO_READ( PVR2, TAOBJPBASE ) );
|
nkeynes@103 | 59 | pvr2_ta_status.last_poly_type = 0;
|
nkeynes@103 | 60 | pvr2_ta_status.length = NULL;
|
nkeynes@100 | 61 | }
|
nkeynes@100 | 62 |
|
nkeynes@100 | 63 | /**
|
nkeynes@100 | 64 | * Write a block of data to the tile accelerator, adding the data to the
|
nkeynes@100 | 65 | * current scene. We don't make any particular attempt to interpret the data
|
nkeynes@100 | 66 | * at this stage, deferring that until render time.
|
nkeynes@103 | 67 | *
|
nkeynes@103 | 68 | * Currently copies the data verbatim to the vertex buffer, processing only
|
nkeynes@103 | 69 | * far enough to generate the correct end-of-list events. Tile buffer is
|
nkeynes@103 | 70 | * entirely ignored.
|
nkeynes@100 | 71 | */
|
nkeynes@100 | 72 | void pvr2_ta_write( char *buf, uint32_t length )
|
nkeynes@100 | 73 | {
|
nkeynes@100 | 74 | int i;
|
nkeynes@100 | 75 | struct tacmd *cmd_list = (struct tacmd *)buf;
|
nkeynes@103 | 76 | uint32_t obj_addr = MMIO_READ( PVR2, TAOBJPOS );
|
nkeynes@103 | 77 | if( pvr2_ta_status.length == NULL ) { /* Start */
|
nkeynes@103 | 78 | pvr2_ta_status.length = (uint32_t *)mem_get_region( PVR2_RAM_BASE + obj_addr );
|
nkeynes@103 | 79 | obj_addr += 4;
|
nkeynes@103 | 80 | *pvr2_ta_status.length = length;
|
nkeynes@103 | 81 | } else {
|
nkeynes@103 | 82 | *pvr2_ta_status.length = *pvr2_ta_status.length + length;
|
nkeynes@103 | 83 | }
|
nkeynes@103 | 84 | mem_copy_to_sh4( PVR2_RAM_BASE + obj_addr, buf, length );
|
nkeynes@103 | 85 | MMIO_WRITE( PVR2, TAOBJPOS, obj_addr + length );
|
nkeynes@103 | 86 |
|
nkeynes@100 | 87 | int count = length >> 5;
|
nkeynes@100 | 88 | for( i=0; i<count; i++ ){
|
nkeynes@100 | 89 | unsigned int type = (cmd_list[i].command >> 24) & 0xFF;
|
nkeynes@100 | 90 | if( type == 0xE0 || type == 0xF0 ) {
|
nkeynes@100 | 91 | struct vertex_type1 *vert = (struct vertex_type1 *)&cmd_list[i];
|
nkeynes@108 | 92 | // DEBUG( "PVR2 vrt: %f %f %f %08X %08X %08X %f", vert->x, vert->y, vert->z, vert->blank, vert->blank2, vert->col, vert->f );
|
nkeynes@100 | 93 | } else {
|
nkeynes@108 | 94 | // DEBUG( "PVR2 cmd: %08X %08X %08X %08X %08X %08X %08X %08X", cmd_list[i].command, cmd_list[i].param1, cmd_list[i].param2, cmd_list[i].texture, cmd_list[i].alpha, cmd_list[i].red, cmd_list[i].green, cmd_list[i].blue );
|
nkeynes@100 | 95 | }
|
nkeynes@100 | 96 | if( type == 0 ) {
|
nkeynes@100 | 97 | /* End of list */
|
nkeynes@103 | 98 | switch( pvr2_ta_status.last_poly_type ) {
|
nkeynes@100 | 99 | case 0x80: /* Opaque polys */
|
nkeynes@100 | 100 | asic_event( EVENT_PVR_OPAQUE_DONE );
|
nkeynes@100 | 101 | break;
|
nkeynes@100 | 102 | case 0x81: /* Opaque poly modifier */
|
nkeynes@100 | 103 | asic_event( EVENT_PVR_OPAQUEMOD_DONE );
|
nkeynes@100 | 104 | break;
|
nkeynes@100 | 105 | case 0x82: /* Transparent polys */
|
nkeynes@100 | 106 | asic_event( EVENT_PVR_TRANS_DONE );
|
nkeynes@100 | 107 | break;
|
nkeynes@100 | 108 | case 0x83: /* Transparent poly modifier */
|
nkeynes@100 | 109 | asic_event( EVENT_PVR_TRANSMOD_DONE );
|
nkeynes@100 | 110 | break;
|
nkeynes@100 | 111 | case 0x84: /* Punchthrough */
|
nkeynes@100 | 112 | asic_event( EVENT_PVR_PUNCHOUT_DONE );
|
nkeynes@100 | 113 | break;
|
nkeynes@100 | 114 | }
|
nkeynes@103 | 115 | pvr2_ta_status.last_poly_type = 0;
|
nkeynes@100 | 116 | } else if( type >= 0x80 && type <= 0x84 ) {
|
nkeynes@103 | 117 | pvr2_ta_status.last_poly_type = type;
|
nkeynes@100 | 118 | }
|
nkeynes@100 | 119 | }
|
nkeynes@100 | 120 | }
|