mb86233/4 rewrite [O. Galibert]

model1: Use the real 315-5573 Virtua Racing coprocessor program [Team Caps0ff]
model2: Rewamp the coprocessors communications [O. Galibert]
This commit is contained in:
Olivier Galibert 2018-03-18 09:26:45 +01:00
parent 7bc00fc17e
commit 1d338061af
18 changed files with 3229 additions and 3485 deletions

View File

@ -3445,3 +3445,15 @@ if (MACHINES["28FXXX"]~=null) then
MAME_DIR .. "src/devices/machine/28fxxx.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/gen_fifo.h,MACHINES["GEN_FIFO"] = true
---------------------------------------------------
if (MACHINES["GEN_FIFO"]~=null) then
files {
MAME_DIR .. "src/devices/machine/gen_fifo.cpp",
MAME_DIR .. "src/devices/machine/gen_fifo.h",
}
end

View File

@ -619,6 +619,7 @@ MACHINES["WATCHDOG"] = true
MACHINES["INPUT_MERGER"] = true
MACHINES["K054321"] = true
MACHINES["ADC0844"] = true
MACHINES["GEN_FIFO"] = true
--------------------------------------------------
-- specify available bus cores

View File

@ -628,6 +628,7 @@ MACHINES["INPUT_MERGER"] = true
-- MACHINES["K054321"] = true
MACHINES["ADC0844"] = true
MACHINES["28FXXX"] = true
-- MACHINES["GEN_FIFO"] = true
--------------------------------------------------
-- specify available bus cores

File diff suppressed because it is too large Load Diff

View File

@ -1,143 +1,137 @@
// license:BSD-3-Clause
// copyright-holders:Ernesto Corvi
// copyright-holders:Olivier Galibert
#ifndef MAME_CPU_MB86233_MB86233_H
#define MAME_CPU_MB86233_MB86233_H
#pragma once
#define MCFG_MB86233_FIFO_READ_CB(_devcb) \
devcb = &downcast<mb86233_cpu_device &>(*device).set_fifo_read_cb(DEVCB_##_devcb);
#define MCFG_MB86233_FIFO_READ_OK_CB(_devcb) \
devcb = &downcast<mb86233_cpu_device &>(*device).set_fifo_read_ok_cb(DEVCB_##_devcb);
#define MCFG_MB86233_FIFO_WRITE_CB(_devcb) \
devcb = &downcast<mb86233_cpu_device &>(*device).set_fifo_write_cb(DEVCB_##_devcb);
#define MCFG_MB86233_TABLE_REGION(_region) \
downcast<mb86233_cpu_device &>(*device).set_tablergn(_region);
class mb86233_cpu_device : public cpu_device
class mb86233_device : public cpu_device
{
public:
// construction/destruction
mb86233_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
template <class Object> devcb_base &set_fifo_read_cb(Object &&cb) { return m_fifo_read_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_fifo_read_ok_cb(Object &&cb) { return m_fifo_read_ok_cb.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_fifo_write_cb(Object &&cb) { return m_fifo_write_cb.set_callback(std::forward<Object>(cb)); }
void set_tablergn(const char *tablergn) { m_tablergn = tablergn; }
protected:
// register enumeration
enum
{
MB86233_PC=1,
MB86233_A,
MB86233_B,
MB86233_D,
MB86233_P,
MB86233_REP,
MB86233_SP,
MB86233_EB,
MB86233_SHIFT,
MB86233_FLAGS,
MB86233_R0,
MB86233_R1,
MB86233_R2,
MB86233_R3,
MB86233_R4,
MB86233_R5,
MB86233_R6,
MB86233_R7,
MB86233_R8,
MB86233_R9,
MB86233_R10,
MB86233_R11,
MB86233_R12,
MB86233_R13,
MB86233_R14,
MB86233_R15
enum address_space_ids {
AS_RF = 4,
AS_EXTERNAL = 5
};
// device-level overrides
enum regs_ids {
REG_A, REG_B, REG_D, REG_P,
REG_R, REG_C0, REG_C1,
REG_B0, REG_B1, REG_X0, REG_X1, REG_I0, REG_I1,
REG_SFT, REG_VSM, REG_MASK, REG_M,
REG_PCS0, REG_PCS1, REG_PCS2, REG_PCS3
};
enum st_flags {
F_ZRC = 0x00000001,
F_ZRD = 0x00000002,
F_SGC = 0x00000004,
F_SGD = 0x00000008,
F_CPC = 0x00000010,
F_CPD = 0x00000020,
F_OVC = 0x00000040,
F_OVD = 0x00000080,
F_UNC = 0x00000100,
F_UND = 0x00000200,
F_DVZC = 0x00000400,
F_DVZD = 0x00000800,
F_CA = 0x00001000,
F_CPP = 0x00002000,
F_OVM = 0x00004000,
F_UNM = 0x00008000,
F_SIF0 = 0x00010000,
F_SIF1 = 0x00020000,
F_SOF0 = 0x00040000,
F_PIF = 0x00100000,
F_POF = 0x00200000,
F_PAIF = 0x00400000,
F_PAOF = 0x00800000,
F_F0S = 0x01000000,
F_F1S = 0x02000000,
F_IT = 0x04000000,
F_ZX0 = 0x08000000,
F_ZX1 = 0x10000000,
F_ZX2 = 0x20000000,
F_ZC0 = 0x40000000,
F_ZC1 = 0x80000000
};
mb86233_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void stall() { m_stall = true; }
DECLARE_WRITE_LINE_MEMBER(gpio0_w);
DECLARE_WRITE_LINE_MEMBER(gpio1_w);
DECLARE_WRITE_LINE_MEMBER(gpio2_w);
DECLARE_WRITE_LINE_MEMBER(gpio3_w);
protected:
mb86233_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
virtual void device_reset() override;
// device_execute_interface overrides
virtual uint32_t execute_min_cycles() const override { return 1; }
virtual uint32_t execute_max_cycles() const override { return 2; }
virtual uint32_t execute_input_lines() const override { return 0; }
virtual uint32_t execute_max_cycles() const override { return 1; }
virtual uint32_t execute_input_lines() const override { return 4; }
virtual void execute_run() override;
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
// device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
address_space_config m_program_config;
address_space_config m_data_config;
address_space_config m_io_config;
address_space_config m_rf_config;
union MB86233_REG
{
int32_t i;
uint32_t u;
float f;
};
uint16_t m_pc;
MB86233_REG m_a;
MB86233_REG m_b;
MB86233_REG m_d;
MB86233_REG m_p;
uint16_t m_reps;
uint16_t m_pcs[4];
uint8_t m_pcsp;
uint32_t m_eb;
uint32_t m_shift;
uint32_t m_repcnt;
uint16_t m_sr;
uint8_t m_fpucontrol;
uint32_t m_gpr[16];
uint32_t m_extport[0x30];
address_space *m_program;
address_space *m_program, *m_data, *m_io, *m_rf;
direct_read_data<-2> *m_direct;
int m_icount;
/* FIFO */
int m_fifo_wait;
devcb_read32 m_fifo_read_cb;
devcb_read_line m_fifo_read_ok_cb;
devcb_write32 m_fifo_write_cb;
const char *m_tablergn;
u32 m_st, m_a, m_b, m_d, m_p;
u32 m_alu_stmask, m_alu_stset, m_alu_r1, m_alu_r2;
u16 m_ppc, m_pc, m_sp, m_b0, m_b1, m_x0, m_x1, m_i0, m_i1, m_vsmr, m_pcs[4], m_mask, m_m;
u8 m_r, m_rpc, m_c0, m_c1, m_sft, m_vsm;
bool m_gpio0, m_gpio1, m_gpio2, m_gpio3;
/* internal RAM */
uint32_t m_RAM[2 * 0x200];
uint32_t *m_ARAM, *m_BRAM;
uint32_t *m_Tables;
bool m_stall;
void FLAGSF( float v );
void FLAGSI( uint32_t v );
int COND( uint32_t cond );
void ALU( uint32_t alu);
uint32_t ScaleExp(unsigned int v,int scale);
uint32_t GETEXTERNAL( uint32_t EB, uint32_t offset );
void SETEXTERNAL( uint32_t EB, uint32_t offset, uint32_t value );
uint32_t GETREGS( uint32_t reg, int source );
void SETREGS( uint32_t reg, uint32_t val );
uint32_t INDIRECT( uint32_t reg, int source );
static s32 s24_32(u32 val);
static u32 set_exp(u32 val, u32 exp);
static u32 set_mant(u32 val, u32 mant);
static u32 get_exp(u32 val);
static u32 get_mant(u32 val);
void testdz();
void alu_update_st();
void alu_pre(u32 alu);
void alu_post(u32 alu);
u16 ea_pre_0(u32 r);
void ea_post_0(u32 r);
u16 ea_pre_1(u32 r);
void ea_post_1(u32 r);
void pcs_push();
void pcs_pop();
u32 read_reg(u32 r);
void write_reg(u32 r, u32 v);
void write_mem_internal_1(u32 r, u32 v, bool bank);
void write_mem_external_1(u32 r, u32 v);
void write_mem_io_1(u32 r, u32 v);
};
class mb86234_device : public mb86233_device
{
public:
mb86234_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
DECLARE_DEVICE_TYPE(MB86233, mb86233_cpu_device)
DECLARE_DEVICE_TYPE(MB86233, mb86233_device)
DECLARE_DEVICE_TYPE(MB86234, mb86234_device)
#endif // MAME_CPU_MB86233_MB86233_H

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Ernesto Corvi
// copyright-holders:Olivier Galibert
#include "emu.h"
#include "mb86233d.h"
@ -15,47 +15,54 @@
2 <register file>
3 sio0 si1 pio pioa rpc - - - pad mod ear st mask tim cx dx
In the 86233/86234 the C, page, serial, parallel, timer registers
don't seem to exist. The register file is turned into i/o ports.
Of the second bank part '3', only "mask" is actually used.
Address encoding:
Address encoding (adx uses x0/b0, ady uses x1/b1):
0 0aaa aaaa $a
0 1aaa aaaa $a(xn)
1 0aaa aaaa $a(xn+)
1 100b bbbb (xn+$b)
1 101b bbbb (bxn+$b)
1 110b bbbb [xn+$b]
1 111b bbbb [bxn+$b]
1 100b bbbb (bxn+$b)
1 101b bbbb (xn+$b)
1 110b bbbb [bxn+$b]
1 111b bbbb [xn+$b]
3322 2222 2222 1111 1111 1100 0000 0000
1098 7654 3210 9876 5432 1098 7654 3210
0000 00aa aaao ooyy yyyy yyyx xxxx xxxx lab
0000 00aa aaa0 00yy yyyy yyyx xxxx xxxx lab adx, ady (e)
0000 00aa aaa0 11yy yyyy yyyx xxxx xxxx lab adx, ady + 0x200
0000 00aa aaa1 00yy yyyy yyyx xxxx xxxx lab adx + 0x200, ady
0000 00aa aaa0 11yy yyyy yyyx xxxx xxxx lab adx (e), ady
0000 00aa aaa1 00yy yyyy yyyx xxxx xxxx lab adx, ady (e)
0001 11aa aaa0 10yy yyyy yyyx xxxx xxxx mov adx, ady
0001 11aa aaa0 11yy yyyy yyyx xxxx xxxx mov adx (e), ady
0001 11aa aaa1 00yy yyyy yyyx xxxx xxxx mov adx, ady (e)
0001 11aa aaa0 0?yy yyyy yyyx xxxx xxxx mov adx, ady (e) (the ? is not a + 0x200 select, cf. VR copro code)
0001 11aa aaa0 10yy yyyy yyyx xxxx xxxx mov adx (e), ady
0001 11aa aaa0 11yy yyyy yyyx xxxx xxxx mov adx, ady + 0x200
0001 11aa aaa1 00yy yyyy yyyx xxxx xxxx mov adx + 0x200, ady
0001 11aa aaa1 01yy yyyy yyyx xxxx xxxx mov adx (o), ady
0001 11aa aaa1 1100 0rrr rrry yyyy yyyy mov r, ady (e)
0001 11aa aaa1 1100 1rrr rrry yyyy yyyy mov r, ady
0001 11aa aaa1 1101 1rrr rrrx xxxx xxxx mov adx (e), r
0001 11aa aaa1 1110 0rrr rrrx xxxx xxxx mov adx, r
0001 11aa aaa1 1100 0rrr rrry yyyy yyyy mov r, ady
0001 11aa aaa1 1100 1rrr rrry yyyy yyyy mov r, ady (e)
0001 11aa aaa1 1101 0rrr rrry yyyy yyyy mov ady + 0x200, r
0001 11aa aaa1 1101 1rrr rrry yyyy yyyy mov ady, r
0001 11aa aaa1 1110 0rrr rrry yyyy yyyy mov ady (e), r
0001 11aa aaa1 1110 1rrr rrrx xxxx xxxx mov adx (o), r
0001 11aa aaa1 1111 0rrr rrr. ..ss ssss mov s, r
0011 011. .... 101. vvvv vvvv vvvv vvvv stmh (bit0 = fp, bit 1-2 = rounding mode, rest unused)
0011 10rr vvvv vvvv vvvv vvvv vvvv vvvv lipl/lia/lib/lid #v
0011 11aa aaa. 000. rrrr rrrr rrrr rrrr clr0 <reglist>
0011 11aa aaa. 001. ffff ffff ffff ffff clr1 flags
0011 11aa aaa. 010. 0... .... nnnn nnnn rep #n
0011 11aa aaa. 010. 1... .... ..11 0100 rep rpc
0011 11aa aaa. 011. ffff ffff ffff ffff set flags
0011 11.a aaaa 000. rrrr rrrr rrrr rrrr clr0 <reglist>
0011 11.a aaaa 001. ffff ffff ffff ffff clr1 flags
0011 11.a aaaa 010. 0... .... nnnn nnnn rep #n (0 = 0x100)
0011 11.a aaaa 010. 1... .... ..11 0100 rep rpc
0011 11.a aaaa 011. ffff ffff ffff ffff set flags
010r rrrr .... .... vvvv vvvv vvvv vvvv ldi #v, b0/.../- (bank 0/1) (h/l is special and targets exponent/mantissa size 8/24)
01rr rrrr vvvv vvvv vvvv vvvv vvvv vvvv ldi #v, r (actual v size varies 3-24 depending on register)
1i11 11.c cccc 0000 aaaa aaaa aaaa aaaa brif cond #a
1i11 11.c cccc 0010 .0.. ...x xxxx xxxx brul cond (adx)
@ -65,10 +72,17 @@
1i11 11.c cccc 0110 .1.. .... ...r rrrr bsul cond r
1i11 11.c cccc 1010 .... .... .... .... rtif cond
1i11 11.c cccc 1100 .rrr rrrx xxxx xxxx ldif cond adx, r
1011 11.c 0110 1110 .... .... .... .... iret
1011 11.1 0110 1110 .... .... .... .... iret
Top 3 bits = instruction group, except when it isn't.
Conditions are 5 bits, but only a subset is known, see condition()
Alu can theorically be on C or D registers, but since C doesn't
exist, we don't know how C access is encoded. The operation
itself is 5-bits for the "full" alu range.
*/
@ -109,24 +123,28 @@ std::string mb86233_disassembler::regs(u32 reg)
return regnames[reg & 0x3f];
}
std::string mb86233_disassembler::memory(u32 reg, bool x1)
std::string mb86233_disassembler::memory(u32 reg, bool x1, bool bank)
{
std::ostringstream stream;
switch(reg & 0x180) {
case 0x000:
if((reg & 0x7f) < 10)
util::stream_format(stream, "$%d", reg & 0x7f );
if(bank)
util::stream_format(stream, "$0x%x", 0x200 | (reg & 0x7f));
else if((reg & 0x7f) < 10)
util::stream_format(stream, "$%d", reg & 0x7f);
else
util::stream_format(stream, "$0x%x", reg & 0x7f );
util::stream_format(stream, "$0x%x", reg & 0x7f);
break;
case 0x080:
if(reg & 0x7f) {
if((reg & 0x7f) < 10)
util::stream_format(stream, "$%d", reg & 0x7f );
if(bank || (reg & 0x7f)) {
if(bank)
util::stream_format(stream, "$0x%x", 0x200 | (reg & 0x7f));
else if((reg & 0x7f) < 10)
util::stream_format(stream, "$%d", reg & 0x7f);
else
util::stream_format(stream, "$0x%x", reg & 0x7f );
util::stream_format(stream, "$0x%x", reg & 0x7f);
}
stream << '(';
@ -139,8 +157,14 @@ std::string mb86233_disassembler::memory(u32 reg, bool x1)
break;
case 0x100:
if(reg & 0x7f)
util::stream_format(stream, "$0x%x", reg & 0x7f );
if(bank || (reg & 0x7f)) {
if(bank)
util::stream_format(stream, "$0x%x", 0x200 | (reg & 0x7f));
else if((reg & 0x7f) < 10)
util::stream_format(stream, "$%d", reg & 0x7f);
else
util::stream_format(stream, "$0x%x", reg & 0x7f);
}
stream << '(';
@ -152,7 +176,7 @@ std::string mb86233_disassembler::memory(u32 reg, bool x1)
break;
case 0x180:
stream << (reg & 0x40 ? "$[" : "$(");
stream << (reg & 0x40 ? "[" : "(");
if(x1) {
if(!(reg & 0x20))
util::stream_format(stream, "bx1");
@ -179,6 +203,10 @@ std::string mb86233_disassembler::memory(u32 reg, bool x1)
}
stream << (reg & 0x40 ? ']' : ')');
if(bank)
stream << "+0x200";
break;
}
@ -204,13 +232,14 @@ std::string mb86233_disassembler::alu0_func(u32 alu)
case 0x0b: util::stream_format(stream, "fabd"); break;
case 0x0c: util::stream_format(stream, "fsmd"); break;
case 0x0d: util::stream_format(stream, "fspd"); break;
case 0x0e: util::stream_format(stream, "cifd"); break;
case 0x0f: util::stream_format(stream, "cfid"); break;
case 0x0e: util::stream_format(stream, "cxfd"); break;
case 0x0f: util::stream_format(stream, "cfxd"); break;
case 0x10: util::stream_format(stream, "fdvd"); break;
case 0x11: util::stream_format(stream, "fned"); break;
// 12
case 0x13: util::stream_format(stream, "d=b+a"); break;
case 0x14: util::stream_format(stream, "d=b-a"); break;
// 15
case 0x16: util::stream_format(stream, "lsrd"); break;
case 0x17: util::stream_format(stream, "lsld"); break;
case 0x18: util::stream_format(stream, "asrd"); break;
@ -243,19 +272,19 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
switch(op) {
case 0:
util::stream_format(stream, "lab %s, %s (io)", memory(r1, false), memory(r2, true));
util::stream_format(stream, "lab %s, %s (e)", memory(r1, false, false), memory(r2, true, false));
break;
case 3:
util::stream_format(stream, "lab %s, %s", memory(r1, false), memory(r2, true));
util::stream_format(stream, "lab %s, %s", memory(r1, false, false), memory(r2, true, true));
break;
case 4:
util::stream_format(stream, "lab %s, %s (e)", memory(r1, false), memory(r2, true));
util::stream_format(stream, "lab %s, %s", memory(r1, false, true), memory(r2, true, false));
break;
default:
util::stream_format(stream, "lab {%d} %s, %s", op, memory(r1, false), memory(r2, true));
util::stream_format(stream, "lab {%d} %s, %s", op, memory(r1, false, false), memory(r2, true, false));
break;
}
break;
@ -278,53 +307,53 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
switch(op) {
case 0:
util::stream_format(stream, "mov %s, %s", memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov {0} %s, %s (e)", memory(r1, false, false), memory(r2, true, false));
break;
case 1:
util::stream_format(stream, "mov %s, %s (io)", memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov {1} %s, %s (e)", memory(r1, false, false), memory(r2, true, false));
break;
case 2:
util::stream_format(stream, "mov %s (io), %s", memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov %s (e), %s", memory(r1, false, false), memory(r2, true, false));
break;
case 3:
util::stream_format(stream, "mov %s, %s (e)", memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov %s, %s", memory(r1, false, false), memory(r2, true, true));
break;
case 4:
util::stream_format(stream, "mov %s (e), %s", memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov %s, %s", memory(r1, false, true), memory(r2, true, false));
break;
case 5:
util::stream_format(stream, "mov %s (o), %s", memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov %s (o), %s", memory(r1, false, false), memory(r2, true, false));
break;
case 7: {
switch(r2 >> 6) {
case 0:
util::stream_format(stream, "mov %s, %s", regs(r2 & 0x3f), memory(r1, true));
util::stream_format(stream, "mov %s, %s", regs(r2 & 0x3f), memory(r1, true, false));
break;
case 1:
util::stream_format(stream, "mov %s, %s (io)", regs(r2 & 0x3f), memory(r1, true));
util::stream_format(stream, "mov %s, %s (e)", regs(r2 & 0x3f), memory(r1, true, false));
break;
case 2:
util::stream_format(stream, "mov %s (e), %s", memory(r1, false), regs(r2 & 0x3f));
util::stream_format(stream, "mov %s, %s", memory(r1, true, true), regs(r2 & 0x3f));
break;
case 3:
util::stream_format(stream, "mov %s, %s", memory(r1, false), regs(r2 & 0x3f));
util::stream_format(stream, "mov %s, %s", memory(r1, true, false), regs(r2 & 0x3f));
break;
case 4:
util::stream_format(stream, "mov %s (io), %s", memory(r1, false), regs(r2 & 0x3f));
util::stream_format(stream, "mov %s (e), %s", memory(r1, true, false), regs(r2 & 0x3f));
break;
case 5:
util::stream_format(stream, "mov %s (o), %s", memory(r1, false), regs(r2 & 0x3f));
util::stream_format(stream, "mov %s (o), %s", memory(r1, false, false), regs(r2 & 0x3f));
break;
case 6:
@ -335,13 +364,33 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
break;
default:
util::stream_format(stream, "mov {r2 %d} %s, %s", r2 >> 6, memory(r1, true), regs(r2 & 0x3f));
util::stream_format(stream, "mov {r2 %d} %s, %s", r2 >> 6, memory(r1, false, false), regs(r2 & 0x3f));
break;
}
break;
}
default:
util::stream_format(stream, "mov {%d} %s, %s", op, memory(r1, false), memory(r2, true));
util::stream_format(stream, "mov {%d} %s, %s", op, memory(r1, false, false), memory(r2, true, false));
break;
}
break;
}
case 0x0d: { // stm/clm
u32 sub2 = (opcode >> 17) & 7;
switch(sub2) {
case 5: {
util::stream_format(stream, "stmh");
if(opcode & 0x0001)
util::stream_format(stream, " fp");
static const char *const round_mode[4] = { "rn", "rp", "rm", "rz" };
util::stream_format(stream, " %s", round_mode[(opcode >> 1) & 3]);
break;
}
default:
util::stream_format(stream, "unk %02x.%x", opcode >> 26, sub2);
break;
}
break;
@ -354,7 +403,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
}
case 0x0f: { // rep/clr0/clr1/set
u32 alu = (opcode >> 21) & 0x1f;
u32 alu = (opcode >> 20) & 0x1f;
u32 sub2 = (opcode >> 17) & 7;
if(alu)
@ -405,6 +454,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
}
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
util::stream_format(stream, "ldi #0x%x, %s", opcode & 0xffffff, regnames[(opcode >> 24) & 0x3f]); break;
break;
@ -424,7 +474,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
if(opcode & 0x4000)
util::stream_format(stream, "%s", regs(opcode & 0x1f));
else
util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false));
util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false, false));
break;
case 2:
@ -436,7 +486,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
if(opcode & 0x4000)
util::stream_format(stream, "%s", regs(opcode & 0x1f));
else
util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false));
util::stream_format(stream, "(%s)", memory(opcode & 0x1ff, false, false));
break;
case 5:
@ -444,7 +494,7 @@ offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const
break;
case 6:
util::stream_format(stream, "ldif %s %s, %s", condition(cond, invert), memory(data & 0x1ff, false), regs((data >> 9) & 0x3f));
util::stream_format(stream, "ldif %s %s, %s", condition(cond, invert), memory(data & 0x1ff, false, false), regs((data >> 9) & 0x3f));
break;
case 7:

View File

@ -19,7 +19,7 @@ private:
static const char *const regnames[0x40];
static std::string condition(unsigned int cond, bool invert);
static std::string regs(u32 reg);
static std::string memory(u32 reg, bool x1);
static std::string memory(u32 reg, bool x1, bool bank);
static std::string alu0_func(u32 alu);
};

View File

@ -263,6 +263,9 @@ mb86235_device::mb86235_device(const machine_config &mconfig, const char *tag, d
, m_program_config("program", ENDIANNESS_LITTLE, 64, 32, -3)
, m_dataa_config("data_a", ENDIANNESS_LITTLE, 32, 24, -2, address_map_constructor(FUNC(mb86235_device::internal_abus), this))
, m_datab_config("data_b", ENDIANNESS_LITTLE, 32, 10, -2, address_map_constructor(FUNC(mb86235_device::internal_bbus), this))
, m_fifoin(*this, finder_base::DUMMY_TAG)
, m_fifoout0(*this, finder_base::DUMMY_TAG)
, m_fifoout1(*this, finder_base::DUMMY_TAG)
, m_cache(CACHE_SIZE + sizeof(mb86235_internal_state))
, m_drcuml(nullptr)
, m_drcfe(nullptr)
@ -292,55 +295,3 @@ std::unique_ptr<util::disasm_interface> mb86235_device::create_disassembler()
{
return std::make_unique<mb86235_disassembler>();
}
void mb86235_device::fifoin_w(uint32_t data)
{
if (m_core->fifoin.num >= FIFOIN_SIZE)
{
fatalerror("fifoin_w: pushing to full fifo");
}
//printf("FIFOIN push %08X\n", data);
m_core->fifoin.data[m_core->fifoin.wpos] = data;
m_core->fifoin.wpos++;
m_core->fifoin.wpos &= FIFOIN_SIZE-1;
m_core->fifoin.num++;
}
bool mb86235_device::is_fifoin_empty()
{
return m_core->fifoin.num == 0;
}
bool mb86235_device::is_fifoin_full()
{
return m_core->fifoin.num >= FIFOIN_SIZE;
}
uint32_t mb86235_device::fifoout0_r()
{
if (m_core->fifoout0.num == 0)
{
fatalerror("fifoout0_r: reading from empty fifo");
}
uint32_t data = m_core->fifoout0.data[m_core->fifoout0.rpos];
m_core->fifoout0.rpos++;
m_core->fifoout0.rpos &= FIFOOUT0_SIZE - 1;
m_core->fifoout0.num--;
return data;
}
bool mb86235_device::is_fifoout0_full()
{
return m_core->fifoout0.num >= FIFOOUT0_SIZE;
}
bool mb86235_device::is_fifoout0_empty()
{
return m_core->fifoout0.num == 0;
}

View File

@ -13,10 +13,21 @@
#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "machine/gen_fifo.h"
#define MCFG_MB86235_FIFOIN(tag) \
downcast<mb86235_device &>(*device).set_fifoin_tag(tag);
#define MCFG_MB86235_FIFOOUT0(tag) \
downcast<mb86235_device &>(*device).set_fifoout0_tag(tag);
#define MCFG_MB86235_FIFOOUT1(tag) \
downcast<mb86235_device &>(*device).set_fifoout1_tag(tag);
class mb86235_frontend;
class mb86235_device : public cpu_device
{
friend class mb86235_frontend;
@ -25,6 +36,10 @@ public:
// construction/destruction
mb86235_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t clock);
void set_fifoin_tag(const char *tag) { m_fifoin.set_tag(tag); }
void set_fifoout0_tag(const char *tag) { m_fifoout0.set_tag(tag); }
void set_fifoout1_tag(const char *tag) { m_fifoout1.set_tag(tag); }
void unimplemented_op();
void unimplemented_alu();
void unimplemented_control();
@ -33,13 +48,6 @@ public:
void pcs_overflow();
void pcs_underflow();
void fifoin_w(uint32_t data);
bool is_fifoin_full();
bool is_fifoin_empty();
uint32_t fifoout0_r();
bool is_fifoout0_empty();
bool is_fifoout0_full();
enum
{
MB86235_PC = 1,
@ -53,10 +61,6 @@ public:
MB86235_ST
};
static constexpr int FIFOIN_SIZE = 16;
static constexpr int FIFOOUT0_SIZE = 16;
static constexpr int FIFOOUT1_SIZE = 16;
void internal_abus(address_map &map);
void internal_bbus(address_map &map);
protected:
@ -102,14 +106,6 @@ private:
uint32_t md;
};
struct fifo
{
int rpos;
int wpos;
int num;
uint32_t data[16];
};
struct fifo_state
{
uint32_t pc;
@ -164,9 +160,6 @@ private:
float fp0;
bool delay_slot;
fifo fifoin;
fifo fifoout0;
fifo fifoout1;
fifo_state cur_fifo_state;
};
@ -177,18 +170,16 @@ private:
uml::code_handle *m_entry; /* entry point */
uml::code_handle *m_nocode; /* nocode exception handler */
uml::code_handle *m_out_of_cycles; /* out of cycles exception handler */
uml::code_handle *m_clear_fifo_in;
uml::code_handle *m_clear_fifo_out0;
uml::code_handle *m_clear_fifo_out1;
uml::code_handle *m_read_fifo_in;
uml::code_handle *m_write_fifo_out0;
uml::code_handle *m_write_fifo_out1;
uml::code_handle *m_read_abus;
uml::code_handle *m_write_abus;
address_space_config m_program_config;
address_space_config m_dataa_config;
address_space_config m_datab_config;
optional_device<generic_fifo_u32_device> m_fifoin;
optional_device<generic_fifo_u32_device> m_fifoout0;
optional_device<generic_fifo_u32_device> m_fifoout1;
drc_cache m_cache;
std::unique_ptr<drcuml_state> m_drcuml;
std::unique_ptr<mb86235_frontend> m_drcfe;
@ -216,7 +207,6 @@ private:
void static_generate_entry_point();
void static_generate_nocode_handler();
void static_generate_out_of_cycles();
void static_generate_fifo();
void static_generate_memory_accessors();
void generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc);
void generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param, bool allow_exception);
@ -244,6 +234,19 @@ private:
bool aluop_has_result(int aluop);
bool check_previous_op_stall();
// UML is sad...
u32 m_cur_value;
static void clear_fifoin(void *param);
static void clear_fifoout0(void *param);
static void clear_fifoout1(void *param);
static void read_fifoin(void *param);
static void write_fifoout0(void *param);
static void write_fifoout1(void *param);
static void empty_fifoin(void *param);
static void full_fifoout0(void *param);
static void full_fifoout1(void *param);
// interpreter
void execute_op(uint32_t h, uint32_t l);
void do_alu1(uint32_t h, uint32_t l);

View File

@ -78,17 +78,6 @@
#define MU_CALC_REQUIRED ((desc->regreq[1] & 0x1000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
#define MD_CALC_REQUIRED ((desc->regreq[1] & 0x2000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
#define FIFOIN_RPOS uml::mem(&m_core->fifoin.rpos)
#define FIFOIN_WPOS uml::mem(&m_core->fifoin.wpos)
#define FIFOIN_NUM uml::mem(&m_core->fifoin.num)
#define FIFOOUT0_RPOS uml::mem(&m_core->fifoout0.rpos)
#define FIFOOUT0_WPOS uml::mem(&m_core->fifoout0.wpos)
#define FIFOOUT0_NUM uml::mem(&m_core->fifoout0.num)
#define FIFOOUT1_RPOS uml::mem(&m_core->fifoout1.rpos)
#define FIFOOUT1_WPOS uml::mem(&m_core->fifoout1.wpos)
#define FIFOOUT1_NUM uml::mem(&m_core->fifoout1.num)
inline void mb86235_device::alloc_handle(uml::code_handle *&handleptr, const char *name)
{
if (!handleptr)
@ -390,89 +379,58 @@ void mb86235_device::static_generate_out_of_cycles()
block.end();
}
void mb86235_device::static_generate_fifo()
void mb86235_device::clear_fifoin(void *param)
{
{
// clear fifo in
drcuml_block &block(m_drcuml->begin_block(20));
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_fifoin->clear();
}
alloc_handle(m_clear_fifo_in, "clear_fifo_in");
UML_HANDLE(block, *m_clear_fifo_in);
UML_MOV(block, FIFOIN_NUM, 0);
UML_MOV(block, FIFOIN_RPOS, 0);
UML_MOV(block, FIFOIN_WPOS, 0);
UML_RET(block);
void mb86235_device::clear_fifoout0(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_fifoout0->clear();
}
block.end();
}
{
// clear fifo out0
drcuml_block &block(m_drcuml->begin_block(20));
void mb86235_device::clear_fifoout1(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_fifoout1->clear();
}
alloc_handle(m_clear_fifo_out0, "clear_fifo_out0");
UML_HANDLE(block, *m_clear_fifo_out0);
UML_MOV(block, FIFOOUT0_NUM, 0);
UML_MOV(block, FIFOOUT0_RPOS, 0);
UML_MOV(block, FIFOOUT0_WPOS, 0);
UML_RET(block);
void mb86235_device::read_fifoin(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_cur_value = cpu->m_fifoin->pop();
}
block.end();
}
{
// clear fifo out1
drcuml_block &block(m_drcuml->begin_block(20));
void mb86235_device::write_fifoout0(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_fifoout0->push(u32(cpu->m_cur_value));
}
alloc_handle(m_clear_fifo_out1, "clear_fifo_out1");
UML_HANDLE(block, *m_clear_fifo_out1);
UML_MOV(block, FIFOOUT1_NUM, 0);
UML_MOV(block, FIFOOUT1_RPOS, 0);
UML_MOV(block, FIFOOUT1_WPOS, 0);
UML_RET(block);
void mb86235_device::write_fifoout1(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_fifoout1->push(u32(cpu->m_cur_value));
}
block.end();
}
{
// read fifo in
// I0 = return value
drcuml_block &block(m_drcuml->begin_block(32));
alloc_handle(m_read_fifo_in, "read_fifo_in");
UML_HANDLE(block, *m_read_fifo_in);
UML_MOV(block, I1, FIFOIN_RPOS);
UML_LOAD(block, I0, m_core->fifoin.data, I1, SIZE_QWORD, SCALE_x8);
UML_ADD(block, I1, I1, 1);
UML_AND(block, I1, I1, FIFOIN_SIZE-1);
UML_MOV(block, FIFOIN_RPOS, I1);
UML_SUB(block, FIFOIN_NUM, FIFOIN_NUM, 1);
UML_RET(block);
void mb86235_device::empty_fifoin(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_cur_value = cpu->m_fifoin->is_empty();
}
block.end();
}
{
// write fifo out0
// I0 = input value
drcuml_block &block(m_drcuml->begin_block(32));
alloc_handle(m_write_fifo_out0, "write_fifo_out0");
UML_HANDLE(block, *m_write_fifo_out0);
UML_MOV(block, I1, FIFOOUT0_WPOS);
UML_STORE(block, m_core->fifoout0.data, I1, I0, SIZE_QWORD, SCALE_x8);
UML_ADD(block, I1, I1, 1);
UML_AND(block, I1, I1, FIFOOUT0_SIZE - 1);
UML_MOV(block, FIFOOUT0_WPOS, I1);
UML_ADD(block, FIFOOUT0_NUM, FIFOOUT0_NUM, 1);
UML_RET(block);
void mb86235_device::full_fifoout0(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_cur_value = cpu->m_fifoout0->is_full();
}
block.end();
}
{
// write fifo out1
drcuml_block &block(m_drcuml->begin_block(32));
alloc_handle(m_write_fifo_out1, "write_fifo_out1");
UML_HANDLE(block, *m_write_fifo_out1);
// TODO
UML_RET(block);
block.end();
}
void mb86235_device::full_fifoout1(void *param)
{
mb86235_device *cpu = (mb86235_device *)param;
cpu->m_cur_value = cpu->m_fifoout1->is_full();
}
void mb86235_device::static_generate_memory_accessors()
@ -542,9 +500,6 @@ void mb86235_device::flush_cache()
static_generate_nocode_handler();
static_generate_out_of_cycles();
// generate utility functions
static_generate_fifo();
// generate exception handlers
// generate memory accessors
@ -690,8 +645,13 @@ void mb86235_device::generate_reg_read(drcuml_block &block, compiler_state &comp
break;
case 0x31: // FI
UML_CALLH(block, *m_read_fifo_in);
UML_MOV(block, dst, I0);
if (m_fifoin)
{
UML_CALLC(block, read_fifoin, this);
UML_MOV(block, dst, mem(&m_cur_value));
}
else
UML_MOV(block, dst, 0);
break;
default:
@ -747,8 +707,11 @@ void mb86235_device::generate_reg_write(drcuml_block &block, compiler_state &com
break;
case 0x32: // FO0
UML_MOV(block, I0, src);
UML_CALLH(block, *m_write_fifo_out0);
if (m_fifoout0)
{
UML_MOV(block, mem(&m_cur_value), src);
UML_CALLC(block, write_fifoout0, this);
}
break;
case 0x34: // PDR
@ -850,11 +813,12 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil
}
// insert FIFO IN check if needed
if (fifoin_check)
if (fifoin_check && m_fifoin)
{
uml::code_label const not_empty = compiler.labelnum++;
UML_CMP(block, FIFOIN_NUM, 0);
UML_JMPc(block, COND_G, not_empty);
UML_CALLC(block, empty_fifoin, this);
UML_CMP(block, mem(&m_cur_value), 1);
UML_JMPc(block, COND_NE, not_empty);
UML_MOV(block, mem(&m_core->icount), 0);
UML_EXH(block, *m_out_of_cycles, desc->pc);
@ -863,11 +827,12 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil
}
// insert FIFO OUT0 check if needed
if (fifoout0_check)
if (fifoout0_check && m_fifoout0)
{
uml::code_label const not_full = compiler.labelnum++;
UML_CMP(block, FIFOOUT0_NUM, FIFOOUT0_SIZE - 1);
UML_JMPc(block, COND_L, not_full);
UML_CALLC(block, full_fifoout0, this);
UML_CMP(block, mem(&m_cur_value), 1);
UML_JMPc(block, COND_NE, not_full);
UML_MOV(block, mem(&m_core->icount), 0);
UML_EXH(block, *m_out_of_cycles, desc->pc);
@ -876,11 +841,12 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil
}
// insert FIFO OUT1 check if needed
if (fifoout1_check)
if (fifoout1_check && m_fifoout1)
{
uml::code_label const not_full = compiler.labelnum++;
UML_CMP(block, FIFOOUT1_NUM, FIFOOUT1_SIZE - 1);
UML_JMPc(block, COND_L, not_full);
UML_CALLC(block, full_fifoout1, this);
UML_CMP(block, mem(&m_cur_value), 1);
UML_JMPc(block, COND_NE, not_full);
UML_MOV(block, mem(&m_core->icount), 0);
UML_EXH(block, *m_out_of_cycles, desc->pc);
@ -1573,17 +1539,25 @@ void mb86235_device::generate_control(drcuml_block &block, compiler_state &compi
case 0x03: //
if (ef1 == 1) // CLRFI
UML_CALLH(block, *m_clear_fifo_in);
{
if (m_fifoin)
UML_CALLC(block, clear_fifoin, this);
}
else if (ef1 == 2) // CLRFO
{
UML_CALLH(block, *m_clear_fifo_out0);
UML_CALLH(block, *m_clear_fifo_out1);
if (m_fifoout0)
UML_CALLC(block, clear_fifoout0, this);
if (m_fifoout1)
UML_CALLC(block, clear_fifoout1, this);
}
else if (ef1 == 3) // CLRF
{
UML_CALLH(block, *m_clear_fifo_in);
UML_CALLH(block, *m_clear_fifo_out0);
UML_CALLH(block, *m_clear_fifo_out1);
if (m_fifoin)
UML_CALLC(block, clear_fifoin, this);
if (m_fifoout0)
UML_CALLC(block, clear_fifoout0, this);
if (m_fifoout1)
UML_CALLC(block, clear_fifoout1, this);
}
break;

View File

@ -752,7 +752,7 @@ inline uint32_t mb86235_device::get_transfer_reg(uint8_t which)
case 1: // FI
{
FCLR(IFE);
if(is_fifoin_empty() == true)
if(m_fifoin->is_empty())
{
FSET(IFE);
m_core->cur_fifo_state.has_stalled = true;
@ -765,13 +765,7 @@ inline uint32_t mb86235_device::get_transfer_reg(uint8_t which)
}
m_core->cur_fifo_state.has_stalled = false;
uint32_t res = (uint32_t)m_core->fifoin.data[m_core->fifoin.rpos];
m_core->fifoin.rpos++;
m_core->fifoin.rpos &= FIFOIN_SIZE-1;
m_core->fifoin.num--;
return res;
return m_fifoin->pop();
}
}
}
@ -827,24 +821,23 @@ inline void mb86235_device::set_transfer_reg(uint8_t which, uint32_t value)
break;
case 2: // FO0
FCLR(OFF);
if(is_fifoout0_full() == true)
if(m_fifoout0)
{
FSET(OFF);
m_core->cur_fifo_state.has_stalled = true;
if((m_core->st & RP) == 0)
m_core->cur_fifo_state.pc = m_core->ppc;
if(m_fifoout0->is_full())
{
FSET(OFF);
m_core->cur_fifo_state.has_stalled = true;
if((m_core->st & RP) == 0)
m_core->cur_fifo_state.pc = m_core->ppc;
//else
// fatalerror("check me (writes)");
return;
}
//else
// fatalerror("check me (writes)");
return;
}
m_core->cur_fifo_state.has_stalled = false;
m_core->fifoout0.data[m_core->fifoin.wpos] = value;
m_core->fifoout0.wpos++;
m_core->fifoout0.wpos &= FIFOIN_SIZE-1;
m_core->fifoout0.num++;
m_core->cur_fifo_state.has_stalled = false;
m_fifoout0->push(u32(value));
}
break;
case 4: m_core->pdr = value; break;
case 5: m_core->ddr = value; break;
@ -1193,21 +1186,18 @@ void mb86235_device::do_control(uint32_t h, uint32_t l)
case 0x03: // CLRF
if(ef1 & 1) // clear fifo in (CLRFI)
{
m_core->fifoin.wpos = 0;
m_core->fifoin.rpos = 0;
m_core->fifoin.num = 0;
if(m_fifoin)
m_fifoin->clear();
FSET(IFE);
FCLR(IFF);
m_core->cur_fifo_state.has_stalled = false;
}
if(ef1 & 2) // clear fifo0/1 out (CLRFO)
{
m_core->fifoout0.wpos = 0;
m_core->fifoout0.rpos = 0;
m_core->fifoout0.num = 0;
m_core->fifoout1.wpos = 0;
m_core->fifoout1.rpos = 0;
m_core->fifoout1.num = 0;
if(m_fifoout0)
m_fifoout0->clear();
if(m_fifoout1)
m_fifoout1->clear();
FSET(OFE);
FCLR(OFF);
m_core->cur_fifo_state.has_stalled = false;

View File

@ -0,0 +1,201 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
#include "emu.h"
#include "gen_fifo.h"
template<typename T> generic_fifo_device_base<T>::generic_fifo_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
m_empty_cb(*this),
m_full_cb(*this),
m_on_fifo_empty_pre_sync([](){}),
m_on_fifo_empty_post_sync([](){}),
m_on_fifo_unempty([](){}),
m_on_fifo_full_post_sync([](){}),
m_on_fifo_unfull([](){}),
m_on_push([](){}),
m_on_pop([](){}),
m_sync_empty(nullptr),
m_sync_full(nullptr),
m_size(0),
m_empty_triggered(false),
m_full_triggered(false)
{
}
template<typename T> void generic_fifo_device_base<T>::clear()
{
bool was_empty = is_empty();
bool was_full = m_size && is_full();
m_values.clear();
m_extra_values.clear();
if(m_sync_empty) {
m_sync_empty->adjust(attotime::never);
m_sync_full->adjust(attotime::never);
}
if(was_full)
m_full_cb(false);
if(m_full_triggered) {
m_full_triggered = false;
m_on_fifo_unfull();
}
if(!was_empty)
m_empty_cb(true);
}
template<typename T> void generic_fifo_device_base<T>::device_start()
{
m_empty_cb.resolve_safe();
m_full_cb.resolve_safe();
m_sync_empty = timer_alloc(0);
m_sync_full = timer_alloc(1);
// This is not saving the fifo, let's hope it's empty...
save_item(NAME(m_size));
save_item(NAME(m_empty_triggered));
save_item(NAME(m_full_triggered));
}
template<typename T> void generic_fifo_device_base<T>::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch(id) {
case T_FULL: {
// Add the extra values in if there's space
bool was_empty = is_empty();
bool was_full = is_full();
while(!m_extra_values.empty() && !is_full()) {
T t(std::move(m_extra_values.front()));
m_extra_values.erase(m_extra_values.begin());
m_values.emplace_back(std::move(t));
}
// Adjust devcb lines as needed
if(was_empty && !is_empty())
set_empty_cb(false);
if(!was_full && is_full())
set_full_cb(true);
// Are there still values that don't fit?
if(!m_extra_values.empty()) {
// If yes, stop the source if not done yet
if(!m_full_triggered) {
m_full_triggered = true;
m_on_fifo_full_post_sync();
}
}
break;
}
case T_EMPTY: {
// Sync was called for a fifo empty, is it still empty?
if(is_empty()) {
// If yes, stop the destination if not done yet
if(!m_empty_triggered) {
m_empty_triggered = true;
m_on_fifo_empty_post_sync();
}
}
break;
}
}
}
template<typename T> T generic_fifo_device_base<T>::pop()
{
// Are we empty?
if(is_empty()) {
// First, trigger the sync
m_sync_empty->adjust(attotime::zero);
// Then fire the callback
m_on_fifo_empty_pre_sync();
return T();
} else {
// Prepare the value
bool was_full = is_full();
T t(std::move(m_values.front()));
m_values.erase(m_values.begin());
// If we have extra values and the source is stopped,
// push one in, and possibly restart the source.
if(!m_extra_values.empty()) {
T t1(std::move(m_extra_values.front()));
m_extra_values.erase(m_extra_values.begin());
m_values.emplace_back(std::move(t1));
if(m_extra_values.empty()) {
// We don't have any extra values left, we can unblock
// the source.
if(m_full_triggered) {
m_full_triggered = false;
m_on_fifo_unfull();
}
}
}
// Update the devcb lines
if(is_empty())
m_empty_cb(true);
if(was_full && !is_full())
m_full_cb(false);
// We did a pop
m_on_pop();
return std::move(t);
}
}
template<typename T> void generic_fifo_device_base<T>::push(T &&t)
{
// Are we already overflowed?
if(!m_extra_values.empty())
// If yes, just add to the overflow queue
m_extra_values.emplace_back(std::move(t));
else if(is_full()) {
// Otherwise, are we full?
// If yes start the overflow queue
m_extra_values.emplace_back(std::move(t));
// And trigger the sync
m_sync_full->adjust(attotime::zero);
} else {
// Add the value to the fifo
bool was_empty = is_empty();
m_values.emplace_back(std::move(t));
// Update the devcb lines
if(was_empty)
m_empty_cb(false);
if(is_full())
m_full_cb(true);
// Unblock the destination if needed
if(m_empty_triggered) {
m_empty_triggered = false;
m_on_fifo_unempty();
}
}
// We did a push
m_on_push();
}
template class generic_fifo_device_base<u32>;
generic_fifo_u32_device::generic_fifo_u32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
generic_fifo_device_base<u32>(mconfig, GENERIC_FIFO_U32, tag, owner, clock)
{
}
DEFINE_DEVICE_TYPE(GENERIC_FIFO_U32, generic_fifo_u32_device, "generic_fifo_u32_device", "Generic fifo, u32 values")

View File

@ -0,0 +1,222 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
#ifndef MAME_MACHINE_GEN_FIFO_H
#define MAME_MACHINE_GEN_FIFO_H
/* Generic fifo device with flow control
*
*
* To use it:
* - Create the device, put push/pop in the appropriate memory maps of
* the source (push) and destination (pop) devices
* - Connect the empty/full callbacks in the MCFG if needed
* - Call setup at init with the size and the callbacks
* - Enjoy
*
* The design is such that destination devices must be able to be
* halted and to retrigger a fifo read when asked to, while the source
* devices only need to be haltable. There is some leeway on the
* source devices, e.g. no values are ever lost, so one can rudely
* overflow the fifo when the source is not a simple executable
* device.
*
* The callbacks:
* - on_fifo_empty_pre_sync:
* Called on a pop with an empty fifo. Must ask the destination
* to try again (e.g. ->stall() or equivalent). The pop itself
* will then return zero. Triggers a machine-wide sync, because
* the source device may be behind and could push data in the
* remaining of its timeslice.
*
* - on_fifo_empty_post_sync:
* Called after the sync consecutive to a pop with an empty fifo.
* It means that even with the source device synced the fifo is
* still empty. The destination device should be halted.
*
* - on_fifo_unempty:
* Called when the fifo is filled again after a call to
* on_fifo_empty_post_sync. The destination device should be
* restarted, the pop will succeed this time.
*
* - on_fifo_full_post_sync:
* When the source pushes in a full fifo, the extra value is
* stored and a machine sync is triggered to give a chance to the
* destination device to pop some of the fifo data in its
* remaining timeslice. If after the sync the fifo is still full,
* that callback is triggered. The source device should be halted.
*
* - on_fifo_unfull:
* Called when the fifo again has free space after a call to
* on_fifo_full_post_sync. The source device should be restarted.
*
* - on_push:
* Called when a new value was just pushed. That callback is
* usually not needed, but it can be useful when the destination
* is not an executable device but something hardcoded
* (rasterizer, etc).
*
* - on_pop:
* Called when a new value was just pushed. That callback is
* usually not needed, but it can be useful when the source is not
* an executable device but something hardcoded.
*
* Note: setup can be called multiple times, each call overrides the
* previous and clears the fifo.
*
* Note: the fifo element type T must be copyable if one wants to use
* peek(). It must trivially copyable and of size 1, 2, 4 or 8 bytes
* to use the memory-map accessors. Otherwise only movability is
* required.
*/
#define MCFG_GENERIC_FIFO_EMPTY_CALLBACK(_devcb) \
devcb = &downcast<screen_device &>(*device).set_empty_cb(DEVCB_##_devcb);
#define MCFG_GENERIC_FIFO_FULL_CALLBACK(_devcb) \
devcb = &downcast<screen_device &>(*device).set_full_cb(DEVCB_##_devcb);
template<typename T> class generic_fifo_device_base : public device_t {
public:
/* The general setup. Call be called multiple times, clears the fifo. */
void setup(size_t size,
std::function<void ()> on_fifo_empty_pre_sync,
std::function<void ()> on_fifo_empty_post_sync,
std::function<void ()> on_fifo_unempty,
std::function<void ()> on_fifo_full_post_sync,
std::function<void ()> on_fifo_unfull,
std::function<void ()> on_push = [](){},
std::function<void ()> on_pop = [](){}) {
m_on_fifo_empty_pre_sync = on_fifo_empty_pre_sync;
m_on_fifo_empty_post_sync = on_fifo_empty_post_sync;
m_on_fifo_unempty = on_fifo_unempty;
m_on_fifo_full_post_sync = on_fifo_full_post_sync;
m_on_fifo_unfull = on_fifo_unfull;
m_on_push = on_push;
m_on_pop = on_pop;
clear();
m_size = size;
}
/* Generic push/pop */
T pop();
void push(T &&value);
/* Indicates whether the fifo is empty or full. Note that a pop
on a full fifo does not ensure it will become non-full, there
may be extra values stored. Also, an empty fifo can fill up
from extra values later after a sync. */
bool is_empty() const { return m_values.empty(); }
bool is_full() const { return m_values.size() >= m_size; }
/* Empty the fifo. */
void clear();
/* Callbacks signalling empty (true)/nonempty (false) and full (true)/nonfull (false) */
template<class Object> devcb_base &set_empty_cb(Object &&object) { return m_empty_cb.set_callback(std::forward<Object>(object)); }
template<class Object> devcb_base &set_full_cb(Object &&object) { return m_full_cb.set_callback(std::forward<Object>(object)); }
/* Get the fifo current size - Note that real hardware usually
can't do that. May be bigger that the fifo size if some extra
values are stored. */
size_t size() const { return m_values.size() + m_extra_values.size(); }
/* Peek at a value in the fifo at an offset, 0 being the next
value to be popped, 1 the one following, etc - Note that real
hardware usually can't do that. Returns 0 or equivalent when
the offset is over the current fifo size. */
template <typename U=T> std::enable_if_t<(std::is_copy_constructible<T>::value && std::is_same<T, U>::value), T> peek(offs_t offset) const {
if(offset < m_values.size())
return m_values[offset];
offset -= m_values.size();
if(offset < m_extra_values.size())
return m_extra_values[offset];
return T();
}
protected:
generic_fifo_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual ~generic_fifo_device_base() = default;
/* These used to build memory accessors that can be put in a
memory map. They do the appropriate bit-identical type
conversions if you say make a fifo of floats and want to access
in with a 32-bits handler, which deals with 32-bits unsigned
integers. Don't be afraid by the apparently costly memcpy, the
compiler sees through it and removes it, and that's the only
standard-sanctioned way to do that.
They need to be upcalled in the deriving class from real
accessors though.
*/
template <typename U> std::enable_if_t<(std::is_trivially_copyable<T>::value && sizeof(T) == sizeof(U)), void> write_gen(U data) {
T t;
memcpy(&t, &data, sizeof(data));
push(std::move(t));
}
template <typename U> std::enable_if_t<(std::is_trivially_copyable<T>::value && sizeof(T) == sizeof(U)), U> read_gen() {
T t(pop());
U data;
memcpy(&data, &t, sizeof(data));
return data;
}
private:
// Timer IDs for sync on empty and full
enum timer_ids { T_EMPTY, T_FULL };
// Configured callbacks
devcb_write_line m_empty_cb;
devcb_write_line m_full_cb;
std::function<void ()> m_on_fifo_empty_pre_sync;
std::function<void ()> m_on_fifo_empty_post_sync;
std::function<void ()> m_on_fifo_unempty;
std::function<void ()> m_on_fifo_full_post_sync;
std::function<void ()> m_on_fifo_unfull;
std::function<void ()> m_on_push;
std::function<void ()> m_on_pop;
// The values are stored into two vectors for simplicity.
// m_values may become a rotating buffer when everything else
// works. m_extra_values should probably stay a vector, but could
// become a list.
std::vector<T> m_values;
std::vector<T> m_extra_values;
// The synchronization timers
emu_timer *m_sync_empty, *m_sync_full;
// Configured size of the fifo
size_t m_size;
// Notes whether the halting callbacks were triggered
bool m_empty_triggered, m_full_triggered;
virtual void device_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
};
class generic_fifo_u32_device : public generic_fifo_device_base<u32>
{
public:
generic_fifo_u32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~generic_fifo_u32_device() = default;
DECLARE_READ32_MEMBER(read) { return read_gen<u32>(); }
DECLARE_WRITE32_MEMBER(write) { write_gen(data); }
};
DECLARE_DEVICE_TYPE(GENERIC_FIFO_U32, generic_fifo_u32_device)
#endif

View File

@ -181,8 +181,8 @@ Notes:
*1 - Unpopulated position for Fujitsu MB8421
D70615GD-16 - NEC uPD70615GD-16-S V60 CPU, running at 16.000MHz (QFP120, clock 32 / 2)
315-5546A - Lattice GAL16V8A (DIP20)
315-5571 - Fujitsu MB86233 Geometrizer (IC57/IC58, QFP160) \
315-5572 - Fujitsu MB86233 Geometrizer (different code) (IC60/IC66, QFP160) / According to test mode, these chips are the TGPs
315-5571 - Fujitsu MB86233 Geometrizer (IC57/IC58, QFP160)
315-5572 - Fujitsu MB86233 Geometrizer (different code) (IC60/IC66, QFP160)
COPRO - Fujitsu MB86233 Coprocessor (QFP160), differs depending on game:
315-5573 - Virtua Racing, Virtua Formula (original for above board part number)
315-5711 - Wing War, Star Wars Arcade, Netmerc
@ -759,7 +759,8 @@ MACHINE_RESET_MEMBER(model1_state,model1)
{
membank("bank1")->set_base(memregion("maincpu")->base() + 0x1000000);
irq_init();
tgp_reset(!strcmp(machine().system().name, "swa") || !strcmp(machine().system().name, "wingwar") || !strcmp(machine().system().name, "wingwaru") || !strcmp(machine().system().name, "wingwarj") || !strcmp(machine().system().name, "wingwar360") || !strcmp(machine().system().name, "netmerc"));
copro_reset();
if (!strcmp(machine().system().name, "swa") )
{
m_sound_irq = 0;
@ -770,14 +771,6 @@ MACHINE_RESET_MEMBER(model1_state,model1)
}
}
MACHINE_RESET_MEMBER(model1_state,model1_vr)
{
membank("bank1")->set_base(memregion("maincpu")->base() + 0x1000000);
irq_init();
vr_tgp_reset();
m_sound_irq = 3;
}
READ16_MEMBER(model1_state::network_ctl_r)
{
if(offset)
@ -809,7 +802,7 @@ WRITE16_MEMBER(model1_state::md1_w)
// never executed
//if(0 && offset)
// return;
if(true && m_dump)
if(false)
logerror("TGP: md1_w %x, %04x @ %04x (%x)\n", offset, data, mem_mask, m_maincpu->pc());
}
@ -819,7 +812,7 @@ WRITE16_MEMBER(model1_state::md0_w)
// never executed
//if(0 && offset)
// return;
if(true && m_dump)
if(false)
logerror("TGP: md0_w %x, %04x @ %04x (%x)\n", offset, data, mem_mask, m_maincpu->pc());
}
@ -894,9 +887,9 @@ void model1_state::model1_mem(address_map &map)
map(0xc40000, 0xc40000).rw(m_m1uart, FUNC(i8251_device::data_r), FUNC(i8251_device::data_w));
map(0xc40002, 0xc40002).rw(m_m1uart, FUNC(i8251_device::status_r), FUNC(i8251_device::control_w));
map(0xd00000, 0xd00001).rw(this, FUNC(model1_state::model1_tgp_copro_adr_r), FUNC(model1_state::model1_tgp_copro_adr_w));
map(0xd20000, 0xd20003).w(this, FUNC(model1_state::model1_tgp_copro_ram_w));
map(0xd80000, 0xd80003).w(this, FUNC(model1_state::model1_tgp_copro_w)).mirror(0x10);
map(0xd00000, 0xd00001).rw(this, FUNC(model1_state::v60_copro_ram_adr_r), FUNC(model1_state::v60_copro_ram_adr_w));
map(0xd20000, 0xd20003).w(this, FUNC(model1_state::v60_copro_ram_w));
map(0xd80000, 0xd80003).w(this, FUNC(model1_state::v60_copro_fifo_w)).mirror(0x10);
map(0xdc0000, 0xdc0003).r(this, FUNC(model1_state::fifoin_status_r));
map(0xe00000, 0xe00001).nopw(); // Watchdog? IRQ ack? Always 0x20, usually on irq
@ -908,8 +901,8 @@ void model1_state::model1_mem(address_map &map)
void model1_state::model1_io(address_map &map)
{
map(0xd20000, 0xd20003).r(this, FUNC(model1_state::model1_tgp_copro_ram_r));
map(0xd80000, 0xd80003).r(this, FUNC(model1_state::model1_tgp_copro_r));
map(0xd20000, 0xd20003).r(this, FUNC(model1_state::v60_copro_ram_r));
map(0xd80000, 0xd80003).r(this, FUNC(model1_state::v60_copro_fifo_r));
}
void model1_state::model1_comm_mem(address_map &map)
@ -921,60 +914,6 @@ void model1_state::model1_comm_mem(address_map &map)
map(0xb01002, 0xb01002).rw(m_m1comm, FUNC(m1comm_device::fg_r), FUNC(m1comm_device::fg_w));
}
void model1_state::model1_vr_mem(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x1fffff).bankr("bank1");
map(0x200000, 0x2fffff).rom();
map(0x400000, 0x40ffff).ram().w(this, FUNC(model1_state::mr2_w)).share("mr2");
map(0x500000, 0x53ffff).ram().w(this, FUNC(model1_state::mr_w)).share("mr");
map(0x600000, 0x60ffff).ram().w(this, FUNC(model1_state::md0_w)).share("display_list0");
map(0x610000, 0x61ffff).ram().w(this, FUNC(model1_state::md1_w)).share("display_list1");
map(0x680000, 0x680003).rw(this, FUNC(model1_state::model1_listctl_r), FUNC(model1_state::model1_listctl_w));
map(0x700000, 0x70ffff).rw(m_tiles, FUNC(segas24_tile_device::tile_r), FUNC(segas24_tile_device::tile_w));
map(0x720000, 0x720001).nopw(); // Unknown, always 0
map(0x740000, 0x740001).nopw(); // Horizontal synchronization register
map(0x760000, 0x760001).nopw(); // Vertical synchronization register
map(0x770000, 0x770001).nopw(); // Video synchronization switch
map(0x780000, 0x7fffff).rw(m_tiles, FUNC(segas24_tile_device::char_r), FUNC(segas24_tile_device::char_w));
map(0x900000, 0x903fff).ram().w(this, FUNC(model1_state::p_w)).share("palette");
map(0x910000, 0x91bfff).ram().share("color_xlat");
map(0xb00000, 0xb00fff).rw(m_m1comm, FUNC(m1comm_device::share_r), FUNC(m1comm_device::share_w));
map(0xb01000, 0xb01000).rw(m_m1comm, FUNC(m1comm_device::cn_r), FUNC(m1comm_device::cn_w));
map(0xb01002, 0xb01002).rw(m_m1comm, FUNC(m1comm_device::fg_r), FUNC(m1comm_device::fg_w));
map(0xc00000, 0xc0003f).rw(this, FUNC(model1_state::io_r), FUNC(model1_state::io_w));
map(0xc00040, 0xc00043).rw(this, FUNC(model1_state::network_ctl_r), FUNC(model1_state::network_ctl_w));
map(0xc00200, 0xc002ff).ram().share("nvram");
map(0xc40000, 0xc40000).rw(m_m1uart, FUNC(i8251_device::data_r), FUNC(i8251_device::data_w));
map(0xc40002, 0xc40002).rw(m_m1uart, FUNC(i8251_device::status_r), FUNC(i8251_device::control_w));
map(0xd00000, 0xd00001).rw(this, FUNC(model1_state::model1_tgp_vr_adr_r), FUNC(model1_state::model1_tgp_vr_adr_w));
map(0xd20000, 0xd20003).w(this, FUNC(model1_state::model1_vr_tgp_ram_w));
map(0xd80000, 0xd80003).w(this, FUNC(model1_state::model1_vr_tgp_w)).mirror(0x10);
map(0xdc0000, 0xdc0003).r(this, FUNC(model1_state::fifoin_status_r));
map(0xe00000, 0xe00001).nopw(); // Watchdog? IRQ ack? Always 0x20, usually on irq
map(0xe00004, 0xe00005).w(this, FUNC(model1_state::bank_w));
map(0xe0000c, 0xe0000f).nopw();
map(0xfc0000, 0xffffff).rom();
}
void model1_state::model1_vr_io(address_map &map)
{
map(0xd20000, 0xd20003).r(this, FUNC(model1_state::model1_vr_tgp_ram_r));
map(0xd80000, 0xd80003).r(this, FUNC(model1_state::model1_vr_tgp_r));
}
static INPUT_PORTS_START( vf )
PORT_START("IN.0")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 )
@ -1125,20 +1064,27 @@ static INPUT_PORTS_START( swa )
INPUT_PORTS_END
#define MODEL1_CPU_BOARD \
ROM_REGION( 0xe0000, "copro_data", 0 ) \
ROM_REGION32_LE( 0x40000, "copro_tables", 0 ) \
ROM_LOAD32_WORD("opr14742.bin", 0x000000, 0x20000, CRC(446a1085) SHA1(51b3f4d3a35a36087ea0ba4e26d6e7d17b6418e2) ) \
ROM_LOAD32_WORD("opr14743.bin", 0x000002, 0x20000, CRC(e8953554) SHA1(1499f8e30ac15affc66e6f04ae031bb8680d9260) ) \
ROM_LOAD("opr14744.bin", 0x040000, 0x20000, CRC(730ea9e0) SHA1(651f1db4089a400d073b19ada299b4b08b08f372) ) \
ROM_LOAD("opr14745.bin", 0x060000, 0x20000, CRC(4c934d96) SHA1(e3349ece0e47f684d61ad11bfea4a90602287350) ) \
ROM_LOAD("opr14746.bin", 0x080000, 0x20000, CRC(2a266cbd) SHA1(34e047a93459406c22acf4c25089d1a4955f94ca) ) \
ROM_LOAD("opr14747.bin", 0x0a0000, 0x20000, CRC(a4ad5e19) SHA1(7d7ec300eeb9a8de1590011e37108688c092f329) ) \
ROM_LOAD("opr14748.bin", 0x0c0000, 0x20000, CRC(4a532cb8) SHA1(23280ebbcd6b2bc8a8e643a2d07a58d6598301b8) ) \
\
\
ROM_REGION32_LE( 0x80000, "other_data", 0 ) \
/* 1/x table */ \
ROM_LOAD32_WORD("opr-14744.58", 0x000000, 0x20000, CRC(730ea9e0) SHA1(651f1db4089a400d073b19ada299b4b08b08f372) ) \
ROM_LOAD32_WORD("opr-14745.59", 0x000002, 0x20000, CRC(4c934d96) SHA1(e3349ece0e47f684d61ad11bfea4a90602287350) ) \
/* 1/sqrt(x) table */ \
ROM_LOAD32_WORD("opr-14746.62", 0x040000, 0x20000, CRC(2a266cbd) SHA1(34e047a93459406c22acf4c25089d1a4955f94ca) ) \
ROM_LOAD32_WORD("opr-14747.63", 0x040002, 0x20000, CRC(a4ad5e19) SHA1(7d7ec300eeb9a8de1590011e37108688c092f329) ) \
\
ROM_REGION16_LE( 0x20000, "other_other_data", 0 ) \
/* 1/(1+x) again, but bottom 16 bits only */ \
ROM_LOAD("opr14748.bin", 0x000000, 0x20000, CRC(4a532cb8) SHA1(23280ebbcd6b2bc8a8e643a2d07a58d6598301b8) ) \
\
ROM_REGION32_LE( 0x2000, "315_5571", 0) \
ROM_LOAD("315-5571.bin", 0, 0x2000, CRC(1233db2a) SHA1(06760409d40f3d9117fd3e7c7ab62dfd70aa2a4d) ) \
\
\
ROM_REGION32_LE( 0x2000, "315_5572", 0) \
ROM_LOAD("315-5572.bin", 0, 0x2000, CRC(0a534a3b) SHA1(b8c988bc414b3ad3cd036ba5a64b5ee04a4758b4) )
ROM_LOAD("315-5572.bin", 0, 0x2000, CRC(66785906) SHA1(d94a51eced65b0073fb39625927782bf264d271a) )
ROM_START( vf )
MODEL1_CPU_BOARD
@ -1159,7 +1105,7 @@ ROM_START( vf )
ROM_LOAD16_BYTE( "mpr-16090.12", 0x1300000, 0x80000, CRC(90c76831) SHA1(5a3c25f2a131cfbb2ad067bef1ab7b1c95645d41) )
ROM_LOAD16_BYTE( "mpr-16091.13", 0x1300001, 0x80000, CRC(53115448) SHA1(af798d5b1fcb720d7288a5ac48839d9ace16a2f2) )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5724.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1205,6 +1151,9 @@ ROM_START( vr )
ROM_LOAD16_BYTE( "mpr-14888.12", 0x1300000, 0x80000, CRC(04bfdc5b) SHA1(bb8788a761620d0440a62ae51c3b41f70a04b5e4) )
ROM_LOAD16_BYTE( "mpr-14889.13", 0x1300001, 0x80000, CRC(c49f0486) SHA1(cc2bb9059c016ba2c4f6e7508bd1687df07b8b48) )
ROM_REGION( 0x2000, "tgp_copro", 0 ) /* TGP program rom */
ROM_LOAD("315-5573.bin", 0, 0x2000, CRC(3335a19b) SHA1(72eedfcc799ec4c7534fd7415de6631087ff6731) )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
ROM_LOAD16_WORD_SWAP( "epr-14870a.7", 0x00000, 0x20000, CRC(919d9b75) SHA1(27be79881cc9a2b5cf37e18f1e2d87251426b428) )
@ -1224,26 +1173,18 @@ ROM_START( vr )
ROM_LOAD32_WORD( "mpr-14896.32", 0xc00000, 0x200000, CRC(382091dc) SHA1(efa266f0f6bfe36ad1c365e588fff33b01e166dd) )
ROM_LOAD32_WORD( "mpr-14879.33", 0xc00002, 0x200000, CRC(74873195) SHA1(80705ec577d14570f9bba77cc26766f831c41f42) )
ROM_REGION32_LE( 0x200000, "tgp_data", 0 ) /* TGP data roms */
ROM_REGION32_LE( 0x200000, "copro_data", 0 ) /* TGP data roms */
ROM_LOAD32_BYTE( "mpr-14898.39", 0x000000, 0x80000, CRC(61da2bb6) SHA1(7a12ba522d64a1aeec1ca6f5a87ee063692131f9) )
ROM_LOAD32_BYTE( "mpr-14899.40", 0x000001, 0x80000, CRC(2cd58bee) SHA1(73defec823de4244a387af55fea7210edc1b314f) )
ROM_LOAD32_BYTE( "mpr-14900.41", 0x000002, 0x80000, CRC(aa7c017d) SHA1(0fa2b59a8bb5f5907b2b2567e69d11c73b398dc1) )
ROM_LOAD32_BYTE( "mpr-14901.42", 0x000003, 0x80000, CRC(175b7a9a) SHA1(c86602e771cd49bab425b4ba7926d2f44858bd39) )
ROM_REGION( 0x2000, "tgp", 0 ) /* TGP program rom */
// The real internal TGP rom
ROM_LOAD("315-5573.bin", 0, 0x2000, CRC(ec913af2) SHA1(a18bf6c9d7b35f8b9e513a7d279f13a30b32a961) )
// this is the Daytona TGP program with some modifications needed for Virtua Racing
// Kept here for now to avoid instantly breaking the game until the tgp is up to it
ROM_LOAD("vr-tgp.bin", 0x000000, 0x2000, CRC(3de33c7f) SHA1(acecc779c9d8fe39ded6c22492be5b7c25fd52db) )
ROM_REGION( 0x100, "nvram", 0 ) // default nvram
ROM_LOAD( "vr_defaults.nv", 0x000, 0x100, CRC(5ccdc835) SHA1(7e809de470f78fb897b938ca2aee2e12f1c8f3a4) )
ROM_REGION ( 0x10000, "io_board", 0)
ROM_LOAD("epr-14869.25", 0x00000, 0x10000, CRC(6187cd7a) SHA1(b65fdd0ad31794a565a0ca4dc67a3f16b329fd71) )
ROM_LOAD("epr-14869b.25", 0x00000, 0x10000, BAD_DUMP CRC(b410f22b) SHA1(75c5009ca4d21ebb53d54d4e3fb8aa55a4c74a07) ) // stray FFs at xx49, xx5F, xxC9, xxDF
// ROM_LOAD("epr-14869b.25", 0x00000, 0x10000, BAD_DUMP CRC(b410f22b) SHA1(75c5009ca4d21ebb53d54d4e3fb8aa55a4c74a07) ) // stray FFs at xx49, xx5F, xxC9, xxDF
// there is also epr-14869c in model2 daytona
ROM_END
@ -1266,6 +1207,9 @@ ROM_START( vformula )
ROM_LOAD16_BYTE( "mpr-14888.12", 0x1300000, 0x80000, CRC(04bfdc5b) SHA1(bb8788a761620d0440a62ae51c3b41f70a04b5e4) )
ROM_LOAD16_BYTE( "mpr-14889.13", 0x1300001, 0x80000, CRC(c49f0486) SHA1(cc2bb9059c016ba2c4f6e7508bd1687df07b8b48) )
ROM_REGION( 0x2000, "tgp_copro", 0 ) /* TGP program rom */
ROM_LOAD("315-5573.bin", 0, 0x2000, CRC(3335a19b) SHA1(72eedfcc799ec4c7534fd7415de6631087ff6731) )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
ROM_LOAD16_WORD_SWAP( "epr-14870a.7", 0x00000, 0x20000, CRC(919d9b75) SHA1(27be79881cc9a2b5cf37e18f1e2d87251426b428) )
@ -1285,19 +1229,14 @@ ROM_START( vformula )
ROM_LOAD32_WORD( "mpr-14896.32", 0xc00000, 0x200000, CRC(382091dc) SHA1(efa266f0f6bfe36ad1c365e588fff33b01e166dd) )
ROM_LOAD32_WORD( "mpr-14879.33", 0xc00002, 0x200000, CRC(74873195) SHA1(80705ec577d14570f9bba77cc26766f831c41f42) )
ROM_REGION32_LE( 0x200000, "tgp_data", 0 ) /* TGP data roms */
ROM_REGION32_LE( 0x200000, "copro_data", 0 ) /* TGP data roms */
ROM_LOAD32_BYTE( "mpr-14898.39", 0x000000, 0x80000, CRC(61da2bb6) SHA1(7a12ba522d64a1aeec1ca6f5a87ee063692131f9) )
ROM_LOAD32_BYTE( "mpr-14899.40", 0x000001, 0x80000, CRC(2cd58bee) SHA1(73defec823de4244a387af55fea7210edc1b314f) )
ROM_LOAD32_BYTE( "mpr-14900.41", 0x000002, 0x80000, CRC(aa7c017d) SHA1(0fa2b59a8bb5f5907b2b2567e69d11c73b398dc1) )
ROM_LOAD32_BYTE( "mpr-14901.42", 0x000003, 0x80000, CRC(175b7a9a) SHA1(c86602e771cd49bab425b4ba7926d2f44858bd39) )
ROM_REGION( 0x2000, "tgp", 0 ) /* TGP program rom */
// The real internal TGP rom
ROM_LOAD("315-5573.bin", 0, 0x2000, CRC(ec913af2) SHA1(a18bf6c9d7b35f8b9e513a7d279f13a30b32a961) )
// this is the Daytona TGP program with some modifications needed for Virtua Racing
// Kept here for now to avoid instantly breaking the game until the tgp is up to it
ROM_LOAD("vr-tgp.bin", 0x000000, 0x2000, CRC(3de33c7f) SHA1(acecc779c9d8fe39ded6c22492be5b7c25fd52db) )
ROM_REGION( 0x20000, "commboard", 0 ) /* Comms Board */
ROM_LOAD( "epr-15624.17", 0x00000, 0x20000, CRC(9b3ba315) SHA1(0cd0983cc8b2f2d6b41617d0d0a24cc6c188e62a) )
ROM_END
@ -1312,7 +1251,7 @@ ROM_START( swa )
ROM_RELOAD( 0x000000, 0x80000 )
ROM_RELOAD( 0x080000, 0x80000 )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5711.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1320,12 +1259,12 @@ ROM_START( swa )
ROM_RELOAD(0x80000, 0x20000)
ROM_REGION( 0x400000, M1AUDIO_MPCM1_REGION, 0 ) /* Samples */
ROM_LOAD( "mpr-16486.bin", 0x000000, 0x200000, CRC(7df50533) SHA1(f2fb876738e37d70eb9005e5629a9ae89aa413a8) )
ROM_LOAD( "mpr-16487.bin", 0x200000, 0x200000, CRC(31b28dfa) SHA1(bd1ac11bf2f9161f61f8af3b9ff4c2709b7ee700) )
ROM_LOAD( "mpr-16486.bin", 0x000000, 0x200000, CRC(7df50533) SHA1(f2fb876738e37d70eb9005e5629a9ae89aa413a8) )
ROM_LOAD( "mpr-16487.bin", 0x200000, 0x200000, CRC(31b28dfa) SHA1(bd1ac11bf2f9161f61f8af3b9ff4c2709b7ee700) )
ROM_REGION( 0x400000, M1AUDIO_MPCM2_REGION, 0 ) /* Samples */
ROM_LOAD( "mpr-16484.bin", 0x000000, 0x200000, CRC(9d4c334d) SHA1(8b4d903f14559fed425d225bb23ccfe8da23cbd3) )
ROM_LOAD( "mpr-16485.bin", 0x200000, 0x200000, CRC(95aadcad) SHA1(4276db655db9834692c3843eb96a3e3a89cb7252) )
ROM_LOAD( "mpr-16484.bin", 0x000000, 0x200000, CRC(9d4c334d) SHA1(8b4d903f14559fed425d225bb23ccfe8da23cbd3) )
ROM_LOAD( "mpr-16485.bin", 0x200000, 0x200000, CRC(95aadcad) SHA1(4276db655db9834692c3843eb96a3e3a89cb7252) )
ROM_REGION( 0x20000, "mpegcpu", 0 ) /* Z80 DSB code */
ROM_LOAD( "epr-16471.bin", 0x000000, 0x020000, CRC(f4ee84a4) SHA1(f12b214e6f195b0e5f49ba9f41d8e54bfcea9acc) )
@ -1372,7 +1311,7 @@ ROM_START( wingwar )
ROM_LOAD16_BYTE( "mpr-16734.10", 0x1200000, 0x80000, CRC(f76371c1) SHA1(0ff082db3877383d0dd977dc60c932b725e3d164) )
ROM_LOAD16_BYTE( "mpr-16733.11", 0x1200001, 0x80000, CRC(e105847b) SHA1(8489a6c91fd6d1e9ba81e8eaf36c514da30dccbe) )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5711.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1406,6 +1345,8 @@ ROM_START( wingwar )
ROM_END
ROM_START( wingwaru )
MODEL1_CPU_BOARD
ROM_REGION( 0x2000000, "maincpu", ROMREGION_ERASEFF ) /* v60 code */
ROM_LOAD16_BYTE( "epr-16729.14", 0x200000, 0x80000, CRC(7edec2cc) SHA1(3e423a868ca7c8475fbb5bc1a10526e69d94d865) )
ROM_LOAD16_BYTE( "epr-16730.15", 0x200001, 0x80000, CRC(bab24dee) SHA1(26c95139c1aa7f34b6a5cce39e5bd1dd2ef0dd49) )
@ -1422,7 +1363,7 @@ ROM_START( wingwaru )
ROM_LOAD16_BYTE( "mpr-16734.10", 0x1200000, 0x80000, CRC(f76371c1) SHA1(0ff082db3877383d0dd977dc60c932b725e3d164) )
ROM_LOAD16_BYTE( "mpr-16733.11", 0x1200001, 0x80000, CRC(e105847b) SHA1(8489a6c91fd6d1e9ba81e8eaf36c514da30dccbe) )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5711.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1474,7 +1415,7 @@ ROM_START( wingwarj )
ROM_LOAD16_BYTE( "mpr-16734.10", 0x1200000, 0x80000, CRC(f76371c1) SHA1(0ff082db3877383d0dd977dc60c932b725e3d164) )
ROM_LOAD16_BYTE( "mpr-16733.11", 0x1200001, 0x80000, CRC(e105847b) SHA1(8489a6c91fd6d1e9ba81e8eaf36c514da30dccbe) )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5711.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1528,7 +1469,7 @@ ROM_START( wingwar360 )
ROM_LOAD16_BYTE( "mpr-16734.10", 0x1200000, 0x80000, CRC(f76371c1) SHA1(0ff082db3877383d0dd977dc60c932b725e3d164) )
ROM_LOAD16_BYTE( "mpr-16733.11", 0x1200001, 0x80000, CRC(e105847b) SHA1(8489a6c91fd6d1e9ba81e8eaf36c514da30dccbe) )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5711.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1583,7 +1524,7 @@ ROM_START( netmerc )
ROM_LOAD16_BYTE( "epr-18126.ic10", 0x1200000, 0x80000, CRC(43dc5ca8) SHA1(249ed83b90b0237ceabbed814cd42dc60dc7a174) )
ROM_LOAD16_BYTE( "epr-18127.ic11", 0x1200001, 0x80000, CRC(d307a4ca) SHA1(5555235f740c1b09f6e1587d0fceb35b23d4a8a8) )
ROM_REGION32_LE( 0x2000, "tgp", 0)
ROM_REGION32_LE( 0x2000, "tgp_copro", 0)
ROM_LOAD("315-5711.bin", 0, 0x2000, NO_DUMP )
ROM_REGION( 0xc0000, M1AUDIO_CPU_REGION, ROMREGION_BE|ROMREGION_16BIT ) /* 68K code */
@ -1621,9 +1562,20 @@ MACHINE_CONFIG_START(model1_state::model1)
MCFG_CPU_IO_MAP(model1_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(model1_state,irq_callback)
MCFG_DEVICE_ADD("copro_fifo_in", GENERIC_FIFO_U32, 0)
MCFG_DEVICE_ADD("copro_fifo_out", GENERIC_FIFO_U32, 0)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", model1_state, model1_interrupt, "screen", 0, 1)
MCFG_TIMER_DRIVER_ADD("iotimer", model1_state, io_command_acknowledge)
#if 1
MCFG_CPU_ADD("tgp_copro", MB86233, 16000000)
MCFG_CPU_PROGRAM_MAP(copro_prog_map)
MCFG_CPU_DATA_MAP(copro_data_map)
MCFG_CPU_IO_MAP(copro_io_map)
MCFG_DEVICE_ADDRESS_MAP(mb86233_device::AS_RF, copro_rf_map)
#endif
MCFG_MACHINE_START_OVERRIDE(model1_state,model1)
MCFG_MACHINE_RESET_OVERRIDE(model1_state,model1)
MCFG_NVRAM_ADD_0FILL("nvram")
@ -1663,8 +1615,14 @@ MACHINE_CONFIG_START(model1_state::wingwar)
MCFG_DEVICE_BIOS("epr15112");
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::swa)
MACHINE_CONFIG_START(model1_state::model1_hle)
model1(config);
MCFG_DEVICE_REMOVE("tgp_copro")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::swa)
model1_hle(config);
MCFG_SPEAKER_STANDARD_STEREO("dleft", "dright")
MCFG_DSBZ80_ADD(DSBZ80_TAG)
MCFG_SOUND_ROUTE(0, "dleft", 1.0)
@ -1684,65 +1642,20 @@ void model1_state::polhemus_map(address_map &map)
}
MACHINE_CONFIG_START(model1_state::netmerc)
model1(config);
model1_hle(config);
MCFG_CPU_ADD("polhemus", I386SX, 16000000)
MCFG_CPU_PROGRAM_MAP(polhemus_map)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::model1_vr)
MCFG_CPU_ADD("maincpu", V60, 16000000)
MCFG_CPU_PROGRAM_MAP(model1_vr_mem)
MCFG_CPU_IO_MAP(model1_vr_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(model1_state,irq_callback)
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", model1_state, model1_interrupt, "screen", 0, 1)
MCFG_TIMER_DRIVER_ADD("iotimer", model1_state, io_command_acknowledge)
MCFG_CPU_ADD("tgp", MB86233, 16000000)
MCFG_CPU_PROGRAM_MAP(model1_vr_tgp_map)
MCFG_MB86233_FIFO_READ_CB(READ32(model1_state,copro_fifoin_pop))
MCFG_MB86233_FIFO_READ_OK_CB(READLINE(model1_state,copro_fifoin_pop_ok))
MCFG_MB86233_FIFO_WRITE_CB(WRITE32(model1_state,copro_fifoout_push))
MCFG_MB86233_TABLE_REGION("copro_data")
MCFG_MACHINE_START_OVERRIDE(model1_state,model1)
MCFG_MACHINE_RESET_OVERRIDE(model1_state,model1_vr)
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_S24TILE_DEVICE_ADD("tile", 0x3fff)
MCFG_S24TILE_DEVICE_PALETTE("palette")
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK )
MCFG_SCREEN_RAW_PARAMS(XTAL(16'000'000), 656, 0/*+69*/, 496/*+69*/, 424, 0/*+25*/, 384/*+25*/)
MCFG_SCREEN_UPDATE_DRIVER(model1_state, screen_update_model1)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(model1_state, screen_vblank_model1))
MCFG_PALETTE_ADD("palette", 8192)
MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR)
MCFG_VIDEO_START_OVERRIDE(model1_state,model1)
MCFG_SEGAM1AUDIO_ADD(M1AUDIO_TAG)
MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_rxd))
MCFG_DEVICE_ADD("m1uart", I8251, 8000000) // uPD71051C, clock unknown
MCFG_I8251_TXD_HANDLER(DEVWRITELINE(M1AUDIO_TAG, segam1audio_device, write_txd))
MCFG_CLOCK_ADD("m1uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate)
MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("m1uart", i8251_device, write_txc))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("m1uart", i8251_device, write_rxc))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::vr)
model1_vr(config);
model1(config);
MCFG_M1COMM_ADD(M1COMM_TAG)
MCFG_DEVICE_BIOS("epr15112");
MACHINE_CONFIG_END
MACHINE_CONFIG_START(model1_state::vformula)
model1_vr(config);
model1(config);
MCFG_M1COMM_ADD(M1COMM_TAG)
MCFG_DEVICE_BIOS("epr15624");
@ -1812,12 +1725,12 @@ WRITE16_MEMBER(model1_state::r360_w)
}
}
GAME( 1993, vf, 0, model1, vf, model1_state, 0, ROT0, "Sega", "Virtua Fighter", MACHINE_IMPERFECT_GRAPHICS )
GAMEL(1992, vr, 0, vr, vr, model1_state, 0, ROT0, "Sega", "Virtua Racing", MACHINE_IMPERFECT_GRAPHICS, layout_vr )
GAME( 1993, vformula, vr, vformula, vr, model1_state, 0, ROT0, "Sega", "Virtua Formula", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1993, swa, 0, swa, swa, model1_state, 0, ROT0, "Sega", "Star Wars Arcade", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
GAME( 1994, wingwar, 0, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (World)", MACHINE_NOT_WORKING )
GAME( 1994, wingwaru, wingwar, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (US)", MACHINE_NOT_WORKING )
GAME( 1994, wingwarj, wingwar, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (Japan)", MACHINE_NOT_WORKING )
GAME( 1994, wingwar360, wingwar, wingwar, wingwar, model1_state, wingwar360, ROT0, "Sega", "Wing War R360 (US)", MACHINE_NOT_WORKING )
GAME( 1993, netmerc, 0, netmerc, vf, model1_state, 0, ROT0, "Sega", "Sega NetMerc", MACHINE_NOT_WORKING )
GAME( 1993, vf, 0, model1_hle, vf, model1_state, 0, ROT0, "Sega", "Virtua Fighter", MACHINE_IMPERFECT_GRAPHICS )
GAMEL(1992, vr, 0, vr, vr, model1_state, 0, ROT0, "Sega", "Virtua Racing", 0, layout_vr )
GAME( 1993, vformula, vr, vformula, vr, model1_state, 0, ROT0, "Sega", "Virtua Formula", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1993, swa, 0, swa, swa, model1_state, 0, ROT0, "Sega", "Star Wars Arcade", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND )
GAME( 1994, wingwar, 0, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (World)", MACHINE_NOT_WORKING )
GAME( 1994, wingwaru, wingwar, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (US)", MACHINE_NOT_WORKING )
GAME( 1994, wingwarj, wingwar, wingwar, wingwar, model1_state, 0, ROT0, "Sega", "Wing War (Japan)", MACHINE_NOT_WORKING )
GAME( 1994, wingwar360, wingwar, wingwar, wingwar, model1_state, wingwar360, ROT0, "Sega", "Wing War R360 (US)", MACHINE_NOT_WORKING )
GAME( 1993, netmerc, 0, netmerc, vf, model1_state, 0, ROT0, "Sega", "Sega NetMerc", MACHINE_NOT_WORKING )

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
#include "cpu/mb86233/mb86233.h"
#include "cpu/v60/v60.h"
#include "machine/i8251.h"
#include "machine/gen_fifo.h"
#include "machine/m1comm.h"
#include "machine/timer.h"
#include "video/segaic24.h"
@ -37,11 +38,14 @@ public:
, m_m1uart(*this, "m1uart")
, m_m1comm(*this, "m1comm")
, m_dsbz80(*this, DSBZ80_TAG)
, m_tgp(*this, "tgp")
, m_tgp_copro(*this, "tgp_copro")
, m_screen(*this, "screen")
, m_io_timer(*this, "iotimer")
, m_copro_fifo_in(*this, "copro_fifo_in")
, m_copro_fifo_out(*this, "copro_fifo_out")
, m_poly_rom(*this, "polygons")
, m_tgp_data(*this, "tgp_data")
, m_copro_tables(*this, "copro_tables")
, m_copro_data(*this, "copro_data")
, m_mr2(*this, "mr2")
, m_mr(*this, "mr")
, m_display_list0(*this, "display_list0")
@ -59,7 +63,6 @@ public:
// Machine
DECLARE_MACHINE_START(model1);
DECLARE_MACHINE_RESET(model1);
DECLARE_MACHINE_RESET(model1_vr);
DECLARE_READ16_MEMBER(network_ctl_r);
DECLARE_WRITE16_MEMBER(network_ctl_w);
@ -81,25 +84,44 @@ public:
DECLARE_WRITE16_MEMBER(mr_w);
DECLARE_WRITE16_MEMBER(mr2_w);
DECLARE_READ16_MEMBER(model1_tgp_copro_r);
DECLARE_WRITE16_MEMBER(model1_tgp_copro_w);
DECLARE_READ16_MEMBER(model1_tgp_copro_adr_r);
DECLARE_WRITE16_MEMBER(model1_tgp_copro_adr_w);
DECLARE_READ16_MEMBER(model1_tgp_copro_ram_r);
DECLARE_WRITE16_MEMBER(model1_tgp_copro_ram_w);
DECLARE_READ16_MEMBER(model1_tgp_vr_adr_r);
DECLARE_WRITE16_MEMBER(model1_tgp_vr_adr_w);
DECLARE_READ16_MEMBER(model1_vr_tgp_ram_r);
DECLARE_WRITE16_MEMBER(model1_vr_tgp_ram_w);
DECLARE_READ16_MEMBER(model1_vr_tgp_r);
DECLARE_WRITE16_MEMBER(model1_vr_tgp_w);
DECLARE_READ16_MEMBER(v60_copro_fifo_r);
DECLARE_WRITE16_MEMBER(v60_copro_fifo_w);
DECLARE_READ16_MEMBER(v60_copro_ram_adr_r);
DECLARE_WRITE16_MEMBER(v60_copro_ram_adr_w);
DECLARE_READ16_MEMBER(v60_copro_ram_r);
DECLARE_WRITE16_MEMBER(v60_copro_ram_w);
DECLARE_READ32_MEMBER(copro_ram_r);
DECLARE_WRITE32_MEMBER(copro_ram_w);
DECLARE_READ_LINE_MEMBER(copro_fifoin_pop_ok);
DECLARE_READ32_MEMBER(copro_fifoin_pop);
DECLARE_WRITE32_MEMBER(copro_fifoout_push);
DECLARE_WRITE32_MEMBER(copro_sincos_w);
DECLARE_READ32_MEMBER(copro_sincos_r);
DECLARE_WRITE32_MEMBER(copro_inv_w);
DECLARE_READ32_MEMBER(copro_inv_r);
DECLARE_WRITE32_MEMBER(copro_isqrt_w);
DECLARE_READ32_MEMBER(copro_isqrt_r);
DECLARE_WRITE32_MEMBER(copro_atan_w);
DECLARE_READ32_MEMBER(copro_atan_r);
DECLARE_WRITE32_MEMBER(copro_data_w);
DECLARE_READ32_MEMBER(copro_data_r);
DECLARE_WRITE32_MEMBER(copro_ramadr_w);
DECLARE_READ32_MEMBER(copro_ramadr_r);
DECLARE_WRITE32_MEMBER(copro_ramdata_w);
DECLARE_READ32_MEMBER(copro_ramdata_r);
void copro_hle_vf();
void copro_hle_swa();
void copro_reset();
u32 m_copro_sincos_base;
u32 m_copro_inv_base;
u32 m_copro_isqrt_base;
u32 m_copro_atan_base[4];
u32 m_copro_data_base;
u32 m_copro_ram_adr;
uint16_t m_r360_state;
DECLARE_DRIVER_INIT(wingwar360);
DECLARE_READ16_MEMBER(r360_r);
@ -187,27 +209,32 @@ public:
};
void model1(machine_config &config);
void wingwar(machine_config &config);
void swa(machine_config &config);
void netmerc(machine_config &config);
void model1_vr(machine_config &config);
void model1_hle(machine_config &config);
void vr(machine_config &config);
void vformula(machine_config &config);
void swa(machine_config &config);
void netmerc(machine_config &config);
void wingwar(machine_config &config);
void model1_io(address_map &map);
void model1_mem(address_map &map);
void model1_comm_mem(address_map &map);
void model1_vr_io(address_map &map);
void model1_vr_mem(address_map &map);
void model1_vr_tgp_map(address_map &map);
void copro_prog_map(address_map &map);
void copro_data_map(address_map &map);
void copro_external_map(address_map &map);
void copro_io_map(address_map &map);
void copro_rf_map(address_map &map);
void polhemus_map(address_map &map);
private:
// Machine
void irq_raise(int level);
void irq_init();
int m_last_irq;
bool m_dump;
bool m_swa;
uint8_t m_io_command;
@ -217,12 +244,14 @@ private:
required_device<i8251_device> m_m1uart;
optional_device<m1comm_device> m_m1comm; // Model 1 communication board
optional_device<dsbz80_device> m_dsbz80; // Digital Sound Board
optional_device<mb86233_cpu_device> m_tgp;
optional_device<mb86233_device> m_tgp_copro;
required_device<screen_device> m_screen;
required_device<timer_device> m_io_timer;
required_device<generic_fifo_u32_device> m_copro_fifo_in, m_copro_fifo_out;
required_region_ptr<uint32_t> m_poly_rom;
optional_region_ptr<uint32_t> m_tgp_data;
required_region_ptr<uint32_t> m_copro_tables;
optional_memory_region m_copro_data;
required_shared_ptr<uint16_t> m_mr2;
required_shared_ptr<uint16_t> m_mr;
@ -234,32 +263,16 @@ private:
int m_sound_irq;
// TGP FIFO
uint32_t fifoout_pop();
void fifoout_push(uint32_t data);
void fifoout_push_f(float data);
uint32_t fifoin_pop();
void fifoin_push(uint32_t data);
float fifoin_pop_f();
uint16_t ram_get_i();
float ram_get_f();
void copro_fifoin_push(uint32_t data);
uint32_t copro_fifoout_pop();
void next_fn();
uint32_t m_copro_r;
uint32_t m_copro_w;
int m_copro_fifoout_rpos;
int m_copro_fifoout_wpos;
uint32_t m_copro_fifoout_data[FIFO_SIZE];
int m_copro_fifoout_num;
int m_copro_fifoin_rpos;
int m_copro_fifoin_wpos;
uint32_t m_copro_fifoin_data[FIFO_SIZE];
int m_copro_fifoin_num;
u32 m_v60_copro_fifo_r, m_v60_copro_fifo_w;
// TGP
void vr_tgp_reset();
void tgp_reset(bool swa);
void tgp_reset();
DECLARE_TGP_FUNCTION( fadd );
DECLARE_TGP_FUNCTION( fsub );
@ -385,12 +398,8 @@ private:
quad_t *m_quadpt;
quad_t **m_quadind;
offs_t m_pushpc;
int m_fifoin_rpos;
int m_fifoin_wpos;
uint32_t m_fifoin_data[FIFO_SIZE];
int m_fifoin_cbcount;
u32 m_copro_hle_active_list_pos, m_copro_hle_active_list_length;
typedef void (model1_state::*tgp_func)();
tgp_func m_fifoin_cb;
struct function
{
@ -398,12 +407,12 @@ private:
int count;
};
static float tsin(s16 angle);
static float tcos(s16 angle);
static const struct function ftab_vf[];
static const struct function ftab_swa[];
int32_t m_fifoout_rpos;
int32_t m_fifoout_wpos;
uint32_t m_fifoout_data[FIFO_SIZE];
uint32_t m_list_length;
uint32_t m_copro_hle_list_length;
float m_cmat[12];
float m_mat_stack[MAT_STACK_SIZE][12];
float m_mat_vector[21][12];
@ -426,15 +435,12 @@ private:
float m_tgp_int_py;
float m_tgp_int_pz;
uint32_t m_tgp_int_adr;
uint16_t m_ram_adr;
uint16_t m_ram_latch[2];
uint16_t m_ram_scanadr;
std::unique_ptr<uint32_t[]> m_ram_data;
uint16_t m_v60_copro_ram_adr;
uint16_t m_v60_copro_ram_latch[2];
uint16_t m_copro_hle_ram_scan_adr;
std::unique_ptr<uint32_t[]> m_copro_ram_data;
float m_tgp_vr_base[4];
int m_puuu;
int m_ccount;
uint32_t m_vr_r;
uint32_t m_vr_w;
uint16_t m_listctl[2];
uint16_t *m_glist;
bool m_render_done;
@ -442,6 +448,8 @@ private:
std::unique_ptr<uint16_t[]> m_tgp_ram;
std::unique_ptr<uint32_t[]> m_poly_ram;
void configure_fifos();
// Rendering helper functions
uint32_t readi(int adr) const;
int16_t readi16(int adr) const;

View File

@ -6,7 +6,11 @@
#include "machine/eepromser.h"
#include "machine/i8251.h"
#include "cpu/i960/i960.h"
#include "cpu/mb86233/mb86233.h"
#include "cpu/sharc/sharc.h"
#include "cpu/mb86235/mb86235.h"
#include "machine/bankdev.h"
#include "machine/gen_fifo.h"
#include "sound/scsp.h"
#include "machine/315-5881_crypt.h"
#include "machine/315-5838_317-0229_comp.h"
@ -24,22 +28,19 @@ class model2_state : public driver_device
public:
model2_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_workram(*this, "workram"),
m_bufferram(*this, "bufferram"),
m_textureram0(*this, "textureram0"),
m_textureram1(*this, "textureram1"),
m_workram(*this, "workram"),
m_bufferram(*this, "bufferram"),
m_soundram(*this, "soundram"),
m_tgp_program(*this, "tgp_program"),
m_tgpx4_program(*this, "tgpx4_program"),
m_maincpu(*this,"maincpu"),
m_dsbz80(*this, DSBZ80_TAG),
m_m1audio(*this, M1AUDIO_TAG),
m_uart(*this, "uart"),
m_m2comm(*this, "m2comm"),
m_audiocpu(*this, "audiocpu"),
m_tgp(*this, "tgp"),
m_dsp(*this, "dsp"),
m_tgpx4(*this, "tgpx4"),
m_copro_fifo_in(*this, "copro_fifo_in"),
m_copro_fifo_out(*this, "copro_fifo_out"),
m_drivecpu(*this, "drivecpu"),
m_eeprom(*this, "eeprom"),
m_screen(*this, "screen"),
@ -47,6 +48,7 @@ public:
m_scsp(*this, "scsp"),
m_cryptdevice(*this, "315_5881"),
m_0229crypt(*this, "317_0229"),
m_copro_data(*this, "copro_data"),
m_in(*this, "IN%u", 0),
m_dsw(*this, "DSW"),
m_steer(*this, "STEER"),
@ -57,18 +59,41 @@ public:
m_lightgun_ports(*this, {"P1_Y", "P1_X", "P2_Y", "P2_X"})
{ }
required_shared_ptr<uint32_t> m_workram;
required_shared_ptr<uint32_t> m_bufferram;
std::unique_ptr<uint16_t[]> m_palram;
std::unique_ptr<uint16_t[]> m_colorxlat;
/* Public for access by the rendering functions */
required_shared_ptr<uint32_t> m_textureram0;
required_shared_ptr<uint32_t> m_textureram1;
std::unique_ptr<uint16_t[]> m_palram;
std::unique_ptr<uint16_t[]> m_colorxlat;
std::unique_ptr<uint16_t[]> m_lumaram;
uint8_t m_gamma_table[256];
model2_renderer *m_poly;
/* Public for access by the ioports */
DECLARE_CUSTOM_INPUT_MEMBER(daytona_gearbox_r);
DECLARE_CUSTOM_INPUT_MEMBER(rchase2_devices_r);
/* Public for access by MCFG */
TIMER_DEVICE_CALLBACK_MEMBER(model2_interrupt);
uint16_t crypt_read_callback(uint32_t addr);
DECLARE_MACHINE_START(model2);
/* Public for access by GAME() */
DECLARE_DRIVER_INIT(overrev);
DECLARE_DRIVER_INIT(pltkids);
DECLARE_DRIVER_INIT(rchase2);
DECLARE_DRIVER_INIT(manxttdx);
DECLARE_DRIVER_INIT(doa);
DECLARE_DRIVER_INIT(zerogun);
DECLARE_DRIVER_INIT(sgt24h);
DECLARE_DRIVER_INIT(srallyc);
protected:
required_shared_ptr<uint32_t> m_workram;
required_shared_ptr<uint32_t> m_bufferram;
std::unique_ptr<uint16_t[]> m_fbvramA;
std::unique_ptr<uint16_t[]> m_fbvramB;
optional_shared_ptr<uint16_t> m_soundram;
optional_shared_ptr<uint32_t> m_tgp_program;
optional_shared_ptr<uint64_t> m_tgpx4_program;
required_device<i960_cpu_device> m_maincpu;
optional_device<dsbz80_device> m_dsbz80; // Z80-based MPEG Digital Sound Board
@ -76,9 +101,8 @@ public:
required_device<i8251_device> m_uart;
optional_device<m2comm_device> m_m2comm; // Model 2 communication board
optional_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_tgp;
optional_device<cpu_device> m_dsp;
optional_device<mb86235_device> m_tgpx4;
required_device<generic_fifo_u32_device> m_copro_fifo_in;
required_device<generic_fifo_u32_device> m_copro_fifo_out;
optional_device<cpu_device> m_drivecpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<screen_device> m_screen;
@ -86,6 +110,7 @@ public:
optional_device<scsp_device> m_scsp;
optional_device<sega_315_5881_crypt_device> m_cryptdevice;
optional_device<sega_315_5838_comp_device> m_0229crypt;
optional_memory_region m_copro_data;
optional_ioport_array<5> m_in;
required_ioport m_dsw;
@ -102,15 +127,6 @@ public:
timer_device *m_timers[4];
int m_ctrlmode;
int m_analog_channel;
int m_dsp_type;
int m_copro_fifoin_rpos;
int m_copro_fifoin_wpos;
std::unique_ptr<uint32_t[]> m_copro_fifoin_data;
int m_copro_fifoin_num;
int m_copro_fifoout_rpos;
int m_copro_fifoout_wpos;
std::unique_ptr<uint32_t[]> m_copro_fifoout_data;
int m_copro_fifoout_num;
uint16_t m_cmd_data;
uint8_t m_driveio_comm_data;
int m_iop_write_num;
@ -120,7 +136,6 @@ public:
uint32_t m_geo_read_start_address;
uint32_t m_geo_write_start_address;
model2_renderer *m_poly;
raster_state *m_raster;
geo_state *m_geo;
bitmap_rgb32 m_sys24_bitmap;
@ -130,9 +145,22 @@ public:
uint8_t m_gearsel;
uint8_t m_lightgun_mux;
// Coprocessor communications
DECLARE_READ32_MEMBER(copro_prg_r);
DECLARE_WRITE32_MEMBER(copro_prg_w);
DECLARE_READ32_MEMBER(copro_ctl1_r);
DECLARE_WRITE32_MEMBER(copro_ctl1_w);
DECLARE_READ32_MEMBER(copro_status_r);
// Geometrizer communications
DECLARE_WRITE32_MEMBER(geo_ctl1_w);
DECLARE_READ32_MEMBER(geo_prg_r);
DECLARE_WRITE32_MEMBER(geo_prg_w);
DECLARE_READ32_MEMBER(geo_r);
DECLARE_WRITE32_MEMBER(geo_w);
// Everything else
DECLARE_READ8_MEMBER(model2_crx_in_r);
DECLARE_CUSTOM_INPUT_MEMBER(daytona_gearbox_r);
DECLARE_CUSTOM_INPUT_MEMBER(rchase2_devices_r);
DECLARE_READ32_MEMBER(timers_r);
DECLARE_WRITE32_MEMBER(timers_w);
DECLARE_READ16_MEMBER(palette_r);
@ -146,19 +174,6 @@ public:
DECLARE_WRITE32_MEMBER(videoctl_w);
DECLARE_WRITE32_MEMBER(rchase2_devices_w);
DECLARE_WRITE32_MEMBER(srallyc_devices_w);
DECLARE_READ32_MEMBER(copro_prg_r);
DECLARE_WRITE32_MEMBER(copro_prg_w);
DECLARE_READ32_MEMBER(copro_ctl1_r);
DECLARE_WRITE32_MEMBER(copro_ctl1_w);
DECLARE_WRITE32_MEMBER(copro_function_port_w);
DECLARE_READ32_MEMBER(copro_fifo_r);
DECLARE_WRITE32_MEMBER(copro_fifo_w);
DECLARE_WRITE32_MEMBER(copro_sharc_iop_w);
DECLARE_WRITE32_MEMBER(geo_ctl1_w);
DECLARE_READ32_MEMBER(geo_prg_r);
DECLARE_WRITE32_MEMBER(geo_prg_w);
DECLARE_READ32_MEMBER(geo_r);
DECLARE_WRITE32_MEMBER(geo_w);
DECLARE_READ8_MEMBER(hotd_lightgun_r);
DECLARE_WRITE32_MEMBER(hotd_lightgun_w);
DECLARE_READ32_MEMBER(irq_request_r);
@ -175,8 +190,6 @@ public:
void geo_init(memory_region *polygon_rom);
DECLARE_READ32_MEMBER(render_mode_r);
DECLARE_WRITE32_MEMBER(render_mode_w);
DECLARE_WRITE32_MEMBER(model2o_tex_w0);
DECLARE_WRITE32_MEMBER(model2o_tex_w1);
DECLARE_READ16_MEMBER(lumaram_r);
DECLARE_WRITE16_MEMBER(lumaram_w);
DECLARE_READ16_MEMBER(fbvram_bankA_r);
@ -185,57 +198,24 @@ public:
DECLARE_WRITE16_MEMBER(fbvram_bankB_w);
DECLARE_WRITE32_MEMBER(model2_3d_zclip_w);
DECLARE_WRITE16_MEMBER(model2snd_ctrl);
DECLARE_READ32_MEMBER(copro_sharc_input_fifo_r);
DECLARE_WRITE32_MEMBER(copro_sharc_output_fifo_w);
DECLARE_READ32_MEMBER(copro_sharc_buffer_r);
DECLARE_WRITE32_MEMBER(copro_sharc_buffer_w);
DECLARE_READ32_MEMBER(copro_tgp_buffer_r);
DECLARE_WRITE32_MEMBER(copro_tgp_buffer_w);
DECLARE_READ8_MEMBER(tgpid_r);
DECLARE_READ32_MEMBER(copro_status_r);
DECLARE_READ32_MEMBER(polygon_count_r);
DECLARE_READ8_MEMBER(driveio_portg_r);
DECLARE_READ8_MEMBER(driveio_porth_r);
DECLARE_WRITE8_MEMBER(driveio_port_w);
void push_geo_data(uint32_t data);
DECLARE_DRIVER_INIT(overrev);
DECLARE_DRIVER_INIT(pltkids);
DECLARE_DRIVER_INIT(rchase2);
DECLARE_DRIVER_INIT(manxttdx);
DECLARE_DRIVER_INIT(srallyc);
DECLARE_DRIVER_INIT(doa);
DECLARE_DRIVER_INIT(zerogun);
DECLARE_DRIVER_INIT(sgt24h);
DECLARE_MACHINE_START(model2);
DECLARE_MACHINE_START(srallyc);
DECLARE_MACHINE_RESET(model2o);
DECLARE_VIDEO_START(model2);
DECLARE_MACHINE_RESET(model2);
DECLARE_MACHINE_RESET(model2b);
DECLARE_MACHINE_RESET(model2c);
DECLARE_MACHINE_RESET(model2_common);
DECLARE_MACHINE_RESET(model2_scsp);
uint32_t screen_update_model2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
// DECLARE_WRITE_LINE_MEMBER(screen_vblank_model2);
// DECLARE_WRITE_LINE_MEMBER(sound_ready_w);
TIMER_DEVICE_CALLBACK_MEMBER(model2_timer_cb);
TIMER_DEVICE_CALLBACK_MEMBER(model2_interrupt);
TIMER_DEVICE_CALLBACK_MEMBER(model2c_interrupt);
DECLARE_WRITE8_MEMBER(scsp_irq);
DECLARE_READ_LINE_MEMBER(copro_tgp_fifoin_pop_ok);
DECLARE_READ32_MEMBER(copro_tgp_fifoin_pop);
DECLARE_WRITE32_MEMBER(copro_tgp_fifoout_push);
DECLARE_READ8_MEMBER(virtuacop_lightgun_r);
DECLARE_READ8_MEMBER(virtuacop_lightgun_offscreen_r);
uint16_t crypt_read_callback(uint32_t addr);
bool copro_fifoin_pop(device_t *device, uint32_t *result,uint32_t offset, uint32_t mem_mask);
void copro_fifoin_push(device_t *device, uint32_t data, uint32_t offset, uint32_t mem_mask);
uint32_t copro_fifoout_pop(address_space &space, uint32_t offset, uint32_t mem_mask);
void copro_fifoout_push(device_t *device, uint32_t data,uint32_t offset,uint32_t mem_mask);
void model2_3d_frame_start( void );
void geo_parse( void );
void model2_3d_frame_end( bitmap_rgb32 &bitmap, const rectangle &cliprect );
@ -246,8 +226,7 @@ public:
void model2_scsp(machine_config &config);
void sj25_0207_01(machine_config &config);
void copro_sharc_map(address_map &map);
void copro_tgp_map(address_map &map);
void drive_io_map(address_map &map);
void drive_map(address_map &map);
void geo_sharc_map(address_map &map);
@ -255,33 +234,35 @@ public:
void model2_5881_mem(address_map &map);
void model2_snd(address_map &map);
uint8_t m_gamma_table[256];
void debug_init();
void debug_commands( int ref, const std::vector<std::string> &params );
void debug_geo_dasm_command(int ref, const std::vector<std::string> &params);
void debug_tri_dump_command(int ref, const std::vector<std::string> &params);
void debug_help_command(int ref, const std::vector<std::string> &params);
protected:
virtual void video_start() override;
private:
void tri_list_dump(FILE *dst);
uint32_t m_intreq;
uint32_t m_intena;
uint32_t m_coproctl;
uint32_t m_coprocnt;
uint32_t m_geoctl;
uint32_t m_geocnt;
uint32_t m_videocontrol;
int m_port_1c00004;
int m_port_1c00006;
int m_port_1c00010;
int m_port_1c00012;
int m_port_1c00014;
virtual void copro_halt() = 0;
virtual void copro_boot() = 0;
private:
void tri_list_dump(FILE *dst);
uint32_t m_geoctl;
uint32_t m_geocnt;
uint32_t m_videocontrol;
bool m_render_unk;
bool m_render_mode;
bool m_render_test_mode;
@ -331,23 +312,96 @@ private:
/*****************************
*
* Model 2
* Model 2/2A TGP support
*
*****************************/
class model2o_state : public model2_state
class model2_tgp_state : public model2_state
{
public:
model2_tgp_state(const machine_config &mconfig, device_type type, const char *tag)
: model2_state(mconfig, type, tag),
m_copro_tgp(*this, "copro_tgp"),
m_copro_tgp_program(*this, "copro_tgp_program"),
m_copro_tgp_tables(*this, "copro_tgp_tables"),
m_copro_tgp_bank(*this, "copro_tgp_bank")
{}
DECLARE_MACHINE_START(model2_tgp);
DECLARE_MACHINE_START(srallyc);
protected:
required_device<mb86234_device> m_copro_tgp;
required_shared_ptr<uint32_t> m_copro_tgp_program;
required_region_ptr<uint32_t> m_copro_tgp_tables;
required_device<address_map_bank_device> m_copro_tgp_bank;
u32 m_copro_tgp_bank_reg;
u32 m_copro_sincos_base;
u32 m_copro_inv_base;
u32 m_copro_isqrt_base;
u32 m_copro_atan_base[4];
DECLARE_READ32_MEMBER(copro_tgp_buffer_r);
DECLARE_WRITE32_MEMBER(copro_tgp_buffer_w);
DECLARE_WRITE32_MEMBER(copro_function_port_w);
DECLARE_READ32_MEMBER(copro_fifo_r);
DECLARE_WRITE32_MEMBER(copro_fifo_w);
DECLARE_WRITE32_MEMBER(tex0_w);
DECLARE_WRITE32_MEMBER(tex1_w);
DECLARE_READ32_MEMBER(copro_tgp_fifoin_pop);
DECLARE_WRITE32_MEMBER(copro_tgp_fifoout_push);
DECLARE_WRITE32_MEMBER(copro_tgp_bank_w);
DECLARE_READ32_MEMBER(copro_tgp_memory_r);
DECLARE_WRITE32_MEMBER(copro_tgp_memory_w);
DECLARE_WRITE32_MEMBER(copro_sincos_w);
DECLARE_READ32_MEMBER(copro_sincos_r);
DECLARE_WRITE32_MEMBER(copro_inv_w);
DECLARE_READ32_MEMBER(copro_inv_r);
DECLARE_WRITE32_MEMBER(copro_isqrt_w);
DECLARE_READ32_MEMBER(copro_isqrt_r);
DECLARE_WRITE32_MEMBER(copro_atan_w);
DECLARE_READ32_MEMBER(copro_atan_r);
DECLARE_MACHINE_RESET(model2_tgp);
void model2_tgp_mem(address_map &map);
void copro_tgp_prog_map(address_map &map);
void copro_tgp_data_map(address_map &map);
void copro_tgp_bank_map(address_map &map);
void copro_tgp_io_map(address_map &map);
void copro_tgp_rf_map(address_map &map);
virtual void copro_halt() override;
virtual void copro_boot() override;
};
/*****************************
*
* Model 2 support
*
*****************************/
class model2o_state : public model2_tgp_state
{
public:
model2o_state(const machine_config &mconfig, device_type type, const char *tag)
: model2_state(mconfig, type, tag)
: model2_tgp_state(mconfig, type, tag)
{}
DECLARE_MACHINE_RESET(model2o);
void daytona(machine_config &config);
void model2o(machine_config &config);
protected:
DECLARE_READ32_MEMBER(daytona_unk_r);
DECLARE_READ8_MEMBER(model2o_in_r);
DECLARE_READ32_MEMBER(fifo_control_2o_r);
void daytona(machine_config &config);
void model2o(machine_config &config);
void model2o_mem(address_map &map);
};
@ -399,19 +453,23 @@ private:
*
*****************************/
class model2a_state : public model2_state
class model2a_state : public model2_tgp_state
{
public:
model2a_state(const machine_config &mconfig, device_type type, const char *tag)
: model2_state(mconfig, type, tag)
: model2_tgp_state(mconfig, type, tag)
{}
DECLARE_MACHINE_RESET(model2a);
void manxtt(machine_config &config);
void manxttdx(machine_config &config);
void model2a(machine_config &config);
void model2a_0229(machine_config &config);
void model2a_5881(machine_config &config);
void srallyc(machine_config &config);
protected:
void model2a_crx_mem(address_map &map);
void model2a_5881_mem(address_map &map);
};
@ -426,19 +484,40 @@ class model2b_state : public model2_state
{
public:
model2b_state(const machine_config &mconfig, device_type type, const char *tag)
: model2_state(mconfig, type, tag)
: model2_state(mconfig, type, tag),
m_copro_adsp(*this, "copro_adsp")
{}
DECLARE_MACHINE_RESET(model2b);
DECLARE_MACHINE_START(model2b);
DECLARE_MACHINE_START(srallyc);
void model2b(machine_config &config);
void model2b_0229(machine_config &config);
void model2b_5881(machine_config &config);
void indy500(machine_config &config);
void rchase2(machine_config &config);
protected:
required_device<adsp21062_device> m_copro_adsp;
DECLARE_WRITE32_MEMBER(copro_function_port_w);
DECLARE_READ32_MEMBER(copro_fifo_r);
DECLARE_WRITE32_MEMBER(copro_fifo_w);
DECLARE_WRITE32_MEMBER(copro_sharc_iop_w);
DECLARE_READ32_MEMBER(copro_sharc_buffer_r);
DECLARE_WRITE32_MEMBER(copro_sharc_buffer_w);
void model2b_crx_mem(address_map &map);
void model2b_5881_mem(address_map &map);
// TODO: split into own class
void rchase2_iocpu_map(address_map &map);
void rchase2_ioport_map(address_map &map);
void copro_sharc_map(address_map &map);
virtual void copro_halt() override;
virtual void copro_boot() override;
};
/*****************************
@ -451,19 +530,37 @@ class model2c_state : public model2_state
{
public:
model2c_state(const machine_config &mconfig, device_type type, const char *tag)
: model2_state(mconfig, type, tag)
: model2_state(mconfig, type, tag),
m_copro_tgpx4(*this, "copro_tgpx4"),
m_copro_tgpx4_program(*this, "copro_tgpx4_program")
{}
DECLARE_READ32_MEMBER(fifo_control_2c_r);
DECLARE_MACHINE_RESET(model2c);
DECLARE_MACHINE_START(model2c);
DECLARE_MACHINE_START(srallyc);
void model2c(machine_config &config);
void model2c_5881(machine_config &config);
void overrev2c(machine_config &config);
void stcc(machine_config &config);
protected:
required_device<mb86235_device> m_copro_tgpx4;
required_shared_ptr<uint64_t> m_copro_tgpx4_program;
DECLARE_WRITE32_MEMBER(copro_function_port_w);
DECLARE_READ32_MEMBER(copro_fifo_r);
DECLARE_WRITE32_MEMBER(copro_fifo_w);
TIMER_DEVICE_CALLBACK_MEMBER(model2c_interrupt);
void model2c_crx_mem(address_map &map);
void model2c_5881_mem(address_map &map);
void copro_tgpx4_map(address_map &map);
void copro_tgpx4_data_map(address_map &map);
virtual void copro_halt() override;
virtual void copro_boot() override;
};
/*****************************

File diff suppressed because it is too large Load Diff