vegas: Corrected sub-device lookup string (nw)

vegas: Added Nile 4 timer scaling (nw)
pci-ide: Added IRQ callback (nw)
atlantis: Added more address map locations (nw)
dcs: Add sport timer for dcs2 dsio device (nw)
This commit is contained in:
Ted Green 2016-06-08 12:01:13 -06:00
parent 4f223dea16
commit 680a81e950
5 changed files with 446 additions and 158 deletions

View File

@ -8,7 +8,8 @@ ide_pci_device::ide_pci_device(const machine_config &mconfig, const char *tag, d
: pci_device(mconfig, IDE_PCI, "IDE PCI interface", tag, owner, clock, "ide_pci", __FILE__),
m_ide(*this, "ide"),
m_ide2(*this, "ide2"),
m_irq_num(-1)
m_irq_num(-1),
m_irq_handler(*this)
{
}
@ -63,7 +64,8 @@ void ide_pci_device::set_irq_info(const char *tag, const int irq_num)
void ide_pci_device::device_start()
{
m_cpu = machine().device<cpu_device>(m_cpu_tag);
if (m_irq_num != -1)
m_cpu = machine().device<cpu_device>(m_cpu_tag);
pci_device::device_start();
@ -77,6 +79,8 @@ void ide_pci_device::device_start()
bank_infos[3].adr = 0x374;
add_map(16, M_IO, FUNC(ide_pci_device::bus_master_map));
bank_infos[4].adr = 0xf00;
m_irq_handler.resolve_safe();
}
void ide_pci_device::device_reset()
@ -119,12 +123,21 @@ WRITE32_MEMBER(ide_pci_device::ide2_write_cs1)
WRITE_LINE_MEMBER(ide_pci_device::ide_interrupt)
{
// Assert/Clear the interrupt if the irq num is set.
if (m_irq_num != -1) {
m_cpu->set_input_line(m_irq_num, state);
}
// Call the callback
m_irq_handler(state);
// PCI646U2 Offset 0x50 is interrupt status
if (main_id == 0x10950646 && state)
m_config_data[0x10/4] |= 0x4;
if (main_id == 0x10950646) {
if (state)
m_config_data[0x10 / 4] |= 0x4;
else
m_config_data[0x10 / 4] &= ~0x4;
}
if (0)
logerror("%s:ide_interrupt %i set to %i\n", machine().describe_context(), m_irq_num, state);
}
@ -138,8 +151,11 @@ WRITE32_MEMBER(ide_pci_device::pcictrl_w)
{
COMBINE_DATA(&m_config_data[offset]);
// PCI646U2 Offset 0x50 is interrupt status
if (main_id == 0x10950646 && offset == 0x10/4 && (data & 0x4))
m_config_data[0x10/4] &= ~0x4;
if (main_id == 0x10950646 && offset == 0x10 / 4 && (data & 0x4)) {
m_config_data[0x10 / 4] &= ~0x4;
if (0)
logerror("%s:ide_pci_device::pcictrl_w Clearing interrupt status\n", machine().describe_context());
}
}
WRITE32_MEMBER(ide_pci_device::address_base_w)

View File

@ -20,9 +20,13 @@ TODO:
#define MCFG_IDE_PCI_ADD(_tag, _main_id, _revision, _subdevice_id) \
MCFG_PCI_DEVICE_ADD(_tag, IDE_PCI, _main_id, _revision, 0x01018a, _subdevice_id)
// Setting this to a value other than -1 will cause the ide_pci_device to assert/clear the cpu interrupt directly.
#define MCFG_IDE_PCI_IRQ_ADD(_cpu_tag, _irq_num) \
downcast<ide_pci_device *>(device)->set_irq_info(_cpu_tag, _irq_num);
#define MCFG_IDE_PCI_IRQ_HANDLER(_devcb) \
devcb = &ide_pci_device::set_irq_handler(*device, DEVCB_##_devcb);
class ide_pci_device : public pci_device {
public:
ide_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
@ -35,6 +39,7 @@ public:
DECLARE_READ32_MEMBER(ide2_read_cs1);
DECLARE_WRITE32_MEMBER(ide2_write_cs1);
void set_irq_info(const char *tag, const int irq_num);
template<class _Object> static devcb_base &set_irq_handler(device_t &device, _Object object) { return downcast<ide_pci_device &>(device).m_irq_handler.set_callback(object); }
protected:
virtual void device_start() override;
@ -47,6 +52,7 @@ private:
const char *m_cpu_tag;
cpu_device *m_cpu;
int m_irq_num;
devcb_write_line m_irq_handler;
UINT32 m_config_data[0x10];
DECLARE_ADDRESS_MAP(chan1_data_command_map, 32);

View File

@ -534,6 +534,7 @@ MACHINE_CONFIG_FRAGMENT( dcs2_audio_dsio )
MCFG_TIMER_DEVICE_ADD("dcs_reg_timer", DEVICE_SELF, dcs_audio_device, dcs_irq)
MCFG_TIMER_DEVICE_ADD("dcs_int_timer", DEVICE_SELF, dcs_audio_device, internal_timer_callback)
MCFG_TIMER_DEVICE_ADD("dcs_sport_timer", DEVICE_SELF, dcs_audio_device, sport0_irq) // roadburn needs this to pass harware test
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")

View File

@ -37,6 +37,7 @@
#include "cpu/adsp2100/adsp2100.h"
#include "machine/idectrl.h"
#include "machine/midwayic.h"
#include "machine/ins8250.h"
#include "audio/dcs.h"
#include "machine/pci.h"
#include "machine/vrc4373.h"
@ -47,12 +48,33 @@
#include "machine/nvram.h"
#include "coreutil.h"
// Board Ctrl Reg Offsets
#define CTRL_POWER0 0
#define CTRL_POWER1 1
#define CTRL_IRQ1_EN 2
#define CTRL_IRQ2_EN 3
#define CTRL_IRQ3_EN 4
#define CTRL_IRQ4_EN 5
#define CTRL_GLOBAL_EN 6
#define CTRL_CAUSE 7
#define CTRL_STATUS 8
#define CTRL_SIZE 9
// These need more verification
#define IOASIC_IRQ_SHIFT 0
#define PARALLEL_IRQ_SHIFT 3
#define UART0_SHIFT 4
#define UART1_SHIFT 5
#define ZEUS_IRQ_SHIFT 2
#define VBLANK_IRQ_SHIFT 7
#define GALILEO_IRQ_SHIFT 0
/* static interrupts */
#define GALILEO_IRQ_NUM MIPS3_IRQ2
#define IOASIC_IRQ_NUM MIPS3_IRQ4
#define GALILEO_IRQ_NUM MIPS3_IRQ0
#define IDE_IRQ_NUM MIPS3_IRQ4
#define LOG_RTC (1)
#define LOG_RTC (1)
#define LOG_ZEUS (0)
class atlantis_state : public driver_device
{
@ -63,6 +85,8 @@ public:
m_screen(*this, "screen"),
m_dcs(*this, "dcs"),
m_ioasic(*this, "ioasic"),
m_uart0(*this, "uart0"),
m_uart1(*this, "uart1"),
m_rtc(*this, "rtc")
{ }
DECLARE_DRIVER_INIT(mwskins);
@ -72,8 +96,11 @@ public:
required_device<mips3_device> m_maincpu;
required_device<screen_device> m_screen;
//required_device<dcs2_audio_dsio_device> m_dcs;
required_device<dcs2_audio_denver_device> m_dcs;
//required_device<dcs2_audio_denver_device> m_dcs;
required_device<dcs_audio_device> m_dcs;
required_device<midway_ioasic_device> m_ioasic;
required_device<ns16550_device> m_uart0;
required_device<ns16550_device> m_uart1;
required_device<nvram_device> m_rtc;
UINT8 m_rtc_data[0x800];
@ -88,6 +115,9 @@ public:
DECLARE_WRITE32_MEMBER(status_leds_w);
UINT8 m_status_leds;
DECLARE_WRITE32_MEMBER(asic_fifo_w);
DECLARE_WRITE32_MEMBER(dcs3_fifo_full_w);
DECLARE_WRITE32_MEMBER(zeus_w);
DECLARE_READ32_MEMBER(zeus_r);
UINT32 m_zeus_data[0x80];
@ -106,12 +136,22 @@ public:
READ32_MEMBER(user_io_input);
int m_user_io_state;
DECLARE_READ32_MEMBER(asic_reset_r);
DECLARE_WRITE32_MEMBER(asic_reset_w);
DECLARE_WRITE32_MEMBER(asic_fifo_w);
int m_asic_reset;
DECLARE_READ32_MEMBER(board_ctrl_r);
DECLARE_WRITE32_MEMBER(board_ctrl_w);
UINT32 m_irq_state;
UINT8 board_ctrl[CTRL_SIZE];
void update_asic_irq();
DECLARE_WRITE_LINE_MEMBER(ide_irq);
DECLARE_WRITE_LINE_MEMBER(ioasic_irq);
DECLARE_WRITE_LINE_MEMBER(uart0_irq_callback);
DECLARE_WRITE_LINE_MEMBER(uart1_irq_callback);
DECLARE_CUSTOM_INPUT_MEMBER(port_mod_r);
DECLARE_READ32_MEMBER(port_ctrl_r);
DECLARE_WRITE32_MEMBER(port_ctrl_w);
UINT32 m_port_ctrl_reg[0x8];
};
READ8_MEMBER (atlantis_state::red_r)
@ -173,43 +213,65 @@ WRITE8_MEMBER(atlantis_state::blue_w)
logerror("%06X: blue_w %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
}
WRITE32_MEMBER(atlantis_state::user_io_output)
READ32_MEMBER(atlantis_state::board_ctrl_r)
{
m_user_io_state = data;
logerror("atlantis_state::user_io_output m_user_io_state = %1x\n", m_user_io_state);
UINT32 newOffset = offset >> 17;
UINT32 data = board_ctrl[newOffset];
switch (newOffset) {
case CTRL_STATUS:
if (1 && m_screen->vblank())
data |= 0x80;
if (m_last_offset != (newOffset | 0x40000))
logerror("%s:board_ctrl_r read from CTRL_STATUS offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
default:
logerror("%s:board_ctrl_r read from offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
}
m_last_offset = newOffset | 0x40000;
return data;
}
READ32_MEMBER(atlantis_state::user_io_input)
WRITE32_MEMBER(atlantis_state::board_ctrl_w)
{
// Set user i/o (2) Power Detect?
m_user_io_state |= 1 << 2;
// User I/O 0 = Allow write to red[0]. Serial Write Enable?
// Loop user_io(0) to user_io(1)
m_user_io_state = (m_user_io_state & ~(0x2)) | ((m_user_io_state & 1) << 1);
if (0)
logerror("atlantis_state::user_io_input m_user_io_state = %1x\n", m_user_io_state);
return m_user_io_state;
}
READ32_MEMBER(atlantis_state::asic_reset_r)
{
logerror("%s:asic_reset_r read from offset %04X = %08X & %08X\n", machine().describe_context(), offset, m_asic_reset, mem_mask);
return m_asic_reset;
}
WRITE32_MEMBER(atlantis_state::asic_reset_w)
{
// 0x1 IOASIC Reset
// 0x4 Zeus2 Reset
// 0x10 IDE Reset
logerror("%s:asic_reset_w write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask);
COMBINE_DATA(&m_asic_reset);
if ((m_asic_reset & 0x0001) == 0) {
m_ioasic->ioasic_reset();
m_dcs->reset_w(ASSERT_LINE);
} else {
m_dcs->reset_w(CLEAR_LINE);
UINT32 newOffset = offset >> 17;
UINT32 changeData = board_ctrl[newOffset] ^ data;
COMBINE_DATA(&board_ctrl[newOffset]);
switch (newOffset) {
case CTRL_POWER0:
// 0x1 IOASIC Reset
// 0x4 Zeus2 Reset
// 0x10 IDE Reset
if (changeData & 0x1) {
if ((data & 0x0001) == 0) {
m_ioasic->ioasic_reset();
m_dcs->reset_w(ASSERT_LINE);
}
else {
m_dcs->reset_w(CLEAR_LINE);
}
}
logerror("%s:board_ctrl_w write to CTRL_POWER0 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
case CTRL_POWER1:
// 0x1 VBlank clear?
if (changeData & 0x1) {
if ((data & 0x0001) == 0) {
}
else {
}
}
logerror("%s:board_ctrl_w write to CTRL_POWER1 offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
case CTRL_GLOBAL_EN:
// Zero bit will clear cause
board_ctrl[CTRL_CAUSE] &= data;
update_asic_irq();
logerror("%s:board_ctrl_w write to CTRL_GLOBAL_EN offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
default:
logerror("%s:board_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
}
}
@ -317,11 +379,15 @@ WRITE32_MEMBER(atlantis_state::status_leds_w)
case 0x90: digit = '9'; break;
case 0x88: digit = 'A'; break;
case 0x83: digit = 'B'; break;
case 0xc6: digit = 'C'; break;
case 0xa7: digit = 'C'; break;
case 0xa1: digit = 'D'; break;
case 0x86: digit = 'E'; break;
case 0x87: digit = 'F'; break;
case 0x7f: digit = 'Z'; break;
case 0x7f: digit = '.'; break;
case 0xf7: digit = '_'; break;
case 0xbf: digit = '|'; break;
case 0xfe: digit = '-'; break;
case 0xff: digit = 'Z'; break;
}
popmessage("LED: %c", digit);
osd_printf_debug("%06X: status_leds_w digit: %c %08x = %02x\n", machine().device("maincpu")->safe_pc(), digit, offset, data);
@ -339,23 +405,24 @@ READ32_MEMBER(atlantis_state::zeus_r)
/* bits $00080000 is tested in a loop until 0 */
/* bit $00000004 is tested for toggling; probably VBLANK */
// zeus is reset if 0x80 is read
result = 0x00;
if (m_screen->vblank())
result |= 0x00008;
//if (m_screen->vblank())
m_zeus_data[offset] = (m_zeus_data[offset] + 1) & 0xf;
break;
case 0x41:
// CPU resets map2, writes 0xffffffff here, and then expects this read
result &= 0x1fff03ff;
break;
}
logerror("%s:zeus_r read from offset %04X = %08X & %08X\n", machine().describe_context(), offset, result, mem_mask);
if (LOG_ZEUS)
logerror("%s:zeus_r read from offset %04X = %08X & %08X\n", machine().describe_context(), offset, result, mem_mask);
return result;
}
WRITE32_MEMBER(atlantis_state::zeus_w)
{
COMBINE_DATA(&m_zeus_data[offset]);
logerror("%s:zeus_w write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask);
if (LOG_ZEUS)
logerror("%s:zeus_w write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask);
m_last_offset = offset | 0x30000;
}
@ -365,28 +432,193 @@ READ32_MEMBER(atlantis_state::cmos_protect_r)
return m_cmos_write_enabled;
}
/*************************************
*
* Machine start
*
*************************************/
WRITE32_MEMBER(atlantis_state::dcs3_fifo_full_w)
{
m_ioasic->fifo_full_w(data);
}
/*************************************
* PCI9050 User I/O handlers
*************************************/
WRITE32_MEMBER(atlantis_state::user_io_output)
{
m_user_io_state = data;
logerror("atlantis_state::user_io_output m_user_io_state = %1x\n", m_user_io_state);
}
READ32_MEMBER(atlantis_state::user_io_input)
{
// Set user i/o (2) Power Detect?
m_user_io_state |= 1 << 2;
// User I/O 0 = Allow write to red[0]. Serial Write Enable?
// Loop user_io(0) to user_io(1)
m_user_io_state = (m_user_io_state & ~(0x2)) | ((m_user_io_state & 1) << 1);
if (0)
logerror("atlantis_state::user_io_input m_user_io_state = %1x\n", m_user_io_state);
return m_user_io_state;
}
/*************************************
* UART0 interrupt handler
*************************************/
WRITE_LINE_MEMBER(atlantis_state::uart0_irq_callback)
{
UINT32 status_bit = (1 << UART0_SHIFT);
if (state && !(board_ctrl[CTRL_STATUS] & status_bit)) {
board_ctrl[CTRL_STATUS] |= status_bit;
update_asic_irq();
}
else if (!state && (board_ctrl[CTRL_STATUS] & status_bit)) {
board_ctrl[CTRL_STATUS] &= ~status_bit;
board_ctrl[CTRL_CAUSE] &= ~status_bit;
update_asic_irq();
}
logerror("atlantis_state::uart0_irq_callback state = %1x\n", state);
}
/*************************************
* UART1 interrupt handler
*************************************/
WRITE_LINE_MEMBER(atlantis_state::uart1_irq_callback)
{
UINT32 status_bit = (1 << UART1_SHIFT);
if (state && !(board_ctrl[CTRL_STATUS] & status_bit)) {
board_ctrl[CTRL_STATUS] |= status_bit;
update_asic_irq();
}
else if (!state && (board_ctrl[CTRL_STATUS] & status_bit)) {
board_ctrl[CTRL_STATUS] &= ~status_bit;
board_ctrl[CTRL_CAUSE] &= ~status_bit;
update_asic_irq();
}
logerror("atlantis_state::uart1_irq_callback state = %1x\n", state);
}
/*************************************
* IDE interrupts
*************************************/
WRITE_LINE_MEMBER(atlantis_state::ide_irq)
{
m_maincpu->set_input_line(IDE_IRQ_NUM, state);
logerror("%s: atlantis_state::ide_irq state = %i\n", machine().describe_context(), state);
}
/*************************************
* I/O ASIC interrupts
*************************************/
WRITE_LINE_MEMBER(atlantis_state::ioasic_irq)
{
logerror("%s: atlantis_state::ioasic_irq state = %i\n", machine().describe_context(), state);
if (state) {
board_ctrl[CTRL_STATUS] |= (1 << IOASIC_IRQ_SHIFT);
update_asic_irq();
}
else {
board_ctrl[CTRL_STATUS] &= ~(1 << IOASIC_IRQ_SHIFT);
board_ctrl[CTRL_CAUSE] &= ~(1 << IOASIC_IRQ_SHIFT);
update_asic_irq();
}
}
/*************************************
* Programmable interrupt control
*************************************/
void atlantis_state::update_asic_irq()
{
// Uknown if CTRL_POWER1 is actually a separate power register. Skip it for now.
for (int irqIndex = 1; irqIndex <= 4; irqIndex++) {
UINT32 irqBits = (board_ctrl[CTRL_GLOBAL_EN] & board_ctrl[CTRL_POWER1 + irqIndex] & board_ctrl[CTRL_STATUS]);
UINT32 causeBits = (board_ctrl[CTRL_GLOBAL_EN] & board_ctrl[CTRL_POWER1 + irqIndex] & board_ctrl[CTRL_CAUSE]);
UINT32 currState = m_irq_state & (1 << irqIndex);
board_ctrl[CTRL_CAUSE] |= irqBits;
if (irqBits && !currState) {
m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, ASSERT_LINE);
m_irq_state |= (1 << irqIndex);
if (1)
logerror("atlantis_state::update_asic_irq Asserting IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]);
}
else if (!(causeBits) && currState) {
m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, CLEAR_LINE);
m_irq_state &= ~(1 << irqIndex);
if (1)
logerror("atlantis_state::update_asic_irq Clearing IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]);
}
}
}
/*************************************
* I/O Port control
*************************************/
READ32_MEMBER(atlantis_state::port_ctrl_r)
{
UINT32 newOffset = offset >> 17;
UINT32 result = m_port_ctrl_reg[newOffset];
logerror("%s: port_ctrl_r newOffset = %02X data = %08X\n", machine().describe_context(), newOffset, result);
return result;
}
WRITE32_MEMBER(atlantis_state::port_ctrl_w)
{
UINT32 newOffset = offset >> 17;
COMBINE_DATA(&m_port_ctrl_reg[newOffset]);
switch (newOffset) {
//case 1:
// m_port_ctrl_reg[newOffset] = 0;
// if (!(data & 0x8))
// m_port_ctrl_reg[newOffset] = 0*3; // Row 0
// else if (!(data & 0x10))
// m_port_ctrl_reg[newOffset] = 1*3; // Row 1
// else if (!(data & 0x20))
// m_port_ctrl_reg[newOffset] = 2*3; // Row 2
// else if (!(data & 0x40))
// m_port_ctrl_reg[newOffset] = 3*3; // Row 3
// logerror("%s: port_ctrl_w Keypad Row Sel = %04X data = %08X\n", machine().describe_context(), m_port_ctrl_reg[newOffset], data);
// break;
default:
logerror("%s: port_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
}
}
CUSTOM_INPUT_MEMBER(atlantis_state::port_mod_r)
{
UINT32 bits = ioport((const char *)param)->read();
//bits &= m_port_ctrl_reg[1];
//bits >>= m_port_ctrl_reg[1];
logerror("%s: port_mod_r read data %s = %08X m_port_ctrl_reg[1] = %08X\n", machine().describe_context(), (const char *)param, bits, m_port_ctrl_reg[1]);
return bits;
}
/*************************************
* Video refresh
*************************************/
UINT32 atlantis_state::screen_update_mwskins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
return 0;
}
/*************************************
* Machine start
*************************************/
void atlantis_state::machine_start()
{
m_rtc->set_base(m_rtc_data, sizeof(m_rtc_data));
/* set the fastest DRC options */
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS);
// Save states
save_item(NAME(m_irq_state));
save_item(NAME(board_ctrl));
save_item(NAME(m_port_ctrl_reg));
}
/*************************************
*
* Machine init
*
*************************************/
* Machine init
*************************************/
void atlantis_state::machine_reset()
{
m_dcs->reset_w(1);
@ -395,31 +627,9 @@ void atlantis_state::machine_reset()
m_cmos_write_enabled = FALSE;
memset(m_zeus_data, 0, sizeof(m_zeus_data));
m_red_count = 0;
}
/*************************************
*
* I/O ASIC interrupts
*
*************************************/
WRITE_LINE_MEMBER(atlantis_state::ioasic_irq)
{
logerror("atlantis_state::ioasic_irq state = %i\n", state);
m_maincpu->set_input_line(IOASIC_IRQ_NUM, state);
}
/*************************************
*
* Video refresh
*
*************************************/
UINT32 atlantis_state::screen_update_mwskins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
return 0;
m_irq_state = 0;
memset(board_ctrl, 0, sizeof(board_ctrl));
memset(m_port_ctrl_reg, 0, sizeof(m_port_ctrl_reg));
}
@ -431,19 +641,22 @@ UINT32 atlantis_state::screen_update_mwskins(screen_device &screen, bitmap_ind16
*************************************/
static ADDRESS_MAP_START( map0, AS_PROGRAM, 32, atlantis_state )
// 00200004
// 00200008
AM_RANGE(0x000000, 0xfff) AM_READWRITE8(red_r, red_w, 0xff)
AM_RANGE(0x00000000, 0x00000fff) AM_READWRITE8(red_r, red_w, 0xff)
AM_RANGE(0x0001e000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff)
//AM_RANGE(0x00180000, 0x0018001f) // Bitlatches?
AM_RANGE(0x00100000, 0x0010001f) AM_DEVREADWRITE8("uart0", ns16550_device, ins8250_r, ins8250_w, 0xff) // Serial UART0 (TL16C552 CS0)
AM_RANGE(0x00180000, 0x0018001f) AM_DEVREADWRITE8("uart1", ns16550_device, ins8250_r, ins8250_w, 0xff) // Serial UART1 (TL16C552 CS1)
//AM_RANGE(0x00200000, 0x0020001f) // Parallel UART (TL16C552 CS2)
AM_RANGE(0x00400000, 0x004000bf) AM_READWRITE8(blue_r, blue_w, 0xff)
AM_RANGE(0x00880000, 0x00880003) AM_READWRITE(asic_reset_r, asic_reset_w)
//00900000
//AM_RANGE(0x00980000, 0x00980003) // irq clear ??
//00a00000
//AM_RANGE(0x00a80000, 0x00a80003) // irq enable ??
//AM_RANGE(0x00b80000, 0x00b80003) // irq cause ??
AM_RANGE(0x00c80000, 0x00c80003) AM_READWRITE(green_r, green_w) // irq status ??
AM_RANGE(0x00880000, 0x00c80003) AM_READWRITE(board_ctrl_r, board_ctrl_w)
//AM_RANGE(0x00880000, 0x00880003) // Sub-module Power0
//AM_RANGE(0x00900000, 0x00900003) // Sub_module Power1 (Zeus or vblank?)
//AM_RANGE(0x00980000, 0x00980003) // IRQ1 Enable
//AM_RANGE(0x00a00000, 0x00a00003) // IRQ2 Enable
//AM_RANGE(0x00a80000, 0x00a80003) // IRQ3 Enable
//AM_RANGE(0x00b00000, 0x00b00003) // IRQ4 Enable Not Seen (Hardcoded to IDE?)
//AM_RANGE(0x00b80000, 0x00b80003) // IRQ Global Enable
//AM_RANGE(0x00c00000, 0x00c00003) // IRQ Cause
//AM_RANGE(0x00c80000, 0x00c80003) // IRQ Status
AM_RANGE(0x00d80000, 0x00d80003) AM_READWRITE(status_leds_r, status_leds_w)
AM_RANGE(0x00e00000, 0x00e00003) AM_READWRITE(cmos_protect_r, cmos_protect_w)
AM_RANGE(0x00e80000, 0x00e80003) AM_NOP // Watchdog?
@ -453,9 +666,18 @@ static ADDRESS_MAP_START( map1, AS_PROGRAM, 32, atlantis_state )
AM_RANGE(0x00000000, 0x0000003f) AM_DEVREADWRITE("ioasic", midway_ioasic_device, read, write)
// asic_fifo_w
// dcs3_fifo_full_w
//AM_RANGE(0x00200000, 0x00200003)
AM_RANGE(0x00400000, 0x00400003) AM_DEVWRITE("dcs", dcs_audio_device, dsio_idma_addr_w)
AM_RANGE(0x00600000, 0x00600003) AM_DEVREADWRITE("dcs", dcs_audio_device, dsio_idma_data_r, dsio_idma_data_w)
ADDRESS_MAP_END
//AM_RANGE(0x00800000, 0x00800003) AM_WRITE(dcs3_fifo_full_w)
//AM_RANGE(0x00800000, 0x00800003) AM_WRITE(asic_fifo_w)
//AM_RANGE(0x00800000, 0x00a00003) AM_READWRITE(port_ctrl_r, port_ctrl_w)
//AM_RANGE(0x00800000, 0x00800003) // Written once = 0000fff8
//AM_RANGE(0x00880000, 0x00880003) // Initial write 0000fff0, follow by sequence ffef, ffdf, ffbf, fff7. Row Select?
//AM_RANGE(0x00900000, 0x00900003) // Read once before each sequence write to 0x00880000. Code checks bits 0,1,2. Keypad?
//AM_RANGE(0x00980000, 0x00980003) // Read / Write. Bytes written 0x8f, 0xcf. Code if read 0x1 then read 00a00000. POTs?
//AM_RANGE(0x00a00000, 0x00a00003)
ADDRESS_MAP_END
static ADDRESS_MAP_START(map2, AS_PROGRAM, 32, atlantis_state)
AM_RANGE(0x00000000, 0x000001ff) AM_READWRITE(zeus_r, zeus_w)
@ -539,40 +761,41 @@ static INPUT_PORTS_START( mwskins )
PORT_BIT(0x8000, IP_ACTIVE_LOW, IPT_BILL1)
PORT_START("IN1")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(1)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(1)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(1)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(1)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(1)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_PLAYER(1) /* 3d cam */
PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(2)
PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(2)
PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(2)
PORT_BIT(0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(2)
PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(2)
PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(2)
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_PLAYER(1) PORT_8WAY
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_PLAYER(1) PORT_8WAY
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(1) PORT_8WAY
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1) PORT_8WAY
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1) PORT_NAME("Camera")
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(1) PORT_NAME("Club Up")
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("Aim Right")
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_PLAYER(2) PORT_8WAY
PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_PLAYER(2) PORT_8WAY
PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(2) PORT_8WAY
PORT_BIT(0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(2) PORT_8WAY
PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(2) PORT_NAME("Aim Left")
PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(2) PORT_NAME("Club Down")
PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2)
PORT_BIT(0x8000, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_PLAYER(2)
PORT_BIT(0x8000, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("IN2")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(3)
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(3)
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(3)
PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(3)
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(3)
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(3)
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(3)
PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(4)
PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(4)
PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(4)
PORT_BIT(0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(4)
PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(4)
PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(4)
PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(4)
PORT_BIT(0x8000, IP_ACTIVE_LOW, IPT_UNUSED)
//PORT_BIT(0x0007, IP_ACTIVE_HIGH, IPT_SPECIAL) PORT_CUSTOM_MEMBER(DEVICE_SELF, atlantis_state, port_mod_r, "KEYPAD")
PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("KEYPAD")
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) /* keypad 3 */
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) /* keypad 1 */
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) /* keypad 2 */
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) /* keypad 6 */
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) /* keypad 4 */
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) /* keypad 5 */
PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) /* keypad 9 */
PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) /* keypad 7 */
PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) /* keypad 8 */
PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad #") PORT_CODE(KEYCODE_PLUS_PAD) /* keypad # */
PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad *") PORT_CODE(KEYCODE_MINUS_PAD) /* keypad * */
PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) /* keypad 0 */
INPUT_PORTS_END
/*************************************
@ -603,9 +826,8 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state )
MCFG_NVRAM_ADD_0FILL("rtc")
//MCFG_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", nullptr, true)
MCFG_IDE_PCI_ADD(PCI_ID_IDE, 0x10950646, 0x03, 0x0)
MCFG_IDE_PCI_IRQ_ADD(":maincpu", IDE_IRQ_NUM)
MCFG_IDE_PCI_IRQ_HANDLER(DEVWRITELINE(":", atlantis_state, ide_irq))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@ -620,9 +842,9 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state )
MCFG_PALETTE_ADD_BBBBBGGGGGRRRRR("palette")
/* sound hardware */
//MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DSIO, 0)
MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DENVER, 0)
MCFG_DCS2_AUDIO_DRAM_IN_MB(4)
MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DSIO, 0)
//MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DENVER, 0)
MCFG_DCS2_AUDIO_DRAM_IN_MB(8)
MCFG_DCS2_AUDIO_POLLING_OFFSET(0) /* no place to hook :-( */
MCFG_DEVICE_ADD("ioasic", MIDWAY_IOASIC, 0)
@ -632,6 +854,12 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state )
MCFG_MIDWAY_IOASIC_IRQ_CALLBACK(WRITELINE(atlantis_state, ioasic_irq))
MCFG_MIDWAY_IOASIC_AUTO_ACK(1)
// TL16C552 UART
MCFG_DEVICE_ADD("uart0", NS16550, XTAL_24MHz)
MCFG_INS8250_OUT_INT_CB(DEVWRITELINE(":", atlantis_state, uart0_irq_callback))
MCFG_DEVICE_ADD("uart1", NS16550, XTAL_24MHz)
MCFG_INS8250_OUT_INT_CB(DEVWRITELINE(":", atlantis_state, uart1_irq_callback))
MACHINE_CONFIG_END

View File

@ -588,12 +588,21 @@ void vegas_state::machine_start()
m_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vegas_state::nile_timer_callback),this));
/* identify our sound board */
if (machine().device("dsio") != nullptr)
if (machine().device("dcs:dsio") != nullptr) {
m_dcs_idma_cs = 6;
else if (machine().device("denver") != nullptr)
if (LOG_SIO)
logerror("Found dsio\n");
}
else if (machine().device("dcs:denver") != nullptr) {
m_dcs_idma_cs = 7;
else
if (LOG_SIO)
logerror("Found denver\n");
}
else {
m_dcs_idma_cs = 0;
if (LOG_SIO)
logerror("Did not find dcs2 sound board\n");
}
/* set the fastest DRC options, but strict verification */
m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS + MIPS3DRC_STRICT_VERIFY + MIPS3DRC_FLUSH_PC);
@ -958,8 +967,13 @@ TIMER_CALLBACK_MEMBER(vegas_state::nile_timer_callback)
/* adjust the timer to fire again */
{
UINT32 scale = regs[0];
if (regs[1] & 2)
logerror("Unexpected value: timer %d is prescaled\n", which);
if (regs[1] & 2) {
UINT32 scaleSrc = (regs[1] >> 2) & 0x3;
UINT32 *scaleReg = &m_nile_regs[NREG_T0CTRL + scaleSrc * 4];
scale *= scaleReg[0];
//logerror("Unexpected value: timer %d is prescaled\n", which);
logerror("Timer Scaling value: timer %d is prescaled from %08X to %08X\n", which, regs[0], scale);
}
if (scale != 0)
m_timer[which]->adjust(TIMER_PERIOD * scale, which);
}
@ -1042,9 +1056,15 @@ READ32_MEMBER( vegas_state::nile_r )
which = (offset - NREG_T0CTRL) / 4;
if (m_nile_regs[offset - 1] & 1)
{
if (m_nile_regs[offset] & 2)
logerror("Unexpected value: timer %d is prescaled\n", which);
result = m_nile_regs[offset + 1] = m_timer[which]->remaining().as_double() * (double)SYSTEM_CLOCK;
//if (m_nile_regs[offset - 1] & 2)
// logerror("Unexpected value: timer %d is prescaled\n", which);
UINT32 scale = 1;
if (m_nile_regs[offset - 1] & 2) {
UINT32 scaleSrc = (m_nile_regs[offset - 1] >> 2) & 0x3;
scale = m_nile_regs[NREG_T0CTRL + scaleSrc * 4];
logerror("Timer value: timer %d is prescaled by \n", which, scale);
}
result = m_nile_regs[offset + 1] = m_timer[which]->remaining().as_double() * (double)SYSTEM_CLOCK / scale;
}
if (LOG_TIMERS) logerror("%08X:NILE READ: timer %d counter(%03X) = %08X\n", safe_pc(), which, offset*4, result);
@ -1164,26 +1184,37 @@ WRITE32_MEMBER( vegas_state::nile_w )
case NREG_T2CTRL+1: /* general purpose timer control (control bits) */
case NREG_T3CTRL+1: /* watchdog timer control (control bits) */
which = (offset - NREG_T0CTRL) / 4;
if (LOG_NILE) logerror("%08X:NILE WRITE: timer %d control(%03X) = %08X & %08X\n", safe_pc(), which, offset*4, data, mem_mask);
if (1 || LOG_NILE) logerror("%08X:NILE WRITE: timer %d control(%03X) = %08X & %08X\n", safe_pc(), which, offset*4, data, mem_mask);
logit = 0;
/* timer just enabled? */
if (!(olddata & 1) && (m_nile_regs[offset] & 1))
{
UINT32 scale = m_nile_regs[offset + 1];
if (m_nile_regs[offset] & 2)
logerror("Unexpected value: timer %d is prescaled\n", which);
UINT32 scale = m_nile_regs[offset - 1];
//if (m_nile_regs[offset] & 2)
// logerror("Unexpected value: timer %d is prescaled\n", which);
if (m_nile_regs[offset] & 2) {
UINT32 scaleSrc = (m_nile_regs[offset] >> 2) & 0x3;
scale *= m_nile_regs[NREG_T0CTRL + which * 4];
logerror("Timer scale: timer %d is scaled by %08X\n", which, m_nile_regs[NREG_T0CTRL + which * 4]);
}
if (scale != 0)
m_timer[which]->adjust(TIMER_PERIOD * scale, which);
if (LOG_TIMERS) logerror("Starting timer %d at a rate of %d Hz\n", which, (int)ATTOSECONDS_TO_HZ((TIMER_PERIOD * (m_nile_regs[offset + 1] + 1)).attoseconds()));
if (LOG_TIMERS) logerror("Starting timer %d at a rate of %f Hz scale = %08X\n", which, ATTOSECONDS_TO_HZ((TIMER_PERIOD * (m_nile_regs[offset + 1] + 1)).attoseconds()), scale);
}
/* timer disabled? */
else if ((olddata & 1) && !(m_nile_regs[offset] & 1))
{
if (m_nile_regs[offset] & 2)
logerror("Unexpected value: timer %d is prescaled\n", which);
m_nile_regs[offset + 1] = m_timer[which]->remaining().as_double() * SYSTEM_CLOCK;
//if (m_nile_regs[offset] & 2)
// logerror("Unexpected value: timer %d is prescaled\n", which);
UINT32 scale = 1;
if (m_nile_regs[offset] & 2) {
UINT32 scaleSrc = (m_nile_regs[offset] >> 2) & 0x3;
scale = m_nile_regs[NREG_T0CTRL + which * 4];
logerror("Timer scale: timer %d is scaled by %08X\n", which, scale);
}
m_nile_regs[offset + 1] = m_timer[which]->remaining().as_double() * SYSTEM_CLOCK / scale;
m_timer[which]->adjust(attotime::never, which);
}
break;
@ -1198,9 +1229,15 @@ WRITE32_MEMBER( vegas_state::nile_w )
if (m_nile_regs[offset - 1] & 1)
{
if (m_nile_regs[offset - 1] & 2)
logerror("Unexpected value: timer %d is prescaled\n", which);
m_timer[which]->adjust(TIMER_PERIOD * m_nile_regs[offset], which);
//if (m_nile_regs[offset - 1] & 2)
// logerror("Unexpected value: timer %d is prescaled\n", which);
UINT32 scale = 1;
if (m_nile_regs[offset - 1] & 2) {
UINT32 scaleSrc = (m_nile_regs[offset - 1] >> 2) & 0x3;
scale = m_nile_regs[NREG_T0CTRL + which * 4];
logerror("Timer scale: timer %d is scaled by %08X\n", which, scale);
}
m_timer[which]->adjust(TIMER_PERIOD * m_nile_regs[offset] * scale, which);
}
break;
@ -1407,7 +1444,7 @@ WRITE32_MEMBER( vegas_state::sio_w )
if (ACCESSING_BITS_16_23) offset += 2;
if (ACCESSING_BITS_24_31) offset += 3;
if (LOG_SIO && offset != 0)
logerror("%08X:sio write to offset %X = %02X\n", safe_pc(), offset, data >> (offset*8));
logerror("%08X:sio write to offset %X = %02X\n", machine().device("maincpu")->safe_pc(), offset, data >> (offset*8));
if (offset < 4)
m_sio_data[offset] = data >> (offset*8);
if (offset == 1)
@ -1425,7 +1462,7 @@ READ32_MEMBER( vegas_state::sio_r )
if (offset < 4)
result = m_sio_data[0] | (m_sio_data[1] << 8) | (m_sio_data[2] << 16) | (m_sio_data[3] << 24);
if (LOG_SIO && offset != 2)
logerror("%08X:sio read from offset %X = %02X\n", safe_pc(), offset, result >> (offset*8));
logerror("%08X:sio read from offset %X = %02X\n", machine().device("maincpu")->safe_pc(), offset, result >> (offset*8));
return result;
}