atlantis: Update address mapping and add zeus2 video device (nw)

dcs: Update 2181 SYSCONTROL bits (nw)
adsp2100: Add more info for invalid register accesses (nw)
zeus2: New video device based on midzeus2 driver (nw)
This commit is contained in:
Ted Green 2016-06-16 14:25:55 -06:00
parent 6d160ed72d
commit aae1cbb6d3
7 changed files with 1725 additions and 196 deletions

View File

@ -804,6 +804,18 @@ if (VIDEOS["V9938"]~=null) then
}
end
--------------------------------------------------
--
--@src/devices/video/zeus2.h,VIDEOS["ZEUS2"] = true
--------------------------------------------------
if (VIDEOS["ZEUS2"]~=null) then
files {
MAME_DIR .. "src/devices/video/zeus2.cpp",
MAME_DIR .. "src/devices/video/zeus2.h",
}
end
--------------------------------------------------
--
--@src/devices/video/voodoo.h,VIDEOS["VOODOO"] = true

View File

@ -332,6 +332,7 @@ VIDEOS["V9938"] = true
--VIDEOS["VIC4567"] = true
VIDEOS["VOODOO"] = true
VIDEOS["VOODOO_PCI"] = true
VIDEOS["ZEUS2"] = true
--------------------------------------------------
-- specify available machine cores

View File

@ -380,7 +380,7 @@ void adsp21xx_device::write_reg1(int regnum, INT32 val)
break;
case 3:
logerror("ADSP %04x: Writing to an invalid register!\n", m_ppc);
logerror("ADSP %04x: Writing to an invalid register! RGP=01 RegCode=%1X Val=%04X\n", m_ppc, regnum, val);
break;
}
}
@ -505,7 +505,7 @@ INT32 adsp21xx_device::read_reg3(int regnum)
case 0x08: if (!m_sport_rx_cb.isnull()) return m_sport_rx_cb(0); else return 0;
case 0x0a: if (!m_sport_rx_cb.isnull()) return m_sport_rx_cb(1); else return 0;
case 0x0f: return pc_stack_pop_val();
default: logerror("ADSP %04x: Reading from an invalid register!\n", m_ppc); return 0;
default: logerror("ADSP %04x: Reading from an invalid register! RGP=b11 RegCode=%1X\n", m_ppc, regnum); return 0;
}
}

1253
src/devices/video/zeus2.cpp Normal file

File diff suppressed because it is too large Load Diff

286
src/devices/video/zeus2.h Normal file
View File

@ -0,0 +1,286 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*************************************************************************
Midway Zeus2 Video
**************************************************************************/
#ifndef __ZEUS2_H__
#define __ZEUS2_H__
#include "emu.h"
#include "video/poly.h"
#include "video/rgbutil.h"
#include "cpu/tms32031/tms32031.h"
#pragma once
/*************************************
* Constants
*************************************/
#define MIDZEUS_VIDEO_CLOCK XTAL_66_6667MHz
#define DUMP_WAVE_RAM 0
#define TRACK_REG_USAGE 0
#define WAVERAM0_WIDTH 1024
#define WAVERAM0_HEIGHT 2048
//#define WAVERAM1_WIDTH 512
#define WAVERAM1_WIDTH 512
#define WAVERAM1_HEIGHT 1024
//#define WAVERAM1_HEIGHT 1024
/*************************************
* Type definitions
*************************************/
struct zeus2_poly_extra_data
{
const void * palbase;
const void * texbase;
UINT16 solidcolor;
INT16 zoffset;
UINT16 transcolor;
UINT16 texwidth;
UINT16 color;
UINT32 alpha;
};
/*************************************
* Macros
*************************************/
#define WAVERAM_BLOCK0(blocknum) ((void *)((UINT8 *)waveram[0] + 8 * (blocknum)))
#define WAVERAM_BLOCK1(blocknum) ((void *)((UINT8 *)waveram[1] + 12 * (blocknum)))
#define WAVERAM_BLOCK0_EXT(blocknum) ((void *)((UINT8 *)m_state.waveram[0] + 8 * (blocknum)))
#define WAVERAM_BLOCK1_EXT(blocknum) ((void *)((UINT8 *)m_state.waveram[1] + 12 * (blocknum)))
#define WAVERAM_PTR8(base, bytenum) ((UINT8 *)(base) + BYTE4_XOR_LE(bytenum))
#define WAVERAM_READ8(base, bytenum) (*WAVERAM_PTR8(base, bytenum))
#define WAVERAM_WRITE8(base, bytenum, data) do { *WAVERAM_PTR8(base, bytenum) = (data); } while (0)
#define WAVERAM_PTR16(base, wordnum) ((UINT16 *)(base) + BYTE_XOR_LE(wordnum))
#define WAVERAM_READ16(base, wordnum) (*WAVERAM_PTR16(base, wordnum))
#define WAVERAM_WRITE16(base, wordnum, data) do { *WAVERAM_PTR16(base, wordnum) = (data); } while (0)
#define WAVERAM_PTR32(base, dwordnum) ((UINT32 *)(base) + (dwordnum))
#define WAVERAM_READ32(base, dwordnum) (*WAVERAM_PTR32(base, dwordnum))
#define WAVERAM_WRITE32(base, dwordnum, data) do { *WAVERAM_PTR32(base, dwordnum) = (data); } while (0)
#define PIXYX_TO_DWORDNUM(y, x) (((((y) & 0x1ff) << 8) | (((x) & 0x1fe) >> 1)) * 3 + ((x) & 1))
#define DEPTHYX_TO_DWORDNUM(y, x) (PIXYX_TO_DWORDNUM(y, (x) & ~1) + 2)
#define WAVERAM_PTRPIX(base, y, x) WAVERAM_PTR32(base, PIXYX_TO_DWORDNUM(y, x))
#define WAVERAM_READPIX(base, y, x) (*WAVERAM_PTRPIX(base, y, x))
#define WAVERAM_WRITEPIX(base, y, x, color) do { *WAVERAM_PTRPIX(base, y, x) = (color); } while (0)
#define WAVERAM_PTRDEPTH(base, y, x) WAVERAM_PTR16(base, DEPTHYX_TO_DWORDNUM(y, x) * 2 + (x & 1))
#define WAVERAM_READDEPTH(base, y, x) (*WAVERAM_PTRDEPTH(base, y, x))
#define WAVERAM_WRITEDEPTH(base, y, x, color) do { *WAVERAM_PTRDEPTH(base, y, x) = (color); } while (0)
/*************************************
* Polygon renderer
*************************************/
class zeus2_device;
class zeus2_renderer : public poly_manager<float, zeus2_poly_extra_data, 4, 10000>
{
public:
zeus2_renderer(zeus2_device &state);
void render_poly_8bit(INT32 scanline, const extent_t& extent, const zeus2_poly_extra_data& object, int threadid);
void zeus2_draw_quad(const UINT32 *databuffer, UINT32 texoffs, int logit);
private:
zeus2_device& m_state;
};
typedef zeus2_renderer::vertex_t poly_vertex;
typedef zeus2_renderer::extent_t poly_extent;
/*************************************
* Zeus2 Video Device
*************************************/
#define MCFG_ZEUS2_VBLANK_CB(_devcb) \
devcb = &zeus2_device::set_vblank_callback(*device, DEVCB_##_devcb);
#define MCFG_ZEUS2_IRQ_CB(_devcb) \
devcb = &zeus2_device::set_irq_callback(*device, DEVCB_##_devcb);
class zeus2_device : public device_t
{
public:
zeus2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
screen_device *m_screen; /* the screen we are acting on */
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ32_MEMBER( zeus2_r );
DECLARE_WRITE32_MEMBER( zeus2_w );
TIMER_CALLBACK_MEMBER(display_irq_off);
TIMER_CALLBACK_MEMBER(display_irq);
template<class _Object> static devcb_base &set_vblank_callback(device_t &device, _Object object) { return downcast<zeus2_device &>(device).m_vblank.set_callback(object); }
template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<zeus2_device &>(device).m_irq.set_callback(object); }
devcb_write_line m_vblank;
devcb_write_line m_irq;
UINT32 m_zeusbase[400];
zeus2_renderer* poly;
void *zeus_renderbase;
rectangle zeus_cliprect;
float zeus_matrix[3][3];
float zeus_point[3];
float zeus_point2[3];
UINT32 zeus_texbase;
UINT32 zeus_unknown_40;
int zeus_quad_size;
UINT32 *waveram[2];
emu_timer *int_timer;
emu_timer *vblank_timer;
int m_yScale;
int yoffs;
int texel_width;
float zbase;
/*************************************
* Inlines for block addressing
*************************************/
inline void *waveram0_ptr_from_expanded_addr(UINT32 addr)
{
UINT32 blocknum = (addr % WAVERAM0_WIDTH) + ((addr >> 16) % WAVERAM0_HEIGHT) * WAVERAM0_WIDTH;
return WAVERAM_BLOCK0(blocknum);
}
inline void *waveram1_ptr_from_expanded_addr(UINT32 addr)
{
UINT32 blocknum = (addr % WAVERAM1_WIDTH) + ((addr >> 16) % WAVERAM1_HEIGHT) * WAVERAM1_WIDTH;
return WAVERAM_BLOCK1(blocknum);
}
#ifdef UNUSED_FUNCTION
inline void *waveram0_ptr_from_texture_addr(UINT32 addr, int width)
{
UINT32 blocknum = ((addr & ~1) * width) / 8;
return WAVERAM_BLOCK0(blocknum);
}
#endif
/*************************************
* Inlines for rendering
*************************************/
#ifdef UNUSED_FUNCTION
inline void waveram_plot(int y, int x, UINT32 color)
{
if (zeus_cliprect.contains(x, y))
WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
}
#endif
inline void waveram_plot_depth(int y, int x, UINT32 color, UINT16 depth)
{
if (zeus_cliprect.contains(x, y))
{
WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
WAVERAM_WRITEDEPTH(zeus_renderbase, y, x, depth);
}
}
#ifdef UNUSED_FUNCTION
inline void waveram_plot_check_depth(int y, int x, UINT32 color, UINT16 depth)
{
if (zeus_cliprect.contains(x, y))
{
UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x);
if (depth <= *depthptr)
{
WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
*depthptr = depth;
}
}
}
#endif
#ifdef UNUSED_FUNCTION
inline void waveram_plot_check_depth_nowrite(int y, int x, UINT32 color, UINT16 depth)
{
if (zeus_cliprect.contains(x, y))
{
UINT16 *depthptr = WAVERAM_PTRDEPTH(zeus_renderbase, y, x);
if (depth <= *depthptr)
WAVERAM_WRITEPIX(zeus_renderbase, y, x, color);
}
}
#endif
/*************************************
* Inlines for texel accesses
*************************************/
inline UINT8 get_texel_8bit(const void *base, int y, int x, int width)
{
UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 4) << 3) + ((y & 1) << 2) + (x & 3);
return WAVERAM_READ8(base, byteoffs);
}
#ifdef UNUSED_FUNCTION
inline UINT8 get_texel_4bit(const void *base, int y, int x, int width)
{
UINT32 byteoffs = (y / 2) * (width * 2) + ((x / 8) << 3) + ((y & 1) << 2) + ((x / 2) & 3);
return (WAVERAM_READ8(base, byteoffs) >> (4 * (x & 1))) & 0x0f;
}
#endif
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_stop() override;
private:
TIMER_CALLBACK_MEMBER(int_timer_callback);
void zeus2_register32_w(offs_t offset, UINT32 data, int logit);
void zeus2_register_update(offs_t offset, UINT32 oldval, int logit);
int zeus2_fifo_process(const UINT32 *data, int numwords);
void zeus2_pointer_write(UINT8 which, UINT32 value);
void zeus2_draw_model(UINT32 baseaddr, UINT16 count, int logit);
void log_fifo_command(const UINT32 *data, int numwords, const char *suffix);
/*************************************
* Member variables
*************************************/
UINT8 log_fifo;
UINT32 zeus_fifo[20];
UINT8 zeus_fifo_words;
#if TRACK_REG_USAGE
struct reg_info
{
struct reg_info *next;
UINT32 value;
};
reg_info *regdata[0x80];
int regdata_count[0x80];
int regread_count[0x80];
int regwrite_count[0x80];
reg_info *subregdata[0x100];
int subregdata_count[0x80];
int subregwrite_count[0x100];
#endif
};
// device type definition
extern const device_type ZEUS2;
#endif

View File

@ -1872,10 +1872,10 @@ WRITE16_MEMBER(dcs_audio_device:: adsp_control_w )
switch (offset)
{
case SYSCONTROL_REG:
/* bit 9 forces a reset */
if (data & 0x0200)
/* bit 9 forces a reset (not on 2181) */
if ((data & 0x0200) && !(m_rev == 3 || m_rev == 4))
{
logerror("%04X:Rebooting DCS due to SYSCONTROL write\n", space.device().safe_pc());
logerror("%04X:Rebooting DCS due to SYSCONTROL write = %04X\n", space.device().safe_pc(), data);
m_cpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
dcs_boot();
m_control_regs[SYSCONTROL_REG] = 0;
@ -1950,9 +1950,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq )
{
int count = m_size / (2*(m_incs ? m_incs : 1));
// sf2049se was having overflow issues with fixed size of 0x400 buffer (m_size==0xb40, count=0x5a0).
//INT16 buffer[0x400];
std::unique_ptr<INT16[]> buffer;
buffer = std::make_unique<INT16[]>(count);
INT16 buffer[0x800];
int i;
for (i = 0; i < count; i++)
@ -1962,7 +1960,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq )
}
if (m_channels)
dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer.get());
dmadac_transfer(&m_dmadac[0], m_channels, 1, m_channels, count / m_channels, buffer);
}
/* check for wrapping */

View File

@ -43,6 +43,7 @@
#include "machine/vrc4373.h"
#include "machine/pci9050.h"
#include "machine/pci-ide.h"
#include "video/zeus2.h"
#include "includes/midzeus.h"
#include "includes/midzeus2.h"
#include "machine/nvram.h"
@ -62,19 +63,22 @@
// These need more verification
#define IOASIC_IRQ_SHIFT 0
#define GALILEO_IRQ_SHIFT 1
#define ZEUS_IRQ_SHIFT 2
#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_IRQ0
#define VBLANK_IRQ_NUM MIPS3_IRQ3
#define IDE_IRQ_NUM MIPS3_IRQ4
#define LOG_RTC (1)
#define LOG_ZEUS (0)
#define LOG_RTC (0)
#define LOG_RED (0)
#define LOG_PORT (0)
#define LOG_IRQ (0)
class atlantis_state : public driver_device
{
@ -83,6 +87,8 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_zeus(*this, "zeus2"),
m_dcs(*this, "dcs"),
m_ioasic(*this, "ioasic"),
m_uart0(*this, "uart0"),
@ -95,14 +101,14 @@ public:
UINT32 screen_update_mwskins(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
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;
optional_device<palette_device> m_palette;
required_device<zeus2_device> m_zeus;
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];
UINT8 m_rtc_data[0x8000];
UINT32 m_last_offset;
READ8_MEMBER(cmos_r);
@ -110,22 +116,13 @@ public:
DECLARE_WRITE32_MEMBER(cmos_protect_w);
DECLARE_READ32_MEMBER(cmos_protect_r);
UINT32 m_cmos_write_enabled;
UINT32 m_serial_count;
DECLARE_READ32_MEMBER(status_leds_r);
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];
READ8_MEMBER (red_r);
WRITE8_MEMBER(red_w);
UINT8 m_red_data[0x1000];
int m_red_count;
READ32_MEMBER (green_r);
WRITE32_MEMBER(green_w);
@ -142,6 +139,8 @@ public:
UINT8 board_ctrl[CTRL_SIZE];
void update_asic_irq();
DECLARE_WRITE_LINE_MEMBER(vblank_irq);
DECLARE_WRITE_LINE_MEMBER(zeus_irq);
DECLARE_WRITE_LINE_MEMBER(ide_irq);
DECLARE_WRITE_LINE_MEMBER(ioasic_irq);
@ -154,37 +153,6 @@ public:
UINT32 m_port_ctrl_reg[0x8];
};
READ8_MEMBER (atlantis_state::red_r)
{
UINT8 data = m_red_data[offset];
logerror("%06X: red_r %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
m_last_offset = offset | 0x10000;
return data;
}
WRITE8_MEMBER(atlantis_state::red_w)
{
COMBINE_DATA(&m_red_data[offset]);
switch (offset) {
case 0:
// User I/O 0 = Allow write to red[0]. Serial Write Enable?
if (m_user_io_state & 0x1) {
// Data written is shifted by 1 bit each time. Maybe a serial line output?
if (m_red_count == 0)
logerror("%06X: red_w start serial %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
m_red_count++;
if (m_red_count == 8)
m_red_count = 0;
break;
} // Fall through to default if not enabled
default:
logerror("%06X: red_w %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
break;
}
m_last_offset = offset | 0x10000;
}
READ32_MEMBER(atlantis_state::green_r)
{
// If not 0x80 cpu writes to 00e80000 = 0
@ -222,10 +190,12 @@ READ32_MEMBER(atlantis_state::board_ctrl_r)
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);
if (LOG_IRQ)
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);
if (LOG_IRQ)
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;
@ -251,66 +221,70 @@ WRITE32_MEMBER(atlantis_state::board_ctrl_w)
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);
if (LOG_IRQ)
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?
// 0x1 VBlank clear?
if (changeData & 0x1) {
if ((data & 0x0001) == 0) {
//UINT32 status_bit = (1 << VBLANK_IRQ_SHIFT);
UINT32 status_bit = (1 << 7);
board_ctrl[CTRL_CAUSE] &= ~status_bit;
board_ctrl[CTRL_STATUS] &= ~status_bit;
update_asic_irq();
}
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);
if (LOG_IRQ)
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);
if (LOG_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);
if (LOG_IRQ)
logerror("%s:board_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
break;
}
}
WRITE32_MEMBER(atlantis_state::asic_fifo_w)
{
m_ioasic->fifo_w(data);
}
READ8_MEMBER(atlantis_state::cmos_r)
{
UINT8 result = m_rtc_data[offset];
switch (offset) {
case 0x7F9:
case 0x7FA:
case 0x7FB:
case 0x7FC:
case 0x7FD:
case 0x7FE:
case 0x7FF:
if ((m_rtc_data[0x7F8] & 0x40)==0) {
case 0x7FF9:
case 0x7FFA:
case 0x7FFB:
case 0x7FFC:
case 0x7FFD:
case 0x7FFE:
case 0x7FFF:
if ((m_rtc_data[0x7FF8] & 0x40)==0) {
system_time systime;
// get the current date/time from the core
machine().current_datetime(systime);
m_rtc_data[0x7F9] = dec_2_bcd(systime.local_time.second);
m_rtc_data[0x7FA] = dec_2_bcd(systime.local_time.minute);
m_rtc_data[0x7FB] = dec_2_bcd(systime.local_time.hour);
m_rtc_data[0x7FF9] = dec_2_bcd(systime.local_time.second);
m_rtc_data[0x7FFA] = dec_2_bcd(systime.local_time.minute);
m_rtc_data[0x7FFB] = dec_2_bcd(systime.local_time.hour);
m_rtc_data[0x7FC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
m_rtc_data[0x7FD] = dec_2_bcd(systime.local_time.mday);
m_rtc_data[0x7FE] = dec_2_bcd(systime.local_time.month + 1);
m_rtc_data[0x7FF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
m_rtc_data[0x7FFC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
m_rtc_data[0x7FFD] = dec_2_bcd(systime.local_time.mday);
m_rtc_data[0x7FFE] = dec_2_bcd(systime.local_time.month + 1);
m_rtc_data[0x7FFF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
result = m_rtc_data[offset];
}
break;
default:
if (LOG_RTC)
logerror("%s:RTC read from offset %04X = %08X m_rtc_data[0x7F8] %02X\n", machine().describe_context(), offset, result, m_rtc_data[0x7F8]);
logerror("%s:RTC read from offset %04X = %08X m_rtc_data[0x7FF8] %02X\n", machine().describe_context(), offset, result, m_rtc_data[0x7FF8]);
break;
}
return result;
@ -319,23 +293,31 @@ READ8_MEMBER(atlantis_state::cmos_r)
WRITE8_MEMBER(atlantis_state::cmos_w)
{
system_time systime;
if (m_cmos_write_enabled) {
// User I/O 0 = Allow write to cmos[0]. Serial Write Enable?
if (offset == 0 && (m_user_io_state & 0x1)) {
// Data written is shifted by 1 bit each time. Maybe a serial line output?
if (LOG_RTC && m_serial_count == 0)
logerror("%06X: cmos_w[0] start serial %08x = %02x\n", machine().device("maincpu")->safe_pc(), offset, data);
m_serial_count++;
if (m_serial_count == 8)
m_serial_count = 0;
}
else if (m_cmos_write_enabled) {
COMBINE_DATA(&m_rtc_data[offset]);
m_cmos_write_enabled = FALSE;
switch (offset) {
case 0x7F8: // M48T02 time
case 0x7FF8: // M48T02 time
if (data & 0x40) {
// get the current date/time from the core
machine().current_datetime(systime);
m_rtc_data[0x7F9] = dec_2_bcd(systime.local_time.second);
m_rtc_data[0x7FA] = dec_2_bcd(systime.local_time.minute);
m_rtc_data[0x7FB] = dec_2_bcd(systime.local_time.hour);
m_rtc_data[0x7FF9] = dec_2_bcd(systime.local_time.second);
m_rtc_data[0x7FFA] = dec_2_bcd(systime.local_time.minute);
m_rtc_data[0x7FFB] = dec_2_bcd(systime.local_time.hour);
m_rtc_data[0x7FC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
m_rtc_data[0x7FD] = dec_2_bcd(systime.local_time.mday);
m_rtc_data[0x7FE] = dec_2_bcd(systime.local_time.month + 1);
m_rtc_data[0x7FF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
m_rtc_data[0x7FFC] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
m_rtc_data[0x7FFD] = dec_2_bcd(systime.local_time.mday);
m_rtc_data[0x7FFE] = dec_2_bcd(systime.local_time.month + 1);
m_rtc_data[0x7FFF] = dec_2_bcd(systime.local_time.year - 1900); // Epoch is 1900
}
if (LOG_RTC)
logerror("%s:RTC write to offset %04X = %08X & %08X\n", machine().describe_context(), offset, data, mem_mask);
@ -396,45 +378,14 @@ WRITE32_MEMBER(atlantis_state::status_leds_w)
}
}
READ32_MEMBER(atlantis_state::zeus_r)
{
UINT32 result = m_zeus_data[offset];
switch (offset) {
case 0x1:
/* bit $000C0070 are tested in a loop until 0 */
/* bits $00080000 is tested in a loop until 0 */
/* bit $00000004 is tested for toggling; probably VBLANK */
// zeus is reset if 0x80 is read
//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;
}
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]);
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;
}
READ32_MEMBER(atlantis_state::cmos_protect_r)
{
return m_cmos_write_enabled;
}
WRITE32_MEMBER(atlantis_state::dcs3_fifo_full_w)
WRITE32_MEMBER(atlantis_state::asic_fifo_w)
{
m_ioasic->fifo_full_w(data);
m_ioasic->fifo_w(data);
}
/*************************************
@ -495,13 +446,49 @@ WRITE_LINE_MEMBER(atlantis_state::uart1_irq_callback)
logerror("atlantis_state::uart1_irq_callback state = %1x\n", state);
}
/*************************************
* Video interrupts
*************************************/
WRITE_LINE_MEMBER(atlantis_state::vblank_irq)
{
//logerror("%s: atlantis_state::vblank state = %i\n", machine().describe_context(), state);
if (1) {
if (state) {
board_ctrl[CTRL_STATUS] |= (1 << VBLANK_IRQ_SHIFT);
update_asic_irq();
}
else {
board_ctrl[CTRL_STATUS] &= ~(1 << VBLANK_IRQ_SHIFT);
board_ctrl[CTRL_CAUSE] &= ~(1 << VBLANK_IRQ_SHIFT);
update_asic_irq();
}
} else {
m_maincpu->set_input_line(VBLANK_IRQ_NUM, state);
}
}
WRITE_LINE_MEMBER(atlantis_state::zeus_irq)
{
logerror("%s: atlantis_state::zeus_irq state = %i\n", machine().describe_context(), state);
if (state) {
board_ctrl[CTRL_STATUS] |= (1 << ZEUS_IRQ_SHIFT);
update_asic_irq();
}
else {
board_ctrl[CTRL_STATUS] &= ~(1 << ZEUS_IRQ_SHIFT);
board_ctrl[CTRL_CAUSE] &= ~(1 << ZEUS_IRQ_SHIFT);
update_asic_irq();
}
}
/*************************************
* 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);
if (LOG_IRQ)
logerror("%s: atlantis_state::ide_irq state = %i\n", machine().describe_context(), state);
}
/*************************************
@ -509,7 +496,8 @@ WRITE_LINE_MEMBER(atlantis_state::ide_irq)
*************************************/
WRITE_LINE_MEMBER(atlantis_state::ioasic_irq)
{
logerror("%s: atlantis_state::ioasic_irq state = %i\n", machine().describe_context(), state);
if (LOG_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();
@ -535,13 +523,13 @@ void atlantis_state::update_asic_irq()
if (irqBits && !currState) {
m_maincpu->set_input_line(MIPS3_IRQ0 + irqIndex, ASSERT_LINE);
m_irq_state |= (1 << irqIndex);
if (1)
if (LOG_IRQ)
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)
if (LOG_IRQ)
logerror("atlantis_state::update_asic_irq Clearing IRQ(%d) CAUSE = %02X\n", irqIndex, board_ctrl[CTRL_CAUSE]);
}
}
@ -553,7 +541,8 @@ 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);
if (LOG_PORT)
logerror("%s: port_ctrl_r newOffset = %02X data = %08X\n", machine().describe_context(), newOffset, result);
return result;
}
@ -562,22 +551,24 @@ 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;
//switch (newOffset) {
if (newOffset == 1) {
UINT32 bits = ioport("KEYPAD")->read();
m_port_ctrl_reg[2] = 0;
if (!(data & 0x8))
m_port_ctrl_reg[2] = bits & 7; // Row 0
else if (!(data & 0x10))
m_port_ctrl_reg[2] = (bits >> 4) & 7; // Row 1
else if (!(data & 0x20))
m_port_ctrl_reg[2] = (bits >> 8) & 7; // Row 2
else if (!(data & 0x40))
m_port_ctrl_reg[2] = (bits >> 12) & 7; // Row 3
if (LOG_PORT)
logerror("%s: port_ctrl_w Keypad Row Sel = %04X bits = %08X\n", machine().describe_context(), data, bits);
}
else {
if (LOG_PORT)
logerror("%s: port_ctrl_w write to offset %04X = %08X & %08X bus offset = %08X\n", machine().describe_context(), newOffset, data, mem_mask, offset);
}
}
@ -625,24 +616,17 @@ void atlantis_state::machine_reset()
m_dcs->reset_w(0);
m_user_io_state = 0;
m_cmos_write_enabled = FALSE;
memset(m_zeus_data, 0, sizeof(m_zeus_data));
m_red_count = 0;
m_serial_count = 0;
m_irq_state = 0;
memset(board_ctrl, 0, sizeof(board_ctrl));
memset(m_port_ctrl_reg, 0, sizeof(m_port_ctrl_reg));
}
/*************************************
*
* Main CPU memory handlers
*
* Address Maps
*************************************/
static ADDRESS_MAP_START( map0, AS_PROGRAM, 32, atlantis_state )
AM_RANGE(0x00000000, 0x00000fff) AM_READWRITE8(red_r, red_w, 0xff)
AM_RANGE(0x0001e000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff)
AM_RANGE(0x00000000, 0x0001ffff) AM_READWRITE8(cmos_r, cmos_w, 0xff)
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)
@ -665,22 +649,20 @@ ADDRESS_MAP_END
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(0x00200000, 0x00200003) AM_WRITE(asic_fifo_w)
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)
//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, 0x00900003) 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
AM_RANGE(0x00980000, 0x00980003) AM_NOP // AM_WRITE(asic_fifo_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START(map2, AS_PROGRAM, 32, atlantis_state)
AM_RANGE(0x00000000, 0x000001ff) AM_READWRITE(zeus_r, zeus_w)
AM_RANGE(0x00000000, 0x000001ff) AM_DEVREADWRITE("zeus2", zeus2_device, zeus2_r, zeus2_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( map3, AS_PROGRAM, 32, atlantis_state )
@ -696,26 +678,26 @@ ADDRESS_MAP_END
static INPUT_PORTS_START( mwskins )
PORT_START("DIPS")
PORT_DIPNAME(0x0003, 0x0003, "Boot Mode")
PORT_DIPSETTING(0x0003, "Normal Boot")
PORT_DIPSETTING(0x0003, "Run Game")
PORT_DIPSETTING(0x0002, "Boot EEPROM Based Self Test")
PORT_DIPSETTING(0x0001, "Boot Disk Based Self Test")
PORT_DIPSETTING(0x0000, "Run Factory Tests")
PORT_DIPNAME(0x0004, 0x0004, "Unknown0004")
PORT_DIPSETTING(0x0004, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0008, 0x0008, "Unknown0008")
PORT_DIPNAME(0x0004, 0x0004, "Boot Message")
PORT_DIPSETTING(0x0004, "Quiet")
PORT_DIPSETTING(0x0000, "Squawk During Boot")
PORT_DIPNAME(0x0008, 0x0008, "Reserved")
PORT_DIPSETTING(0x0008, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0010, 0x0010, "Unknown0010")
PORT_DIPNAME(0x0010, 0x0010, "Reserved")
PORT_DIPSETTING(0x0010, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0020, 0x0020, "Unknown0020")
PORT_DIPNAME(0x0020, 0x0020, "Reserved")
PORT_DIPSETTING(0x0020, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0040, 0x0040, "Unknown0040")
PORT_DIPNAME(0x0040, 0x0040, "Reserved")
PORT_DIPSETTING(0x0040, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0080, 0x0080, "Unknown0080")
PORT_DIPNAME(0x0080, 0x0080, "Reserved")
PORT_DIPSETTING(0x0080, DEF_STR(Off))
PORT_DIPSETTING(0x0000, DEF_STR(On))
PORT_DIPNAME(0x0100, 0x0100, "Unknown0100")
@ -783,18 +765,18 @@ static INPUT_PORTS_START( mwskins )
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 */
PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD) /* keypad 1 */
PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD) /* keypad 2 */
PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) /* keypad 3 */
PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD) /* keypad 4 */
PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD) /* keypad 5 */
PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) /* keypad 6 */
PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) /* keypad 7 */
PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) /* keypad 8 */
PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) /* keypad 9 */
PORT_BIT(0x1000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad *") PORT_CODE(KEYCODE_MINUS_PAD) /* keypad - */
PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD) /* keypad 0 */
PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_SPECIAL) PORT_NAME("Keypad #") PORT_CODE(KEYCODE_PLUS_PAD) /* keypad + */
INPUT_PORTS_END
@ -830,16 +812,13 @@ static MACHINE_CONFIG_START( mwskins, atlantis_state )
MCFG_IDE_PCI_IRQ_HANDLER(DEVWRITELINE(":", atlantis_state, ide_irq))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
MCFG_SCREEN_SIZE(320, 240)
MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239)
MCFG_SCREEN_UPDATE_DRIVER(atlantis_state, screen_update_mwskins)
MCFG_SCREEN_PALETTE("palette")
MCFG_DEVICE_ADD("zeus2", ZEUS2, MIDZEUS_VIDEO_CLOCK)
MCFG_ZEUS2_IRQ_CB(WRITELINE(atlantis_state, zeus_irq))
MCFG_ZEUS2_VBLANK_CB(WRITELINE(atlantis_state, vblank_irq))
MCFG_PALETTE_ADD_BBBBBGGGGGRRRRR("palette")
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(MIDZEUS_VIDEO_CLOCK / 4, 634, 0, 368, 560, 0, 512)
MCFG_SCREEN_UPDATE_DEVICE("zeus2", zeus2_device, screen_update)
/* sound hardware */
//MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_DSIO, 0)