// license:LGPL-2.1+
// copyright-holders:Angelo Salese, R. Belmont
// TODO: make separate device when code is decoupled better
//DECLARE_WRITE8_MEMBER( stv_SMPC_w );
//DECLARE_READ8_MEMBER( stv_SMPC_r );
//DECLARE_WRITE8_MEMBER( saturn_SMPC_w );
//DECLARE_READ8_MEMBER( saturn_SMPC_r );
#ifndef MAME_MACHINE_SMPC_HLE_H
#define MAME_MACHINE_SMPC_HLE_H
#pragma once
#include "screen.h"
#include "bus/sat_ctrl/ctrl.h"
#include "machine/nvram.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> smpc_hle_device
class smpc_hle_device : public device_t,
public device_memory_interface
{
public:
// construction/destruction
smpc_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// I/O operations
// void io_map(address_map &map);
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi_r );
void m68k_reset_trigger();
bool get_iosel(bool which);
uint8_t get_ddr(bool which);
// system delegation
auto master_reset_handler() { return m_mshres.bind(); }
auto master_nmi_handler() { return m_mshnmi.bind(); }
auto slave_reset_handler() { return m_sshres.bind(); }
auto sound_reset_handler() { return m_sndres.bind(); }
auto system_reset_handler() { return m_sysres.bind(); }
auto system_halt_handler() { return m_syshalt.bind(); }
auto dot_select_handler() { return m_dotsel.bind(); }
// PDR delegation
auto pdr1_in_handler() { return m_pdr1_read.bind(); }
auto pdr2_in_handler() { return m_pdr2_read.bind(); }
auto pdr1_out_handler() { return m_pdr1_write.bind(); }
auto pdr2_out_handler() { return m_pdr2_write.bind(); }
// interrupt handler, doesn't work in Saturn driver???
auto interrupt_handler() { return m_irq_line.bind(); }
void set_region_code(uint8_t rgn) { m_region_code = rgn; }
template <typename T> void set_screen_tag(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
template <typename T, typename U> void set_control_port_tags(T &&tag1, U &&tag2)
{
m_ctrl1.set_tag(std::forward<T>(tag1));
m_ctrl2.set_tag(std::forward<U>(tag2));
// TODO: checking against nullptr still returns a device!?
m_has_ctrl_ports = true;
}
protected:
// device-level overrides
// virtual void device_validity_check(validity_checker &valid) const 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,
SNDRES_ID
};
emu_timer *m_cmd_timer;
emu_timer *m_rtc_timer;
emu_timer *m_intback_timer;
emu_timer *m_sndres_timer;
bool m_has_ctrl_ports;
bool m_sf;
bool m_cd_sf;
uint8_t m_sr;
uint8_t m_ddr1, m_ddr2;
uint8_t m_pdr1_readback, m_pdr2_readback;
bool m_iosel1, m_iosel2;
bool m_exle1, m_exle2;
uint8_t m_ireg[7];
uint8_t m_intback_buf[3];
uint8_t m_oreg[32];
uint8_t m_rtc_data[7];
uint8_t m_smem[5];
uint8_t m_comreg;
// in usec
// timing table, from manual in usec
const uint32_t m_cmd_table_timing[0x20] =
{
30, 30, // MASTER ON / OFF
30, 30, // SLAVE ON / OFF
10, 10, // <unknown>
30, 30, // SOUND ON / OFF
40, 40, // CD ON / OFF
30, 30, 30, // NETLINK ON / OFF / <unknown>
100*1000, 100*1000, 100*1000, // SYSTEM RESET / ClocK CHaNGe 352 / 320
320*1000, // INTBACK
30, 30, 30, 30, 30, // <unknown>
70, 40, 30, 30, 30, // SETTIME / SETSMEM / NMIREQ / RESENAB / RESDISA
30, 30, 30, 30 // <unknown>
};
bool m_command_in_progress;
bool m_NMI_reset;
bool m_cur_dotsel;
void master_sh2_nmi();
void irq_request();
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<nvram_device> m_mini_nvram;
devcb_write_line m_mshres;
devcb_write_line m_mshnmi;
devcb_write_line m_sshres;
// devcb_write_line m_sshnmi;
devcb_write_line m_sndres;
devcb_write_line m_sysres;
// devcb_write_line m_cdres;
devcb_write_line m_syshalt;
devcb_write_line m_dotsel;
devcb_read8 m_pdr1_read;
devcb_read8 m_pdr2_read;
devcb_write8 m_pdr1_write;
devcb_write8 m_pdr2_write;
devcb_write_line m_irq_line;
optional_device<saturn_control_port_device> m_ctrl1;
optional_device<saturn_control_port_device> m_ctrl2;
required_device<screen_device> m_screen;
void smpc_regs(address_map &map);
DECLARE_WRITE8_MEMBER( ireg_w );
DECLARE_WRITE8_MEMBER( command_register_w );
DECLARE_READ8_MEMBER( oreg_r );
DECLARE_READ8_MEMBER( status_register_r );
DECLARE_WRITE8_MEMBER( status_flag_w );
DECLARE_READ8_MEMBER( status_flag_r );
DECLARE_READ8_MEMBER( pdr1_r );
DECLARE_READ8_MEMBER( pdr2_r );
DECLARE_WRITE8_MEMBER( pdr1_w );
DECLARE_WRITE8_MEMBER( pdr2_w );
DECLARE_WRITE8_MEMBER( ddr1_w );
DECLARE_WRITE8_MEMBER( ddr2_w );
DECLARE_WRITE8_MEMBER( iosel_w );
DECLARE_WRITE8_MEMBER( exle_w );
};
// device type definition
DECLARE_DEVICE_TYPE(SMPC_HLE, smpc_hle_device)
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif // MAME_MACHINE_SMPC_HLE_H