From dbb50ed6344b025387c7a3858e4bf6c6b52aacb1 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Fri, 21 Dec 2007 16:12:20 +0000 Subject: Zeus hardware: * Cleaned up zeus wave RAM accessors. * Changed rendering code to allow for greater parallelism on multicore systems. * Removed some vestigial zeus 2 hacks. * Reduced visible area to remove artifacts. * Made right/bottom vertices inclusive to fix some gapping issues. * Fixed invasn lightgun offset. * Marked invasn as playable. Zeus 2 hardware: * Fixed ROM loading, added banking support. * Separated zeus 2 video implementation from zeus implementation. * Implemented direct pixel accesses; enough to get startup screens to show. ADSP-2100: * Properly documented ADSP-2104 internal memory map. --- .gitattributes | 1 + src/emu/cpu/adsp2100/adsp2100.c | 27 +- src/mame/drivers/midzeus.c | 91 ++++-- src/mame/includes/midzeus.h | 3 + src/mame/mame.mak | 2 +- src/mame/video/midzeus.c | 418 ++++++++++++--------------- src/mame/video/midzeus2.c | 615 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 889 insertions(+), 268 deletions(-) create mode 100644 src/mame/video/midzeus2.c diff --git a/.gitattributes b/.gitattributes index 2cdc389cad0..b9eadf9f7c7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2900,6 +2900,7 @@ src/mame/video/midtunit.c svneol=native#text/plain src/mame/video/midvunit.c svneol=native#text/plain src/mame/video/midyunit.c svneol=native#text/plain src/mame/video/midzeus.c svneol=native#text/plain +src/mame/video/midzeus2.c svneol=native#text/plain src/mame/video/mikie.c svneol=native#text/plain src/mame/video/mitchell.c svneol=native#text/plain src/mame/video/mjkjidai.c svneol=native#text/plain diff --git a/src/emu/cpu/adsp2100/adsp2100.c b/src/emu/cpu/adsp2100/adsp2100.c index 2f0680c10b1..2d2d9a4b0da 100644 --- a/src/emu/cpu/adsp2100/adsp2100.c +++ b/src/emu/cpu/adsp2100/adsp2100.c @@ -27,8 +27,8 @@ 3c00-3fff = 1k Internal Control regs 3c00-3fff = 1k Internal Control regs - For ADSP-2105, ADSP-2115, ADSP-2104 - ----------------------------------- + For ADSP-2105, ADSP-2115 + ------------------------ MMAP = 0 MMAP = 1 @@ -50,6 +50,29 @@ 3c00-3fff = 1k Internal Control regs 3c00-3fff = 1k Internal Control regs + For ADSP-2104 + ------------- + + MMAP = 0 MMAP = 1 + + Automatic boot loading No auto boot loading + + Program Space: Program Space: + 0000-01ff = 512 Internal RAM (booted) 0000-37ff = 14k External access + 0400-07ff = 1k Reserved 3800-3bff = 1k Internal RAM + 0800-3fff = 14k External access 3c00-3fff = 1k Reserved + + Data Space: Data Space: + 0000-03ff = 1k External DWAIT0 0000-03ff = 1k External DWAIT0 + 0400-07ff = 1k External DWAIT1 0400-07ff = 1k External DWAIT1 + 0800-2fff = 10k External DWAIT2 0800-2fff = 10k External DWAIT2 + 3000-33ff = 1k External DWAIT3 3000-33ff = 1k External DWAIT3 + 3400-37ff = 1k External DWAIT4 3400-37ff = 1k External DWAIT4 + 3800-38ff = 256 Internal RAM 3800-38ff = 256 Internal RAM + 3a00-3bff = 512 Reserved 3a00-3bff = 512 Reserved + 3c00-3fff = 1k Internal Control regs 3c00-3fff = 1k Internal Control regs + + For ADSP-2181 ------------- diff --git a/src/mame/drivers/midzeus.c b/src/mame/drivers/midzeus.c index ed45dd24f2c..32dadf4aab4 100644 --- a/src/mame/drivers/midzeus.c +++ b/src/mame/drivers/midzeus.c @@ -27,7 +27,7 @@ #define BEAM_DY 3 #define BEAM_DX 3 -#define BEAM_XOFFS 20 /* table in the code indicates an offset of 20 with a beam height of 7 */ +#define BEAM_XOFFS 40 /* table in the code indicates an offset of 20 with a beam height of 7 */ static UINT32 gun_control; static UINT8 gun_irq_state; @@ -138,6 +138,7 @@ static WRITE32_HANDLER( tms32031_control_w ) } + /************************************* * * Lightgun handling @@ -146,6 +147,7 @@ static WRITE32_HANDLER( tms32031_control_w ) static void update_gun_irq(void) { + /* low 2 bits of gun_control seem to enable IRQs */ if (gun_irq_state & gun_control & 0x03) cpunum_set_input_line(0, 3, ASSERT_LINE); else @@ -158,9 +160,11 @@ static TIMER_CALLBACK( invasn_gun_callback ) int player = param; int beamy = video_screen_get_vpos(0); + /* set the appropriate IRQ in the internal gun control and update */ gun_irq_state |= 0x01 << player; update_gun_irq(); + /* generate another interrupt on the next scanline while we are within the BEAM_DY */ beamy++; if (beamy <= machine->screen[0].visarea.max_y && beamy <= gun_y[player] + BEAM_DY) timer_adjust(gun_timer[player], video_screen_get_time_until_pos(0, beamy, MAX(0, gun_x[player] - BEAM_DX)), player, attotime_never); @@ -197,6 +201,7 @@ static WRITE32_HANDLER( invasn_gun_w ) } } + static READ32_HANDLER( invasn_gun_r ) { int beamx = video_screen_get_hpos(0); @@ -215,6 +220,7 @@ static READ32_HANDLER( invasn_gun_r ) } + /************************************* * * Memory maps @@ -232,9 +238,19 @@ static READ32_HANDLER( unknown_8d0000_r ) } static WRITE32_HANDLER( unknown_8d0000_w ) { - logerror("%06X:write to %06X = %08X\n", activecpu_get_pc(), 0x8d0000 + offset, data); +// logerror("%06X:write to %06X = %08X\n", activecpu_get_pc(), 0x8d0000 + offset, data); COMBINE_DATA(&unknown_8d0000[offset]); } +static WRITE32_HANDLER( unknown_9d0000_w ) +{ +// logerror("%06X:write to %06X = %08X\n", activecpu_get_pc(), 0x9d0000 + offset, data); + COMBINE_DATA(&unknown_8d0000[offset]); +} + +static WRITE32_HANDLER( rombank_select_w ) +{ + memory_set_bank(1, data); +} static ADDRESS_MAP_START( zeus_map, ADDRESS_SPACE_PROGRAM, 32 ) @@ -245,6 +261,7 @@ static ADDRESS_MAP_START( zeus_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x880000, 0x8803ff) AM_READWRITE(zeus_r, zeus_w) AM_BASE(&zeusbase) AM_RANGE(0x8d0000, 0x8d0003) AM_READWRITE(unknown_8d0000_r, unknown_8d0000_w) AM_BASE(&unknown_8d0000) AM_RANGE(0x990000, 0x99000f) AM_READWRITE(midway_ioasic_r, midway_ioasic_w) + AM_RANGE(0x9d0000, 0x9d0001) AM_WRITE(unknown_9d0000_w) AM_RANGE(0x9e0000, 0x9e0000) AM_WRITENOP // watchdog? AM_RANGE(0x9f0000, 0x9f7fff) AM_READWRITE(cmos_r, cmos_w) AM_BASE(&generic_nvram32) AM_SIZE(&generic_nvram_size) AM_RANGE(0x9f8000, 0x9f8000) AM_WRITE(cmos_protect_w) @@ -259,11 +276,13 @@ static ADDRESS_MAP_START( zeus2_map, ADDRESS_SPACE_PROGRAM, 32 ) AM_RANGE(0x808000, 0x80807f) AM_READWRITE(tms32031_control_r, tms32031_control_w) AM_BASE(&tms32031_control) AM_RANGE(0x880000, 0x8801ff) AM_READWRITE(zeus2_r, zeus2_w) AM_BASE(&zeusbase) AM_RANGE(0x8d0000, 0x8d0003) AM_READWRITE(unknown_8d0000_r, unknown_8d0000_w) AM_BASE(&unknown_8d0000) + AM_RANGE(0x8d0005, 0x8d0005) AM_WRITE(rombank_select_w) AM_RANGE(0x990000, 0x99000f) AM_READWRITE(midway_ioasic_r, midway_ioasic_w) AM_RANGE(0x9e0000, 0x9e0000) AM_WRITENOP // watchdog? AM_RANGE(0x9f0000, 0x9f7fff) AM_READWRITE(cmos_r, cmos_w) AM_BASE(&generic_nvram32) AM_SIZE(&generic_nvram_size) AM_RANGE(0x9f8000, 0x9f8000) AM_WRITE(cmos_protect_w) - AM_RANGE(0xa00000, 0xffffff) AM_ROM AM_REGION(REGION_USER1, 0) + AM_RANGE(0xa00000, 0xbfffff) AM_ROM AM_REGION(REGION_USER1, 0) + AM_RANGE(0xc00000, 0xffffff) AM_ROMBANK(1) AM_REGION(REGION_USER2, 0) ADDRESS_MAP_END @@ -717,8 +736,8 @@ static MACHINE_DRIVER_START( midzeus ) /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(512/*+256*/, 278/*+256*/) - MDRV_SCREEN_VISIBLE_AREA(0, 399/*+256*/, 0, 255/*+256*/) + MDRV_SCREEN_SIZE(512, 278) + MDRV_SCREEN_VISIBLE_AREA(0, 399, 0, 255) MDRV_PALETTE_LENGTH(32768) MDRV_VIDEO_START(midzeus) @@ -735,6 +754,12 @@ static MACHINE_DRIVER_START( midzeus2 ) /* basic machine hardware */ MDRV_CPU_MODIFY("main") MDRV_CPU_PROGRAM_MAP(zeus2_map,0) + + /* video hardware */ + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) + + MDRV_VIDEO_START(midzeus2) + MDRV_VIDEO_UPDATE(midzeus2) MACHINE_DRIVER_END @@ -810,23 +835,25 @@ ROM_START( crusnexo ) ROM_LOAD( "exotica.u3", 0x400000, 0x400000, CRC(28a3a13d) SHA1(8d7d641b883df089adefdd144229afef79db9e8a) ) ROM_LOAD( "exotica.u4", 0x800000, 0x400000, CRC(213f7fd8) SHA1(8528d524a62bc41a8e3b39f0dbeeba33c862ee27) ) - ROM_REGION32_LE( 0x3000000, REGION_USER1, 0 ) + ROM_REGION32_LE( 0x0800000, REGION_USER1, 0 ) ROM_LOAD32_WORD( "exotica.u10", 0x0000000, 0x200000, CRC(65450140) SHA1(cad41a2cad48426de01feb78d3f71f768e3fc872) ) ROM_LOAD32_WORD( "exotica.u11", 0x0000002, 0x200000, CRC(e994891f) SHA1(bb088729b665864c7f3b79b97c3c86f9c8f68770) ) ROM_LOAD32_WORD( "exotica.u12", 0x0400000, 0x200000, CRC(21f122b2) SHA1(5473401ec954bf9ab66a8283bd08d17c7960cd29) ) ROM_LOAD32_WORD( "exotica.u13", 0x0400002, 0x200000, CRC(cf9d3609) SHA1(6376891f478185d26370466bef92f0c5304d58d3) ) - ROM_LOAD32_WORD( "exotica.u14", 0x0800000, 0x400000, CRC(84452fc2) SHA1(06d87263f83ef079e6c5fb9de620e0135040c858) ) - ROM_LOAD32_WORD( "exotica.u15", 0x0800002, 0x400000, CRC(b6aaebdb) SHA1(6ede6ea123be6a88d1ff38e90f059c9d1f822d6d) ) - ROM_LOAD32_WORD( "exotica.u16", 0x1000000, 0x400000, CRC(aac6d2a5) SHA1(6c336520269d593b46b82414d9352a3f16955cc3) ) - ROM_LOAD32_WORD( "exotica.u17", 0x1000002, 0x400000, CRC(71cf5404) SHA1(a6eed1a66fb4f4ddd749e4272a2cdb8e3e354029) ) - ROM_LOAD32_WORD( "exotica.u18", 0x1800000, 0x200000, CRC(60cf5caa) SHA1(629870a305802d632bd2681131d1ffc0086280d2) ) - ROM_LOAD32_WORD( "exotica.u19", 0x1800002, 0x200000, CRC(6b919a18) SHA1(20e40e195554146ed1d3fad54f7280823ae89d4b) ) - ROM_LOAD32_WORD( "exotica.u20", 0x1c00002, 0x200000, CRC(4855b68b) SHA1(1f6e557590b2621d0d5c782b95577f1be5cbc51d) ) - ROM_LOAD32_WORD( "exotica.u21", 0x1c00002, 0x200000, CRC(0011b9d6) SHA1(231d768c964a16b905857b0814d758fe93c2eefb) ) - ROM_LOAD32_WORD( "exotica.u22", 0x2000002, 0x400000, CRC(ad6dcda7) SHA1(5c9291753e1659f9adbe7e59fa2d0e030efae5bc) ) - ROM_LOAD32_WORD( "exotica.u23", 0x2000002, 0x400000, CRC(1f103a68) SHA1(3b3acc63a461677cd424e75e7211fa6f063a37ef) ) - ROM_LOAD32_WORD( "exotica.u24", 0x2800002, 0x400000, CRC(6312feef) SHA1(4113e4e5d39c99e8131d41a57c973df475b67d18) ) - ROM_LOAD32_WORD( "exotica.u25", 0x2800002, 0x400000, CRC(b8277b16) SHA1(1355e87affd78e195906aedc9aed9e230374e2bf) ) + + ROM_REGION32_LE( 0x3000000, REGION_USER2, 0 ) + ROM_LOAD32_WORD( "exotica.u14", 0x0000000, 0x400000, CRC(84452fc2) SHA1(06d87263f83ef079e6c5fb9de620e0135040c858) ) + ROM_LOAD32_WORD( "exotica.u15", 0x0000002, 0x400000, CRC(b6aaebdb) SHA1(6ede6ea123be6a88d1ff38e90f059c9d1f822d6d) ) + ROM_LOAD32_WORD( "exotica.u16", 0x0800000, 0x400000, CRC(aac6d2a5) SHA1(6c336520269d593b46b82414d9352a3f16955cc3) ) + ROM_LOAD32_WORD( "exotica.u17", 0x0800002, 0x400000, CRC(71cf5404) SHA1(a6eed1a66fb4f4ddd749e4272a2cdb8e3e354029) ) + ROM_LOAD32_WORD( "exotica.u22", 0x1000000, 0x400000, CRC(ad6dcda7) SHA1(5c9291753e1659f9adbe7e59fa2d0e030efae5bc) ) + ROM_LOAD32_WORD( "exotica.u23", 0x1000002, 0x400000, CRC(1f103a68) SHA1(3b3acc63a461677cd424e75e7211fa6f063a37ef) ) + ROM_LOAD32_WORD( "exotica.u24", 0x1800000, 0x400000, CRC(6312feef) SHA1(4113e4e5d39c99e8131d41a57c973df475b67d18) ) + ROM_LOAD32_WORD( "exotica.u25", 0x1800002, 0x400000, CRC(b8277b16) SHA1(1355e87affd78e195906aedc9aed9e230374e2bf) ) + ROM_LOAD32_WORD( "exotica.u18", 0x2000000, 0x200000, CRC(60cf5caa) SHA1(629870a305802d632bd2681131d1ffc0086280d2) ) + ROM_LOAD32_WORD( "exotica.u19", 0x2000002, 0x200000, CRC(6b919a18) SHA1(20e40e195554146ed1d3fad54f7280823ae89d4b) ) + ROM_LOAD32_WORD( "exotica.u20", 0x2400000, 0x200000, CRC(4855b68b) SHA1(1f6e557590b2621d0d5c782b95577f1be5cbc51d) ) + ROM_LOAD32_WORD( "exotica.u21", 0x2400002, 0x200000, CRC(0011b9d6) SHA1(231d768c964a16b905857b0814d758fe93c2eefb) ) ROM_END @@ -836,17 +863,19 @@ ROM_START( thegrid ) ROM_LOAD( "the_grid.u3", 0x400000, 0x400000, CRC(40be7585) SHA1(e481081edffa07945412a6eab17b4d3e7b42cfd3) ) ROM_LOAD( "the_grid.u4", 0x800000, 0x400000, CRC(7a15c203) SHA1(a0a49dd08bba92402640ed2d1fb4fee112c4ab5f) ) - ROM_REGION32_LE( 0x3000000, REGION_USER1, 0 ) + ROM_REGION32_LE( 0x0800000, REGION_USER1, 0 ) ROM_LOAD32_WORD( "thegrid-11.u10", 0x0000000, 0x100000, CRC(87ea0e9e) SHA1(618de2ca87b7a3e0225d1f7e65f8fc1356de1421) ) ROM_LOAD32_WORD( "thegrid-11.u11", 0x0000002, 0x100000, CRC(73d84b1a) SHA1(8dcfcab5ff64f46f8486e6439a10d91ad26fd48a) ) ROM_LOAD32_WORD( "thegrid-11.u12", 0x0200000, 0x100000, CRC(78d16ca1) SHA1(7b893ec8af2f44d8bc293861fd8622d68d41ccbe) ) ROM_LOAD32_WORD( "thegrid-11.u13", 0x0200002, 0x100000, CRC(8e00b400) SHA1(96581c5da62afc19e6d69b2352b3166665cb9918) ) - ROM_LOAD32_WORD( "the_grid.u18", 0x0400000, 0x400000, CRC(3a3460be) SHA1(e719dae8a2e54584cb6a074ed42e35e3debef2f6) ) - ROM_LOAD32_WORD( "the_grid.u19", 0x0400002, 0x400000, CRC(af262d5b) SHA1(3eb3980fa81a360a70aa74e793b2bc3028f68cf2) ) - ROM_LOAD32_WORD( "the_grid.u20", 0x0c00002, 0x400000, CRC(e6ad1917) SHA1(acab25e1251fd07b374badebe79f6ec1772b3589) ) - ROM_LOAD32_WORD( "the_grid.u21", 0x0c00002, 0x400000, CRC(48c03f8e) SHA1(50790bdae9f2234ffb4914c2c5c16374e3508b47) ) - ROM_LOAD32_WORD( "the_grid.u22", 0x1400002, 0x400000, CRC(84c3a8b6) SHA1(de0dcf9daf7ada7a6952b9e29a29571b2aa9d0b2) ) - ROM_LOAD32_WORD( "the_grid.u23", 0x1400002, 0x400000, CRC(f48ef409) SHA1(79d74b4fe38b06a02ae0351d13d7f0a7ed0f0c87) ) + + ROM_REGION32_LE( 0x3000000, REGION_USER2, 0 ) + ROM_LOAD32_WORD( "the_grid.u18", 0x0000000, 0x400000, CRC(3a3460be) SHA1(e719dae8a2e54584cb6a074ed42e35e3debef2f6) ) + ROM_LOAD32_WORD( "the_grid.u19", 0x0000002, 0x400000, CRC(af262d5b) SHA1(3eb3980fa81a360a70aa74e793b2bc3028f68cf2) ) + ROM_LOAD32_WORD( "the_grid.u20", 0x0800000, 0x400000, CRC(e6ad1917) SHA1(acab25e1251fd07b374badebe79f6ec1772b3589) ) + ROM_LOAD32_WORD( "the_grid.u21", 0x0800002, 0x400000, CRC(48c03f8e) SHA1(50790bdae9f2234ffb4914c2c5c16374e3508b47) ) + ROM_LOAD32_WORD( "the_grid.u22", 0x1000000, 0x400000, CRC(84c3a8b6) SHA1(de0dcf9daf7ada7a6952b9e29a29571b2aa9d0b2) ) + ROM_LOAD32_WORD( "the_grid.u23", 0x1000002, 0x400000, CRC(f48ef409) SHA1(79d74b4fe38b06a02ae0351d13d7f0a7ed0f0c87) ) ROM_END @@ -860,7 +889,7 @@ ROM_END static DRIVER_INIT( mk4 ) { dcs2_init(0, 0); - midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 461/* or 474 */, 94, NULL); + midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 461/* or 474 */, 97, NULL); midway_ioasic_set_shuffle_state(1); } @@ -868,7 +897,7 @@ static DRIVER_INIT( mk4 ) static DRIVER_INIT( invasn ) { dcs2_init(0, 0); - midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 468/* or 488 */, 94, NULL); + midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 468/* or 488 */, 97, NULL); memory_install_readwrite32_handler(0, ADDRESS_SPACE_PROGRAM, 0x9c0000, 0x9c0000, 0, 0, invasn_gun_r, invasn_gun_w); } @@ -876,7 +905,8 @@ static DRIVER_INIT( invasn ) static DRIVER_INIT( crusnexo ) { dcs2_init(0, 0); - midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 461/* unknown */, 94, NULL); + midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 472/* or 476,477,478,110 */, 99, NULL); + memory_configure_bank(1, 0, 3, memory_region(REGION_USER2), 0x400000*4); } @@ -884,7 +914,8 @@ static DRIVER_INIT( thegrid ) { cpunum_set_input_line(0, INPUT_LINE_HALT, ASSERT_LINE); dcs2_init(0, 0); - midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 461/* unknown */, 94, NULL); + midway_ioasic_init(MIDWAY_IOASIC_STANDARD, 474/* or 491 */, 99, NULL); + memory_configure_bank(1, 0, 3, memory_region(REGION_USER2), 0x400000*4); } @@ -897,6 +928,6 @@ static DRIVER_INIT( thegrid ) GAME( 1997, mk4, 0, midzeus, mk4, mk4, ROT0, "Midway", "Mortal Kombat 4 (3.0)", GAME_IMPERFECT_GRAPHICS ) GAME( 1997, mk4a, mk4, midzeus, mk4, mk4, ROT0, "Midway", "Mortal Kombat 4 (2.1)", GAME_IMPERFECT_GRAPHICS ) -GAME( 1999, invasn, 0, midzeus, invasn, invasn, ROT0, "Midway", "Invasion (Midway)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS ) +GAME( 1999, invasn, 0, midzeus, invasn, invasn, ROT0, "Midway", "Invasion (Midway)", GAME_IMPERFECT_GRAPHICS ) GAME( 1999, crusnexo, 0, midzeus2, crusnexo, crusnexo, ROT0, "Midway", "Cruis'n Exotica", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND ) GAME( 2001, thegrid, 0, midzeus2, thegrid, thegrid, ROT0, "Midway", "The Grid (version 1.1)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND ) diff --git a/src/mame/includes/midzeus.h b/src/mame/includes/midzeus.h index 9a9578552d0..0547246ce0e 100644 --- a/src/mame/includes/midzeus.h +++ b/src/mame/includes/midzeus.h @@ -17,6 +17,9 @@ VIDEO_UPDATE( midzeus ); READ32_HANDLER( zeus_r ); WRITE32_HANDLER( zeus_w ); +VIDEO_START( midzeus2 ); +VIDEO_UPDATE( midzeus2 ); + READ32_HANDLER( zeus2_r ); WRITE32_HANDLER( zeus2_w ); diff --git a/src/mame/mame.mak b/src/mame/mame.mak index c0591f2e011..ebd672ca450 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -931,7 +931,7 @@ $(MAMEOBJ)/midway.a: \ $(DRIVERS)/midwunit.o $(MACHINE)/midwunit.o \ $(DRIVERS)/midxunit.o \ $(DRIVERS)/midyunit.o $(MACHINE)/midyunit.o $(VIDEO)/midyunit.o \ - $(DRIVERS)/midzeus.o $(VIDEO)/midzeus.o \ + $(DRIVERS)/midzeus.o $(VIDEO)/midzeus.o $(VIDEO)/midzeus2.o \ $(DRIVERS)/omegrace.o \ $(DRIVERS)/seattle.o \ $(DRIVERS)/tmaster.o \ diff --git a/src/mame/video/midzeus.c b/src/mame/video/midzeus.c index b79d19db3a3..83935c9d8b7 100644 --- a/src/mame/video/midzeus.c +++ b/src/mame/video/midzeus.c @@ -34,8 +34,8 @@ typedef struct _poly_extra_data poly_extra_data; struct _poly_extra_data { - const UINT64 * palbase; - const UINT64 * texbase; + const void * palbase; + const void * texbase; UINT16 solidcolor; INT16 zoffset; UINT16 transcolor; @@ -62,20 +62,13 @@ static UINT8 zeus_fifo_words; static INT16 zeus_matrix[3][3]; static INT32 zeus_point[3]; static INT16 zeus_light[3]; -static UINT64 *zeus_renderbase; -static UINT64 *zeus_palbase; +static void *zeus_renderbase; +static void *zeus_palbase; static int zeus_enable_logging; static UINT32 zeus_objdata; static rectangle zeus_cliprect; -static UINT64 *waveram[2]; - -static UINT8 single_step; -static poly_extra_data single_step_extra; -static UINT32 single_step_val1; -static UINT32 single_step_val2; -static INT32 single_step_dx, single_step_dy; -static UINT8 single_step_advance; +static void *waveram[2]; @@ -108,106 +101,126 @@ static void log_waveram(UINT32 length_and_base); /************************************* * - * Inlines + * Macros * *************************************/ -INLINE UINT64 *waveram_ptr_from_block_addr(UINT8 bank, UINT32 addr) -{ - return &waveram[bank][(addr % WAVERAM_WIDTH) + ((addr >> 12) % WAVERAM_HEIGHT) * WAVERAM_WIDTH]; -} +#define WAVERAM_BLOCK(bank, blocknum) ((void *)((UINT8 *)waveram[bank] + 8 * (blocknum))) +#define WAVERAM_PTR8(base, bytenum) ((UINT8 *)(base) + BYTE4_XOR_LE(bytenum)) +#define WAVERAM_READ8(base, bytenum) (*WAVERAM_PTR8(base, bytenum)) +#define WAVERAM_WRITE8(base, bytenum, data) do { *WAVERAM_PTR8(base, bytenum) = (data); } while (0) -INLINE UINT64 *waveram_ptr_from_expanded_addr(UINT8 bank, UINT32 addr) -{ - return &waveram[bank][(addr % WAVERAM_WIDTH) + ((addr >> 16) % WAVERAM_HEIGHT) * WAVERAM_WIDTH]; -} +#define WAVERAM_PTR16(base, wordnum) ((UINT16 *)(base) + BYTE_XOR_LE(wordnum)) +#define WAVERAM_READ16(base, wordnum) (*WAVERAM_PTR16(base, wordnum)) +#define WAVERAM_WRITE16(base, wordnum, data) do { *WAVERAM_PTR16(base, wordnum) = (data); } while (0) + +#define WAVERAM_PTR32(base, dwordnum) ((UINT32 *)(base) + (dwordnum)) +#define WAVERAM_READ32(base, dwordnum) (*WAVERAM_PTR32(base, dwordnum)) +#define WAVERAM_WRITE32(base, dwordnum, data) do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0) + +#define PIXYX_TO_WORDNUM(y, x) (((y) << 10) | (((x) & 0x1fe) << 1) | ((x) & 1)) +#define DEPTHYX_TO_WORDNUM(y, x) (PIXYX_TO_WORDNUM(y, x) | 2) + +#define WAVERAM_PTRPIX(base, y, x) WAVERAM_PTR16(base, PIXYX_TO_WORDNUM(y, x)) +#define WAVERAM_READPIX(base, y, x) (*WAVERAM_PTRPIX(base, y, x)) +#define WAVERAM_WRITEPIX(base, y, x, color) do { *WAVERAM_PTRPIX(base, y, x) = (color); } while (0) + +#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_WORDNUM(y, x)) +#define WAVERAM_READDEPTH(base, y, x) (*WAVERAM_PTRDEPTH(base, y, x)) +#define WAVERAM_WRITEDEPTH(base, y, x, color) do { *WAVERAM_PTRDEPTH(base, y, x) = (color); } while (0) -INLINE UINT64 *waveram_ptr_from_texture_addr(UINT8 bank, UINT32 addr, int width) + +/************************************* + * + * Inlines for block addressing + * + *************************************/ + +INLINE void *waveram_ptr_from_block_addr(UINT8 bank, UINT32 addr) { - return &waveram[bank][((addr & ~1) * width) / 8]; + UINT32 blocknum = (addr % WAVERAM_WIDTH) + ((addr >> 12) % WAVERAM_HEIGHT) * WAVERAM_WIDTH; + return WAVERAM_BLOCK(bank, blocknum); } +INLINE void *waveram_ptr_from_expanded_addr(UINT8 bank, UINT32 addr) +{ + UINT32 blocknum = (addr % WAVERAM_WIDTH) + ((addr >> 16) % WAVERAM_HEIGHT) * WAVERAM_WIDTH; + return WAVERAM_BLOCK(bank, blocknum); +} -INLINE UINT16 *waveram_pixel_ptr(UINT64 *base, int y, int x, UINT16 **depthptr) +INLINE void *waveram_ptr_from_texture_addr(UINT8 bank, UINT32 addr, int width) { - UINT16 *baseptr = (UINT16 *)base + y * 512*2 + (x & ~1) * 2; - if (depthptr != NULL) - *depthptr = baseptr + BYTE4_XOR_LE((x & 1) + 2); - return baseptr + BYTE4_XOR_LE(x & 1); + UINT32 blocknum = ((addr & ~1) * width) / 8; + return WAVERAM_BLOCK(bank, blocknum); } + +/************************************* + * + * Inlines for rendering + * + *************************************/ + INLINE void waveram_plot(int y, int x, UINT16 color) { - if (x >= 0 && x < 400 && y >= 0 && y < 256) - { - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, y, x, NULL); - *ptr = color; - } + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); } - INLINE void waveram_plot_depth(int y, int x, UINT16 color, UINT16 depth) { - if (x >= 0 && x < 400 && y >= 0 && y < 256) + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) { - UINT16 *depthptr; - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, y, x, &depthptr); - *ptr = color; - *depthptr = depth; + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth); } } - INLINE void waveram_plot_check_depth(int y, int x, UINT16 color, UINT16 depth) { - if (x >= 0 && x < 400 && y >= 0 && y < 256) + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) { - UINT16 *depthptr; - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, y, x, &depthptr); + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x); if (depth <= *depthptr) { - *ptr = color; + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); *depthptr = depth; } } } - INLINE void waveram_plot_check_depth_nowrite(int y, int x, UINT16 color, UINT16 depth) { - if (x >= 0 && x < 400 && y >= 0 && y < 256) + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) { - UINT16 *depthptr; - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, y, x, &depthptr); + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x); if (depth <= *depthptr) - *ptr = color; + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); } } -INLINE UINT8 get_texel_8bit(const UINT64 *base, int y, int x, int width) -{ - const UINT8 *base8 = (const UINT8 *)base; - base8 += BYTE8_XOR_LE((y / 2) * (width * 2) + (x / 4) * 8 + (y & 1) * 4 + (x & 3)); - return *base8; -} +/************************************* + * + * Inlines for texel accesses + * + *************************************/ -INLINE UINT8 get_texel_4bit(const UINT64 *base, int y, int x, int width) +INLINE UINT8 get_texel_8bit(const void *base, int y, int x, int width) { - const UINT8 *base8 = (const UINT8 *)base; - base8 += BYTE8_XOR_LE((y / 2) * (width * 2) + (x / 8) * 8 + (y & 1) * 4 + ((x / 2) & 3)); - return (*base8 >> (4 * (x & 1))) & 0x0f; + UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 4) << 3) + ((y & 1) << 2) + (x & 3); + return WAVERAM_READ8(base, byteoffs); } -INLINE UINT16 get_palette_entry(const UINT64 *palbase, UINT8 texel) +INLINE UINT8 get_texel_4bit(const void *base, int y, int x, int width) { - const UINT16 *base16 = (const UINT16 *)palbase; - return base16[BYTE4_XOR_LE(texel)]; + UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 8) << 3) + ((y & 1) << 2) + ((x / 2) & 3); + return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f; } @@ -223,17 +236,17 @@ VIDEO_START( midzeus ) int i; /* allocate memory for "wave" RAM */ - waveram[0] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * sizeof(*waveram[0])); - waveram[1] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * sizeof(*waveram[1])); - state_save_register_global_pointer(waveram[0], WAVERAM_WIDTH * WAVERAM_HEIGHT); - state_save_register_global_pointer(waveram[1], WAVERAM_WIDTH * WAVERAM_HEIGHT); + waveram[0] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * 8); + waveram[1] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * 8); + state_save_register_global_pointer(((UINT32 *)waveram[0]), WAVERAM_WIDTH * WAVERAM_HEIGHT * 8/4); + state_save_register_global_pointer(((UINT32 *)waveram[1]), WAVERAM_WIDTH * WAVERAM_HEIGHT * 8/4); /* initialize a 5-5-5 palette */ for (i = 0; i < 32768; i++) palette_set_color_rgb(machine, i, pal5bit(i >> 10), pal5bit(i >> 5), pal5bit(i >> 0)); /* initialize polygon engine */ - poly = poly_alloc(1000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS); + poly = poly_alloc(10000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS); /* we need to cleanup on exit */ add_exit_callback(machine, exit_handler); @@ -274,45 +287,18 @@ VIDEO_UPDATE( midzeus ) { int x, y; + poly_wait(poly, "VIDEO_UPDATE"); + /* normal update case */ if (!input_code_pressed(KEYCODE_W)) { - UINT64 *base = waveram_ptr_from_expanded_addr(1, zeusbase[0xcc]); + const void *base = waveram_ptr_from_expanded_addr(1, zeusbase[0xcc]); int xoffs = machine->screen[screen].visarea.min_x; for (y = cliprect->min_y; y <= cliprect->max_y; y++) { UINT16 *dest = (UINT16 *)bitmap->base + y * bitmap->rowpixels; for (x = cliprect->min_x; x <= cliprect->max_x; x++) - dest[x] = *waveram_pixel_ptr(base, y, x - xoffs, NULL); - } - - if (single_step) - { - int texwshift = ((single_step_val2 >> 6) + single_step_dx) & 7; - int texwidth = 512 >> texwshift; - int texdepth = (single_step_val2 & 0x20) ? 8 : 4; - const UINT64 *texbase = waveram_ptr_from_texture_addr(0, single_step_val1, texwidth); - int x, y; - - for (y = 0; y < 256; y++) - { - UINT16 *dest = (UINT16 *)bitmap->base + y * bitmap->rowpixels + 400; - for (x = 0; x < 256; x++) - { - if (x < texwidth) - dest[x] = get_palette_entry(single_step_extra.palbase, (texdepth == 8) ? get_texel_8bit(texbase, y, x, texwidth) : get_texel_4bit(texbase, y, x, texwidth)); - else - dest[x] = 0; - } - } - - popmessage("val1=%08X val2=%08X\nwidth=%d depth=%d", single_step_val1, single_step_val2, texwidth, texdepth); - - if (input_code_pressed(KEYCODE_UP)) { single_step_dy--; while (input_code_pressed(KEYCODE_UP)) ; } - if (input_code_pressed(KEYCODE_DOWN)) { single_step_dy++; while (input_code_pressed(KEYCODE_DOWN)) ; } - if (input_code_pressed(KEYCODE_LEFT)) { single_step_dx--; while (input_code_pressed(KEYCODE_LEFT)) ; } - if (input_code_pressed(KEYCODE_RIGHT)) { single_step_dx++; while (input_code_pressed(KEYCODE_RIGHT)) ; } - if (input_code_pressed(KEYCODE_LSHIFT)) { single_step_advance = TRUE; while (input_code_pressed(KEYCODE_LSHIFT)) ; } + dest[x] = WAVERAM_READPIX(base, y, x - xoffs); } } @@ -321,7 +307,7 @@ VIDEO_UPDATE( midzeus ) { static int yoffs = 0; static int width = 256; - const UINT64 *base; + const void *base; if (input_code_pressed(KEYCODE_DOWN)) yoffs += input_code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; if (input_code_pressed(KEYCODE_UP)) yoffs -= input_code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; @@ -361,16 +347,6 @@ READ32_HANDLER( zeus_r ) switch (offset & ~1) { - case 0x00: - // crusnexo wants bit 0x20 to be non-zero - result = 0x20; - break; - - case 0x51: - // crusnexo expects a reflection of the data at 0x08 here (b425) - result = zeusbase[0x08]; - break; - case 0xf0: result = video_screen_get_hpos(0); logit = 0; @@ -451,19 +427,6 @@ WRITE32_HANDLER( zeus_w ) } -READ32_HANDLER( zeus2_r ) -{ - logerror("%06X:zeus_r(%02X)\n", activecpu_get_pc(), offset * 2); - return zeus_r(offset * 2, 0); -} - - -WRITE32_HANDLER( zeus2_w ) -{ - logerror("%06X:zeus_w(%02X) = %08X\n", activecpu_get_pc(), offset * 2, data); -} - - /************************************* * @@ -686,15 +649,15 @@ static void zeus_register_update(offs_t offset) if ((offset == 0xb0 && (zeusbase[0xb6] & 0x02000000) == 0) || (offset == 0xb2 && (zeusbase[0xb6] & 0x02000000) != 0)) { - UINT16 *dest = (UINT16 *)waveram_ptr_from_expanded_addr(zeusbase[0xb6] >> 31, zeusbase[0xb4]); + void *dest = waveram_ptr_from_expanded_addr(zeusbase[0xb6] >> 31, zeusbase[0xb4]); if (zeusbase[0xb6] & 0x00100000) - dest[BYTE4_XOR_LE(0)] = zeusbase[0xb0]; + WAVERAM_WRITE16(dest, 0, zeusbase[0xb0]); if (zeusbase[0xb6] & 0x00200000) - dest[BYTE4_XOR_LE(1)] = zeusbase[0xb0] >> 16; + WAVERAM_WRITE16(dest, 1, zeusbase[0xb0] >> 16); if (zeusbase[0xb6] & 0x00400000) - dest[BYTE4_XOR_LE(2)] = zeusbase[0xb2]; + WAVERAM_WRITE16(dest, 2, zeusbase[0xb2]); if (zeusbase[0xb6] & 0x00800000) - dest[BYTE4_XOR_LE(3)] = zeusbase[0xb2] >> 16; + WAVERAM_WRITE16(dest, 3, zeusbase[0xb2] >> 16); if (zeusbase[0xb6] & 0x00020000) zeusbase[0xb4]++; } @@ -704,9 +667,10 @@ static void zeus_register_update(offs_t offset) case 0xb4: if (zeusbase[0xb6] & 0x00010000) { - const UINT64 *src = waveram_ptr_from_expanded_addr(zeusbase[0xb6] >> 31, zeusbase[0xb4]); - zeusbase[0xb0] = *src; - zeusbase[0xb2] = *src >> 32; + const UINT32 *src = waveram_ptr_from_expanded_addr(zeusbase[0xb6] >> 31, zeusbase[0xb4]); + poly_wait(poly, "vram_read"); + zeusbase[0xb0] = WAVERAM_READ32(src, 0); + zeusbase[0xb2] = WAVERAM_READ32(src, 1); } break; @@ -723,7 +687,7 @@ static void zeus_register_update(offs_t offset) rectangle visarea; visarea.min_x = zeusbase[0xc6] & 0xffff; - visarea.max_x = htotal - 1; + visarea.max_x = htotal - 3; visarea.min_y = 0; visarea.max_y = zeusbase[0xc8] & 0xffff; if (htotal > 0 && vtotal > 0 && visarea.min_x < visarea.max_x && visarea.max_y < vtotal) @@ -738,11 +702,7 @@ static void zeus_register_update(offs_t offset) case 0xcc: video_screen_update_partial(0, video_screen_get_vpos(0)); - log_fifo = input_code_pressed(KEYCODE_L); -// single_step = input_code_pressed(KEYCODE_S); - if (single_step) - popmessage("Single Step"); break; case 0xe0: @@ -809,95 +769,71 @@ static int zeus_fifo_process(const UINT32 *data, int numwords) /* 0x1C: write matrix and translation vector */ case 0x1c: + + /* single matrix form */ if ((data[0] & 0xffff) != 0x7fff) { + /* requires 8 words total */ if (numwords < 8) return FALSE; if (log_fifo) { log_fifo_command(data, numwords, ""); logerror("\n\t\tmatrix ( %04X %04X %04X ) ( %04X %04X %04X ) ( %04X %04X %04X )\n\t\tvector %8.2f %8.2f %8.5f\n", - data[2] & 0xffff, - data[2] >> 16, - data[0] & 0xffff, - data[3] & 0xffff, - data[3] >> 16, - data[1] >> 16, - data[4] & 0xffff, - data[4] >> 16, - data[1] & 0xffff, + data[2] & 0xffff, data[2] >> 16, data[0] & 0xffff, + data[3] & 0xffff, data[3] >> 16, data[1] >> 16, + data[4] & 0xffff, data[4] >> 16, data[1] & 0xffff, (float)(INT32)data[5] * (1.0f / 65536.0f), (float)(INT32)data[6] * (1.0f / 65536.0f), (float)(INT32)data[7] * (1.0f / (65536.0f * 512.0f))); } - zeus_matrix[0][0] = data[2]; - zeus_matrix[0][1] = data[2] >> 16; - zeus_matrix[0][2] = data[0]; - zeus_matrix[1][0] = data[3]; - zeus_matrix[1][1] = data[3] >> 16; - zeus_matrix[1][2] = data[1] >> 16; - zeus_matrix[2][0] = data[4]; - zeus_matrix[2][1] = data[4] >> 16; - zeus_matrix[2][2] = data[1]; + /* extract the matrix from the raw data */ + zeus_matrix[0][0] = data[2]; zeus_matrix[0][1] = data[2] >> 16; zeus_matrix[0][2] = data[0]; + zeus_matrix[1][0] = data[3]; zeus_matrix[1][1] = data[3] >> 16; zeus_matrix[1][2] = data[1] >> 16; + zeus_matrix[2][0] = data[4]; zeus_matrix[2][1] = data[4] >> 16; zeus_matrix[2][2] = data[1]; + /* extract the translation point from the raw data */ zeus_point[0] = data[5]; zeus_point[1] = data[6]; zeus_point[2] = data[7]; } + + /* double matrix form */ else { INT16 matrix1[3][3]; INT16 matrix2[3][3]; + + /* requires 13 words total */ if (numwords < 13) return FALSE; if (log_fifo) { log_fifo_command(data, numwords, ""); logerror("\n\t\tmatrix ( %04X %04X %04X ) ( %04X %04X %04X ) ( %04X %04X %04X )\n\t\tmatrix ( %04X %04X %04X ) ( %04X %04X %04X ) ( %04X %04X %04X )\n\t\tvector %8.2f %8.2f %8.5f\n", - data[3] & 0xffff, - data[3] >> 16, - data[7] & 0xffff, - data[5] & 0xffff, - data[6] & 0xffff, - data[2] >> 16, - data[1] & 0xffff, - data[1] >> 16, - data[2] & 0xffff, - data[4] & 0xffff, - data[4] >> 16, - data[5] >> 16, - data[8] & 0xffff, - data[8] >> 16, - data[6] >> 16, - data[9] & 0xffff, - data[9] >> 16, - data[7] >> 16, + data[4] & 0xffff, data[4] >> 16, data[5] >> 16, + data[8] & 0xffff, data[8] >> 16, data[6] >> 16, + data[9] & 0xffff, data[9] >> 16, data[7] >> 16, + data[1] & 0xffff, data[2] & 0xffff, data[3] & 0xffff, + data[1] >> 16, data[2] >> 16, data[3] >> 16, + data[5] & 0xffff, data[6] & 0xffff, data[7] & 0xffff, (float)(INT32)data[10] * (1.0f / 65536.0f), (float)(INT32)data[11] * (1.0f / 65536.0f), (float)(INT32)data[12] * (1.0f / (65536.0f * 512.0f))); } - matrix1[0][0] = data[4]; - matrix1[0][1] = data[4] >> 16; - matrix1[0][2] = data[5] >> 16; - matrix1[1][0] = data[8]; - matrix1[1][1] = data[8] >> 16; - matrix1[1][2] = data[6] >> 16; - matrix1[2][0] = data[9]; - matrix1[2][1] = data[9] >> 16; - matrix1[2][2] = data[7] >> 16; + /* extract the first matrix from the raw data */ + matrix1[0][0] = data[4]; matrix1[0][1] = data[4] >> 16; matrix1[0][2] = data[5] >> 16; + matrix1[1][0] = data[8]; matrix1[1][1] = data[8] >> 16; matrix1[1][2] = data[6] >> 16; + matrix1[2][0] = data[9]; matrix1[2][1] = data[9] >> 16; matrix1[2][2] = data[7] >> 16; - matrix2[0][0] = data[1]; - matrix2[0][1] = data[2]; - matrix2[0][2] = data[3]; - matrix2[1][0] = data[1] >> 16; - matrix2[1][1] = data[2] >> 16; - matrix2[1][2] = data[3] >> 16; - matrix2[2][0] = data[5]; - matrix2[2][1] = data[6]; - matrix2[2][2] = data[7]; + /* extract the second matrix from the raw data */ + matrix2[0][0] = data[1]; matrix2[0][1] = data[2]; matrix2[0][2] = data[3]; + matrix2[1][0] = data[1] >> 16; matrix2[1][1] = data[2] >> 16; matrix2[1][2] = data[3] >> 16; + matrix2[2][0] = data[5]; matrix2[2][1] = data[6]; matrix2[2][2] = data[7]; + /* multiply them together to get the final matrix */ zeus_matrix[0][0] = ((INT64)(matrix1[0][0] * matrix2[0][0]) + (INT64)(matrix1[0][1] * matrix2[1][0]) + (INT64)(matrix1[0][2] * matrix2[2][0])) >> 16; zeus_matrix[0][1] = ((INT64)(matrix1[0][0] * matrix2[0][1]) + (INT64)(matrix1[0][1] * matrix2[1][1]) + (INT64)(matrix1[0][2] * matrix2[2][1])) >> 16; zeus_matrix[0][2] = ((INT64)(matrix1[0][0] * matrix2[0][2]) + (INT64)(matrix1[0][1] * matrix2[1][2]) + (INT64)(matrix1[0][2] * matrix2[2][2])) >> 16; @@ -908,6 +844,7 @@ static int zeus_fifo_process(const UINT32 *data, int numwords) zeus_matrix[2][1] = ((INT64)(matrix1[2][0] * matrix2[0][1]) + (INT64)(matrix1[2][1] * matrix2[1][1]) + (INT64)(matrix1[2][2] * matrix2[2][1])) >> 16; zeus_matrix[2][2] = ((INT64)(matrix1[2][0] * matrix2[0][2]) + (INT64)(matrix1[2][1] * matrix2[1][2]) + (INT64)(matrix1[2][2] * matrix2[2][2])) >> 16; + /* extract the translation point from the raw data */ zeus_point[0] = data[10]; zeus_point[1] = data[11]; zeus_point[2] = data[12]; @@ -924,6 +861,8 @@ static int zeus_fifo_process(const UINT32 *data, int numwords) { log_fifo_command(data, numwords, ""); logerror(" -- additional xyz = %d,%d,%d\n", (INT16)data[0], (INT16)(data[1] >> 16), (INT16)data[1]); + + /* guessing this might be a light source? */ zeus_light[0] = (INT16)data[0]; zeus_light[1] = (INT16)(data[1] >> 16); zeus_light[2] = (INT16)data[1]; @@ -994,21 +933,22 @@ static void zeus_draw_model(UINT32 texdata, int logit) while (zeus_objdata != 0 && !model_done) { - const UINT64 *data = waveram_ptr_from_block_addr(0, zeus_objdata); - int count = (zeus_objdata >> 24) + 1; + const void *base = waveram_ptr_from_block_addr(0, zeus_objdata); + int count = zeus_objdata >> 24; + int curoffs; /* reset the objdata address */ zeus_objdata = 0; /* loop until we run out of data */ - while (count--) + for (curoffs = 0; curoffs <= count; curoffs++) { int countneeded; UINT8 cmd; /* accumulate 2 words of data */ - databuffer[databufcount++] = *data; - databuffer[databufcount++] = *data++ >> 32; + databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 0); + databuffer[databufcount++] = WAVERAM_READ32(base, curoffs * 2 + 1); /* if this is enough, process the command */ cmd = databuffer[0] >> 24; @@ -1087,6 +1027,7 @@ static void zeus_draw_quad(const UINT32 *databuffer, UINT32 texdata, int logit) poly_vertex clipvert[8]; poly_vertex vert[4]; float uscale, vscale; + float maxy, maxx; int val1, val2, texwshift; int numverts; int i; @@ -1121,7 +1062,8 @@ if ( { if (logit) logerror("quad (culled %08X)\n", rotnormal[2]); -// return; +// if (input_code_pressed(KEYCODE_COMMA)) +// return; } if (logit) @@ -1133,6 +1075,14 @@ if ( val2 = (texdata >> 16) & 0x3ff; texwshift = (val2 >> 6) & 7; +//if (input_code_pressed(KEYCODE_Z) && (val2 & 0x01)) return; +//if (input_code_pressed(KEYCODE_X) && (val2 & 0x02)) return; +//if (input_code_pressed(KEYCODE_C) && (val2 & 0x04)) return; +//if (input_code_pressed(KEYCODE_V) && (val2 & 0x08)) return; +//if (input_code_pressed(KEYCODE_B) && (val2 & 0x10)) return; +//if (input_code_pressed(KEYCODE_N) && (val2 & 0x20)) return; +//if (input_code_pressed(KEYCODE_M) && (val2 & 0x200)) return; + uscale = (8 >> ((zeusbase[0x04] >> 4) & 3)) * 0.125f * 256.0f; vscale = (8 >> ((zeusbase[0x04] >> 6) & 3)) * 0.125f * 256.0f; @@ -1153,9 +1103,9 @@ if ( INT32 xo = (INT16)ixy; INT32 yo = (INT16)(ixy >> 16); INT32 zo = (INT16)iuvz; - INT32 xn = (INT32)(inormal << 22) >> 20; + INT32 xn = (INT32)(inormal << 2) >> 20; INT32 yn = (INT32)(inormal << 12) >> 20; - INT32 zn = (INT32)(inormal << 2) >> 20; + INT32 zn = (INT32)(inormal << 22) >> 20; UINT8 u = iuvz >> 16; UINT8 v = iuvz >> 24; INT32 dotnormal; @@ -1192,14 +1142,27 @@ if ( if (numverts < 3) return; + maxx = maxy = -1000.0f; for (i = 0; i < numverts; i++) { float ooz = 512.0f / clipvert[i].p[0]; clipvert[i].x *= ooz; clipvert[i].y *= ooz; - clipvert[i].x += 200.0f; - clipvert[i].y += 128.0f; + clipvert[i].x += 200.5f; + clipvert[i].y += 128.5f; + + maxx = MAX(maxx, clipvert[i].x); + maxy = MAX(maxy, clipvert[i].y); + if (logit) + logerror("\t\t\tTranslated=(%f,%f)\n", clipvert[i].x, clipvert[i].y); + } + for (i = 0; i < numverts; i++) + { + if (clipvert[i].x == maxx) + clipvert[i].x += 0.0005f; + if (clipvert[i].y == maxy) + clipvert[i].y += 0.0005f; } extra = poly_get_extra_data(poly); @@ -1211,20 +1174,7 @@ if ( extra->texbase = waveram_ptr_from_texture_addr(0, val1, extra->texwidth); extra->palbase = zeus_palbase; - if (single_step) - { - single_step_extra = *extra; - single_step_val1 = val1; - single_step_val2 = val2; - single_step_dx = single_step_dy = 0; - single_step_advance = FALSE; - } - poly_render_quad_fan(poly, NULL, &zeus_cliprect, callback, 4, numverts, &clipvert[0]); - poly_wait(poly, "Normal"); - - if (single_step) - while (!single_step_advance) video_frame_update(TRUE); } @@ -1246,16 +1196,15 @@ static void render_poly_4bit(void *dest, INT32 scanline, const poly_extent *exte INT32 dudx = extent->param[1].dpdx; INT32 dvdx = extent->param[2].dpdx; INT32 didx = extent->param[3].dpdx; - const UINT64 *texbase = extra->texbase; - const UINT64 *palbase = extra->palbase; + const void *texbase = extra->texbase; + const void *palbase = extra->palbase; UINT16 transcolor = extra->transcolor; int texwidth = extra->texwidth; int x; for (x = extent->startx; x < extent->stopx; x++) { - UINT16 *depthptr; - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, scanline, x, &depthptr); + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, scanline, x); INT32 depth = (curz >> 16) + extra->zoffset; if (depth > 0x7fff) depth = 0x7fff; if (depth >= 0 && depth <= *depthptr) @@ -1270,17 +1219,17 @@ static void render_poly_4bit(void *dest, INT32 scanline, const poly_extent *exte UINT8 texel3 = get_texel_4bit(texbase, v1, u1, texwidth); if (texel0 != transcolor) { - rgb_t color0 = get_palette_entry(palbase, texel0); - rgb_t color1 = get_palette_entry(palbase, texel1); - rgb_t color2 = get_palette_entry(palbase, texel2); - rgb_t color3 = get_palette_entry(palbase, texel3); + rgb_t color0 = WAVERAM_READ16(palbase, texel0); + rgb_t color1 = WAVERAM_READ16(palbase, texel1); + rgb_t color2 = WAVERAM_READ16(palbase, texel2); + rgb_t color3 = WAVERAM_READ16(palbase, texel3); rgb_t filtered; color0 = ((color0 & 0x7fe0) << 6) | (color0 & 0x1f); color1 = ((color1 & 0x7fe0) << 6) | (color1 & 0x1f); color2 = ((color2 & 0x7fe0) << 6) | (color2 & 0x1f); color3 = ((color3 & 0x7fe0) << 6) | (color3 & 0x1f); filtered = rgb_bilinear_filter(color0, color1, color2, color3, curu, curv); - *ptr = ((filtered >> 6) & 0x7fe0) | (filtered & 0x1f); + WAVERAM_WRITEPIX(zeus_renderbase, scanline, x, ((filtered >> 6) & 0x7fe0) | (filtered & 0x1f)); *depthptr = depth; } } @@ -1304,16 +1253,15 @@ static void render_poly_8bit(void *dest, INT32 scanline, const poly_extent *exte INT32 dudx = extent->param[1].dpdx; INT32 dvdx = extent->param[2].dpdx; INT32 didx = extent->param[3].dpdx; - const UINT64 *texbase = extra->texbase; - const UINT64 *palbase = extra->palbase; + const void *texbase = extra->texbase; + const void *palbase = extra->palbase; UINT16 transcolor = extra->transcolor; int texwidth = extra->texwidth; int x; for (x = extent->startx; x < extent->stopx; x++) { - UINT16 *depthptr; - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, scanline, x, &depthptr); + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, scanline, x); INT32 depth = (curz >> 16) + extra->zoffset; if (depth > 0x7fff) depth = 0x7fff; if (depth >= 0 && depth <= *depthptr) @@ -1328,17 +1276,17 @@ static void render_poly_8bit(void *dest, INT32 scanline, const poly_extent *exte UINT8 texel3 = get_texel_8bit(texbase, v1, u1, texwidth); if (texel0 != transcolor) { - rgb_t color0 = get_palette_entry(palbase, texel0); - rgb_t color1 = get_palette_entry(palbase, texel1); - rgb_t color2 = get_palette_entry(palbase, texel2); - rgb_t color3 = get_palette_entry(palbase, texel3); + rgb_t color0 = WAVERAM_READ16(palbase, texel0); + rgb_t color1 = WAVERAM_READ16(palbase, texel1); + rgb_t color2 = WAVERAM_READ16(palbase, texel2); + rgb_t color3 = WAVERAM_READ16(palbase, texel3); rgb_t filtered; color0 = ((color0 & 0x7fe0) << 6) | (color0 & 0x1f); color1 = ((color1 & 0x7fe0) << 6) | (color1 & 0x1f); color2 = ((color2 & 0x7fe0) << 6) | (color2 & 0x1f); color3 = ((color3 & 0x7fe0) << 6) | (color3 & 0x1f); filtered = rgb_bilinear_filter(color0, color1, color2, color3, curu, curv); - *ptr = ((filtered >> 6) & 0x7fe0) | (filtered & 0x1f); + WAVERAM_WRITEPIX(zeus_renderbase, scanline, x, ((filtered >> 6) & 0x7fe0) | (filtered & 0x1f)); *depthptr = depth; } } @@ -1362,7 +1310,7 @@ static void render_poly_shade(void *dest, INT32 scanline, const poly_extent *ext { if (extra->alpha <= 0x80) { - UINT16 *ptr = waveram_pixel_ptr(zeus_renderbase, scanline, x, NULL); + UINT16 *ptr = WAVERAM_PTRPIX(zeus_renderbase, scanline, x); UINT16 pix = *ptr; *ptr = ((((pix & 0x7c00) * extra->alpha) >> 7) & 0x7c00) | @@ -1439,17 +1387,17 @@ static void log_waveram(UINT32 length_and_base) static struct { UINT32 lab; - UINT64 checksum; + UINT32 checksum; } recent_entries[100]; UINT32 numoctets = (length_and_base >> 24) + 1; - const UINT64 *ptr = waveram_ptr_from_block_addr(0, length_and_base); + const UINT32 *ptr = waveram_ptr_from_block_addr(0, length_and_base); UINT64 checksum = length_and_base; int foundit = FALSE; int i; for (i = 0; i < numoctets; i++) - checksum += ptr[i]; + checksum += ptr[i*2] + ptr[i*2+1]; for (i = 0; i < ARRAY_LENGTH(recent_entries); i++) if (recent_entries[i].lab == length_and_base && recent_entries[i].checksum == checksum) @@ -1470,5 +1418,5 @@ static void log_waveram(UINT32 length_and_base) return; for (i = 0; i < numoctets; i++) - logerror("\t%02X: %08X %08X\n", i, (UINT32)ptr[i], (UINT32)(ptr[i] >> 32)); + logerror("\t%02X: %08X %08X\n", i, ptr[i*2], ptr[i*2+1]); } diff --git a/src/mame/video/midzeus2.c b/src/mame/video/midzeus2.c new file mode 100644 index 00000000000..264f8afed79 --- /dev/null +++ b/src/mame/video/midzeus2.c @@ -0,0 +1,615 @@ +/************************************************************************* + + Driver for Midway Zeus games + +**************************************************************************/ + +#include "driver.h" +#include "eminline.h" +#include "includes/midzeus.h" +#include "video/poly.h" +#include "video/rgbutil.h" + + + +/************************************* + * + * Constants + * + *************************************/ + +#define DUMP_WAVE_RAM 0 + +#define WAVERAM_WIDTH 1024 +#define WAVERAM_HEIGHT 2048 + + + +/************************************* + * + * Type definitions + * + *************************************/ + +typedef struct _poly_extra_data poly_extra_data; +struct _poly_extra_data +{ + const void * palbase; + const void * texbase; + UINT16 solidcolor; + INT16 zoffset; + UINT16 transcolor; + UINT16 texwidth; + UINT16 color; + UINT32 alpha; +}; + + + +/************************************* + * + * Global variables + * + *************************************/ + +extern UINT32 *zeusbase; + +static poly_manager *poly; +static UINT8 log_fifo; + +static UINT32 zeus_fifo[20]; +static UINT8 zeus_fifo_words; +static void *zeus_renderbase; +static rectangle zeus_cliprect; + +static void *waveram[2]; + + + +/************************************* + * + * Function prototypes + * + *************************************/ + +static void exit_handler(running_machine *machine); + +static void zeus_register32_w(offs_t offset, UINT32 data, int logit); +static void zeus_register_update(offs_t offset, UINT32 oldval); +static int zeus_fifo_process(const UINT32 *data, int numwords); + +static void log_fifo_command(const UINT32 *data, int numwords, const char *suffix); + + + +/************************************* + * + * Macros + * + *************************************/ + +#define WAVERAM_BLOCK(bank, blocknum) ((void *)((UINT8 *)waveram[bank] + 16 * (blocknum))) + +#define WAVERAM_PTR8(base, bytenum) ((UINT8 *)(base) + BYTE4_XOR_LE(bytenum)) +#define WAVERAM_READ8(base, bytenum) (*WAVERAM_PTR8(base, bytenum)) +#define WAVERAM_WRITE8(base, bytenum, data) do { *WAVERAM_PTR8(base, bytenum) = (data); } while (0) + +#define WAVERAM_PTR16(base, wordnum) ((UINT16 *)(base) + BYTE_XOR_LE(wordnum)) +#define WAVERAM_READ16(base, wordnum) (*WAVERAM_PTR16(base, wordnum)) +#define WAVERAM_WRITE16(base, wordnum, data) do { *WAVERAM_PTR16(base, wordnum) = (data); } while (0) + +#define WAVERAM_PTR32(base, dwordnum) ((UINT32 *)(base) + (dwordnum)) +#define WAVERAM_READ32(base, dwordnum) (*WAVERAM_PTR32(base, dwordnum)) +#define WAVERAM_WRITE32(base, dwordnum, data) do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0) + +#define PIXYX_TO_DWORDNUM(y, x) ((((y) & 0x1fe) << 11) | (((y) & 1) << 10) | (((x) & 0x1fe) << 1) | ((x) & 1)) +#define DEPTHYX_TO_DWORDNUM(y, x) (PIXYX_TO_DWORDNUM(y, x) | 2) + +#define WAVERAM_PTRPIX(base, y, x) WAVERAM_PTR32(base, PIXYX_TO_DWORDNUM(y, x)) +#define WAVERAM_READPIX(base, y, x) (*WAVERAM_PTRPIX(base, y, x)) +#define WAVERAM_WRITEPIX(base, y, x, color) do { *WAVERAM_PTRPIX(base, y, x) = (color); } while (0) + +#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_DWORDNUM(y, x & ~1) * 2 + (x & 1)) +#define WAVERAM_READDEPTH(base, y, x) (*WAVERAM_PTRDEPTH(base, y, x)) +#define WAVERAM_WRITEDEPTH(base, y, x, color) do { *WAVERAM_PTRDEPTH(base, y, x) = (color); } while (0) + + + +/************************************* + * + * Inlines for block addressing + * + *************************************/ + +INLINE void *waveram_ptr_from_block_addr(UINT8 bank, UINT32 addr) +{ + UINT32 blocknum = (addr % WAVERAM_WIDTH) + ((addr >> 12) % WAVERAM_HEIGHT) * WAVERAM_WIDTH; + return WAVERAM_BLOCK(bank, blocknum); +} + +INLINE void *waveram_ptr_from_expanded_addr(UINT8 bank, UINT32 addr) +{ + UINT32 blocknum = (addr % WAVERAM_WIDTH) + ((addr >> 16) % WAVERAM_HEIGHT) * WAVERAM_WIDTH; + return WAVERAM_BLOCK(bank, blocknum); +} + +INLINE void *waveram_ptr_from_texture_addr(UINT8 bank, UINT32 addr, int width) +{ + UINT32 blocknum = ((addr & ~1) * width) / 8; + return WAVERAM_BLOCK(bank, blocknum); +} + + + +/************************************* + * + * Inlines for rendering + * + *************************************/ + +INLINE void waveram_plot(int y, int x, UINT32 color) +{ + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); +} + +INLINE void waveram_plot_depth(int y, int x, UINT32 color, UINT16 depth) +{ + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) + { + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth); + } +} + +INLINE void waveram_plot_check_depth(int y, int x, UINT32 color, UINT16 depth) +{ + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) + { + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x); + if (depth <= *depthptr) + { + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + *depthptr = depth; + } + } +} + +INLINE void waveram_plot_check_depth_nowrite(int y, int x, UINT32 color, UINT16 depth) +{ + if (x >= 0 && x <= zeus_cliprect.max_x && y >= 0 && y < zeus_cliprect.max_y) + { + UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x); + if (depth <= *depthptr) + WAVERAM_WRITEPIX(zeus_renderbase, y, x, color); + } +} + + + +/************************************* + * + * Inlines for texel accesses + * + *************************************/ + +INLINE UINT8 get_texel_8bit(const void *base, int y, int x, int width) +{ + UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 4) << 3) + ((y & 1) << 2) + (x & 3); + return WAVERAM_READ8(base, byteoffs); +} + + +INLINE UINT8 get_texel_4bit(const void *base, int y, int x, int width) +{ + UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 8) << 3) + ((y & 1) << 2) + ((x / 2) & 3); + return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f; +} + + + +/************************************* + * + * Video startup + * + *************************************/ + +VIDEO_START( midzeus2 ) +{ + /* allocate memory for "wave" RAM */ + waveram[0] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * 16); + waveram[1] = auto_malloc(WAVERAM_WIDTH * WAVERAM_HEIGHT * 16); + state_save_register_global_pointer(((UINT32 *)waveram[0]), WAVERAM_WIDTH * WAVERAM_HEIGHT * 16/4); + state_save_register_global_pointer(((UINT32 *)waveram[1]), WAVERAM_WIDTH * WAVERAM_HEIGHT * 16/4); + + /* initialize polygon engine */ + poly = poly_alloc(10000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS); + + /* we need to cleanup on exit */ + add_exit_callback(machine, exit_handler); + + zeus_renderbase = waveram[1]; +} + + +static void exit_handler(running_machine *machine) +{ +#if DUMP_WAVE_RAM + FILE *f = fopen("waveram.dmp", "w"); + int bank; + int i; + + for (bank = 0; bank < 2; bank++) + for (i = 0; i < WAVERAM_WIDTH * WAVERAM_HEIGHT; i++) + { + if (i % 4 == 0) fprintf(f, "%03X%03X: ", i / WAVERAM_WIDTH, i % WAVERAM_WIDTH); + fprintf(f, " %08X %08X ", (UINT32)(waveram[bank][i] >> 32), (UINT32)waveram[bank][i]); + if (i % 4 == 3) fprintf(f, "\n"); + } + fclose(f); +#endif + + poly_free(poly); +} + + + +/************************************* + * + * Video update + * + *************************************/ + +VIDEO_UPDATE( midzeus2 ) +{ + int x, y; + + poly_wait(poly, "VIDEO_UPDATE"); + + /* normal update case */ + if (!input_code_pressed(KEYCODE_W)) + { + const void *base = waveram_ptr_from_expanded_addr(1, 0);//zeusbase[0xcc]); + int xoffs = machine->screen[screen].visarea.min_x; + for (y = cliprect->min_y; y <= cliprect->max_y; y++) + { + UINT32 *dest = (UINT32 *)bitmap->base + y * bitmap->rowpixels; + for (x = cliprect->min_x; x <= cliprect->max_x; x++) + dest[x] = WAVERAM_READPIX(base, y, x - xoffs); + } + } + + /* waveram drawing case */ + else + { + static int yoffs = 0; + static int width = 256; + const UINT64 *base; + + if (input_code_pressed(KEYCODE_DOWN)) yoffs += input_code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; + if (input_code_pressed(KEYCODE_UP)) yoffs -= input_code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1; + if (input_code_pressed(KEYCODE_LEFT) && width > 4) { width >>= 1; while (input_code_pressed(KEYCODE_LEFT)) ; } + if (input_code_pressed(KEYCODE_RIGHT) && width < 512) { width <<= 1; while (input_code_pressed(KEYCODE_RIGHT)) ; } + + if (yoffs < 0) yoffs = 0; + base = waveram_ptr_from_block_addr(0, yoffs << 12); + + for (y = cliprect->min_y; y <= cliprect->max_y; y++) + { + UINT16 *dest = (UINT16 *)bitmap->base + y * bitmap->rowpixels; + for (x = cliprect->min_x; x <= cliprect->max_x; x++) + { + UINT8 tex = get_texel_8bit(base, y, x, width); + dest[x] = (tex << 8) | tex; + } + } + popmessage("offs = %06X", yoffs << 12); + } + + return 0; +} + + + +/************************************* + * + * Core read handler + * + *************************************/ + +READ32_HANDLER( zeus2_r ) +{ + UINT32 result = zeusbase[offset]; + + logerror("%06X:zeus2_r(%02X)\n", activecpu_get_pc(), offset); + + switch (offset) + { + case 0x00: + result = 0x20; + break; + + case 0x01: + /* bit $000C0070 are tested in a loop until 0 */ + /* bits $00080000 is tested in a loop until 0 */ + /* bit $00000004 is tested for toggling; probably VBLANK */ + result = 0x00; + if (video_screen_get_vblank(0)) + result |= 0x04; + break; + + case 0x54: + /* upper 16 bits are masked when read -- is that the hpos? */ + result = video_screen_get_vpos(0); + break; + } + + return result; +} + + + +/************************************* + * + * Core write handler + * + *************************************/ + +WRITE32_HANDLER( zeus2_w ) +{ + logerror("%06X:zeus2_w", activecpu_get_pc()); + zeus_register32_w(offset, data, TRUE); +} + + + + /************************************* + * + * Handle register writes + * + *************************************/ + +static void zeus_register32_w(offs_t offset, UINT32 data, int logit) +{ + UINT32 oldval = zeusbase[offset]; + + /* writes to register $CC need to force a partial update */ +// if ((offset & ~1) == 0xcc) +// video_screen_update_partial(0, video_screen_get_vpos(0)); + + /* always write to low word? */ + zeusbase[offset] = data; + + /* log appropriately */ + if (logit) + logerror("(%02X) = %08X\n", offset, data); + + /* handle the update */ + zeus_register_update(offset, oldval); +} + + + +/************************************* + * + * Update state after a register write + * + *************************************/ + +static void zeus_register_update(offs_t offset, UINT32 oldval) +{ + /* handle the writes; only trigger on low accesses */ + switch (offset) + { + case 0x08: + zeus_fifo[zeus_fifo_words++] = zeusbase[0x08]; + if (zeus_fifo_process(zeus_fifo, zeus_fifo_words)) + zeus_fifo_words = 0; + break; + + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + video_screen_update_partial(0, video_screen_get_vpos(0)); + { + int vtotal = zeusbase[0x37] & 0xffff; + int htotal = zeusbase[0x34] >> 16; + rectangle visarea; + + visarea.min_x = zeusbase[0x33] >> 16; + visarea.max_x = (zeusbase[0x34] & 0xffff) - 1; + visarea.min_y = 0; + visarea.max_y = zeusbase[0x35] & 0xffff; + if (htotal > 0 && vtotal > 0 && visarea.min_x < visarea.max_x && visarea.max_y < vtotal) + { + video_screen_configure(0, htotal, vtotal, &visarea, HZ_TO_ATTOSECONDS((double)MIDZEUS_VIDEO_CLOCK / 4.0 / (htotal * vtotal))); + zeus_cliprect = visarea; + zeus_cliprect.max_x -= zeus_cliprect.min_x; + zeus_cliprect.min_x = 0; + } + } + break; + + case 0x41: + /* this is the address, except in read mode, where it latches values */ + if (zeusbase[0x4e] & 0x10) + { + const void *src = waveram_ptr_from_expanded_addr(0, oldval); + zeusbase[0x41] = oldval; + zeusbase[0x48] = WAVERAM_READ32(src, 0); + zeusbase[0x49] = WAVERAM_READ32(src, 1); + + if (zeusbase[0x4e] & 0x40) + { + zeusbase[0x41]++; + zeusbase[0x41] += (zeusbase[0x41] & 0x400) << 6; + zeusbase[0x41] &= ~0xfc00; + } + } + break; + + case 0x48: + case 0x49: + /* if we're in write mode, process it */ + if (zeusbase[0x40] == 0x00890000) + { + /* + zeusbase[0x4e]: + bit 0-1: which register triggers write through + bit 3: enable write through via these registers + bit 4: seems to be set during reads, when 0x41 is used for latching + bit 6: enable autoincrement on write through + */ + if ((zeusbase[0x4e] & 0x08) && (offset & 3) == (zeusbase[0x4e] & 3)) + { + void *dest = waveram_ptr_from_expanded_addr(0, zeusbase[0x41]); + WAVERAM_WRITE32(dest, 0, zeusbase[0x48]); + WAVERAM_WRITE32(dest, 1, zeusbase[0x49]); + + if (zeusbase[0x4e] & 0x40) + { + zeusbase[0x41]++; + zeusbase[0x41] += (zeusbase[0x41] & 0x400) << 6; + zeusbase[0x41] &= ~0xfc00; + } + } + } + + /* make sure we log anything else */ + else + logerror("\t[40]=%08X [4E]=%08X\n", zeusbase[0x40], zeusbase[0x4e]); + break; + + case 0x51: + + /* in this mode, crusnexo expects the reads to immediately latch */ + if (zeusbase[0x50] == 0x00a20000) + oldval = zeusbase[0x51]; + + /* this is the address, except in read mode, where it latches values */ + if ((zeusbase[0x5e] & 0x10) || (zeusbase[0x50] == 0x00a20000)) + { + const void *src = waveram_ptr_from_expanded_addr(1, oldval); + zeusbase[0x51] = oldval; + zeusbase[0x58] = WAVERAM_READ32(src, 0); + zeusbase[0x59] = WAVERAM_READ32(src, 1); + zeusbase[0x5a] = WAVERAM_READ32(src, 2); + + if (zeusbase[0x5e] & 0x40) + { + zeusbase[0x51]++; + zeusbase[0x51] += (zeusbase[0x51] & 0x200) << 7; + zeusbase[0x51] &= ~0xfe00; + } + } + break; + + case 0x57: + /* thegrid uses this to write either left or right halves of pixels */ + if (zeusbase[0x50] == 0x00e90000) + { + void *dest = waveram_ptr_from_expanded_addr(1, zeusbase[0x51]); + if (zeusbase[0x57] & 1) + WAVERAM_WRITE32(dest, 0, zeusbase[0x58]); + if (zeusbase[0x57] & 4) + WAVERAM_WRITE32(dest, 1, zeusbase[0x59]); + } + + /* make sure we log anything else */ + else + logerror("\t[50]=%08X [5E]=%08X\n", zeusbase[0x50], zeusbase[0x5e]); + break; + + case 0x58: + case 0x59: + case 0x5a: + /* if we're in write mode, process it */ + if (zeusbase[0x50] == 0x00890000) + { + /* + zeusbase[0x5e]: + bit 0-1: which register triggers write through + bit 3: enable write through via these registers + bit 4: seems to be set during reads, when 0x51 is used for latching + bit 5: unknown, currently used to specify ordering, but this is suspect + bit 6: enable autoincrement on write through + */ + if ((zeusbase[0x5e] & 0x08) && (offset & 3) == (zeusbase[0x5e] & 3)) + { + void *dest = waveram_ptr_from_expanded_addr(1, zeusbase[0x51]); + WAVERAM_WRITE32(dest, 0, zeusbase[0x58]); + if (zeusbase[0x5e] & 0x20) + WAVERAM_WRITE32(dest, 1, zeusbase[0x5a]); + else + { + WAVERAM_WRITE32(dest, 1, zeusbase[0x59]); + WAVERAM_WRITE32(dest, 2, zeusbase[0x5a]); + } + + if (zeusbase[0x5e] & 0x40) + { + zeusbase[0x51]++; + zeusbase[0x51] += (zeusbase[0x51] & 0x200) << 7; + zeusbase[0x51] &= ~0xfe00; + } + } + } + + /* make sure we log anything else */ + else + logerror("\t[50]=%08X [5E]=%08X\n", zeusbase[0x50], zeusbase[0x5e]); + break; + } +} + + + +/************************************* + * + * Process the FIFO + * + *************************************/ + +static int zeus_fifo_process(const UINT32 *data, int numwords) +{ + /* handle logging */ + switch (data[0] >> 24) + { + /* 0x05: write 32-bit value to low registers */ + /* in model data, this is 0x19 */ + case 0x05: + if (numwords < 2) + return FALSE; + if (log_fifo) + log_fifo_command(data, numwords, " -- reg32"); + zeus_register32_w((data[0] >> 16) & 0x7f, data[1], log_fifo); + break; + + default: + printf("Unknown command %08X\n", data[0]); + if (log_fifo) + log_fifo_command(data, numwords, "\n"); + break; + } + return TRUE; +} + + + +/************************************* + * + * Debugging tools + * + *************************************/ + +static void log_fifo_command(const UINT32 *data, int numwords, const char *suffix) +{ + int wordnum; + + logerror("Zeus cmd %02X :", data[0] >> 24); + for (wordnum = 0; wordnum < numwords; wordnum++) + logerror(" %08X", data[wordnum]); + logerror("%s", suffix); +} -- cgit v1.2.3