diff options
author | angelosa <salese_corp_ltd@email.it> | 2016-06-20 23:04:57 +0200 |
---|---|---|
committer | angelosa <salese_corp_ltd@email.it> | 2016-06-20 23:05:17 +0200 |
commit | 75a4c41dd311835c68bb8413fe0a393396dc6a8f (patch) | |
tree | ac54ebf8faf6ae986d45239247570d05c09d70e1 | |
parent | 3da81f42211f271f9cb93bf96b6d68b729e15b9b (diff) |
Moved DMA and commands into own files, nw
-rw-r--r-- | scripts/target/mame/arcade.lua | 6 | ||||
-rw-r--r-- | src/mame/drivers/alg.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/dlair.cpp | 8 | ||||
-rw-r--r-- | src/mame/includes/legionna.h | 2 | ||||
-rw-r--r-- | src/mame/includes/raiden2.h | 2 | ||||
-rw-r--r-- | src/mame/machine/seibucop/seibucop.cpp | 863 | ||||
-rw-r--r-- | src/mame/machine/seibucop/seibucop.h | 5 | ||||
-rw-r--r-- | src/mame/machine/seibucop/seibucop_cmd.hxx | 700 | ||||
-rw-r--r-- | src/mame/machine/seibucop/seibucop_dma.hxx | 152 | ||||
-rw-r--r-- | src/mame/machine/seicop.h | 2 |
10 files changed, 870 insertions, 872 deletions
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index d660e649a5c..2119d2b30f7 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -3267,8 +3267,10 @@ files { MAME_DIR .. "src/mame/includes/raiden2.h", MAME_DIR .. "src/mame/machine/r2crypt.cpp", MAME_DIR .. "src/mame/machine/r2crypt.h", - MAME_DIR .. "src/mame/machine/raiden2cop.cpp", - MAME_DIR .. "src/mame/machine/raiden2cop.h", + MAME_DIR .. "src/mame/machine/seibucop/seibucop.cpp", + MAME_DIR .. "src/mame/machine/seibucop/seibucop_dma.hxx", + MAME_DIR .. "src/mame/machine/seibucop/seibucop_cmd.hxx", + MAME_DIR .. "src/mame/machine/seibucop/seibucop.h", MAME_DIR .. "src/mame/drivers/r2dx_v33.cpp", MAME_DIR .. "src/mame/drivers/seibuspi.cpp", MAME_DIR .. "src/mame/includes/seibuspi.h", diff --git a/src/mame/drivers/alg.cpp b/src/mame/drivers/alg.cpp index bf1ceeebc50..d9649286dc9 100644 --- a/src/mame/drivers/alg.cpp +++ b/src/mame/drivers/alg.cpp @@ -408,7 +408,7 @@ ROM_START( maddoga ) ROM_LOAD16_BYTE( "maddog_02.dat", 0x000001, 0x10000, CRC(f64014ec) SHA1(d343a2cb5d8992153b8c916f39b11d3db736543d)) DISK_REGION( "laserdisc" ) - DISK_IMAGE_READONLY( "maddoga", 0, SHA1(a05ef13979882e0964d030169789ac4f58db10d0) ) + DISK_IMAGE_READONLY( "maddoga", 0, NO_DUMP ) ROM_END diff --git a/src/mame/drivers/dlair.cpp b/src/mame/drivers/dlair.cpp index 35c587f73be..c9932c76271 100644 --- a/src/mame/drivers/dlair.cpp +++ b/src/mame/drivers/dlair.cpp @@ -802,7 +802,7 @@ ROM_START( dlair ) /* revision F2 */ ROM_LOAD( "dl_f2_u4.bin", 0x6000, 0x2000, CRC(f5ec23d2) SHA1(71149e2d359cc5944fbbb53dd7d0c2b42fbc9bb4) ) DISK_REGION( "ld_ldv1000" ) - DISK_IMAGE_READONLY( "dlair", 0, SHA1(da70bac4fe526e48d556ad3fea72cde022c26648) ) + DISK_IMAGE_READONLY( "dlair", 0, NO_DUMP ) ROM_END ROM_START( dlair_1 ) /* Serial #001, courtesy Jason Finn */ @@ -951,7 +951,7 @@ ROM_START( spaceace ) /* revision A3 */ ROM_LOAD( "sa_a3_u5.bin", 0x8000, 0x2000, CRC(85cbcdc4) SHA1(97e01e96c885ab7af4c3a3b586eb40374d54f12f) ) DISK_REGION( "ld_ldv1000" ) - DISK_IMAGE_READONLY( "space_ace_ver2", 0, SHA1(9ca7d4cba380b04a3277a9b706b35036622fe2fb) ) + DISK_IMAGE_READONLY( "space_ace_ver2", 0, NO_DUMP ) ROM_END ROM_START( spaceacea2 ) /* revision A2 */ @@ -963,7 +963,7 @@ ROM_START( spaceacea2 ) /* revision A2 */ ROM_LOAD( "sa_a2_u5.bin", 0x8000, 0x2000, CRC(85cbcdc4) SHA1(97e01e96c885ab7af4c3a3b586eb40374d54f12f) ) DISK_REGION( "ld_ldv1000" ) - DISK_IMAGE_READONLY( "space_ace_ver2", 0, SHA1(9ca7d4cba380b04a3277a9b706b35036622fe2fb) ) + DISK_IMAGE_READONLY( "space_ace_ver2", 0, NO_DUMP ) ROM_END ROM_START( spaceacea ) /* revision A */ @@ -975,7 +975,7 @@ ROM_START( spaceacea ) /* revision A */ ROM_LOAD( "sa_a_u5.bin", 0x8000, 0x2000, CRC(85cbcdc4) SHA1(97e01e96c885ab7af4c3a3b586eb40374d54f12f) ) DISK_REGION( "ld_ldv1000" ) - DISK_IMAGE_READONLY( "space_ace_ver2", 0, SHA1(9ca7d4cba380b04a3277a9b706b35036622fe2fb) ) + DISK_IMAGE_READONLY( "space_ace_ver2", 0, NO_DUMP ) ROM_END ROM_START( spaceaceeuro ) /* Italian Sidam version */ diff --git a/src/mame/includes/legionna.h b/src/mame/includes/legionna.h index 5305b00cd82..6d7dfe2d167 100644 --- a/src/mame/includes/legionna.h +++ b/src/mame/includes/legionna.h @@ -4,7 +4,7 @@ #include "sound/okim6295.h" #include "audio/seibu.h" #include "machine/gen_latch.h" -#include "machine/raiden2cop.h" +#include "machine/seibucop/seibucop.h" #include "video/seibu_crtc.h" class legionna_state : public driver_device diff --git a/src/mame/includes/raiden2.h b/src/mame/includes/raiden2.h index 6a2a1e06217..c8bae63738a 100644 --- a/src/mame/includes/raiden2.h +++ b/src/mame/includes/raiden2.h @@ -1,7 +1,7 @@ // license:LGPL-2.1+ // copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina #include "audio/seibu.h" -#include "machine/raiden2cop.h" +#include "machine/seibucop/seibucop.h" #include "video/seibu_crtc.h" class raiden2_state : public driver_device diff --git a/src/mame/machine/seibucop/seibucop.cpp b/src/mame/machine/seibucop/seibucop.cpp index 103a0b145c9..99aabca96f1 100644 --- a/src/mame/machine/seibucop/seibucop.cpp +++ b/src/mame/machine/seibucop/seibucop.cpp @@ -30,16 +30,14 @@ ***************************************************************************/ #include "emu.h" -#include "raiden2cop.h" +#include "seibucop.h" #include "debugger.h" // use Z to dump out table info //#define TABLE_DUMPER - -#define LOG_Commands 0 -#define LOG_Phytagoras 0 -#define LOG_Division 0 +#include "seibucop_dma.hxx" +#include "seibucop_cmd.hxx" #define seibu_cop_log \ if (LOG_Commands) logerror @@ -658,157 +656,6 @@ UINT8 raiden2cop_device::fade_table(int v) return (low * (high | (high >> 5)) + 0x210) >> 10; } -// ALL games use this - tilemap DMA (RAM -> private buffer) -void raiden2cop_device::dma_tilemap_buffer() -{ - int src = cop_dma_src[cop_dma_mode] << 6; - if (src == 0xcfc0) src = 0xd000; // R2, why?? everything else sets the right pointer (it also sets up odd size / dest regs, they probably counteract this) - - for (int i = 0; i < 0x2800 / 2; i++) - { - UINT16 tileval = m_host_space->read_word(src); - src += 2; - m_videoramout_cb(i, tileval, 0xffff); - } -} - - // ALL games use this - palette DMA (RAM -> private buffer) -void raiden2cop_device::dma_palette_buffer() -{ - int src = cop_dma_src[cop_dma_mode] << 6; - - for (int i = 0; i < 0x1000 / 2; i++) // todo, use length register - { - UINT16 palval = m_host_space->read_word(src); - src += 2; - m_palette->set_pen_color(i, pal5bit(palval >> 0), pal5bit(palval >> 5), pal5bit(palval >> 10)); - } -} - -// these are typically used to transfer palette data from one RAM buffer to another, applying fade values to it prior to the 0x15 transfer -void raiden2cop_device::dma_palette_brightness() -{ - UINT32 src, dst, size, i; - - /* - Apparently all of those are just different DMA channels, brightness effects are done through a RAM table and the pal_brightness_val / mode - 0x80 is used by Legionnaire - 0x81 is used by SD Gundam and Godzilla - 0x82 is used by Zero Team and X Se Dae - 0x86 is used by Seibu Cup Soccer - 0x87 is used by Denjin Makai - - TODO: - - Denjin Makai mode 4 is totally guessworked. - - SD Gundam doesn't fade colors correctly, it should have the text layer / sprites with normal gradient and the rest dimmed in most cases, - presumably bad RAM table or bad algorithm - */ - - //if(dma_trigger != 0x87) - //printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x %02x %02x\n",cop_dma_src[cop_dma_mode] << 6,cop_dma_adr_rel * 0x400,cop_dma_dst[cop_dma_mode] << 6,cop_dma_size[cop_dma_mode] << 5,cop_dma_mode,pal_brightness_val,pal_brightness_mode); - - src = (cop_dma_src[cop_dma_mode] << 6); - dst = (cop_dma_dst[cop_dma_mode] << 6); - size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20) / 2; - - for (i = 0; i < size; i++) - { - UINT16 pal_val; - int r, g, b; - int rt, gt, bt; - - if (pal_brightness_mode == 5) - { - bt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x7c00) >> 5; - bt = fade_table(bt | (pal_brightness_val ^ 0)); - b = ((m_host_space->read_word(src)) & 0x7c00) >> 5; - b = fade_table(b | (pal_brightness_val ^ 0x1f)); - pal_val = ((b + bt) & 0x1f) << 10; - gt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x03e0); - gt = fade_table(gt | (pal_brightness_val ^ 0)); - g = ((m_host_space->read_word(src)) & 0x03e0); - g = fade_table(g | (pal_brightness_val ^ 0x1f)); - pal_val |= ((g + gt) & 0x1f) << 5; - rt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x001f) << 5; - rt = fade_table(rt | (pal_brightness_val ^ 0)); - r = ((m_host_space->read_word(src)) & 0x001f) << 5; - r = fade_table(r | (pal_brightness_val ^ 0x1f)); - pal_val |= ((r + rt) & 0x1f); - } - else if (pal_brightness_mode == 4) //Denjin Makai - { - UINT16 targetpaldata = m_host_space->read_word(src + (cop_dma_adr_rel * 0x400)); - UINT16 paldata = m_host_space->read_word(src); // ^1 !!! (why?) - - bt = (targetpaldata & 0x7c00) >> 10; - b = (paldata & 0x7c00) >> 10; - gt = (targetpaldata & 0x03e0) >> 5; - g = (paldata & 0x03e0) >> 5; - rt = (targetpaldata & 0x001f) >> 0; - r = (paldata & 0x001f) >> 0; - - if (pal_brightness_val == 0x10) - pal_val = bt << 10 | gt << 5 | rt << 0; - else if (pal_brightness_val == 0xff) // TODO: might be the back plane or it still doesn't do any mod, needs PCB tests - pal_val = 0; - else - { - bt = fade_table(bt << 5 | ((pal_brightness_val * 2) ^ 0)); - b = fade_table(b << 5 | ((pal_brightness_val * 2) ^ 0x1f)); - pal_val = ((b + bt) & 0x1f) << 10; - gt = fade_table(gt << 5 | ((pal_brightness_val * 2) ^ 0)); - g = fade_table(g << 5 | ((pal_brightness_val * 2) ^ 0x1f)); - pal_val |= ((g + gt) & 0x1f) << 5; - rt = fade_table(rt << 5 | ((pal_brightness_val * 2) ^ 0)); - r = fade_table(r << 5 | ((pal_brightness_val * 2) ^ 0x1f)); - pal_val |= ((r + rt) & 0x1f); - } - } - else - { - printf("Warning: palette DMA used with mode %02x!\n", pal_brightness_mode); - pal_val = m_host_space->read_word(src); - } - - m_host_space->write_word(dst, pal_val); - src += 2; - dst += 2; - } -} - -void raiden2cop_device::dma_fill() -{ - UINT32 length, address; - int i; - if (cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid? - return; - - address = (cop_dma_src[cop_dma_mode] << 6); - length = (cop_dma_size[cop_dma_mode] + 1) << 5; - - //printf("%08x %08x\n",address,length); - - for (i = address; i < address + length; i += 4) - m_host_space->write_dword(i, (cop_dma_v1) | (cop_dma_v2 << 16)); - - /* - UINT32 length, address; - int i; - if(cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid? - return; - - address = (cop_dma_src[cop_dma_mode] << 6); - length = (cop_dma_size[cop_dma_mode]+1) << 5; - - //printf("%08x %08x\n",address,length); - - for (i=address;i<address+length;i+=4) - { - m_host_space->write_dword(i, m_fill_val); - } - */ -} - WRITE16_MEMBER(raiden2cop_device::cop_dma_trigger_w) { #if 0 @@ -982,710 +829,6 @@ READ16_MEMBER(raiden2cop_device::cop_itoa_digits_r) return cop_itoa_digits[offset*2] | (cop_itoa_digits[offset*2+1] << 8); } -/* Main COP functionality */ - -// notes about tables: -// (TABLENOTE1) -// in all but one case the upload table position (5-bits) is the SAME as the upper 5-bits of the 'trigger value' -// the exception to this rule is program 0x18 uploads on zeroteam -// in this case you can see that the 'trigger' value upper bits are 0x0f, this would be potentially interesting if it were used (but it isn't) -// 18 - c480 ( 18) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk) -// 18 - 7c80 ( 0f) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (zeroteam, xsedae) - -// It is unknown if the lower 11 bits uploaded as part of the 'trigger' value to the table are used during execution. -// When the actual trigger is written these bits can be different to the upload and for the written value we know they give extended -// meanings to the commands (eg. signs swapped in operations - for program 0x01 (0905) Zero Team writes 0904 (lowest bit different to uploaded -// value) to negate the logic - -/* - -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -00 - 0205 ( 00) ( 205) : (188, 282, 082, b8e, 98e, 000, 000, 000) 6 ffeb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -00 - 0105 ( 00) ( 105) : (180, 2e0, 0a0, 000, 000, 000, 000, 000) 6 fffb (zeroteamsr) -*/ -void raiden2cop_device::execute_0205(int offset, UINT16 data) -{ - int ppos = m_host_space->read_dword(cop_regs[0] + 4 + offset * 4); - int npos = ppos + m_host_space->read_dword(cop_regs[0] + 0x10 + offset * 4); - int delta = (npos >> 16) - (ppos >> 16); - m_host_space->write_dword(cop_regs[0] + 4 + offset * 4, npos); - cop_write_word(cop_regs[0] + 0x1e + offset * 4, cop_read_word(cop_regs[0] + 0x1e + offset * 4) + delta); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -01 - 0905 ( 01) ( 105) : (194, 288, 088, 000, 000, 000, 000, 000) 6 fbfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -01 - 0b05 ( 01) ( 305) : (180, 2e0, 0a0, 182, 2e0, 0c0, 000, 000) 6 ffdb (zeroteamsr) -*/ - -// triggered with 0904 0905 - -void raiden2cop_device::execute_0904(int offset, UINT16 data) -{ - if (data&0x0001) - m_host_space->write_dword(cop_regs[0] + 16 + offset * 4, m_host_space->read_dword(cop_regs[0] + 16 + offset * 4) + m_host_space->read_dword(cop_regs[0] + 0x28 + offset * 4)); - else /* X Se Dae and Zero Team uses this variant */ - m_host_space->write_dword(cop_regs[0] + 16 + offset * 4, m_host_space->read_dword(cop_regs[0] + 16 + offset * 4) - m_host_space->read_dword(cop_regs[0] + 0x28 + offset * 4)); -} - - - - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -02 - 138e ( 02) ( 38e) : (984, aa4, d82, aa2, 39b, b9a, b9a, b9a) 5 bf7f (legionna, heatbrl) -02 - 138e ( 02) ( 38e) : (984, aa4, d82, aa2, 39b, b9a, b9a, a9a) 5 bf7f (cupsoc, grainbow, godzilla, denjinmk) -02 - 130e ( 02) ( 30e) : (984, aa4, d82, aa2, 39b, b9a, b9a, a9a) 5 bf7f (raiden2, raidendx, zeroteam, xsedae) -*/ - -// triggered with 130e, 138e -void raiden2cop_device::execute_130e(int offset, UINT16 data) -{ - // this can't be right - execute_338e(offset, data); -} - -void raiden2cop_device::LEGACY_execute_130e(int offset, UINT16 data) -{ - int dy = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); - int dx = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); - - cop_status = 7; - if (!dx) { - cop_status |= 0x8000; - cop_angle = 0; - } - else { - cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI); - if (dx < 0) - cop_angle += 0x80; - } - - m_LEGACY_r0 = dy; - m_LEGACY_r1 = dx; - - if (data & 0x80) - m_host_space->write_word(cop_regs[0] + (0x34 ^ 2), cop_angle); -} - -void raiden2cop_device::LEGACY_execute_130e_cupsoc(int offset, UINT16 data) -{ - int dy = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); - int dx = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); - - cop_status = 7; - if (!dx) { - cop_status |= 0x8000; - cop_angle = 0; - } - else { - cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI); - if (dx < 0) - cop_angle += 0x80; - } - - m_LEGACY_r0 = dy; - m_LEGACY_r1 = dx; - - //printf("%d %d %f %04x\n",dx,dy,atan(double(dy)/double(dx)) * 128 / M_PI,cop_angle); - - if (data & 0x80) - m_host_space->write_word(cop_regs[0] + (0x34 ^ 2), cop_angle); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -03 - 1905 ( 03) ( 105) : (994, a88, 088, 000, 000, 000, 000, 000) 6 fbfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -*/ - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -04 - 2288 ( 04) ( 288) : (f8a, b8a, 388, b9c, b9a, a9a, 000, 000) 5 f5df (legionna, heatbrl) -04 - 2288 ( 04) ( 288) : (f8a, b8a, 388, b9a, b9a, a9a, 000, 000) 5 f5df (cupsoc, grainbow, godzilla, denjinmk) -04 - 2208 ( 04) ( 208) : (f8a, b8a, 388, b9a, b9a, a9a, 000, 000) 5 f5df (raiden2, raidendx, zeroteam, xsedae) -*/ - -// also triggered with 0x2208 -void raiden2cop_device::execute_2288(int offset, UINT16 data) -{ - int dx = m_host_space->read_word(cop_regs[0] + 0x12); - int dy = m_host_space->read_word(cop_regs[0] + 0x16); - - if (!dy) { - cop_status |= 0x8000; - cop_angle = 0; - } - else { - cop_angle = (int)(atan(double(dx) / double(dy)) * 128 / M_PI); - if (dy < 0) - cop_angle += 0x80; - } - - if (data & 0x0080) { - m_host_space->write_byte(cop_regs[0] + 0x34, cop_angle); - } -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -05 - 2a05 ( 05) ( 205) : (9af, a82, 082, a8f, 18e, 000, 000, 000) 6 ebeb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -*/ - -void raiden2cop_device::execute_2a05(int offset, UINT16 data) -{ - int delta = m_host_space->read_word(cop_regs[1] + 0x1e + offset * 4); - m_host_space->write_dword(cop_regs[0] + 4 + 2 + offset * 4, m_host_space->read_word(cop_regs[0] + 4 + 2 + offset * 4) + delta); - m_host_space->write_dword(cop_regs[0] + 0x1e + offset * 4, m_host_space->read_word(cop_regs[0] + 0x1e + offset * 4) + delta); -} - - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -06 - 338e ( 06) ( 38e) : (984, aa4, d82, aa2, 39c, b9c, b9c, a9a) 5 bf7f (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx) -06 - 330e ( 06) ( 30e) : (984, aa4, d82, aa2, 39c, b9c, b9c, a9a) 5 bf7f (zeroteam, xsedae) -*/ -void raiden2cop_device::execute_338e(int offset, UINT16 data) -{ - int dx = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); - int dy = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); - - if (!dy) { - cop_status |= 0x8000; - cop_angle = 0; - } - else { - cop_angle = (int)(atan(double(dx) / double(dy)) * 128 / M_PI); - if (dy < 0) - cop_angle += 0x80; - } - -#if LOG_Phytagoras - printf("cmd %04x: dx = %d dy = %d angle = %02x\n",data,dx,dy,cop_angle); -#endif - - if (data & 0x0080) { - m_host_space->write_byte(cop_regs[0] + 0x34, cop_angle); - } -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -07 - 3bb0 ( 07) ( 3b0) : (f9c, b9c, b9c, b9c, b9c, b9c, b9c, 99c) 4 007f (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, -07 - 3b30 ( 07) ( 330) : (f9c, b9c, b9c, b9c, b9c, b9c, b9c, 99c) 4 007f (zeroteam, xsedae) -*/ - -// triggered with 0x39b0, 0x3b30, 0x3bb0 - -void raiden2cop_device::execute_3b30(int offset, UINT16 data) -{ - /* TODO: these are actually internally loaded via 0x130e command */ - int dx, dy; - - dx = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); - dy = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); - - dx = dx >> 16; - dy = dy >> 16; - cop_dist = sqrt((double)(dx*dx + dy*dy)); - -#if LOG_Phytagoras - printf("cmd %04x: dx = %d dy = %d dist = %08x \n",data,dx >> 16,dy >> 16,cop_dist); -#endif - - if (data & 0x0080) - m_host_space->write_word(cop_regs[0] + (data & 0x200 ? 0x3a : 0x38), cop_dist); -} - -void raiden2cop_device::LEGACY_execute_3b30(int offset, UINT16 data) -{ - int dy = m_LEGACY_r0; - int dx = m_LEGACY_r1; - - dx >>= 16; - dy >>= 16; - cop_dist = sqrt((double)(dx*dx + dy*dy)); - - if (data & 0x80) - m_host_space->write_word(cop_regs[0] + (0x38), cop_dist); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -08 - 42c2 ( 08) ( 2c2) : (f9a, b9a, b9c, b9c, b9c, 29c, 000, 000) 5 fcdd (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -*/ -void raiden2cop_device::execute_42c2(int offset, UINT16 data) -{ - int div = m_host_space->read_word(cop_regs[0] + (0x36)); - -#if LOG_Division - printf("cmd %04x: div = %04x scale = %04x\n",data,div,cop_scale); -#endif - - if (!div) - { - cop_status |= 0x8000; - m_host_space->write_word(cop_regs[0] + (0x38), 0); - return; - } - - /* TODO: bits 5-6-15 */ - cop_status = 7; - -#if LOG_Division - printf("res = %04x dist %04x\n",(cop_dist << (5 - cop_scale)) / div,cop_dist); - -// if(div & 0x8000) -// machine().debugger().debug_break(); -#endif - - m_host_space->write_word(cop_regs[0] + (0x38), (cop_dist << (5 - cop_scale)) / div); -} - -void raiden2cop_device::LEGACY_execute_42c2(int offset, UINT16 data) -{ - int dy = m_LEGACY_r0; - int dx = m_LEGACY_r1; - int div = m_host_space->read_word(cop_regs[0] + (0x36 ^ 2)); - int res; - int cop_dist_raw; - - // divide by zero? - if (!div) - { - // No emulation error here: heatbrl specifically tests this - cop_status |= 0x8000; - res = 0; - } - else - { - /* TODO: calculation of this one should occur at 0x3b30/0x3bb0 I *think* */ - /* TODO: recheck if cop_scale still masks at 3 with this command */ - dx >>= 11 + cop_scale; - dy >>= 11 + cop_scale; - cop_dist_raw = sqrt((double)(dx*dx + dy*dy)); - - res = cop_dist_raw; - res /= div; - - cop_dist = (1 << (5 - cop_scale)) / div; - - /* TODO: bits 5-6-15 */ - cop_status = 7; - } - - m_host_space->write_word(cop_regs[0] + (0x38 ^ 2), res); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -09 - 4aa0 ( 09) ( 2a0) : (f9a, b9a, b9c, b9c, b9c, 99b, 000, 000) 5 fcdd (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -*/ -void raiden2cop_device::execute_4aa0(int offset, UINT16 data) -{ - int div = m_host_space->read_word(cop_regs[0] + (0x38)); - if (!div) - div = 1; - - /* TODO: bits 5-6-15 */ - cop_status = 7; - - m_host_space->write_word(cop_regs[0] + (0x36), (cop_dist << (5 - cop_scale)) / div); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -0a - 5105 ( 0a) ( 105) : (a80, 984, 082, 000, 000, 000, 000, 000) 5 fefb (cupsoc, grainbow) -0a - 5205 ( 0a) ( 205) : (180, 2e0, 3a0, 0a0, 3a0, 000, 000, 000) 6 fff7 (raiden2, raidendx) -0a - 5105 ( 0a) ( 105) : (180, 2e0, 0a0, 000, 000, 000, 000, 000) 6 fffb (zeroteam, xsedae) -*/ -void raiden2cop_device::execute_5205(int offset, UINT16 data) -{ - m_host_space->write_dword(cop_regs[1], m_host_space->read_dword(cop_regs[0])); -} -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -0b - 5905 ( 0b) ( 105) : (9c8, a84, 0a2, 000, 000, 000, 000, 000) 5 fffb (cupsoc, grainbow) -0b - 5a05 ( 0b) ( 205) : (180, 2e0, 3a0, 0a0, 3a0, 000, 000, 000) 6 fff7 (raiden2, raidendx) -0b - 5a85 ( 0b) ( 285) : (180, 2e0, 0a0, 182, 2e0, 0c0, 3c0, 3c0) 6 ffdb (zeroteam, xsedae) -*/ -void raiden2cop_device::execute_5a05(int offset, UINT16 data) -{ - m_host_space->write_dword(cop_regs[1], m_host_space->read_dword(cop_regs[0])); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -0c - 6200 ( 0c) ( 200) : (380, 39a, 380, a80, 29a, 000, 000, 000) 8 f3e7 (legionn, heatbrla, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -0c - 6200 ( 0c) ( 200) : (3a0, 3a6, 380, aa0, 2a6, 000, 000, 000) 8 f3e7 (cupsoc) -*/ -void raiden2cop_device::execute_6200(int offset, UINT16 data) -{ - int primary_reg = 0; - int primary_offset = 0x34; - - UINT8 angle = cop_read_byte(cop_regs[primary_reg] + primary_offset); - UINT16 flags = cop_read_word(cop_regs[primary_reg]); - cop_angle_target &= 0xff; - cop_angle_step &= 0xff; - flags &= ~0x0004; - int delta = angle - cop_angle_target; - if (delta >= 128) - delta -= 256; - else if (delta < -128) - delta += 256; - if (delta < 0) { - if (delta >= -cop_angle_step) { - angle = cop_angle_target; - flags |= 0x0004; - } - else - angle += cop_angle_step; - } - else { - if (delta <= cop_angle_step) { - angle = cop_angle_target; - flags |= 0x0004; - } - else - angle -= cop_angle_step; - } - - cop_write_word(cop_regs[primary_reg], flags); - - if (!m_host_endian) - cop_write_byte(cop_regs[primary_reg] + primary_offset, angle); - else // angle is a byte, but grainbow (cave mid-boss) is only happy with write-word, could be more endian weirdness, or it always writes a word? - cop_write_word(cop_regs[primary_reg] + primary_offset, angle); - -} - - -void raiden2cop_device::LEGACY_execute_6200(int offset, UINT16 data) // this is for cupsoc, different sequence, works on different registers -{ - int primary_reg = 1; - int primary_offset = 0xc; - - UINT8 angle = cop_read_byte(cop_regs[primary_reg] + primary_offset); - UINT16 flags = cop_read_word(cop_regs[primary_reg]); - cop_angle_target &= 0xff; - cop_angle_step &= 0xff; - flags &= ~0x0004; - int delta = angle - cop_angle_target; - if (delta >= 128) - delta -= 256; - else if (delta < -128) - delta += 256; - if (delta < 0) { - if (delta >= -cop_angle_step) { - angle = cop_angle_target; - flags |= 0x0004; - } - else - angle += cop_angle_step; - } - else { - if (delta <= cop_angle_step) { - angle = cop_angle_target; - flags |= 0x0004; - } - else - angle -= cop_angle_step; - } - - cop_write_word(cop_regs[primary_reg], flags); - - if (!m_host_endian) - cop_write_byte(cop_regs[primary_reg] + primary_offset, angle); - else // angle is a byte, but grainbow (cave mid-boss) is only happy with write-word, could be more endian weirdness, or it always writes a word? - cop_write_word(cop_regs[primary_reg] + primary_offset, angle); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -0d - 6880 ( 0d) ( 080) : (b80, ba0, 000, 000, 000, 000, 000, 000) a fff3 (legionna, heatbrl, cupsoc, godzilla, denjinmk) -0d - 6980 ( 0d) ( 180) : (b80, ba0, 000, 000, 000, 000, 000, 000) a fff3 (grainbow, zeroteam, xsedae) -*/ -void raiden2cop_device::LEGACY_execute_6980(int offset, UINT16 data) -{ - UINT8 offs; - int abs_x, abs_y, rel_xy; - - offs = (offset & 3) * 4; - - /* TODO: I really suspect that following two are actually taken from the 0xa180 macro command then internally loaded */ - abs_x = m_host_space->read_word(cop_regs[0] + 8) - m_cop_sprite_dma_abs_x; - abs_y = m_host_space->read_word(cop_regs[0] + 4) - m_cop_sprite_dma_abs_y; - rel_xy = m_host_space->read_word(m_cop_sprite_dma_src + 4 + offs); - - //if(rel_xy & 0x0706) - // printf("sprite rel_xy = %04x\n",rel_xy); - - if (rel_xy & 1) - m_host_space->write_word(cop_regs[4] + offs + 4, 0xc0 + abs_x - (rel_xy & 0xf8)); - else - m_host_space->write_word(cop_regs[4] + offs + 4, (((rel_xy & 0x78) + (abs_x)-((rel_xy & 0x80) ? 0x80 : 0)))); - - m_host_space->write_word(cop_regs[4] + offs + 6, (((rel_xy & 0x7800) >> 8) + (abs_y)-((rel_xy & 0x8000) ? 0x80 : 0))); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -0e - 7100 ( 0e) ( 100) : (b80, a80, b80, 000, 000, 000, 000, 000) 8 fdfd (zeroteam, xsedae) -*/ - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -0f - 7905 ( 0f) ( 105) : (1a2, 2c2, 0a2, 000, 000, 000, 000, 000) 6 fffb (cupsoc, grainbow) -0f - 7e05 ( 0f) ( 605) : (180, 282, 080, 180, 282, 000, 000, 000) 6 fffb (raidendx) -*/ - -void raiden2cop_device::execute_7e05(int offset, UINT16 data) // raidendx -{ - m_host_space->write_byte(0x470, m_host_space->read_byte(cop_regs[4])); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -10 - 8100 ( 10) ( 100) : (b9a, b88, 888, 000, 000, 000, 000, 000) 7 fdfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -*/ - -void raiden2cop_device::execute_8100(int offset, UINT16 data) -{ - int raw_angle = (cop_read_word(cop_regs[0] + (0x34)) & 0xff); - double angle = raw_angle * M_PI / 128; - double amp = (65536 >> 5)*(cop_read_word(cop_regs[0] + (0x36)) & 0xff); - int res; - // TODO: up direction needs to be doubled, happens on bootleg too, why is that? - if (raw_angle == 0xc0) - amp *= 2; - res = int(amp*sin(angle)) << cop_scale; - m_host_space->write_dword(cop_regs[0] + 16, res); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -11 - 8900 ( 11) ( 100) : (b9a, b8a, 88a, 000, 000, 000, 000, 000) 7 fdfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -*/ -void raiden2cop_device::execute_8900(int offset, UINT16 data) -{ - int raw_angle = (cop_read_word(cop_regs[0] + (0x34)) & 0xff); - double angle = raw_angle * M_PI / 128; - double amp = (65536 >> 5)*(cop_read_word(cop_regs[0] + (0x36)) & 0xff); - int res; - // TODO: left direction needs to be doubled, happens on bootleg too, why is that? - if (raw_angle == 0x80) - amp *= 2; - res = int(amp*cos(angle)) << cop_scale; - m_host_space->write_dword(cop_regs[0] + 20, res); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -12 - 9180 ( 12) ( 180) : (b80, b94, b94, 894, 000, 000, 000, 000) 7 f8f7 (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk) -12 - 9100 ( 12) ( 100) : (b80, b94, 894, 000, 000, 000, 000, 000) 7 fefb (raiden2, raidendx) -12 - 9100 ( 12) ( 100) : (b80, b94, b94, 894, 000, 000, 000, 000) 7 f8f7 (zeroteam, xsedae) -*/ -// Unused code suggests this may be an alternate sine function: the longword result at cop_regs[0] + 0x28 is doubled when the angle is 0xC0. - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -13 - 9980 ( 13) ( 180) : (b80, b96, b96, 896, 000, 000, 000, 000) 7 f8f7 (legionna, heatbrl) -13 - 9980 ( 13) ( 180) : (b80, b94, b94, 896, 000, 000, 000, 000) 7 f8f7 (cupsoc, grainbow, godzilla, denjinmk) -13 - 9900 ( 13) ( 100) : (b80, b94, 896, 000, 000, 000, 000, 000) 7 fefb (raiden2, raidendx) -13 - 9900 ( 13) ( 100) : (b80, b94, b94, 896, 000, 000, 000, 000) 7 f8f7 (zeroteam, xsedae) -*/ -// Unused code suggests this may be an alternate cosine function: the longword result at cop_regs[0] + 0x2C is doubled when the angle is 0x80. - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -14 - a180 ( 14) ( 180) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 ffff (legionna, cupsoc, godzilla, denjinmk) -14 - a100 ( 14) ( 100) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 ffff (heatbrl, zeroteam, xsedae) -14 - a180 ( 14) ( 180) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 02ff (grainbow) -14 - a100 ( 14) ( 100) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 00ff (raiden2, raidendx) -*/ - -// the last value (ffff / 02ff / 00ff depending on game) might be important here as they've been intentionally changed for the different games -void raiden2cop_device::execute_a100(int offset, UINT16 data) -{ - cop_collision_read_pos(0, cop_regs[0], data & 0x0080); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -15 - a980 ( 15) ( 180) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f ffff (legionna, cupsoc, godzilla, denjinmk) -15 - a900 ( 15) ( 100) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f ffff (heatbrl, zeroteam), xsedae -15 - a980 ( 15) ( 180) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f 02ff (grainbow) -15 - a900 ( 15) ( 100) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f 00ff (raiden2, raidendx)*/ -void raiden2cop_device::execute_a900(int offset, UINT16 data) -{ - cop_collision_read_pos(1, cop_regs[1], data & 0x0080); -} - - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -16 - b100 ( 16) ( 100) : (b40, bc0, bc2, 000, 000, 000, 000, 000) 9 ffff (legionna, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -16 - b080 ( 16) ( 080) : (b40, bc0, bc2, 000, 000, 000, 000, 000) 9 ffff (heatbrl) -*/ -void raiden2cop_device::execute_b100(int offset, UINT16 data) -{ - cop_collision_update_hitbox(data, 0, cop_regs[2]); -} - - - - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -17 - b900 ( 17) ( 100) : (b60, be0, be2, 000, 000, 000, 000, 000) 6 ffff (legionna, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) -17 - b880 ( 17) ( 080) : (b60, be0, be2, 000, 000, 000, 000, 000) 6 ffff (heatbrl) -*/ -void raiden2cop_device::execute_b900(int offset, UINT16 data) -{ - cop_collision_update_hitbox(data, 1, cop_regs[3]); -} - - - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -18 - c480 ( 18) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk) -18 - 7c80 ( 0f) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (zeroteam, xsedae) -*/ - -void raiden2cop_device::LEGACY_execute_c480(int offset, UINT16 data) -{ - UINT8 offs; - - offs = (offset & 3) * 4; - - m_host_space->write_word(cop_regs[4] + offs + 0, m_host_space->read_word(m_cop_sprite_dma_src + offs) + (m_cop_sprite_dma_param & 0x3f)); - //m_host_space->write_word(cop_regs[4] + offs + 2,m_host_space->read_word(m_cop_sprite_dma_src+2 + offs)); - -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -19 - cb8f ( 19) ( 38f) : (984, aa4, d82, aa2, 39b, b9a, b9a, a9f) 5 bf7f (cupsoc, grainbow) -*/ - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -1a - d104 ( 1a) ( 104) : (ac2, 9e0, 0a2, 000, 000, 000, 000, 000) 5 fffb (cupsoc, grainbow) -*/ -void raiden2cop_device::LEGACY_execute_d104(int offset, UINT16 data) -{ - UINT16 *ROM = (UINT16 *)m_host_space->machine().root_device().memregion("maincpu")->base(); - UINT32 rom_addr = (m_cop_rom_addr_hi << 16 | m_cop_rom_addr_lo); - UINT16 rom_data = ROM[rom_addr / 2]; - - /* writes to some unemulated COP registers, then puts the result in here, adding a parameter taken from ROM */ - //m_host_space->write_word(cop_regs[0]+(0x44 + offset * 4), rom_data); - - logerror("%04x%04x %04x %04x\n", m_cop_rom_addr_hi, m_cop_rom_addr_lo, m_cop_precmd, rom_data); -} -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -1b - dde5 ( 1b) ( 5e5) : (f80, aa2, 984, 0c2, 000, 000, 000, 000) 5 7ff7 (cupsoc, grainbow) -*/ - -void raiden2cop_device::LEGACY_execute_dde5(int offset, UINT16 data) -{ - UINT8 offs; - int div; - INT16 dir_offset; - // INT16 offs_val; - - /* TODO: [4-7] could be mirrors of [0-3] (this is the only command so far that uses 4-7 actually)*/ - /* ? 0 + [4] */ - /* sub32 4 + [5] */ - /* write16h 8 + [4] */ - /* addmem16 4 + [6] */ - - // these two are obvious ... - // 0xf x 16 = 240 - // 0x14 x 16 = 320 - // what are these two instead? scale factor? offsets? (edit: offsets to apply from the initial sprite data) - // 0xfc69 ? - // 0x7f4 ? - //printf("%08x %08x %08x %08x %08x %08x %08x\n",cop_regs[0],cop_regs[1],cop_regs[2],cop_regs[3],cop_regs[4],cop_regs[5],cop_regs[6]); - - offs = (offset & 3) * 4; - - div = m_host_space->read_word(cop_regs[4] + offs); - dir_offset = m_host_space->read_word(cop_regs[4] + offs + 8); - // offs_val = m_host_space.read_word(cop_regs[3] + offs); - //420 / 180 = 500 : 400 = 30 / 50 = 98 / 18 - - /* TODO: this probably trips a cop status flag */ - if (div == 0) { div = 1; } - - - m_host_space->write_word((cop_regs[6] + offs + 4), ((m_host_space->read_word(cop_regs[5] + offs + 4) + dir_offset) / div)); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -1c - e38e ( 1c) ( 38e) : (984, ac4, d82, ac2, 39b, b9a, b9a, a9a) 5 b07f (cupsoc, grainbow) -1c - e105 ( 1c) ( 105) : (a88, 994, 088, 000, 000, 000, 000, 000) 5 06fb (zeroteam, xsedae) -*/ - -void raiden2cop_device::LEGACY_execute_e30e(int offset, UINT16 data) -{ - int dy = m_host_space->read_dword(cop_regs[2] + 4) - m_host_space->read_dword(cop_regs[0] + 4); - int dx = m_host_space->read_dword(cop_regs[2] + 8) - m_host_space->read_dword(cop_regs[0] + 8); - - cop_status = 7; - if (!dx) { - cop_status |= 0x8000; - cop_angle = 0; - } - else { - cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI); - if (dx < 0) - cop_angle += 0x80; - } - - m_LEGACY_r0 = dy; - m_LEGACY_r1 = dx; - - //printf("%d %d %f %04x\n",dx,dy,atan(double(dy)/double(dx)) * 128 / M_PI,cop_angle); - - if (data & 0x80) - m_host_space->write_word(cop_regs[0] + (0x34 ^ 2), cop_angle); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -1d - eb8e ( 1d) ( 38e) : (984, ac4, d82, ac2, 39b, b9a, b9a, a9f) 5 b07f (cupsoc, grainbow) -1d - ede5 ( 1d) ( 5e5) : (f88, a84, 986, 08a, 000, 000, 000, 000) 5 05f7 (zeroteam, xsedae) -*/ - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -1e - f105 ( 1e) ( 105) : (a88, 994, 088, 000, 000, 000, 000, 000) 5 fefb (cupsoc, grainbow) -1e - f205 ( 1e) ( 205) : (182, 2e0, 3c0, 0c0, 3c0, 000, 000, 000) 6 fff7 (raiden2, raidendx) -1e - f790 ( 1e) ( 790) : (f80, b84, b84, b84, b84, b84, b84, b84) 4 00ff (zeroteam, xsedae) -*/ - -void raiden2cop_device::execute_f205(int offset, UINT16 data) -{ - m_host_space->write_dword(cop_regs[2], m_host_space->read_dword(cop_regs[0]+4)); -} - -/* -## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask -1f - fc84 ( 1f) ( 484) : (182, 280, 000, 000, 000, 000, 000, 000) 6 00ff (zeroteam, xsedae) -*/ - - - - - - - - - READ16_MEMBER( raiden2cop_device::cop_status_r) { return cop_status; diff --git a/src/mame/machine/seibucop/seibucop.h b/src/mame/machine/seibucop/seibucop.h index eefda38ca1a..69b0a4973d7 100644 --- a/src/mame/machine/seibucop/seibucop.h +++ b/src/mame/machine/seibucop/seibucop.h @@ -10,8 +10,9 @@ #ifndef RAIDEN2COP_H #define RAIDEN2COP_H - - +#define LOG_Commands 0 +#define LOG_Phytagoras 0 +#define LOG_Division 0 #define MCFG_RAIDEN2COP_VIDEORAM_OUT_CB(_devcb) \ devcb = &raiden2cop_device::set_m_videoramout_cb(*device, DEVCB_##_devcb); diff --git a/src/mame/machine/seibucop/seibucop_cmd.hxx b/src/mame/machine/seibucop/seibucop_cmd.hxx new file mode 100644 index 00000000000..f3f386f4243 --- /dev/null +++ b/src/mame/machine/seibucop/seibucop_cmd.hxx @@ -0,0 +1,700 @@ + + +/* Main COP functionality */ + +// notes about tables: +// (TABLENOTE1) +// in all but one case the upload table position (5-bits) is the SAME as the upper 5-bits of the 'trigger value' +// the exception to this rule is program 0x18 uploads on zeroteam +// in this case you can see that the 'trigger' value upper bits are 0x0f, this would be potentially interesting if it were used (but it isn't) +// 18 - c480 ( 18) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk) +// 18 - 7c80 ( 0f) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (zeroteam, xsedae) + +// It is unknown if the lower 11 bits uploaded as part of the 'trigger' value to the table are used during execution. +// When the actual trigger is written these bits can be different to the upload and for the written value we know they give extended +// meanings to the commands (eg. signs swapped in operations - for program 0x01 (0905) Zero Team writes 0904 (lowest bit different to uploaded +// value) to negate the logic + +/* + +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +00 - 0205 ( 00) ( 205) : (188, 282, 082, b8e, 98e, 000, 000, 000) 6 ffeb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +00 - 0105 ( 00) ( 105) : (180, 2e0, 0a0, 000, 000, 000, 000, 000) 6 fffb (zeroteamsr) +*/ +void raiden2cop_device::execute_0205(int offset, UINT16 data) +{ + int ppos = m_host_space->read_dword(cop_regs[0] + 4 + offset * 4); + int npos = ppos + m_host_space->read_dword(cop_regs[0] + 0x10 + offset * 4); + int delta = (npos >> 16) - (ppos >> 16); + m_host_space->write_dword(cop_regs[0] + 4 + offset * 4, npos); + cop_write_word(cop_regs[0] + 0x1e + offset * 4, cop_read_word(cop_regs[0] + 0x1e + offset * 4) + delta); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +01 - 0905 ( 01) ( 105) : (194, 288, 088, 000, 000, 000, 000, 000) 6 fbfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +01 - 0b05 ( 01) ( 305) : (180, 2e0, 0a0, 182, 2e0, 0c0, 000, 000) 6 ffdb (zeroteamsr) +*/ + +// triggered with 0904 0905 + +void raiden2cop_device::execute_0904(int offset, UINT16 data) +{ + if (data&0x0001) + m_host_space->write_dword(cop_regs[0] + 16 + offset * 4, m_host_space->read_dword(cop_regs[0] + 16 + offset * 4) + m_host_space->read_dword(cop_regs[0] + 0x28 + offset * 4)); + else /* X Se Dae and Zero Team uses this variant */ + m_host_space->write_dword(cop_regs[0] + 16 + offset * 4, m_host_space->read_dword(cop_regs[0] + 16 + offset * 4) - m_host_space->read_dword(cop_regs[0] + 0x28 + offset * 4)); +} + + + + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +02 - 138e ( 02) ( 38e) : (984, aa4, d82, aa2, 39b, b9a, b9a, b9a) 5 bf7f (legionna, heatbrl) +02 - 138e ( 02) ( 38e) : (984, aa4, d82, aa2, 39b, b9a, b9a, a9a) 5 bf7f (cupsoc, grainbow, godzilla, denjinmk) +02 - 130e ( 02) ( 30e) : (984, aa4, d82, aa2, 39b, b9a, b9a, a9a) 5 bf7f (raiden2, raidendx, zeroteam, xsedae) +*/ + +// triggered with 130e, 138e +void raiden2cop_device::execute_130e(int offset, UINT16 data) +{ + // this can't be right + execute_338e(offset, data); +} + +void raiden2cop_device::LEGACY_execute_130e(int offset, UINT16 data) +{ + int dy = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); + int dx = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); + + cop_status = 7; + if (!dx) { + cop_status |= 0x8000; + cop_angle = 0; + } + else { + cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI); + if (dx < 0) + cop_angle += 0x80; + } + + m_LEGACY_r0 = dy; + m_LEGACY_r1 = dx; + + if (data & 0x80) + m_host_space->write_word(cop_regs[0] + (0x34 ^ 2), cop_angle); +} + +void raiden2cop_device::LEGACY_execute_130e_cupsoc(int offset, UINT16 data) +{ + int dy = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); + int dx = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); + + cop_status = 7; + if (!dx) { + cop_status |= 0x8000; + cop_angle = 0; + } + else { + cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI); + if (dx < 0) + cop_angle += 0x80; + } + + m_LEGACY_r0 = dy; + m_LEGACY_r1 = dx; + + //printf("%d %d %f %04x\n",dx,dy,atan(double(dy)/double(dx)) * 128 / M_PI,cop_angle); + + if (data & 0x80) + m_host_space->write_word(cop_regs[0] + (0x34 ^ 2), cop_angle); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +03 - 1905 ( 03) ( 105) : (994, a88, 088, 000, 000, 000, 000, 000) 6 fbfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +*/ + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +04 - 2288 ( 04) ( 288) : (f8a, b8a, 388, b9c, b9a, a9a, 000, 000) 5 f5df (legionna, heatbrl) +04 - 2288 ( 04) ( 288) : (f8a, b8a, 388, b9a, b9a, a9a, 000, 000) 5 f5df (cupsoc, grainbow, godzilla, denjinmk) +04 - 2208 ( 04) ( 208) : (f8a, b8a, 388, b9a, b9a, a9a, 000, 000) 5 f5df (raiden2, raidendx, zeroteam, xsedae) +*/ + +// also triggered with 0x2208 +void raiden2cop_device::execute_2288(int offset, UINT16 data) +{ + int dx = m_host_space->read_word(cop_regs[0] + 0x12); + int dy = m_host_space->read_word(cop_regs[0] + 0x16); + + if (!dy) { + cop_status |= 0x8000; + cop_angle = 0; + } + else { + cop_angle = (int)(atan(double(dx) / double(dy)) * 128 / M_PI); + if (dy < 0) + cop_angle += 0x80; + } + + if (data & 0x0080) { + m_host_space->write_byte(cop_regs[0] + 0x34, cop_angle); + } +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +05 - 2a05 ( 05) ( 205) : (9af, a82, 082, a8f, 18e, 000, 000, 000) 6 ebeb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +*/ + +void raiden2cop_device::execute_2a05(int offset, UINT16 data) +{ + int delta = m_host_space->read_word(cop_regs[1] + 0x1e + offset * 4); + m_host_space->write_dword(cop_regs[0] + 4 + 2 + offset * 4, m_host_space->read_word(cop_regs[0] + 4 + 2 + offset * 4) + delta); + m_host_space->write_dword(cop_regs[0] + 0x1e + offset * 4, m_host_space->read_word(cop_regs[0] + 0x1e + offset * 4) + delta); +} + + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +06 - 338e ( 06) ( 38e) : (984, aa4, d82, aa2, 39c, b9c, b9c, a9a) 5 bf7f (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx) +06 - 330e ( 06) ( 30e) : (984, aa4, d82, aa2, 39c, b9c, b9c, a9a) 5 bf7f (zeroteam, xsedae) +*/ +void raiden2cop_device::execute_338e(int offset, UINT16 data) +{ + int dx = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); + int dy = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); + + if (!dy) { + cop_status |= 0x8000; + cop_angle = 0; + } + else { + cop_angle = (int)(atan(double(dx) / double(dy)) * 128 / M_PI); + if (dy < 0) + cop_angle += 0x80; + } + +#if LOG_Phytagoras + printf("cmd %04x: dx = %d dy = %d angle = %02x\n",data,dx,dy,cop_angle); +#endif + + if (data & 0x0080) { + m_host_space->write_byte(cop_regs[0] + 0x34, cop_angle); + } +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +07 - 3bb0 ( 07) ( 3b0) : (f9c, b9c, b9c, b9c, b9c, b9c, b9c, 99c) 4 007f (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, +07 - 3b30 ( 07) ( 330) : (f9c, b9c, b9c, b9c, b9c, b9c, b9c, 99c) 4 007f (zeroteam, xsedae) +*/ + +// triggered with 0x39b0, 0x3b30, 0x3bb0 + +void raiden2cop_device::execute_3b30(int offset, UINT16 data) +{ + /* TODO: these are actually internally loaded via 0x130e command */ + int dx, dy; + + dx = m_host_space->read_dword(cop_regs[1] + 4) - m_host_space->read_dword(cop_regs[0] + 4); + dy = m_host_space->read_dword(cop_regs[1] + 8) - m_host_space->read_dword(cop_regs[0] + 8); + + dx = dx >> 16; + dy = dy >> 16; + cop_dist = sqrt((double)(dx*dx + dy*dy)); + +#if LOG_Phytagoras + printf("cmd %04x: dx = %d dy = %d dist = %08x \n",data,dx >> 16,dy >> 16,cop_dist); +#endif + + if (data & 0x0080) + m_host_space->write_word(cop_regs[0] + (data & 0x200 ? 0x3a : 0x38), cop_dist); +} + +void raiden2cop_device::LEGACY_execute_3b30(int offset, UINT16 data) +{ + int dy = m_LEGACY_r0; + int dx = m_LEGACY_r1; + + dx >>= 16; + dy >>= 16; + cop_dist = sqrt((double)(dx*dx + dy*dy)); + + if (data & 0x80) + m_host_space->write_word(cop_regs[0] + (0x38), cop_dist); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +08 - 42c2 ( 08) ( 2c2) : (f9a, b9a, b9c, b9c, b9c, 29c, 000, 000) 5 fcdd (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +*/ +void raiden2cop_device::execute_42c2(int offset, UINT16 data) +{ + int div = m_host_space->read_word(cop_regs[0] + (0x36)); + +#if LOG_Division + printf("cmd %04x: div = %04x scale = %04x\n",data,div,cop_scale); +#endif + + if (!div) + { + cop_status |= 0x8000; + m_host_space->write_word(cop_regs[0] + (0x38), 0); + return; + } + + /* TODO: bits 5-6-15 */ + cop_status = 7; + +#if LOG_Division + printf("res = %04x dist %04x\n",(cop_dist << (5 - cop_scale)) / div,cop_dist); + +// if(div & 0x8000) +// machine().debugger().debug_break(); +#endif + + m_host_space->write_word(cop_regs[0] + (0x38), (cop_dist << (5 - cop_scale)) / div); +} + +void raiden2cop_device::LEGACY_execute_42c2(int offset, UINT16 data) +{ + int dy = m_LEGACY_r0; + int dx = m_LEGACY_r1; + int div = m_host_space->read_word(cop_regs[0] + (0x36 ^ 2)); + int res; + int cop_dist_raw; + + // divide by zero? + if (!div) + { + // No emulation error here: heatbrl specifically tests this + cop_status |= 0x8000; + res = 0; + } + else + { + /* TODO: calculation of this one should occur at 0x3b30/0x3bb0 I *think* */ + /* TODO: recheck if cop_scale still masks at 3 with this command */ + dx >>= 11 + cop_scale; + dy >>= 11 + cop_scale; + cop_dist_raw = sqrt((double)(dx*dx + dy*dy)); + + res = cop_dist_raw; + res /= div; + + cop_dist = (1 << (5 - cop_scale)) / div; + + /* TODO: bits 5-6-15 */ + cop_status = 7; + } + + m_host_space->write_word(cop_regs[0] + (0x38 ^ 2), res); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +09 - 4aa0 ( 09) ( 2a0) : (f9a, b9a, b9c, b9c, b9c, 99b, 000, 000) 5 fcdd (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +*/ +void raiden2cop_device::execute_4aa0(int offset, UINT16 data) +{ + int div = m_host_space->read_word(cop_regs[0] + (0x38)); + if (!div) + div = 1; + + /* TODO: bits 5-6-15 */ + cop_status = 7; + + m_host_space->write_word(cop_regs[0] + (0x36), (cop_dist << (5 - cop_scale)) / div); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +0a - 5105 ( 0a) ( 105) : (a80, 984, 082, 000, 000, 000, 000, 000) 5 fefb (cupsoc, grainbow) +0a - 5205 ( 0a) ( 205) : (180, 2e0, 3a0, 0a0, 3a0, 000, 000, 000) 6 fff7 (raiden2, raidendx) +0a - 5105 ( 0a) ( 105) : (180, 2e0, 0a0, 000, 000, 000, 000, 000) 6 fffb (zeroteam, xsedae) +*/ +void raiden2cop_device::execute_5205(int offset, UINT16 data) +{ + m_host_space->write_dword(cop_regs[1], m_host_space->read_dword(cop_regs[0])); +} +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +0b - 5905 ( 0b) ( 105) : (9c8, a84, 0a2, 000, 000, 000, 000, 000) 5 fffb (cupsoc, grainbow) +0b - 5a05 ( 0b) ( 205) : (180, 2e0, 3a0, 0a0, 3a0, 000, 000, 000) 6 fff7 (raiden2, raidendx) +0b - 5a85 ( 0b) ( 285) : (180, 2e0, 0a0, 182, 2e0, 0c0, 3c0, 3c0) 6 ffdb (zeroteam, xsedae) +*/ +void raiden2cop_device::execute_5a05(int offset, UINT16 data) +{ + m_host_space->write_dword(cop_regs[1], m_host_space->read_dword(cop_regs[0])); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +0c - 6200 ( 0c) ( 200) : (380, 39a, 380, a80, 29a, 000, 000, 000) 8 f3e7 (legionn, heatbrla, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +0c - 6200 ( 0c) ( 200) : (3a0, 3a6, 380, aa0, 2a6, 000, 000, 000) 8 f3e7 (cupsoc) +*/ +void raiden2cop_device::execute_6200(int offset, UINT16 data) +{ + int primary_reg = 0; + int primary_offset = 0x34; + + UINT8 angle = cop_read_byte(cop_regs[primary_reg] + primary_offset); + UINT16 flags = cop_read_word(cop_regs[primary_reg]); + cop_angle_target &= 0xff; + cop_angle_step &= 0xff; + flags &= ~0x0004; + int delta = angle - cop_angle_target; + if (delta >= 128) + delta -= 256; + else if (delta < -128) + delta += 256; + if (delta < 0) { + if (delta >= -cop_angle_step) { + angle = cop_angle_target; + flags |= 0x0004; + } + else + angle += cop_angle_step; + } + else { + if (delta <= cop_angle_step) { + angle = cop_angle_target; + flags |= 0x0004; + } + else + angle -= cop_angle_step; + } + + cop_write_word(cop_regs[primary_reg], flags); + + if (!m_host_endian) + cop_write_byte(cop_regs[primary_reg] + primary_offset, angle); + else // angle is a byte, but grainbow (cave mid-boss) is only happy with write-word, could be more endian weirdness, or it always writes a word? + cop_write_word(cop_regs[primary_reg] + primary_offset, angle); + +} + + +void raiden2cop_device::LEGACY_execute_6200(int offset, UINT16 data) // this is for cupsoc, different sequence, works on different registers +{ + int primary_reg = 1; + int primary_offset = 0xc; + + UINT8 angle = cop_read_byte(cop_regs[primary_reg] + primary_offset); + UINT16 flags = cop_read_word(cop_regs[primary_reg]); + cop_angle_target &= 0xff; + cop_angle_step &= 0xff; + flags &= ~0x0004; + int delta = angle - cop_angle_target; + if (delta >= 128) + delta -= 256; + else if (delta < -128) + delta += 256; + if (delta < 0) { + if (delta >= -cop_angle_step) { + angle = cop_angle_target; + flags |= 0x0004; + } + else + angle += cop_angle_step; + } + else { + if (delta <= cop_angle_step) { + angle = cop_angle_target; + flags |= 0x0004; + } + else + angle -= cop_angle_step; + } + + cop_write_word(cop_regs[primary_reg], flags); + + if (!m_host_endian) + cop_write_byte(cop_regs[primary_reg] + primary_offset, angle); + else // angle is a byte, but grainbow (cave mid-boss) is only happy with write-word, could be more endian weirdness, or it always writes a word? + cop_write_word(cop_regs[primary_reg] + primary_offset, angle); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +0d - 6880 ( 0d) ( 080) : (b80, ba0, 000, 000, 000, 000, 000, 000) a fff3 (legionna, heatbrl, cupsoc, godzilla, denjinmk) +0d - 6980 ( 0d) ( 180) : (b80, ba0, 000, 000, 000, 000, 000, 000) a fff3 (grainbow, zeroteam, xsedae) +*/ +void raiden2cop_device::LEGACY_execute_6980(int offset, UINT16 data) +{ + UINT8 offs; + int abs_x, abs_y, rel_xy; + + offs = (offset & 3) * 4; + + /* TODO: I really suspect that following two are actually taken from the 0xa180 macro command then internally loaded */ + abs_x = m_host_space->read_word(cop_regs[0] + 8) - m_cop_sprite_dma_abs_x; + abs_y = m_host_space->read_word(cop_regs[0] + 4) - m_cop_sprite_dma_abs_y; + rel_xy = m_host_space->read_word(m_cop_sprite_dma_src + 4 + offs); + + //if(rel_xy & 0x0706) + // printf("sprite rel_xy = %04x\n",rel_xy); + + if (rel_xy & 1) + m_host_space->write_word(cop_regs[4] + offs + 4, 0xc0 + abs_x - (rel_xy & 0xf8)); + else + m_host_space->write_word(cop_regs[4] + offs + 4, (((rel_xy & 0x78) + (abs_x)-((rel_xy & 0x80) ? 0x80 : 0)))); + + m_host_space->write_word(cop_regs[4] + offs + 6, (((rel_xy & 0x7800) >> 8) + (abs_y)-((rel_xy & 0x8000) ? 0x80 : 0))); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +0e - 7100 ( 0e) ( 100) : (b80, a80, b80, 000, 000, 000, 000, 000) 8 fdfd (zeroteam, xsedae) +*/ + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +0f - 7905 ( 0f) ( 105) : (1a2, 2c2, 0a2, 000, 000, 000, 000, 000) 6 fffb (cupsoc, grainbow) +0f - 7e05 ( 0f) ( 605) : (180, 282, 080, 180, 282, 000, 000, 000) 6 fffb (raidendx) +*/ + +void raiden2cop_device::execute_7e05(int offset, UINT16 data) // raidendx +{ + m_host_space->write_byte(0x470, m_host_space->read_byte(cop_regs[4])); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +10 - 8100 ( 10) ( 100) : (b9a, b88, 888, 000, 000, 000, 000, 000) 7 fdfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +*/ + +void raiden2cop_device::execute_8100(int offset, UINT16 data) +{ + int raw_angle = (cop_read_word(cop_regs[0] + (0x34)) & 0xff); + double angle = raw_angle * M_PI / 128; + double amp = (65536 >> 5)*(cop_read_word(cop_regs[0] + (0x36)) & 0xff); + int res; + // TODO: up direction needs to be doubled, happens on bootleg too, why is that? + if (raw_angle == 0xc0) + amp *= 2; + res = int(amp*sin(angle)) << cop_scale; + m_host_space->write_dword(cop_regs[0] + 16, res); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +11 - 8900 ( 11) ( 100) : (b9a, b8a, 88a, 000, 000, 000, 000, 000) 7 fdfb (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +*/ +void raiden2cop_device::execute_8900(int offset, UINT16 data) +{ + int raw_angle = (cop_read_word(cop_regs[0] + (0x34)) & 0xff); + double angle = raw_angle * M_PI / 128; + double amp = (65536 >> 5)*(cop_read_word(cop_regs[0] + (0x36)) & 0xff); + int res; + // TODO: left direction needs to be doubled, happens on bootleg too, why is that? + if (raw_angle == 0x80) + amp *= 2; + res = int(amp*cos(angle)) << cop_scale; + m_host_space->write_dword(cop_regs[0] + 20, res); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +12 - 9180 ( 12) ( 180) : (b80, b94, b94, 894, 000, 000, 000, 000) 7 f8f7 (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk) +12 - 9100 ( 12) ( 100) : (b80, b94, 894, 000, 000, 000, 000, 000) 7 fefb (raiden2, raidendx) +12 - 9100 ( 12) ( 100) : (b80, b94, b94, 894, 000, 000, 000, 000) 7 f8f7 (zeroteam, xsedae) +*/ +// Unused code suggests this may be an alternate sine function: the longword result at cop_regs[0] + 0x28 is doubled when the angle is 0xC0. + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +13 - 9980 ( 13) ( 180) : (b80, b96, b96, 896, 000, 000, 000, 000) 7 f8f7 (legionna, heatbrl) +13 - 9980 ( 13) ( 180) : (b80, b94, b94, 896, 000, 000, 000, 000) 7 f8f7 (cupsoc, grainbow, godzilla, denjinmk) +13 - 9900 ( 13) ( 100) : (b80, b94, 896, 000, 000, 000, 000, 000) 7 fefb (raiden2, raidendx) +13 - 9900 ( 13) ( 100) : (b80, b94, b94, 896, 000, 000, 000, 000) 7 f8f7 (zeroteam, xsedae) +*/ +// Unused code suggests this may be an alternate cosine function: the longword result at cop_regs[0] + 0x2C is doubled when the angle is 0x80. + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +14 - a180 ( 14) ( 180) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 ffff (legionna, cupsoc, godzilla, denjinmk) +14 - a100 ( 14) ( 100) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 ffff (heatbrl, zeroteam, xsedae) +14 - a180 ( 14) ( 180) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 02ff (grainbow) +14 - a100 ( 14) ( 100) : (b80, b82, b84, b86, 000, 000, 000, 000) 0 00ff (raiden2, raidendx) +*/ + +// the last value (ffff / 02ff / 00ff depending on game) might be important here as they've been intentionally changed for the different games +void raiden2cop_device::execute_a100(int offset, UINT16 data) +{ + cop_collision_read_pos(0, cop_regs[0], data & 0x0080); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +15 - a980 ( 15) ( 180) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f ffff (legionna, cupsoc, godzilla, denjinmk) +15 - a900 ( 15) ( 100) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f ffff (heatbrl, zeroteam), xsedae +15 - a980 ( 15) ( 180) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f 02ff (grainbow) +15 - a900 ( 15) ( 100) : (ba0, ba2, ba4, ba6, 000, 000, 000, 000) f 00ff (raiden2, raidendx)*/ +void raiden2cop_device::execute_a900(int offset, UINT16 data) +{ + cop_collision_read_pos(1, cop_regs[1], data & 0x0080); +} + + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +16 - b100 ( 16) ( 100) : (b40, bc0, bc2, 000, 000, 000, 000, 000) 9 ffff (legionna, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +16 - b080 ( 16) ( 080) : (b40, bc0, bc2, 000, 000, 000, 000, 000) 9 ffff (heatbrl) +*/ +void raiden2cop_device::execute_b100(int offset, UINT16 data) +{ + cop_collision_update_hitbox(data, 0, cop_regs[2]); +} + + + + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +17 - b900 ( 17) ( 100) : (b60, be0, be2, 000, 000, 000, 000, 000) 6 ffff (legionna, cupsoc, grainbow, godzilla, denjinmk, raiden2, raidendx, zeroteam, xsedae) +17 - b880 ( 17) ( 080) : (b60, be0, be2, 000, 000, 000, 000, 000) 6 ffff (heatbrl) +*/ +void raiden2cop_device::execute_b900(int offset, UINT16 data) +{ + cop_collision_update_hitbox(data, 1, cop_regs[3]); +} + + + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +18 - c480 ( 18) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (legionna, heatbrl, cupsoc, grainbow, godzilla, denjinmk) +18 - 7c80 ( 0f) ( 480) : (080, 882, 000, 000, 000, 000, 000, 000) a ff00 (zeroteam, xsedae) +*/ + +void raiden2cop_device::LEGACY_execute_c480(int offset, UINT16 data) +{ + UINT8 offs; + + offs = (offset & 3) * 4; + + m_host_space->write_word(cop_regs[4] + offs + 0, m_host_space->read_word(m_cop_sprite_dma_src + offs) + (m_cop_sprite_dma_param & 0x3f)); + //m_host_space->write_word(cop_regs[4] + offs + 2,m_host_space->read_word(m_cop_sprite_dma_src+2 + offs)); + +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +19 - cb8f ( 19) ( 38f) : (984, aa4, d82, aa2, 39b, b9a, b9a, a9f) 5 bf7f (cupsoc, grainbow) +*/ + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +1a - d104 ( 1a) ( 104) : (ac2, 9e0, 0a2, 000, 000, 000, 000, 000) 5 fffb (cupsoc, grainbow) +*/ +void raiden2cop_device::LEGACY_execute_d104(int offset, UINT16 data) +{ + UINT16 *ROM = (UINT16 *)m_host_space->machine().root_device().memregion("maincpu")->base(); + UINT32 rom_addr = (m_cop_rom_addr_hi << 16 | m_cop_rom_addr_lo); + UINT16 rom_data = ROM[rom_addr / 2]; + + /* writes to some unemulated COP registers, then puts the result in here, adding a parameter taken from ROM */ + //m_host_space->write_word(cop_regs[0]+(0x44 + offset * 4), rom_data); + + logerror("%04x%04x %04x %04x\n", m_cop_rom_addr_hi, m_cop_rom_addr_lo, m_cop_precmd, rom_data); +} +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +1b - dde5 ( 1b) ( 5e5) : (f80, aa2, 984, 0c2, 000, 000, 000, 000) 5 7ff7 (cupsoc, grainbow) +*/ + +void raiden2cop_device::LEGACY_execute_dde5(int offset, UINT16 data) +{ + UINT8 offs; + int div; + INT16 dir_offset; + // INT16 offs_val; + + /* TODO: [4-7] could be mirrors of [0-3] (this is the only command so far that uses 4-7 actually)*/ + /* ? 0 + [4] */ + /* sub32 4 + [5] */ + /* write16h 8 + [4] */ + /* addmem16 4 + [6] */ + + // these two are obvious ... + // 0xf x 16 = 240 + // 0x14 x 16 = 320 + // what are these two instead? scale factor? offsets? (edit: offsets to apply from the initial sprite data) + // 0xfc69 ? + // 0x7f4 ? + //printf("%08x %08x %08x %08x %08x %08x %08x\n",cop_regs[0],cop_regs[1],cop_regs[2],cop_regs[3],cop_regs[4],cop_regs[5],cop_regs[6]); + + offs = (offset & 3) * 4; + + div = m_host_space->read_word(cop_regs[4] + offs); + dir_offset = m_host_space->read_word(cop_regs[4] + offs + 8); + // offs_val = m_host_space.read_word(cop_regs[3] + offs); + //420 / 180 = 500 : 400 = 30 / 50 = 98 / 18 + + /* TODO: this probably trips a cop status flag */ + if (div == 0) { div = 1; } + + + m_host_space->write_word((cop_regs[6] + offs + 4), ((m_host_space->read_word(cop_regs[5] + offs + 4) + dir_offset) / div)); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +1c - e38e ( 1c) ( 38e) : (984, ac4, d82, ac2, 39b, b9a, b9a, a9a) 5 b07f (cupsoc, grainbow) +1c - e105 ( 1c) ( 105) : (a88, 994, 088, 000, 000, 000, 000, 000) 5 06fb (zeroteam, xsedae) +*/ + +void raiden2cop_device::LEGACY_execute_e30e(int offset, UINT16 data) +{ + int dy = m_host_space->read_dword(cop_regs[2] + 4) - m_host_space->read_dword(cop_regs[0] + 4); + int dx = m_host_space->read_dword(cop_regs[2] + 8) - m_host_space->read_dword(cop_regs[0] + 8); + + cop_status = 7; + if (!dx) { + cop_status |= 0x8000; + cop_angle = 0; + } + else { + cop_angle = (int)(atan(double(dy) / double(dx)) * 128.0 / M_PI); + if (dx < 0) + cop_angle += 0x80; + } + + m_LEGACY_r0 = dy; + m_LEGACY_r1 = dx; + + //printf("%d %d %f %04x\n",dx,dy,atan(double(dy)/double(dx)) * 128 / M_PI,cop_angle); + + if (data & 0x80) + m_host_space->write_word(cop_regs[0] + (0x34 ^ 2), cop_angle); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +1d - eb8e ( 1d) ( 38e) : (984, ac4, d82, ac2, 39b, b9a, b9a, a9f) 5 b07f (cupsoc, grainbow) +1d - ede5 ( 1d) ( 5e5) : (f88, a84, 986, 08a, 000, 000, 000, 000) 5 05f7 (zeroteam, xsedae) +*/ + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +1e - f105 ( 1e) ( 105) : (a88, 994, 088, 000, 000, 000, 000, 000) 5 fefb (cupsoc, grainbow) +1e - f205 ( 1e) ( 205) : (182, 2e0, 3c0, 0c0, 3c0, 000, 000, 000) 6 fff7 (raiden2, raidendx) +1e - f790 ( 1e) ( 790) : (f80, b84, b84, b84, b84, b84, b84, b84) 4 00ff (zeroteam, xsedae) +*/ + +void raiden2cop_device::execute_f205(int offset, UINT16 data) +{ + m_host_space->write_dword(cop_regs[2], m_host_space->read_dword(cop_regs[0]+4)); +} + +/* +## - trig (up5) (low11) : (sq0, sq1, sq2, sq3, sq4, sq5, sq6, sq7) valu mask +1f - fc84 ( 1f) ( 484) : (182, 280, 000, 000, 000, 000, 000, 000) 6 00ff (zeroteam, xsedae) +*/ + + + diff --git a/src/mame/machine/seibucop/seibucop_dma.hxx b/src/mame/machine/seibucop/seibucop_dma.hxx new file mode 100644 index 00000000000..d0cd8d4b714 --- /dev/null +++ b/src/mame/machine/seibucop/seibucop_dma.hxx @@ -0,0 +1,152 @@ + +// ALL games use this - tilemap DMA (RAM -> private buffer) +void raiden2cop_device::dma_tilemap_buffer() +{ + int src = cop_dma_src[cop_dma_mode] << 6; + if (src == 0xcfc0) src = 0xd000; // R2, why?? everything else sets the right pointer (it also sets up odd size / dest regs, they probably counteract this) + + for (int i = 0; i < 0x2800 / 2; i++) + { + UINT16 tileval = m_host_space->read_word(src); + src += 2; + m_videoramout_cb(i, tileval, 0xffff); + } +} + + // ALL games use this - palette DMA (RAM -> private buffer) +void raiden2cop_device::dma_palette_buffer() +{ + int src = cop_dma_src[cop_dma_mode] << 6; + + for (int i = 0; i < 0x1000 / 2; i++) // todo, use length register + { + UINT16 palval = m_host_space->read_word(src); + src += 2; + m_palette->set_pen_color(i, pal5bit(palval >> 0), pal5bit(palval >> 5), pal5bit(palval >> 10)); + } +} + +// these are typically used to transfer palette data from one RAM buffer to another, applying fade values to it prior to the 0x15 transfer +void raiden2cop_device::dma_palette_brightness() +{ + UINT32 src, dst, size, i; + + /* + Apparently all of those are just different DMA channels, brightness effects are done through a RAM table and the pal_brightness_val / mode + 0x80 is used by Legionnaire + 0x81 is used by SD Gundam and Godzilla + 0x82 is used by Zero Team and X Se Dae + 0x86 is used by Seibu Cup Soccer + 0x87 is used by Denjin Makai + + TODO: + - Denjin Makai mode 4 is totally guessworked. + - SD Gundam doesn't fade colors correctly, it should have the text layer / sprites with normal gradient and the rest dimmed in most cases, + presumably bad RAM table or bad algorithm + */ + + //if(dma_trigger != 0x87) + //printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x %02x %02x\n",cop_dma_src[cop_dma_mode] << 6,cop_dma_adr_rel * 0x400,cop_dma_dst[cop_dma_mode] << 6,cop_dma_size[cop_dma_mode] << 5,cop_dma_mode,pal_brightness_val,pal_brightness_mode); + + src = (cop_dma_src[cop_dma_mode] << 6); + dst = (cop_dma_dst[cop_dma_mode] << 6); + size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20) / 2; + + for (i = 0; i < size; i++) + { + UINT16 pal_val; + int r, g, b; + int rt, gt, bt; + + if (pal_brightness_mode == 5) + { + bt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x7c00) >> 5; + bt = fade_table(bt | (pal_brightness_val ^ 0)); + b = ((m_host_space->read_word(src)) & 0x7c00) >> 5; + b = fade_table(b | (pal_brightness_val ^ 0x1f)); + pal_val = ((b + bt) & 0x1f) << 10; + gt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x03e0); + gt = fade_table(gt | (pal_brightness_val ^ 0)); + g = ((m_host_space->read_word(src)) & 0x03e0); + g = fade_table(g | (pal_brightness_val ^ 0x1f)); + pal_val |= ((g + gt) & 0x1f) << 5; + rt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x001f) << 5; + rt = fade_table(rt | (pal_brightness_val ^ 0)); + r = ((m_host_space->read_word(src)) & 0x001f) << 5; + r = fade_table(r | (pal_brightness_val ^ 0x1f)); + pal_val |= ((r + rt) & 0x1f); + } + else if (pal_brightness_mode == 4) //Denjin Makai + { + UINT16 targetpaldata = m_host_space->read_word(src + (cop_dma_adr_rel * 0x400)); + UINT16 paldata = m_host_space->read_word(src); // ^1 !!! (why?) + + bt = (targetpaldata & 0x7c00) >> 10; + b = (paldata & 0x7c00) >> 10; + gt = (targetpaldata & 0x03e0) >> 5; + g = (paldata & 0x03e0) >> 5; + rt = (targetpaldata & 0x001f) >> 0; + r = (paldata & 0x001f) >> 0; + + if (pal_brightness_val == 0x10) + pal_val = bt << 10 | gt << 5 | rt << 0; + else if (pal_brightness_val == 0xff) // TODO: might be the back plane or it still doesn't do any mod, needs PCB tests + pal_val = 0; + else + { + bt = fade_table(bt << 5 | ((pal_brightness_val * 2) ^ 0)); + b = fade_table(b << 5 | ((pal_brightness_val * 2) ^ 0x1f)); + pal_val = ((b + bt) & 0x1f) << 10; + gt = fade_table(gt << 5 | ((pal_brightness_val * 2) ^ 0)); + g = fade_table(g << 5 | ((pal_brightness_val * 2) ^ 0x1f)); + pal_val |= ((g + gt) & 0x1f) << 5; + rt = fade_table(rt << 5 | ((pal_brightness_val * 2) ^ 0)); + r = fade_table(r << 5 | ((pal_brightness_val * 2) ^ 0x1f)); + pal_val |= ((r + rt) & 0x1f); + } + } + else + { + printf("Warning: palette DMA used with mode %02x!\n", pal_brightness_mode); + pal_val = m_host_space->read_word(src); + } + + m_host_space->write_word(dst, pal_val); + src += 2; + dst += 2; + } +} + +void raiden2cop_device::dma_fill() +{ + UINT32 length, address; + int i; + if (cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid? + return; + + address = (cop_dma_src[cop_dma_mode] << 6); + length = (cop_dma_size[cop_dma_mode] + 1) << 5; + + //printf("%08x %08x\n",address,length); + + for (i = address; i < address + length; i += 4) + m_host_space->write_dword(i, (cop_dma_v1) | (cop_dma_v2 << 16)); + + /* + UINT32 length, address; + int i; + if(cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid? + return; + + address = (cop_dma_src[cop_dma_mode] << 6); + length = (cop_dma_size[cop_dma_mode]+1) << 5; + + //printf("%08x %08x\n",address,length); + + for (i=address;i<address+length;i+=4) + { + m_host_space->write_dword(i, m_fill_val); + } + */ +} + diff --git a/src/mame/machine/seicop.h b/src/mame/machine/seicop.h index 002b11d463c..f7a2c7f0ab1 100644 --- a/src/mame/machine/seicop.h +++ b/src/mame/machine/seicop.h @@ -1,7 +1,7 @@ // license:LGPL-2.1+ // copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina -#include "raiden2cop.h" +#include "seibucop/seibucop.h" |