mirror of
https://github.com/holub/mame
synced 2025-06-07 13:23:50 +03:00
jaguar.cpp updates [Angelo Salese]
* move i/o handlers to specific maps, untangle register array usage, to be completed * Nuke duplicate I/O accesses, rename to iobus_r/w, make go_w to be an actual line * Fix addqmod & subqmod modulo mask for DSP * Refactor TOM to host CPU function, and fix GPU irq lv 3 when a GPU object is encountered. Fixes mutntpng and atarikrt booting * Fix Jaguar irq line to 2, trusted * Start reworking the blitter * Relicensed to BSD
This commit is contained in:
parent
12ec6362bb
commit
5ad522f0c1
@ -168,7 +168,7 @@ Unreleased (possibly no prototypes exist):
|
|||||||
</part>
|
</part>
|
||||||
</software>
|
</software>
|
||||||
|
|
||||||
<!-- black screen -->
|
<!-- boot OK, gameplay graphics have clipping/alignment issues, eventually throws an exception, no sound -->
|
||||||
<software name="atarikrt" supported="no">
|
<software name="atarikrt" supported="no">
|
||||||
<description>Atari Karts</description>
|
<description>Atari Karts</description>
|
||||||
<year>1995</year>
|
<year>1995</year>
|
||||||
@ -181,8 +181,8 @@ Unreleased (possibly no prototypes exist):
|
|||||||
</part>
|
</part>
|
||||||
</software>
|
</software>
|
||||||
|
|
||||||
<!-- black screen -->
|
<!-- boot OK, title screen foreground layer not drawn properly, no sound -->
|
||||||
<software name="mutntpng" supported="no">
|
<software name="mutntpng" supported="partial">
|
||||||
<description>Attack of the Mutant Penguins</description>
|
<description>Attack of the Mutant Penguins</description>
|
||||||
<year>1996</year>
|
<year>1996</year>
|
||||||
<publisher>Atari</publisher>
|
<publisher>Atari</publisher>
|
||||||
@ -592,7 +592,8 @@ Unreleased (possibly no prototypes exist):
|
|||||||
</part>
|
</part>
|
||||||
</software>
|
</software>
|
||||||
|
|
||||||
<!-- hangs at the NBA Jam TE logo -->
|
<!-- exception on non-debug, on debug gameplay sports no sprite GFXs -->
|
||||||
|
<!-- minor glitch on team box when selecting one (blitter not filling properly) -->
|
||||||
<software name="nbajamte" supported="no">
|
<software name="nbajamte" supported="no">
|
||||||
<description>NBA Jam T.E. - Tournament Edition</description>
|
<description>NBA Jam T.E. - Tournament Edition</description>
|
||||||
<year>1996</year>
|
<year>1996</year>
|
||||||
@ -966,7 +967,7 @@ Unreleased (possibly no prototypes exist):
|
|||||||
</software>
|
</software>
|
||||||
|
|
||||||
<!-- boot OK, no BGMs, has minor GFX pitch issue when action summary message pops up after a play -->
|
<!-- boot OK, no BGMs, has minor GFX pitch issue when action summary message pops up after a play -->
|
||||||
<software name="troyaik" supported="no">
|
<software name="troyaik" supported="partial">
|
||||||
<description>Troy Aikman NFL Football</description>
|
<description>Troy Aikman NFL Football</description>
|
||||||
<year>1995</year>
|
<year>1995</year>
|
||||||
<publisher>Williams Entertainment</publisher>
|
<publisher>Williams Entertainment</publisher>
|
||||||
|
@ -1219,6 +1219,8 @@ files {
|
|||||||
MAME_DIR .. "src/mame/drivers/jaguar.cpp",
|
MAME_DIR .. "src/mame/drivers/jaguar.cpp",
|
||||||
MAME_DIR .. "src/mame/includes/jaguar.h",
|
MAME_DIR .. "src/mame/includes/jaguar.h",
|
||||||
MAME_DIR .. "src/mame/audio/jaguar.cpp",
|
MAME_DIR .. "src/mame/audio/jaguar.cpp",
|
||||||
|
MAME_DIR .. "src/mame/video/jag_blitter.cpp",
|
||||||
|
MAME_DIR .. "src/mame/video/jag_blitter.h",
|
||||||
MAME_DIR .. "src/mame/video/jaguar.cpp",
|
MAME_DIR .. "src/mame/video/jaguar.cpp",
|
||||||
MAME_DIR .. "src/mame/video/jagblit.h",
|
MAME_DIR .. "src/mame/video/jagblit.h",
|
||||||
MAME_DIR .. "src/mame/video/jagblit.hxx",
|
MAME_DIR .. "src/mame/video/jagblit.hxx",
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
- Implement pipeline, actually instruction cycles;
|
- Implement pipeline, actually instruction cycles;
|
||||||
Currently implementation is similar to single stepping
|
Currently implementation is similar to single stepping
|
||||||
with single cycle
|
with single cycle
|
||||||
- Implement and acknowlodge remain registers
|
- Implement and acknowlodge remain registers;
|
||||||
|
- Improve delay slot display in debugger (highlight current instruction
|
||||||
|
doesn't work but instruction hook does);
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@ -53,13 +55,13 @@ enum : u32
|
|||||||
CINT5FLAG = 0x20000 // DSP only
|
CINT5FLAG = 0x20000 // DSP only
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void jaguar_cpu_device::CLR_Z() { m_ctrl[G_FLAGS] &= ~ZFLAG; }
|
inline void jaguar_cpu_device::CLR_Z() { m_flags &= ~ZFLAG; }
|
||||||
inline void jaguar_cpu_device::CLR_ZN() { m_ctrl[G_FLAGS] &= ~(ZFLAG | NFLAG); }
|
inline void jaguar_cpu_device::CLR_ZN() { m_flags &= ~(ZFLAG | NFLAG); }
|
||||||
inline void jaguar_cpu_device::CLR_ZNC() { m_ctrl[G_FLAGS] &= ~(CFLAG | ZFLAG | NFLAG); }
|
inline void jaguar_cpu_device::CLR_ZNC() { m_flags &= ~(CFLAG | ZFLAG | NFLAG); }
|
||||||
inline void jaguar_cpu_device::SET_Z(u32 r) { m_ctrl[G_FLAGS] |= (r == 0); }
|
inline void jaguar_cpu_device::SET_Z(u32 r) { m_flags |= (r == 0); }
|
||||||
inline void jaguar_cpu_device::SET_C_ADD(u32 a, u32 b) { m_ctrl[G_FLAGS] |= (b > (~a)) << 1; }
|
inline void jaguar_cpu_device::SET_C_ADD(u32 a, u32 b) { m_flags |= (b > (~a)) << 1; }
|
||||||
inline void jaguar_cpu_device::SET_C_SUB(u32 a, u32 b) { m_ctrl[G_FLAGS] |= (b > a) << 1; }
|
inline void jaguar_cpu_device::SET_C_SUB(u32 a, u32 b) { m_flags |= (b > a) << 1; }
|
||||||
inline void jaguar_cpu_device::SET_N(u32 r) { m_ctrl[G_FLAGS] |= ((r >> 29) & 4); }
|
inline void jaguar_cpu_device::SET_N(u32 r) { m_flags |= ((r >> 29) & 4); }
|
||||||
inline void jaguar_cpu_device::SET_ZN(u32 r) { SET_N(r); SET_Z(r); }
|
inline void jaguar_cpu_device::SET_ZN(u32 r) { SET_N(r); SET_Z(r); }
|
||||||
inline void jaguar_cpu_device::SET_ZNC_ADD(u32 a, u32 b, u32 r) { SET_N(r); SET_Z(r); SET_C_ADD(a, b); }
|
inline void jaguar_cpu_device::SET_ZNC_ADD(u32 a, u32 b, u32 r) { SET_N(r); SET_Z(r); SET_C_ADD(a, b); }
|
||||||
inline void jaguar_cpu_device::SET_ZNC_SUB(u32 a, u32 b, u32 r) { SET_N(r); SET_Z(r); SET_C_SUB(a, b); }
|
inline void jaguar_cpu_device::SET_ZNC_SUB(u32 a, u32 b, u32 r) { SET_N(r); SET_Z(r); SET_C_SUB(a, b); }
|
||||||
@ -69,12 +71,9 @@ inline void jaguar_cpu_device::SET_ZNC_SUB(u32 a, u32 b, u32 r) { SET_N(r); SET_
|
|||||||
MACROS
|
MACROS
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#define PC m_ctrl[G_PC]
|
|
||||||
#define FLAGS m_ctrl[G_FLAGS]
|
|
||||||
|
|
||||||
inline u8 jaguar_cpu_device::CONDITION(u8 x)
|
inline u8 jaguar_cpu_device::CONDITION(u8 x)
|
||||||
{
|
{
|
||||||
return condition_table[x + ((m_ctrl[G_FLAGS] & 7) << 5)];
|
return condition_table[x + ((m_flags & 7) << 5)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u8 jaguar_cpu_device::READBYTE(offs_t a) { return m_program->read_byte(a); }
|
inline u8 jaguar_cpu_device::READBYTE(offs_t a) { return m_program->read_byte(a); }
|
||||||
@ -151,15 +150,33 @@ DEFINE_DEVICE_TYPE(JAGUARGPU, jaguargpu_cpu_device, "jaguargpu", "Motorola Atari
|
|||||||
DEFINE_DEVICE_TYPE(JAGUARDSP, jaguardsp_cpu_device, "jaguardsp", "Motorola Atari Jaguar DSP \"Jerry\"")
|
DEFINE_DEVICE_TYPE(JAGUARDSP, jaguardsp_cpu_device, "jaguardsp", "Motorola Atari Jaguar DSP \"Jerry\"")
|
||||||
|
|
||||||
|
|
||||||
jaguar_cpu_device::jaguar_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 version, bool isdsp)
|
jaguar_cpu_device::jaguar_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 version, bool isdsp, address_map_constructor io_map)
|
||||||
: cpu_device(mconfig, type, tag, owner, clock)
|
: cpu_device(mconfig, type, tag, owner, clock)
|
||||||
, m_program_config("program", ENDIANNESS_BIG, 32, 24, 0)
|
, m_program_config("program", ENDIANNESS_BIG, 32, 24, 0)
|
||||||
|
, m_io_config("io", ENDIANNESS_BIG, 32, 8, 0, io_map)
|
||||||
, m_version(version) // 1 : Jaguar prototype, 2 : Jaguar first release, 3 : Midsummer prototype, Other : unknown/reserved
|
, m_version(version) // 1 : Jaguar prototype, 2 : Jaguar first release, 3 : Midsummer prototype, Other : unknown/reserved
|
||||||
, m_isdsp(isdsp)
|
, m_isdsp(isdsp)
|
||||||
, m_cpu_interrupt(*this)
|
, m_cpu_interrupt(*this)
|
||||||
, m_tables_referenced(false)
|
, m_tables_referenced(false)
|
||||||
, table_refcount(0)
|
, table_refcount(0)
|
||||||
, m_table(isdsp ? dsp_op_table : gpu_op_table)
|
, m_table(isdsp ? dsp_op_table : gpu_op_table)
|
||||||
|
, m_io_end(0x00070007)
|
||||||
|
, m_io_pc(0)
|
||||||
|
, m_io_status(0)
|
||||||
|
, m_pc(0)
|
||||||
|
, m_flags(0)
|
||||||
|
, m_imask(false)
|
||||||
|
, m_maddw(0)
|
||||||
|
, m_mwidth(0)
|
||||||
|
, m_mtxaddr(0)
|
||||||
|
, m_go(false)
|
||||||
|
, m_int_latch(0)
|
||||||
|
, m_int_mask(0)
|
||||||
|
, m_bus_hog(false)
|
||||||
|
, m_div_remainder(0)
|
||||||
|
, m_div_offset(false)
|
||||||
|
, m_hidata(0)
|
||||||
|
, m_modulo(0xffffffff)
|
||||||
{
|
{
|
||||||
if (isdsp)
|
if (isdsp)
|
||||||
{
|
{
|
||||||
@ -175,20 +192,21 @@ jaguar_cpu_device::jaguar_cpu_device(const machine_config &mconfig, device_type
|
|||||||
|
|
||||||
|
|
||||||
jaguargpu_cpu_device::jaguargpu_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
jaguargpu_cpu_device::jaguargpu_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
: jaguar_cpu_device(mconfig, JAGUARGPU, tag, owner, clock, 2, false)
|
: jaguar_cpu_device(mconfig, JAGUARGPU, tag, owner, clock, 2, false, address_map_constructor(FUNC(jaguargpu_cpu_device::io_map), this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
jaguardsp_cpu_device::jaguardsp_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
jaguardsp_cpu_device::jaguardsp_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
: jaguar_cpu_device(mconfig, JAGUARDSP, tag, owner, clock, 2, true)
|
: jaguar_cpu_device(mconfig, JAGUARDSP, tag, owner, clock, 2, true, address_map_constructor(FUNC(jaguardsp_cpu_device::io_map), this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
device_memory_interface::space_config_vector jaguar_cpu_device::memory_space_config() const
|
device_memory_interface::space_config_vector jaguar_cpu_device::memory_space_config() const
|
||||||
{
|
{
|
||||||
return space_config_vector {
|
return space_config_vector {
|
||||||
std::make_pair(AS_PROGRAM, &m_program_config)
|
std::make_pair(AS_PROGRAM, &m_program_config),
|
||||||
|
std::make_pair(AS_IO, &m_io_config)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,8 +214,8 @@ device_memory_interface::space_config_vector jaguar_cpu_device::memory_space_con
|
|||||||
void jaguar_cpu_device::update_register_banks()
|
void jaguar_cpu_device::update_register_banks()
|
||||||
{
|
{
|
||||||
/* pick the bank */
|
/* pick the bank */
|
||||||
u32 bank = FLAGS & RPAGEFLAG;
|
u32 bank = m_flags & RPAGEFLAG;
|
||||||
if (FLAGS & IFLAG) bank = 0;
|
if (m_imask == true) bank = 0;
|
||||||
|
|
||||||
/* do we need to swap? */
|
/* do we need to swap? */
|
||||||
if ((bank == 0 && m_b0 != m_r) || (bank != 0 && m_b1 != m_r))
|
if ((bank == 0 && m_b0 != m_r) || (bank != 0 && m_b1 != m_r))
|
||||||
@ -237,51 +255,43 @@ void jaguar_cpu_device::check_irqs()
|
|||||||
int which = 0;
|
int which = 0;
|
||||||
|
|
||||||
/* if the IMASK is set, bail */
|
/* if the IMASK is set, bail */
|
||||||
if (FLAGS & IFLAG)
|
if (m_imask == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* get the active interrupt bits */
|
u8 latch = m_int_latch;
|
||||||
u8 bits = (m_ctrl[G_CTRL] >> 6) & 0x1f;
|
u8 mask = m_int_mask;
|
||||||
bits |= (m_ctrl[G_CTRL] >> 10) & 0x20;
|
|
||||||
|
|
||||||
/* get the interrupt mask */
|
|
||||||
u8 mask = (FLAGS >> 4) & 0x1f;
|
|
||||||
mask |= (FLAGS >> 11) & 0x20;
|
|
||||||
|
|
||||||
/* bail if nothing is available */
|
/* bail if nothing is available */
|
||||||
bits &= mask;
|
latch &= mask;
|
||||||
if (bits == 0)
|
if (latch == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* determine which interrupt */
|
/* determine which interrupt */
|
||||||
if (bits & 0x01) which = 0;
|
for (int i = 0; i < 6; i++)
|
||||||
if (bits & 0x02) which = 1;
|
if (latch & (1 << i))
|
||||||
if (bits & 0x04) which = 2;
|
which = i;
|
||||||
if (bits & 0x08) which = 3;
|
|
||||||
if (bits & 0x10) which = 4;
|
|
||||||
if (bits & 0x20) which = 5;
|
|
||||||
|
|
||||||
/* set the interrupt flag */
|
/* set the interrupt flag */
|
||||||
FLAGS |= IFLAG;
|
m_imask = true;
|
||||||
update_register_banks();
|
update_register_banks();
|
||||||
|
|
||||||
/* push the PC-2 on the stack */
|
/* push the m_pc-2 on the stack */
|
||||||
m_r[31] -= 4;
|
m_r[31] -= 4;
|
||||||
WRITELONG(m_r[31], PC - 2);
|
WRITELONG(m_r[31], m_pc - 2);
|
||||||
|
|
||||||
/* dispatch */
|
/* dispatch */
|
||||||
PC = (m_isdsp) ? 0xf1b000 : 0xf03000;
|
m_pc = m_internal_ram_start;
|
||||||
PC += which * 0x10;
|
m_pc += which * 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void jaguar_cpu_device::execute_set_input(int irqline, int state)
|
void jaguar_cpu_device::execute_set_input(int irqline, int state)
|
||||||
{
|
{
|
||||||
const u32 mask = (irqline < 5) ? (0x40 << irqline) : 0x10000;
|
const u32 mask = (1 << irqline);
|
||||||
m_ctrl[G_CTRL] &= ~mask;
|
m_int_latch &= ~mask;
|
||||||
if (state != CLEAR_LINE)
|
if (state != CLEAR_LINE)
|
||||||
{
|
{
|
||||||
m_ctrl[G_CTRL] |= mask;
|
m_int_latch |= mask;
|
||||||
check_irqs();
|
check_irqs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,14 +356,29 @@ void jaguar_cpu_device::device_start()
|
|||||||
init_tables();
|
init_tables();
|
||||||
|
|
||||||
m_program = &space(AS_PROGRAM);
|
m_program = &space(AS_PROGRAM);
|
||||||
|
m_io = &space(AS_IO);
|
||||||
m_cache = m_program->cache<2, 0, ENDIANNESS_BIG>();
|
m_cache = m_program->cache<2, 0, ENDIANNESS_BIG>();
|
||||||
m_cpu_interrupt.resolve_safe();
|
m_cpu_interrupt.resolve_safe();
|
||||||
|
|
||||||
save_item(NAME(m_r));
|
save_item(NAME(m_r));
|
||||||
save_item(NAME(m_a));
|
save_item(NAME(m_a));
|
||||||
save_item(NAME(m_ctrl));
|
|
||||||
save_item(NAME(m_ppc));
|
save_item(NAME(m_ppc));
|
||||||
|
save_item(NAME(m_go));
|
||||||
|
save_item(NAME(m_int_latch));
|
||||||
|
save_item(NAME(m_int_mask));
|
||||||
|
save_item(NAME(m_bus_hog));
|
||||||
|
save_item(NAME(m_flags));
|
||||||
|
save_item(NAME(m_imask));
|
||||||
|
save_item(NAME(m_div_remainder));
|
||||||
|
save_item(NAME(m_div_offset));
|
||||||
|
|
||||||
|
save_item(NAME(m_io_end));
|
||||||
|
save_item(NAME(m_io_pc));
|
||||||
|
save_item(NAME(m_io_status));
|
||||||
|
save_item(NAME(m_io_mtxc));
|
||||||
|
save_item(NAME(m_io_mtxa));
|
||||||
|
|
||||||
|
// TODO: data map
|
||||||
if (m_isdsp)
|
if (m_isdsp)
|
||||||
{
|
{
|
||||||
m_internal_ram_start = 0xf1b000;
|
m_internal_ram_start = 0xf1b000;
|
||||||
@ -367,13 +392,12 @@ void jaguar_cpu_device::device_start()
|
|||||||
|
|
||||||
std::fill(std::begin(m_r), std::end(m_r), 0);
|
std::fill(std::begin(m_r), std::end(m_r), 0);
|
||||||
std::fill(std::begin(m_a), std::end(m_a), 0);
|
std::fill(std::begin(m_a), std::end(m_a), 0);
|
||||||
std::fill(std::begin(m_ctrl), std::end(m_ctrl), 0);
|
|
||||||
m_ppc = 0;
|
m_ppc = 0;
|
||||||
m_accum = 0;
|
m_accum = 0;
|
||||||
m_bankswitch_icount = 0;
|
m_bankswitch_icount = 0;
|
||||||
|
|
||||||
state_add( JAGUAR_PC, "PC", PC).formatstr("%08X");
|
state_add( JAGUAR_PC, "PC", m_pc).formatstr("%08X");
|
||||||
state_add( JAGUAR_FLAGS, "FLAGS", FLAGS).formatstr("%08X");
|
state_add( JAGUAR_FLAGS, "FLAGS", m_flags).formatstr("%08X");
|
||||||
state_add( JAGUAR_R0, "R0", m_r[0]).formatstr("%08X");
|
state_add( JAGUAR_R0, "R0", m_r[0]).formatstr("%08X");
|
||||||
state_add( JAGUAR_R1, "R1", m_r[1]).formatstr("%08X");
|
state_add( JAGUAR_R1, "R1", m_r[1]).formatstr("%08X");
|
||||||
state_add( JAGUAR_R2, "R2", m_r[2]).formatstr("%08X");
|
state_add( JAGUAR_R2, "R2", m_r[2]).formatstr("%08X");
|
||||||
@ -407,9 +431,9 @@ void jaguar_cpu_device::device_start()
|
|||||||
state_add( JAGUAR_R30, "R30", m_r[30]).formatstr("%08X");
|
state_add( JAGUAR_R30, "R30", m_r[30]).formatstr("%08X");
|
||||||
state_add( JAGUAR_R31, "R31", m_r[31]).formatstr("%08X");
|
state_add( JAGUAR_R31, "R31", m_r[31]).formatstr("%08X");
|
||||||
|
|
||||||
state_add( STATE_GENPC, "GENPC", PC).noshow();
|
state_add( STATE_GENPC, "GENPC", m_pc).noshow();
|
||||||
state_add( STATE_GENPCBASE, "CURPC", m_ppc).noshow();
|
state_add( STATE_GENPCBASE, "CURPC", m_ppc).noshow();
|
||||||
state_add( STATE_GENFLAGS, "GENFLAGS", FLAGS).formatstr("%11s").noshow();
|
state_add( STATE_GENFLAGS, "GENFLAGS", m_flags).formatstr("%11s").noshow();
|
||||||
|
|
||||||
set_icountptr(m_icount);
|
set_icountptr(m_icount);
|
||||||
}
|
}
|
||||||
@ -421,17 +445,17 @@ void jaguar_cpu_device::state_string_export(const device_state_entry &entry, std
|
|||||||
{
|
{
|
||||||
case STATE_GENFLAGS:
|
case STATE_GENFLAGS:
|
||||||
str = string_format("%c%c%c%c%c%c%c%c%c%c%c",
|
str = string_format("%c%c%c%c%c%c%c%c%c%c%c",
|
||||||
FLAGS & 0x8000 ? 'D':'.',
|
m_flags & 0x8000 ? 'D':'.',
|
||||||
FLAGS & 0x4000 ? 'A':'.',
|
m_flags & 0x4000 ? 'A':'.',
|
||||||
FLAGS & 0x0100 ? '4':'.',
|
m_flags & 0x0100 ? '4':'.',
|
||||||
FLAGS & 0x0080 ? '3':'.',
|
m_flags & 0x0080 ? '3':'.',
|
||||||
FLAGS & 0x0040 ? '2':'.',
|
m_flags & 0x0040 ? '2':'.',
|
||||||
FLAGS & 0x0020 ? '1':'.',
|
m_flags & 0x0020 ? '1':'.',
|
||||||
FLAGS & 0x0010 ? '0':'.',
|
m_flags & 0x0010 ? '0':'.',
|
||||||
FLAGS & 0x0008 ? 'I':'.',
|
m_imask == true ? 'I':'.',
|
||||||
FLAGS & 0x0004 ? 'N':'.',
|
m_flags & 0x0004 ? 'N':'.',
|
||||||
FLAGS & 0x0002 ? 'C':'.',
|
m_flags & 0x0002 ? 'C':'.',
|
||||||
FLAGS & 0x0001 ? 'Z':'.');
|
m_flags & 0x0001 ? 'Z':'.');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,6 +465,7 @@ void jaguar_cpu_device::device_reset()
|
|||||||
{
|
{
|
||||||
m_b0 = m_r;
|
m_b0 = m_r;
|
||||||
m_b1 = m_a;
|
m_b1 = m_a;
|
||||||
|
m_modulo = 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -464,7 +489,7 @@ jaguar_cpu_device::~jaguar_cpu_device()
|
|||||||
void jaguargpu_cpu_device::execute_run()
|
void jaguargpu_cpu_device::execute_run()
|
||||||
{
|
{
|
||||||
/* if we're halted, we shouldn't be here */
|
/* if we're halted, we shouldn't be here */
|
||||||
if (!(m_ctrl[G_CTRL] & 1))
|
if (m_go == false)
|
||||||
{
|
{
|
||||||
//device->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
//device->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||||
m_icount = 0;
|
m_icount = 0;
|
||||||
@ -481,13 +506,13 @@ void jaguargpu_cpu_device::execute_run()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* debugging */
|
/* debugging */
|
||||||
//if (PC < 0xf03000 || PC > 0xf04000) { fatalerror("GPU: PC = %06X (ppc = %06X)\n", PC, m_ppc); }
|
//if (m_pc < 0xf03000 || m_pc > 0xf04000) { fatalerror("GPU: m_pc = %06X (ppc = %06X)\n", m_pc, m_ppc); }
|
||||||
m_ppc = PC;
|
m_ppc = m_pc;
|
||||||
debugger_instruction_hook(PC);
|
debugger_instruction_hook(m_pc);
|
||||||
|
|
||||||
/* instruction fetch */
|
/* instruction fetch */
|
||||||
const u16 op = ROPCODE(PC);
|
const u16 op = ROPCODE(m_pc);
|
||||||
PC += 2;
|
m_pc += 2;
|
||||||
|
|
||||||
/* parse the instruction */
|
/* parse the instruction */
|
||||||
(this->*gpu_op_table[op >> 10])(op);
|
(this->*gpu_op_table[op >> 10])(op);
|
||||||
@ -499,7 +524,7 @@ void jaguargpu_cpu_device::execute_run()
|
|||||||
void jaguardsp_cpu_device::execute_run()
|
void jaguardsp_cpu_device::execute_run()
|
||||||
{
|
{
|
||||||
/* if we're halted, we shouldn't be here */
|
/* if we're halted, we shouldn't be here */
|
||||||
if (!(m_ctrl[G_CTRL] & 1))
|
if (m_go == false)
|
||||||
{
|
{
|
||||||
//device->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
//device->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||||
m_icount = 0;
|
m_icount = 0;
|
||||||
@ -516,13 +541,13 @@ void jaguardsp_cpu_device::execute_run()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* debugging */
|
/* debugging */
|
||||||
//if (PC < 0xf1b000 || PC > 0xf1d000) { fatalerror(stderr, "DSP: PC = %06X\n", PC); }
|
//if (m_pc < 0xf1b000 || m_pc > 0xf1d000) { fatalerror(stderr, "DSP: m_pc = %06X\n", m_pc); }
|
||||||
m_ppc = PC;
|
m_ppc = m_pc;
|
||||||
debugger_instruction_hook(PC);
|
debugger_instruction_hook(m_pc);
|
||||||
|
|
||||||
/* instruction fetch */
|
/* instruction fetch */
|
||||||
const u16 op = ROPCODE(PC);
|
const u16 op = ROPCODE(m_pc);
|
||||||
PC += 2;
|
m_pc += 2;
|
||||||
|
|
||||||
/* parse the instruction */
|
/* parse the instruction */
|
||||||
(this->*dsp_op_table[op >> 10])(op);
|
(this->*dsp_op_table[op >> 10])(op);
|
||||||
@ -544,7 +569,7 @@ void jaguar_cpu_device::abs_rn(u16 op)
|
|||||||
if (res & 0x80000000)
|
if (res & 0x80000000)
|
||||||
{
|
{
|
||||||
m_r[dreg] = res = -res;
|
m_r[dreg] = res = -res;
|
||||||
FLAGS |= CFLAG;
|
m_flags |= CFLAG;
|
||||||
}
|
}
|
||||||
SET_Z(res);
|
SET_Z(res);
|
||||||
}
|
}
|
||||||
@ -564,7 +589,7 @@ void jaguar_cpu_device::addc_rn_rn(u16 op)
|
|||||||
const u8 dreg = op & 31;
|
const u8 dreg = op & 31;
|
||||||
const u32 r1 = m_r[(op >> 5) & 31];
|
const u32 r1 = m_r[(op >> 5) & 31];
|
||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
u32 c = ((FLAGS >> 1) & 1);
|
u32 c = ((m_flags >> 1) & 1);
|
||||||
const u32 res = r2 + r1 + c;
|
const u32 res = r2 + r1 + c;
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZNC_ADD(r2, r1 + c, res);
|
CLR_ZNC(); SET_ZNC_ADD(r2, r1 + c, res);
|
||||||
@ -586,7 +611,7 @@ void jaguar_cpu_device::addqmod_n_rn(u16 op) /* DSP only */
|
|||||||
const u32 r1 = convert_zero[(op >> 5) & 31];
|
const u32 r1 = convert_zero[(op >> 5) & 31];
|
||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
u32 res = r2 + r1;
|
u32 res = r2 + r1;
|
||||||
res = (res & ~m_ctrl[D_MOD]) | (r2 & ~m_ctrl[D_MOD]);
|
res = (res & ~m_modulo) | (r2 & m_modulo);
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZNC_ADD(r2, r1, res);
|
CLR_ZNC(); SET_ZNC_ADD(r2, r1, res);
|
||||||
}
|
}
|
||||||
@ -634,7 +659,7 @@ void jaguar_cpu_device::btst_n_rn(u16 op)
|
|||||||
{
|
{
|
||||||
const u32 r1 = (op >> 5) & 31;
|
const u32 r1 = (op >> 5) & 31;
|
||||||
const u32 r2 = m_r[op & 31];
|
const u32 r2 = m_r[op & 31];
|
||||||
CLR_Z(); FLAGS |= (~r2 >> r1) & 1;
|
CLR_Z(); m_flags |= (~r2 >> r1) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::cmp_rn_rn(u16 op)
|
void jaguar_cpu_device::cmp_rn_rn(u16 op)
|
||||||
@ -660,19 +685,23 @@ void jaguar_cpu_device::div_rn_rn(u16 op)
|
|||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
if (r1)
|
if (r1)
|
||||||
{
|
{
|
||||||
if (m_ctrl[D_DIVCTRL] & 1)
|
if (m_div_offset & 1)
|
||||||
{
|
{
|
||||||
m_r[dreg] = ((u64)r2 << 16) / r1;
|
m_r[dreg] = ((u64)r2 << 16) / r1;
|
||||||
m_ctrl[D_REMAINDER] = ((u64)r2 << 16) % r1;
|
m_div_remainder = ((u64)r2 << 16) % r1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_r[dreg] = r2 / r1;
|
m_r[dreg] = r2 / r1;
|
||||||
m_ctrl[D_REMAINDER] = r2 % r1;
|
m_div_remainder = r2 % r1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// TODO: exact values for divide by zero
|
||||||
m_r[dreg] = 0xffffffff;
|
m_r[dreg] = 0xffffffff;
|
||||||
|
m_div_remainder = 0xffffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::illegal(u16 op)
|
void jaguar_cpu_device::illegal(u16 op)
|
||||||
@ -684,6 +713,7 @@ void jaguar_cpu_device::imacn_rn_rn(u16 op)
|
|||||||
const u32 r1 = m_r[(op >> 5) & 31];
|
const u32 r1 = m_r[(op >> 5) & 31];
|
||||||
const u32 r2 = m_r[op & 31];
|
const u32 r2 = m_r[op & 31];
|
||||||
m_accum += (s64)((int16_t)r1 * (int16_t)r2);
|
m_accum += (s64)((int16_t)r1 * (int16_t)r2);
|
||||||
|
// TODO: what's really "unexpected"?
|
||||||
logerror("Unexpected IMACN instruction!\n");
|
logerror("Unexpected IMACN instruction!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,18 +736,18 @@ void jaguar_cpu_device::imultn_rn_rn(u16 op)
|
|||||||
m_accum = (s32)res;
|
m_accum = (s32)res;
|
||||||
CLR_ZN(); SET_ZN(res);
|
CLR_ZN(); SET_ZN(res);
|
||||||
|
|
||||||
op = ROPCODE(PC);
|
op = ROPCODE(m_pc);
|
||||||
while ((op >> 10) == 20)
|
while ((op >> 10) == 20)
|
||||||
{
|
{
|
||||||
r1 = m_r[(op >> 5) & 31];
|
r1 = m_r[(op >> 5) & 31];
|
||||||
r2 = m_r[op & 31];
|
r2 = m_r[op & 31];
|
||||||
m_accum += (s64)((int16_t)r1 * (int16_t)r2);
|
m_accum += (s64)((int16_t)r1 * (int16_t)r2);
|
||||||
PC += 2;
|
m_pc += 2;
|
||||||
op = ROPCODE(PC);
|
op = ROPCODE(m_pc);
|
||||||
}
|
}
|
||||||
if ((op >> 10) == 19)
|
if ((op >> 10) == 19)
|
||||||
{
|
{
|
||||||
PC += 2;
|
m_pc += 2;
|
||||||
m_r[op & 31] = (u32)m_accum;
|
m_r[op & 31] = (u32)m_accum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -727,10 +757,10 @@ void jaguar_cpu_device::jr_cc_n(u16 op)
|
|||||||
if (CONDITION(op & 31))
|
if (CONDITION(op & 31))
|
||||||
{
|
{
|
||||||
const s32 r1 = (s8)((op >> 2) & 0xf8) >> 2;
|
const s32 r1 = (s8)((op >> 2) & 0xf8) >> 2;
|
||||||
const u32 newpc = PC + r1;
|
const u32 newpc = m_pc + r1;
|
||||||
debugger_instruction_hook(PC);
|
debugger_instruction_hook(m_pc);
|
||||||
op = ROPCODE(PC);
|
op = ROPCODE(m_pc);
|
||||||
PC = newpc;
|
m_pc = newpc;
|
||||||
(this->*m_table[op >> 10])(op);
|
(this->*m_table[op >> 10])(op);
|
||||||
|
|
||||||
m_icount -= 3; /* 3 wait states guaranteed */
|
m_icount -= 3; /* 3 wait states guaranteed */
|
||||||
@ -745,9 +775,9 @@ void jaguar_cpu_device::jump_cc_rn(u16 op)
|
|||||||
|
|
||||||
/* special kludge for risky code in the cojag DSP interrupt handlers */
|
/* special kludge for risky code in the cojag DSP interrupt handlers */
|
||||||
const u32 newpc = (m_icount == m_bankswitch_icount) ? m_a[reg] : m_r[reg];
|
const u32 newpc = (m_icount == m_bankswitch_icount) ? m_a[reg] : m_r[reg];
|
||||||
debugger_instruction_hook(PC);
|
debugger_instruction_hook(m_pc);
|
||||||
op = ROPCODE(PC);
|
op = ROPCODE(m_pc);
|
||||||
PC = newpc;
|
m_pc = newpc;
|
||||||
(this->*m_table[op >> 10])(op);
|
(this->*m_table[op >> 10])(op);
|
||||||
|
|
||||||
m_icount -= 3; /* 3 wait states guaranteed */
|
m_icount -= 3; /* 3 wait states guaranteed */
|
||||||
@ -819,7 +849,7 @@ void jaguar_cpu_device::loadp_rn_rn(u16 op) /* GPU only */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_ctrl[G_HIDATA] = READLONG(r1);
|
m_hidata = READLONG(r1);
|
||||||
m_r[op & 31] = READLONG(r1+4);
|
m_r[op & 31] = READLONG(r1+4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -835,13 +865,13 @@ void jaguar_cpu_device::mirror_rn(u16 op) /* DSP only */
|
|||||||
|
|
||||||
void jaguar_cpu_device::mmult_rn_rn(u16 op)
|
void jaguar_cpu_device::mmult_rn_rn(u16 op)
|
||||||
{
|
{
|
||||||
const u8 count = m_ctrl[G_MTXC] & 15;
|
const u8 count = m_mwidth;
|
||||||
const u8 sreg = (op >> 5) & 31;
|
const u8 sreg = (op >> 5) & 31;
|
||||||
const u8 dreg = op & 31;
|
const u8 dreg = op & 31;
|
||||||
u32 addr = m_ctrl[G_MTXA];
|
u32 addr = m_mtxaddr;
|
||||||
s64 accum = 0;
|
s64 accum = 0;
|
||||||
|
|
||||||
if (!(m_ctrl[G_MTXC] & 0x10))
|
if (m_maddw == false)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
@ -879,8 +909,8 @@ void jaguar_cpu_device::movefa_rn_rn(u16 op)
|
|||||||
|
|
||||||
void jaguar_cpu_device::movei_n_rn(u16 op)
|
void jaguar_cpu_device::movei_n_rn(u16 op)
|
||||||
{
|
{
|
||||||
const u32 res = ROPCODE(PC) | (ROPCODE(PC + 2) << 16);
|
const u32 res = ROPCODE(m_pc) | (ROPCODE(m_pc + 2) << 16);
|
||||||
PC += 4;
|
m_pc += 4;
|
||||||
m_r[op & 31] = res;
|
m_r[op & 31] = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,7 +1017,7 @@ void jaguar_cpu_device::ror_rn_rn(u16 op)
|
|||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
const u32 res = (r2 >> r1) | (r2 << (32 - r1));
|
const u32 res = (r2 >> r1) | (r2 << (32 - r1));
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZN(res); FLAGS |= (r2 >> 30) & 2;
|
CLR_ZNC(); SET_ZN(res); m_flags |= (r2 >> 30) & 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::rorq_n_rn(u16 op)
|
void jaguar_cpu_device::rorq_n_rn(u16 op)
|
||||||
@ -997,7 +1027,7 @@ void jaguar_cpu_device::rorq_n_rn(u16 op)
|
|||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
const u32 res = (r2 >> r1) | (r2 << (32 - r1));
|
const u32 res = (r2 >> r1) | (r2 << (32 - r1));
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZN(res); FLAGS |= (r2 >> 30) & 2;
|
CLR_ZNC(); SET_ZN(res); m_flags |= (r2 >> 30) & 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::sat8_rn(u16 op) /* GPU only */
|
void jaguar_cpu_device::sat8_rn(u16 op) /* GPU only */
|
||||||
@ -1057,12 +1087,12 @@ void jaguar_cpu_device::sh_rn_rn(u16 op)
|
|||||||
if (r1 < 0)
|
if (r1 < 0)
|
||||||
{
|
{
|
||||||
res = (r1 <= -32) ? 0 : (r2 << -r1);
|
res = (r1 <= -32) ? 0 : (r2 << -r1);
|
||||||
FLAGS |= (r2 >> 30) & 2;
|
m_flags |= (r2 >> 30) & 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = (r1 >= 32) ? 0 : (r2 >> r1);
|
res = (r1 >= 32) ? 0 : (r2 >> r1);
|
||||||
FLAGS |= (r2 << 1) & 2;
|
m_flags |= (r2 << 1) & 2;
|
||||||
}
|
}
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
SET_ZN(res);
|
SET_ZN(res);
|
||||||
@ -1079,12 +1109,12 @@ void jaguar_cpu_device::sha_rn_rn(u16 op)
|
|||||||
if (r1 < 0)
|
if (r1 < 0)
|
||||||
{
|
{
|
||||||
res = (r1 <= -32) ? 0 : (r2 << -r1);
|
res = (r1 <= -32) ? 0 : (r2 << -r1);
|
||||||
FLAGS |= (r2 >> 30) & 2;
|
m_flags |= (r2 >> 30) & 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = (r1 >= 32) ? ((s32)r2 >> 31) : ((s32)r2 >> r1);
|
res = (r1 >= 32) ? ((s32)r2 >> 31) : ((s32)r2 >> r1);
|
||||||
FLAGS |= (r2 << 1) & 2;
|
m_flags |= (r2 << 1) & 2;
|
||||||
}
|
}
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
SET_ZN(res);
|
SET_ZN(res);
|
||||||
@ -1097,7 +1127,7 @@ void jaguar_cpu_device::sharq_n_rn(u16 op)
|
|||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
const u32 res = (s32)r2 >> r1;
|
const u32 res = (s32)r2 >> r1;
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZN(res); FLAGS |= (r2 << 1) & 2;
|
CLR_ZNC(); SET_ZN(res); m_flags |= (r2 << 1) & 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::shlq_n_rn(u16 op)
|
void jaguar_cpu_device::shlq_n_rn(u16 op)
|
||||||
@ -1107,7 +1137,7 @@ void jaguar_cpu_device::shlq_n_rn(u16 op)
|
|||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
const u32 res = r2 << (32 - r1);
|
const u32 res = r2 << (32 - r1);
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZN(res); FLAGS |= (r2 >> 30) & 2;
|
CLR_ZNC(); SET_ZN(res); m_flags |= (r2 >> 30) & 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::shrq_n_rn(u16 op)
|
void jaguar_cpu_device::shrq_n_rn(u16 op)
|
||||||
@ -1117,7 +1147,7 @@ void jaguar_cpu_device::shrq_n_rn(u16 op)
|
|||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
const u32 res = r2 >> r1;
|
const u32 res = r2 >> r1;
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZN(res); FLAGS |= (r2 << 1) & 2;
|
CLR_ZNC(); SET_ZN(res); m_flags |= (r2 << 1) & 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_cpu_device::store_rn_rn(u16 op)
|
void jaguar_cpu_device::store_rn_rn(u16 op)
|
||||||
@ -1185,7 +1215,7 @@ void jaguar_cpu_device::storep_rn_rn(u16 op) /* GPU only */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WRITELONG(r1, m_ctrl[G_HIDATA]);
|
WRITELONG(r1, m_hidata);
|
||||||
WRITELONG(r1+4, m_r[op & 31]);
|
WRITELONG(r1+4, m_r[op & 31]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1205,7 +1235,7 @@ void jaguar_cpu_device::subc_rn_rn(u16 op)
|
|||||||
const u8 dreg = op & 31;
|
const u8 dreg = op & 31;
|
||||||
const u32 r1 = m_r[(op >> 5) & 31];
|
const u32 r1 = m_r[(op >> 5) & 31];
|
||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
u32 c = ((FLAGS >> 1) & 1);
|
u32 c = ((m_flags >> 1) & 1);
|
||||||
const u32 res = r2 - r1 - c;
|
const u32 res = r2 - r1 - c;
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZNC_SUB(r2, r1 + c, res);
|
CLR_ZNC(); SET_ZNC_SUB(r2, r1 + c, res);
|
||||||
@ -1227,7 +1257,7 @@ void jaguar_cpu_device::subqmod_n_rn(u16 op) /* DSP only */
|
|||||||
const u32 r1 = convert_zero[(op >> 5) & 31];
|
const u32 r1 = convert_zero[(op >> 5) & 31];
|
||||||
const u32 r2 = m_r[dreg];
|
const u32 r2 = m_r[dreg];
|
||||||
u32 res = r2 - r1;
|
u32 res = r2 - r1;
|
||||||
res = (res & ~m_ctrl[D_MOD]) | (r2 & ~m_ctrl[D_MOD]);
|
res = (res & ~m_modulo) | (r2 & m_modulo);
|
||||||
m_r[dreg] = res;
|
m_r[dreg] = res;
|
||||||
CLR_ZNC(); SET_ZNC_SUB(r2, r1, res);
|
CLR_ZNC(); SET_ZNC_SUB(r2, r1, res);
|
||||||
}
|
}
|
||||||
@ -1257,191 +1287,212 @@ void jaguar_cpu_device::xor_rn_rn(u16 op)
|
|||||||
I/O HANDLING
|
I/O HANDLING
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
u32 jaguargpu_cpu_device::ctrl_r(offs_t offset)
|
void jaguar_cpu_device::io_common_map(address_map &map)
|
||||||
{
|
{
|
||||||
if (LOG_GPU_IO) logerror("GPU read register @ F021%02X\n", offset * 4);
|
map(0x00, 0x03).rw(FUNC(jaguar_cpu_device::flags_r), FUNC(jaguar_cpu_device::flags_w));
|
||||||
|
map(0x04, 0x07).w(FUNC(jaguar_cpu_device::matrix_control_w));
|
||||||
u32 res = m_ctrl[offset];
|
map(0x08, 0x0b).w(FUNC(jaguar_cpu_device::matrix_address_w));
|
||||||
if (offset == G_CTRL)
|
// map(0x0c, 0x0f) endian
|
||||||
res |= (m_version & 0xf) << 12;
|
map(0x10, 0x13).w(FUNC(jaguar_cpu_device::pc_w));
|
||||||
|
map(0x14, 0x17).rw(FUNC(jaguar_cpu_device::status_r), FUNC(jaguar_cpu_device::control_w));
|
||||||
return res;
|
// map(0x18, 0x1b) implementation specific
|
||||||
|
map(0x1c, 0x1f).rw(FUNC(jaguar_cpu_device::div_remainder_r), FUNC(jaguar_cpu_device::div_control_w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $f02100
|
||||||
void jaguargpu_cpu_device::ctrl_w(offs_t offset, u32 data, u32 mem_mask)
|
void jaguargpu_cpu_device::io_map(address_map &map)
|
||||||
{
|
{
|
||||||
if (LOG_GPU_IO && offset != G_HIDATA)
|
jaguar_cpu_device::io_common_map(map);
|
||||||
logerror("GPU write register @ F021%02X = %08X\n", offset * 4, data);
|
map(0x0c, 0x0f).w(FUNC(jaguargpu_cpu_device::end_w));
|
||||||
|
map(0x18, 0x1b).rw(FUNC(jaguargpu_cpu_device::hidata_r), FUNC(jaguargpu_cpu_device::hidata_w));
|
||||||
|
}
|
||||||
|
|
||||||
/* remember the old and set the new */
|
// $f0a100
|
||||||
const u32 oldval = m_ctrl[offset];
|
void jaguardsp_cpu_device::io_map(address_map &map)
|
||||||
u32 newval = oldval;
|
|
||||||
COMBINE_DATA(&newval);
|
|
||||||
|
|
||||||
/* handle the various registers */
|
|
||||||
switch (offset)
|
|
||||||
{
|
{
|
||||||
case G_FLAGS:
|
jaguar_cpu_device::io_common_map(map);
|
||||||
|
map(0x0c, 0x0f).w(FUNC(jaguardsp_cpu_device::dsp_end_w));
|
||||||
|
map(0x18, 0x1b).w(FUNC(jaguardsp_cpu_device::modulo_w));
|
||||||
|
map(0x20, 0x23).r(FUNC(jaguardsp_cpu_device::high_accum_r));
|
||||||
|
}
|
||||||
|
|
||||||
/* combine the data properly */
|
READ32_MEMBER(jaguar_cpu_device::flags_r)
|
||||||
m_ctrl[offset] = newval & (ZFLAG | CFLAG | NFLAG | EINT04FLAGS | RPAGEFLAG);
|
{
|
||||||
if (newval & IFLAG)
|
return (m_flags & 0x1c1f7) | (m_imask << 3);
|
||||||
m_ctrl[offset] |= oldval & IFLAG;
|
}
|
||||||
|
|
||||||
/* clear interrupts */
|
WRITE32_MEMBER(jaguar_cpu_device::flags_w)
|
||||||
m_ctrl[G_CTRL] &= ~((newval & CINT04FLAGS) >> 3);
|
{
|
||||||
|
COMBINE_DATA(&m_flags);
|
||||||
|
// clear imask only on bit 3 clear (1 has no effect)
|
||||||
|
if ((m_flags & 0x08) == 0)
|
||||||
|
m_imask = false;
|
||||||
|
|
||||||
|
// update int latch & mask
|
||||||
|
m_int_mask = (m_flags >> 4) & 0x1f;
|
||||||
|
m_int_latch &= ~((m_flags >> 9) & 0x1f);
|
||||||
|
|
||||||
|
// TODO: move to specific handler
|
||||||
|
if (m_isdsp)
|
||||||
|
{
|
||||||
|
m_int_mask |= (BIT(m_flags, 16) << 5);
|
||||||
|
m_int_latch &= ~(BIT(m_flags, 17) << 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: DMAEN (bit 15)
|
||||||
|
|
||||||
/* determine which register bank should be active */
|
|
||||||
update_register_banks();
|
update_register_banks();
|
||||||
|
|
||||||
/* update IRQs */
|
|
||||||
check_irqs();
|
check_irqs();
|
||||||
break;
|
}
|
||||||
|
|
||||||
case G_MTXC:
|
WRITE32_MEMBER(jaguar_cpu_device::matrix_control_w)
|
||||||
case G_MTXA:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case G_END:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
if ((newval & 7) != 7)
|
|
||||||
logerror("GPU to set to little-endian!\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case G_PC:
|
|
||||||
PC = newval & 0xffffff;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case G_CTRL:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
if ((oldval ^ newval) & 0x01)
|
|
||||||
{
|
{
|
||||||
set_input_line(INPUT_LINE_HALT, (newval & 1) ? CLEAR_LINE : ASSERT_LINE);
|
COMBINE_DATA(&m_io_mtxc);
|
||||||
|
m_mwidth = m_io_mtxc & 0xf;
|
||||||
|
m_maddw = BIT(m_io_mtxc, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jaguar_cpu_device::matrix_address_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_io_mtxa);
|
||||||
|
// matrix can be long word address only, and only read from internal RAM
|
||||||
|
m_mtxaddr = m_internal_ram_start | (m_io_mtxa & 0xffc);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jaguar_cpu_device::pc_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_io_pc);
|
||||||
|
if (m_go == false)
|
||||||
|
m_pc = m_io_pc & 0xffffff;
|
||||||
|
else
|
||||||
|
throw emu_fatalerror("%s: inflight PC write %08x", this->tag(), m_pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data Organization Register
|
||||||
|
* Note: The canonical way to set this up from 68k is $00070007,
|
||||||
|
* so that Power-On endianness doesn't matter. 1=Big Endian
|
||||||
|
* ---- -x-- Instruction endianness
|
||||||
|
* ---- --x- Pixel endianness (GPU only)
|
||||||
|
* ---- ---x I/O endianness
|
||||||
|
*/
|
||||||
|
// TODO: just log if anything farts for now, change to bit struct once we have something to test out
|
||||||
|
WRITE32_MEMBER(jaguar_cpu_device::end_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_io_end);
|
||||||
|
// sburnout sets bit 1 == 0
|
||||||
|
if ((m_io_end & 0x7) != 0x7)
|
||||||
|
throw emu_fatalerror("%s: fatal endian setup %08x", this->tag(), m_io_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jaguardsp_cpu_device::dsp_end_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_io_end);
|
||||||
|
// wolfn3d writes a '0' to bit 1 (which is a NOP for DSP)
|
||||||
|
if ((m_io_end & 0x5) != 0x5)
|
||||||
|
throw emu_fatalerror("%s: fatal endian setup %08x", this->tag(), m_io_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control/Status Register
|
||||||
|
* - xxxx ---- ---- ---- chip version number
|
||||||
|
* - ---- x--- ---- ---- bus hog (increase self chip priority on bus)
|
||||||
|
* y ---- -xxx xx-- ---- interrupt latch (y is DSP specific) (r/o)
|
||||||
|
* - ---- ---- --0- ---- <unused>
|
||||||
|
* - ---- ---- ---x x--- single step regs
|
||||||
|
* - ---- ---- ---- -x-- GPUINT0 or DSPINT0
|
||||||
|
* - ---- ---- ---- --x- Host interrupt (w/o)
|
||||||
|
* - ---- ---- ---- ---x GPUGO or DSPGO flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
READ32_MEMBER(jaguar_cpu_device::status_r)
|
||||||
|
{
|
||||||
|
u32 result = ((m_version & 0xf)<<12) | (m_bus_hog<<11) | m_go;
|
||||||
|
result|= (m_int_latch & 0x1f) << 6;
|
||||||
|
// TODO: make it DSP specific
|
||||||
|
if (m_isdsp == true)
|
||||||
|
result|= (m_int_latch & 0x20) << 11;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(jaguar_cpu_device::go_w)
|
||||||
|
{
|
||||||
|
m_go = state;
|
||||||
|
set_input_line(INPUT_LINE_HALT, (m_go == true) ? CLEAR_LINE : ASSERT_LINE);
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
if (newval & 0x02)
|
|
||||||
|
WRITE32_MEMBER(jaguar_cpu_device::control_w)
|
||||||
{
|
{
|
||||||
|
COMBINE_DATA(&m_io_status);
|
||||||
|
bool new_go = BIT(m_io_status, 0);
|
||||||
|
if (new_go != m_go)
|
||||||
|
go_w(new_go);
|
||||||
|
|
||||||
|
if (BIT(m_io_status, 1))
|
||||||
m_cpu_interrupt(ASSERT_LINE);
|
m_cpu_interrupt(ASSERT_LINE);
|
||||||
m_ctrl[offset] &= ~0x02;
|
|
||||||
}
|
// TODO: following does nothing if set by itself, or acts as a trap?
|
||||||
if (newval & 0x04)
|
if (BIT(m_io_status, 2))
|
||||||
{
|
{
|
||||||
m_ctrl[G_CTRL] |= 1 << 6;
|
m_int_latch |= 1;
|
||||||
m_ctrl[offset] &= ~0x04;
|
|
||||||
check_irqs();
|
check_irqs();
|
||||||
}
|
}
|
||||||
if (newval & 0x18)
|
|
||||||
|
// TODO: single step handling
|
||||||
|
|
||||||
|
m_bus_hog = BIT(m_io_status, 11);
|
||||||
|
// TODO: protect/protectse uses this, why?
|
||||||
|
if (m_bus_hog == true)
|
||||||
|
logerror("%s: bus hog enabled\n", this->tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
READ32_MEMBER(jaguargpu_cpu_device::hidata_r)
|
||||||
{
|
{
|
||||||
logerror("GPU single stepping was enabled!\n");
|
return m_hidata;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case G_HIDATA:
|
|
||||||
case G_DIVCTRL:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jaguargpu_cpu_device::hidata_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_hidata);
|
||||||
|
}
|
||||||
|
|
||||||
|
READ32_MEMBER(jaguar_cpu_device::div_remainder_r)
|
||||||
|
{
|
||||||
|
// TODO: truly 32-bit?
|
||||||
|
return m_div_remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jaguar_cpu_device::div_control_w)
|
||||||
|
{
|
||||||
|
m_div_offset = BIT(data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jaguardsp_cpu_device::modulo_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_modulo);
|
||||||
|
}
|
||||||
|
|
||||||
|
READ32_MEMBER(jaguardsp_cpu_device::high_accum_r)
|
||||||
|
{
|
||||||
|
printf("%s: high 16-bit accumulator read\n", this->tag());
|
||||||
|
return (m_accum >> 32) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 jaguar_cpu_device::iobus_r(offs_t offset, u32 mem_mask)
|
||||||
|
{
|
||||||
|
return m_io->read_dword(offset*4, mem_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void jaguar_cpu_device::iobus_w(offs_t offset, u32 data, u32 mem_mask)
|
||||||
|
{
|
||||||
|
m_io->write_dword(offset*4, data, mem_mask);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
I/O HANDLING
|
DASM
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
u32 jaguardsp_cpu_device::ctrl_r(offs_t offset)
|
|
||||||
{
|
|
||||||
if (LOG_DSP_IO && offset != D_FLAGS)
|
|
||||||
logerror("DSP read register @ F1A1%02X\n", offset * 4);
|
|
||||||
|
|
||||||
/* switch to the target context */
|
|
||||||
u32 res = m_ctrl[offset];
|
|
||||||
if (offset == D_CTRL)
|
|
||||||
res |= (m_version & 0xf) << 12;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void jaguardsp_cpu_device::ctrl_w(offs_t offset, u32 data, u32 mem_mask)
|
|
||||||
{
|
|
||||||
if (LOG_DSP_IO && offset != D_FLAGS)
|
|
||||||
logerror("DSP write register @ F1A1%02X = %08X\n", offset * 4, data);
|
|
||||||
|
|
||||||
/* remember the old and set the new */
|
|
||||||
const u32 oldval = m_ctrl[offset];
|
|
||||||
u32 newval = oldval;
|
|
||||||
COMBINE_DATA(&newval);
|
|
||||||
|
|
||||||
/* handle the various registers */
|
|
||||||
switch (offset)
|
|
||||||
{
|
|
||||||
case D_FLAGS:
|
|
||||||
|
|
||||||
/* combine the data properly */
|
|
||||||
m_ctrl[offset] = newval & (ZFLAG | CFLAG | NFLAG | EINT04FLAGS | EINT5FLAG | RPAGEFLAG);
|
|
||||||
if (newval & IFLAG)
|
|
||||||
m_ctrl[offset] |= oldval & IFLAG;
|
|
||||||
|
|
||||||
/* clear interrupts */
|
|
||||||
m_ctrl[D_CTRL] &= ~((newval & CINT04FLAGS) >> 3);
|
|
||||||
m_ctrl[D_CTRL] &= ~((newval & CINT5FLAG) >> 1);
|
|
||||||
|
|
||||||
/* determine which register bank should be active */
|
|
||||||
update_register_banks();
|
|
||||||
|
|
||||||
/* update IRQs */
|
|
||||||
check_irqs();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D_MTXC:
|
|
||||||
case D_MTXA:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D_END:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
if ((newval & 7) != 7)
|
|
||||||
logerror("DSP to set to little-endian!\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D_PC:
|
|
||||||
PC = newval & 0xffffff;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D_CTRL:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
if ((oldval ^ newval) & 0x01)
|
|
||||||
{
|
|
||||||
set_input_line(INPUT_LINE_HALT, (newval & 1) ? CLEAR_LINE : ASSERT_LINE);
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
if (newval & 0x02)
|
|
||||||
{
|
|
||||||
m_cpu_interrupt(ASSERT_LINE);
|
|
||||||
m_ctrl[offset] &= ~0x02;
|
|
||||||
}
|
|
||||||
if (newval & 0x04)
|
|
||||||
{
|
|
||||||
m_ctrl[D_CTRL] |= 1 << 6;
|
|
||||||
m_ctrl[offset] &= ~0x04;
|
|
||||||
check_irqs();
|
|
||||||
}
|
|
||||||
if (newval & 0x18)
|
|
||||||
{
|
|
||||||
logerror("DSP single stepping was enabled!\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case D_MOD:
|
|
||||||
case D_DIVCTRL:
|
|
||||||
m_ctrl[offset] = newval;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<util::disasm_interface> jaguargpu_cpu_device::create_disassembler()
|
std::unique_ptr<util::disasm_interface> jaguargpu_cpu_device::create_disassembler()
|
||||||
{
|
{
|
||||||
return std::make_unique<jaguar_disassembler>(jaguar_disassembler::variant::GPU);
|
return std::make_unique<jaguar_disassembler>(jaguar_disassembler::variant::GPU);
|
||||||
|
@ -28,38 +28,6 @@ enum
|
|||||||
JAGUAR_R24,JAGUAR_R25,JAGUAR_R26,JAGUAR_R27,JAGUAR_R28,JAGUAR_R29,JAGUAR_R30,JAGUAR_R31
|
JAGUAR_R24,JAGUAR_R25,JAGUAR_R26,JAGUAR_R27,JAGUAR_R28,JAGUAR_R29,JAGUAR_R30,JAGUAR_R31
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
G_FLAGS = 0,
|
|
||||||
G_MTXC,
|
|
||||||
G_MTXA,
|
|
||||||
G_END,
|
|
||||||
G_PC,
|
|
||||||
G_CTRL,
|
|
||||||
G_HIDATA,
|
|
||||||
G_DIVCTRL,
|
|
||||||
G_DUMMY,
|
|
||||||
G_REMAINDER,
|
|
||||||
G_CTRLMAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
D_FLAGS = 0,
|
|
||||||
D_MTXC,
|
|
||||||
D_MTXA,
|
|
||||||
D_END,
|
|
||||||
D_PC,
|
|
||||||
D_CTRL,
|
|
||||||
D_MOD,
|
|
||||||
D_DIVCTRL,
|
|
||||||
D_MACHI,
|
|
||||||
D_REMAINDER,
|
|
||||||
D_CTRLMAX
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
INTERRUPT CONSTANTS
|
INTERRUPT CONSTANTS
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -90,11 +58,13 @@ public:
|
|||||||
// configuration helpers
|
// configuration helpers
|
||||||
auto irq() { return m_cpu_interrupt.bind(); }
|
auto irq() { return m_cpu_interrupt.bind(); }
|
||||||
|
|
||||||
virtual void ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0) = 0;
|
// TODO: add which device triggered the I/O
|
||||||
virtual u32 ctrl_r(offs_t offset) = 0;
|
void iobus_w(offs_t offset, u32 data, u32 mem_mask = ~0);
|
||||||
|
u32 iobus_r(offs_t offset, u32 mem_mask = ~0);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(go_w);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
jaguar_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 version, bool isdsp);
|
jaguar_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 version, bool isdsp, address_map_constructor io_map);
|
||||||
|
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
@ -113,6 +83,18 @@ protected:
|
|||||||
// device_state_interface overrides
|
// device_state_interface overrides
|
||||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||||
|
|
||||||
|
// I/Os (common)
|
||||||
|
DECLARE_READ32_MEMBER(flags_r);
|
||||||
|
DECLARE_WRITE32_MEMBER(flags_w);
|
||||||
|
DECLARE_WRITE32_MEMBER(matrix_control_w);
|
||||||
|
DECLARE_WRITE32_MEMBER(matrix_address_w);
|
||||||
|
DECLARE_WRITE32_MEMBER(end_w);
|
||||||
|
DECLARE_WRITE32_MEMBER(pc_w);
|
||||||
|
DECLARE_READ32_MEMBER(status_r);
|
||||||
|
DECLARE_WRITE32_MEMBER(control_w);
|
||||||
|
DECLARE_READ32_MEMBER(div_remainder_r);
|
||||||
|
DECLARE_WRITE32_MEMBER(div_control_w);
|
||||||
|
|
||||||
// defines
|
// defines
|
||||||
inline void CLR_Z();
|
inline void CLR_Z();
|
||||||
inline void CLR_ZN();
|
inline void CLR_ZN();
|
||||||
@ -138,6 +120,7 @@ protected:
|
|||||||
inline u16 ROPCODE(offs_t pc);
|
inline u16 ROPCODE(offs_t pc);
|
||||||
|
|
||||||
address_space_config m_program_config;
|
address_space_config m_program_config;
|
||||||
|
address_space_config m_io_config;
|
||||||
|
|
||||||
/* core registers */
|
/* core registers */
|
||||||
u32 m_r[32];
|
u32 m_r[32];
|
||||||
@ -146,7 +129,6 @@ protected:
|
|||||||
u32 * m_b1;
|
u32 * m_b1;
|
||||||
|
|
||||||
/* control registers */
|
/* control registers */
|
||||||
u32 m_ctrl[G_CTRLMAX];
|
|
||||||
u32 m_ppc;
|
u32 m_ppc;
|
||||||
u64 m_accum;
|
u64 m_accum;
|
||||||
|
|
||||||
@ -157,6 +139,7 @@ protected:
|
|||||||
int m_bankswitch_icount;
|
int m_bankswitch_icount;
|
||||||
devcb_write_line m_cpu_interrupt;
|
devcb_write_line m_cpu_interrupt;
|
||||||
address_space *m_program;
|
address_space *m_program;
|
||||||
|
address_space *m_io;
|
||||||
memory_access_cache<2, 0, ENDIANNESS_BIG> *m_cache;
|
memory_access_cache<2, 0, ENDIANNESS_BIG> *m_cache;
|
||||||
|
|
||||||
u32 m_internal_ram_start;
|
u32 m_internal_ram_start;
|
||||||
@ -164,8 +147,6 @@ protected:
|
|||||||
|
|
||||||
typedef void (jaguar_cpu_device::*op_func)(u16 op);
|
typedef void (jaguar_cpu_device::*op_func)(u16 op);
|
||||||
|
|
||||||
static const op_func gpu_op_table[64];
|
|
||||||
static const op_func dsp_op_table[64];
|
|
||||||
static const u32 convert_zero[32];
|
static const u32 convert_zero[32];
|
||||||
bool m_tables_referenced;
|
bool m_tables_referenced;
|
||||||
|
|
||||||
@ -179,7 +160,6 @@ protected:
|
|||||||
void add_rn_rn(u16 op);
|
void add_rn_rn(u16 op);
|
||||||
void addc_rn_rn(u16 op);
|
void addc_rn_rn(u16 op);
|
||||||
void addq_n_rn(u16 op);
|
void addq_n_rn(u16 op);
|
||||||
void addqmod_n_rn(u16 op); /* DSP only */
|
|
||||||
void addqt_n_rn(u16 op);
|
void addqt_n_rn(u16 op);
|
||||||
void and_rn_rn(u16 op);
|
void and_rn_rn(u16 op);
|
||||||
void bclr_n_rn(u16 op);
|
void bclr_n_rn(u16 op);
|
||||||
@ -201,8 +181,6 @@ protected:
|
|||||||
void load_r15rn_rn(u16 op);
|
void load_r15rn_rn(u16 op);
|
||||||
void loadb_rn_rn(u16 op);
|
void loadb_rn_rn(u16 op);
|
||||||
void loadw_rn_rn(u16 op);
|
void loadw_rn_rn(u16 op);
|
||||||
void loadp_rn_rn(u16 op); /* GPU only */
|
|
||||||
void mirror_rn(u16 op); /* DSP only */
|
|
||||||
void mmult_rn_rn(u16 op);
|
void mmult_rn_rn(u16 op);
|
||||||
void move_rn_rn(u16 op);
|
void move_rn_rn(u16 op);
|
||||||
void move_pc_rn(u16 op);
|
void move_pc_rn(u16 op);
|
||||||
@ -217,15 +195,10 @@ protected:
|
|||||||
void normi_rn_rn(u16 op);
|
void normi_rn_rn(u16 op);
|
||||||
void not_rn(u16 op);
|
void not_rn(u16 op);
|
||||||
void or_rn_rn(u16 op);
|
void or_rn_rn(u16 op);
|
||||||
void pack_rn(u16 op); /* GPU only */
|
|
||||||
void resmac_rn(u16 op);
|
void resmac_rn(u16 op);
|
||||||
void ror_rn_rn(u16 op);
|
void ror_rn_rn(u16 op);
|
||||||
void rorq_n_rn(u16 op);
|
void rorq_n_rn(u16 op);
|
||||||
void sat8_rn(u16 op); /* GPU only */
|
|
||||||
void sat16_rn(u16 op); /* GPU only */
|
|
||||||
void sat16s_rn(u16 op); /* DSP only */
|
|
||||||
void sat24_rn(u16 op); /* GPU only */
|
|
||||||
void sat32s_rn(u16 op); /* DSP only */
|
|
||||||
void sh_rn_rn(u16 op);
|
void sh_rn_rn(u16 op);
|
||||||
void sha_rn_rn(u16 op);
|
void sha_rn_rn(u16 op);
|
||||||
void sharq_n_rn(u16 op);
|
void sharq_n_rn(u16 op);
|
||||||
@ -238,16 +211,58 @@ protected:
|
|||||||
void store_rn_r15rn(u16 op);
|
void store_rn_r15rn(u16 op);
|
||||||
void storeb_rn_rn(u16 op);
|
void storeb_rn_rn(u16 op);
|
||||||
void storew_rn_rn(u16 op);
|
void storew_rn_rn(u16 op);
|
||||||
void storep_rn_rn(u16 op); /* GPU only */
|
|
||||||
void sub_rn_rn(u16 op);
|
void sub_rn_rn(u16 op);
|
||||||
void subc_rn_rn(u16 op);
|
void subc_rn_rn(u16 op);
|
||||||
void subq_n_rn(u16 op);
|
void subq_n_rn(u16 op);
|
||||||
void subqmod_n_rn(u16 op); /* DSP only */
|
|
||||||
void subqt_n_rn(u16 op);
|
void subqt_n_rn(u16 op);
|
||||||
void xor_rn_rn(u16 op);
|
void xor_rn_rn(u16 op);
|
||||||
|
// GPU only opcodes
|
||||||
|
void loadp_rn_rn(u16 op);
|
||||||
|
void pack_rn(u16 op);
|
||||||
|
void sat8_rn(u16 op);
|
||||||
|
void sat16_rn(u16 op);
|
||||||
|
void sat24_rn(u16 op);
|
||||||
|
void storep_rn_rn(u16 op);
|
||||||
|
// DSP only opcodes
|
||||||
|
void addqmod_n_rn(u16 op);
|
||||||
|
void mirror_rn(u16 op);
|
||||||
|
void sat16s_rn(u16 op);
|
||||||
|
void sat32s_rn(u16 op);
|
||||||
|
void subqmod_n_rn(u16 op);
|
||||||
|
|
||||||
void update_register_banks();
|
void update_register_banks();
|
||||||
void check_irqs();
|
void check_irqs();
|
||||||
void init_tables();
|
void init_tables();
|
||||||
|
|
||||||
|
// I/O internal regs
|
||||||
|
void io_common_map(address_map &map);
|
||||||
|
// TODO: the m_io* stubs are conventionally given for allowing a correct register setup from vanilla 68k.
|
||||||
|
// This is yet another reason about needing a bus device dispatcher for this system.
|
||||||
|
u32 m_io_end;
|
||||||
|
u32 m_io_pc;
|
||||||
|
u32 m_io_status;
|
||||||
|
u32 m_io_mtxc;
|
||||||
|
u32 m_io_mtxa;
|
||||||
|
|
||||||
|
u32 m_pc;
|
||||||
|
u32 m_flags;
|
||||||
|
bool m_imask;
|
||||||
|
bool m_maddw;
|
||||||
|
u8 m_mwidth;
|
||||||
|
u32 m_mtxaddr;
|
||||||
|
bool m_go;
|
||||||
|
u8 m_int_latch;
|
||||||
|
u8 m_int_mask;
|
||||||
|
bool m_bus_hog;
|
||||||
|
u32 m_div_remainder;
|
||||||
|
bool m_div_offset;
|
||||||
|
|
||||||
|
// GPU specific
|
||||||
|
u32 m_hidata;
|
||||||
|
static const op_func gpu_op_table[64];
|
||||||
|
// DSP specific
|
||||||
|
u32 m_modulo;
|
||||||
|
static const op_func dsp_op_table[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -257,12 +272,14 @@ public:
|
|||||||
// construction/destruction
|
// construction/destruction
|
||||||
jaguargpu_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
jaguargpu_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
void ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0) override;
|
void io_map(address_map &map);
|
||||||
u32 ctrl_r(offs_t offset) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void execute_run() override;
|
virtual void execute_run() override;
|
||||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||||
|
|
||||||
|
DECLARE_WRITE32_MEMBER(hidata_w);
|
||||||
|
DECLARE_READ32_MEMBER(hidata_r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -272,14 +289,16 @@ public:
|
|||||||
// construction/destruction
|
// construction/destruction
|
||||||
jaguardsp_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
jaguardsp_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
void ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0) override;
|
void io_map(address_map &map);
|
||||||
u32 ctrl_r(offs_t offset) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual u32 execute_input_lines() const noexcept override { return 6; }
|
virtual u32 execute_input_lines() const noexcept override { return 6; }
|
||||||
virtual void execute_run() override;
|
virtual void execute_run() override;
|
||||||
|
|
||||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||||
|
DECLARE_WRITE32_MEMBER(modulo_w);
|
||||||
|
DECLARE_WRITE32_MEMBER(dsp_end_w);
|
||||||
|
DECLARE_READ32_MEMBER(high_accum_r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ WRITE16_MEMBER( jaguar_state::jerry_regs_w )
|
|||||||
WRITE32_MEMBER( jaguar_state::dsp_flags_w )
|
WRITE32_MEMBER( jaguar_state::dsp_flags_w )
|
||||||
{
|
{
|
||||||
/* write the data through */
|
/* write the data through */
|
||||||
m_dsp->ctrl_w(offset, data, mem_mask);
|
m_dsp->iobus_w(offset, data, mem_mask);
|
||||||
|
|
||||||
/* if they were clearing the A2S interrupt, see if we are headed for the spin */
|
/* if they were clearing the A2S interrupt, see if we are headed for the spin */
|
||||||
/* loop with R22 != 0; if we are, just start spinning again */
|
/* loop with R22 != 0; if we are, just start spinning again */
|
||||||
|
@ -459,8 +459,8 @@ void jaguar_state::machine_reset()
|
|||||||
dsp_resume();
|
dsp_resume();
|
||||||
|
|
||||||
/* halt the CPUs */
|
/* halt the CPUs */
|
||||||
m_gpu->ctrl_w(G_CTRL, 0);
|
m_gpu->go_w(false);
|
||||||
m_dsp->ctrl_w(D_CTRL, 0);
|
m_dsp->go_w(false);
|
||||||
|
|
||||||
/* set blitter idle flag */
|
/* set blitter idle flag */
|
||||||
m_blitter_status = 1;
|
m_blitter_status = 1;
|
||||||
@ -640,8 +640,8 @@ WRITE32_MEMBER(jaguar_state::misc_control_w)
|
|||||||
dsp_resume();
|
dsp_resume();
|
||||||
|
|
||||||
/* halt the CPUs */
|
/* halt the CPUs */
|
||||||
m_gpu->ctrl_w(G_CTRL, 0);
|
m_gpu->go_w(false);
|
||||||
m_dsp->ctrl_w(D_CTRL, 0);
|
m_dsp->go_w(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust banking */
|
/* adjust banking */
|
||||||
@ -663,17 +663,14 @@ WRITE32_MEMBER(jaguar_state::misc_control_w)
|
|||||||
|
|
||||||
READ32_MEMBER(jaguar_state::gpuctrl_r)
|
READ32_MEMBER(jaguar_state::gpuctrl_r)
|
||||||
{
|
{
|
||||||
return m_gpu->ctrl_r(offset);
|
return m_gpu->iobus_r(offset, mem_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE32_MEMBER(jaguar_state::gpuctrl_w)
|
WRITE32_MEMBER(jaguar_state::gpuctrl_w)
|
||||||
{
|
{
|
||||||
m_gpu->ctrl_w(offset, data, mem_mask);
|
m_gpu->iobus_w(offset, data, mem_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
* 32-bit access to the DSP
|
* 32-bit access to the DSP
|
||||||
@ -682,16 +679,14 @@ WRITE32_MEMBER(jaguar_state::gpuctrl_w)
|
|||||||
|
|
||||||
READ32_MEMBER(jaguar_state::dspctrl_r)
|
READ32_MEMBER(jaguar_state::dspctrl_r)
|
||||||
{
|
{
|
||||||
return m_dsp->ctrl_r(offset);
|
return m_dsp->iobus_r(offset, mem_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE32_MEMBER(jaguar_state::dspctrl_w)
|
WRITE32_MEMBER(jaguar_state::dspctrl_w)
|
||||||
{
|
{
|
||||||
m_dsp->ctrl_w(offset, data, mem_mask);
|
m_dsp->iobus_w(offset, data, mem_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
* Input ports
|
* Input ports
|
||||||
@ -1119,7 +1114,7 @@ void jaguar_state::console_base_map(address_map &map)
|
|||||||
map(0xe00000, 0xe1ffff).rom().region("mainrom", 0);
|
map(0xe00000, 0xe1ffff).rom().region("mainrom", 0);
|
||||||
map(0xf00000, 0xf003ff).rw(FUNC(jaguar_state::tom_regs_r), FUNC(jaguar_state::tom_regs_w)); // might be reversed endian of the others..
|
map(0xf00000, 0xf003ff).rw(FUNC(jaguar_state::tom_regs_r), FUNC(jaguar_state::tom_regs_w)); // might be reversed endian of the others..
|
||||||
map(0xf00400, 0xf005ff).mirror(0x000200).rw(FUNC(jaguar_state::gpu_clut_r16), FUNC(jaguar_state::gpu_clut_w16));
|
map(0xf00400, 0xf005ff).mirror(0x000200).rw(FUNC(jaguar_state::gpu_clut_r16), FUNC(jaguar_state::gpu_clut_w16));
|
||||||
map(0xf02100, 0xf021ff).mirror(0x008000).rw(FUNC(jaguar_state::gpuctrl_r16), FUNC(jaguar_state::gpuctrl_w16));
|
map(0xf02100, 0xf021ff).rw(FUNC(jaguar_state::gpuctrl_r16), FUNC(jaguar_state::gpuctrl_w16));
|
||||||
map(0xf02200, 0xf022ff).mirror(0x008000).rw(FUNC(jaguar_state::blitter_r16), FUNC(jaguar_state::blitter_w16));
|
map(0xf02200, 0xf022ff).mirror(0x008000).rw(FUNC(jaguar_state::blitter_r16), FUNC(jaguar_state::blitter_w16));
|
||||||
map(0xf03000, 0xf03fff).mirror(0x008000).rw(FUNC(jaguar_state::gpu_ram_r16), FUNC(jaguar_state::gpu_ram_w16));
|
map(0xf03000, 0xf03fff).mirror(0x008000).rw(FUNC(jaguar_state::gpu_ram_r16), FUNC(jaguar_state::gpu_ram_w16));
|
||||||
map(0xf10000, 0xf103ff).rw(FUNC(jaguar_state::jerry_regs_r), FUNC(jaguar_state::jerry_regs_w)); // might be reversed endian of the others..
|
map(0xf10000, 0xf103ff).rw(FUNC(jaguar_state::jerry_regs_r), FUNC(jaguar_state::jerry_regs_w)); // might be reversed endian of the others..
|
||||||
@ -1141,7 +1136,7 @@ void jaguar_state::jaguar_map(address_map &map)
|
|||||||
void jaguar_state::cpu_space_map(address_map &map)
|
void jaguar_state::cpu_space_map(address_map &map)
|
||||||
{
|
{
|
||||||
map(0xfffff0, 0xffffff).m(m_maincpu, FUNC(m68000_base_device::autovectors_map));
|
map(0xfffff0, 0xffffff).m(m_maincpu, FUNC(m68000_base_device::autovectors_map));
|
||||||
map(0xfffffd, 0xfffffd).lr8([] () -> u8 { return 0x40; }, "level6");
|
map(0xfffff5, 0xfffff5).lr8([] () -> u8 { return 0x40; }, "level2");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1451,7 +1446,7 @@ void jaguar_state::console_base_gpu_map(address_map &map)
|
|||||||
map(0xe00000, 0xe1ffff).r(FUNC(jaguar_state::rom_base_r));
|
map(0xe00000, 0xe1ffff).r(FUNC(jaguar_state::rom_base_r));
|
||||||
map(0xf00000, 0xf003ff).rw(FUNC(jaguar_state::tom_regs_r), FUNC(jaguar_state::tom_regs_w));
|
map(0xf00000, 0xf003ff).rw(FUNC(jaguar_state::tom_regs_r), FUNC(jaguar_state::tom_regs_w));
|
||||||
map(0xf00400, 0xf005ff).mirror(0x000200).ram().share("gpuclut");
|
map(0xf00400, 0xf005ff).mirror(0x000200).ram().share("gpuclut");
|
||||||
map(0xf02100, 0xf021ff).mirror(0x008000).rw(FUNC(jaguar_state::gpuctrl_r), FUNC(jaguar_state::gpuctrl_w));
|
map(0xf02100, 0xf021ff).rw(FUNC(jaguar_state::gpuctrl_r), FUNC(jaguar_state::gpuctrl_w));
|
||||||
map(0xf02200, 0xf022ff).mirror(0x008000).rw(FUNC(jaguar_state::blitter_r), FUNC(jaguar_state::blitter_w));
|
map(0xf02200, 0xf022ff).mirror(0x008000).rw(FUNC(jaguar_state::blitter_r), FUNC(jaguar_state::blitter_w));
|
||||||
map(0xf03000, 0xf03fff).mirror(0x008000).ram().share("gpuram");
|
map(0xf03000, 0xf03fff).mirror(0x008000).ram().share("gpuram");
|
||||||
map(0xf10000, 0xf103ff).rw(FUNC(jaguar_state::jerry_regs_r), FUNC(jaguar_state::jerry_regs_w));
|
map(0xf10000, 0xf103ff).rw(FUNC(jaguar_state::jerry_regs_r), FUNC(jaguar_state::jerry_regs_w));
|
||||||
@ -1764,18 +1759,28 @@ INPUT_PORTS_END
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
|
void jaguar_state::video_config(machine_config &config, const XTAL clock)
|
||||||
|
{
|
||||||
|
JAGUARGPU(config, m_gpu, clock);
|
||||||
|
m_gpu->irq().set(FUNC(jaguar_state::gpu_cpu_int));
|
||||||
|
|
||||||
|
JAGUARDSP(config, m_dsp, clock);
|
||||||
|
m_dsp->irq().set(FUNC(jaguar_state::dsp_cpu_int));
|
||||||
|
|
||||||
|
// TODO: Tom
|
||||||
|
// TODO: Object Processor
|
||||||
|
|
||||||
|
JAG_BLITTER(config, m_blitter, clock);
|
||||||
|
}
|
||||||
|
|
||||||
void jaguar_state::cojagr3k(machine_config &config)
|
void jaguar_state::cojagr3k(machine_config &config)
|
||||||
{
|
{
|
||||||
/* basic machine hardware */
|
/* basic machine hardware */
|
||||||
R3041(config, m_maincpu, R3000_CLOCK).set_endianness(ENDIANNESS_BIG);
|
R3041(config, m_maincpu, R3000_CLOCK).set_endianness(ENDIANNESS_BIG);
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &jaguar_state::r3000_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &jaguar_state::r3000_map);
|
||||||
|
|
||||||
JAGUARGPU(config, m_gpu, COJAG_CLOCK/2);
|
video_config(config, COJAG_CLOCK/2);
|
||||||
m_gpu->irq().set(FUNC(jaguar_state::gpu_cpu_int));
|
|
||||||
m_gpu->set_addrmap(AS_PROGRAM, &jaguar_state::gpu_map);
|
m_gpu->set_addrmap(AS_PROGRAM, &jaguar_state::gpu_map);
|
||||||
|
|
||||||
JAGUARDSP(config, m_dsp, COJAG_CLOCK/2);
|
|
||||||
m_dsp->irq().set(FUNC(jaguar_state::dsp_cpu_int));
|
|
||||||
m_dsp->set_addrmap(AS_PROGRAM, &jaguar_state::dsp_map);
|
m_dsp->set_addrmap(AS_PROGRAM, &jaguar_state::dsp_map);
|
||||||
|
|
||||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
|
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
|
||||||
@ -1803,6 +1808,8 @@ void jaguar_state::cojagr3k(machine_config &config)
|
|||||||
vref.add_route(0, "ldac", -1.0, DAC_VREF_NEG_INPUT);
|
vref.add_route(0, "ldac", -1.0, DAC_VREF_NEG_INPUT);
|
||||||
vref.add_route(0, "rdac", 1.0, DAC_VREF_POS_INPUT);
|
vref.add_route(0, "rdac", 1.0, DAC_VREF_POS_INPUT);
|
||||||
vref.add_route(0, "rdac", -1.0, DAC_VREF_NEG_INPUT);
|
vref.add_route(0, "rdac", -1.0, DAC_VREF_NEG_INPUT);
|
||||||
|
|
||||||
|
// TODO: subwoofer speaker
|
||||||
}
|
}
|
||||||
|
|
||||||
void jaguar_state::cojagr3k_rom(machine_config &config)
|
void jaguar_state::cojagr3k_rom(machine_config &config)
|
||||||
@ -1832,12 +1839,8 @@ void jaguar_state::jaguar(machine_config &config)
|
|||||||
m_maincpu->set_addrmap(AS_PROGRAM, &jaguar_state::jaguar_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &jaguar_state::jaguar_map);
|
||||||
m_maincpu->set_addrmap(m68000_device::AS_CPU_SPACE, &jaguar_state::cpu_space_map);
|
m_maincpu->set_addrmap(m68000_device::AS_CPU_SPACE, &jaguar_state::cpu_space_map);
|
||||||
|
|
||||||
JAGUARGPU(config, m_gpu, JAGUAR_CLOCK);
|
video_config(config, JAGUAR_CLOCK);
|
||||||
m_gpu->irq().set(FUNC(jaguar_state::gpu_cpu_int));
|
|
||||||
m_gpu->set_addrmap(AS_PROGRAM, &jaguar_state::jag_gpu_dsp_map);
|
m_gpu->set_addrmap(AS_PROGRAM, &jaguar_state::jag_gpu_dsp_map);
|
||||||
|
|
||||||
JAGUARDSP(config, m_dsp, JAGUAR_CLOCK);
|
|
||||||
m_dsp->irq().set(FUNC(jaguar_state::dsp_cpu_int));
|
|
||||||
m_dsp->set_addrmap(AS_PROGRAM, &jaguar_state::jag_gpu_dsp_map);
|
m_dsp->set_addrmap(AS_PROGRAM, &jaguar_state::jag_gpu_dsp_map);
|
||||||
|
|
||||||
// MCFG_NVRAM_HANDLER(jaguar)
|
// MCFG_NVRAM_HANDLER(jaguar)
|
||||||
@ -1902,6 +1905,7 @@ void jaguar_state::fix_endian( void *base, uint32_t size )
|
|||||||
|
|
||||||
void jaguar_state::init_jaguar()
|
void jaguar_state::init_jaguar()
|
||||||
{
|
{
|
||||||
|
m_is_cojag = false;
|
||||||
m_hacks_enabled = false;
|
m_hacks_enabled = false;
|
||||||
save_item(NAME(m_joystick_data));
|
save_item(NAME(m_joystick_data));
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "machine/eepromser.h"
|
#include "machine/eepromser.h"
|
||||||
#include "machine/vt83c461.h"
|
#include "machine/vt83c461.h"
|
||||||
#include "imagedev/snapquik.h"
|
#include "imagedev/snapquik.h"
|
||||||
|
#include "video/jag_blitter.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
#include "imagedev/chd_cd.h"
|
#include "imagedev/chd_cd.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
@ -33,6 +34,7 @@ public:
|
|||||||
: driver_device(mconfig, type, tag)
|
: driver_device(mconfig, type, tag)
|
||||||
, m_maincpu(*this, "maincpu")
|
, m_maincpu(*this, "maincpu")
|
||||||
, m_gpu(*this, "gpu")
|
, m_gpu(*this, "gpu")
|
||||||
|
, m_blitter(*this, "blitter")
|
||||||
, m_dsp(*this, "dsp")
|
, m_dsp(*this, "dsp")
|
||||||
, m_ldac(*this, "ldac")
|
, m_ldac(*this, "ldac")
|
||||||
, m_rdac(*this, "rdac")
|
, m_rdac(*this, "rdac")
|
||||||
@ -111,9 +113,12 @@ protected:
|
|||||||
virtual void device_postload();
|
virtual void device_postload();
|
||||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||||
|
|
||||||
|
void video_config(machine_config &config, const XTAL clock);
|
||||||
|
|
||||||
// devices
|
// devices
|
||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
required_device<jaguargpu_cpu_device> m_gpu;
|
required_device<jaguargpu_cpu_device> m_gpu;
|
||||||
|
required_device<jag_blitter_device> m_blitter;
|
||||||
required_device<jaguardsp_cpu_device> m_dsp;
|
required_device<jaguardsp_cpu_device> m_dsp;
|
||||||
required_device<dac_word_interface> m_ldac;
|
required_device<dac_word_interface> m_ldac;
|
||||||
required_device<dac_word_interface> m_rdac;
|
required_device<dac_word_interface> m_rdac;
|
||||||
@ -301,7 +306,8 @@ private:
|
|||||||
void get_crosshair_xy(int player, int &x, int &y);
|
void get_crosshair_xy(int player, int &x, int &y);
|
||||||
int effective_hvalue(int value);
|
int effective_hvalue(int value);
|
||||||
bool adjust_object_timer(int vc);
|
bool adjust_object_timer(int vc);
|
||||||
void update_cpu_irq();
|
inline void trigger_host_cpu_irq(int level);
|
||||||
|
inline void verify_host_cpu_irq();
|
||||||
uint8_t *memory_base(uint32_t offset) { return reinterpret_cast<uint8_t *>(m_gpu->space(AS_PROGRAM).get_read_ptr(offset)); }
|
uint8_t *memory_base(uint32_t offset) { return reinterpret_cast<uint8_t *>(m_gpu->space(AS_PROGRAM).get_read_ptr(offset)); }
|
||||||
void blitter_run();
|
void blitter_run();
|
||||||
void scanline_update(int param);
|
void scanline_update(int param);
|
||||||
|
240
src/mame/video/jag_blitter.cpp
Normal file
240
src/mame/video/jag_blitter.cpp
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Angelo Salese
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
Atari Jaguar "Blitter" device
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- Stub device, port/rewrite from jagblit;
|
||||||
|
- actual codename/chip part number;
|
||||||
|
- has different revs, encapsulate;
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "jag_blitter.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
DEFINE_DEVICE_TYPE(JAG_BLITTER, jag_blitter_device, "jag_blitter", "Atari Jaguar Blitter")
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// LIVE DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// jag_blitter_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
jag_blitter_device::jag_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
|
: device_t(mconfig, JAG_BLITTER, tag, owner, clock)
|
||||||
|
, device_memory_interface(mconfig, *this)
|
||||||
|
, m_space_config("regs", ENDIANNESS_BIG, 32, 8, 0, address_map_constructor(FUNC(jag_blitter_device::regs_map), this))
|
||||||
|
, m_command_latch(0)
|
||||||
|
, m_status_idle(true)
|
||||||
|
, m_count_lines(0)
|
||||||
|
, m_count_pixels(0)
|
||||||
|
{
|
||||||
|
m_a1.base = 0;
|
||||||
|
m_a1.xstep = 0;
|
||||||
|
m_a1.ystep = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_memory_interface::space_config_vector jag_blitter_device::memory_space_config() const
|
||||||
|
{
|
||||||
|
return space_config_vector {
|
||||||
|
std::make_pair(0, &m_space_config)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void jag_blitter_device::device_start()
|
||||||
|
{
|
||||||
|
save_item(NAME(m_status_idle));
|
||||||
|
save_item(NAME(m_command_latch));
|
||||||
|
save_item(NAME(m_count_lines));
|
||||||
|
save_item(NAME(m_count_pixels));
|
||||||
|
save_item(NAME(m_a1.base));
|
||||||
|
save_item(NAME(m_a1.xstep));
|
||||||
|
save_item(NAME(m_a1.ystep));
|
||||||
|
|
||||||
|
m_command_timer = timer_alloc(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_reset - device-specific reset
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void jag_blitter_device::device_reset()
|
||||||
|
{
|
||||||
|
m_command_latch = 0;
|
||||||
|
m_status_idle = true;
|
||||||
|
|
||||||
|
m_command_timer->adjust(attotime::never);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// core workings
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
FUNCTION TABLES
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
const jag_blitter_device::op_func jag_blitter_device::upda_ops[8] =
|
||||||
|
{
|
||||||
|
&jag_blitter_device::op_nop,
|
||||||
|
&jag_blitter_device::op_unemulated, // upda1f
|
||||||
|
&jag_blitter_device::op_upda1,
|
||||||
|
&jag_blitter_device::op_unemulated, // upda1 + upda1f
|
||||||
|
|
||||||
|
&jag_blitter_device::op_unemulated, // upda2
|
||||||
|
&jag_blitter_device::op_unemulated, // upda1f + upda2
|
||||||
|
&jag_blitter_device::op_unemulated, // upda1 + upda2
|
||||||
|
&jag_blitter_device::op_unemulated // upda1 + upda1f + upda2
|
||||||
|
};
|
||||||
|
|
||||||
|
void jag_blitter_device::op_nop()
|
||||||
|
{
|
||||||
|
// do nothing for this step
|
||||||
|
}
|
||||||
|
|
||||||
|
// common cases for unhandled, will be removed once everything is set
|
||||||
|
void jag_blitter_device::op_unemulated()
|
||||||
|
{
|
||||||
|
throw emu_fatalerror("%s: unhandled step with command latch %08x",m_command_latch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void jag_blitter_device::op_upda1()
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void jag_blitter_device::command_start()
|
||||||
|
{
|
||||||
|
if (m_status_idle == false)
|
||||||
|
throw emu_fatalerror("%s: inflight blitter trigger %08x", this->tag(), m_command_latch);
|
||||||
|
m_status_idle = false;
|
||||||
|
// TODO: to be removed, see below
|
||||||
|
m_command_timer->adjust(attotime::from_ticks(m_count_lines * m_count_pixels, this->clock()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void jag_blitter_device::command_run()
|
||||||
|
{
|
||||||
|
// TODO: need to single step, have different timings between pixel and phrase modes,
|
||||||
|
// calculate collision detection, delay a bit the kickoff due of bus chain requests,
|
||||||
|
// take more time by virtue of using additional steps, be a civilian or not depending
|
||||||
|
// of BUSHI setting
|
||||||
|
|
||||||
|
printf("%08x\n",m_command_latch);
|
||||||
|
// init
|
||||||
|
m_a1.ptr = m_a1.base;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
command_done();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void jag_blitter_device::command_done()
|
||||||
|
{
|
||||||
|
// m_status_idle = true;
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
void jag_blitter_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
|
{
|
||||||
|
command_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// READ/WRITE HANDLERS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
void jag_blitter_device::regs_map(address_map &map)
|
||||||
|
{
|
||||||
|
// $f02200
|
||||||
|
map(0x00, 0x03).w(FUNC(jag_blitter_device::a1_base_w));
|
||||||
|
map(0x10, 0x13).w(FUNC(jag_blitter_device::a1_ystep_w)).umask32(0xffff0000);
|
||||||
|
map(0x10, 0x13).w(FUNC(jag_blitter_device::a1_xstep_w)).umask32(0x0000ffff);
|
||||||
|
map(0x38, 0x3b).rw(FUNC(jag_blitter_device::status_r), FUNC(jag_blitter_device::command_w));
|
||||||
|
map(0x3c, 0x3f).w(FUNC(jag_blitter_device::count_outer_w)).umask32(0xffff0000);
|
||||||
|
map(0x3c, 0x3f).w(FUNC(jag_blitter_device::count_inner_w)).umask32(0x0000ffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jag_blitter_device::a1_base_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_a1.base);
|
||||||
|
// align to phrase
|
||||||
|
m_a1.base &= ~7;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(jag_blitter_device::a1_xstep_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_a1.xstep);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(jag_blitter_device::a1_ystep_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_a1.ystep);
|
||||||
|
}
|
||||||
|
|
||||||
|
READ32_MEMBER(jag_blitter_device::status_r)
|
||||||
|
{
|
||||||
|
// TODO: stopped bit
|
||||||
|
// TODO: diag bits 2-31
|
||||||
|
return m_status_idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(jag_blitter_device::command_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_command_latch);
|
||||||
|
// TODO: is it possible from 68k to write on this in byte units?
|
||||||
|
// We may just do so in order to take endianness into account, or just delegate to the overlying bus framework,
|
||||||
|
// may be a common problem with ALL video regs for that matter.
|
||||||
|
if (ACCESSING_BITS_0_15)
|
||||||
|
command_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(jag_blitter_device::count_outer_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_count_lines);
|
||||||
|
if (m_count_lines == 0)
|
||||||
|
{
|
||||||
|
// according to documentation, log it out
|
||||||
|
m_count_lines = 0x10000;
|
||||||
|
popmessage("Blitter: line count set to max, contact MAMEdev");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_MEMBER(jag_blitter_device::count_inner_w)
|
||||||
|
{
|
||||||
|
COMBINE_DATA(&m_count_pixels);
|
||||||
|
if (m_count_pixels == 0)
|
||||||
|
{
|
||||||
|
// according to documentation, log it out
|
||||||
|
m_count_pixels = 0x10000;
|
||||||
|
popmessage("Blitter: pixel count set to max, contact MAMEdev");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 jag_blitter_device::iobus_r(offs_t offset, u32 mem_mask)
|
||||||
|
{
|
||||||
|
return space().read_dword(offset*4, mem_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void jag_blitter_device::iobus_w(offs_t offset, u32 data, u32 mem_mask)
|
||||||
|
{
|
||||||
|
space().write_dword(offset*4, data, mem_mask);
|
||||||
|
}
|
100
src/mame/video/jag_blitter.h
Normal file
100
src/mame/video/jag_blitter.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Angelo Salese
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
Atari Jaguar "Blitter" device
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAME_MACHINE_JAG_BLITTER_H
|
||||||
|
#define MAME_MACHINE_JAG_BLITTER_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INTERFACE CONFIGURATION MACROS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> jag_blitter_device
|
||||||
|
|
||||||
|
class jag_blitter_device : public device_t,
|
||||||
|
public device_memory_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
jag_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
// TODO: add which device triggered the I/O
|
||||||
|
void iobus_w(offs_t offset, u32 data, u32 mem_mask = ~0);
|
||||||
|
u32 iobus_r(offs_t offset, u32 mem_mask = ~0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device-level overrides
|
||||||
|
//virtual void device_validity_check(validity_checker &valid) const override;
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||||
|
virtual space_config_vector memory_space_config() const override;
|
||||||
|
|
||||||
|
const address_space_config m_space_config;
|
||||||
|
|
||||||
|
// address_space *m_host_space;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void regs_map(address_map &map);
|
||||||
|
|
||||||
|
DECLARE_WRITE32_MEMBER(a1_base_w);
|
||||||
|
DECLARE_WRITE16_MEMBER(a1_xstep_w);
|
||||||
|
DECLARE_WRITE16_MEMBER(a1_ystep_w);
|
||||||
|
DECLARE_READ32_MEMBER(status_r);
|
||||||
|
DECLARE_WRITE32_MEMBER(command_w);
|
||||||
|
DECLARE_WRITE16_MEMBER(count_outer_w);
|
||||||
|
DECLARE_WRITE16_MEMBER(count_inner_w);
|
||||||
|
|
||||||
|
// timer setups
|
||||||
|
emu_timer *m_command_timer;
|
||||||
|
inline void command_start();
|
||||||
|
inline void command_run();
|
||||||
|
inline void command_done();
|
||||||
|
|
||||||
|
// functional switches
|
||||||
|
|
||||||
|
typedef void (jag_blitter_device::*op_func)(void);
|
||||||
|
|
||||||
|
static const op_func upda_ops[8];
|
||||||
|
void op_nop();
|
||||||
|
void op_unemulated();
|
||||||
|
void op_upda1();
|
||||||
|
|
||||||
|
u32 m_command_latch;
|
||||||
|
bool m_status_idle;
|
||||||
|
u32 m_count_lines, m_count_pixels;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 base;
|
||||||
|
s16 xstep, ystep;
|
||||||
|
|
||||||
|
u32 ptr; /**< Current pixel address */
|
||||||
|
} m_a1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
DECLARE_DEVICE_TYPE(JAG_BLITTER, jag_blitter_device)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MAME_MACHINE_JAG_BLITTER_H
|
@ -1056,9 +1056,11 @@ void jaguar_state::process_object_list(int vc, uint16_t *scanline)
|
|||||||
m_gpu_regs[OB_HL]=objdata[1]&0xffff;
|
m_gpu_regs[OB_HL]=objdata[1]&0xffff;
|
||||||
m_gpu_regs[OB_LH]=(objdata[0]&0xffff0000)>>16;
|
m_gpu_regs[OB_LH]=(objdata[0]&0xffff0000)>>16;
|
||||||
m_gpu_regs[OB_LL]=objdata[0]&0xffff;
|
m_gpu_regs[OB_LL]=objdata[0]&0xffff;
|
||||||
m_cpu_irq_state |= 2;
|
m_gpu->set_input_line(3, ASSERT_LINE);
|
||||||
update_cpu_irq();
|
|
||||||
done=1;
|
done=1;
|
||||||
|
// mutntpng, atarikrt VPOS = 0
|
||||||
|
// TODO: what the VPOS is actually for?
|
||||||
|
//printf("GPU irq VPOS = %04x\n",(objdata[1] >> 3) & 0x7ff);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* branch */
|
/* branch */
|
||||||
@ -1078,16 +1080,20 @@ void jaguar_state::process_object_list(int vc, uint16_t *scanline)
|
|||||||
logerror("stop = %08X-%08X\n", objdata[0], objdata[1]);
|
logerror("stop = %08X-%08X\n", objdata[0], objdata[1]);
|
||||||
if (interrupt)
|
if (interrupt)
|
||||||
{
|
{
|
||||||
|
// TODO: fball95 doesn't have a real handling for stop irq, causing the line to be always asserted, how to prevent?
|
||||||
// fprintf(stderr, "stop int=%d\n", interrupt);
|
// fprintf(stderr, "stop int=%d\n", interrupt);
|
||||||
m_cpu_irq_state |= 4;
|
trigger_host_cpu_irq(2);
|
||||||
update_cpu_irq();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
// kasumi: F7000000 00F0311E (nop? bad align?)
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%08X %08X\n", objdata[0], objdata[1]);
|
fprintf(stderr, "%08X %08X\n", objdata[0], objdata[1]);
|
||||||
done = 1;
|
//done = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
Atari Jaguar hardware
|
Atari Jaguar hardware
|
||||||
|
|
||||||
|
TODO (list of exceptions):
|
||||||
|
jaguar_state::generic_blitter()
|
||||||
|
- atarikrt, bretth, brutalsp, nbajamte, spacewar, spacewarp, tempst2k
|
||||||
|
jaguar_state::blitter_09800009_000020_000020()
|
||||||
|
- ruinerp
|
||||||
|
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
@ -150,7 +156,8 @@
|
|||||||
#define LOG_BLITTER_STATS 0
|
#define LOG_BLITTER_STATS 0
|
||||||
#define LOG_BLITTER_WRITE 0
|
#define LOG_BLITTER_WRITE 0
|
||||||
#define LOG_UNHANDLED_BLITS 0
|
#define LOG_UNHANDLED_BLITS 0
|
||||||
|
// use the new version in jag_blitter.cpp/.h if 0
|
||||||
|
#define USE_LEGACY_BLITTER 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -266,25 +273,38 @@ inline bool jaguar_state::adjust_object_timer(int vc)
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
void jaguar_state::update_cpu_irq()
|
// TODO: new TOM install irq handler
|
||||||
|
inline void jaguar_state::verify_host_cpu_irq()
|
||||||
{
|
{
|
||||||
|
// jaguar uses irq 2
|
||||||
|
if (m_is_cojag == false)
|
||||||
|
m_maincpu->set_input_line(M68K_IRQ_2, ((m_cpu_irq_state & m_gpu_regs[INT1] & 0x1f) != 0) ? ASSERT_LINE : CLEAR_LINE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// cojag r3000 uses irq 4
|
||||||
|
// cojag 68020 uses irq 6
|
||||||
if ((m_cpu_irq_state & m_gpu_regs[INT1] & 0x1f) != 0)
|
if ((m_cpu_irq_state & m_gpu_regs[INT1] & 0x1f) != 0)
|
||||||
m_maincpu->set_input_line(m_is_r3000 ? INPUT_LINE_IRQ4 : M68K_IRQ_6, ASSERT_LINE);
|
m_maincpu->set_input_line(m_is_r3000 ? INPUT_LINE_IRQ4 : M68K_IRQ_6, ASSERT_LINE);
|
||||||
else
|
else
|
||||||
m_maincpu->set_input_line(m_is_r3000 ? INPUT_LINE_IRQ4 : M68K_IRQ_6, CLEAR_LINE);
|
m_maincpu->set_input_line(m_is_r3000 ? INPUT_LINE_IRQ4 : M68K_IRQ_6, CLEAR_LINE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void jaguar_state::trigger_host_cpu_irq(int level)
|
||||||
|
{
|
||||||
|
m_cpu_irq_state |= 1 << level;
|
||||||
|
verify_host_cpu_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( jaguar_state::gpu_cpu_int )
|
WRITE_LINE_MEMBER( jaguar_state::gpu_cpu_int )
|
||||||
{
|
{
|
||||||
m_cpu_irq_state |= 2;
|
trigger_host_cpu_irq(1);
|
||||||
update_cpu_irq();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( jaguar_state::dsp_cpu_int )
|
WRITE_LINE_MEMBER( jaguar_state::dsp_cpu_int )
|
||||||
{
|
{
|
||||||
m_cpu_irq_state |= 16;
|
trigger_host_cpu_irq(4);
|
||||||
update_cpu_irq();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -524,6 +544,7 @@ if (++reps % 100 == 99)
|
|||||||
|
|
||||||
READ32_MEMBER( jaguar_state::blitter_r )
|
READ32_MEMBER( jaguar_state::blitter_r )
|
||||||
{
|
{
|
||||||
|
#if USE_LEGACY_BLITTER
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case B_CMD: /* B_CMD */
|
case B_CMD: /* B_CMD */
|
||||||
@ -533,11 +554,15 @@ READ32_MEMBER( jaguar_state::blitter_r )
|
|||||||
logerror("%s:Blitter read register @ F022%02X\n", machine().describe_context(), offset * 4);
|
logerror("%s:Blitter read register @ F022%02X\n", machine().describe_context(), offset * 4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
return m_blitter->iobus_r(offset, mem_mask);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE32_MEMBER( jaguar_state::blitter_w )
|
WRITE32_MEMBER( jaguar_state::blitter_w )
|
||||||
{
|
{
|
||||||
|
#if USE_LEGACY_BLITTER
|
||||||
COMBINE_DATA(&m_blitter_regs[offset]);
|
COMBINE_DATA(&m_blitter_regs[offset]);
|
||||||
if ((offset == B_CMD) && ACCESSING_BITS_0_15)
|
if ((offset == B_CMD) && ACCESSING_BITS_0_15)
|
||||||
{
|
{
|
||||||
@ -550,6 +575,9 @@ WRITE32_MEMBER( jaguar_state::blitter_w )
|
|||||||
|
|
||||||
if (LOG_BLITTER_WRITE)
|
if (LOG_BLITTER_WRITE)
|
||||||
logerror("%s:Blitter write register @ F022%02X = %08X\n", machine().describe_context(), offset * 4, data);
|
logerror("%s:Blitter write register @ F022%02X = %08X\n", machine().describe_context(), offset * 4, data);
|
||||||
|
#else
|
||||||
|
m_blitter->iobus_w(offset, data, mem_mask);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -568,7 +596,9 @@ READ16_MEMBER( jaguar_state::tom_regs_r )
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case INT1:
|
case INT1:
|
||||||
|
{
|
||||||
return m_cpu_irq_state;
|
return m_cpu_irq_state;
|
||||||
|
}
|
||||||
|
|
||||||
case HC:
|
case HC:
|
||||||
return m_screen->hpos() % (m_screen->width() / 2);
|
return m_screen->hpos() % (m_screen->width() / 2);
|
||||||
@ -615,17 +645,18 @@ WRITE16_MEMBER( jaguar_state::tom_regs_w )
|
|||||||
|
|
||||||
case INT1:
|
case INT1:
|
||||||
m_cpu_irq_state &= ~(m_gpu_regs[INT1] >> 8);
|
m_cpu_irq_state &= ~(m_gpu_regs[INT1] >> 8);
|
||||||
update_cpu_irq();
|
verify_host_cpu_irq();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// TODO: INT2 bus mechanism
|
||||||
|
|
||||||
case VMODE:
|
case VMODE:
|
||||||
if (reg_store != m_gpu_regs[offset])
|
if (reg_store != m_gpu_regs[offset])
|
||||||
set_palette(m_gpu_regs[VMODE]);
|
set_palette(m_gpu_regs[VMODE]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OBF: /* clear GPU interrupt */
|
case OBF: /* clear GPU interrupt */
|
||||||
m_cpu_irq_state &= 0xfd;
|
m_gpu->set_input_line(3, CLEAR_LINE);
|
||||||
update_cpu_irq();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HP:
|
case HP:
|
||||||
@ -715,10 +746,7 @@ void jaguar_state::device_timer(emu_timer &timer, device_timer_id id, int param,
|
|||||||
|
|
||||||
case TID_PIT:
|
case TID_PIT:
|
||||||
if (m_gpu_regs[INT1] & 0x8)
|
if (m_gpu_regs[INT1] & 0x8)
|
||||||
{
|
trigger_host_cpu_irq(3);
|
||||||
m_cpu_irq_state |= 8;
|
|
||||||
update_cpu_irq();
|
|
||||||
}
|
|
||||||
if (m_gpu_regs[PIT0] != 0)
|
if (m_gpu_regs[PIT0] != 0)
|
||||||
{
|
{
|
||||||
attotime sample_period = attotime::from_ticks((1+m_gpu_regs[PIT0]) * (1+m_gpu_regs[PIT1]), m_gpu->clock()/2);
|
attotime sample_period = attotime::from_ticks((1+m_gpu_regs[PIT0]) * (1+m_gpu_regs[PIT1]), m_gpu->clock()/2);
|
||||||
@ -789,10 +817,7 @@ void jaguar_state::scanline_update(int param)
|
|||||||
{
|
{
|
||||||
/* handle vertical interrupts */
|
/* handle vertical interrupts */
|
||||||
if (vc == m_gpu_regs[VI])
|
if (vc == m_gpu_regs[VI])
|
||||||
{
|
trigger_host_cpu_irq(0);
|
||||||
m_cpu_irq_state |= 1;
|
|
||||||
update_cpu_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* point to the next counter value */
|
/* point to the next counter value */
|
||||||
if (++vc / 2 >= m_screen->height())
|
if (++vc / 2 >= m_screen->height())
|
||||||
@ -824,7 +849,7 @@ void jaguar_state::video_start()
|
|||||||
|
|
||||||
void jaguar_state::device_postload()
|
void jaguar_state::device_postload()
|
||||||
{
|
{
|
||||||
update_cpu_irq();
|
verify_host_cpu_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user