summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2015-05-11 23:52:10 +0200
committer yz70s <yz70s@users.noreply.github.com>2015-05-12 00:00:14 +0200
commit9bdeedb52bd39163d4e93832a9f509b3d00e3dd8 (patch)
tree44dae619d630cb3d46c283cb068ee390404aa89b /src/mame
parent88c04136c83e43d6e441704f7ad1e78dc898738a (diff)
chihiro.c: add 3d method 1808 puls a few misc. changes (nw)
Diffstat (limited to 'src/mame')
-rw-r--r--src/mame/drivers/chihiro.c2
-rw-r--r--src/mame/includes/chihiro.h63
-rw-r--r--src/mame/video/chihiro.c183
3 files changed, 180 insertions, 68 deletions
diff --git a/src/mame/drivers/chihiro.c b/src/mame/drivers/chihiro.c
index a385f0b7be2..ce5ea0b9cf2 100644
--- a/src/mame/drivers/chihiro.c
+++ b/src/mame/drivers/chihiro.c
@@ -1803,7 +1803,7 @@ void chihiro_state::machine_start()
save_item(NAME(smbusst.words));
save_item(NAME(pic16lc_buffer));
save_item(NAME(usbhack_counter));
- nvidia_nv2a->start();
+ nvidia_nv2a->start(&m_maincpu->space());
nvidia_nv2a->savestate_items();
}
diff --git a/src/mame/includes/chihiro.h b/src/mame/includes/chihiro.h
index 73acd6ae920..896b7985f0a 100644
--- a/src/mame/includes/chihiro.h
+++ b/src/mame/includes/chihiro.h
@@ -70,6 +70,32 @@ struct vertex_nv {
*/
class vertex_program_simulator {
public:
+ enum VectorialOperation {
+ VecNOP=0,
+ VecMOV,
+ VecMUL,
+ VecADD,
+ VecMAD,
+ VecDP3,
+ VecDPH,
+ VecDP4,
+ VecDST,
+ VecMIN,
+ VecMAX,
+ VecSLT,
+ VecSGE,
+ VecARL
+ };
+ enum ScalarOperation {
+ ScaNOP=0,
+ ScaIMV,
+ ScaRCP,
+ ScaRCC,
+ ScaRSQ,
+ ScaEXP,
+ ScaLOG,
+ ScaLIT
+ };
vertex_program_simulator();
// input vertex
vertex_nv *input;
@@ -92,7 +118,8 @@ public:
int SwizzleA[4], SignA, ParameterTypeA, TempIndexA;
int SwizzleB[4], SignB, ParameterTypeB, TempIndexB;
int SwizzleC[4], SignC, ParameterTypeC, TempIndexC;
- int VecOperation, ScaOperation;
+ VectorialOperation VecOperation;
+ ScalarOperation ScaOperation;
int OutputWriteMask, MultiplexerControl;
int VecTempWriteMask, ScaTempWriteMask;
int VecTempIndex, OutputIndex;
@@ -190,6 +217,12 @@ public:
limits_rendertarget.set(0, 0, 640, 480);
pitch_rendertarget = 0;
pitch_depthbuffer = 0;
+ height_rendertarget=0;
+ width_rendertarget=0;
+ antialiasing_rendertarget=0;
+ type_rendertarget=nv2a_renderer::LINEAR;
+ depth_rendertarget=nv2a_renderer::NV2A_RT_DEPTH_FORMAT_Z24S8;
+ color_rendertarget=nv2a_renderer::NV2A_COLOR_FORMAT_A8R8G8B8;
rendertarget = NULL;
depthbuffer = NULL;
displayedtarget = NULL;
@@ -247,13 +280,15 @@ public:
int toggle_wait_vblank_support();
void debug_grab_texture(int type, const char *filename);
void debug_grab_vertex_program_slot(int slot, UINT32 *instruction);
- void start();
+ void start(address_space *cpu_space);
void savestate_items();
void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib);
- int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit);
int read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit);
+ int read_vertices_0x1808(address_space & space, vertex_nv *destination, UINT32 address, int limit);
+ int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit);
int read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit);
void convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count);
+ inline UINT8 *direct_access_ptr(offs_t address);
TIMER_CALLBACK_MEMBER(puller_timer_work);
struct {
@@ -270,9 +305,16 @@ public:
UINT32 ramin[0x100000 / 4];
UINT32 dma_offset[2];
UINT32 dma_size[2];
+ UINT8 *basemempointer;
rectangle limits_rendertarget;
UINT32 pitch_rendertarget;
UINT32 pitch_depthbuffer;
+ int height_rendertarget;
+ int width_rendertarget;
+ int antialiasing_rendertarget;
+ int type_rendertarget;
+ int depth_rendertarget;
+ int color_rendertarget;
UINT32 *rendertarget;
UINT32 *depthbuffer;
UINT32 *displayedtarget;
@@ -595,4 +637,19 @@ public:
INCR_WRAP = 0x8507,
DECR_WRAP = 0x8508
};
+ enum NV2A_RT_TYPE {
+ LINEAR = 1,
+ SWIZZLED = 2
+ };
+ enum NV2A_RT_DEPTH_FORMAT {
+ NV2A_RT_DEPTH_FORMAT_Z16 = 0x0001,
+ NV2A_RT_DEPTH_FORMAT_Z24S8 = 0x0002
+ };
+
+ enum NV2A_COLOR_FORMAT {
+ NV2A_COLOR_FORMAT_R5G6B5 = 0x0003,
+ NV2A_COLOR_FORMAT_X8R8G8B8 = 0x0005,
+ NV2A_COLOR_FORMAT_A8R8G8B8 = 0x0008,
+ NV2A_COLOR_FORMAT_B8 = 0x0009
+ };
};
diff --git a/src/mame/video/chihiro.c b/src/mame/video/chihiro.c
index ede19297dea..ac74dc2ac24 100644
--- a/src/mame/video/chihiro.c
+++ b/src/mame/video/chihiro.c
@@ -477,8 +477,8 @@ void vertex_program_simulator::decode_instruction(int address)
i->d.SwizzleC[1] = (i->i[2] >> 6) & 3;
i->d.SwizzleC[2] = (i->i[2] >> 4) & 3;
i->d.SwizzleC[3] = (i->i[2] >> 2) & 3;
- i->d.VecOperation = (i->i[1] >> 21) & 15;
- i->d.ScaOperation = (i->i[1] >> 25) & 15;
+ i->d.VecOperation = (VectorialOperation)((i->i[1] >> 21) & 15);
+ i->d.ScaOperation = (ScalarOperation)((i->i[1] >> 25) & 15);
i->d.OutputWriteMask = ((i->i[3] >> 12) & 15);
i->d.MultiplexerControl = i->i[3] & 4; // 0 : output Rn from vectorial operation 4 : output Rn from scalar operation
i->d.VecTempIndex = (i->i[3] >> 20) & 15;
@@ -910,6 +910,11 @@ void nv2a_renderer::computedilated(void)
dilatechose[(b << 4) + a] = (a < b ? a : b);
}
+inline UINT8 *nv2a_renderer::direct_access_ptr(offs_t address)
+{
+ return basemempointer + address;
+}
+
int nv2a_renderer::geforce_commandkind(UINT32 word)
{
if ((word & 0x00000003) == 0x00000002)
@@ -2059,29 +2064,42 @@ void nv2a_renderer::read_vertex(address_space & space, offs_t address, vertex_nv
}
}
-/* Read vertices data from system memory. Method 0x1810 */
-int nv2a_renderer::read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit)
+/* Read vertices data from system memory. Method 0x1800 */
+int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit)
{
- UINT32 m;
+ UINT32 data;
+ UINT32 m, i, c;
int a, b;
#ifdef MAME_DEBUG
memset(destination, 0, sizeof(vertex_nv)*limit);
#endif
+ c = 0;
for (m = 0; m < limit; m++) {
+ if (indexesleft_count == 0) {
+ data = space.read_dword(address);
+ i = (indexesleft_first + indexesleft_count) & 7;
+ indexesleft[i] = data & 0xffff;
+ indexesleft[(i + 1) & 7] = (data >> 16) & 0xffff;
+ indexesleft_count = indexesleft_count + 2;
+ address += 4;
+ c++;
+ }
b = enabled_vertex_attributes;
for (a = 0; a < 16; a++) {
if (b & 1) {
- read_vertex(space, vertexbuffer_address[a] + (m + offset)*vertexbuffer_stride[a], destination[m], a);
+ read_vertex(space, vertexbuffer_address[a] + indexesleft[indexesleft_first] * vertexbuffer_stride[a], destination[m], a);
}
b = b >> 1;
}
+ indexesleft_first = (indexesleft_first + 1) & 7;
+ indexesleft_count--;
}
- return m;
+ return (int)c;
}
-/* Read vertices data from system memory. Method 0x1800 */
-int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destination, UINT32 address, int limit)
+/* Read vertices data from system memory. Method 0x1808 */
+int nv2a_renderer::read_vertices_0x1808(address_space & space, vertex_nv *destination, UINT32 address, int limit)
{
UINT32 data;
UINT32 m, i, c;
@@ -2095,9 +2113,8 @@ int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destin
if (indexesleft_count == 0) {
data = space.read_dword(address);
i = (indexesleft_first + indexesleft_count) & 7;
- indexesleft[i] = data & 0xffff;
- indexesleft[(i + 1) & 7] = (data >> 16) & 0xffff;
- indexesleft_count = indexesleft_count + 2;
+ indexesleft[i] = data;
+ indexesleft_count = indexesleft_count + 1;
address += 4;
c++;
}
@@ -2114,6 +2131,27 @@ int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destin
return (int)c;
}
+/* Read vertices data from system memory. Method 0x1810 */
+int nv2a_renderer::read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit)
+{
+ UINT32 m;
+ int a, b;
+
+#ifdef MAME_DEBUG
+ memset(destination, 0, sizeof(vertex_nv)*limit);
+#endif
+ for (m = 0; m < limit; m++) {
+ b = enabled_vertex_attributes;
+ for (a = 0; a < 16; a++) {
+ if (b & 1) {
+ read_vertex(space, vertexbuffer_address[a] + (m + offset)*vertexbuffer_stride[a], destination[m], a);
+ }
+ b = b >> 1;
+ }
+ }
+ return m;
+}
+
/* Read vertices data from system memory. Method 0x1818 */
int nv2a_renderer::read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit)
{
@@ -2243,9 +2281,10 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
countlen--;
}
- if (maddress == 0x1800) {
+ if ((maddress == 0x1800) || (maddress == 0x1808)) {
UINT32 type, n;
render_delegate renderspans;
+ int mult;
if (((channel[chanel][subchannel].object.method[0x1e60 / 4] & 7) > 0) && (combiner.used != 0)) {
renderspans = render_delegate(FUNC(nv2a_renderer::render_register_combiners), this);
@@ -2255,8 +2294,13 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
else
renderspans = render_delegate(FUNC(nv2a_renderer::render_color), this);
+ if (maddress == 0x1800)
+ mult = 2;
+ else
+ mult = 1;
// vertices are selected from the vertex buffer using an array of indexes
// each dword after 1800 contains two 16 bit index values to select the vartices
+ // each dword after 1808 contains a 32 bit index value to select the vartices
type = channel[chanel][subchannel].object.method[0x17fc / 4];
#ifdef LOG_NV2A
printf("vertex %d %d %d\n\r", type, offset, count);
@@ -2267,24 +2311,17 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
vertex_t xy[4];
int c;
- if ((countlen * 2 + indexesleft_count) < 4)
+ if ((countlen * mult + indexesleft_count) < 4)
break;
- c = read_vertices_0x1800(space, vert, address, 4);
+ if (mult == 1)
+ c = read_vertices_0x1808(space, vert, address, 4);
+ else
+ c = read_vertices_0x1800(space, vert, address, 4);
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vert, xy, 4);
render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
}
- while (countlen > 0) {
- data = space.read_dword(address);
- n = (indexesleft_first + indexesleft_count) & 7;
- indexesleft[n] = data & 0xffff;
- indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
- indexesleft_count = indexesleft_count + 2;
- address += 4;
- countlen--;
- }
- wait();
}
else if (type == nv2a_renderer::TRIANGLES) {
while (1) {
@@ -2292,38 +2329,37 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
vertex_t xy[3];
int c;
- if ((countlen * 2 + indexesleft_count) < 3)
+ if ((countlen * mult + indexesleft_count) < 3)
break;
- c = read_vertices_0x1800(space, vert, address, 3);
+ if (mult == 1)
+ c = read_vertices_0x1808(space, vert, address, 3);
+ else
+ c = read_vertices_0x1800(space, vert, address, 3);
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vert, xy, 3);
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
}
- while (countlen > 0) {
- data = space.read_dword(address);
- n = (indexesleft_first + indexesleft_count) & 7;
- indexesleft[n] = data & 0xffff;
- indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
- indexesleft_count = indexesleft_count + 2;
- address += 4;
- countlen--;
- }
- wait();
}
else if (type == nv2a_renderer::TRIANGLE_STRIP) {
- if ((countlen * 2 + indexesleft_count) >= 3) {
+ if ((countlen * mult + indexesleft_count) >= 3) {
vertex_nv vert[4];
vertex_t xy[4];
int c, count;
- c = read_vertices_0x1800(space, vert, address, 2);
+ if (mult == 1)
+ c = read_vertices_0x1808(space, vert, address, 2);
+ else
+ c = read_vertices_0x1800(space, vert, address, 2);
convert_vertices_poly(vert, xy, 2);
address = address + c * 4;
countlen = countlen - c;
- count = countlen * 2 + indexesleft_count;
- for (n = 0; n < count; n++) { // <=
- c = read_vertices_0x1800(space, vert + ((n + 2) & 3), address, 1);
+ count = countlen * mult + indexesleft_count;
+ for (n = 0; n < count; n++) {
+ if (mult == 1)
+ c = read_vertices_0x1808(space, vert + ((n + 2) & 3), address, 1);
+ else
+ c = read_vertices_0x1800(space, vert + ((n + 2) & 3), address, 1);
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
@@ -2332,21 +2368,27 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
}
}
- while (countlen > 0) {
- data = space.read_dword(address);
- n = (indexesleft_first + indexesleft_count) & 7;
+ }
+ else {
+ logerror("Unsupported primitive %d for method 0x1800/8\n", type);
+ countlen = 0;
+ }
+ while (countlen > 0) {
+ data = space.read_dword(address);
+ n = (indexesleft_first + indexesleft_count) & 7;
+ if (mult == 2) {
indexesleft[n] = data & 0xffff;
indexesleft[(n + 1) & 7] = (data >> 16) & 0xffff;
indexesleft_count = indexesleft_count + 2;
- address += 4;
- countlen--;
}
- wait();
- }
- else {
- logerror("Unsupported primitive %d for method 0x1800\n", type);
- countlen = 0;
+ else {
+ indexesleft[n] = data;
+ indexesleft_count = indexesleft_count + 1;
+ }
+ address += 4;
+ countlen--;
}
+ wait();
}
if (maddress == 0x1818) {
int n;
@@ -2575,14 +2617,26 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
countlen--;
}
if (maddress == 0x0200) {
- //x = data & 0xffff;
- //w = (data >> 16) & 0xffff;
- limits_rendertarget.setx(0,((data >> 16) & 0xffff)-1);
+ int x, w;
+
+ x = data & 0xffff;
+ w = (data >> 16) & 0xffff;
+ limits_rendertarget.setx(x,x+w-1);
}
if (maddress == 0x0204) {
- //y = data & 0xffff;
- //h = (data >> 16) & 0xffff;
- limits_rendertarget.sety(0,((data >> 16) & 0xffff)-1);
+ int y, h;
+
+ y = data & 0xffff;
+ h = (data >> 16) & 0xffff;
+ limits_rendertarget.sety(y,y+h-1);
+ }
+ if (maddress == 0x0208) {
+ height_rendertarget=(data >> 24) & 255;
+ width_rendertarget=(data >> 16) & 255;
+ antialiasing_rendertarget=(data >> 12) & 15;
+ type_rendertarget=(data >> 8) & 15;
+ depth_rendertarget=(data >> 4) & 15;
+ color_rendertarget=(data >> 0) & 15;
}
if (maddress == 0x020c) {
// line size ?
@@ -2596,7 +2650,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
if ((data & 0x1f) == 1) {
data = data >> 5;
data = data & 0x0ffffff0;
- displayedtarget = (UINT32 *)space.get_write_ptr(data);
+ displayedtarget = (UINT32 *)direct_access_ptr(data);
}
}
if (maddress == 0x0130) {
@@ -2608,13 +2662,13 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
}
if (maddress == 0x0210) {
// framebuffer offset ?
- rendertarget = (UINT32 *)space.get_write_ptr(data);
+ rendertarget = (UINT32 *)direct_access_ptr(data);
//printf("Render target at %08X\n\r",data);
countlen--;
}
if (maddress == 0x0214) {
// zbuffer offset ?
- depthbuffer = (UINT32 *)space.get_write_ptr(data);
+ depthbuffer = (UINT32 *)direct_access_ptr(data);
//printf("Depth buffer at %08X\n\r",data);
if ((data == 0) || (data > 0x7ffffffc))
depth_write_enabled = false;
@@ -2708,7 +2762,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
//UINT32 dmahand,dmaoff,dmasiz;
offset = data;
- texture[unit].buffer = space.get_read_ptr(offset);
+ texture[unit].buffer = direct_access_ptr(offset);
/*if (dma0 != 0) {
dmahand=channel[channel][subchannel].object.method[0x184/4];
geforce_read_dma_object(dmahand,dmaoff,smasiz);
@@ -3839,7 +3893,7 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w)
return;
COMBINE_DATA(pcrtc + e);
if (e == 0x800 / 4) {
- displayedtarget = (UINT32 *)space.get_read_ptr(data);
+ displayedtarget = (UINT32 *)direct_access_ptr(data);
//printf("crtc buffer %08X\n\r", data);
}
//logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
@@ -3898,8 +3952,9 @@ void nv2a_renderer::savestate_items()
{
}
-void nv2a_renderer::start()
+void nv2a_renderer::start(address_space *cpu_space)
{
+ basemempointer = (UINT8 *)cpu_space->get_read_ptr(0);
puller_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nv2a_renderer::puller_timer_work), this), (void *)"NV2A Puller Timer");
puller_timer->enable(false);
}