mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Moved DMA and commands into own files, nw
This commit is contained in:
parent
3da81f4221
commit
75a4c41dd3
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
700
src/mame/machine/seibucop/seibucop_cmd.hxx
Normal file
700
src/mame/machine/seibucop/seibucop_cmd.hxx
Normal file
@ -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)
|
||||
*/
|
||||
|
||||
|
||||
|
152
src/mame/machine/seibucop/seibucop_dma.hxx
Normal file
152
src/mame/machine/seibucop/seibucop_dma.hxx
Normal file
@ -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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user