-sun4c: Added savestate support. [Ryan Holtz]

-sun4c: SPARCstation IPX, SLC, 1+ and 2 now boot, but get angry to varying degrees for varying reasons. [Ryan Holtz]
This commit is contained in:
mooglyguy 2018-09-29 02:17:17 +02:00
parent 10e4a7babb
commit a5bec0491f
10 changed files with 303 additions and 47 deletions

View File

@ -47,7 +47,6 @@ sbus_bwtwo_device::sbus_bwtwo_device(const machine_config &mconfig, const char *
: device_t(mconfig, SBUS_BWTWO, tag, owner, clock)
, device_sbus_card_interface(mconfig, *this)
, m_rom(*this, "prom")
//, m_vram(*this, "vram")
, m_screen(*this, "screen")
{
}
@ -55,6 +54,7 @@ sbus_bwtwo_device::sbus_bwtwo_device(const machine_config &mconfig, const char *
void sbus_bwtwo_device::device_start()
{
m_vram = std::make_unique<uint8_t[]>(0x100000);
save_pointer(NAME(m_vram), 0x100000);
for (int i = 0; i < 0x100; i++)
{

View File

@ -36,6 +36,128 @@ sbus_cgsix_device::sbus_cgsix_device(const machine_config &mconfig, device_type
void sbus_cgsix_device::device_start()
{
m_vram = std::make_unique<uint32_t[]>(m_vram_size / 4);
save_pointer(NAME(m_vram), m_vram_size / 4);
save_item(NAME(m_vram_size));
save_item(NAME(m_fbc.m_clip_check));
save_item(NAME(m_fbc.m_status));
save_item(NAME(m_fbc.m_draw_status));
save_item(NAME(m_fbc.m_blit_status));
save_item(NAME(m_fbc.m_font));
save_item(NAME(m_fbc.m_x0));
save_item(NAME(m_fbc.m_y0));
save_item(NAME(m_fbc.m_z0));
save_item(NAME(m_fbc.m_color0));
save_item(NAME(m_fbc.m_x1));
save_item(NAME(m_fbc.m_y1));
save_item(NAME(m_fbc.m_z1));
save_item(NAME(m_fbc.m_color1));
save_item(NAME(m_fbc.m_x2));
save_item(NAME(m_fbc.m_y2));
save_item(NAME(m_fbc.m_z2));
save_item(NAME(m_fbc.m_color2));
save_item(NAME(m_fbc.m_x3));
save_item(NAME(m_fbc.m_y3));
save_item(NAME(m_fbc.m_z3));
save_item(NAME(m_fbc.m_color3));
save_item(NAME(m_fbc.m_raster_offx));
save_item(NAME(m_fbc.m_raster_offy));
save_item(NAME(m_fbc.m_autoincx));
save_item(NAME(m_fbc.m_autoincy));
save_item(NAME(m_fbc.m_clip_minx));
save_item(NAME(m_fbc.m_clip_miny));
save_item(NAME(m_fbc.m_clip_maxx));
save_item(NAME(m_fbc.m_clip_maxy));
save_item(NAME(m_fbc.m_fcolor));
save_item(NAME(m_fbc.m_bcolor));
save_item(NAME(m_fbc.m_rasterop));
save_item(NAME(m_fbc.m_plane_mask));
save_item(NAME(m_fbc.m_pixel_mask));
save_item(NAME(m_fbc.m_patt_align));
save_item(NAME(m_fbc.m_pattern[8]));
save_item(NAME(m_fbc.m_ipoint_absx));
save_item(NAME(m_fbc.m_ipoint_absy));
save_item(NAME(m_fbc.m_ipoint_absz));
save_item(NAME(m_fbc.m_ipoint_relx));
save_item(NAME(m_fbc.m_ipoint_rely));
save_item(NAME(m_fbc.m_ipoint_relz));
save_item(NAME(m_fbc.m_ipoint_r));
save_item(NAME(m_fbc.m_ipoint_g));
save_item(NAME(m_fbc.m_ipoint_b));
save_item(NAME(m_fbc.m_ipoint_a));
save_item(NAME(m_fbc.m_iline_absx));
save_item(NAME(m_fbc.m_iline_absy));
save_item(NAME(m_fbc.m_iline_absz));
save_item(NAME(m_fbc.m_iline_relx));
save_item(NAME(m_fbc.m_iline_rely));
save_item(NAME(m_fbc.m_iline_relz));
save_item(NAME(m_fbc.m_iline_r));
save_item(NAME(m_fbc.m_iline_g));
save_item(NAME(m_fbc.m_iline_b));
save_item(NAME(m_fbc.m_iline_a));
save_item(NAME(m_fbc.m_itri_absx));
save_item(NAME(m_fbc.m_itri_absy));
save_item(NAME(m_fbc.m_itri_absz));
save_item(NAME(m_fbc.m_itri_relx));
save_item(NAME(m_fbc.m_itri_rely));
save_item(NAME(m_fbc.m_itri_relz));
save_item(NAME(m_fbc.m_itri_r));
save_item(NAME(m_fbc.m_itri_g));
save_item(NAME(m_fbc.m_itri_b));
save_item(NAME(m_fbc.m_itri_a));
save_item(NAME(m_fbc.m_iquad_absx));
save_item(NAME(m_fbc.m_iquad_absy));
save_item(NAME(m_fbc.m_iquad_absz));
save_item(NAME(m_fbc.m_iquad_relx));
save_item(NAME(m_fbc.m_iquad_rely));
save_item(NAME(m_fbc.m_iquad_relz));
save_item(NAME(m_fbc.m_iquad_r));
save_item(NAME(m_fbc.m_iquad_g));
save_item(NAME(m_fbc.m_iquad_b));
save_item(NAME(m_fbc.m_iquad_a));
save_item(NAME(m_fbc.m_irect_absx));
save_item(NAME(m_fbc.m_irect_absy));
save_item(NAME(m_fbc.m_irect_absz));
save_item(NAME(m_fbc.m_irect_relx));
save_item(NAME(m_fbc.m_irect_rely));
save_item(NAME(m_fbc.m_irect_relz));
save_item(NAME(m_fbc.m_irect_r));
save_item(NAME(m_fbc.m_irect_g));
save_item(NAME(m_fbc.m_irect_b));
save_item(NAME(m_fbc.m_irect_a));
save_item(NAME(m_fbc.m_vertex_count));
for (int i = 0; i < 0x1000; i++)
{
save_item(NAME(m_fbc.m_prim_buf[i].m_absx), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_absy), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_absz), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_relx), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_rely), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_relz), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_r), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_g), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_b), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_a), i);
}
save_item(NAME(m_fbc.m_curr_prim_type));
}
void sbus_cgsix_device::device_reset()

View File

@ -345,7 +345,7 @@ protected:
uint32_t m_a;
};
enum prim_type
enum prim_type : uint32_t
{
PRIM_POINT = 0,
PRIM_LINE,
@ -462,7 +462,7 @@ protected:
vertex_t m_prim_buf[0x1000]; // unknown size
uint32_t m_vertex_count;
prim_type m_curr_prim_type;
uint32_t m_curr_prim_type;
};
required_memory_region m_rom;

View File

@ -55,6 +55,7 @@ sbus_cgthree_device::sbus_cgthree_device(const machine_config &mconfig, const ch
void sbus_cgthree_device::device_start()
{
m_vram = std::make_unique<uint32_t[]>(0x100000/4);
save_pointer(NAME(m_vram), 0x100000/4);
}
void sbus_cgthree_device::device_reset()

View File

@ -21,13 +21,13 @@ class sbus_slot_device : public device_t, public device_slot_interface
public:
// construction/destruction
template <typename T, typename U>
sbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&sbus_tag, U &&opts, const char *dflt)
sbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&sbus_tag, U &&opts, const char *dflt, bool fixed = false)
: sbus_slot_device(mconfig, tag, owner, clock)
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
set_fixed(fixed);
m_sbus.set_tag(std::forward<T>(sbus_tag));
}
sbus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

View File

@ -343,8 +343,10 @@ void mb86901_device::device_start()
save_item(NAME(m_bp_irl));
save_item(NAME(m_bp_fpu_present));
save_item(NAME(m_bp_cp_present));
save_item(NAME(m_pb_error));
save_item(NAME(m_pb_block_ldst_byte));
save_item(NAME(m_pb_block_ldst_word));
save_item(NAME(m_irq_state));
save_item(NAME(m_trap));
save_item(NAME(m_tt));
save_item(NAME(m_ticc_trap_type));
@ -384,9 +386,27 @@ void mb86901_device::device_start()
save_item(NAME(m_ps));
save_item(NAME(m_et));
save_item(NAME(m_cwp));
save_item(NAME(m_alu_op3_assigned));
save_item(NAME(m_ldst_op3_assigned));
save_item(NAME(m_alu_setcc));
save_item(NAME(m_privileged_asr));
save_item(NAME(m_illegal_instruction_asr));
save_item(NAME(m_mae));
save_item(NAME(m_no_annul));
save_item(NAME(m_hold_bus));
save_item(NAME(m_icount));
save_item(NAME(m_stashed_icount));
save_item(NAME(m_insn_space));
save_item(NAME(m_data_space));
#if LOG_FCODES
save_item(NAME(m_ss1_next_pc));
save_item(NAME(m_ss1_next_opcode));
save_item(NAME(m_ss1_next_handler_base));
save_item(NAME(m_ss1_next_entry_point));
save_item(NAME(m_ss1_next_stack));
save_item(NAME(m_log_fcodes));
#endif
// set our instruction counter
set_icountptr(m_icount);
@ -462,6 +482,17 @@ void mb86901_device::device_reset()
}
//-------------------------------------------------
// device_post_load - update register pointers
// after loading a savestate
//-------------------------------------------------
void mb86901_device::device_post_load()
{
update_gpr_pointers();
}
//-------------------------------------------------
// memory_space_config - return the configuration
// of the specified address space, or nullptr if

View File

@ -34,6 +34,7 @@ public:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_stop() override;
virtual void device_post_load() override;
virtual void device_resolve_objects() override;
// device_execute_interface overrides

View File

@ -42,6 +42,37 @@ void sun4c_mmu_device::device_start()
// allocate timer for system reset
m_reset_timer = timer_alloc(TIMER_RESET);
m_reset_timer->adjust(attotime::never);
for (int i = 0; i < 16; i++)
{
save_item(NAME(m_segmap[i]), i);
save_item(NAME(m_segmap_masked[i]), i);
}
for (int i = 0; i < 16384; i++)
{
save_item(NAME(m_pagemap[i].valid), i);
save_item(NAME(m_pagemap[i].writable), i);
save_item(NAME(m_pagemap[i].supervisor), i);
save_item(NAME(m_pagemap[i].uncached), i);
save_item(NAME(m_pagemap[i].accessed), i);
save_item(NAME(m_pagemap[i].modified), i);
save_item(NAME(m_pagemap[i].page), i);
save_item(NAME(m_pagemap[i].type), i);
}
save_item(NAME(m_cachetags));
save_item(NAME(m_cachedata));
save_item(NAME(m_ram_size));
save_item(NAME(m_ram_size_words));
save_item(NAME(m_context));
save_item(NAME(m_context_masked));
save_item(NAME(m_system_enable));
save_item(NAME(m_fetch_bootrom));
save_item(NAME(m_buserr));
save_item(NAME(m_page_valid));
save_item(NAME(m_ctx_mask));
save_item(NAME(m_pmeg_mask));
}
void sun4c_mmu_device::device_reset()

View File

@ -21,8 +21,8 @@ public:
sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint8_t ctx_mask, uint8_t pmeg_mask)
: sun4c_mmu_device(mconfig, tag, owner, clock)
{
m_ctx_mask = ctx_mask;
m_pmeg_mask = pmeg_mask;
set_ctx_mask(ctx_mask);
set_pmeg_mask(pmeg_mask);
}
sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@ -35,6 +35,9 @@ public:
auto type1_r() { return m_type1_r.bind(); }
auto type1_w() { return m_type1_w.bind(); }
void set_ctx_mask(uint8_t ctx_mask) { m_ctx_mask = ctx_mask; }
void set_pmeg_mask(uint8_t pmeg_mask) { m_pmeg_mask = pmeg_mask; }
enum insn_data_mode
{
USER_INSN,

View File

@ -541,6 +541,7 @@ public:
, m_scsibus(*this, "scsibus")
, m_scsi(*this, "scsibus:7:ncr53c90a")
, m_sbus(*this, "sbus")
, m_sbus_slot(*this, "slot%u", 1U)
, m_type0space(*this, "type0")
, m_type1space(*this, "type1")
, m_ram(*this, RAM_TAG)
@ -550,14 +551,16 @@ public:
}
void sun4c(machine_config &config);
void sun4_20(machine_config &config);
void sun4_40(machine_config &config);
void sun4_50(machine_config &config);
void sun4_60(machine_config &config);
void sun4_65(machine_config &config);
void sun4_75(machine_config &config);
void sun4(machine_config &config);
void init_sun4();
void init_sun4c();
void init_ss2();
private:
virtual void machine_reset() override;
@ -680,6 +683,7 @@ private:
required_device<ncr53c90a_device> m_scsi;
optional_device<sbus_device> m_sbus;
optional_device_array<sbus_slot_device, 3> m_sbus_slot;
optional_device<address_map_bank_device> m_type0space;
optional_device<address_map_bank_device> m_type1space;
memory_access_cache<2, 0, ENDIANNESS_BIG> *m_type1_cache;
@ -1209,6 +1213,50 @@ void sun4_state::machine_start()
// allocate timer for system reset
m_reset_timer = timer_alloc(TIMER_RESET);
m_reset_timer->adjust(attotime::never);
for (int i = 0; i < 16; i++)
{
save_item(NAME(m_segmap[i]), i);
save_item(NAME(m_segmap_masked[i]), i);
}
for (int i = 0; i < 16384; i++)
{
save_item(NAME(m_pagemap[i].valid), i);
save_item(NAME(m_pagemap[i].writable), i);
save_item(NAME(m_pagemap[i].supervisor), i);
save_item(NAME(m_pagemap[i].uncached), i);
save_item(NAME(m_pagemap[i].accessed), i);
save_item(NAME(m_pagemap[i].modified), i);
save_item(NAME(m_pagemap[i].page), i);
save_item(NAME(m_pagemap[i].type), i);
}
save_item(NAME(m_cachetags));
save_item(NAME(m_cachedata));
save_item(NAME(m_ram_size));
save_item(NAME(m_ram_size_words));
save_item(NAME(m_context));
save_item(NAME(m_context_masked));
save_item(NAME(m_system_enable));
save_item(NAME(m_fetch_bootrom));
save_item(NAME(m_buserr));
save_item(NAME(m_page_valid));
save_item(NAME(m_auxio));
save_item(NAME(m_counter));
save_item(NAME(m_dma));
save_item(NAME(m_dma_irq));
save_item(NAME(m_dma_tc_read));
save_item(NAME(m_dma_pack_register));
save_item(NAME(m_scsi_irq));
save_item(NAME(m_fdc_irq));
save_item(NAME(m_irq_reg));
save_item(NAME(m_scc1_int));
save_item(NAME(m_scc2_int));
save_item(NAME(m_diag));
save_item(NAME(m_arch));
}
READ32_MEMBER( sun4_state::ram_r )
@ -1888,11 +1936,11 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(sun4_state::sun4c)
/* basic machine hardware */
MCFG_DEVICE_ADD(m_maincpu, MB86901, 16'670'000)
MCFG_DEVICE_ADD(m_maincpu, MB86901, 20'000'000)
MCFG_SPARC_ADD_ASI_DESC(sun4c_asi_desc)
m_maincpu->set_addrmap(0, &sun4_state::sun4c_debugger_map);
SUN4C_MMU(config, m_mmu, 16'670'000, 7, 0x7f);
SUN4C_MMU(config, m_mmu, 20'000'000, 7, 0x7f);
m_mmu->type1_r().set(m_type1space, FUNC(address_map_bank_device::read32));
m_mmu->type1_w().set(m_type1space, FUNC(address_map_bank_device::write32));
m_mmu->set_cpu(m_maincpu);
@ -1914,7 +1962,7 @@ MACHINE_CONFIG_START(sun4_state::sun4c)
ADDRESS_MAP_BANK(config, m_type0space).set_map(&sun4_state::type0space_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
// MMU Type 1 device space
ADDRESS_MAP_BANK(config, m_type1space).set_map(&sun4_state::type1space_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
ADDRESS_MAP_BANK(config, m_type1space).set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
// Ethernet
AM79C90(config, m_lance, 10'000'000); // clock is a guess
@ -1956,57 +2004,81 @@ MACHINE_CONFIG_START(sun4_state::sun4c)
MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr53c90a", true)
MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); })
// SBus
SBUS(config, m_sbus, 20'000'000, "maincpu", "type1");
SBUS_SLOT(config, m_sbus_slot[0], 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, m_sbus_slot[1], 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, m_sbus_slot[2], 20'000'000, m_sbus, sbus_cards, nullptr);
MACHINE_CONFIG_END
void sun4_state::sun4_20(machine_config &config)
{
sun4c(config);
m_sbus_slot[0]->set_fixed(true);
m_sbus_slot[1]->set_fixed(true);
m_sbus_slot[2]->set_default_option("bwtwo");
m_sbus_slot[2]->set_fixed(true);
}
void sun4_state::sun4_40(machine_config &config)
{
sun4c(config);
m_mmu->set_clock(25'000'000);
m_maincpu->set_clock(25'000'000);
m_maincpu->set_mmu(m_mmu);
m_type1space->set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
m_sbus->set_clock(25'000'000);
m_sbus_slot[0]->set_clock(25'000'000);
m_sbus_slot[1]->set_clock(25'000'000);
m_sbus_slot[2]->set_clock(25'000'000);
m_sbus_slot[2]->set_default_option("bwtwo");
m_sbus_slot[2]->set_fixed(true);
}
// SBus
SBUS(config, m_sbus, 25'000'000, "maincpu", "type1");
SBUS_SLOT(config, "slot1", 25'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot2", 25'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot3", 25'000'000, m_sbus, sbus_cards, "bwtwo");
void sun4_state::sun4_50(machine_config &config)
{
sun4c(config);
m_mmu->set_clock(40'000'000);
m_maincpu->set_clock(40'000'000);
m_sbus->set_clock(20'000'000);
m_sbus_slot[0]->set_clock(20'000'000);
m_sbus_slot[1]->set_clock(20'000'000);
m_sbus_slot[2]->set_clock(20'000'000);
m_sbus_slot[2]->set_default_option("turbogx"); // not accurate, should be gxp, not turbogx
m_sbus_slot[2]->set_fixed(true);
}
void sun4_state::sun4_60(machine_config &config)
{
sun4c(config);
}
m_mmu->set_clock(20'000'000);
m_maincpu->set_clock(20'000'000);
m_maincpu->set_mmu(m_mmu);
void sun4_state::sun4_65(machine_config &config)
{
sun4c(config);
m_type1space->set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
m_mmu->set_clock(25'000'000);
m_maincpu->set_clock(25'000'000);
// SBus
SBUS(config, m_sbus, 20'000'000, "maincpu", "type1");
SBUS_SLOT(config, "slot1", 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot2", 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot3", 20'000'000, m_sbus, sbus_cards, nullptr);
m_sbus->set_clock(25'000'000);
m_sbus_slot[0]->set_clock(25'000'000);
m_sbus_slot[1]->set_clock(25'000'000);
m_sbus_slot[2]->set_clock(25'000'000);
}
void sun4_state::sun4_75(machine_config &config)
{
sun4c(config);
m_mmu->set_ctx_mask(0xf);
m_mmu->set_pmeg_mask(0xff);
m_mmu->set_clock(40'000'000);
m_maincpu->set_clock(40'000'000);
m_maincpu->set_mmu(m_mmu);
m_type1space->set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
// SBus
SBUS(config, m_sbus, 20'000'000, "maincpu", "type1");
SBUS_SLOT(config, "slot1", 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot2", 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot3", 20'000'000, m_sbus, sbus_cards, nullptr);
}
/*
@ -2258,11 +2330,6 @@ void sun4_state::init_sun4c()
m_arch = ARCH_SUN4C;
}
void sun4_state::init_ss2()
{
m_arch = ARCH_SUN4C;
}
/* Drivers */
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
@ -2272,12 +2339,12 @@ COMP( 1987, sun4_300, 0, 0, sun4, sun4, sun4_state, init_sun4,
COMP( 198?, sun4_400, 0, 0, sun4, sun4, sun4_state, init_sun4, "Sun Microsystems", "Sun 4/4x0", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// sun4c
COMP( 1990, sun4_40, sun4_300, 0, sun4_40, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation IPC (Sun 4/40)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1991, sun4_50, sun4_300, 0, sun4c, sun4, sun4_state, init_ss2, "Sun Microsystems", "SPARCstation IPX (Sun 4/50)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 199?, sun4_20, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1989, sun4_60, sun4_300, 0, sun4_60, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1990, sun4_65, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1+ (Sun 4/65)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1990, sun4_75, sun4_300, 0, sun4_75, sun4, sun4_state, init_ss2, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1990, sun4_40, sun4_300, 0, sun4_40, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation IPC (Sun 4/40)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
COMP( 1991, sun4_50, sun4_300, 0, sun4_50, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation IPX (Sun 4/50)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 199?, sun4_20, sun4_300, 0, sun4_20, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1989, sun4_60, sun4_300, 0, sun4_60, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
COMP( 1990, sun4_65, sun4_300, 0, sun4_65, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1+ (Sun 4/65)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1990, sun4_75, sun4_300, 0, sun4_75, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// sun4m (using the SPARC "reference MMU", probably will go to a separate driver)
COMP( 1992, sun_s10, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 10 (Sun S10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )