Merge remote-tracking branch 'origin/master' into netlist_dev

This commit is contained in:
couriersud 2016-06-22 01:00:25 +02:00
commit 23c5c02d5a
58 changed files with 3805 additions and 2075 deletions

View File

@ -329,7 +329,7 @@ function cheat.startplugin()
index = index - #cheats
if index == 2 then
for num, cheat in pairs(cheats) do
if cheat.script and cheat.script.off then
if cheat.enabled and cheat.script.off then
cheat.script.off()
end
cheat.enabled = false
@ -340,7 +340,7 @@ function cheat.startplugin()
end
elseif index == 3 then
for num, cheat in pairs(cheats) do
if cheat.script and cheat.script.off then
if cheat.enabled and cheat.script.off then
cheat.script.off()
end
end

View File

@ -40,6 +40,15 @@ function cheatfind.startplugin()
return ram
end
-- return table of share regions
function cheat.getshares()
local shares = {}
for tag, share in pairs(manager:machine():memory().shares) do
shares[tag] = share
end
return shares
end
-- save data block
function cheat.save(space, start, size)
local data = { block = "", start = start, size = size, space = space }
@ -274,6 +283,10 @@ function cheatfind.startplugin()
for tag, ram in pairs(space_table) do
devtable[#devtable + 1] = { tag = tag, space = ram.dev, ram = {{ offset = 0, size = ram.size }} }
end
space_table = cheat.getshares()
for tag, share in pairs(space_table) do
devtable[#devtable + 1] = { tag = tag, space = share, ram = {{ offset = 0, size = share.size }} }
end
end
emu.register_start(start)

View File

@ -2378,6 +2378,7 @@ end
if (CPUS["MB86901"]~=null) then
files {
MAME_DIR .. "src/devices/cpu/sparc/mb86901.cpp",
MAME_DIR .. "src/devices/cpu/sparc/sparcdasm.h",
MAME_DIR .. "src/devices/cpu/sparc/sparcdefs.h",
MAME_DIR .. "src/devices/cpu/sparc/sparc.h",
}

View File

@ -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",

View File

@ -52,9 +52,16 @@ const device_type V35 = &device_creator<v35_device>;
v25_common_device::v25_common_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, bool is_16bit, offs_t fetch_xor, UINT8 prefetch_size, UINT8 prefetch_cycles, UINT32 chip_type)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__)
, m_program_config("program", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 20, 0)
, m_io_config("io", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 16+1, 0)
, m_io_config("io", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 16, 0)
, m_fetch_xor(fetch_xor)
, m_PCK(8)
, m_pt_in(*this)
, m_p0_in(*this)
, m_p1_in(*this)
, m_p2_in(*this)
, m_p0_out(*this)
, m_p1_out(*this)
, m_p2_out(*this)
, m_prefetch_size(prefetch_size)
, m_prefetch_cycles(prefetch_cycles)
, m_chip_type(chip_type)
@ -501,6 +508,15 @@ void v25_common_device::device_start()
m_direct = &m_program->direct();
m_io = &space(AS_IO);
m_pt_in.resolve_safe(0xff);
m_p0_in.resolve_safe(0xff);
m_p1_in.resolve_safe(0xff);
m_p2_in.resolve_safe(0xff);
m_p0_out.resolve_safe();
m_p1_out.resolve_safe();
m_p2_out.resolve_safe();
state_add( V25_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%05X");
state_add( V25_IP, "IP", m_ip).formatstr("%04X");
state_add( V25_SP, "SP", m_debugger_temp).callimport().callexport().formatstr("%04X");

View File

@ -10,11 +10,6 @@
#define NEC_INPUT_LINE_INTP2 12
#define NEC_INPUT_LINE_POLL 20
#define V25_PORT_P0 0x10000
#define V25_PORT_P1 0x10002
#define V25_PORT_P2 0x10004
#define V25_PORT_PT 0x10006
enum
{
V25_PC=0,
@ -28,6 +23,28 @@ enum
v25_common_device::set_decryption_table(*device, _table);
#define MCFG_V25_PORT_PT_READ_CB(_devcb) \
devcb = &v25_common_device::set_pt_in_cb(*device, DEVCB_##_devcb);
#define MCFG_V25_PORT_P0_READ_CB(_devcb) \
devcb = &v25_common_device::set_p0_in_cb(*device, DEVCB_##_devcb);
#define MCFG_V25_PORT_P1_READ_CB(_devcb) \
devcb = &v25_common_device::set_p1_in_cb(*device, DEVCB_##_devcb);
#define MCFG_V25_PORT_P2_READ_CB(_devcb) \
devcb = &v25_common_device::set_p2_in_cb(*device, DEVCB_##_devcb);
#define MCFG_V25_PORT_P0_WRITE_CB(_devcb) \
devcb = &v25_common_device::set_p0_out_cb(*device, DEVCB_##_devcb);
#define MCFG_V25_PORT_P1_WRITE_CB(_devcb) \
devcb = &v25_common_device::set_p1_out_cb(*device, DEVCB_##_devcb);
#define MCFG_V25_PORT_P2_WRITE_CB(_devcb) \
devcb = &v25_common_device::set_p2_out_cb(*device, DEVCB_##_devcb);
class v25_common_device : public cpu_device
{
public:
@ -36,6 +53,15 @@ public:
// static configuration helpers
static void set_decryption_table(device_t &device, const UINT8 *decryption_table) { downcast<v25_common_device &>(device).m_v25v35_decryptiontable = decryption_table; }
template<class _Object> static devcb_base & set_pt_in_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_pt_in.set_callback(object); }
template<class _Object> static devcb_base & set_p0_in_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_p0_in.set_callback(object); }
template<class _Object> static devcb_base & set_p1_in_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_p1_in.set_callback(object); }
template<class _Object> static devcb_base & set_p2_in_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_p2_in.set_callback(object); }
template<class _Object> static devcb_base & set_p0_out_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_p0_out.set_callback(object); }
template<class _Object> static devcb_base & set_p1_out_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_p1_out.set_callback(object); }
template<class _Object> static devcb_base & set_p2_out_cb(device_t &device, _Object object) { return downcast<v25_common_device &>(device).m_p2_out.set_callback(object); }
TIMER_CALLBACK_MEMBER(v25_timer_callback);
@ -118,6 +144,16 @@ union internalram
address_space *m_io;
int m_icount;
/* callbacks */
devcb_read8 m_pt_in;
devcb_read8 m_p0_in;
devcb_read8 m_p1_in;
devcb_read8 m_p2_in;
devcb_write8 m_p0_out;
devcb_write8 m_p1_out;
devcb_write8 m_p2_out;
UINT8 m_prefetch_size;
UINT8 m_prefetch_cycles;
INT8 m_prefetch_count;

View File

@ -25,21 +25,21 @@ UINT8 v25_common_device::read_sfr(unsigned o)
switch(o)
{
case 0x00: /* P0 */
ret = m_io->read_byte(V25_PORT_P0);
ret = m_p0_in();
break;
case 0x08: /* P1 */
/* P1 is combined with the interrupt lines */
ret = ((m_io->read_byte(V25_PORT_P1) & 0xF0)
ret = ((m_p1_in() & 0xF0)
| (m_nmi_state ? 0x00 : 0x01)
| (m_intp_state[0] ? 0x00 : 0x02)
| (m_intp_state[1] ? 0x00 : 0x04)
| (m_intp_state[2] ? 0x00 : 0x08));
break;
case 0x10: /* P2 */
ret = m_io->read_byte(V25_PORT_P2);
ret = m_p2_in();
break;
case 0x38: /* PT */
ret = m_io->read_byte(V25_PORT_PT);
ret = m_pt_in();
break;
case 0x4C: /* EXIC0 */
ret = read_irqcontrol(INTP0, m_priority_intp);
@ -169,14 +169,14 @@ void v25_common_device::write_sfr(unsigned o, UINT8 d)
switch(o)
{
case 0x00: /* P0 */
m_io->write_byte(V25_PORT_P0, d);
m_p0_out(d);
break;
case 0x08: /* P1 */
/* only the upper four bits of P1 can be used as output */
m_io->write_byte(V25_PORT_P1, d & 0xF0);
m_p1_out(d & 0xF0);
break;
case 0x10: /* P2 */
m_io->write_byte(V25_PORT_P2, d);
m_p2_out(d);
break;
case 0x4C: /* EXIC0 */
write_irqcontrol(INTP0, d);

View File

@ -37,6 +37,7 @@ const int mb86901_device::WINDOW_COUNT = 7;
mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, MB86901, "Fujitsu MB86901", tag, owner, clock, "mb86901", __FILE__)
, m_program_config("program", ENDIANNESS_BIG, 32, 32)
, m_dasm(7)
{
}
@ -166,7 +167,7 @@ void mb86901_device::device_stop()
void mb86901_device::device_reset()
{
m_queued_tt = 0;
m_queued_priority = 0;
m_queued_priority = SPARC_NO_TRAP;
m_asi = 0;
MAE = false;
HOLD_BUS = false;
@ -351,8 +352,8 @@ UINT32 mb86901_device::disasm_max_opcode_bytes() const
offs_t mb86901_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
{
extern CPU_DISASSEMBLE( sparc );
return CPU_DISASSEMBLE_NAME(sparc)(this, buffer, pc, oprom, opram, options);
UINT32 op = *reinterpret_cast<const UINT32 *>(oprom);
return m_dasm.dasm(buffer, pc, BIG_ENDIANIZE_INT32(op));
}
@ -877,6 +878,7 @@ bool mb86901_device::execute_group2(UINT32 op)
else
{
m_tbr = (arg1 ^ arg2) & 0xfffff000;
printf("wr (%08x ^ %08x) & 0xfffff000 (%08x),tbr", arg1, arg2, m_tbr);
}
break;
case 52: // FPop1
@ -1352,6 +1354,7 @@ bool mb86901_device::execute_ticc(UINT32 op)
{
bool trap_taken = evaluate_condition(op);
printf("ticc @ %x\n", PC);
if (trap_taken)
{
UINT32 arg2 = USEIMM ? SIMM7 : RS2REG;
@ -1410,11 +1413,8 @@ void mb86901_device::trap(UINT8 type, UINT8 tt_override)
bool mb86901_device::invoke_queued_traps()
{
if (m_queued_priority > 0)
if (m_queued_priority != SPARC_NO_TRAP)
{
m_queued_priority = 0;
m_queued_tt = 0;
m_et = false;
m_ps = m_s;
m_s = true;
@ -1430,6 +1430,9 @@ bool mb86901_device::invoke_queued_traps()
PC = m_tbr;
nPC = m_tbr + 4;
m_queued_priority = SPARC_NO_TRAP;
m_queued_tt = 0;
return true;
}
@ -1472,6 +1475,7 @@ void mb86901_device::execute_run()
switch (OP2)
{
case 0: // unimp
printf("unimp @ %x\n", PC);
break;
case 2: // branch on integer condition codes
update_npc = execute_bicc(op);
@ -1480,12 +1484,14 @@ void mb86901_device::execute_run()
SET_RDREG(IMM22);
break;
case 6: // branch on floating-point condition codes
printf("fbfcc @ %x\n", PC);
break;
#if SPARCV8
case 7: // branch on coprocessor condition codes, SPARCv8
break;
#endif
default:
printf("unknown %08x @ %x\n", op, PC);
break;
}
break;

View File

@ -4,11 +4,14 @@
SPARC v7 emulator
*/
#pragma once
#ifndef __SPARC_H__
#define __SPARC_H__
#pragma once
#include "sparcdasm.h"
#define SPARC_NO_TRAP 256
#define SPARC_RESET 0
#define SPARC_INSTRUCTION_ACCESS_EXCEPTION 1
#define SPARC_ILLEGAL_INSTRUCTION 2
@ -132,15 +135,16 @@ protected:
UINT8 m_asi;
// other internal states
UINT8 m_trap_priorities[256];
UINT8 m_queued_tt;
UINT8 m_queued_priority;
UINT32 m_trap_priorities[256];
UINT32 m_queued_tt;
UINT32 m_queued_priority;
bool m_mae;
bool m_hold_bus;
int m_icount;
// debugger helpers
UINT32 m_dbgregs[24];
sparc_disassembler m_dasm;
// address spaces
address_space *m_program;
@ -189,6 +193,4 @@ enum
SPARC_R96, SPARC_R97, SPARC_R98, SPARC_R99, SPARC_R100, SPARC_R101, SPARC_R102, SPARC_R103, SPARC_R104, SPARC_R105, SPARC_R106, SPARC_R107, SPARC_R108, SPARC_R109, SPARC_R110, SPARC_R111
};
CPU_DISASSEMBLE( sparc );
#endif /* __SPARC_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,201 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz, Vas Crabb
/*
SPARC disassembler
*/
#ifndef MAME_DEVICES_CPU_SPARC_SPARC_DASM_H
#define MAME_DEVICES_CPU_SPARC_SPARC_DASM_H
#pragma once
#include <map>
class sparc_disassembler
{
public:
struct asi_desc
{
const char *name = nullptr;
const char *desc = nullptr;
};
typedef std::map<UINT8, asi_desc> asi_desc_map;
struct state_reg_desc
{
bool reserved = false;
const char *read_name = nullptr;
const char *write_name = nullptr;
};
typedef std::map<UINT8, state_reg_desc> state_reg_desc_map;
struct prftch_desc
{
const char *name = nullptr;
};
typedef std::map<UINT8, prftch_desc> prftch_desc_map;
sparc_disassembler(unsigned version);
template <typename T> void add_state_reg_desc(const T &desc)
{
for (const auto &it : desc)
{
auto ins = m_state_reg_desc.insert(it);
if (!ins.second)
{
ins.first->second.reserved = it.second.reserved;
if (it.second.read_name)
ins.first->second.read_name = it.second.read_name;
if (it.second.write_name)
ins.first->second.write_name = it.second.write_name;
}
}
}
template <typename T> void add_asi_desc(const T &desc)
{
// TODO: support ranges
for (const auto &it : desc)
{
auto ins = m_asi_desc.insert(it);
if (!ins.second)
{
if (it.second.name)
ins.first->second.name = it.second.name;
if (it.second.desc)
ins.first->second.desc = it.second.desc;
}
}
}
template <typename T> void add_prftch_desc(const T &desc)
{
for (const auto &it : desc)
{
auto ins = m_prftch_desc.insert(it);
if (!ins.second)
{
if (it.second.name)
ins.first->second.name = it.second.name;
}
}
}
offs_t dasm(char *buf, offs_t pc, UINT32 op) const;
private:
struct branch_desc
{
INT32 (*get_disp)(UINT32 op);
int disp_width;
bool use_pred, use_cc;
const char *reg_cc[4];
const char *mnemonic[16];
};
struct int_op_desc
{
unsigned min_version;
bool hex_imm;
const char *mnemonic;
};
typedef std::map<UINT8, int_op_desc> int_op_desc_map;
struct fpop1_desc
{
bool three_op = true;
bool rs1_shift = false;
bool rs2_shift = false;
bool rd_shift = false;
const char *mnemonic = nullptr;
};
typedef std::map<UINT16, fpop1_desc> fpop1_desc_map;
struct fpop2_desc
{
bool int_rs1 = false;
bool shift = false;
const char *mnemonic = nullptr;
};
typedef std::map<UINT16, fpop2_desc> fpop2_desc_map;
struct ldst_desc
{
bool rd_first = false;
bool alternate = false;
char rd_alt_reg = '\0';
bool rd_shift = false;
const char *mnemonic = nullptr;
const char *g0_synth = nullptr;
};
typedef std::map<UINT8, ldst_desc> ldst_desc_map;
offs_t dasm_invalid(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_branch(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_shift(char *buf, offs_t pc, UINT32 op, const char *mnemonic, const char *mnemonicx, const char *mnemonicx0) const;
offs_t dasm_read_state_reg(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_write_state_reg(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_move_cond(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_move_reg_cond(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_fpop1(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_fpop2(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_jmpl(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_return(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_tcc(char *buf, offs_t pc, UINT32 op) const;
offs_t dasm_ldst(char *buf, offs_t pc, UINT32 op) const;
void dasm_address(char *&output, UINT32 op) const;
void dasm_asi(char *&output, UINT32 op) const;
void dasm_asi_comment(char *&output, UINT32 op) const;
UINT32 freg(UINT32 val, bool shift) const;
template <typename T> void add_fpop1_desc(const T &desc);
template <typename T> void add_fpop2_desc(const T &desc);
template <typename T> void add_ldst_desc(const T &desc);
void pad_op_field(char *buf, char *&output) const;
ATTR_PRINTF(2, 3) static void print(char *&output, const char *fmt, ...);
static const char * const REG_NAMES[32];
static const branch_desc EMPTY_BRANCH_DESC;
static const branch_desc BPCC_DESC;
static const branch_desc BICC_DESC;
static const branch_desc BPR_DESC;
static const branch_desc FBPFCC_DESC;
static const branch_desc FBFCC_DESC;
static const branch_desc CBCCC_DESC;
static const int_op_desc_map::value_type SIMPLE_INT_OP_DESC[];
static const state_reg_desc_map::value_type V9_STATE_REG_DESC[];
static const char * const MOVCC_CC_NAMES[8];
static const char * const MOVCC_COND_NAMES[32];
static const char * const MOVE_INT_COND_MNEMONICS[8];
static const char * const V9_PRIV_REG_NAMES[32];
static const fpop1_desc_map::value_type V7_FPOP1_DESC[];
static const fpop1_desc_map::value_type V9_FPOP1_DESC[];
static const fpop2_desc_map::value_type V7_FPOP2_DESC[];
static const fpop2_desc_map::value_type V9_FPOP2_DESC[];
static const ldst_desc_map::value_type V7_LDST_DESC[];
static const ldst_desc_map::value_type V9_LDST_DESC[];
static const asi_desc_map::value_type V9_ASI_DESC[];
static const prftch_desc_map::value_type V9_PRFTCH_DESC[];
unsigned m_version;
int m_op_field_width;
branch_desc m_branch_desc[8];
int_op_desc_map m_simple_int_op_desc;
state_reg_desc_map m_state_reg_desc;
fpop1_desc_map m_fpop1_desc;
fpop2_desc_map m_fpop2_desc;
ldst_desc_map m_ldst_desc;
asi_desc_map m_asi_desc;
prftch_desc_map m_prftch_desc;
};
CPU_DISASSEMBLE( sparcv7 );
CPU_DISASSEMBLE( sparcv8 );
CPU_DISASSEMBLE( sparcv9 );
#endif // MAME_DEVICES_CPU_SPARC_SPARC_DASM_H

View File

@ -83,20 +83,39 @@
#define OP2 ((op >> 22) & 7)
#define OP3 ((op >> 19) & 63)
#define OPF ((op >> 5) & 0x1ff)
#define OPC ((op >> 5) & 0x1ff)
#define OPFLOW ((op >> 5) & 0x3f)
#define DISP30 (op << 2)
#define DISP22 (((INT32)(op << 10)) >> 8)
#define DISP30 (INT32(op << 2))
#define DISP22 (INT32(op << 10) >> 8)
#define DISP19 (INT32(op << 13) >> 11)
#define DISP16 (INT32(((op << 10) & 0xc0000000) | ((op << 16) & 0x3fff0000)) >> 14)
#define IMM22 (op << 10)
#define CONST22 (op & 0x3fffff)
#define SIMM13 (((INT32)(op << 19)) >> 19)
#define SIMM13 (INT32(op << 19) >> 19)
#define SIMM11 (INT32(op << 21) >> 21)
#define SIMM10 (INT32(op << 22) >> 22)
#define IMM7 (op & 0x7f)
#define SIMM7 (((INT32)(op << 25)) >> 25)
#define OPIMM (op & 0x00002000)
#define SIMM7 (INT32(op << 25) >> 25)
#define SIMM8 (INT32(op << 24) >> 24)
#define SHCNT32 (op & 31)
#define SHCNT64 (op & 63)
#define USEIMM ((op >> 13) & 1)
#define USEEXT ((op >> 12) & 1)
#define COND ((op >> 25) & 15)
#define RCOND ((op >> 10) & 7)
#define MOVCOND ((op >> 14) & 15)
#define PRED ((op >> 19) & 1)
#define ANNUL ((op >> 29) & 1)
#define ASI ((op >> 5) & 0xff)
#define BRCC ((op >> 20) & 3)
#define MOVCC (((op >> 11) & 3) | ((op >> 16) & 4))
#define OPFCC ((op >> 11) & 7)
#define TCCCC ((op >> 11) & 3)
#define ASI ((op >> 5) & 255)
#define MMASK (op & 15)
#define CMASK ((op >> 4) & 7)
#define RD ((op >> 25) & 31)
#define RS1 ((op >> 14) & 31)
@ -107,7 +126,7 @@
#define RS1REG *m_regs[RS1]
#define RS2REG *m_regs[RS2]
#define SET_RDREG(x) if(RD) { RDREG = x; }
#define ADDRESS (OPIMM ? (RS1REG + SIMM13) : (RS1REG + RS2REG))
#define ADDRESS (USEIMM ? (RS1REG + SIMM13) : (RS1REG + RS2REG))
#define PC m_pc
#define nPC m_npc

View File

@ -290,7 +290,7 @@ void t11_device::mark(UINT16 op)
{
m_icount -= 36;
SP = SP + 2 * (op & 0x3f);
SP = PC + 2 * (op & 0x3f);
PC = REGW(5);
REGW(5) = POP();
}

View File

@ -17,7 +17,7 @@ const device_type TMS57002 = &device_creator<tms57002_device>;
// Can't use a DEVICE_ADDRESS_MAP, not yet anyway
static ADDRESS_MAP_START(internal_pgm, AS_PROGRAM, 32, tms57002_device)
AM_RANGE(0x000, 0x3ff) AM_RAM
AM_RANGE(0x00, 0xff) AM_RAM
ADDRESS_MAP_END
tms57002_device::tms57002_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)

View File

@ -7,7 +7,7 @@
**************************************************************************/
#include "zeus2.h"
#define LOG_REGS 0
#define LOG_REGS 1
/*************************************
* Constructor
@ -22,7 +22,7 @@ const device_type ZEUS2 = &device_creator<zeus2_device>;
zeus2_device::zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, ZEUS2, "Midway Zeus2", tag, owner, clock, "zeus2", __FILE__),
m_vblank(*this), m_irq(*this)
m_vblank(*this), m_irq(*this), m_ieee754_float(0)
{
}
@ -69,7 +69,9 @@ void zeus2_device::device_start()
/* allocate memory for "wave" RAM */
waveram[0] = auto_alloc_array(machine(), UINT32, WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8/4);
waveram[1] = auto_alloc_array(machine(), UINT32, WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12/4);
//waveram[1] = auto_alloc_array(machine(), UINT32, WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12/4);
m_frameColor = std::make_unique<UINT32[]>(WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2);
m_frameDepth = std::make_unique<UINT16[]>(WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2);
/* initialize polygon engine */
poly = auto_alloc(machine(), zeus2_renderer(this));
@ -87,8 +89,11 @@ void zeus2_device::device_start()
/* save states */
save_pointer(NAME(waveram[0]), WAVERAM0_WIDTH * WAVERAM0_HEIGHT * 8 / sizeof(waveram[0][0]));
save_pointer(NAME(waveram[1]), WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0]));
save_pointer(NAME(m_zeusbase), sizeof(m_zeusbase[0])*0x80);
//save_pointer(NAME(waveram[1]), WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 12 / sizeof(waveram[1][0]));
save_pointer(m_frameColor.get(), "m_frameColor", sizeof(m_frameColor[0]) * WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2);
save_pointer(m_frameDepth.get(), "m_frameDepth", sizeof(m_frameDepth[0]) * WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 2);
save_pointer(NAME(m_zeusbase), sizeof(m_zeusbase[0]) * 0x80);
save_pointer(NAME(m_renderRegs), sizeof(m_renderRegs[0]) * 0x80);
save_item(NAME(zeus_fifo));
save_item(NAME(zeus_fifo_words));
save_item(NAME(zeus_cliprect.min_x));
@ -104,12 +109,13 @@ void zeus2_device::device_start()
void zeus2_device::device_reset()
{
memset(m_zeusbase, 0, sizeof(m_zeusbase));
memset(m_zeusbase, 0, sizeof(m_zeusbase[0]) * 0x80);
memset(m_renderRegs, 0, sizeof(m_renderRegs[0]) * 0x80);
zbase = 2.0f;
m_yScale = 0;
m_yScale = 1;
yoffs = 0;
texel_width = 256;
zeus_renderbase = waveram[1];
zeus_fifo_words = 0;
m_fill_color = 0;
m_fill_depth = 0;
@ -177,6 +183,10 @@ void zeus2_device::device_stop()
UINT32 zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
// Wait until configuration is completed before transfering anything
if (m_zeusbase[0x30] == 0)
return 0;
int x, y;
poly->wait();
@ -187,17 +197,15 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z
/* normal update case */
if (!machine().input().code_pressed(KEYCODE_W))
{
const void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x38] >> m_yScale);
int xoffs = screen.visible_area().min_x;
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
UINT32 *colorptr = &m_frameColor[frame_addr_from_xy(0, y, false)];
UINT32 *dest = &bitmap.pix32(y);
UINT32 bufY = y >> m_yScale;
UINT32 bufOffsX = (m_yScale && (y & 1)) ? 0x200 : 0;
for (x = cliprect.min_x; x <= cliprect.max_x; x++) {
UINT32 bufX = x - xoffs + bufOffsX;
dest[x] = WAVERAM_READPIX(base, bufY, bufX);
UINT32 bufX = x - xoffs;
//dest[x] = WAVERAM_READPIX(base, y, x - xoffs);
dest[x] = colorptr[bufX];
}
}
}
@ -205,7 +213,7 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z
/* waveram drawing case */
else
{
const UINT64 *base;
const void *base;
if (machine().input().code_pressed(KEYCODE_DOWN)) yoffs += machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1;
if (machine().input().code_pressed(KEYCODE_UP)) yoffs -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1;
@ -214,9 +222,9 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z
if (yoffs < 0) yoffs = 0;
if (0)
base = (const UINT64 *)waveram0_ptr_from_expanded_addr(yoffs << 16);
base = waveram0_ptr_from_expanded_addr(yoffs << 16);
else
base = (const UINT64 *)waveram1_ptr_from_expanded_addr(yoffs << 16);
base = (void *)&m_frameColor[yoffs<<9];
int xoffs = screen.visible_area().min_x;
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
@ -225,15 +233,15 @@ if (machine().input().code_pressed(KEYCODE_DOWN)) { zbase -= 1.0f; popmessage("Z
for (x = cliprect.min_x; x <= cliprect.max_x; x++)
{
if (0) {
UINT8 tex = get_texel_8bit(base, y, x, texel_width);
UINT8 tex = get_texel_8bit((UINT64 *)base, y, x, texel_width);
dest[x] = (tex << 16) | (tex << 8) | tex;
}
else {
dest[x] = WAVERAM_READPIX(base, y, x - xoffs);
dest[x] = ((UINT32 *)(base))[((y * WAVERAM1_WIDTH)) + x - xoffs];
}
}
}
popmessage("offs = %06X", yoffs);
popmessage("offs = %06X base = %08X", yoffs, yoffs<<9);
}
return 0;
@ -303,7 +311,8 @@ WRITE32_MEMBER( zeus2_device::zeus2_w )
int logit = (offset != 0x08 &&
(offset != 0x20 || data != 0) &&
offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e &&
offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e);
offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e
);
logit &= LOG_REGS;
if (logit)
logerror("%08X:zeus2_w", machine().device("maincpu")->safe_pc());
@ -389,6 +398,18 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
zeus2_pointer_write(m_zeusbase[0x20] >> 24, m_zeusbase[0x20]);
break;
case 0x30:
{
int horPixels = (m_zeusbase[0x34] & 0xffff) - (m_zeusbase[0x33] >> 16);
// Just a guess. Atlantis startup has two scanlines per physical ram row
if (horPixels <= 0x200)
m_yScale = 1;
else
m_yScale = 0;
popmessage("reg[30]: %08X horPixels: %d scale: %d", m_zeusbase[0x30], horPixels, m_yScale);
}
break;
case 0x33:
case 0x34:
case 0x35:
@ -396,15 +417,9 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
case 0x37:
m_screen->update_partial(m_screen->vpos());
{
// Just a guess. Atlantis startup has two scanlines per physical ram row
if ((m_zeusbase[0x30] & 0xfff) <= 0x100)
m_yScale = 1;
else
m_yScale = 0;
int vtotal = (m_zeusbase[0x37] & 0xffff) << m_yScale;
int vtotal = (m_zeusbase[0x37] & 0xffff);
int htotal = (m_zeusbase[0x34] >> 16);
rectangle visarea((m_zeusbase[0x33] >> 16), htotal - 1, 0, (m_zeusbase[0x35] & 0xffff)<< m_yScale);
rectangle visarea((m_zeusbase[0x33] >> 16), htotal - 1, 0, (m_zeusbase[0x35] & 0xffff));
if (htotal > 0 && vtotal > 0 && visarea.min_x < visarea.max_x && visarea.max_y < vtotal)
{
m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS((double)ZEUS2_VIDEO_CLOCK / 4.0 / (htotal * vtotal)));
@ -423,7 +438,7 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
m_zeusbase[0x38] = oldval;
m_screen->update_partial(m_screen->vpos());
log_fifo = machine().input().code_pressed(KEYCODE_L);
//log_fifo = 1;
log_fifo = 1;
m_zeusbase[0x38] = temp;
}
break;
@ -500,39 +515,34 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
case 0x50:
if (m_zeusbase[0x50] == 0x00510000) {
// SGRAM Special Mode Register Write
if (m_zeusbase[0x51] & 0x00400000) {
if (m_zeusbase[0x51] == 0x00200000) {
// SGRAM Mask Register
if ((m_zeusbase[0x58] & m_zeusbase[0x59] & m_zeusbase[0x5a]) != 0xffffffff)
logerror("zeus2_register_update: Warning! Mask Register not equal to 0xffffffff\n");
}
if (m_zeusbase[0x51] & 0x00200000) {
if (m_zeusbase[0x51] == 0x00400000) {
// SGRAM Color Register
m_fill_color = m_zeusbase[0x58];
m_fill_depth = m_zeusbase[0x5a] & 0xffff;
m_fill_depth = m_zeusbase[0x5a];
if (m_zeusbase[0x58] != m_zeusbase[0x59])
logerror("zeus2_register_update: Warning! Different fill colors are set.\n");
}
}
else if (1 && (m_zeusbase[0x50] & 0x00080000) && (m_zeusbase[0x50] & 0xffff)) {
else if (1 && ((m_zeusbase[0x50] & 0x000f0000)==0x80000) && (m_zeusbase[0x50] & 0xffff)) {
// Fast fill
// Unknown what the exact bit fields are, this is a just a guess
// Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame
// crusnexo: 0x007831FF => clear one frame
// thegrid: 0x008831FF => clear one frame
//UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x7;
UINT32 lastRow = (((m_zeusbase[0x50] >> 8) & 0xff) << 3) | 0x3;
UINT32 lastCol = (((m_zeusbase[0x50] >> 0) & 0xff) << 2) | 0x3;
// Not sure how to select
//void *base = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
void *base = (m_zeusbase[0x50] & 0x800000) ? waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]) : zeus_renderbase;
for (int y = 0; y <= lastRow; y++)
for (int x = 0; x <= lastCol; x++) {
WAVERAM_WRITEPIX(base, y, x, m_fill_color);
WAVERAM_WRITEDEPTH(base, y, x, m_fill_depth);
}
//waveram_plot_depth(y, x, m_fill_color, m_fill_depth);
// thegrid: 0x0079FFFF => clear one frame at 51=0 then 51=00800000 ???
UINT32 addr = frame_addr_from_reg51();
UINT32 numBytes = (m_zeusbase[0x50] & 0xffff) + 1;
numBytes *= 0x40;
//printf("Clearing buffer: numPixels: %08X addr: %08X reg50: %08X\n", numBytes/4, addr, m_zeusbase[0x50]);
memset(&m_frameColor[addr], m_fill_color, numBytes);
memset(&m_frameDepth[addr], m_fill_depth, numBytes/2);
}
else if ((m_zeusbase[0x5e] >> 16) != 0xF208) {
else if ((m_zeusbase[0x5e] >> 16) != 0xf208 && !(m_zeusbase[0x5e] & 0xffff)) {
/* If 0x5e==0xf20a0000 (atlantis) or 0xf20d0000 (the grid) then process the read/write now */
/*
m_zeusbase[0x5e]:
@ -542,39 +552,18 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
bit 5: unknown, currently used to specify ordering, but this is suspect
bit 6: enable autoincrement on write through
*/
if (m_zeusbase[0x50] == 0x00890000)
//if (m_zeusbase[0x50] == 0x00890000)
if ((m_zeusbase[0x50] == 0x00890000) || (m_zeusbase[0x50] == 0x00e90000))
{
void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]);
if (m_zeusbase[0x5e] & 0x20)
WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]);
else
{
WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]);
WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]);
}
if (m_zeusbase[0x5e] & 0x40)
{
m_zeusbase[0x51]++;
m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
m_zeusbase[0x51] &= ~0xfe00;
}
frame_write();
}
else if (m_zeusbase[0x50] == 0x00720000) {
/* Do the read */
const void *src = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
m_zeusbase[0x58] = WAVERAM_READ32(src, 0);
m_zeusbase[0x59] = WAVERAM_READ32(src, 1);
m_zeusbase[0x5a] = WAVERAM_READ32(src, 2);
if (m_zeusbase[0x5e] & 0x40)
{
m_zeusbase[0x51]++;
m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
m_zeusbase[0x51] &= ~0xfe00;
}
frame_read();
}
/* make sure we log anything else */
else if (1 || logit)
logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
}
break;
case 0x51:
@ -586,36 +575,26 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
/* this is the address, except in read mode, where it latches values */
if ((m_zeusbase[0x5e] & 0x10) || (m_zeusbase[0x50] == 0x00a20000))
{
const void *src = waveram1_ptr_from_expanded_addr(oldval);
{
m_zeusbase[0x51] = oldval;
m_zeusbase[0x58] = WAVERAM_READ32(src, 0);
m_zeusbase[0x59] = WAVERAM_READ32(src, 1);
m_zeusbase[0x5a] = WAVERAM_READ32(src, 2);
if (m_zeusbase[0x5e] & 0x40)
{
m_zeusbase[0x51]++;
m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
m_zeusbase[0x51] &= ~0xfe00;
}
frame_read();
}
break;
case 0x57:
/* thegrid uses this to write either left or right halves of pixels */
if (m_zeusbase[0x50] == 0x00e90000)
{
void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
if (m_zeusbase[0x57] & 1)
WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]);
if (m_zeusbase[0x57] & 4)
WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]);
}
//if (m_zeusbase[0x50] == 0x00e90000)
//{
// UINT32 addr = frame_addr_from_reg51();
// if (m_zeusbase[0x57] & 1)
// m_frameColor[addr] = m_zeusbase[0x58];
// if (m_zeusbase[0x57] & 4)
// m_frameColor[addr+1] = m_zeusbase[0x59];
//}
/* make sure we log anything else */
else if (logit)
logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
///* make sure we log anything else */
//else if (logit)
// logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
break;
case 0x58:
@ -633,23 +612,8 @@ void zeus2_device::zeus2_register_update(offs_t offset, UINT32 oldval, int logit
bit 6: enable autoincrement on write through
*/
if ((m_zeusbase[0x5e] & 0x08) && (offset & 3) == (m_zeusbase[0x5e] & 3))
{
void *dest = waveram1_ptr_from_expanded_addr(m_zeusbase[0x51]);
WAVERAM_WRITE32(dest, 0, m_zeusbase[0x58]);
if (m_zeusbase[0x5e] & 0x20)
WAVERAM_WRITE32(dest, 1, m_zeusbase[0x5a]);
else
{
WAVERAM_WRITE32(dest, 1, m_zeusbase[0x59]);
WAVERAM_WRITE32(dest, 2, m_zeusbase[0x5a]);
}
if (m_zeusbase[0x5e] & 0x40)
{
m_zeusbase[0x51]++;
m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
m_zeusbase[0x51] &= ~0xfe00;
}
{
frame_write();
}
}
@ -688,13 +652,10 @@ if (subregdata_count[which] < 256)
}
}
#endif
m_renderRegs[which] = value;
switch (which)
{
case 0x04:
zeus_renderbase = waveram1_ptr_from_expanded_addr(value << 16);
break;
case 0x05:
zeus_texbase = value % (WAVERAM0_HEIGHT * WAVERAM0_WIDTH);
break;
@ -757,20 +718,20 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords)
return FALSE;
/* extract the matrix from the raw data */
zeus_matrix[0][0] = tms3203x_device::fp_to_float(data[dataoffs + 1]);
zeus_matrix[0][1] = tms3203x_device::fp_to_float(data[dataoffs + 2]);
zeus_matrix[0][2] = tms3203x_device::fp_to_float(data[dataoffs + 3]);
zeus_matrix[1][0] = tms3203x_device::fp_to_float(data[dataoffs + 4]);
zeus_matrix[1][1] = tms3203x_device::fp_to_float(data[dataoffs + 5]);
zeus_matrix[1][2] = tms3203x_device::fp_to_float(data[dataoffs + 6]);
zeus_matrix[2][0] = tms3203x_device::fp_to_float(data[dataoffs + 7]);
zeus_matrix[2][1] = tms3203x_device::fp_to_float(data[dataoffs + 8]);
zeus_matrix[2][2] = tms3203x_device::fp_to_float(data[dataoffs + 9]);
zeus_matrix[0][0] = convert_float(data[dataoffs + 1]);
zeus_matrix[0][1] = convert_float(data[dataoffs + 2]);
zeus_matrix[0][2] = convert_float(data[dataoffs + 3]);
zeus_matrix[1][0] = convert_float(data[dataoffs + 4]);
zeus_matrix[1][1] = convert_float(data[dataoffs + 5]);
zeus_matrix[1][2] = convert_float(data[dataoffs + 6]);
zeus_matrix[2][0] = convert_float(data[dataoffs + 7]);
zeus_matrix[2][1] = convert_float(data[dataoffs + 8]);
zeus_matrix[2][2] = convert_float(data[dataoffs + 9]);
/* extract the translation point from the raw data */
zeus_point[0] = tms3203x_device::fp_to_float(data[dataoffs + 10]);
zeus_point[1] = tms3203x_device::fp_to_float(data[dataoffs + 11]);
zeus_point[2] = tms3203x_device::fp_to_float(data[dataoffs + 12]);
zeus_point[0] = convert_float(data[dataoffs + 10]);
zeus_point[1] = convert_float(data[dataoffs + 11]);
zeus_point[2] = convert_float(data[dataoffs + 12]);
if (log_fifo)
{
@ -795,9 +756,9 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords)
return FALSE;
/* extract the translation point from the raw data */
zeus_point[0] = tms3203x_device::fp_to_float(data[1]);
zeus_point[1] = tms3203x_device::fp_to_float(data[2]);
zeus_point[2] = tms3203x_device::fp_to_float(data[3]);
zeus_point[0] = convert_float(data[1]);
zeus_point[1] = convert_float(data[2]);
zeus_point[2] = convert_float(data[3]);
if (log_fifo)
{
@ -817,23 +778,14 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords)
{
log_fifo_command(data, numwords, " -- unknown control + hack clear screen\n");
logerror("\t\tvector %8.2f %8.2f %8.5f\n",
(double) tms3203x_device::fp_to_float(data[1]),
(double) tms3203x_device::fp_to_float(data[2]),
(double) tms3203x_device::fp_to_float(data[3]));
(double) convert_float(data[1]),
(double) convert_float(data[2]),
(double) convert_float(data[3]));
/* extract the translation point from the raw data */
zeus_point2[0] = tms3203x_device::fp_to_float(data[1]);
zeus_point2[1] = tms3203x_device::fp_to_float(data[2]);
zeus_point2[2] = tms3203x_device::fp_to_float(data[3]);
}
{
/* not right -- just a hack */
if (0) {
int x, y;
for (y = zeus_cliprect.min_y; y <= zeus_cliprect.max_y; y++)
for (x = zeus_cliprect.min_x; x <= zeus_cliprect.max_x; x++)
waveram_plot_depth(y, x, 0, 0x7fff);
}
zeus_point2[0] = convert_float(data[1]);
zeus_point2[1] = convert_float(data[2]);
zeus_point2[2] = convert_float(data[3]);
}
break;
@ -851,7 +803,7 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords)
zeus2_draw_model(data[1], data[0] & 0x3fff, log_fifo);
break;
// 0x2d; ??? (atlantis)
// 0x2d; direct render quad (atlantis)
case 0x2d:
if (numwords < 2)
return FALSE;
@ -860,10 +812,15 @@ int zeus2_device::zeus2_fifo_process(const UINT32 *data, int numwords)
//zeus2_draw_model(data[1], data[0] & 0xff, log_fifo);
break;
/* 0x31: sync pipeline? (thegrid) */
/* 0x32: sync pipeline? (crusnexo) */
// 0x25 ?? (atlantis)
case 0x25:
if (log_fifo)
log_fifo_command(data, numwords, "\n");
//zeus_quad_size = 10;
break;
/* 0x31: sync pipeline? (thegrid) */
/* 0x32: sync pipeline? (crusnexo) */
case 0x31:
case 0x32:
if (log_fifo)
@ -936,7 +893,7 @@ void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit)
/* if this is enough, process the command */
cmd = databuffer[0] >> 24;
if (cmd == 0x38)
if ((cmd == 0x38) || (cmd == 0x2d))
countneeded = quadsize;
if (databufcount == countneeded)
{
@ -970,6 +927,7 @@ void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit)
logerror("sync?\n");
break;
case 0x29: // atlantis
case 0x35: /* thegrid */
case 0x36: /* crusnexo */
if (logit)
@ -977,6 +935,11 @@ void zeus2_device::zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit)
zeus2_register32_w((databuffer[0] >> 16) & 0x7f, databuffer[1], logit);
break;
case 0x2d: // atlantis
texoffs = databuffer[1];
poly->zeus2_draw_quad(&databuffer[1], texoffs, logit);
break;
case 0x38: /* crusnexo/thegrid */
poly->zeus2_draw_quad(databuffer, texoffs, logit);
break;
@ -1179,11 +1142,13 @@ void zeus2_renderer::zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, i
case 0x05d: /* crusnexo: background, road */
case 0x0dd: /* crusnexo: license plate letters */
case 0x11d: /* crusnexo: LHS of score bar */
case 0x14d: // atlantis
case 0x15d: /* crusnexo */
case 0x85d: /* crusnexo */
case 0x95d: /* crusnexo */
case 0xc1d: /* crusnexo */
case 0xc5d: /* crusnexo */
case 0x18e: // atlantis
extra.texwidth = 256;
break;
@ -1191,16 +1156,20 @@ void zeus2_renderer::zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, i
case 0x0d9: /* crusnexo */
case 0x119: /* crusnexo: license plates */
case 0x159: /* crusnexo */
case 0x18a: // atlantis
extra.texwidth = 128;
break;
case 0x055: /* crusnexo */
case 0x145: // atlantis
case 0x155: /* crusnexo */
extra.texwidth = 64;
break;
case 0x000: // thegrid guess
case 0x120: // thegrid guess
case 0x140: // atlantis
case 0x141: // atlantis
extra.texwidth = 32;
break;
@ -1257,13 +1226,16 @@ void zeus2_renderer::render_poly_8bit(INT32 scanline, const extent_t& extent, co
int texwidth = object.texwidth;
int x;
UINT32 addr = m_state->frame_addr_from_xy(0, scanline, true);
UINT16 *depthptr = &m_state->m_frameDepth[addr];
UINT32 *colorptr = &m_state->m_frameColor[addr];
for (x = extent.startx; x < extent.stopx; x++)
{
UINT16 *depthptr = WAVERAM_PTRDEPTH(m_state->zeus_renderbase, scanline, x);
//UINT16 *depthptr = WAVERAM_PTRDEPTH(m_state->zeus_renderbase, scanline, x);
INT32 depth = (curz >> 16) + object.zoffset;
//if (depth > 0x7fff) depth = 0x7fff;
if (depth > 0xffff) depth = 0xffff;
if (depth >= 0 && depth <= *depthptr)
if (depth >= 0 && depth <= depthptr[x])
{
int u0 = (curu >> 8);// & (texwidth - 1);
int v0 = (curv >> 8);// & 255;
@ -1284,8 +1256,10 @@ void zeus2_renderer::render_poly_8bit(INT32 scanline, const extent_t& extent, co
color2 = ((color2 & 0x7c00) << 9) | ((color2 & 0x3e0) << 6) | ((color2 & 0x1f) << 3);
color3 = ((color3 & 0x7c00) << 9) | ((color3 & 0x3e0) << 6) | ((color3 & 0x1f) << 3);
rgb_t filtered = rgbaint_t::bilinear_filter(color0, color1, color2, color3, curu, curv);
WAVERAM_WRITEPIX(m_state->zeus_renderbase, scanline, x, filtered);
*depthptr = depth;
//WAVERAM_WRITEPIX(m_state->zeus_renderbase, scanline, x, filtered);
//*depthptr = depth;
colorptr[x] = filtered;
depthptr[x] = depth;
}
}

View File

@ -106,6 +106,9 @@ typedef zeus2_renderer::extent_t z2_poly_extent;
#define MCFG_ZEUS2_IRQ_CB(_devcb) \
devcb = &zeus2_device::set_irq_callback(*device, DEVCB_##_devcb);
#define MCFG_ZEUS2_FLOAT_MODE(_mode) \
downcast<zeus2_device *>(device)->set_float_mode(_mode);
class zeus2_device : public device_t
{
public:
@ -124,11 +127,14 @@ public:
devcb_write_line m_vblank;
devcb_write_line m_irq;
void set_float_mode(int mode) { m_ieee754_float = mode; }
int m_ieee754_float; // Used to switch to using IEEE754 floating point format
UINT32 m_zeusbase[0x80];
UINT32 m_renderRegs[0x100];
zeus2_renderer* poly;
void *zeus_renderbase;
rectangle zeus_cliprect;
float zeus_matrix[3][3];
@ -139,6 +145,9 @@ public:
int zeus_quad_size;
UINT32 *waveram[2];
std::unique_ptr<UINT32[]> m_frameColor;
std::unique_ptr<UINT16[]> m_frameDepth;
emu_timer *int_timer;
emu_timer *vblank_timer;
int m_yScale;
@ -164,15 +173,13 @@ private:
/*************************************
* Member variables
*************************************/
UINT8 log_fifo;
UINT32 zeus_fifo[20];
UINT8 zeus_fifo_words;
UINT32 m_fill_color;
UINT16 m_fill_depth;
UINT32 m_fill_depth;
#if TRACK_REG_USAGE
struct reg_info
@ -193,6 +200,75 @@ public:
/*************************************
* Inlines for block addressing
*************************************/
inline float convert_float(UINT32 val)
{
if (m_ieee754_float)
return reinterpret_cast<float&>(val);
else
return tms3203x_device::fp_to_float(val);
}
inline UINT32 frame_addr_from_xy(UINT32 x, UINT32 y, bool render)
{
UINT32 addr = render ? frame_addr_from_expanded_addr(m_renderRegs[0x4] << 16)
: frame_addr_from_expanded_addr(m_zeusbase[0x38]);
addr += ((y * WAVERAM1_WIDTH) << (1 - m_yScale)) + x;
return addr;
}
// Convert 0xRRRRCCCC to frame buffer addresss
inline UINT32 frame_addr_from_expanded_addr(UINT32 addr)
{
return (((addr & 0x3ff0000) >> (16 - 9 + m_yScale)) | (addr & 0x1ff)) << 1;
}
// Convert Physical 0xRRRRCCCC to frame buffer addresss
// Based on address reg 51 (no scaling)
inline UINT32 frame_addr_from_reg51()
{
UINT32 addr = (((m_zeusbase[0x51] & 0x3ff0000) >> (16 - 9)) | (m_zeusbase[0x51] & 0x1ff)) << 1;
return addr;
}
// Read from frame buffer
inline void frame_read()
{
UINT32 addr = frame_addr_from_reg51();
m_zeusbase[0x58] = m_frameColor[addr];
m_zeusbase[0x59] = m_frameColor[addr + 1];
m_zeusbase[0x5a] = *(UINT32*)&m_frameDepth[addr];
if (m_zeusbase[0x5e] & 0x40)
{
m_zeusbase[0x51]++;
m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
m_zeusbase[0x51] &= ~0xfe00;
}
}
// Write to frame buffer
inline void frame_write()
{
UINT32 addr = frame_addr_from_reg51();
if (m_zeusbase[0x57] & 0x1)
m_frameColor[addr] = m_zeusbase[0x58];
if (m_zeusbase[0x5e] & 0x20) {
if (m_zeusbase[0x57] & 0x4)
m_frameColor[addr + 1] = m_zeusbase[0x5a];
} else
{
if (m_zeusbase[0x57] & 0x4)
m_frameColor[addr + 1] = m_zeusbase[0x59];
if (m_zeusbase[0x57] & 0x10)
*(UINT32*)&m_frameDepth[addr] = m_zeusbase[0x5a];
}
if (m_zeusbase[0x5e] & 0x40)
{
m_zeusbase[0x51]++;
m_zeusbase[0x51] += (m_zeusbase[0x51] & 0x200) << 7;
m_zeusbase[0x51] &= ~0xfe00;
}
}
inline void *waveram0_ptr_from_expanded_addr(UINT32 addr)
{
@ -226,6 +302,7 @@ public:
}
#endif
#ifdef UNUSED_FUNCTION
inline void waveram_plot_depth(int y, int x, UINT32 color, UINT16 depth)
{
if (zeus_cliprect.contains(x, y))
@ -234,6 +311,7 @@ public:
WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth);
}
}
#endif
#ifdef UNUSED_FUNCTION
inline void waveram_plot_check_depth(int y, int x, UINT32 color, UINT16 depth)

View File

@ -360,6 +360,10 @@ bool device_t::findit(bool isvalidation) const
void device_t::start()
{
// prepare the logerror buffer
if (m_machine->allow_logging())
m_string_buffer.reserve(1024);
// find all the registered devices
if (!findit(false))
throw emu_fatalerror("Missing some required objects, unable to proceed");
@ -380,7 +384,7 @@ void device_t::start()
device_sound_interface *sound;
if (state_registrations == 0 && (interface(exec) || interface(sound)) && type() != SPEAKER)
{
logerror("Device '%s' did not register any state to save!\n", tag());
logerror("Device did not register any state to save!\n");
if ((machine().system().flags & MACHINE_SUPPORTS_SAVE) != 0)
fatalerror("Device '%s' did not register any state to save!\n", tag());
}

View File

@ -361,6 +361,9 @@ private:
bool m_config_complete; // have we completed our configuration?
bool m_started; // true if the start function has succeeded
finder_base * m_auto_finder_list; // list of objects to auto-find
// string formatting buffer for logerror
mutable util::ovectorstream m_string_buffer;
};

View File

@ -17,8 +17,6 @@
#ifndef __DEVICE_IPP__
#define __DEVICE_IPP__
#include "strformat.h"
//**************************************************************************
// MEMBER TEMPLATES
//**************************************************************************
@ -26,15 +24,28 @@
template <typename Format, typename... Params>
inline void device_t::popmessage(Format &&fmt, Params &&... args) const
{
if (m_machine)
if (m_machine != nullptr)
m_machine->popmessage(std::forward<Format>(fmt), std::forward<Params>(args)...);
}
template <typename Format, typename... Params>
inline void device_t::logerror(Format &&fmt, Params &&... args) const
{
if (m_machine)
m_machine->logerror(string_format("[%s] %s", tag(), std::forward<Format>(fmt)), std::forward<Params>(args)...);
if (m_machine != nullptr && m_machine->allow_logging())
{
g_profiler.start(PROFILER_LOGERROR);
// dump to the buffer
m_string_buffer.clear();
m_string_buffer.seekp(0);
util::stream_format(m_string_buffer, "[%s] ", tag());
util::stream_format(m_string_buffer, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_string_buffer.put('\0');
m_machine->strlog(&m_string_buffer.vec()[0]);
g_profiler.stop();
}
}
#endif // __DEVICE_IPP__

View File

@ -29,9 +29,11 @@
#include "eminline.h"
#include "profiler.h"
// commonly-referenecd utilities imported from lib/util
// commonly-referenced utilities imported from lib/util
#include "palette.h"
#include "unicode.h"
#include "strformat.h"
#include "vecstream.h"
// emulator-specific utilities
#include "attotime.h"

View File

@ -727,6 +727,19 @@ void running_machine::add_logerror_callback(logerror_callback callback)
}
//-------------------------------------------------
// strlog - send an error logging string to the
// debugger and any OSD-defined output streams
//-------------------------------------------------
void running_machine::strlog(const char *str) const
{
// log to all callbacks
for (auto &cb : m_logerror_list)
cb->m_func(str);
}
//-------------------------------------------------
// debug_break - breaks into the debugger, if
// enabled

View File

@ -19,9 +19,6 @@
#include <functional>
#include "strformat.h"
#include "vecstream.h"
#include <time.h>
// forward declaration instead of osdepend.h
@ -198,6 +195,7 @@ public:
emu_options &options() const { return m_config.options(); }
attotime time() const { return m_scheduler.time(); }
bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; }
bool allow_logging() const { return !m_logerror_list.empty(); }
// fetch items by name
inline device_t *device(const char *tag) const { return root_device().subdevice(tag); }
@ -233,6 +231,7 @@ public:
void popmessage() const { popmessage(static_cast<char const *>(nullptr)); }
template <typename Format, typename... Params> void popmessage(Format &&fmt, Params &&... args) const;
template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;
void strlog(const char *str) const;
UINT32 rand();
const char *describe_context();
@ -387,7 +386,7 @@ template <typename Format, typename... Params>
inline void running_machine::logerror(Format &&fmt, Params &&... args) const
{
// process only if there is a target
if (!m_logerror_list.empty())
if (allow_logging())
{
g_profiler.start(PROFILER_LOGERROR);
@ -397,10 +396,7 @@ inline void running_machine::logerror(Format &&fmt, Params &&... args) const
util::stream_format(m_string_buffer, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_string_buffer.put('\0');
// log to all callbacks
char const *const str(&m_string_buffer.vec()[0]);
for (auto &cb : m_logerror_list)
cb->m_func(str);
strlog(&m_string_buffer.vec()[0]);
g_profiler.stop();
}

View File

@ -587,7 +587,25 @@ luabridge::LuaRef lua_engine::l_memory_get_regions(const memory_manager *m)
luabridge::LuaRef table = luabridge::LuaRef::newTable(L);
for (auto &region: mm->regions()) {
table[region.second->name()] = &region;
table[region.second->name()] = region.second.get();
}
return table;
}
//-------------------------------------------------
// memory_shares - return memory_shares
// -> manager:machine():memory().share[":maincpu"]
//-------------------------------------------------
luabridge::LuaRef lua_engine::l_memory_get_shares(const memory_manager *m)
{
memory_manager *mm = const_cast<memory_manager *>(m);
lua_State *L = luaThis->m_lua_state;
luabridge::LuaRef table = luabridge::LuaRef::newTable(L);
for (auto &share: mm->shares()) {
table[share.first] = share.second.get();
}
return table;
@ -1063,7 +1081,7 @@ int lua_engine::lua_addr_space::l_direct_mem_write(lua_State *L)
//-------------------------------------------------
// region_read - templated region readers for <sign>,<size>
// -> manager:machine():memory().region[":maincpu"]:read_i8(0xC000)
// -> manager:machine():memory().regions[":maincpu"]:read_i8(0xC000)
//-------------------------------------------------
template <typename T>
@ -1097,7 +1115,7 @@ int lua_engine::lua_memory_region::l_region_read(lua_State *L)
//-------------------------------------------------
// region_write - templated region writer for <sign>,<size>
// -> manager:machine():memory().region[":maincpu"]:write_u16(0xC000, 0xF00D)
// -> manager:machine():memory().regions[":maincpu"]:write_u16(0xC000, 0xF00D)
//-------------------------------------------------
template <typename T>
@ -1124,6 +1142,71 @@ int lua_engine::lua_memory_region::l_region_write(lua_State *L)
return 0;
}
//-------------------------------------------------
// share_read - templated share readers for <sign>,<size>
// -> manager:machine():memory().shares[":maincpu"]:read_i8(0xC000)
//-------------------------------------------------
template <typename T>
int lua_engine::lua_memory_share::l_share_read(lua_State *L)
{
memory_share &share = luabridge::Stack<memory_share &>::get(L, 1);
luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected");
offs_t address = lua_tounsigned(L, 2);
T mem_content = 0;
offs_t lowmask = share.bytewidth() - 1;
UINT8* ptr = (UINT8*)share.ptr();
for(int i = 0; i < sizeof(T); i++)
{
int addr = share.endianness() == ENDIANNESS_LITTLE ? address + sizeof(T) - 1 - i : address + i;
if(addr >= share.bytes())
continue;
mem_content <<= 8;
if(share.endianness() == ENDIANNESS_BIG)
mem_content |= ptr[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)];
else
mem_content |= ptr[(BYTE8_XOR_LE(addr) & lowmask) | (addr & ~lowmask)];
}
if (std::numeric_limits<T>::is_signed) {
lua_pushinteger(L, mem_content);
} else {
lua_pushunsigned(L, mem_content);
}
return 1;
}
//-------------------------------------------------
// share_write - templated share writer for <sign>,<size>
// -> manager:machine():memory().shares[":maincpu"]:write_u16(0xC000, 0xF00D)
//-------------------------------------------------
template <typename T>
int lua_engine::lua_memory_share::l_share_write(lua_State *L)
{
memory_share &share = luabridge::Stack<memory_share &>::get(L, 1);
luaL_argcheck(L, lua_isnumber(L, 2), 2, "address (integer) expected");
luaL_argcheck(L, lua_isnumber(L, 3), 3, "value (integer) expected");
offs_t address = lua_tounsigned(L, 2);
T val = lua_tounsigned(L, 3);
offs_t lowmask = share.bytewidth() - 1;
UINT8* ptr = (UINT8*)share.ptr();
for(int i = 0; i < sizeof(T); i++)
{
int addr = share.endianness() == ENDIANNESS_BIG ? address + sizeof(T) - 1 - i : address + i;
if(addr >= share.bytes())
continue;
if(share.endianness() == ENDIANNESS_BIG)
ptr[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)] = val & 0xff;
else
ptr[(BYTE8_XOR_BE(addr) & lowmask) | (addr & ~lowmask)] = val & 0xff;
val >>= 8;
}
return 0;
}
luabridge::LuaRef lua_engine::l_addr_space_map(const address_space *space)
{
lua_State *L = luaThis->m_lua_state;
@ -2375,6 +2458,7 @@ void lua_engine::initialize()
.beginClass <memory_manager> ("memory")
.addProperty <luabridge::LuaRef, void> ("banks", &lua_engine::l_memory_get_banks)
.addProperty <luabridge::LuaRef, void> ("regions", &lua_engine::l_memory_get_regions)
.addProperty <luabridge::LuaRef, void> ("shares", &lua_engine::l_memory_get_shares)
.endClass()
.beginClass <lua_memory_region> ("lua_region")
.addCFunction ("read_i8", &lua_memory_region::l_region_read<INT8>)
@ -2394,6 +2478,30 @@ void lua_engine::initialize()
.addCFunction ("write_i64", &lua_memory_region::l_region_write<INT64>)
.addCFunction ("write_u64", &lua_memory_region::l_region_write<UINT64>)
.endClass()
.deriveClass <memory_region, lua_memory_region> ("region")
.addProperty <UINT32> ("size", &memory_region::bytes)
.endClass()
.beginClass <lua_memory_share> ("lua_share")
.addCFunction ("read_i8", &lua_memory_share::l_share_read<INT8>)
.addCFunction ("read_u8", &lua_memory_share::l_share_read<UINT8>)
.addCFunction ("read_i16", &lua_memory_share::l_share_read<INT16>)
.addCFunction ("read_u16", &lua_memory_share::l_share_read<UINT16>)
.addCFunction ("read_i32", &lua_memory_share::l_share_read<INT32>)
.addCFunction ("read_u32", &lua_memory_share::l_share_read<UINT32>)
.addCFunction ("read_i64", &lua_memory_share::l_share_read<INT64>)
.addCFunction ("read_u64", &lua_memory_share::l_share_read<UINT64>)
.addCFunction ("write_i8", &lua_memory_share::l_share_write<INT8>)
.addCFunction ("write_u8", &lua_memory_share::l_share_write<UINT8>)
.addCFunction ("write_i16", &lua_memory_share::l_share_write<INT16>)
.addCFunction ("write_u16", &lua_memory_share::l_share_write<UINT16>)
.addCFunction ("write_i32", &lua_memory_share::l_share_write<INT32>)
.addCFunction ("write_u32", &lua_memory_share::l_share_write<UINT32>)
.addCFunction ("write_i64", &lua_memory_share::l_share_write<INT64>)
.addCFunction ("write_u64", &lua_memory_share::l_share_write<UINT64>)
.endClass()
.deriveClass <memory_share, lua_memory_share> ("region")
.addProperty <size_t> ("size", &memory_share::bytes)
.endClass()
.beginClass <output_manager> ("output")
.addFunction ("set_value", &output_manager::set_value)
.addFunction ("set_indexed_value", &output_manager::set_indexed_value)
@ -2402,9 +2510,6 @@ void lua_engine::initialize()
.addFunction ("name_to_id", &output_manager::name_to_id)
.addFunction ("id_to_name", &output_manager::id_to_name)
.endClass()
.deriveClass <memory_region, lua_memory_region> ("region")
.addProperty <UINT32> ("size", &memory_region::bytes)
.endClass()
.beginClass <device_image_interface> ("image")
.addFunction ("exists", &device_image_interface::exists)
.addFunction ("filename", &device_image_interface::filename)

View File

@ -198,6 +198,11 @@ private:
};
static luabridge::LuaRef l_memory_get_banks(const memory_manager *m);
static luabridge::LuaRef l_memory_get_shares(const memory_manager *m);
struct lua_memory_share {
template<typename T> int l_share_read(lua_State *L);
template<typename T> int l_share_write(lua_State *L);
};
static luabridge::LuaRef l_memory_get_regions(const memory_manager *m);
struct lua_memory_region {
template<typename T> int l_region_read(lua_State *L);

View File

@ -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

View File

@ -950,8 +950,8 @@ void apollo_state::machine_start(){
MACHINE_START_CALL_MEMBER(apollo);
// install nop handlers for unmapped ISA bus addresses
m_isa->install16_device(0, ATBUS_IO_END, read16_delegate(FUNC(apollo_state::apollo_atbus_unmap_io_r), this), write16_delegate(FUNC(apollo_state::apollo_atbus_unmap_io_w), this));
m_isa->install_memory(0, ATBUS_MEMORY_END, read8_delegate(FUNC(apollo_state::apollo_atbus_unmap_r), this), write8_delegate(FUNC(apollo_state::apollo_atbus_unmap_w), this));
m_isa->install16_device((ATBUS_IO_BASE - 0x40000) >> 7, (ATBUS_IO_END - 0x40000) >> 7, read16_delegate(FUNC(apollo_state::apollo_atbus_unmap_io_r), this), write16_delegate(FUNC(apollo_state::apollo_atbus_unmap_io_w), this));
m_isa->install_memory(ATBUS_MEMORY_BASE, ATBUS_MEMORY_END, read8_delegate(FUNC(apollo_state::apollo_atbus_unmap_r), this), write8_delegate(FUNC(apollo_state::apollo_atbus_unmap_w), this));
}
/***************************************************************************

View File

@ -370,7 +370,7 @@ WRITE32_MEMBER(atlantis_state::status_leds_w)
case 0xfe: digit = '-'; break;
case 0xff: digit = 'Z'; break;
}
popmessage("LED: %c", digit);
//popmessage("LED: %c", digit);
osd_printf_debug("%06X: status_leds_w digit: %c %08x = %02x\n", machine().device("maincpu")->safe_pc(), digit, offset, data);
logerror("%06X: status_leds_w digit: %c %08x = %02x\n", machine().device("maincpu")->safe_pc(), digit, offset, data);
}
@ -818,6 +818,7 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state )
/* video hardware */
MCFG_DEVICE_ADD("zeus2", ZEUS2, ZEUS2_VIDEO_CLOCK)
MCFG_ZEUS2_FLOAT_MODE(1)
MCFG_ZEUS2_IRQ_CB(WRITELINE(atlantis_state, zeus_irq))
MCFG_ZEUS2_VBLANK_CB(WRITELINE(atlantis_state, vblank_irq))

View File

@ -10,7 +10,7 @@
#include "emu.h"
#include "cpu/mcs51/mcs51.h"
#include "cpu/m6805/m6805.h"
#include "cpu/m6800/m6800.h"
#include "includes/banctec.h"
#include "video/mc6845.h"
@ -87,7 +87,7 @@ static MACHINE_CONFIG_START( banctec, banctec_state )
MCFG_CPU_ADD("maincpu", I80C31, XTAL_11_0592MHz)
MCFG_CPU_PROGRAM_MAP(banctec_mem)
MCFG_CPU_ADD("mcu", M6805, 4000000) /* Actual MCU is a Motorola 6803 and the clock frequency is still unknown */
MCFG_CPU_ADD("mcu", M6803, 4000000) /* Actual MCU is a Motorola 6803 and the clock frequency is still unknown */
MCFG_CPU_PROGRAM_MAP(banctec_mcu_mem)
// The video signal is generated by a R6545EAP character generator chip

View File

@ -27,7 +27,7 @@ public:
static ADDRESS_MAP_START( bingo_map, AS_PROGRAM, 8, bingo_state )
AM_RANGE(0x0000, 0xffff) AM_NOP
AM_RANGE(0x0000, 0x7fff) AM_NOP
AM_RANGE(0x0000, 0x1eff) AM_ROM
AM_RANGE(0x1f00, 0x1fff) AM_RAM
ADDRESS_MAP_END

View File

@ -65,25 +65,25 @@ MACHINE_RESET_MEMBER(blstroid_state,blstroid)
static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, blstroid_state )
ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_GLOBAL_MASK(0x83ffff)
AM_RANGE(0x000000, 0x03ffff) AM_MIRROR(0x7c0000) AM_ROM
AM_RANGE(0x800000, 0x800001) AM_MIRROR(0x7f81fe) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w)
AM_RANGE(0x800200, 0x800201) AM_MIRROR(0x7f81fe) AM_WRITE(scanline_int_ack_w)
AM_RANGE(0x800400, 0x800401) AM_MIRROR(0x7f81fe) AM_WRITE(video_int_ack_w)
AM_RANGE(0x800600, 0x800601) AM_MIRROR(0x7f81fe) AM_DEVWRITE("eeprom", atari_eeprom_device, unlock_write)
AM_RANGE(0x800800, 0x8009ff) AM_MIRROR(0x7f8000) AM_WRITEONLY AM_SHARE("priorityram")
AM_RANGE(0x800a00, 0x800a01) AM_MIRROR(0x7f81fe) AM_DEVWRITE8("jsa", atari_jsa_i_device, main_command_w, 0x00ff)
AM_RANGE(0x800c00, 0x800c01) AM_MIRROR(0x7f81fe) AM_DEVWRITE("jsa", atari_jsa_i_device, sound_reset_w)
AM_RANGE(0x800e00, 0x800e01) AM_MIRROR(0x7f81fe) AM_WRITE(blstroid_halt_until_hblank_0_w)
AM_RANGE(0x801400, 0x801401) AM_MIRROR(0x7f83fe) AM_DEVREAD8("jsa", atari_jsa_i_device, main_response_r, 0x00ff)
AM_RANGE(0x801800, 0x801801) AM_MIRROR(0x7f83f8) AM_READ_PORT("DIAL0")
AM_RANGE(0x801804, 0x801805) AM_MIRROR(0x7f83f8) AM_READ_PORT("DIAL1")
AM_RANGE(0x801c00, 0x801c01) AM_MIRROR(0x7f83fc) AM_READ_PORT("IN0")
AM_RANGE(0x801c02, 0x801c03) AM_MIRROR(0x7f83fc) AM_READ_PORT("IN1")
AM_RANGE(0x802000, 0x8023ff) AM_MIRROR(0x7f8c00) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x803000, 0x8033ff) AM_MIRROR(0x7f8c00) AM_DEVREADWRITE8("eeprom", atari_eeprom_device, read, write, 0x00ff)
AM_RANGE(0x804000, 0x804fff) AM_MIRROR(0x7f8000) AM_RAM_DEVWRITE("playfield", tilemap_device, write) AM_SHARE("playfield")
AM_RANGE(0x805000, 0x805fff) AM_MIRROR(0x7f8000) AM_RAM AM_SHARE("mob")
AM_RANGE(0x806000, 0x807fff) AM_MIRROR(0x7f8000) AM_RAM
AM_RANGE(0x000000, 0x03ffff) AM_MIRROR(0x000000) AM_ROM
AM_RANGE(0x800000, 0x800001) AM_MIRROR(0x0381fe) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w)
AM_RANGE(0x800200, 0x800201) AM_MIRROR(0x0381fe) AM_WRITE(scanline_int_ack_w)
AM_RANGE(0x800400, 0x800401) AM_MIRROR(0x0381fe) AM_WRITE(video_int_ack_w)
AM_RANGE(0x800600, 0x800601) AM_MIRROR(0x0381fe) AM_DEVWRITE("eeprom", atari_eeprom_device, unlock_write)
AM_RANGE(0x800800, 0x8009ff) AM_MIRROR(0x038000) AM_WRITEONLY AM_SHARE("priorityram")
AM_RANGE(0x800a00, 0x800a01) AM_MIRROR(0x0381fe) AM_DEVWRITE8("jsa", atari_jsa_i_device, main_command_w, 0x00ff)
AM_RANGE(0x800c00, 0x800c01) AM_MIRROR(0x0381fe) AM_DEVWRITE("jsa", atari_jsa_i_device, sound_reset_w)
AM_RANGE(0x800e00, 0x800e01) AM_MIRROR(0x0381fe) AM_WRITE(blstroid_halt_until_hblank_0_w)
AM_RANGE(0x801400, 0x801401) AM_MIRROR(0x0383fe) AM_DEVREAD8("jsa", atari_jsa_i_device, main_response_r, 0x00ff)
AM_RANGE(0x801800, 0x801801) AM_MIRROR(0x0383f8) AM_READ_PORT("DIAL0")
AM_RANGE(0x801804, 0x801805) AM_MIRROR(0x0383f8) AM_READ_PORT("DIAL1")
AM_RANGE(0x801c00, 0x801c01) AM_MIRROR(0x0383fc) AM_READ_PORT("IN0")
AM_RANGE(0x801c02, 0x801c03) AM_MIRROR(0x0383fc) AM_READ_PORT("IN1")
AM_RANGE(0x802000, 0x8023ff) AM_MIRROR(0x038c00) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x803000, 0x8033ff) AM_MIRROR(0x038c00) AM_DEVREADWRITE8("eeprom", atari_eeprom_device, read, write, 0x00ff)
AM_RANGE(0x804000, 0x804fff) AM_MIRROR(0x038000) AM_RAM_DEVWRITE("playfield", tilemap_device, write) AM_SHARE("playfield")
AM_RANGE(0x805000, 0x805fff) AM_MIRROR(0x038000) AM_RAM AM_SHARE("mob")
AM_RANGE(0x806000, 0x807fff) AM_MIRROR(0x038000) AM_RAM
ADDRESS_MAP_END

View File

@ -62,8 +62,6 @@ WRITE8_MEMBER(comquest_state::comquest_write)
static ADDRESS_MAP_START( comquest_mem , AS_PROGRAM, 8, comquest_state )
// { 0x0000, 0x7fff, SMH_BANK(1) },
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0xffff) AM_READONLY AM_WRITENOP
// { 0x8000, 0xffff, SMH_RAM }, // batterie buffered
ADDRESS_MAP_END
static INPUT_PORTS_START( comquest )

View File

@ -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 */

View File

@ -421,7 +421,7 @@ DRIVER_INIT_MEMBER(drw80pkr_state,drw80pkr)
*************************/
static ADDRESS_MAP_START( drw80pkr_map, AS_PROGRAM, 8, drw80pkr_state )
AM_RANGE(0x0000, 0x1fff) AM_ROMBANK("bank1")
AM_RANGE(0x0000, 0x0fff) AM_ROMBANK("bank1")
ADDRESS_MAP_END
static ADDRESS_MAP_START( drw80pkr_io_map, AS_IO, 8, drw80pkr_state )

View File

@ -6916,7 +6916,7 @@ static INPUT_PORTS_START( cmtetris )
INPUT_PORTS_END
static INPUT_PORTS_START( flaming7 )
static INPUT_PORTS_START( flam7_w4 )
PORT_START("IN0") /* b800 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_L) PORT_NAME("Button Lockout")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 - Big")
@ -7066,6 +7066,157 @@ static INPUT_PORTS_START( flaming7 )
INPUT_PORTS_END
static INPUT_PORTS_START( flaming7 )
PORT_START("IN0") /* b800 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_L) PORT_NAME("Button Lockout")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 - Big")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) PORT_NAME("Hold 3 - Double-Up")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) PORT_NAME("Hold 4 - Take Score")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet 1")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) PORT_NAME("Hold 2 - Low")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Start")
PORT_START("IN1") /* b801 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN2") /* b802 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER( "fl7w4_id", ds2401_device, read ) // Same input, different device.
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN3") /* b810 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_D) PORT_NAME("Main Door SW")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_H) PORT_NAME("Change")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_F) PORT_NAME("Logic Door SW")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_G) PORT_NAME("Cash Door SW")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_T) PORT_NAME("IN3-5")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Coin B") // confirmed.
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_NAME("Coin A") // confirmed.
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) PORT_NAME("Coin C or Mars") // confirmed.
PORT_START("IN4") /* b811 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_A) PORT_NAME("WT RXD")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S) PORT_NAME("COUT RTS") // related to hopper...
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Y) PORT_NAME("IN4-3")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_U) PORT_NAME("IN4-4 Active") // This one is active in real PCB.
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_I) PORT_NAME("IN4-5")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Collect")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_R) PORT_NAME("Reset")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_CODE(KEYCODE_0) PORT_NAME("Books / Stats / Setup") PORT_TOGGLE
PORT_START("DSW1")
PORT_DIPNAME( 0x03, 0x03, "Credits Out" ) PORT_DIPLOCATION("DSW1:1,2")
PORT_DIPSETTING( 0x03, "Amusement (no credits out)" )
PORT_DIPSETTING( 0x02, "Ticket Printer" )
PORT_DIPSETTING( 0x01, "Hopper Payout" )
PORT_DIPSETTING( 0x00, "Remote Clear" )
PORT_DIPNAME( 0x04, 0x04, "Game Speed" ) PORT_DIPLOCATION("DSW1:3")
PORT_DIPSETTING( 0x04, "Fast Game" )
PORT_DIPSETTING( 0x00, "Slow Game" )
PORT_DIPNAME( 0x08, 0x08, "Lock-Up on 7 or 8 of a kind" ) PORT_DIPLOCATION("DSW1:4")
PORT_DIPSETTING( 0x08, DEF_STR( No ) )
PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
PORT_DIPNAME( 0x30, 0x30, "Graphics Type" ) PORT_DIPLOCATION("DSW1:5,6")
PORT_DIPSETTING( 0x30, "Regular Fruit" )
PORT_DIPSETTING( 0x20, "Numbers" )
PORT_DIPSETTING( 0x10, "Graphics Option 1" )
PORT_DIPSETTING( 0x00, "Graphics Option 2" )
PORT_DIPNAME( 0xc0, 0xc0, "Paytable" ) PORT_DIPLOCATION("DSW1:7,8")
PORT_DIPSETTING( 0xc0, "9322" )
PORT_DIPSETTING( 0x80, "9323" )
PORT_DIPSETTING( 0x40, "9324" )
PORT_DIPSETTING( 0x00, "9321" )
PORT_START("DSW2")
PORT_DIPNAME( 0x07, 0x07, "Bonus Pay" ) PORT_DIPLOCATION("DSW2:1,2,3") // percentage of how quickly the internal progressive advances.
PORT_DIPSETTING( 0x07, "1.00%" )
PORT_DIPSETTING( 0x06, "2.00%" )
PORT_DIPSETTING( 0x05, "3.30%" )
PORT_DIPSETTING( 0x04, "4.00%" )
PORT_DIPSETTING( 0x03, "5.00%" )
PORT_DIPSETTING( 0x02, "6.20%" )
PORT_DIPSETTING( 0x01, "8.30%" )
PORT_DIPSETTING( 0x00, "10%" )
PORT_DIPNAME( 0x08, 0x00, "Internal Progressive" ) PORT_DIPLOCATION("DSW2:4")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW2:5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW2:6")
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW2:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW2:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("DSW3")
PORT_DIPNAME( 0x03, 0x03, "Maximum Bet" ) PORT_DIPLOCATION("DSW3:1,2")
PORT_DIPSETTING( 0x03, "8" )
PORT_DIPSETTING( 0x02, "16" )
PORT_DIPSETTING( 0x01, "32" )
PORT_DIPSETTING( 0x00, "64" )
PORT_DIPNAME( 0x04, 0x04, "Coin-In Timeout" ) PORT_DIPLOCATION("DSW3:3")
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x38, 0x38, "Denomination" ) PORT_DIPLOCATION("DSW3:4,5,6")
PORT_DIPSETTING( 0x38, "$1.00" )
PORT_DIPSETTING( 0x30, "50 Cents" )
PORT_DIPSETTING( 0x28, "25 Cents" )
PORT_DIPSETTING( 0x20, "10 Cents" )
PORT_DIPSETTING( 0x18, "5 Cents" )
PORT_DIPSETTING( 0x10, "5 Cents" )
PORT_DIPSETTING( 0x08, "5 Cents" )
PORT_DIPSETTING( 0x00, "5 Cents" )
PORT_DIPNAME( 0xc0, 0xc0, "Progressive Sign" ) PORT_DIPLOCATION("DSW3:7,8")
PORT_DIPSETTING( 0xc0, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, "Single Level" )
PORT_DIPSETTING( 0x40, "Multi Level" ) // use this setting *only* if using external sign.
PORT_DIPSETTING( 0x00, "Test Mode" )
PORT_START("DSW4")
PORT_DIPNAME( 0x01, 0x01, "Button Lockout" ) PORT_DIPLOCATION("DSW4:1") // this is used to lockout the button panel switches...
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, "Lockout Polarity" ) PORT_DIPLOCATION("DSW4:2")
PORT_DIPSETTING( 0x02, "Active High" )
PORT_DIPSETTING( 0x00, "Active Low" )
PORT_DIPNAME( 0x0c, 0x0c, "Printer Type" ) PORT_DIPLOCATION("DSW4:3,4")
PORT_DIPSETTING( 0x0c, "Epson 267A" )
PORT_DIPSETTING( 0x08, "Star 300" )
PORT_DIPSETTING( 0x04, "Ithaca 76" )
PORT_DIPSETTING( 0x00, "Citizen 3541" )
PORT_DIPNAME( 0x10, 0x10, "Paper Low Sensor" ) PORT_DIPLOCATION("DSW4:5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW4:6")
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW4:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Not Used (Leave OFF)" ) PORT_DIPLOCATION("DSW4:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
/*****************************************************
* Graphics Layouts & Decode *
@ -7396,6 +7547,31 @@ static const gfx_layout flaming7_tilelayout =
128*8 /* every char takes 128 consecutive bytes */
};
static const gfx_layout flam7_tw_charlayout =
{
8,8, /* 8*8 characters */
4096, /* 4096 characters */
3, /* 3 bits per pixel */
{ 2, 4, 6 }, /* the bitplanes are packed in one byte */
{ 3*8+0, 3*8+1, 2*8+0, 2*8+1, 1*8+0, 1*8+1, 0*8+0, 0*8+1 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
32*8 /* every char takes 32 consecutive bytes */
};
static const gfx_layout flam7_tw_tilelayout = // FIXME
{
8,32, /* 8*32 characters */
256, /* 256 tiles */
4, /* 4 bits per pixel */
{ 0, 2, 4, 6 },
{ 3*8+0, 3*8+1, 2*8+0, 1*8+0, 1*8+1, 2*8+1, 0, 1 },
{ 0*8, 4*8, 8*8, 12*8, 16*8, 20*8, 24*8, 28*8,
32*8, 36*8, 40*8, 44*8, 48*8, 52*8, 56*8, 60*8,
64*8, 68*8, 72*8, 76*8, 80*8, 84*8, 88*8, 92*8,
96*8, 100*8, 104*8, 108*8, 112*8, 116*8, 120*8, 124*8 },
128*8 /* every char takes 128 consecutive bytes */
};
static GFXDECODE_START( goldstar )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 16 )
@ -7505,6 +7681,11 @@ static GFXDECODE_START( flaming7 ) // gfx 2 still wrong...
GFXDECODE_ENTRY( "gfx2", 0, flaming7_tilelayout, 104, 8 )
GFXDECODE_END
static GFXDECODE_START( flam7_tw ) // gfx 2 still wrong...
GFXDECODE_ENTRY( "gfx1", 0, flam7_tw_charlayout, 0, 16 )
GFXDECODE_ENTRY( "gfx2", 0, flam7_tw_tilelayout, 104, 8 )
GFXDECODE_END
static const gfx_layout tiles8x32_4bpp_layout =
{
@ -8245,6 +8426,20 @@ static MACHINE_CONFIG_DERIVED( flaming7, lucky8 )
MCFG_DS2401_ADD("fl7w4_id")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( flam7_tw, lucky8 )
/* basic machine hardware */
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(flaming7_map)
MCFG_GFXDECODE_MODIFY("gfxdecode", flam7_tw)
// to do serial protection.
MCFG_DEVICE_MODIFY("ppi8255_0")
MCFG_I8255_OUT_PORTC_CB(WRITE8(wingco_state, fl7w4_outc802_w))
MCFG_DS2401_ADD("fl7w4_id")
MACHINE_CONFIG_END
PALETTE_INIT_MEMBER(wingco_state, magodds)
@ -14126,12 +14321,12 @@ ROM_END
| 02 | Buffalo Bills. | NO | NO |
| 03 | Cash Cabaret. | NO | NO |
| 04 | Cash Cow. | NO | NO |
| 05 | Cherry 50 Bonus. | NO | NO |
| 06 | Cherry 500 Bonus. | NO | NO |
| 07 | Cherry 1000 Bonus. | NO | NO |
| 05 | Cherry 50 Bonus. | YES | YES | Custom main 50, 500 & 2000.
| 06 | Cherry 500 Bonus. | YES | YES | Custom main 50, 500 & 2000.
| 07 | Cherry 1000 Bonus. | YES | YES | Custom main 50, 500 & 2000.
| 08 | Christmas. | NO | NO |
| 09 | Deuces Wild. | NO | NO |
| 10 | Diamond Delight. | NO | NO |
| 10 | Diamond Delight. | YES | YES | Different set. Custom main 50, 500 & 2000.
| 11 | Diamond Doubles. | NO | NO |
| 12 | Diamond Treasure. | NO | NO |
| 13 | Dream Catcher. | NO | NO |
@ -14142,7 +14337,7 @@ ROM_END
| 18 | Golden Treasure. | NO | NO |
| 19 | Greenbacks. | NO | NO |
| 20 | Harley Davidson. | NO | NO |
| 21 | Hollywood Nights. | YES | YES |
| 21 | Hollywood Nights. | YES (W4)| YES (W4) | Flaming 7's W4 version.
| 22 | Independence Day. | NO | NO |
| 23 | Jokers Wild. | NO | NO |
| 24 | Midnight Sevens. | NO | NO |
@ -14152,7 +14347,7 @@ ROM_END
| 28 | New Year's. | NO | NO |
| 29 | Prospector's Gold. | NO | NO |
| 30 | Red Hot Ice. | NO | NO |
| 31 | Red, White & Blue 7's. | YES | YES |
| 31 | Red, White & Blue 7's. | YES (W4)| YES (W4) | Flaming 7's W4 version.
| 32 | Rising Star. | NO | NO |
| 33 | Rockin' Reels. | NO | NO |
| 34 | Rolling Thunder. | NO | NO |
@ -14175,6 +14370,269 @@ ROM_END
-------------------------------------------------------------------
Original Cyberdyne Systems hardware DIP switches:
+-----------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| DIP SWITCHES BANK #1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| CREDITS OUT | NO CREDITS OUT | OFF | OFF | | | | | | |
| | TICKET PRINTER | ON | OFF | | | | | | |
| | HOPPER PAYOUT | OFF | ON | | | | | | |
| | REMOTE CLEAR | ON | ON | | | | | | |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| GAME SPEED | FAST GAME | | | OFF | | | | | |
| | SLOW GAME | | | ON | | | | | |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| LOCK UP ON 7-8 | NO | | | | OFF | | | | |
| OF ANY KIND | YES | | | | ON | | | | |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| GRAPHICS TYPE | REGULAR FRUIT | | | | | OFF | OFF | | |
| | NUMBERS | | | | | ON | OFF | | |
| | CUSTOM OPTION 1 | | | | | OFF | ON | | |
| | CUSTOM OPTION 2 | | | | | ON | ON | | |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| PAY TABLE | 9322 | | | | | | | OFF | OFF |
| | 9323 | | | | | | | ON | OFF |
| | 9324 | | | | | | | OFF | ON |
| | 9321 | | | | | | | ON | ON |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
+-----------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| DIP SWITCHES BANK #2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| BONUS PAY % | 1.0 % | OFF | OFF | OFF | | | | | |
| | 1.2 % | ON | OFF | OFF | | | | | |
| | 3.3 % | OFF | ON | OFF | | | | | |
| | 4.0 % | ON | ON | OFF | | | | | |
| | 5.0 % | OFF | OFF | ON | | | | | |
| | 6.2 % | ON | OFF | ON | | | | | |
| | 8.0 % | OFF | ON | ON | | | | | |
| | 10.0 % | ON | ON | ON | | | | | |
+----------------+-----+------------+-----+-----+-----+-----+-----+-----+-----+-----+
| INTERNAL PROGRESSIVE | ON | | | | OFF | | | | |
| | OFF | | | | ON | | | | |
+----------------+-----+------------+-----+-----+-----+-----+-----+-----+-----+-----+
| NOT USED | | | | | | OFF | OFF | OFF | OFF |
+----------------+------------------+-----+-----+-----+-----+-----+-----+-----+-----+
+-----------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| DIP SWITCHES BANK #3 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| MAXIMUM BET | 8 | OFF | OFF | | | | | | |
| | 16 | ON | OFF | | | | | | |
| | 32 | OFF | ON | | | | | | |
| | 64 | ON | ON | | | | | | |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| COIN IN-TIME OUT | OFF | | | OFF | | | | | |
| | ON | | | ON | | | | | |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| DEMONATION | $1.00 | | | | OFF | OFF | OFF | | |
| | 50 CENTS | | | | ON | OFF | OFF | | |
| | 25 CENTS | | | | OFF | ON | OFF | | |
| | 10 CENTS | | | | ON | ON | OFF | | |
| | 5 CENTS | | | | OFF | OFF | ON | | |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| PROGRESSIVE SIGN | OFF | | | | | | | OFF | OFF |
| | SINGLE LEVEL | | | | | | | ON | OFF |
| | MULTI-LEVEL | | | | | | | OFF | ON |
| | TEST MODE | | | | | | | ON | ON |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
+-----------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
| DIP SWITCHES BANK #4 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| BUTTON LOCKOUT | OFF | OFF | | | | | | | |
| | ON | ON | | | | | | | |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| LOCKOUT POLARITY | ACTIVE HIGH | | OFF | | | | | | |
| | ACTIVE LOW | | ON | | | | | | |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| PRINTER TYPE | EPSON 276A | | | OFF | OFF | | | | |
| | STAR 300 | | | ON | OFF | | | | |
| | ITHACA 75 | | | OFF | ON | | | | |
| | CITIZEN 3541 | | | ON | ON | | | | |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
| PAPER LOW SENSOR | OFF | | | | | OFF | OFF | OFF | OFF |
| | ON | | | | | ON | OFF | OFF | OFF |
+------------------+----------------+-----+-----+-----+-----+-----+-----+-----+-----+
NOTE: Set bill validator DIP switches for 1 pulse per dollar. When you choose the
demonation with the DIP switch on the board, the software will know how many
credits to give per dollar.
Pay Table Diagram: (Set With DIP Switches Bank #1, numbers 7 & 8)
--- 9323 ---
3 Flaming Sevens 75 for 1
3 Sevens 40 for 1
9 Bars 15 for 1
6 Bars 12 for 1
3 Bars 10 for 1
3 Cherries 08 for 1
2 Cherries 05 for 1
1 Cherries 02 for 1
With 8 or more Bet:
9 of any one = 1000 for 1
8 of any one = 500 for 1
7 of any one = 100 for 1
If Cherry Bonus is on 5 or more Cherries, Pays Bonus.
--- 9324 ---
3 Flaming Sevens 75 for 1
3 Sevens 40 for 1
9 Bars 15 for 1
6 Bars 12 for 1
3 Bars 10 for 1
3 Cherries 08 for 1
2 Cherries 04 for 1
1 Cherries 01 for 1
With 8 or more Bet:
9 of any one = 5000 for 1
8 of any one = 2500 for 1
7 of any one = 500 for 1
If Cherry Bonus is on 5 or more Cherries, Pays Bonus.
--- 9321 ---
3 Flaming Sevens 75 for 1
3 Sevens 40 for 1
9 Bars 15 for 1
6 Bars 12 for 1
3 Bars 10 for 1
3 Cherries 08 for 1
2 Cherries 05 for 1
1 Cherries 02 for 1
With 8 or more Bet:
9 of any one = 3000 for 1
8 of any one = 1500 for 1
7 of any one = 300 for 1
If Cherry Bonus is on 5 or more Cherries, Pays Bonus.
--- 9322 ---
3 Flaming Sevens 100 for 1
3 Sevens 50 for 1
9 Bars 18 for 1
6 Bars 14 for 1
3 Bars 10 for 1
3 Cherries 10 for 1
2 Cherries 05 for 1
1 Cherries 02 for 1
With 8 or more Bet:
9 of any one = 1000 for 1
8 of any one = 500 for 1
7 of any one = 100 for 1
If Cherry Bonus is on 5 or more Cherries, Pays Bonus.
-------------------------------------------------------------------------
CYBERDYNE 72 PIN GAME LOGIC CONNECTOR
Parts Side | | | Solder Side
---------------+--+--+---------------
Red Video |01|37| Green Video
Blue Video |02|38| Video Sync
Speaker (+)|03|39| Speaker Ground
|04|40|
|05|41|
|06|42|
Drop Door SW |07|43| Change SW
Logic Door SW |08|44| Main Door SW
Start Switch |09|45|
Low Switch |10|46|
Play Credit Switch |11|47|
Take Score Switch |12|48|
Double Up Switch |13|49|
High Switch |14|50|
Button Lock |15|51|
|16|52|
|17|53|
(DBA) Inuput0 |18|54| Coin Switch A
Coin Switch B |19|55|
Book Keeping Switch |20|56| Stats / Setup SW
Collect SW |21|57|
Hopper Full Switch |22|58|
Counter Out A |23|59|
Bell |24|60| Lockout mars (DBA)
Tower Lamp |25|61|
Counter Out D |26|62|
Played Meter |27|63| Lack of Hopper Counter
Count down Meter Out |28|64|
Start Lamp |29|65|
Low Lamp |30|66| Collect Lamp
Play Credit Lamp |31|67| Progressive Link
Take Score Lamp |32|68|
Double Up Lamp |33|69| TXD
High Lamp |34|70|
|35|71|
Switch Grounds |36|72| Switch Grounds
+--+--+
20 Pin Game PCB Power Connector
Parts Side | | | Solder Side
---------------+--+--+---------------
Logic Ground |01|11| Logic Ground
Logic Ground |02|12| Logic Ground
+5 VDC |03|13|
+5 VDC |04|14| +5 VDC
+12 VDC |05|15| +12 VDC
|06|16|
|07|17|
|08|18|
Logic Ground |09|19| Logic Ground
Logic Ground |10|20| Logic Ground
+--+--+
-------------------------------------------------------------------------
Cyberdyne Printer Harness (Flaming 7)
-------------------------------------
+12V.----+----+
| |
Z Z
Z Z 470 ohm 1/4 watt resistors
Z Z
| |
PCB Pin 69 Solder Side (TXD) ---+----|---- DB25 pin 3 (received data)
|
+---- DB25 pin 6
PCB Pin 22 Parts Side -------------------- DB25 pins 1 & 7 (Single & Safety)
PCB Pin 35 Parts Side -------------------- DB25 pin 20 (Printer Busy Signal)
DIP Switches settings for Citizen Printer:
Model # 3551
DIP SW #1 = 5, 7, 9, 10 OFF.
DIP SW #2 = 5, 7, 8, OFF.
-------------------------------------------------------------------------
Tech Notes:
W-4 PCB type has some hacks...
@ -14212,7 +14670,7 @@ ROM_END
...and written 0x10 at B0C0-B0FF.
*/
*******************************************************************************************/
/*
Flaming 7
@ -14361,6 +14819,69 @@ ROM_START( fl7_2000 ) // Serial 00000063A47F.
ROM_END
/*
Flaming 7's
Cyberdyne Systems.
2000 Bonus. Egyptian Gold.
Custom Hardware.
*/
ROM_START( fl7_2k16 ) // Serial 000000743111.
ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "2000_bonus_27c256.u22", 0x0000, 0x8000, CRC(290c37b0) SHA1(a90093d2139fd5ca261870298c2d84648f14e6bc) )
ROM_REGION( 0x20000, "gfx1", 0 )
ROM_LOAD( "egyptian_gold_m27c1001.u6", 0x00000, 0x20000, CRC(5a2157bb) SHA1(2b170102caf1224df7a6d33bb84d19114f453d89) )
ROM_REGION( 0x8000, "gfx2", 0 )
ROM_LOAD( "egyptian_gold_27c256.u3", 0x0000, 0x8000, CRC(11241dae) SHA1(7197813304623c022dc37aa603c0cb067c8bf1fd) )
/* Bipolar PROM dump borrowed from main sets */
ROM_REGION( 0x200, "proms", 0 )
ROM_LOAD( "am27s29.u1", 0x0000, 0x0100, CRC(3fe7e369) SHA1(cf4ae287cb58581a4bf9e9ff1994426461fb38cc) )
ROM_CONTINUE( 0x0000, 0x0100) // palette data is stored in the second half.
ROM_REGION( 0x20, "proms2", 0 )
ROM_LOAD( "dummy", 0x0000, 0x0020, NO_DUMP )
ROM_REGION(0x8, "fl7w4_id", 0) /* Electronic Serial */
ROM_LOAD( "eserial.bin", 0x0000, 0x0008, NO_DUMP ) // Hand built to match our ROM set
ROM_END
/*
Flaming 7's (unknown version)
Taiwanese Hardware.
Needs proper graphics ROM decryption and gfxdecode...
*/
ROM_START( fl7_tw ) // Serial 00000050E9B7.
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "27c512_tw.u20", 0x0000, 0x10000, CRC(50927a1b) SHA1(2557069f497b23f13978294f3ac108229d9db544) ) // identical halves.
ROM_REGION( 0x20000, "gfx1", 0 )
ROM_LOAD( "m27c1001_tw.u1", 0x00000, 0x20000, CRC(e6099723) SHA1(31e73a81166dd0d50d51ead38d348e36018d0698) )
ROM_REGION( 0x8000, "gfx2", 0 )
ROM_LOAD( "27c256_tw.u3", 0x0000, 0x8000, CRC(7f163639) SHA1(607aa1e7d15423409bb2cd49895502dc2e4b3e46) )
/* Bipolar PROM dump borrowed from main sets */
ROM_REGION( 0x200, "proms", 0 )
ROM_LOAD( "am27s29.u1", 0x0000, 0x0100, CRC(3fe7e369) SHA1(cf4ae287cb58581a4bf9e9ff1994426461fb38cc) )
ROM_CONTINUE( 0x0000, 0x0100) // palette data is stored in the second half.
ROM_REGION( 0x20, "proms2", 0 )
ROM_LOAD( "dummy", 0x0000, 0x0020, NO_DUMP )
ROM_REGION(0x8, "fl7w4_id", 0) /* Electronic Serial */
ROM_LOAD( "eserial.bin", 0x0000, 0x0008, NO_DUMP ) // Hand built to match our ROM set
ROM_END
/*********************************************************************************************************************/
DRIVER_INIT_MEMBER(goldstar_state,goldstar)
@ -15130,10 +15651,12 @@ GAMEL( 1993, bingownga, bingowng, bingownga,bingownga,driver_device, 0,
// --- Flaming 7's hardware (W-4 derivative) ---
GAME( 199?, fl7_3121, 0, flam7_w4, flaming7, driver_device, 0, ROT0, "Cyberdyne Systems", "Flaming 7 (W4 Hardware, Red, White & Blue 7's + Hollywood Nights)", 0 )
GAME( 199?, fl7_50, 0, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Main, 50)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_500, fl7_50, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Main, 500)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_2000, fl7_50, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Main, 2000)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_3121, 0, flam7_w4, flam7_w4, driver_device, 0, ROT0, "Cyberdyne Systems", "Flaming 7 (W4 Hardware, Red, White & Blue 7's + Hollywood Nights)", 0 )
GAME( 199?, fl7_50, 0, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Main, 50 Bonus)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_500, fl7_50, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Main, 500 Bonus)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_2000, fl7_50, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Main, 2000 Bonus)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_2k16, fl7_50, flaming7, flaming7, wingco_state, flaming7, ROT0, "Cyberdyne Systems", "Flaming 7 (Custom Hardware, Egyptian Gold, 2000 Bonus)", MACHINE_NOT_WORKING )
GAME( 199?, fl7_tw, fl7_50, flam7_tw, flaming7, driver_device, 0, ROT0, "Cyberdyne Systems", "Flaming 7 (Taiwanese Hardware, unknown version)", MACHINE_NOT_WORKING ) // needs proper gfx roms decryption.
// --- Wing W-8 hardware ---

View File

@ -643,7 +643,7 @@ static ADDRESS_MAP_START( sound_prg, AS_PROGRAM, 8, maygayv1_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( sound_data, AS_DATA, 8, maygayv1_state )
AM_RANGE(0x0000, 0xffff) AM_RAM // nothing?
AM_RANGE(0x0000, 0x1ff) AM_RAM // nothing?
ADDRESS_MAP_END
static ADDRESS_MAP_START( sound_io, AS_IO, 8, maygayv1_state )

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
// thanks-to: David Haywood, Peter Wilhelmsen
/*************************************************************************************************************************
Metal Freezer (c) 1989 Seibu

View File

@ -899,19 +899,19 @@ ROM_END
ROM_START( helifire )
ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "hf.f1", 0x0000, 0x0400, CRC(032f89ca) SHA1(63b0310875ed78a6385e44eea781ddcc4a63557c) )
ROM_LOAD( "hf.f2", 0x0400, 0x0400, CRC(2774e70f) SHA1(98d845e80db61799493dbebe8db801567277432c) )
ROM_LOAD( "hf.g1", 0x0800, 0x0400, CRC(b5ad6e8a) SHA1(1eb4931e85bd6a559e85a2b978d383216d3988a7) )
ROM_LOAD( "hf.g2", 0x0c00, 0x0400, CRC(5e015bf4) SHA1(60f5a9707c8655e54a8381afd764856fb25c29f1) )
ROM_LOAD( "hf.h1", 0x1000, 0x0400, CRC(23bb4e5a) SHA1(b59bc0adff3635aca1def2b1997f7edc6ca7e8ee) )
ROM_LOAD( "hf.h2", 0x1400, 0x0400, CRC(358227c6) SHA1(d7bd678ef1737edc6aa609e43e3ae96a8d61dc15) )
ROM_LOAD( "hf.i1", 0x1800, 0x0400, CRC(0c679f44) SHA1(cbe31dbe5f2c5f11a637cb3bde4e059c310d0e76) )
ROM_LOAD( "hf.i2", 0x1c00, 0x0400, CRC(d8b7a398) SHA1(3ddfeac39147d5df6096f525f7ef67abef32a28b) )
ROM_LOAD( "hf.j1", 0x2000, 0x0400, CRC(98ef24db) SHA1(70ad8dd6e1e8f4bf4ce431737ca1856eecc03d53) )
ROM_LOAD( "hf.j2", 0x2400, 0x0400, CRC(5e2b5877) SHA1(f7c747e8a1d9fe2dda71ee6304636cf3cdf727a7) )
ROM_LOAD( "tub_f1_b", 0x0000, 0x0400, CRC(032f89ca) SHA1(63b0310875ed78a6385e44eea781ddcc4a63557c) )
ROM_LOAD( "tub_f2_b", 0x0400, 0x0400, CRC(2774e70f) SHA1(98d845e80db61799493dbebe8db801567277432c) )
ROM_LOAD( "tub_g1_b", 0x0800, 0x0400, CRC(b5ad6e8a) SHA1(1eb4931e85bd6a559e85a2b978d383216d3988a7) )
ROM_LOAD( "tub_g2_b", 0x0c00, 0x0400, CRC(5e015bf4) SHA1(60f5a9707c8655e54a8381afd764856fb25c29f1) )
ROM_LOAD( "tub_h1_b", 0x1000, 0x0400, CRC(23bb4e5a) SHA1(b59bc0adff3635aca1def2b1997f7edc6ca7e8ee) )
ROM_LOAD( "tub_h2_b", 0x1400, 0x0400, CRC(358227c6) SHA1(d7bd678ef1737edc6aa609e43e3ae96a8d61dc15) )
ROM_LOAD( "tub_i1_b", 0x1800, 0x0400, CRC(0c679f44) SHA1(cbe31dbe5f2c5f11a637cb3bde4e059c310d0e76) )
ROM_LOAD( "tub_i2_b", 0x1c00, 0x0400, CRC(d8b7a398) SHA1(3ddfeac39147d5df6096f525f7ef67abef32a28b) )
ROM_LOAD( "tub_j1_b", 0x2000, 0x0400, CRC(98ef24db) SHA1(70ad8dd6e1e8f4bf4ce431737ca1856eecc03d53) )
ROM_LOAD( "tub_j2_b", 0x2400, 0x0400, CRC(5e2b5877) SHA1(f7c747e8a1d9fe2dda71ee6304636cf3cdf727a7) )
ROM_REGION( 0x0400, "audiocpu", 0 )
ROM_LOAD( "hf.snd", 0x0000, 0x0400, CRC(9d77a31f) SHA1(36db9b5087b6661de88042854874bc247c92d985) )
ROM_LOAD( "tub-e_ic5-a", 0x0000, 0x0400, CRC(9d77a31f) SHA1(36db9b5087b6661de88042854874bc247c92d985) )
ROM_END
ROM_START( helifirea )

View File

@ -65,9 +65,9 @@ public:
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode") { }
required_shared_ptr<UINT8> m_videoram;
required_shared_ptr<UINT16> m_videoram;
tilemap_t *m_bg_tilemap;
DECLARE_WRITE8_MEMBER(nibble_videoram_w);
DECLARE_WRITE16_MEMBER(nibble_videoram_w);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
virtual void machine_start() override;
@ -85,10 +85,11 @@ public:
* Video Hardware *
*************************/
WRITE8_MEMBER(nibble_state::nibble_videoram_w)
WRITE16_MEMBER(nibble_state::nibble_videoram_w)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
COMBINE_DATA(m_videoram+offset);
m_bg_tilemap->mark_tile_dirty(offset*2);
m_bg_tilemap->mark_tile_dirty(offset*2+1);
}
@ -100,7 +101,7 @@ TILE_GET_INFO_MEMBER(nibble_state::get_bg_tile_info)
---- ---- color code.
---- ---- seems unused.
*/
int code = m_videoram[tile_index];
UINT8 code = m_videoram[tile_index/2] >> (tile_index & 1 ? 0 : 8);
SET_TILE_INFO_MEMBER(0 /* bank */, code, 0 /* color */, 0);
}
@ -147,7 +148,7 @@ void nibble_state::machine_reset()
* Memory Map Information *
*************************/
static ADDRESS_MAP_START( nibble_map, AS_PROGRAM, 8, nibble_state )
static ADDRESS_MAP_START( nibble_map, AS_PROGRAM, 16, nibble_state )
// ADDRESS_MAP_GLOBAL_MASK(0x3fff)
AM_RANGE(0x0000, 0xbfff) AM_ROM
AM_RANGE(0xc000, 0xc3ff) AM_WRITE(nibble_videoram_w) AM_SHARE("videoram") // placeholder
@ -301,8 +302,7 @@ GFXDECODE_END
static MACHINE_CONFIG_START( nibble, nibble_state )
// CPU should be switched to TMS9900
MCFG_TMS99xx_ADD("maincpu", TMS9980A, MASTER_CLOCK/4, nibble_map, nibble_cru_map)
MCFG_TMS99xx_ADD("maincpu", TMS9900, MASTER_CLOCK/4, nibble_map, nibble_cru_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", nibble_state, nibble_interrupt)
/* video hardware */

View File

@ -186,7 +186,7 @@ READ8_MEMBER( prof180x_state::status_r )
/* Address Maps */
static ADDRESS_MAP_START( prof180x_mem, AS_PROGRAM, 8, prof180x_state )
AM_RANGE(0x00000, 0x7ffff) AM_READWRITE(read, write)
AM_RANGE(0x0000, 0xffff) AM_READWRITE(read, write)
ADDRESS_MAP_END
static ADDRESS_MAP_START( prof180x_io , AS_IO, 8, prof180x_state )

View File

@ -109,9 +109,8 @@ static const z80_daisy_config maincpu_daisy_chain[] =
static ADDRESS_MAP_START(maincpu_io, AS_IO, 8, pve500_state)
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("external_sio", z80sio0_device, cd_ba_r, cd_ba_w)
AM_RANGE(0x08, 0x0B) AM_DEVREADWRITE("external_ctc", z80ctc_device, read, write)
AM_RANGE(0x00, 0x03) AM_MIRROR(0xff00) AM_DEVREADWRITE("external_sio", z80sio0_device, cd_ba_r, cd_ba_w)
AM_RANGE(0x08, 0x0B) AM_MIRROR(0xff00) AM_DEVREADWRITE("external_ctc", z80ctc_device, read, write)
ADDRESS_MAP_END
static ADDRESS_MAP_START(maincpu_prg, AS_PROGRAM, 8, pve500_state)
@ -121,7 +120,6 @@ static ADDRESS_MAP_START(maincpu_prg, AS_PROGRAM, 8, pve500_state)
ADDRESS_MAP_END
static ADDRESS_MAP_START(subcpu_io, AS_IO, 8, pve500_state)
ADDRESS_MAP_GLOBAL_MASK(0xff)
ADDRESS_MAP_END
static ADDRESS_MAP_START(subcpu_prg, AS_PROGRAM, 8, pve500_state)

View File

@ -715,7 +715,7 @@ static MACHINE_CONFIG_START( sg1000, sg1000_state )
/* video hardware */
MCFG_DEVICE_ADD( TMS9918A_TAG, TMS9918A, XTAL_10_738635MHz / 2 )
MCFG_TMS9928A_VRAM_SIZE(0x4000)
MCFG_TMS9928A_OUT_INT_LINE_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
MCFG_TMS9928A_OUT_INT_LINE_CB(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG )
MCFG_SCREEN_UPDATE_DEVICE( TMS9918A_TAG, tms9918a_device, screen_update )
@ -765,7 +765,7 @@ static MACHINE_CONFIG_START( sc3000, sc3000_state )
/* video hardware */
MCFG_DEVICE_ADD( TMS9918A_TAG, TMS9918A, XTAL_10_738635MHz / 2 )
MCFG_TMS9928A_VRAM_SIZE(0x4000)
MCFG_TMS9928A_OUT_INT_LINE_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
MCFG_TMS9928A_OUT_INT_LINE_CB(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG )
MCFG_SCREEN_UPDATE_DEVICE( TMS9918A_TAG, tms9918a_device, screen_update )
@ -814,7 +814,7 @@ static MACHINE_CONFIG_START( sf7000, sf7000_state )
/* video hardware */
MCFG_DEVICE_ADD( TMS9918A_TAG, TMS9918A, XTAL_10_738635MHz / 2 )
MCFG_TMS9928A_VRAM_SIZE(0x4000)
MCFG_TMS9928A_OUT_INT_LINE_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
MCFG_TMS9928A_OUT_INT_LINE_CB(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG )
MCFG_SCREEN_UPDATE_DEVICE( TMS9918A_TAG, tms9918a_device, screen_update )

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
// copyright-holders:Miodrag Milanovic, R. Belmont, Ryan Holtz
/***************************************************************************
Sun-4 Models
@ -379,38 +379,55 @@
high 3.5" disks. Code name "Scorpion". First
supported in Solaris 2.2 (SunOS 5.2).
21/11/2011 Skeleton driver.
20/06/2016 Much less skeletony.
4/60 memory test notes:
ffe809fc: call to print "Sizing Memory" to the UART
ffe80a04: set o0 to 0xf0000000, a valid PTE that points to absolute zero in main RAM
ffe80a08: call to set that PTE in the page table (routine also reads back the written value and verifies that the unused bits are all 0)
ffe80a0c: stash g0, the current memory base testing, to o2, which the CALL above uses as the virtual address to set the PTE for
ffe80a10: set o0 to 0xf0000400, a valid PTE that points to the 4 MB mark (0x400000) in main RAM
ffe80a14: call to set that PTE in the page table
ffe80a18: set o2 to 0x00001000, so virtual address 0x1000 now points to physical 0x400000
ffe80a1c: set i7 to 0x01000000, which indicates the memory size is 64MB if everything passes
ffe80a20: store i7 at g0, which is currently 0
ffe80a24: SRL i7 by 2, now 0x00400000, so if the next store fails on a bus error memory size is 4 MB
ffe80a28: store the new i7 at o2, which is 0x400000
ffe80a2c: store succeeded! load [g0] to i7, ta-da, 64 MB RAM sized
****************************************************************************/
#include "emu.h"
#include "cpu/sparc/sparc.h"
#include "machine/timekpr.h"
#include "machine/ram.h"
#include "machine/z80scc.h"
#include "machine/bankdev.h"
#include "machine/nvram.h"
#include "bus/rs232/rs232.h"
#define ENA_NOTBOOT 0x80
#define ENA_SDVMA 0x20
#define ENA_CACHE 0x10
#define ENA_RESET 0x04
#define ENA_DIAG 0x01
#define SCC1_TAG "kbdmouse"
#define SCC2_TAG "uart"
#define TIMEKEEPER_TAG "timekpr"
#define SCC1_TAG "scc1"
#define SCC2_TAG "scc2"
#define RS232A_TAG "rs232a"
#define RS232B_TAG "rs232b"
#define ASI_SYSTEM_SPACE 2
#define ASI_SEGMENT_MAP 3
#define ASI_PAGE_MAP 4
#define ASI_USER_INSN 8
#define ASI_SUPER_INSN 9
#define ASI_USER_DATA 10
#define ASI_SUPER_DATA 11
#define ASI_FLUSH_SEGMENT 12
#define ASI_FLUSH_PAGE 13
#define ASI_FLUSH_CONTEXT 14
#define ENA_NOTBOOT (0x80)
#define ENA_SDVMA (0x20)
#define ENA_CACHE (0x10)
#define ENA_RESET (0x04)
#define ENA_DIAG (0x01)
// page table entry constants
#define PM_VALID (0x80000000) // page is valid
#define PM_WRITEMASK (0x40000000) // writable?
#define PM_SYSMASK (0x20000000) // system use only?
#define PM_CACHE (0x10000000) // cachable?
#define PM_TYPEMASK (0x0c000000) // type mask
#define PM_ACCESSED (0x02000000) // accessed flag
#define PM_MODIFIED (0x01000000) // modified flag
class sun4_state : public driver_device
{
@ -418,11 +435,13 @@ public:
sun4_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_scc1(*this, SCC1_TAG)
, m_scc2(*this, SCC2_TAG)
, m_type0space(*this, "type0")
, m_type1space(*this, "type1")
, m_ram(*this, RAM_TAG)
, m_rom(*this, "user1")
, m_kbdmouse(*this, SCC1_TAG)
, m_uart(*this, SCC2_TAG)
, m_rom_ptr(nullptr)
, m_context(0)
, m_system_enable(0)
{
}
@ -432,184 +451,140 @@ public:
DECLARE_READ32_MEMBER( sun4_mmu_r );
DECLARE_WRITE32_MEMBER( sun4_mmu_w );
DECLARE_READ32_MEMBER( ram_r );
DECLARE_WRITE32_MEMBER( ram_w );
DECLARE_READ32_MEMBER( ss1_sl0_id );
DECLARE_READ32_MEMBER( ss1_sl3_id );
protected:
required_device<mb86901_device> m_maincpu;
required_device<z80scc_device> m_scc1;
required_device<z80scc_device> m_scc2;
optional_device<address_map_bank_device> m_type0space, m_type1space;
required_device<ram_device> m_ram;
required_memory_region m_rom;
required_device<z80scc_device> m_kbdmouse;
required_device<z80scc_device> m_uart;
UINT32 read_supervisor_data(UINT32 vaddr, UINT32 mem_mask);
void write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask);
UINT32 *m_rom_ptr;
UINT32 m_context;
UINT16 m_segmap[8][4096];
UINT32 m_pagemap[8192];
UINT32 m_system_enable;
private:
UINT32 *m_ram_ptr;
UINT8 m_segmap[8][4096];
UINT32 m_pagemap[8192];
UINT32 m_ram_size, m_ram_size_words;
};
#define SEGMENT(vaddr) m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff]
#define PAGE(vaddr) m_pagemap[((m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff] & 0x7f) << 6) | (((vaddr) >> 12) & 0x3f)]
#define PADDR(vaddr) (((PAGE(vaddr) << 12) & 0x0ffff000) | ((vaddr) & 0xfff))
UINT32 sun4_state::read_supervisor_data(UINT32 vaddr, UINT32 mem_mask)
{
UINT32 page = PAGE(vaddr);
bool v = (page & 0x80000000) ? true : false;
bool w = (page & 0x40000000) ? true : false;
bool s = (page & 0x20000000) ? true : false;
bool x = (page & 0x10000000) ? true : false;
int t = (page & 0x0c000000) >> 26;
bool a = (page & 0x02000000) ? true : false;
bool m = (page & 0x01000000) ? true : false;
char mode[4] = { 'M', 'S', '0', '1' };
logerror("supervisor data read: vaddr %08x, paddr %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), m_context, SEGMENT(vaddr), PAGE(vaddr)
, v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm');
return 0;
}
void sun4_state::write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask)
{
UINT32 page = PAGE(vaddr);
bool v = (page & 0x80000000) ? true : false;
bool w = (page & 0x40000000) ? true : false;
bool s = (page & 0x20000000) ? true : false;
bool x = (page & 0x10000000) ? true : false;
int t = (page & 0x0c000000) >> 26;
bool a = (page & 0x02000000) ? true : false;
bool m = (page & 0x01000000) ? true : false;
char mode[4] = { 'M', 'S', '0', '1' };
logerror("supervisor data write: vaddr %08x, paddr %08x, data %08x, mem_mask %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), data, mem_mask,
m_context, SEGMENT(vaddr), PAGE(vaddr), v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm');
}
READ32_MEMBER( sun4_state::sun4_mmu_r )
{
UINT8 asi = m_maincpu->get_asi();
int page;
if (!space.debugger_access())
{
switch(asi)
{
case ASI_SYSTEM_SPACE:
switch (offset >> 26)
{
case 3: // context reg
logerror("sun4: read context register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_context << 24, mem_mask, offset << 2, m_maincpu->pc());
return m_context << 24;
case 4: // system enable reg
logerror("sun4: read system enable register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_system_enable << 24, mem_mask, offset << 2, m_maincpu->pc());
return m_system_enable << 24;
case 8: // (d-)cache tags
logerror("sun4: read dcache tags %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc());
return 0xffffffff;
case 9: // (d-)cache data
logerror("sun4: read dcache data %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc());
return 0xffffffff;
case 15: // Type 1 space passthrough
switch ((offset >> 22) & 15)
{
case 0: // keyboard/mouse
switch (offset & 1)
{
case 0:
{
UINT32 ret = 0;
if (mem_mask & 0xffff0000)
ret |= m_kbdmouse->cb_r(space, 0) << 24;
if (mem_mask & 0x0000ffff)
ret |= m_kbdmouse->db_r(space, 0) << 8;
return ret;
}
case 1:
{
UINT32 ret = 0;
if (mem_mask & 0xffff0000)
ret |= m_kbdmouse->ca_r(space, 0) << 24;
if (mem_mask & 0x0000ffff)
ret |= m_kbdmouse->da_r(space, 0) << 8;
return ret;
}
}
break;
case 1: // serial ports
switch (offset & 1)
{
case 0:
{
UINT32 ret = 0;
if (mem_mask & 0xffff0000)
ret |= m_uart->cb_r(space, 0) << 24;
if (mem_mask & 0x0000ffff)
ret |= m_uart->db_r(space, 0) << 8;
return ret;
}
case 1:
{
UINT32 ret = 0;
if (mem_mask & 0xffff0000)
ret |= m_uart->ca_r(space, 0) << 24;
if (mem_mask & 0x0000ffff)
ret |= m_uart->da_r(space, 0) << 8;
return ret;
}
}
break;
default:
logerror("sun4: read unknown type 1 space at address %x (& %08x) asi 2, offset %x, PC = %x\n", offset << 2, mem_mask, offset << 2, m_maincpu->pc());
}
break;
case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
default:
logerror("sun4: read unknown register (& %08x) asi 2, offset %x, PC = %x\n", mem_mask, offset << 2, m_maincpu->pc());
return 0;
}
break;
case ASI_SEGMENT_MAP:
{
logerror("sun4: read m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 24 & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), mem_mask);
UINT32 result = SEGMENT(offset << 2);
while (!(mem_mask & 1))
{
mem_mask >>= 1;
result <<= 1;
}
return result;
}
case ASI_PAGE_MAP: // page map
{
logerror("sun4: read m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, PAGE(offset << 2), mem_mask);
return PAGE(offset << 2);
}
case ASI_SUPER_INSN: // supervisor instruction space
return m_rom_ptr[offset & 0x1ffff]; // wrong, but works for now
case ASI_SUPER_DATA:
return read_supervisor_data(offset << 2, mem_mask);
default:
logerror("sun4: read (& %08x) asi %d byte offset %x, PC = %x\n", mem_mask, asi, offset << 2, m_maincpu->pc());
break;
}
}
if (!(m_system_enable & ENA_NOTBOOT))
if (space.debugger_access()) return m_rom_ptr[offset & 0x1ffff];
// supervisor program fetches in boot state are special
if ((!(m_system_enable & ENA_NOTBOOT)) && (asi == 9))
{
return m_rom_ptr[offset & 0x1ffff];
}
switch (asi)
{
case 2: // system space
switch (offset >> 26)
{
case 3: // context reg
return m_context<<24;
case 4: // system enable reg
return m_system_enable;
case 6: // bus error register
return 0;
case 8: // (d-)cache tags
logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc());
return 0xffffffff;
case 9: // (d-)cache data
logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
return 0xffffffff;
case 0xf: // UART bypass
//printf("read UART bypass @ %x mask %08x\n", offset<<2, mem_mask);
switch (offset & 3)
{
case 0: if (mem_mask == 0xff000000) return m_scc1->cb_r(space, offset)<<24; else return m_scc1->db_r(space, offset)<<8; break;
case 1: if (mem_mask == 0xff000000) return m_scc1->ca_r(space, offset)<<24; else return m_scc1->da_r(space, offset)<<8; break;
}
return 0xffffffff;
case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
default:
printf("sun4: ASI 2 space unhandled read @ %x (PC=%x)\n", offset<<2, m_maincpu->pc());
return 0;
}
break;
case 3: // segment map
//printf("sun4: read segment map @ %x (entry %d, mem_mask %08x, PC=%x)\n", offset << 2, (offset>>16) & 0xfff, mem_mask, m_maincpu->pc());
return m_segmap[m_context][(offset>>16) & 0xfff]<<24;
break;
case 4: // page map
page = m_segmap[m_context & 7][(offset >> 16) & 0xfff] << 6;
page += (offset >> 10) & 0x3f;
//printf("sun4: read page map @ %x (entry %d, mem_mask %08x, PC=%x)\n", offset << 2, page, mem_mask, m_maincpu->pc());
return m_pagemap[page];
break;
case 8:
case 9:
case 10:
case 11:
{
// it's translation time
UINT8 pmeg = m_segmap[m_context & 7][(offset >> 16) & 0xfff];
UINT32 entry = (pmeg << 6) + ((offset >> 10) & 0x3f);
if (m_pagemap[entry] & PM_VALID)
{
m_pagemap[entry] |= PM_ACCESSED;
UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10;
tmp |= (offset & 0x3ff);
//printf("sun4: translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc());
switch ((m_pagemap[entry] >> 26) & 3)
{
case 0: // type 0 space
return m_type0space->read32(space, tmp, mem_mask);
case 1: // type 1 space
// magic EPROM bypass
if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2)))
{
return m_rom_ptr[offset & 0x1ffff];
}
//printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2);
return m_type1space->read32(space, tmp, mem_mask);
default:
printf("sun4: access to memory type not defined in sun4c\n");
return 0;
}
}
else
{
printf("sun4: INVALID PTE accessed! PC=%x\n", m_maincpu->pc());
}
}
break;
default:
if (!space.debugger_access()) printf("sun4: ASI %d unhandled read @ %x (PC=%x)\n", asi, offset<<2, m_maincpu->pc());
return 0;
}
printf("sun4: read asi %d byte offset %x, PC = %x\n", asi, offset << 2, m_maincpu->pc());
return 0;
}
@ -617,109 +592,107 @@ READ32_MEMBER( sun4_state::sun4_mmu_r )
WRITE32_MEMBER( sun4_state::sun4_mmu_w )
{
UINT8 asi = m_maincpu->get_asi();
int page;
//printf("sun4: write %08x to %08x (ASI %d, mem_mask %08x, PC %x)\n", data, offset, asi, mem_mask, m_maincpu->pc());
switch (asi)
{
case 2:
switch (offset >> 26)
{
case 3: // context reg
logerror("sun4: %08x (& %08x) asi 2 to context register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
m_context = (UINT8)(data >> 24) & 7;
return;
case 4: // system enable reg
logerror("sun4: write %08x (& %08x) asi 2 to system enable register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
m_system_enable = (UINT8)data;
return;
case 8: // cache tags
logerror("sun4: write %08x (& %08x) asi 2 to cache tags @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
return;
case 9: // cache data
logerror("sun4: write %08x (& %08x) asi 2 to cache data @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
return;
case 15: // Type 1 space passthrough
switch ((offset >> 22) & 15)
{
case 0: // keyboard/mouse
switch (offset & 1)
{
case 0:
if (mem_mask & 0xffff0000)
m_kbdmouse->cb_w(space, 0, data >> 24);
if (mem_mask & 0x0000ffff)
m_kbdmouse->db_w(space, 0, data >> 24);
break;
case 1:
if (mem_mask & 0xffff0000)
m_kbdmouse->ca_w(space, 0, data >> 24);
if (mem_mask & 0x0000ffff)
m_kbdmouse->da_w(space, 0, data >> 24);
break;
}
break;
case 1: // serial ports
switch (offset & 1)
{
case 0:
if (mem_mask & 0xffff0000)
m_uart->cb_w(space, 0, data >> 24);
if (mem_mask & 0x0000ffff)
m_uart->db_w(space, 0, data >> 24);
break;
case 1:
if (mem_mask & 0xffff0000)
m_uart->ca_w(space, 0, data >> 24);
if (mem_mask & 0x0000ffff)
m_uart->da_w(space, 0, data >> 24);
break;
}
break;
default:
logerror("sun4: write unknown type 1 space %08x (& %08x) asi 2, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
}
break;
case 0: // IDPROM
default:
logerror("sun4: write %08x (& %08x) asi 2 to unknown register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
return;
}
break;
case 3: // segment map
offset <<= 2;
while (!(mem_mask & 1))
{
mem_mask >>= 1;
data >>= 1;
}
SEGMENT(offset) = data;
//m_segmap[m_context & 7][(offset >> 18) & 0xfff] &= ~(mem_mask >> 16);
//m_segmap[m_context & 7][(offset >> 18) & 0xfff] |= (data >> 16) & (mem_mask >> 16);
logerror("sun4: write m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, data, mem_mask);
break;
case ASI_PAGE_MAP: // page map
case 2:
switch (offset >> 26)
{
logerror("sun4: write m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2,
(offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, data, mem_mask);
COMBINE_DATA(&PAGE(offset << 2));
PAGE(offset << 2) &= 0xff00ffff;
break;
case 3: // context reg
printf("%08x to context, mask %08x\n", data, mem_mask);
m_context = (UINT8)data<<24;
return;
case 4: // system enable reg
m_system_enable = (UINT8)data;
return;
case 8: // cache tags
logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc());
return;
case 9: // cache data
logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
return;
case 0xf: // UART bypass
//printf("%08x to UART @ %d, mask %08x\n", data, offset & 3, mem_mask);
switch (offset & 3)
{
case 0: if (mem_mask == 0xff000000) m_scc1->cb_w(space, offset, data>>24); else m_scc1->db_w(space, offset, data>>8); break;
case 1: if (mem_mask == 0xff000000) m_scc1->ca_w(space, offset, data>>24); else { m_scc1->da_w(space, offset, data>>8); printf("%c", data>>8); } break;
}
return;
case 0: // IDPROM
default:
printf("sun4: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x)\n", data, offset<<2, mem_mask, m_maincpu->pc());
return;
}
break;
case 3: // segment map
{
UINT8 segdata = 0;
if (mem_mask == 0xffff0000) segdata = (data >> 16) & 0x7f;
else if (mem_mask == 0xff000000) segdata = (data >> 24) & 0x7f;
else logerror("sun4: writing segment map with unknown mask %08x, PC=%x\n", mem_mask, m_maincpu->pc());
//printf("sun4: %08x to segment map @ %x (entry %d, mem_mask %08x, PC=%x)\n", segdata, offset << 2, (offset>>16) & 0xfff, mem_mask, m_maincpu->pc());
m_segmap[m_context & 7][(offset>>16) & 0xfff] = segdata; // only 7 bits of the segment are necessary
}
return;
case 4: // page map
page = m_segmap[m_context & 7][(offset >> 16) & 0xfff] << 6; // get the PMEG
page += (offset >> 10) & 0x3f; // add the offset
//printf("sun4: %08x to page map @ %x (entry %d, mem_mask %08x, PC=%x)\n", data, offset << 2, page, mem_mask, m_maincpu->pc());
COMBINE_DATA(&m_pagemap[page]);
m_pagemap[page] &= 0xff00ffff; // these 8 bits are cleared when written and tested as such
return;
case 8:
case 9:
case 10:
case 11:
// it's translation time
UINT8 pmeg = m_segmap[m_context & 7][(offset >> 16) & 0xfff];
UINT32 entry = (pmeg << 6) + ((offset >> 10) & 0x3f);
case ASI_SUPER_DATA:
write_supervisor_data(offset << 2, data, mem_mask);
break;
if (m_pagemap[entry] & PM_VALID)
{
m_pagemap[entry] |= PM_ACCESSED;
UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10;
tmp |= (offset & 0x3ff);
//printf("sun4: translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], m_maincpu->pc());
default:
logerror("sun4: write %08x (& %08x) to asi %d byte offset %x, PC = %x\n", data, mem_mask, asi, offset << 2, m_maincpu->pc());
break;
switch ((m_pagemap[entry] >> 26) & 3)
{
case 0: // type 0
m_type0space->write32(space, tmp, data, mem_mask);
return;
case 1: // type 1
//printf("write device space @ %x\n", tmp<<1);
m_type1space->write32(space, tmp, data, mem_mask);
return;
default:
printf("sun4: access to memory type not defined in sun4c\n");
return;
}
}
else
{
printf("sun4: INVALID PTE accessed! PC=%x\n", m_maincpu->pc());
}
break;
}
printf("sun4: %08x to asi %d byte offset %x, PC = %x, mask = %08x\n", data, asi, offset << 2, m_maincpu->pc(), mem_mask);
}
static ADDRESS_MAP_START(sun4_mem, AS_PROGRAM, 32, sun4_state)
@ -733,11 +706,116 @@ INPUT_PORTS_END
void sun4_state::machine_reset()
{
m_context = 0;
m_system_enable = 0;
}
void sun4_state::machine_start()
{
m_rom_ptr = (UINT32 *)m_rom->base();
m_ram_ptr = (UINT32 *)m_ram->pointer();
m_ram_size = m_ram->size();
m_ram_size_words = m_ram_size >> 2;
}
READ32_MEMBER( sun4_state::ram_r )
{
if (offset < m_ram_size_words) return m_ram_ptr[offset];
//printf("ram_r: DAEing on access to %08x\n", offset<<2);
m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION);
return 0xffffffff;
}
WRITE32_MEMBER( sun4_state::ram_w )
{
#if 0
// if writing bad parity is enabled
if (((m_parregs[0] & 0x20000000) == 0x20000000) &&
(m_irqctrl & 0x01000000) &&
!(m_bInBusErr))
{
m_parregs[1] = offset<<2;
//printf("Generating parity error, mem_mask %08x\n", mem_mask);
switch (mem_mask)
{
case 0xff000000:
m_parregs[0] |= 0x08<<24;
break;
case 0x00ff0000:
m_parregs[1] += 1;
m_parregs[0] |= 0x04<<24;
break;
case 0x0000ff00:
m_parregs[1] += 2;
m_parregs[0] |= 0x02<<24;
break;
case 0x000000ff:
m_parregs[1] += 3;
m_parregs[0] |= 0x01<<24;
break;
case 0x0000ffff:
m_parregs[1] += 2;
m_parregs[0] |= 0x03<<24;
break;
case 0xffff0000:
m_parregs[0] |= 0x0c<<24;
break;
case 0xffffffff: // no address adjust, show all 4 lanes as problematic
m_parregs[0] |= 0x0f<<24;
break;
}
// indicate parity interrupt
m_parregs[0] |= 0x80000000;
// and can we take that now?
if (m_parregs[0] & 0x40000000)
{
}
}
#endif
if (offset < m_ram_size_words)
{
COMBINE_DATA(&m_ram_ptr[offset]);
return;
}
printf("ram_w: DAEing on access to %08x\n", offset<<2);
m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION);
}
static ADDRESS_MAP_START(type0space_map, AS_PROGRAM, 32, sun4_state)
AM_RANGE(0x00000000, 0x03ffffff) AM_READWRITE(ram_r, ram_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START(type1space_map, AS_PROGRAM, 32, sun4_state)
AM_RANGE(0x00000000, 0x0000000f) AM_DEVREADWRITE8(SCC1_TAG, z80scc_device, ba_cd_inv_r, ba_cd_inv_w, 0xff00ff00)
AM_RANGE(0x01000000, 0x0100000f) AM_DEVREADWRITE8(SCC2_TAG, z80scc_device, ba_cd_inv_r, ba_cd_inv_w, 0xff00ff00)
AM_RANGE(0x02000000, 0x020007ff) AM_DEVREADWRITE8(TIMEKEEPER_TAG, timekeeper_device, read, write, 0xffffffff)
AM_RANGE(0x06000000, 0x0607ffff) AM_ROM AM_REGION("user1", 0)
AM_RANGE(0x08000000, 0x08000003) AM_READ(ss1_sl0_id) // slot 0 contains SCSI/DMA/Ethernet
AM_RANGE(0x0e000000, 0x0e000003) AM_READ(ss1_sl3_id) // slot 3 contains video board
ADDRESS_MAP_END
// indicate 4/60 SCSI/DMA/Ethernet card exists
READ32_MEMBER( sun4_state::ss1_sl0_id )
{
return 0xfe810101;
}
// indicate 4/60 color video card exists
READ32_MEMBER( sun4_state::ss1_sl3_id )
{
return 0xfe010101;
}
static MACHINE_CONFIG_START( sun4, sun4_state )
@ -745,6 +823,26 @@ static MACHINE_CONFIG_START( sun4, sun4_state )
MCFG_CPU_ADD("maincpu", MB86901, 16670000)
MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, sun4_mem)
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("4M")
MCFG_RAM_DEFAULT_VALUE(0x00)
MCFG_M48T02_ADD(TIMEKEEPER_TAG)
// MMU Type 0 device space
MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(type0space_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
// MMU Type 1 device space
MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0)
MCFG_DEVICE_PROGRAM_MAP(type1space_map)
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG)
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
MCFG_SCC8530_ADD(SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
@ -926,11 +1024,11 @@ ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
COMP( 198?, sun4_300, 0, 0, sun4, sun4, driver_device, 0, "Sun Microsystems", "Sun 4/3x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun4_40, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation IPC (Sun 4/40)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun4_50, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation IPX (Sun 4/50)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun4_20, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun4_60, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun4_75, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun_s10, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 10 (Sun S10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 198?, sun_s20, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 20", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1987, sun4_300, 0, 0, sun4, sun4, driver_device, 0, "Sun Microsystems", "Sun 4/3x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1990, sun4_40, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation IPC (Sun 4/40)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1991, sun4_50, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation IPX (Sun 4/50)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 199?, sun4_20, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1989, sun4_60, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1990, sun4_75, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1992, sun_s10, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 10 (Sun S10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1994, sun_s20, sun4_300,0, sun4, sun4, driver_device, 0, "Sun Microsystems", "SPARCstation 20", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)

View File

@ -82,6 +82,8 @@ public:
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_WRITE_LINE_MEMBER(crtc_vsync);
DECLARE_WRITE16_MEMBER(palette_w);
DECLARE_READ16_MEMBER(read_from_z80);
DECLARE_WRITE16_MEMBER(write_to_z80);
@ -195,6 +197,12 @@ WRITE16_MEMBER(tapatune_state::palette_w)
}
WRITE_LINE_MEMBER(tapatune_state::crtc_vsync)
{
m_videocpu->set_input_line(2, state ? HOLD_LINE : CLEAR_LINE);
}
/*************************************
*
* 68000 <-> Z80 comms
@ -529,7 +537,7 @@ static MACHINE_CONFIG_DERIVED( tapatune, tapatune_base )
MCFG_MC6845_CHAR_WIDTH(5)
MCFG_MC6845_BEGIN_UPDATE_CB(tapatune_state, crtc_begin_update)
MCFG_MC6845_UPDATE_ROW_CB(tapatune_state, crtc_update_row)
MCFG_MC6845_OUT_VSYNC_CB(INPUTLINE("videocpu", 2))
MCFG_MC6845_OUT_VSYNC_CB(WRITELINE(tapatune_state, crtc_vsync))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)

View File

@ -3497,6 +3497,34 @@ ROM_START( tmht22pe )
ROM_LOAD( "tmnt2_eba.nv", 0x0000, 0x080, CRC(c0a3ed50) SHA1(6deec720c7f1c607740076cb8b5b5becd175aed0) )
ROM_END
ROM_START( tmht24pe )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 4*128k for 68000 code */
ROM_LOAD16_BYTE( "063eaa02.8e", 0x000000, 0x20000, CRC(665a68de) SHA1(3cefc2cb0f0a42f1044ef04862669fc7893005da) )
ROM_LOAD16_BYTE( "063eaa03.8g", 0x000001, 0x20000, CRC(7b7fb3af) SHA1(1c96283af8fc81c30136dfe2efbd113cb7dd3d66) )
ROM_LOAD16_BYTE( "063eaa04.10e", 0x040000, 0x20000, CRC(69f38e1d) SHA1(a63aa86a11f803fa3f07c5eb2fdbdb75bb850d55) )
ROM_LOAD16_BYTE( "063eaa05.10g", 0x040001, 0x20000, CRC(818032af) SHA1(60d416a58696add58493c0f2297b3a4af5f46d6d) )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "063b01.2f", 0x0000, 0x10000, CRC(364f548a) SHA1(e0636e27d4fc48b2ccb1417b63d2b68d9e272c06) )
ROM_REGION( 0x100000, "k052109", 0 ) /* tiles */
ROM_LOAD32_WORD( "063b12.16k", 0x000000, 0x080000, CRC(d3283d19) SHA1(49e4daa9cbe4d99bf71fcee6237cb434a0d55312) )
ROM_LOAD32_WORD( "063b11.12k", 0x000002, 0x080000, CRC(6ebc0c15) SHA1(e6848405076937fbf8ec6d318293a0ff922725f4) )
ROM_REGION( 0x400000, "k053245", 0 ) /* sprites */
ROM_LOAD32_WORD( "063b09.7l", 0x000000, 0x100000, CRC(2d7a9d2a) SHA1(a26f9c1a07152bc8c7bcd797d4485bf848f5e2a0) )
ROM_LOAD32_WORD( "063b07.3l", 0x000002, 0x100000, CRC(d9bee7bf) SHA1(7bbb65138fbd216b80412783e6f0072742101440) )
ROM_LOAD32_WORD( "063b10.7k", 0x200000, 0x080000, CRC(f2dd296e) SHA1(a2aad10bfb0904dd73c2ee11049648c94de7f4d5) )
ROM_LOAD32_WORD( "063b08.3k", 0x200002, 0x080000, CRC(3b1ae36f) SHA1(9e69cae8b517497ac77c4d148f56f2bb6a23de89) )
/* second half empty */
ROM_REGION( 0x200000, "k053260", 0 ) /* samples for the 053260 */
ROM_LOAD( "063b06.1d", 0x0000, 0x200000, CRC(1e510aa5) SHA1(02b9bd6bb6b098026a620e4d671c40a31ad9e318) )
ROM_REGION( 0x80, "eeprom", 0 ) // default eeprom to prevent game booting with invisible error message
ROM_LOAD( "tmnt2_eaa.nv", 0x0000, 0x080, CRC(124af18f) SHA1(bbd0629663135fc6c08b000b886ea76a96592a9e) )
ROM_END
ROM_START( tmnt2a )
ROM_REGION( 0x100000, "maincpu", 0 ) /* 4*128k for 68000 code */
ROM_LOAD16_BYTE( "063ada02.8e", 0x000000, 0x20000, CRC(4f11b587) SHA1(111051da23ce7035405b4d12c0f18dcc1d6c8ddc) )
@ -4207,6 +4235,7 @@ GAME( 1991, glfgreatj, glfgreat, glfgreat, glfgreatj, driver_device, 0,
GAME( 1991, tmnt2, 0, tmnt2, ssridr4p, driver_device, 0, ROT0, "Konami", "Teenage Mutant Ninja Turtles - Turtles in Time (4 Players ver UAA)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, tmnt2a, tmnt2, tmnt2, ssrid4ps, driver_device, 0, ROT0, "Konami", "Teenage Mutant Ninja Turtles - Turtles in Time (4 Players ver ADA)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, tmht22pe, tmnt2, tmnt2, ssriders, driver_device, 0, ROT0, "Konami", "Teenage Mutant Hero Turtles - Turtles in Time (2 Players ver EBA)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, tmht24pe, tmnt2, tmnt2, ssriders, driver_device, 0, ROT0, "Konami", "Teenage Mutant Hero Turtles - Turtles in Time (4 Players ver EAA)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, tmnt22pu, tmnt2, tmnt2, ssriders, driver_device, 0, ROT0, "Konami", "Teenage Mutant Ninja Turtles - Turtles in Time (2 Players ver UDA)", MACHINE_SUPPORTS_SAVE )
GAME( 1993, qgakumon, 0, tmnt2, qgakumon, driver_device, 0, ROT0, "Konami", "Quiz Gakumon no Susume (Japan ver. JA2 Type L)", MACHINE_SUPPORTS_SAVE )

View File

@ -776,25 +776,6 @@ WRITE16_MEMBER(toaplan2_state::fixeightbl_oki_bankswitch_w)
}
}
READ8_MEMBER(toaplan2_state::v25_dswa_r)
{
return ioport("DSWA")->read() ^ 0xff;
}
READ8_MEMBER(toaplan2_state::v25_dswb_r)
{
return ioport("DSWB")->read() ^ 0xff;
}
READ8_MEMBER(toaplan2_state::v25_jmpr_r)
{
return ioport("JMPR")->read() ^ 0xff;
}
READ8_MEMBER(toaplan2_state::fixeight_region_r)
{
// this must match the eeprom region!
@ -1497,27 +1478,6 @@ static ADDRESS_MAP_START( vfive_v25_mem, AS_PROGRAM, 8, toaplan2_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( v25_port, AS_IO, 8, toaplan2_state )
AM_RANGE(V25_PORT_PT, V25_PORT_PT) AM_READ(v25_dswa_r)
AM_RANGE(V25_PORT_P0, V25_PORT_P0) AM_READ(v25_dswb_r)
AM_RANGE(V25_PORT_P1, V25_PORT_P1) AM_READ(v25_jmpr_r)
AM_RANGE(V25_PORT_P2, V25_PORT_P2) AM_WRITENOP // bit 0 is FAULT according to kbash schematic
ADDRESS_MAP_END
static ADDRESS_MAP_START( dogyuun_v25_port, AS_IO, 8, toaplan2_state )
AM_RANGE(V25_PORT_PT, V25_PORT_PT) AM_READ(v25_dswb_r)
AM_RANGE(V25_PORT_P0, V25_PORT_P0) AM_READ(v25_dswa_r)
AM_RANGE(V25_PORT_P1, V25_PORT_P1) AM_READ(v25_jmpr_r)
AM_RANGE(V25_PORT_P2, V25_PORT_P2) AM_WRITENOP // bit 0 is FAULT according to kbash schematic
ADDRESS_MAP_END
static ADDRESS_MAP_START( fixeight_v25_port, AS_IO, 8, toaplan2_state )
AM_RANGE(V25_PORT_P0, V25_PORT_P0) AM_READWRITE_PORT("EEPROM")
ADDRESS_MAP_END
static ADDRESS_MAP_START( fixeightbl_oki, AS_0, 8, toaplan2_state )
AM_RANGE(0x00000, 0x2ffff) AM_ROM
AM_RANGE(0x30000, 0x3ffff) AM_ROMBANK("bank1")
@ -3219,8 +3179,11 @@ static MACHINE_CONFIG_START( dogyuun, toaplan2_state )
MCFG_CPU_ADD("audiocpu", V25, XTAL_25MHz/2) /* NEC V25 type Toaplan marked CPU ??? */
MCFG_CPU_PROGRAM_MAP(v25_mem)
MCFG_CPU_IO_MAP(dogyuun_v25_port)
MCFG_V25_CONFIG(nitro_decryption_table)
MCFG_V25_PORT_PT_READ_CB(IOPORT("DSWB")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P0_READ_CB(IOPORT("DSWA")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P1_READ_CB(IOPORT("JMPR")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P2_WRITE_CB(NOOP) // bit 0 is FAULT according to kbash schematic
MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2)
@ -3264,8 +3227,11 @@ static MACHINE_CONFIG_START( kbash, toaplan2_state )
/* ROM based v25 */
MCFG_CPU_ADD("audiocpu", V25, XTAL_16MHz) /* NEC V25 type Toaplan marked CPU ??? */
MCFG_CPU_PROGRAM_MAP(kbash_v25_mem)
MCFG_CPU_IO_MAP(v25_port)
MCFG_V25_CONFIG(nitro_decryption_table)
MCFG_V25_PORT_PT_READ_CB(IOPORT("DSWA")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P0_READ_CB(IOPORT("DSWB")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P1_READ_CB(IOPORT("JMPR")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P2_WRITE_CB(NOOP) // bit 0 is FAULT according to kbash schematic
MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2)
@ -3519,8 +3485,9 @@ static MACHINE_CONFIG_START( fixeight, toaplan2_state )
MCFG_CPU_ADD("audiocpu", V25, XTAL_16MHz) /* NEC V25 type Toaplan marked CPU ??? */
MCFG_CPU_PROGRAM_MAP(fixeight_v25_mem)
MCFG_CPU_IO_MAP(fixeight_v25_port)
MCFG_V25_CONFIG(ts001turbo_decryption_table)
MCFG_V25_PORT_P0_READ_CB(IOPORT("EEPROM"))
MCFG_V25_PORT_P0_WRITE_CB(IOPORT("EEPROM"))
MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2)
@ -3601,8 +3568,11 @@ static MACHINE_CONFIG_START( vfive, toaplan2_state )
MCFG_CPU_ADD("audiocpu", V25, XTAL_20MHz/2) /* Verified on pcb, NEC V25 type Toaplan mark scratched out */
MCFG_CPU_PROGRAM_MAP(vfive_v25_mem)
MCFG_CPU_IO_MAP(v25_port)
MCFG_V25_CONFIG(nitro_decryption_table)
MCFG_V25_PORT_PT_READ_CB(IOPORT("DSWA")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P0_READ_CB(IOPORT("DSWB")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P1_READ_CB(IOPORT("JMPR")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P2_WRITE_CB(NOOP) // bit 0 is FAULT according to kbash schematic
MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2)
@ -3639,7 +3609,10 @@ static MACHINE_CONFIG_START( batsugun, toaplan2_state )
MCFG_CPU_ADD("audiocpu", V25, XTAL_32MHz/2) /* NEC V25 type Toaplan marked CPU ??? */
MCFG_CPU_PROGRAM_MAP(v25_mem)
MCFG_CPU_IO_MAP(v25_port)
MCFG_V25_PORT_PT_READ_CB(IOPORT("DSWA")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P0_READ_CB(IOPORT("DSWB")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P1_READ_CB(IOPORT("JMPR")) MCFG_DEVCB_XOR(0xff)
MCFG_V25_PORT_P2_WRITE_CB(NOOP) // bit 0 is FAULT according to kbash schematic
MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2)

View File

@ -165,8 +165,9 @@ class dc_state : public driver_device
#define SB_G1CRDYC ((0x005f74b4-0x005f7400)/4)
#define SB_GDAPRO ((0x005f74b8-0x005f7400)/4)
/*-------- Unknown/Special Registers ---------*/
#define GD_UNLOCK ((0x005f74e4-0x005f7400)/4)
/*-------- BIOS security Registers ---------*/
#define SB_SECUR_EADR ((0x005f74e4-0x005f7400)/4)
#define SB_SECUR_STATE ((0x005f74ec-0x005f7400)/4)
/*---------- GD-DMA Debug Registers ------------*/
#define SB_GDSTARD ((0x005f74f4-0x005f7400)/4)
#define SB_GDLEND ((0x005f74f8-0x005f7400)/4)

View File

@ -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

View File

@ -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

View File

@ -100,9 +100,6 @@ public:
DECLARE_WRITE16_MEMBER(ghox_shared_ram_w);
DECLARE_WRITE16_MEMBER(fixeight_subcpu_ctrl_w);
DECLARE_WRITE16_MEMBER(fixeightbl_oki_bankswitch_w);
DECLARE_READ8_MEMBER(v25_dswa_r);
DECLARE_READ8_MEMBER(v25_dswb_r);
DECLARE_READ8_MEMBER(v25_jmpr_r);
DECLARE_READ8_MEMBER(fixeight_region_r);
DECLARE_WRITE8_MEMBER(raizing_z80_bankswitch_w);
DECLARE_WRITE8_MEMBER(raizing_oki_bankswitch_w);

View File

@ -510,8 +510,10 @@ void sam6883_device::sam_space<_addrstart, _addrend>::point_specific_bank(const
// normalize offset
if (mask != 0)
offset &= mask;
else
mask = 0xffff;
UINT32 mirror = (addrend - addrstart) ^ mask;
UINT32 mirror = (addrend - addrstart) & ~mask;
// this bank is a memory bank - first ensure that we have a bank
if (!memory_bank || !memory_bank->matches_exactly(addrstart, addrend) || (mask != m_mask))

View File

@ -126,6 +126,13 @@ READ32_MEMBER(dc_cons_state::dc_mess_g1_ctrl_r )
case SB_GDLEND:
//machine().debug_break();
return atapi_xferlen; // TODO: check me
case SB_SECUR_EADR: // always read 0xFF on hardware
return 0x000000ff;
case SB_SECUR_STATE: // state of BIOS checksum security system (R/O):
// 3 - check passed OK, G1 ATA (5F70xx) registers area accessible
// 2 - check failed, G1 ATA area blocked (read FFFFFFFFh)
// 0 - check in progress, BIOS data summed, G1 ATA area blocked (read FFFFFFFFh)
return 3;
default:
printf("G1CTRL: Unmapped read %08x\n", 0x5f7400+offset*4);
machine().debug_break();
@ -166,27 +173,27 @@ WRITE32_MEMBER(dc_cons_state::dc_mess_g1_ctrl_w )
The following register is involved in BIOS checksum protection system.
current understanding of its functioning based on several hardware tests:
after power on system is in "protected state":
- access to G1 ATA register area (5F70XX) is locked, ie GD-ROM in Dreamcast or cartridge/DIMM in arcade systems is not accessible;
- *any* data readed via G1 data bus (ie BIOS) is summed internally by chipset;
- write to GD_UNLOCK (5F74E4) register set "last address" of checksummed area;
after power on security system is in state 0 (check in progress):
- access to G1 ATA register area (5F70XX) is blocked, ie GD-ROM in Dreamcast or cartridge/DIMM in arcade systems is not accessible;
- *any* data readed via G1 data bus (i.e. BIOS) is summed internally by chipset;
- write to SB_SECUR_EADR register set last address of checksummed area;
then readed address matches with "last address" - calculated summ compared with some hardcoded value
if values match - system becomes in "unlocked state":
- G1 ATA registers unlocked;
- by write to GD_UNLOCK register system can be switched back to "protected state"
then read address will match SB_SECUR_EADR - calculated summ compared with some hardcoded value
if values match - security system becomes in state 3 (check OK):
- G1 ATA registers area unlocked;
- can be switched back to state 0 by write to SB_SECUR_EADR register, Dreamcast BIOS write 42FEh before jump into Mil-CD executables
if values doesn't match - system switch to "locked state":
- similar to protected, but data summing seems not performed anymore,
at least write to GD_UNLOCK and "pumping" through G1 bus data chunk with valid checksumm have no effect;
if values doesn't match - security system switch to state 2 (check fail):
- similar to state 0, but data summing seems not performed anymore,
- the only exit from this state - power off/on or reset;
current state can be read from SB_SECUR_STATE register
actual checksum algorithm is unknown, but its supposed to be simple and weak,
known few modded BIOSes which succesfully passes this CRC check, because of good luck
all described above works the same way in all HOLLY/CLX2-based systems - Dreamcast, Naomi 1/2, Atomiswave, SystemSP
*/
case GD_UNLOCK:
case SB_SECUR_EADR:
if (data==0 || data==0x001fffff || data==0x42fe)
{
// atapi_regs[ATAPI_REG_SAMTAG] = GDROM_PAUSE_STATE | 0x80;

View File

@ -3,6 +3,14 @@
/***************************************************************************
Seibu Cop (Co-Processor) device emulation
a.k.a. known as Toshiba gate array TC25SC rebadged as:
SEI300 - Legionnaire PCB
There's also a ROM labeled COP-Dx, which is probably used for some in-game maths:
COP-D1 - Seibu Cup Soccer PCBs
COP-D2 - legionna.cpp and raiden2.cpp, latter might use another component too
COP-D3 - New Zero Team / Raiden 2 V33 HWs
Raiden 2 first boss arms is known to behave strangely without this ROM on a real PCB
(new implementation, based on Raiden 2 code)
TODO:
@ -17,7 +25,20 @@
- printing facilities;
- debugger break on pre-setted commands;
- ...
per-game TODO:
legionnaire
- (fixed) player walks on spot on stage clear;
- several enemies seems to not like a missing min/max range limit for a specific operation?
(when i.e. first boss goes to bottom of the screen and become unreachable)
heated barrel
- gives random value to hi-score if you continue (only the first time, not a bug?);
- (fixed?) throws random address exceptions at level 3 and above, a RAM address arrives corrupt in the snippet at 0x136a;
- (fixed?) some corrupt sprites, probably a non-fatal version of the one above;
- stage 2 boss attacks only in vertical (regressed with the 130e / 3b30 / 42c2 command merge);
- (fixed) level 3+ boss movements looks wrong;
- missiles doesn't seem to like our 6200 hookup here;
Tech notes:
-----------
[0x6fc] DMA mode bit scheme:
@ -30,16 +51,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 +677,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 +850,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;
@ -2271,7 +1435,7 @@ WRITE16_MEMBER(raiden2cop_device::LEGACY_cop_cmd_w)
if (check_command_matches(command, 0x984, 0xaa4, 0xd82, 0xaa2, 0x39b, 0xb9a, 0xb9a, 0xb9a, 5, 0xbf7f))
{
executed = 1;
LEGACY_execute_130e(offset, data);
execute_130e(offset, data);
return;
}
@ -2286,7 +1450,7 @@ WRITE16_MEMBER(raiden2cop_device::LEGACY_cop_cmd_w)
if (check_command_matches(command, 0xf9c, 0xb9c, 0xb9c, 0xb9c, 0xb9c, 0xb9c, 0xb9c, 0x99c, 4, 0x007f))
{
executed = 1;
LEGACY_execute_3b30(offset, data);
execute_3b30(offset, data);
return;
}
@ -2304,7 +1468,7 @@ WRITE16_MEMBER(raiden2cop_device::LEGACY_cop_cmd_w)
if (check_command_matches(command, 0xf9a, 0xb9a, 0xb9c, 0xb9c, 0xb9c, 0x29c, 0x000, 0x000, 5, 0xfcdd))
{
executed = 1;
LEGACY_execute_42c2(offset, data);
execute_42c2(offset, data);
return;
}

View File

@ -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);
@ -249,10 +250,10 @@ private:
void execute_b900(int offset, UINT16 data);
// TODO: remove these
void LEGACY_execute_130e(int offset, UINT16 data);
//void LEGACY_execute_130e(int offset, UINT16 data);
void LEGACY_execute_130e_cupsoc(int offset, UINT16 data);
void LEGACY_execute_3b30(int offset, UINT16 data);
void LEGACY_execute_42c2(int offset, UINT16 data);
//void LEGACY_execute_3b30(int offset, UINT16 data);
//void LEGACY_execute_42c2(int offset, UINT16 data);
void LEGACY_execute_e30e(int offset, UINT16 data);
void LEGACY_execute_6200(int offset, UINT16 data);
void LEGACY_execute_dde5(int offset, UINT16 data);

View File

@ -0,0 +1,705 @@
/* 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] + 0x04 + 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_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;
cop_angle &= 0xff;
}
#if LOG_Phytagoras
printf("cmd %04x: dx = %d dy = %d angle = %02x\n",data,dx,dy,cop_angle);
#endif
if (data & 0x0080) {
// TODO: byte or word?
cop_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)
cop_write_word(cop_regs[0] + (data & 0x200 ? 0x3a : 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 = cop_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;
cop_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
cop_write_word(cop_regs[0] + (0x38), (cop_dist << (5 - cop_scale)) / div);
}
/*
## - 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)
*/
#ifdef UNUSED_COMMANDS
// For reference only, will be nuked at some point
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_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);
}
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);
}
#endif

View 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);
}
*/
}

View File

@ -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"

View File

@ -13465,6 +13465,8 @@ fl7_3121 // (c) 199? Cyberdyne Systems, Inc.
fl7_50 // (c) 199? Cyberdyne Systems, Inc.
fl7_500 // (c) 199? Cyberdyne Systems, Inc.
fl7_2000 // (c) 199? Cyberdyne Systems, Inc.
fl7_2k16 // (c) 199? Cyberdyne Systems, Inc.
fl7_tw // Taiwanese Hardware.
goldfrui // bootleg
goldstar // (c) 198? IGS
goldstbl // (c) 198? IGS
@ -35296,7 +35298,6 @@ thndrx2 // GX073 (c) 1991 (World)
thndrx2a // GX073 (c) 1991 (Asia)
thndrx2j // GX073 (c) 1991 (Japan)
tmht // GX963 (c) 1989 (UK)
tmht22pe // GX063 (c) 1991 (UK)
tmht2p // GX963 (c) 1989 (UK)
tmht2pa // GX963 (c) 1989 (UK)
tmhta // GX963 (c) 1989 (UK)
@ -35304,6 +35305,8 @@ tmhtb // GX963 (c) 1989 (UK?)
tmnt // GX963 (c) 1989 (World)
tmnt2 // GX063 (c) 1991 (US)
tmnt22pu // GX063 (c) 1991 (US)
tmht22pe // GX063 (c) 1991 (UK)
tmht24pe // GX063 (c) 1991 (UK)
tmnt2a // GX063 (c) 1991 (Asia)
tmnt2pj // GX963 (c) 1990 (Japan)
tmnt2po // GX963 (c) 1989 (Oceania)

View File

@ -21,7 +21,8 @@ Raiden later rev (probably the first game to use it)
TODO:
- Most registers are still a mystery;
- Get the proper Seibu chip ID number;
- Get the proper Seibu chip ID number.
Kold found that a Raiden alt set has irq request pin from a chip named SEI0160, which might be our man.
preliminary memory map:
(screen 0 -> Background)