chihiro.c/xbox.c: Various updates [Samuele Zannoli]

- support render targets different than rgb32
 - support 16 bit depth buffer
 - support independent clearing of stencil and depth values
 - update rom loading
 - add xbox hack to avoid stalling
 - set xbox bios 4134 as the one used
This commit is contained in:
yz70s 2015-09-09 20:48:51 +02:00
parent a73522ab0f
commit 07c3b7ac13
5 changed files with 267 additions and 62 deletions

View File

@ -896,7 +896,7 @@ MACHINE_CONFIG_END
ROMX_LOAD(name, offset, length, hash, ROM_BIOS(bios+1)) /* Note '+1' */
#define CHIHIRO_BIOS \
ROM_REGION( 0x80000, "bios", 0) \
ROM_REGION( 0x100000, "bios", 0) \
ROM_SYSTEM_BIOS( 0, "bios0", "Chihiro Bios" ) \
ROM_LOAD_BIOS( 0, "chihiro_xbox_bios.bin", 0x000000, 0x80000, CRC(66232714) SHA1(b700b0041af8f84835e45d1d1250247bf7077188) ) \
ROM_REGION( 0x404080, "others", 0) \

View File

@ -224,8 +224,10 @@ public:
dilate_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;
depthformat_rendertarget = nv2a_renderer::NV2A_RT_DEPTH_FORMAT_Z24S8;
colorformat_rendertarget = nv2a_renderer::NV2A_COLOR_FORMAT_A8R8G8B8;
bytespixel_rendertarget = 4;
antialias_control = 0;
rendertarget = NULL;
depthbuffer = NULL;
displayedtarget = NULL;
@ -254,6 +256,7 @@ public:
void geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size);
int geforce_exec_method(address_space &space, UINT32 channel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen);
UINT32 texture_get_texel(int number, int x, int y);
UINT8 *read_pixel(int x, int y, UINT32 c[4]);
void write_pixel(int x, int y, UINT32 color, UINT32 depth);
void combiner_initialize_registers(UINT32 argb8[6]);
void combiner_initialize_stage(int stage_number);
@ -293,6 +296,7 @@ public:
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);
void clear_depth_buffer(int what, UINT32 value);
inline UINT8 *direct_access_ptr(offs_t address);
TIMER_CALLBACK_MEMBER(puller_timer_work);
@ -321,8 +325,10 @@ public:
int dilate_rendertarget;
int antialiasing_rendertarget;
int type_rendertarget;
int depth_rendertarget;
int color_rendertarget;
int depthformat_rendertarget;
int colorformat_rendertarget;
int bytespixel_rendertarget;
UINT32 antialias_control;
UINT32 *rendertarget;
UINT32 *depthbuffer;
UINT32 *displayedtarget;

View File

@ -1418,7 +1418,7 @@ ADDRESS_MAP_START(xbox_base_map, AS_PROGRAM, 32, xbox_base_state)
AM_RANGE(0xfed00000, 0xfed003ff) AM_READWRITE(usbctrl_r, usbctrl_w)
AM_RANGE(0xfe800000, 0xfe85ffff) AM_READWRITE(audio_apu_r, audio_apu_w)
AM_RANGE(0xfec00000, 0xfec001ff) AM_READWRITE(audio_ac93_r, audio_ac93_w)
AM_RANGE(0xff000000, 0xff07ffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x00f80000)
AM_RANGE(0xff000000, 0xff0fffff) AM_ROM AM_REGION("bios", 0) AM_MIRROR(0x00f80000)
ADDRESS_MAP_END
ADDRESS_MAP_START(xbox_base_map_io, AS_IO, 32, xbox_base_state)

View File

@ -1240,42 +1240,99 @@ UINT32 nv2a_renderer::texture_get_texel(int number, int x, int y)
}
}
inline UINT8 *nv2a_renderer::read_pixel(int x, int y, UINT32 c[4])
{
UINT32 offset;
UINT32 color;
UINT32 *addr;
UINT16 *addr16;
UINT8 *addr8;
if (type_rendertarget == SWIZZLED)
offset = (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]) * bytespixel_rendertarget;
else // type_rendertarget == LINEAR*/
offset = pitch_rendertarget * y + x * bytespixel_rendertarget;
switch (colorformat_rendertarget) {
case NV2A_COLOR_FORMAT_R5G6B5:
addr16 = (UINT16 *)((UINT8 *)rendertarget + offset);
color = *addr16;
c[3] = 0xff;
c[2] = pal5bit((color & 0xf800) >> 11);
c[1] = pal6bit((color & 0x07e0) >> 5);
c[0] = pal5bit(color & 0x1f);
return (UINT8 *)addr16;
case NV2A_COLOR_FORMAT_X8R8G8B8:
addr = (UINT32 *)((UINT8 *)rendertarget + offset);
color = *addr;
c[3] = 0xff;
c[2] = (color >> 16) & 255;
c[1] = (color >> 8) & 255;
c[0] = color & 255;
return (UINT8 *)addr;
case NV2A_COLOR_FORMAT_A8R8G8B8:
addr = (UINT32 *)((UINT8 *)rendertarget + offset);
color = *addr;
c[3] = color >> 24;
c[2] = (color >> 16) & 255;
c[1] = (color >> 8) & 255;
c[0] = color & 255;
return (UINT8 *)addr;
case NV2A_COLOR_FORMAT_B8:
addr8 = (UINT8 *)rendertarget + offset;
c[0] = *addr8;
c[1] = c[2] = 0;
c[3] = 0xff;
return addr8;
}
return NULL;
}
void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
{
UINT32 *addr, *daddr;
UINT32 fbcolor, deptsten;
UINT8 *addr;
UINT32 *daddr32;
UINT16 *daddr16;
UINT32 deptsten;
UINT32 c[4], fb[4], s[4], d[4], cc[4];
UINT32 dep, sten, stenc, stenv;
bool stencil_passed;
bool depth_passed;
if (type_rendertarget == SWIZZLED)
addr = rendertarget + (dilated0[dilate_rendertarget][x] + dilated1[dilate_rendertarget][y]);
else // type_rendertarget == LINEAR*/
addr = rendertarget + (pitch_rendertarget / 4)*y + x;
fbcolor = 0;
fb[3] = fb[2] = fb[1] = fb[0] = 0;
addr = NULL;
if (color_mask != 0)
fbcolor = *addr;
daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
deptsten = *daddr;
addr = read_pixel(x, y, fb);
if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z24S8) {
daddr32 = depthbuffer + (pitch_depthbuffer / 4) * y + x;
deptsten = *daddr32;
dep = deptsten >> 8;
sten = deptsten & 255;
daddr16 = NULL;
}
else if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z16) {
daddr16 = (UINT16 *)depthbuffer + (pitch_depthbuffer / 2) * y + x;
deptsten = *daddr16;
dep = (deptsten << 8) | 0xff;
sten = 0;
daddr32 = NULL;
}
else {
daddr32 = NULL;
daddr16 = NULL;
dep = 0xffffff;
sten = 0;
}
if (depth > 0xffffff)
depth = 0xffffff;
c[3] = color >> 24;
c[2] = (color >> 16) & 255;
c[1] = (color >> 8) & 255;
c[0] = color & 255;
fb[3] = fbcolor >> 24;
fb[2] = (fbcolor >> 16) & 255;
fb[1] = (fbcolor >> 8) & 255;
fb[0] = fbcolor & 255;
cc[3] = blend_color >> 24;
cc[2] = (blend_color >> 16) & 255;
cc[1] = (blend_color >> 8) & 255;
cc[0] = blend_color & 255;
dep = deptsten >> 8;
sten = deptsten & 255;
if (depth > 0xffffff)
depth = 0xffffff;
if (depth & 0x80000000)
depth = 0;
// ownership test and scissor test not done
// alpha test
if (alpha_test_enabled) {
@ -1383,8 +1440,14 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
sten = 255;
break;
}
deptsten = (dep << 8) | sten;
*daddr = deptsten;
if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z24S8) {
deptsten = (dep << 8) | sten;
*daddr32 = deptsten;
}
else if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z16) {
deptsten = dep >> 8;
*daddr16 = (UINT16)deptsten;
}
return;
}
}
@ -1458,8 +1521,14 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
sten = 255;
break;
}
deptsten = (dep << 8) | sten;
*daddr = deptsten;
if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z24S8) {
deptsten = (dep << 8) | sten;
*daddr32 = deptsten;
}
else if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z16) {
deptsten = dep >> 8;
*daddr16 = (UINT16)deptsten;
}
return;
}
switch (stencil_op_zpass) {
@ -1782,15 +1851,37 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
}
}
if (color_mask != 0) {
UINT32 fbcolor_tmp;
UINT32 ct,ft,w;
fbcolor_tmp = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
*addr = (fbcolor & ~color_mask) | (fbcolor_tmp & color_mask);
ct = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
ft = (fb[3] << 24) | (fb[2] << 16) | (fb[1] << 8) | fb[0];
w = (ft & ~color_mask) | (ct & color_mask);
switch (colorformat_rendertarget) {
case NV2A_COLOR_FORMAT_R5G6B5:
w = ((w >> 8) & 0xf800) + ((w >> 5) & 0x7e0) + ((w >> 3) & 0x1f);
*((UINT16 *)addr) = (UINT16)w;
break;
case NV2A_COLOR_FORMAT_X8R8G8B8:
*((UINT32 *)addr) = w;
break;
case NV2A_COLOR_FORMAT_A8R8G8B8:
*((UINT32 *)addr) = w;
break;
case NV2A_COLOR_FORMAT_B8:
*addr = (UINT8)w;
break;
}
}
if (depth_write_enabled)
dep = depth;
deptsten = (dep << 8) | sten;
*daddr = deptsten;
if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z24S8) {
deptsten = (dep << 8) | sten;
*daddr32 = deptsten;
}
else if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z16) {
deptsten = dep >> 8;
*daddr16 = (UINT16)deptsten;
}
}
void nv2a_renderer::render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
@ -2238,6 +2329,83 @@ void nv2a_renderer::convert_vertices_poly(vertex_nv *source, vertex_t *destinati
}
}
void nv2a_renderer::clear_depth_buffer(int what, UINT32 value)
{
int m;
m = antialias_control;
if (antialiasing_rendertarget != 0)
m = 2;
else
m = 1;
if (what == 3) {
if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z24S8) {
UINT32 *p, *pl;
int x, y;
pl = (UINT32 *)depthbuffer;
for (y = (limits_rendertarget.bottom() + 1) * m; y != 0; y--) {
p = pl;
for (x = (limits_rendertarget.right() + 1) * m; x != 0; x--) {
*p = value;
p++;
}
pl = pl + pitch_rendertarget / 4;
}
}
else if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z16) {
UINT16 *p, *pl;
int x, y;
pl = (UINT16 *)depthbuffer;
for (y = (limits_rendertarget.bottom() + 1) * m; y != 0; y--) {
p = pl;
for (x = (limits_rendertarget.right() + 1) * m; x != 0; x--) {
*p = (UINT16)value;
p++;
}
pl = pl + pitch_rendertarget / 2;
}
}
}
else {
if (depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z24S8) {
UINT32 mask;
UINT32 *p, *pl;
int x, y;
if ((what & 0x03) == 2)
mask = 0x000000ff;
else
mask = 0xffffff00;
value = value & mask;
pl = depthbuffer;
for (y = (limits_rendertarget.bottom() + 1) * m; y != 0; y--) {
p = pl;
for (x = (limits_rendertarget.right() + 1) * m; x != 0; x--) {
*p = (*p & ~mask) | value;
p++;
}
pl = pl + pitch_rendertarget / 4;
}
}
else if ((depthformat_rendertarget == NV2A_RT_DEPTH_FORMAT_Z16) && (what == 1)) {
UINT16 *p, *pl;
int x, y;
pl = (UINT16 *)depthbuffer;
for (y = (limits_rendertarget.bottom() + 1) * m; y != 0; y--) {
p = pl;
for (x = (limits_rendertarget.right() + 1) * m; x != 0; x--) {
*p = (UINT16)value;
p++;
}
pl = pl + pitch_rendertarget / 2;
}
}
}
}
int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen)
{
UINT32 maddress;
@ -2359,6 +2527,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
convert_vertices_poly(vert, xy, 4);
render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
}
wait();
}
else if (type == nv2a_renderer::TRIANGLE_FAN) {
if ((countlen * mult + indexesleft_count) >= 3) {
@ -2405,6 +2574,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
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
}
wait();
}
else if (type == nv2a_renderer::TRIANGLE_STRIP) {
if ((countlen * mult + indexesleft_count) >= 3) {
@ -2432,6 +2602,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
xy[(n + 2) & 3].y = xy[(n + 2) & 3].y + 1.0f;
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
}
wait();
}
}
else {
@ -2519,6 +2690,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
address = address + c * 3;
render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
}
wait();
}
else if (type == nv2a_renderer::TRIANGLE_STRIP) {
vertex_nv vert[4];
@ -2666,6 +2838,10 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
space.write_dword(base + offset, data);
countlen--;
}
if (maddress == 0x1d7c) {
antialias_control = data;
countlen--;
}
if (maddress == 0x1d98) {
countlen--;
}
@ -2675,7 +2851,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
if (maddress == 0x1d94) {
int m;
m = channel[chanel][subchannel].object.method[0x1d7c / 4];
m = antialias_control;
if (antialiasing_rendertarget != 0)
m = 2;
else
@ -2683,22 +2859,29 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
// possible buffers: color, depth, stencil
// clear framebuffer
if (data & 0xf0) {
bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
// clear colors
UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
bm.fill(color);
if (bytespixel_rendertarget == 4) {
bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4);
UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
bm.fill(color);
}
else if (bytespixel_rendertarget == 2) {
bitmap_ind16 bm((UINT16 *)rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 2);
UINT16 color = channel[chanel][subchannel].object.method[0x1d90 / 4] & 0xffff;
bm.fill(color);
}
else if (bytespixel_rendertarget == 1) {
UINT8 color = channel[chanel][subchannel].object.method[0x1d90 / 4] & 0xff;
memset(rendertarget, color, pitch_rendertarget*(limits_rendertarget.bottom() + 1) * m);
}
#ifdef LOG_NV2A
printf("clearscreen\n\r");
#endif
}
if ((data & 0x03) == 3) {
bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
// clear zbuffer and stencil
UINT32 depth_stencil = channel[chanel][subchannel].object.method[0x1d8c / 4];
bm.fill(depth_stencil);
}
else if (((data & 0x03) == 1) || ((data & 0x03) == 2))
logerror("Unsupported clear method parameter %d\n\r", data & 0x03);
clear_depth_buffer(data & 3, channel[chanel][subchannel].object.method[0x1d8c / 4]);
countlen--;
}
if (maddress == 0x0200) {
@ -2720,8 +2903,26 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN
log2width_rendertarget = (data >> 16) & 255;
antialiasing_rendertarget = (data >> 12) & 15;
type_rendertarget = (data >> 8) & 15;
depth_rendertarget = (data >> 4) & 15;
color_rendertarget = (data >> 0) & 15;;
depthformat_rendertarget = (data >> 4) & 15;
colorformat_rendertarget = (data >> 0) & 15;
switch (colorformat_rendertarget) {
case NV2A_COLOR_FORMAT_R5G6B5:
bytespixel_rendertarget = 2;
break;
case NV2A_COLOR_FORMAT_X8R8G8B8:
case NV2A_COLOR_FORMAT_A8R8G8B8:
bytespixel_rendertarget = 4;
break;
case NV2A_COLOR_FORMAT_B8:
bytespixel_rendertarget = 1;
break;
default:
#ifdef LOG_NV2A
printf("Unknown render target color format %d\n\r", colorformat_rendertarget);
#endif
bytespixel_rendertarget = 4;
break;
}
dilate_rendertarget = dilatechose[(log2width_rendertarget << 4) + log2height_rendertarget];
}
if (maddress == 0x020c) {

View File

@ -122,11 +122,8 @@ INPUT_PORTS_END
void xbox_state::hack_eeprom()
{
// 8003b744,3b744=0x90 0x90
/*m_maincpu->space(0).write_byte(0x3b744, 0x90);
m_maincpu->space(0).write_byte(0x3b745, 0x90);
m_maincpu->space(0).write_byte(0x3b766, 0xc9);
m_maincpu->space(0).write_byte(0x3b767, 0xc3);*/
// 8004e5da,4e5da=0xc3
m_maincpu->space(0).write_byte(0x4e5da, 0xc3);
}
/*static const struct {
@ -196,22 +193,23 @@ MACHINE_CONFIG_END
***************************************************************************/
ROM_START( xbox )
ROM_REGION( 0x200, "mcpx", 0 )
ROM_REGION( 0x400, "mcpx", 0 )
// mcpx_1_0.bin is bad, first byte (0x7f) sould be removed and a byte with value 0xee added at the end
ROM_LOAD( "mcpx_1_0.bin", 0, 0x200, CRC(f31429fc) SHA1(a9ecbf8896d10db81594923e485862aa3aac7b58) )
ROM_LOAD( "mcpx_1_1.bin", 0, 0x200, CRC(94ce376b) SHA1(6c875f17f773aaec51eb434068bb6c657c4343c0) )
ROM_LOAD( "mcpx_1_1.bin", 0x200, 0x200, CRC(94ce376b) SHA1(6c875f17f773aaec51eb434068bb6c657c4343c0) )
ROM_REGION( 0x80000, "bios", 0)
ROM_LOAD( "xbox-5530.bin", 0x000000, 0x040000, CRC(9569c4d3) SHA1(40fa73277013be3168135e1768b09623a987ff63) )
ROM_LOAD( "xbox-5713.bin", 0x040000, 0x040000, CRC(58fd8173) SHA1(8b7ccc4648ccd78cdb7b65cfca09621eaf2d4238) )
ROM_COPY( "mcpx", 0, 0x7fe00, 0x200 )
ROM_REGION( 0x100000, "bios", 0)
ROM_LOAD( "4134_1024k.bin", 0x000000, 0x100000, CRC(49d8055a) SHA1(d46cef771a63dc8024fe36d7ab5b959087ac999f) )
ROM_COPY( "mcpx", 1, 0x7fe00, 0x1ff)
ROM_REGION( 0x1000000, "tbp", 0 ) // To Be Processed, of course
ROM_LOAD( "3944_1024k.bin", 0x000000, 0x100000, CRC(32a9ecb6) SHA1(67054fc88bda94e33e86f1b19be60efec0724fb6) )
ROM_LOAD( "4034_1024k.bin", 0x000000, 0x100000, CRC(0d6fc88f) SHA1(ab676b712204fb1728bf89f9cd541a8f5a64ab97) )
ROM_LOAD( "4134_1024k.bin", 0x000000, 0x100000, CRC(49d8055a) SHA1(d46cef771a63dc8024fe36d7ab5b959087ac999f) )
ROM_LOAD( "4817_1024k.bin", 0x000000, 0x100000, CRC(3f30863a) SHA1(dc955bd4d3ca71e01214a49e5d0aba615270c03c) )
ROM_LOAD( "5101_256k.bin", 0x000000, 0x040000, CRC(e8a9224e) SHA1(5108e1025f48071c07a6823661d708c66dee97a9) )
ROM_LOAD( "xbox-5530.bin", 0x000000, 0x040000, CRC(9569c4d3) SHA1(40fa73277013be3168135e1768b09623a987ff63) )
ROM_LOAD( "xbox-5713.bin", 0x040000, 0x040000, CRC(58fd8173) SHA1(8b7ccc4648ccd78cdb7b65cfca09621eaf2d4238) )
ROM_LOAD( "5838_256k.bin", 0x000000, 0x040000, CRC(5be2413d) SHA1(b9489e883c650b5e5fe2f83a32237dbf74f0e9f1) )
ROM_END
// See src/emu/gamedrv.h for details