mirror of
https://github.com/holub/mame
synced 2025-06-05 04:16:28 +03:00
Merge remote-tracking branch 'origin/master' into netlist_dev
This commit is contained in:
commit
23c5c02d5a
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
201
src/devices/cpu/sparc/sparcdasm.h
Normal file
201
src/devices/cpu/sparc/sparcdasm.h
Normal 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
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 ®ion: mm->regions()) {
|
||||
table[region.second->name()] = ®ion;
|
||||
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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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 */
|
||||
|
@ -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 )
|
||||
|
@ -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 ---
|
||||
|
@ -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 )
|
||||
|
@ -1,5 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Angelo Salese
|
||||
// thanks-to: David Haywood, Peter Wilhelmsen
|
||||
/*************************************************************************************************************************
|
||||
|
||||
Metal Freezer (c) 1989 Seibu
|
||||
|
@ -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 )
|
||||
|
@ -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 */
|
||||
|
@ -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 )
|
||||
|
@ -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)
|
||||
|
@ -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 )
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 )
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "sound/okim6295.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/raiden2cop.h"
|
||||
#include "machine/seibucop/seibucop.h"
|
||||
#include "video/seibu_crtc.h"
|
||||
|
||||
class legionna_state : public driver_device
|
||||
|
@ -1,7 +1,7 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina
|
||||
#include "audio/seibu.h"
|
||||
#include "machine/raiden2cop.h"
|
||||
#include "machine/seibucop/seibucop.h"
|
||||
#include "video/seibu_crtc.h"
|
||||
|
||||
class raiden2_state : public driver_device
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
705
src/mame/machine/seibucop/seibucop_cmd.hxx
Normal file
705
src/mame/machine/seibucop/seibucop_cmd.hxx
Normal 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
|
152
src/mame/machine/seibucop/seibucop_dma.hxx
Normal file
152
src/mame/machine/seibucop/seibucop_dma.hxx
Normal file
@ -0,0 +1,152 @@
|
||||
|
||||
// ALL games use this - tilemap DMA (RAM -> private buffer)
|
||||
void raiden2cop_device::dma_tilemap_buffer()
|
||||
{
|
||||
int src = cop_dma_src[cop_dma_mode] << 6;
|
||||
if (src == 0xcfc0) src = 0xd000; // R2, why?? everything else sets the right pointer (it also sets up odd size / dest regs, they probably counteract this)
|
||||
|
||||
for (int i = 0; i < 0x2800 / 2; i++)
|
||||
{
|
||||
UINT16 tileval = m_host_space->read_word(src);
|
||||
src += 2;
|
||||
m_videoramout_cb(i, tileval, 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
// ALL games use this - palette DMA (RAM -> private buffer)
|
||||
void raiden2cop_device::dma_palette_buffer()
|
||||
{
|
||||
int src = cop_dma_src[cop_dma_mode] << 6;
|
||||
|
||||
for (int i = 0; i < 0x1000 / 2; i++) // todo, use length register
|
||||
{
|
||||
UINT16 palval = m_host_space->read_word(src);
|
||||
src += 2;
|
||||
m_palette->set_pen_color(i, pal5bit(palval >> 0), pal5bit(palval >> 5), pal5bit(palval >> 10));
|
||||
}
|
||||
}
|
||||
|
||||
// these are typically used to transfer palette data from one RAM buffer to another, applying fade values to it prior to the 0x15 transfer
|
||||
void raiden2cop_device::dma_palette_brightness()
|
||||
{
|
||||
UINT32 src, dst, size, i;
|
||||
|
||||
/*
|
||||
Apparently all of those are just different DMA channels, brightness effects are done through a RAM table and the pal_brightness_val / mode
|
||||
0x80 is used by Legionnaire
|
||||
0x81 is used by SD Gundam and Godzilla
|
||||
0x82 is used by Zero Team and X Se Dae
|
||||
0x86 is used by Seibu Cup Soccer
|
||||
0x87 is used by Denjin Makai
|
||||
|
||||
TODO:
|
||||
- Denjin Makai mode 4 is totally guessworked.
|
||||
- SD Gundam doesn't fade colors correctly, it should have the text layer / sprites with normal gradient and the rest dimmed in most cases,
|
||||
presumably bad RAM table or bad algorithm
|
||||
*/
|
||||
|
||||
//if(dma_trigger != 0x87)
|
||||
//printf("SRC: %08x %08x DST:%08x SIZE:%08x TRIGGER: %08x %02x %02x\n",cop_dma_src[cop_dma_mode] << 6,cop_dma_adr_rel * 0x400,cop_dma_dst[cop_dma_mode] << 6,cop_dma_size[cop_dma_mode] << 5,cop_dma_mode,pal_brightness_val,pal_brightness_mode);
|
||||
|
||||
src = (cop_dma_src[cop_dma_mode] << 6);
|
||||
dst = (cop_dma_dst[cop_dma_mode] << 6);
|
||||
size = ((cop_dma_size[cop_dma_mode] << 5) - (cop_dma_dst[cop_dma_mode] << 6) + 0x20) / 2;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
UINT16 pal_val;
|
||||
int r, g, b;
|
||||
int rt, gt, bt;
|
||||
|
||||
if (pal_brightness_mode == 5)
|
||||
{
|
||||
bt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x7c00) >> 5;
|
||||
bt = fade_table(bt | (pal_brightness_val ^ 0));
|
||||
b = ((m_host_space->read_word(src)) & 0x7c00) >> 5;
|
||||
b = fade_table(b | (pal_brightness_val ^ 0x1f));
|
||||
pal_val = ((b + bt) & 0x1f) << 10;
|
||||
gt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x03e0);
|
||||
gt = fade_table(gt | (pal_brightness_val ^ 0));
|
||||
g = ((m_host_space->read_word(src)) & 0x03e0);
|
||||
g = fade_table(g | (pal_brightness_val ^ 0x1f));
|
||||
pal_val |= ((g + gt) & 0x1f) << 5;
|
||||
rt = ((m_host_space->read_word(src + (cop_dma_adr_rel * 0x400))) & 0x001f) << 5;
|
||||
rt = fade_table(rt | (pal_brightness_val ^ 0));
|
||||
r = ((m_host_space->read_word(src)) & 0x001f) << 5;
|
||||
r = fade_table(r | (pal_brightness_val ^ 0x1f));
|
||||
pal_val |= ((r + rt) & 0x1f);
|
||||
}
|
||||
else if (pal_brightness_mode == 4) //Denjin Makai
|
||||
{
|
||||
UINT16 targetpaldata = m_host_space->read_word(src + (cop_dma_adr_rel * 0x400));
|
||||
UINT16 paldata = m_host_space->read_word(src); // ^1 !!! (why?)
|
||||
|
||||
bt = (targetpaldata & 0x7c00) >> 10;
|
||||
b = (paldata & 0x7c00) >> 10;
|
||||
gt = (targetpaldata & 0x03e0) >> 5;
|
||||
g = (paldata & 0x03e0) >> 5;
|
||||
rt = (targetpaldata & 0x001f) >> 0;
|
||||
r = (paldata & 0x001f) >> 0;
|
||||
|
||||
if (pal_brightness_val == 0x10)
|
||||
pal_val = bt << 10 | gt << 5 | rt << 0;
|
||||
else if (pal_brightness_val == 0xff) // TODO: might be the back plane or it still doesn't do any mod, needs PCB tests
|
||||
pal_val = 0;
|
||||
else
|
||||
{
|
||||
bt = fade_table(bt << 5 | ((pal_brightness_val * 2) ^ 0));
|
||||
b = fade_table(b << 5 | ((pal_brightness_val * 2) ^ 0x1f));
|
||||
pal_val = ((b + bt) & 0x1f) << 10;
|
||||
gt = fade_table(gt << 5 | ((pal_brightness_val * 2) ^ 0));
|
||||
g = fade_table(g << 5 | ((pal_brightness_val * 2) ^ 0x1f));
|
||||
pal_val |= ((g + gt) & 0x1f) << 5;
|
||||
rt = fade_table(rt << 5 | ((pal_brightness_val * 2) ^ 0));
|
||||
r = fade_table(r << 5 | ((pal_brightness_val * 2) ^ 0x1f));
|
||||
pal_val |= ((r + rt) & 0x1f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Warning: palette DMA used with mode %02x!\n", pal_brightness_mode);
|
||||
pal_val = m_host_space->read_word(src);
|
||||
}
|
||||
|
||||
m_host_space->write_word(dst, pal_val);
|
||||
src += 2;
|
||||
dst += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void raiden2cop_device::dma_fill()
|
||||
{
|
||||
UINT32 length, address;
|
||||
int i;
|
||||
if (cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid?
|
||||
return;
|
||||
|
||||
address = (cop_dma_src[cop_dma_mode] << 6);
|
||||
length = (cop_dma_size[cop_dma_mode] + 1) << 5;
|
||||
|
||||
//printf("%08x %08x\n",address,length);
|
||||
|
||||
for (i = address; i < address + length; i += 4)
|
||||
m_host_space->write_dword(i, (cop_dma_v1) | (cop_dma_v2 << 16));
|
||||
|
||||
/*
|
||||
UINT32 length, address;
|
||||
int i;
|
||||
if(cop_dma_dst[cop_dma_mode] != 0x0000) // Invalid?
|
||||
return;
|
||||
|
||||
address = (cop_dma_src[cop_dma_mode] << 6);
|
||||
length = (cop_dma_size[cop_dma_mode]+1) << 5;
|
||||
|
||||
//printf("%08x %08x\n",address,length);
|
||||
|
||||
for (i=address;i<address+length;i+=4)
|
||||
{
|
||||
m_host_space->write_dword(i, m_fill_val);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Olivier Galibert, Angelo Salese, David Haywood, Tomasz Slanina
|
||||
|
||||
#include "raiden2cop.h"
|
||||
#include "seibucop/seibucop.h"
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user