diff --git a/src/devices/machine/smpc.cpp b/src/devices/machine/smpc.cpp index 8e55d7a529c..aa8ef073dbb 100644 --- a/src/devices/machine/smpc.cpp +++ b/src/devices/machine/smpc.cpp @@ -160,11 +160,8 @@ SMPC NVRAM contents: #include "emu.h" #include "machine/smpc.h" -#include "includes/saturn.h" // FIXME: this is a dependency from devices on MAME -#include "machine/eepromser.h" #include "screen.h" - #include "coreutil.h" @@ -178,9 +175,10 @@ SMPC NVRAM contents: // device type definition DEFINE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device, "smpc_hle", "Sega Saturn SMPC HLE (HD404920FS)") -// TODO: this is actually a DEVICE_ADDRESS_MAP, fix once everything is merged +// TODO: use DEVICE_ADDRESS_MAP once this fatalerror is fixed: +// "uplift_submaps unhandled case: range straddling slots." static ADDRESS_MAP_START( smpc_regs, 0, 8, smpc_hle_device ) - ADDRESS_MAP_UNMAP_HIGH +// ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00, 0x0d) AM_WRITE(ireg_w) AM_RANGE(0x1f, 0x1f) AM_WRITE(command_register_w) AM_RANGE(0x20, 0x5f) AM_READ(oreg_r) @@ -206,6 +204,7 @@ smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, : device_t(mconfig, SMPC_HLE, tag, owner, clock), device_memory_interface(mconfig, *this), m_space_config("regs", ENDIANNESS_LITTLE, 8, 7, 0, nullptr, *ADDRESS_MAP_NAME(smpc_regs)), + m_smpc_nv(*this, "smpc_nv"), m_mshres(*this), m_mshnmi(*this), m_sshres(*this), @@ -217,10 +216,41 @@ smpc_hle_device::smpc_hle_device(const machine_config &mconfig, const char *tag, m_pdr2_read(*this), m_pdr1_write(*this), m_pdr2_write(*this), - m_irq_line(*this) + m_irq_line(*this), + m_ctrl1(nullptr), + m_ctrl2(nullptr) { + m_ctrl1 = nullptr; + m_ctrl2 = nullptr; + m_has_ctrl_ports = false; } +// method setters +void smpc_hle_device::static_set_region_code(device_t &device, uint8_t rgn) +{ + smpc_hle_device &dev = downcast(device); + dev.m_region_code = rgn; +} + +void smpc_hle_device::static_set_control_port_tags(device_t &device, const char *tag1, const char *tag2) +{ + smpc_hle_device &dev = downcast(device); + dev.m_ctrl1_tag = tag1; + dev.m_ctrl2_tag = tag2; + // TODO: checking against nullptr still returns a device!? + dev.m_has_ctrl_ports = true; +} + +//------------------------------------------------- +// device_add_mconfig - device-specific machine +// configuration addiitons +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(smpc_hle_device::device_add_mconfig) + MCFG_NVRAM_ADD_0FILL("smpc_nv") // TODO: default for each region (+ move it inside SMPC when converted to device) + + // TODO: custom RTC subdevice +MACHINE_CONFIG_END //------------------------------------------------- // device_start - device-specific startup @@ -231,6 +261,8 @@ void smpc_hle_device::device_start() system_time systime; machine().base_datetime(systime); + m_smpc_nv->set_base(&m_smem, 4); + m_mshres.resolve_safe(); m_mshnmi.resolve_safe(); m_sshres.resolve_safe(); @@ -263,10 +295,12 @@ void smpc_hle_device::device_start() save_item(NAME(m_intback_stage)); save_item(NAME(m_pmode)); save_item(NAME(m_rtc_data)); + save_item(NAME(m_smem)); m_cmd_timer = timer_alloc(COMMAND_ID); m_rtc_timer = timer_alloc(RTC_ID); m_intback_timer = timer_alloc(INTBACK_ID); + m_sndres_timer = timer_alloc(SNDRES_ID); // TODO: tag-ify, needed when SCU will be a device m_screen = machine().first_screen(); @@ -279,6 +313,9 @@ void smpc_hle_device::device_start() m_rtc_data[5] = DectoBCD(systime.local_time.minute); m_rtc_data[6] = DectoBCD(systime.local_time.second); + m_ctrl1 = downcast(machine().device(m_ctrl1_tag)); + m_ctrl2 = downcast(machine().device(m_ctrl2_tag)); +// m_has_ctrl_ports = (m_ctrl1 != nullptr && m_ctrl2 != nullptr); } @@ -301,6 +338,7 @@ void smpc_hle_device::device_reset() m_cmd_timer->reset(); m_intback_timer->reset(); + m_sndres_timer->reset(); m_comreg = 0xff; m_command_in_progress = false; m_NMI_reset = false; @@ -309,11 +347,6 @@ void smpc_hle_device::device_reset() m_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); } -//------------------------------------------------- -// memory_space_config - return a description of -// any address spaces owned by this device -//------------------------------------------------- - device_memory_interface::space_config_vector smpc_hle_device::memory_space_config() const { return space_config_vector { @@ -322,7 +355,6 @@ device_memory_interface::space_config_vector smpc_hle_device::memory_space_confi } - //************************************************************************** // READ/WRITE HANDLERS //************************************************************************** @@ -471,65 +503,26 @@ uint8_t smpc_hle_device::get_ddr(bool which) return which == true ? m_ddr2 : m_ddr1; } -// TODO: trampolines that needs to go away -uint8_t smpc_hle_device::get_ireg(uint8_t offset) -{ - return m_ireg[offset]; -} -void smpc_hle_device::set_oreg(uint8_t offset, uint8_t data) -{ - m_oreg[offset] = data; -} - -void smpc_hle_device::master_sh2_reset(bool state) -{ - m_mshres(state); -} - -void smpc_hle_device::slave_sh2_reset(bool state) -{ - m_sshres(state); -} - -void smpc_hle_device::sound_reset(bool state) -{ - m_sndres(state); -} - -void smpc_hle_device::system_reset(bool state) -{ - m_sysres(state); -} - -// actually a PLL connection, handled here for simplicity -void smpc_hle_device::system_halt_request(bool state) -{ - m_syshalt(state); -} - -void smpc_hle_device::dot_select_request(bool state) -{ - m_dotsel(state); -} - -bool smpc_hle_device::get_nmi_status() +inline bool smpc_hle_device::get_nmi_status() { return m_NMI_reset; } -void smpc_hle_device::master_sh2_nmi() +inline void smpc_hle_device::master_sh2_nmi() { m_mshnmi(1); m_mshnmi(0); } -void smpc_hle_device::irq_request() +inline void smpc_hle_device::irq_request() { m_irq_line(1); m_irq_line(0); } +// TODO: trampolines that needs to go away + READ8_MEMBER( smpc_hle_device::read ) { return this->space().read_byte(offset); @@ -620,6 +613,14 @@ void smpc_hle_device::device_timer(emu_timer &timer, device_timer_id id, int par m_sndres(m_comreg & 1); break; + case 0x08: // CDON + case 0x09: // CDOFF + // ... + m_command_in_progress = false; + m_oreg[31] = m_comreg; + sf_ack(true); //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high) + return; + // case 0x0a: // NETLINKON // case 0x0b: // NETLINKOFF @@ -655,9 +656,19 @@ void smpc_hle_device::device_timer(emu_timer &timer, device_timer_id id, int par return; case 0x16: // SETTIME + { for(int i=0;i<7;i++) m_rtc_data[i] = m_ireg[i]; break; + } + + case 0x17: // SETSMEM + { + for(int i=0;i<4;i++) + m_smem[i] = m_ireg[i]; + + break; + } case 0x18: // NMIREQ // NMI is unconditionally requested @@ -679,8 +690,16 @@ void smpc_hle_device::device_timer(emu_timer &timer, device_timer_id id, int par sf_ack(false); break; } + case INTBACK_ID: intback_continue_request(); break; case RTC_ID: handle_rtc_increment(); break; + + // from m68k reset opcode trigger + case SNDRES_ID: + m_sndres(1); + m_sndres(0); + break; + default: printf("%d\n",id); break; @@ -702,8 +721,8 @@ void smpc_hle_device::resolve_intback() m_oreg[8] = 0; // CTG0 / CTG1? - m_oreg[9] = 0; // TODO: system region on Saturn - + m_oreg[9] = m_region_code; // TODO: system region on Saturn + /* 0-11 -1-- unknown -x-- ---- VDP2 dot select @@ -723,7 +742,7 @@ void smpc_hle_device::resolve_intback() m_oreg[11] = 0 << 6; // CDRES for(i=0;i<4;i++) - m_oreg[12+i] = 0; //m_smpc.SMEM[i]); TODO + m_oreg[12+i] = m_smem[i]; for(i=0;i<15;i++) m_oreg[16+i] = 0xff; // undefined @@ -756,6 +775,9 @@ void smpc_hle_device::resolve_intback() void smpc_hle_device::intback_continue_request() { + if( m_has_ctrl_ports == true ) + read_saturn_ports(); + if (m_intback_stage == 2) { sr_set(0x80 | m_pmode); // pad 2, no more data, echo back pad mode set by intback @@ -769,8 +791,7 @@ void smpc_hle_device::intback_continue_request() irq_request(); m_oreg[31] = 0x10; // callback for last command issued - sf_ack(false); - + sf_ack(false); } int smpc_hle_device::DectoBCD(int num) @@ -790,6 +811,10 @@ int smpc_hle_device::DectoBCD(int num) return res; } +//************************************************************************** +// RTC handling +//************************************************************************** + void smpc_hle_device::handle_rtc_increment() { const uint8_t dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; @@ -859,157 +884,15 @@ void smpc_hle_device::handle_rtc_increment() //if((m_rtc_data[0] & 0xf0) >= 0xa0) { m_rtc_data[0] = 0; } //roll over } + + + /******************************************** * - * Command functions + * Saturn handlers * *******************************************/ -void saturn_state::smpc_master_on() -{ - m_smpc_hle->master_sh2_reset(0); -} - -TIMER_CALLBACK_MEMBER( saturn_state::smpc_slave_enable ) -{ - m_smpc_hle->slave_sh2_reset(param); - m_smpc_hle->set_oreg(31, param + 0x02); - m_smpc_hle->sf_ack(false); -// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); -} - -TIMER_CALLBACK_MEMBER( saturn_state::smpc_sound_enable ) -{ - m_smpc_hle->sound_reset(param); - m_smpc_hle->set_oreg(31, param + 0x06); //read-back for last command issued - m_smpc_hle->sf_ack(false); -} - -TIMER_CALLBACK_MEMBER( saturn_state::smpc_cd_enable ) -{ -// ... - m_smpc_hle->set_oreg(31,param + 0x08); //read-back for last command issued - m_smpc_hle->sf_ack(true); //clear hand-shake flag (TODO: diagnostic wants this to have bit 3 high) -} - -void saturn_state::smpc_system_reset() -{ - m_smpc_hle->system_reset(1); - m_smpc_hle->system_reset(0); - - // send a 1 -> 0 transition to reset line (was PULSE_LINE) - m_smpc_hle->master_sh2_reset(1); - m_smpc_hle->master_sh2_reset(0); -} - -TIMER_CALLBACK_MEMBER( saturn_state::smpc_change_clock ) -{ - if(LOG_SMPC) printf ("Clock change execute at (%d %d)\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); - - m_smpc_hle->dot_select_request(param); - - if(m_smpc_hle->get_nmi_status() == false) - m_smpc_hle->master_sh2_nmi(); - - m_smpc_hle->slave_sh2_reset(1); - - m_smpc_hle->system_halt_request(0); - - /* put issued command in OREG31 */ - m_smpc_hle->set_oreg( 31, 0x0e + param ); - /* clear hand-shake flag */ - m_smpc_hle->sf_ack(false); - // TODO: VDP1 / VDP2 / SCU / SCSP default power ON values??? -} - -TIMER_CALLBACK_MEMBER( saturn_state::stv_intback_peripheral ) -{ - if (m_smpc.intback_stage == 2) - { - m_smpc_hle->sr_set(0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback - m_smpc.intback_stage = 0; - } - else - { - m_smpc_hle->sr_set(0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback - m_smpc.intback_stage ++; - } - m_smpc_hle->irq_request(); - - m_smpc_hle->set_oreg(31, 0x10); /* callback for last command issued */ - m_smpc_hle->sf_ack(false); -} - - -TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback ) -{ - int i; - -// printf("%02x %02x %02x\n",m_smpc.intback_buf[0],m_smpc.intback_buf[1],m_smpc.intback_buf[2]); - - if(m_smpc.intback_buf[0] != 0) - { - m_smpc_hle->set_oreg(0, (0x80) | ((m_smpc_hle->get_nmi_status() & 1) << 6)); - - for(i=0;i<7;i++) - m_smpc_hle->set_oreg(1+i, m_smpc.rtc_data[i]); - - m_smpc_hle->set_oreg(8,0); // CTG0 / CTG1? - - m_smpc_hle->set_oreg(9,0); // TODO: system region on Saturn - - /* - 0-11 -1-- unknown - -x-- ---- VDP2 dot select - ---- x--- MSHNMI - ---- --x- SYSRES - ---- ---x SOUNDRES - */ - m_smpc_hle->set_oreg(10, 0 << 7 | - m_vdp2.dotsel << 6 | - 1 << 5 | - 1 << 4 | - 0 << 3 | - 1 << 2 | - 0 << 1 | - 0 << 0); - - m_smpc_hle->set_oreg(11,0 << 6); //CDRES - - for(i=0;i<4;i++) - m_smpc_hle->set_oreg(12+i,m_smpc.SMEM[i]); - - for(i=0;i<15;i++) - m_smpc_hle->set_oreg(16+i,0xff); // undefined - - m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral - m_smpc_hle->sr_set(0x40 | (m_smpc.intback_stage << 5)); - m_smpc.pmode = m_smpc.intback_buf[0]>>4; - - //if(LOG_SMPC) printf ("Interrupt: System Manager (SMPC) at scanline %04x, Vector 0x47 Level 0x08\n",scanline); - // send an interupt to the SCU - m_smpc_hle->irq_request(); - - /* put issued command in OREG31 */ - m_smpc_hle->set_oreg(31,0x10); // TODO: doc says 0? - /* clear hand-shake flag */ - m_smpc_hle->sf_ack(false); - } - else if(m_smpc.intback_buf[1] & 8) - { - m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral - m_smpc_hle->sr_set(0x40); - m_smpc_hle->set_oreg(31,0x10); - machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0); - } - else - { - /* Shienryu calls this, it would be plainly illegal on Saturn, I'll just return the command and clear the hs flag for now. */ - m_smpc_hle->set_oreg(31,0x10); - m_smpc_hle->sf_ack(false); - } -} - /* [0] port status: 0x04 Sega-tap @@ -1039,15 +922,8 @@ TIMER_CALLBACK_MEMBER( saturn_state::stv_smpc_intback ) how did a real unit behave in this case? */ -TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral ) +void smpc_hle_device::read_saturn_ports() { -// if (LOG_SMPC) logerror("SMPC: providing PAD data for intback, pad %d\n", intback_stage-2); - - // doesn't work? - //pad_num = m_smpc.intback_stage - 1; - - if(LOG_PAD_CMD) printf("%d %d %d\n", m_smpc.intback_stage - 1, machine().first_screen()->vpos(), (int)machine().first_screen()->frame_number()); - uint8_t status1 = m_ctrl1 ? m_ctrl1->read_status() : 0xf0; uint8_t status2 = m_ctrl2 ? m_ctrl2->read_status() : 0xf0; @@ -1055,519 +931,51 @@ TIMER_CALLBACK_MEMBER( saturn_state::intback_peripheral ) uint8_t ctrl1_offset = 0; // this is used when there is segatap or multitap connected uint8_t ctrl2_offset = 0; // this is used when there is segatap or multitap connected - m_smpc_hle->set_oreg(reg_offset++,status1); + m_oreg[reg_offset++] = status1; // read ctrl1 for (int i = 0; i < (status1 & 0xf); i++) { uint8_t id = m_ctrl1->read_id(i); - m_smpc_hle->set_oreg(reg_offset++,id); + m_oreg[reg_offset++] = id; for (int j = 0; j < (id & 0xf); j++) - m_smpc_hle->set_oreg(reg_offset++,m_ctrl1->read_ctrl(j + ctrl1_offset)); + m_oreg[reg_offset++] = m_ctrl1->read_ctrl(j + ctrl1_offset); ctrl1_offset += (id & 0xf); } - m_smpc_hle->set_oreg(reg_offset++,status2); + m_oreg[reg_offset++] = status2; // read ctrl2 for (int i = 0; i < (status2 & 0xf); i++) { uint8_t id = m_ctrl2->read_id(i); - m_smpc_hle->set_oreg(reg_offset++,id); + m_oreg[reg_offset++] = id; for (int j = 0; j < (id & 0xf); j++) - m_smpc_hle->set_oreg(reg_offset++,m_ctrl2->read_ctrl(j + ctrl2_offset)); + m_oreg[reg_offset++] = m_ctrl2->read_ctrl(j + ctrl2_offset); ctrl2_offset += (id & 0xf); } - - if (m_smpc.intback_stage == 2) - { - m_smpc_hle->sr_set(0x80 | m_smpc.pmode); // pad 2, no more data, echo back pad mode set by intback - m_smpc.intback_stage = 0; - } - else - { - m_smpc_hle->sr_set(0xc0 | m_smpc.pmode); // pad 1, more data, echo back pad mode set by intback - m_smpc.intback_stage ++; - } - - m_smpc_hle->irq_request(); - - m_smpc_hle->set_oreg(31,0x10); /* callback for last command issued */ - m_smpc_hle->sf_ack(false); } -// TODO: duplicated code -TIMER_CALLBACK_MEMBER( saturn_state::saturn_smpc_intback ) +INPUT_CHANGED_MEMBER(smpc_hle_device::trigger_nmi_r ) { - if(m_smpc.intback_buf[0] != 0) - { - { - int i; - - m_smpc_hle->set_oreg(0, (0x80) | ((m_smpc_hle->get_nmi_status() & 1) << 6)); // bit 7: SETTIME (RTC isn't setted up properly) - - for(i=0;i<7;i++) - m_smpc_hle->set_oreg(1+i, m_smpc.rtc_data[i]); - - m_smpc_hle->set_oreg(8, 0); //Cartridge code? - - m_smpc_hle->set_oreg(9, m_saturn_region); - - m_smpc_hle->set_oreg(10, 0 << 7 | - m_vdp2.dotsel << 6 | - 1 << 5 | - 1 << 4 | - 0 << 3 | - 1 << 2 | - 0 << 1 | - 0 << 0); - - m_smpc_hle->set_oreg(11,0 << 6); //CDRES - - for(i=0;i<4;i++) - m_smpc_hle->set_oreg(12+i,m_smpc.SMEM[i]); - - for(i=0;i<15;i++) - m_smpc_hle->set_oreg(16+i,0xff); // undefined - } - - m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral - m_smpc_hle->sr_set(0x40 | (m_smpc.intback_stage << 5)); - m_smpc.pmode = m_smpc.intback_buf[0]>>4; - - m_smpc_hle->irq_request(); - - /* put issued command in OREG31 */ - m_smpc_hle->set_oreg(31,0x10); - /* clear hand-shake flag */ - m_smpc_hle->sf_ack(false); - } - else if(m_smpc.intback_buf[1] & 8) - { - m_smpc.intback_stage = (m_smpc.intback_buf[1] & 8) >> 3; // first peripheral - m_smpc_hle->sr_set(0x40); - m_smpc_hle->set_oreg(31,0x10); - machine().scheduler().timer_set(attotime::from_usec(0), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0); - } - else - { -// printf("SMPC intback bogus behaviour called %02x %02x\n",m_smpc.IREG[0],m_smpc.IREG[1]); - } - -} - -void saturn_state::smpc_rtc_write() -{ - int i; - - for(i=0;i<7;i++) - m_smpc.rtc_data[i] = m_smpc_hle->get_ireg(i); -} - -void saturn_state::smpc_memory_setting() -{ - int i; - - for(i=0;i<4;i++) - m_smpc.SMEM[i] = m_smpc_hle->get_ireg(i); -} - -void saturn_state::smpc_nmi_req() -{ - // NMI is unconditionally requested - m_smpc_hle->master_sh2_nmi(); -} - -TIMER_CALLBACK_MEMBER( saturn_state::smpc_nmi_set ) -{ -// printf("%d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); - - m_NMI_reset = param; - /* put issued command in OREG31 */ - m_smpc_hle->set_oreg(31,0x19 + param); - - /* clear hand-shake flag */ - m_smpc_hle->sf_ack(false); -} - - -TIMER_CALLBACK_MEMBER( saturn_state::smpc_audio_reset_line_pulse ) -{ - m_smpc_hle->sound_reset(1); - m_smpc_hle->sound_reset(0); -} - -/******************************************** - * - * COMREG sub-routine - * - *******************************************/ - -void saturn_state::smpc_comreg_exec(address_space &space, uint8_t data, uint8_t is_stv) -{ - switch (data) - { - case 0x00: - if(LOG_SMPC) printf ("SMPC: Master ON\n"); - smpc_master_on(); - break; - //case 0x01: Master OFF? - case 0x02: - case 0x03: - if(LOG_SMPC) printf ("SMPC: Slave %s %d %d\n",(data & 1) ? "off" : "on",machine().first_screen()->hpos(),machine().first_screen()->vpos()); - machine().scheduler().timer_set(attotime::from_usec(15), timer_expired_delegate(FUNC(saturn_state::smpc_slave_enable),this),data & 1); - break; - case 0x06: - case 0x07: - if(LOG_SMPC) printf ("SMPC: Sound %s\n",(data & 1) ? "off" : "on"); - - if(!is_stv) - machine().scheduler().timer_set(attotime::from_usec(15), timer_expired_delegate(FUNC(saturn_state::smpc_sound_enable),this),data & 1); - break; - /*CD (SH-1) ON/OFF */ - case 0x08: - case 0x09: - printf ("SMPC: CD %s\n",(data & 1) ? "off" : "on"); - machine().scheduler().timer_set(attotime::from_usec(20), timer_expired_delegate(FUNC(saturn_state::smpc_cd_enable),this),data & 1); - break; - case 0x0a: - case 0x0b: - popmessage ("SMPC: NETLINK %s, contact MAMEdev",(data & 1) ? "off" : "on"); - break; - case 0x0d: - if(LOG_SMPC) printf ("SMPC: System Reset\n"); - smpc_system_reset(); - break; - case 0x0e: - case 0x0f: - if(LOG_SMPC) printf ("SMPC: Change Clock to %s (%d %d)\n",data & 1 ? "320" : "352",machine().first_screen()->hpos(),machine().first_screen()->vpos()); - - /* on ST-V timing of this is pretty fussy, you get 2 credits at start-up otherwise - * My current theory is that the PLL device can halt the whole system until the frequency change occurs. - * (cfr. diagram on page 3 of SMPC manual) - * I really don't think that the system can do an usable mid-frame clock switching anyway. - */ - m_smpc_hle->system_halt_request(1); - - machine().scheduler().timer_set(machine().first_screen()->time_until_pos(get_vblank_start_position()*get_ystep_count(), 0), timer_expired_delegate(FUNC(saturn_state::smpc_change_clock),this),data & 1); - break; - /*"Interrupt Back"*/ - case 0x10: - if(0) - { -// printf ("SMPC: Status Acquire %02x %02x %02x %d\n" m_smpc_hle->get_ireg(0),m_smpc.IREG[1],m_smpc.IREG[2],machine().first_screen()->vpos()); - } - - int timing; - - timing = 8; - - if( m_smpc_hle->get_ireg(0) != 0) // non-peripheral data - timing += 8; - - /* TODO: At vblank-out actually ... */ - if( m_smpc_hle->get_ireg(1) & 8) // peripheral data - timing += 700; - - /* TODO: check if IREG[2] is setted to 0xf0 */ - { - int i; - - for(i=0;i<3;i++) - m_smpc.intback_buf[i] = m_smpc_hle->get_ireg(i); - } - - if(is_stv) - { - machine().scheduler().timer_set(attotime::from_usec(timing), timer_expired_delegate(FUNC(saturn_state::stv_smpc_intback),this),0); //TODO: variable time - } - else - { - //if(LOG_PAD_CMD) printf("INTBACK %02x %02x %d %d\n",m_smpc.IREG[0],m_smpc.IREG[1],machine().first_screen()->vpos(),(int)machine().first_screen()->frame_number()); - machine().scheduler().timer_set(attotime::from_usec(timing), timer_expired_delegate(FUNC(saturn_state::saturn_smpc_intback),this),0); //TODO: is variable time correct? - } - break; - /* RTC write*/ - case 0x16: - if(LOG_SMPC) printf("SMPC: RTC write\n"); - smpc_rtc_write(); - break; - /* SMPC memory setting*/ - case 0x17: - if(LOG_SMPC) printf ("SMPC: memory setting\n"); - smpc_memory_setting(); - break; - case 0x18: - if(LOG_SMPC) printf ("SMPC: NMI request\n"); - smpc_nmi_req(); - break; - case 0x19: - case 0x1a: - /* TODO: timing */ - if(LOG_SMPC) printf ("SMPC: NMI %sable %d %d\n",data & 1 ? "Dis" : "En",machine().first_screen()->hpos(),machine().first_screen()->vpos()); - machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_nmi_set),this),data & 1); - break; - default: - printf ("cpu '%s' (PC=%08X) SMPC: undocumented Command %02x\n", space.device().tag(), space.device().safe_pc(), data); - } -} - -/******************************************** - * - * ST-V handlers - * - *******************************************/ - -READ8_MEMBER( saturn_state::stv_SMPC_r ) -{ - int return_data = 0; - - if(!(offset & 1)) - return 0; - - if(offset >= 0x20 && offset <= 0x5f) - return_data = m_smpc_hle->read(space,offset); - - if (offset == 0x61) // TODO: SR - return_data = m_smpc_hle->read(space,offset); - - if (offset == 0x63) - return_data = m_smpc_hle->read(space,offset); - - if (offset == 0x75)//PDR1 read - return_data = m_smpc_hle->read(space,offset); //ioport("DSW1")->read(); - - if (offset == 0x77)//PDR2 read - return_data = m_smpc_hle->read(space,offset); //(0xfe | m_eeprom->do_read()); - - return return_data; -} - -WRITE8_MEMBER( saturn_state::stv_SMPC_w ) -{ - if (!(offset & 1)) // avoid writing to even bytes + // punt if NMI trigger is disabled + if(!m_NMI_reset) return; -// if(LOG_SMPC) printf ("8-bit SMPC Write to Offset %02x with Data %02x\n", offset, data); - - if(offset >= 1 && offset <= 0xd) - m_smpc_hle->write(space,offset,data); - - #if 0 - if(offset == 1) //IREG0, check if a BREAK / CONTINUE request for INTBACK command - { - if(m_smpc.intback_stage) - { - if(data & 0x40) - { - if(LOG_PAD_CMD) printf("SMPC: BREAK request\n"); - m_smpc_hle->sr_ack(); - m_smpc.intback_stage = 0; - } - else if(data & 0x80) - { - if(LOG_PAD_CMD) printf("SMPC: CONTINUE request\n"); - machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::stv_intback_peripheral),this),0); /* TODO: is timing correct? */ - m_smpc_hle->set_oreg(31,0x10); - m_smpc_hle->sf_set(); - } - } - } - #endif - - if (offset == 0x1f) // COMREG - { - m_smpc_hle->write(space,offset,data); - -// smpc_comreg_exec(space,data,1); - - // we've processed the command, clear status flag - #if 0 - if(data != 0x10 && data != 0x02 && data != 0x03 && data != 0x08 && data != 0x09 && data != 0xe && data != 0xf && data != 0x19 && data != 0x1a) - { - m_smpc_hle->set_oreg(31,data); - m_smpc_hle->sf_ack(false); - } - #endif - /*TODO:emulate the timing of each command...*/ - } - - if(offset == 0x63) - m_smpc_hle->write(space,offset,data); - - // PDR1 - if(offset == 0x75) - m_smpc_hle->write(space,offset,data); - - // PDR2 - if(offset == 0x77) - m_smpc_hle->write(space,offset,data); - - if(offset == 0x79) - m_smpc_hle->write(space,offset,data); - - if(offset == 0x7b) - m_smpc_hle->write(space,offset,data); - - if(offset == 0x7d) - { - m_smpc_hle->write(space,offset,data); - } - - if(offset == 0x7f) - { - m_smpc_hle->write(space,offset,data); - } + // TODO: generated during the 3VINT period according to manual + if(newval) + master_sh2_nmi(); } -/******************************************** - * - * Saturn handlers - * - *******************************************/ - - - - -READ8_MEMBER( saturn_state::saturn_SMPC_r ) +/* Official documentation says that the "RESET/TAS opcodes aren't supported", but Out Run definitely contradicts with it. + Since that m68k can't reset itself via the RESET opcode I suppose that the SMPC actually do it by reading an i/o + connected to this opcode. */ +void smpc_hle_device::m68k_reset_trigger() { - uint8_t return_data = 0; - - if (!(offset & 1)) // avoid reading to even bytes (TODO: is it 0s or 1s?) - return 0x00; - - if(offset >= 0x20 && offset <= 0x5f) - return_data = m_smpc_hle->read(space,offset); - - if (offset == 0x61) - return_data = m_smpc_hle->read(space,offset); - - if (offset == 0x63) - { - //printf("SF %d %d\n",machine().first_screen()->hpos(),machine().first_screen()->vpos()); - return_data = m_smpc_hle->read(space,offset); - } - - if (offset == 0x75 || offset == 0x77)//PDR1/2 read - { - return_data = m_smpc_hle->read(space,offset); - #if 0 - if ((m_smpc.IOSEL1 && offset == 0x75) || (m_smpc.IOSEL2 && offset == 0x77)) - { - uint8_t cur_ddr; - - if (((m_ctrl1 && m_ctrl1->read_id(0) != 0x02) || (m_ctrl2 && m_ctrl2->read_id(0) != 0x02)) && !(machine().side_effect_disabled())) - { - popmessage("Warning: read with SH-2 direct mode with a non-pad device"); - return 0; - } - - cur_ddr = (offset == 0x75) ? m_smpc.DDR1 : m_smpc.DDR2; - - switch(cur_ddr & 0x60) - { - case 0x00: break; // in diag test - case 0x40: return_data = smpc_th_control_mode(offset == 0x77); break; - case 0x60: return_data = smpc_direct_mode(offset == 0x77); break; - default: - popmessage("SMPC: unemulated control method %02x, contact MAMEdev",cur_ddr & 0x60); - return_data = 0; - break; - } - } - #endif - } - - if (LOG_SMPC) logerror ("cpu %s (PC=%08X) SMPC: Read from Byte Offset %02x (%d) Returns %02x\n", space.device().tag(), space.device().safe_pc(), offset, offset>>1, return_data); - - return return_data; -} - -WRITE8_MEMBER( saturn_state::saturn_SMPC_w ) -{ - if (LOG_SMPC) logerror ("8-bit SMPC Write to Offset %02x (reg %d) with Data %02x\n", offset, offset>>1, data); - - if (!(offset & 1)) // avoid writing to even bytes - return; - - if(offset >= 1 && offset <= 0xd) - m_smpc_hle->write(space,offset,data); - - if(offset == 1) //IREG0, check if a BREAK / CONTINUE request for INTBACK command - { - if(m_smpc.intback_stage) - { - if(data & 0x40) - { - if(LOG_PAD_CMD) printf("SMPC: BREAK request %02x\n",data); - m_smpc_hle->sr_ack(); - m_smpc.intback_stage = 0; - } - else if(data & 0x80) - { - if(LOG_PAD_CMD) printf("SMPC: CONTINUE request %02x\n",data); - machine().scheduler().timer_set(attotime::from_usec(700), timer_expired_delegate(FUNC(saturn_state::intback_peripheral),this),0); /* TODO: is timing correct? */ - m_smpc_hle->set_oreg(31,0x10); - m_smpc_hle->sf_set(); //TODO: set hand-shake flag? - } - } - } - - if (offset == 0x1f) - { - smpc_comreg_exec(space,data,0); - - // we've processed the command, clear status flag - if(data != 0x10 && data != 2 && data != 3 && data != 6 && data != 7 && data != 0x08 && data != 0x09 && data != 0x0e && data != 0x0f && data != 0x19 && data != 0x1a) - { - m_smpc_hle->set_oreg(31,data); //read-back for last command issued - m_smpc_hle->sf_ack(false); //clear hand-shake flag - } - // TODO: emulate the timing of each command... - } - - if (offset == 0x63) - m_smpc_hle->write(space,offset,data); - - if(offset == 0x75) // PDR1 - m_smpc_hle->write(space,offset,data); - - //m_smpc.PDR1 = data & 0x7f; - - if(offset == 0x77) // PDR2 - m_smpc_hle->write(space,offset,data); - - //m_smpc.PDR2 = data & 0x7f; - - if(offset == 0x79) - m_smpc_hle->write(space,offset,data); - -// m_smpc.DDR1 = data & 0x7f; - - if(offset == 0x7b) - m_smpc_hle->write(space,offset,data); - -// m_smpc.DDR2 = data & 0x7f; - - if(offset == 0x7d) - { - m_smpc_hle->write(space,offset,data); - -// m_smpc.IOSEL1 = data & 1; -// m_smpc.IOSEL2 = (data & 2) >> 1; - } - - if(offset == 0x7f) - { - m_smpc_hle->write(space,offset,data); - - //enable PAD irq & VDP2 external latch for port 1/2 -// m_smpc.EXLE1 = (data & 1) >> 0; -// m_smpc.EXLE2 = (data & 2) >> 1; - } + m_sndres_timer->adjust(attotime::from_usec(100)); } diff --git a/src/devices/machine/smpc.h b/src/devices/machine/smpc.h index 2c1ff6aa5c5..d86e40b431e 100644 --- a/src/devices/machine/smpc.h +++ b/src/devices/machine/smpc.h @@ -12,6 +12,8 @@ #pragma once #include "screen.h" +#include "bus/sat_ctrl/ctrl.h" +#include "machine/nvram.h" //************************************************************************** @@ -72,9 +74,11 @@ public: // construction/destruction smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual space_config_vector memory_space_config() const override; - // I/O operations +// DECLARE_ADDRESS_MAP( io_map, 8); + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + DECLARE_WRITE8_MEMBER( ireg_w ); DECLARE_WRITE8_MEMBER( command_register_w ); DECLARE_READ8_MEMBER( oreg_r ); @@ -89,29 +93,11 @@ public: DECLARE_WRITE8_MEMBER( ddr2_w ); DECLARE_WRITE8_MEMBER( iosel_w ); DECLARE_WRITE8_MEMBER( exle_w ); + DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi_r ); - - // TODO: public stuff & trampolines that should be internal to the device - DECLARE_WRITE8_MEMBER( write ); - DECLARE_READ8_MEMBER( read ); - void sr_set(uint8_t data); - void sr_ack(); - void sf_ack(bool cd_enable); - void sf_set(); - void master_sh2_reset(bool state); - void master_sh2_nmi(); - void slave_sh2_reset(bool state); - void sound_reset(bool state); - void system_reset(bool state); - void dot_select_request(bool state); - void system_halt_request(bool state); - void irq_request(); - bool get_nmi_status(); - + void m68k_reset_trigger(); bool get_iosel(bool which); uint8_t get_ddr(bool which); - uint8_t get_ireg(uint8_t offset); - void set_oreg(uint8_t offset,uint8_t data); // system delegation template static devcb_base &set_master_reset_handler(device_t &device, Object &&cb) { return downcast(device).m_mshres.set_callback(std::forward(cb)); } @@ -132,29 +118,36 @@ public: // interrupt handler template static devcb_base &set_interrupt_handler(device_t &device, Object &&cb) { return downcast(device).m_irq_line.set_callback(std::forward(cb)); } - static void static_set_screentag(device_t &device, const char *tag); - + static void static_set_region_code(device_t &device, uint8_t rgn); + static void static_set_control_port_tags(device_t &device, const char *tag1, const char *tag2); + protected: // device-level overrides // virtual void device_validity_check(validity_checker &valid) const override; -// virtual void device_add_mconfig() override; + virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + virtual space_config_vector memory_space_config() const override; private: + const address_space_config m_space_config; enum { COMMAND_ID = 1, RTC_ID, - INTBACK_ID + INTBACK_ID, + SNDRES_ID }; - const address_space_config m_space_config; emu_timer *m_cmd_timer; emu_timer *m_rtc_timer; emu_timer *m_intback_timer; - + emu_timer *m_sndres_timer; + const char *m_ctrl1_tag; + const char *m_ctrl2_tag; + bool m_has_ctrl_ports; + bool m_sf; bool m_cd_sf; uint8_t m_sr; @@ -166,6 +159,7 @@ private: uint8_t m_intback_buf[3]; uint8_t m_oreg[32]; uint8_t m_rtc_data[7]; + uint8_t m_smem[4]; uint8_t m_comreg; // in usec // timing table, from manual in usec @@ -186,13 +180,26 @@ private: bool m_command_in_progress; bool m_NMI_reset; bool m_cur_dotsel; + + void master_sh2_nmi(); + void irq_request(); + bool get_nmi_status(); + void resolve_intback(); void intback_continue_request(); void handle_rtc_increment(); + void read_saturn_ports(); + + void sr_set(uint8_t data); + void sr_ack(); + void sf_ack(bool cd_enable); + void sf_set(); int DectoBCD(int num); int m_intback_stage; int m_pmode; + uint8_t m_region_code; + required_device m_smpc_nv; devcb_write_line m_mshres; devcb_write_line m_mshnmi; devcb_write_line m_sshres; @@ -207,7 +214,9 @@ private: devcb_write8 m_pdr1_write; devcb_write8 m_pdr2_write; devcb_write_line m_irq_line; - + saturn_control_port_device *m_ctrl1; + saturn_control_port_device *m_ctrl2; + screen_device *m_screen; }; diff --git a/src/mame/drivers/saturn.cpp b/src/mame/drivers/saturn.cpp index 183df5ca476..4b4f7e69d4b 100644 --- a/src/mame/drivers/saturn.cpp +++ b/src/mame/drivers/saturn.cpp @@ -457,10 +457,10 @@ public: : saturn_state(mconfig, type, tag) , m_exp(*this, "exp") , m_nvram(*this, "nvram") - , m_smpc_nv(*this, "smpc_nv") + , m_ctrl1(*this, "ctrl1") + , m_ctrl2(*this, "ctrl2") { } - DECLARE_INPUT_CHANGED_MEMBER(nmi_reset); DECLARE_INPUT_CHANGED_MEMBER(tray_open); DECLARE_INPUT_CHANGED_MEMBER(tray_close); @@ -477,12 +477,23 @@ public: DECLARE_DRIVER_INIT(saturnus); DECLARE_DRIVER_INIT(saturneu); DECLARE_DRIVER_INIT(saturnjp); - + DECLARE_READ8_MEMBER(saturn_pdr1_direct_r); + DECLARE_READ8_MEMBER(saturn_pdr2_direct_r); + DECLARE_WRITE8_MEMBER(saturn_pdr1_direct_w); + DECLARE_WRITE8_MEMBER(saturn_pdr2_direct_w); + uint8_t m_direct_mux[2]; + uint8_t saturn_direct_port_read(bool which); + uint8_t smpc_direct_mode(uint16_t in_value, bool which); + uint8_t smpc_th_control_mode(uint16_t in_value, bool which); + void nvram_init(nvram_device &nvram, void *data, size_t size); required_device m_exp; required_device m_nvram; - required_device m_smpc_nv; // TODO: move this in the base class saturn_state and add it to stv in MAME + + required_device m_ctrl1; + required_device m_ctrl2; + }; @@ -503,7 +514,7 @@ READ32_MEMBER( sat_console_state::abus_dummy_r ) static ADDRESS_MAP_START( saturn_mem, AS_PROGRAM, 32, sat_console_state ) AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") AM_WRITENOP // bios - AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(saturn_SMPC_r, saturn_SMPC_w,0xffffffff) + AM_RANGE(0x00100000, 0x0010007f) AM_DEVREADWRITE8("smpc", smpc_hle_device, read, write, 0xffffffff) AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r, saturn_backupram_w,0xffffffff) AM_SHARE("share1") AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("workram_l") AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(saturn_minit_w) @@ -547,18 +558,6 @@ static ADDRESS_MAP_START( scudsp_data, AS_DATA, 32, sat_console_state ) ADDRESS_MAP_END - -INPUT_CHANGED_MEMBER(sat_console_state::nmi_reset) -{ - /* TODO: correct? */ - if(!m_NMI_reset) - return; - - /* TODO: NMI doesn't stay held on SH-2 core so we can't use ASSERT_LINE/CLEAR_LINE with that yet */ - if(newval) - m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); -} - INPUT_CHANGED_MEMBER(sat_console_state::tray_open) { if(newval) @@ -573,7 +572,7 @@ INPUT_CHANGED_MEMBER(sat_console_state::tray_close) static INPUT_PORTS_START( saturn ) PORT_START("RESET") /* hardwired buttons */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, sat_console_state, nmi_reset,0) PORT_NAME("Reset Button") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER("smpc", smpc_hle_device, trigger_nmi_r, 0) PORT_NAME("Reset Button") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, sat_console_state, tray_open,0) PORT_NAME("Tray Open Button") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, sat_console_state, tray_close,0) PORT_NAME("Tray Close") @@ -663,7 +662,6 @@ MACHINE_START_MEMBER(sat_console_state, saturn) m_slave->space(AS_PROGRAM).nop_readwrite(0x04000000, 0x047fffff); m_nvram->set_base(m_backupram.get(), 0x8000); - m_smpc_nv->set_base(&m_smpc.SMEM, 4); if (m_exp) { @@ -713,25 +711,13 @@ MACHINE_START_MEMBER(sat_console_state, saturn) // save states save_pointer(NAME(m_scu_regs.get()), 0x100/4); save_pointer(NAME(m_scsp_regs.get()), 0x1000/2); - save_item(NAME(m_NMI_reset)); save_item(NAME(m_en_68k)); -// save_item(NAME(m_smpc.IOSEL1)); -// save_item(NAME(m_smpc.IOSEL2)); -// save_item(NAME(m_smpc.EXLE1)); -// save_item(NAME(m_smpc.EXLE2)); -// save_item(NAME(m_smpc.PDR1)); -// save_item(NAME(m_smpc.PDR2)); -// save_item(NAME(m_port_sel)); -// save_item(NAME(mux_data)); save_item(NAME(m_scsp_last_line)); - save_item(NAME(m_smpc.intback_stage)); - save_item(NAME(m_smpc.pmode)); -// save_item(NAME(m_smpc.SR)); - save_item(NAME(m_smpc.SMEM)); machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&sat_console_state::stvcd_exit, this)); - m_audiocpu->set_reset_callback(write_line_delegate(FUNC(sat_console_state::m68k_reset_callback),this)); + // TODO: trampoline + m_audiocpu->set_reset_callback(write_line_delegate(FUNC(saturn_state::m68k_reset_callback),this)); } /* Die Hard Trilogy tests RAM address 0x25e7ffe bit 2 with Slave during FRT minit irq, in-development tool for breaking execution of it? */ @@ -753,13 +739,9 @@ MACHINE_RESET_MEMBER(sat_console_state,saturn) m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_scudsp->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); -// m_smpc.SR = 0x40; // this bit is always on according to docs - scu_reset(); m_en_68k = 0; - m_NMI_reset = 0; -// m_smpc.slave_on = 0; //memset(stv_m_workram_l, 0, 0x100000); //memset(stv_m_workram_h, 0, 0x100000); @@ -773,27 +755,27 @@ MACHINE_RESET_MEMBER(sat_console_state,saturn) m_vdp2.old_tvmd = -1; } -READ8_MEMBER( saturn_state::saturn_pdr1_direct_r ) +READ8_MEMBER( sat_console_state::saturn_pdr1_direct_r ) { return saturn_direct_port_read(false); } -READ8_MEMBER( saturn_state::saturn_pdr2_direct_r ) +READ8_MEMBER( sat_console_state::saturn_pdr2_direct_r ) { return saturn_direct_port_read(true); } -WRITE8_MEMBER( saturn_state::saturn_pdr1_direct_w ) +WRITE8_MEMBER( sat_console_state::saturn_pdr1_direct_w ) { m_direct_mux[0] = data; } -WRITE8_MEMBER( saturn_state::saturn_pdr2_direct_w ) +WRITE8_MEMBER( sat_console_state::saturn_pdr2_direct_w ) { m_direct_mux[1] = data; } -inline uint8_t saturn_state::saturn_direct_port_read(bool which) +inline uint8_t sat_console_state::saturn_direct_port_read(bool which) { // bail out if direct mode is disabled if(m_smpc_hle->get_iosel(which) == false) @@ -818,7 +800,7 @@ inline uint8_t saturn_state::saturn_direct_port_read(bool which) return res; } -uint8_t saturn_state::smpc_th_control_mode(uint16_t in_value, bool which) +uint8_t sat_console_state::smpc_th_control_mode(uint16_t in_value, bool which) { uint8_t res = 0; uint8_t th = (m_direct_mux[which] >> 5) & 3; @@ -856,7 +838,7 @@ uint8_t saturn_state::smpc_th_control_mode(uint16_t in_value, bool which) return res; } -uint8_t saturn_state::smpc_direct_mode(uint16_t in_value,bool which) +uint8_t sat_console_state::smpc_direct_mode(uint16_t in_value,bool which) { uint8_t hshake = (m_direct_mux[which] >> 5) & 3; const int shift_bit[4] = { 4, 12, 8, 0 }; @@ -891,10 +873,11 @@ static MACHINE_CONFIG_START( saturn ) // SMPC MCU, running at 4 MHz (+ custom RTC device that runs at 32.768 KHz) MCFG_SMPC_HLE_ADD("smpc", XTAL_4MHz) - MCFG_SMPC_HLE_PDR1_IN_CB(READ8(saturn_state, saturn_pdr1_direct_r)) - MCFG_SMPC_HLE_PDR2_IN_CB(READ8(saturn_state, saturn_pdr2_direct_r)) - MCFG_SMPC_HLE_PDR1_OUT_CB(WRITE8(saturn_state, saturn_pdr1_direct_w)) - MCFG_SMPC_HLE_PDR2_OUT_CB(WRITE8(saturn_state, saturn_pdr2_direct_w)) + smpc_hle_device::static_set_control_port_tags(*device, "ctrl1", "ctrl2"); + MCFG_SMPC_HLE_PDR1_IN_CB(READ8(sat_console_state, saturn_pdr1_direct_r)) + MCFG_SMPC_HLE_PDR2_IN_CB(READ8(sat_console_state, saturn_pdr2_direct_r)) + MCFG_SMPC_HLE_PDR1_OUT_CB(WRITE8(sat_console_state, saturn_pdr1_direct_w)) + MCFG_SMPC_HLE_PDR2_OUT_CB(WRITE8(sat_console_state, saturn_pdr2_direct_w)) MCFG_SMPC_HLE_MASTER_RESET_CB(WRITELINE(saturn_state, master_sh2_reset_w)) MCFG_SMPC_HLE_MASTER_NMI_CB(WRITELINE(saturn_state, master_sh2_nmi_w)) MCFG_SMPC_HLE_SLAVE_RESET_CB(WRITELINE(saturn_state, slave_sh2_reset_w)) @@ -908,7 +891,6 @@ static MACHINE_CONFIG_START( saturn ) MCFG_MACHINE_RESET_OVERRIDE(sat_console_state,saturn) MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", sat_console_state, nvram_init) - MCFG_NVRAM_ADD_0FILL("smpc_nv") // TODO: default for each region (+ move it inside SMPC when converted to device) MCFG_TIMER_DRIVER_ADD("sector_timer", sat_console_state, stv_sector_cb) MCFG_TIMER_DRIVER_ADD("sh1_cmd", sat_console_state, stv_sh1_sim) @@ -961,6 +943,9 @@ MACHINE_CONFIG_DERIVED( saturnus, saturn ) MCFG_SATURN_CARTRIDGE_ADD("exp", saturn_cart, nullptr) MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") + MCFG_DEVICE_MODIFY("smpc") + smpc_hle_device::static_set_region_code(*device, 4); + MACHINE_CONFIG_END MACHINE_CONFIG_DERIVED( saturneu, saturn ) @@ -974,6 +959,8 @@ MACHINE_CONFIG_DERIVED( saturneu, saturn ) MCFG_SATURN_CARTRIDGE_ADD("exp", saturn_cart, nullptr) MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") + MCFG_DEVICE_MODIFY("smpc") + smpc_hle_device::static_set_region_code(*device, 12); MACHINE_CONFIG_END MACHINE_CONFIG_DERIVED( saturnjp, saturn ) @@ -987,12 +974,14 @@ MACHINE_CONFIG_DERIVED( saturnjp, saturn ) MCFG_SATURN_CARTRIDGE_ADD("exp", saturn_cart, nullptr) MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") + MCFG_DEVICE_MODIFY("smpc") + smpc_hle_device::static_set_region_code(*device, 1); MACHINE_CONFIG_END void sat_console_state::saturn_init_driver(int rgn) { - m_saturn_region = rgn; +// m_saturn_region = rgn; m_vdp2.pal = (rgn == 12) ? 1 : 0; // set compatible options diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp index e7d1dbd0fa1..222087da8a0 100644 --- a/src/mame/drivers/stv.cpp +++ b/src/mame/drivers/stv.cpp @@ -982,7 +982,7 @@ DRIVER_INIT_MEMBER(stv_state, hopper) static ADDRESS_MAP_START( stv_mem, AS_PROGRAM, 32, stv_state ) AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios - AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(stv_SMPC_r, stv_SMPC_w,0xffffffff) + AM_RANGE(0x00100000, 0x0010007f) AM_DEVREADWRITE8("smpc", smpc_hle_device, read, write, 0xffffffff) AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r,saturn_backupram_w,0xffffffff) AM_SHARE("share1") AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("workram_l") // AM_RANGE(0x00400000, 0x0040001f) AM_READWRITE(stv_ioga_r32, stv_io_w32) AM_SHARE("ioga") AM_MIRROR(0x20) /* installed with per-game specific */ @@ -1096,6 +1096,7 @@ static MACHINE_CONFIG_START( stv ) MCFG_SCUDSP_OUT_DMA_CB(WRITE16(saturn_state, scudsp_dma_w)) MCFG_SMPC_HLE_ADD("smpc", XTAL_4MHz) + smpc_hle_device::static_set_region_code(*device, 0); MCFG_SMPC_HLE_PDR1_IN_CB(READ8(stv_state, pdr1_input_r)) MCFG_SMPC_HLE_PDR2_IN_CB(READ8(stv_state, pdr2_input_r)) MCFG_SMPC_HLE_PDR1_OUT_CB(WRITE8(stv_state, pdr1_output_w)) @@ -1236,7 +1237,6 @@ MACHINE_RESET_MEMBER(stv_state,stv) m_en_68k = 0; - m_NMI_reset = 0; m_port_sel = m_mux_data = 0; @@ -1293,16 +1293,8 @@ MACHINE_START_MEMBER(stv_state,stv) // save states save_pointer(NAME(m_scu_regs.get()), 0x100/4); save_pointer(NAME(m_scsp_regs.get()), 0x1000/2); - save_item(NAME(m_NMI_reset)); save_item(NAME(m_en_68k)); save_item(NAME(m_prev_gamebank_select)); -// save_item(NAME(scanline)); -// save_item(NAME(m_smpc.IOSEL1)); -// save_item(NAME(m_smpc.IOSEL2)); -// save_item(NAME(m_smpc.EXLE1)); -// save_item(NAME(m_smpc.EXLE2)); -// save_item(NAME(m_smpc.PDR1)); -// save_item(NAME(m_smpc.PDR2)); save_item(NAME(m_port_sel)); save_item(NAME(m_mux_data)); save_item(NAME(m_scsp_last_line)); diff --git a/src/mame/includes/saturn.h b/src/mame/includes/saturn.h index 499e9eb34a4..955360c36ad 100644 --- a/src/mame/includes/saturn.h +++ b/src/mame/includes/saturn.h @@ -43,9 +43,7 @@ public: m_scudsp(*this, "scudsp"), m_eeprom(*this, "eeprom"), m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_ctrl1(*this, "ctrl1"), - m_ctrl2(*this, "ctrl2") + m_palette(*this, "palette") { } @@ -65,7 +63,6 @@ public: std::unique_ptr m_vdp1_vram; std::unique_ptr m_vdp1_regs; - uint8_t m_NMI_reset; uint8_t m_en_68k; @@ -127,28 +124,6 @@ public: int old_tvmd; }m_vdp2; - struct { -// uint8_t IOSEL1; -// uint8_t IOSEL2; -// uint8_t EXLE1; -// uint8_t EXLE2; -// uint8_t PDR1; -// uint8_t PDR2; -// uint8_t DDR1; -// uint8_t DDR2; -// uint8_t SF; -// uint8_t SR; -// uint8_t IREG[7]; - uint8_t intback_buf[7]; -// uint8_t OREG[32]; - int intback_stage; - int pmode; - uint8_t SMEM[4]; - uint8_t intback; - uint8_t rtc_data[7]; -// uint8_t slave_on; - }m_smpc; - /* Saturn specific*/ int m_saturn_region; uint8_t m_cart_type; @@ -169,8 +144,6 @@ public: optional_device m_eeprom; required_device m_gfxdecode; required_device m_palette; - optional_device m_ctrl1; - optional_device m_ctrl2; bitmap_rgb32 m_tmpbitmap; DECLARE_VIDEO_START(stv_vdp2); @@ -201,10 +174,6 @@ public: DECLARE_WRITE8_MEMBER(scsp_irq); int m_scsp_last_line; - TIMER_CALLBACK_MEMBER( smpc_audio_reset_line_pulse ); - DECLARE_READ8_MEMBER( saturn_SMPC_r ); - DECLARE_WRITE8_MEMBER( saturn_SMPC_w ); - DECLARE_READ16_MEMBER ( saturn_vdp1_regs_r ); DECLARE_READ32_MEMBER ( saturn_vdp1_vram_r ); DECLARE_READ32_MEMBER ( saturn_vdp1_framebuffer0_r ); @@ -660,25 +629,6 @@ public: DECLARE_READ16_MEMBER(scudsp_dma_r); DECLARE_WRITE16_MEMBER(scudsp_dma_w); - // FROM smpc.c - void smpc_master_on(); - TIMER_CALLBACK_MEMBER( smpc_slave_enable ); - TIMER_CALLBACK_MEMBER( smpc_sound_enable ); - TIMER_CALLBACK_MEMBER( smpc_cd_enable ); - void smpc_system_reset(); - TIMER_CALLBACK_MEMBER( smpc_change_clock ); - TIMER_CALLBACK_MEMBER( stv_intback_peripheral ); - TIMER_CALLBACK_MEMBER( stv_smpc_intback ); - TIMER_CALLBACK_MEMBER( intback_peripheral ); - TIMER_CALLBACK_MEMBER( saturn_smpc_intback ); - void smpc_rtc_write(); - void smpc_memory_setting(); - void smpc_nmi_req(); - TIMER_CALLBACK_MEMBER( smpc_nmi_set ); - void smpc_comreg_exec(address_space &space, uint8_t data, uint8_t is_stv); - DECLARE_READ8_MEMBER( stv_SMPC_r ); - DECLARE_WRITE8_MEMBER( stv_SMPC_w ); - // SMPC HLE delegates DECLARE_WRITE_LINE_MEMBER(master_sh2_reset_w); DECLARE_WRITE_LINE_MEMBER(master_sh2_nmi_w); @@ -688,14 +638,7 @@ public: DECLARE_WRITE_LINE_MEMBER(system_halt_w); DECLARE_WRITE_LINE_MEMBER(dot_select_w); DECLARE_WRITE_LINE_MEMBER(smpc_irq_w); - DECLARE_READ8_MEMBER(saturn_pdr1_direct_r); - DECLARE_READ8_MEMBER(saturn_pdr2_direct_r); - DECLARE_WRITE8_MEMBER(saturn_pdr1_direct_w); - DECLARE_WRITE8_MEMBER(saturn_pdr2_direct_w); - uint8_t m_direct_mux[2]; - uint8_t saturn_direct_port_read(bool which); - uint8_t smpc_direct_mode(uint16_t in_value, bool which); - uint8_t smpc_th_control_mode(uint16_t in_value, bool which); + void debug_scudma_command(int ref, const std::vector ¶ms); void debug_scuirq_command(int ref, const std::vector ¶ms); diff --git a/src/mame/machine/saturn.cpp b/src/mame/machine/saturn.cpp index 8a37c301ecd..86dd075cffb 100644 --- a/src/mame/machine/saturn.cpp +++ b/src/mame/machine/saturn.cpp @@ -660,12 +660,10 @@ void saturn_state::scu_reset(void) } -/* Official documentation says that the "RESET/TAS opcodes aren't supported", but Out Run definitely contradicts with it. - Since that m68k can't reset itself via the RESET opcode I suppose that the SMPC actually do it by reading an i/o - connected to this opcode. */ + WRITE_LINE_MEMBER(saturn_state::m68k_reset_callback) { - machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_audio_reset_line_pulse), this)); + m_smpc_hle->m68k_reset_trigger(); printf("m68k RESET opcode triggered\n"); }