Add INTREQ/INTACK to S2636, not used by any drivers yet

This commit is contained in:
Vas Crabb 2015-12-14 12:11:20 +11:00
parent 287041f333
commit 9484f593ca
8 changed files with 122 additions and 48 deletions

View File

@ -162,9 +162,12 @@ s2636_device::s2636_device(const machine_config &mconfig, const char *tag, devic
, m_divider(1)
, m_y_offset(0)
, m_x_offset(0)
, m_intreq_cb(*this)
, m_vrst(false)
, m_screen_line(0)
, m_vis_line(0)
, m_intreq(CLEAR_LINE)
, m_intack(CLEAR_LINE)
, m_stream(nullptr)
, m_sample_cnt(0)
, m_sound_lvl(false)
@ -187,19 +190,25 @@ void s2636_device::device_start()
save_item(NAME(m_registers));
save_item(NAME(m_obj_cnt));
save_item(NAME(m_obj_disp));
save_item(NAME(m_obj_dup));
save_item(NAME(m_vrst));
save_item(NAME(m_screen_line));
save_item(NAME(m_vis_line));
save_item(NAME(m_obj_cnt));
save_item(NAME(m_obj_disp));
save_item(NAME(m_obj_dup));
save_item(NAME(m_intreq));
save_item(NAME(m_intack));
m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate());
save_item(NAME(m_sample_cnt));
save_item(NAME(m_sound_lvl));
m_intreq_cb.resolve_safe();
}
//-------------------------------------------------
// backwards-compatible update method
//-------------------------------------------------
@ -215,6 +224,10 @@ bitmap_ind16 const &s2636_device::update(const rectangle &cliprect)
}
//-------------------------------------------------
// render the first line into the bitmap
//-------------------------------------------------
void s2636_device::render_first_line()
{
m_screen_line = 0;
@ -222,8 +235,14 @@ void s2636_device::render_first_line()
}
//-------------------------------------------------
// render next line into the bitmap
//-------------------------------------------------
void s2636_device::render_next_line()
{
assert(m_screen_line < m_bitmap.height());
// pre-clear the line for convenience
rectangle const &vis_area = m_screen->visible_area();
UINT16 *const row = &m_bitmap.pix16(m_screen_line);
@ -235,6 +254,7 @@ void s2636_device::render_next_line()
{
m_registers[REG_VBL_COL_OBJ] |= 0x40;
m_vrst = true;
update_intreq(ASSERT_LINE);
}
}
else
@ -254,9 +274,10 @@ void s2636_device::render_next_line()
m_registers[REG_COL_BG_CMPL] = 0x00;
m_registers[REG_VBL_COL_OBJ] = 0x00;
// set our internal tracking flags
// set our internal tracking flags and clear interrupt
m_vrst = false;
m_vis_line = 0;
update_intreq(CLEAR_LINE);
}
// work out what object pixels belong in this line
@ -295,6 +316,7 @@ void s2636_device::render_next_line()
m_obj_cnt[i] = 1 + m_registers[OFFS_OBJ[i] + OFFS_VCB];
m_obj_disp[i] = false;
m_obj_dup[i] = true;
update_intreq(ASSERT_LINE);
}
}
else
@ -381,7 +403,7 @@ void s2636_device::render_next_line()
// bus access handlers
//-------------------------------------------------
READ8_MEMBER( s2636_device::read )
READ8_MEMBER( s2636_device::read_data )
{
mask_offset(offset);
UINT8 data = m_registers[offset];
@ -399,7 +421,7 @@ READ8_MEMBER( s2636_device::read )
return data;
}
WRITE8_MEMBER( s2636_device::write )
WRITE8_MEMBER( s2636_device::write_data )
{
mask_offset(offset);
@ -409,6 +431,17 @@ WRITE8_MEMBER( s2636_device::write )
m_registers[offset] = data;
}
WRITE_LINE_MEMBER( s2636_device::write_intack )
{
assert((ASSERT_LINE == state) || (HOLD_LINE == state) || (CLEAR_LINE == state) || (PULSE_LINE == state));
// pretend interrupt acknowledge is handled instantaneously
m_intack = state;
update_intreq(m_intreq);
if (ASSERT_LINE != m_intreq)
m_intack = CLEAR_LINE;
}
//-------------------------------------------------
// sound_stream_update - generate audio output
@ -437,3 +470,14 @@ void s2636_device::sound_stream_update(sound_stream &stream, stream_sample_t **i
m_sample_cnt--;
}
}
void s2636_device::update_intreq(int value)
{
int const new_value = m_intack ? CLEAR_LINE : value;
if (new_value != m_intreq)
{
m_intreq = new_value;
m_intreq_cb(m_intreq);
}
}

View File

@ -13,12 +13,29 @@
#define S2636_IS_PIXEL_DRAWN(p) (((p) & 0x08) ? TRUE : FALSE)
#define S2636_PIXEL_COLOR(p) ((p) & 0x07)
/*************************************
*
* Device configuration macros
*
*************************************/
#define MCFG_S2636_OFFSETS(_yoffs, _xoffs) \
s2636_device::set_offsets(*device, _yoffs, _xoffs);
#define MCFG_S2636_DIVIDER(_divider) \
s2636_device::set_divider(*device, _divider);
#define MCFG_S2623_SET_INTREQ_CALLBACK(_devcb) \
devcb = &s2636_device::set_intreq_cb(*device, DEVCB_##_devcb);
/*************************************
*
* Device state class
*
*************************************/
class s2636_device : public device_t,
public device_video_interface,
public device_sound_interface
@ -40,6 +57,12 @@ public:
dev.m_divider = divider;
}
template<class _Object> static devcb_base &set_intreq_cb(device_t &device, _Object object)
{
s2636_device &dev = downcast<s2636_device &>(device);
return dev.m_intreq_cb.set_callback(object);
}
// returns a BITMAP_FORMAT_IND16 bitmap the size of the screen
// D0-D2 of each pixel is the pixel color
// D3 indicates how the S2636 drew this pixel - 0 = background, 1 = object/score
@ -53,8 +76,10 @@ public:
void render_first_line();
void render_next_line();
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_READ8_MEMBER( read_data );
DECLARE_WRITE8_MEMBER( write_data );
DECLARE_WRITE_LINE_MEMBER( write_intack );
protected:
// device-level overrides
@ -116,22 +141,35 @@ private:
UINT8 object_color(int obj) const { return (m_registers[REG_OBJ_CLR_1_2 + (obj >> 1)] >> ((obj & 1) ? 0 : 3)) & 0x07; }
UINT8 score_digit(int digit) const { return (m_registers[REG_SCORE_1_2 + (digit >> 1)] >> ((digit & 1) ? 0 : 4)) & 0x0f; }
int m_divider;
int m_y_offset;
int m_x_offset;
void update_intreq(int value);
bitmap_ind16 m_bitmap;
// Configuration
int m_divider;
int m_y_offset;
int m_x_offset;
UINT8 m_registers[0x100];
// interfacing with other devices
devcb_write_line m_intreq_cb;
bitmap_ind16 m_bitmap;
int m_obj_cnt[OBJ_COUNT];
bool m_obj_disp[OBJ_COUNT];
bool m_obj_dup[OBJ_COUNT];
// 256-byte register file (not all of this really exists)
UINT8 m_registers[0x100];
bool m_vrst;
int m_screen_line;
int m_vis_line;
// tracking where we're up to in the screen update
bool m_vrst;
int m_screen_line;
int m_vis_line;
// current display state of object
int m_obj_cnt[OBJ_COUNT];
bool m_obj_disp[OBJ_COUNT];
bool m_obj_dup[OBJ_COUNT];
// interrupt generation
int m_intreq;
int m_intack;
// sound generation state
sound_stream *m_stream;
int m_sample_cnt;
bool m_sound_lvl;
@ -139,12 +177,4 @@ private:
extern const device_type S2636;
#define MCFG_S2636_OFFSETS(_yoffs, _xoffs) \
s2636_device::set_offsets(*device, _yoffs, _xoffs);
#define MCFG_S2636_DIVIDER(_divider) \
s2636_device::set_divider(*device, _divider);
#endif /* __S2636_H__ */

View File

@ -155,7 +155,7 @@ READ8_MEMBER(cvs_state::cvs_s2636_0_or_character_ram_r)
if (m_s2650_flag)
return m_character_ram[(0 * 0x800) | 0x400 | m_character_ram_page_start | offset];
else
return m_s2636_0->read(space, offset);
return m_s2636_0->read_data(space, offset);
}
WRITE8_MEMBER(cvs_state::cvs_s2636_0_or_character_ram_w)
@ -167,7 +167,7 @@ WRITE8_MEMBER(cvs_state::cvs_s2636_0_or_character_ram_w)
m_gfxdecode->gfx(1)->mark_dirty((offset / 8) % 256);
}
else
m_s2636_0->write(space, offset, data);
m_s2636_0->write_data(space, offset, data);
}
@ -176,7 +176,7 @@ READ8_MEMBER(cvs_state::cvs_s2636_1_or_character_ram_r)
if (m_s2650_flag)
return m_character_ram[(1 * 0x800) | 0x400 | m_character_ram_page_start | offset];
else
return m_s2636_1->read(space, offset);
return m_s2636_1->read_data(space, offset);
}
WRITE8_MEMBER(cvs_state::cvs_s2636_1_or_character_ram_w)
@ -188,7 +188,7 @@ WRITE8_MEMBER(cvs_state::cvs_s2636_1_or_character_ram_w)
m_gfxdecode->gfx(1)->mark_dirty((offset / 8) % 256);
}
else
m_s2636_1->write(space, offset, data);
m_s2636_1->write_data(space, offset, data);
}
@ -197,7 +197,7 @@ READ8_MEMBER(cvs_state::cvs_s2636_2_or_character_ram_r)
if (m_s2650_flag)
return m_character_ram[(2 * 0x800) | 0x400 | m_character_ram_page_start | offset];
else
return m_s2636_2->read(space, offset);
return m_s2636_2->read_data(space, offset);
}
WRITE8_MEMBER(cvs_state::cvs_s2636_2_or_character_ram_w)
@ -209,7 +209,7 @@ WRITE8_MEMBER(cvs_state::cvs_s2636_2_or_character_ram_w)
m_gfxdecode->gfx(1)->mark_dirty((offset / 8) % 256);
}
else
m_s2636_2->write(space, offset, data);
m_s2636_2->write_data(space, offset, data);
}

View File

@ -130,9 +130,9 @@ READ8_MEMBER(galaxia_state::galaxia_collision_clear)
static ADDRESS_MAP_START( galaxia_mem_map, AS_PROGRAM, 8, galaxia_state )
AM_RANGE(0x0000, 0x13ff) AM_ROM
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("bullet_ram")
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read, write)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read, write)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_2", s2636_device, read, write)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read_data, write_data)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read_data, write_data)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_2", s2636_device, read_data, write_data)
AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_READ(cvs_video_or_color_ram_r) AM_WRITE(galaxia_video_w) AM_SHARE("video_ram")
AM_RANGE(0x1c00, 0x1fff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x2000, 0x33ff) AM_ROM
@ -142,7 +142,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( astrowar_mem_map, AS_PROGRAM, 8, galaxia_state )
AM_RANGE(0x0000, 0x13ff) AM_ROM
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read, write)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read_data, write_data)
AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_READ(cvs_video_or_color_ram_r) AM_WRITE(galaxia_video_w) AM_SHARE("video_ram")
AM_RANGE(0x1c00, 0x1cff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("bullet_ram")
AM_RANGE(0x2000, 0x33ff) AM_ROM

View File

@ -165,9 +165,9 @@ static ADDRESS_MAP_START( laserbat_map, AS_PROGRAM, 8, laserbat_state )
AM_RANGE(0x7800, 0x7bff) AM_ROM
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_WRITENOP // always 0 (bullet ram in Quasar)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read, write)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_2", s2636_device, read, write)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_3", s2636_device, read, write)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read_data, write_data)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_2", s2636_device, read_data, write_data)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_3", s2636_device, read_data, write_data)
AM_RANGE(0x1800, 0x1bff) AM_MIRROR(0x6000) AM_WRITE(laserbat_videoram_w)
AM_RANGE(0x1c00, 0x1fff) AM_MIRROR(0x6000) AM_RAM
ADDRESS_MAP_END

View File

@ -74,7 +74,7 @@
READ8_MEMBER(malzak_state::fake_VRLE_r)
{
return (m_s2636_0->read(space, 0xcb) & 0x3f) + (m_screen->vblank() * 0x40);
return (m_s2636_0->read_data(space, 0xcb) & 0x3f) + (m_screen->vblank() ? 0x40 : 0x00);
}
READ8_MEMBER(malzak_state::s2636_portA_r)
@ -106,8 +106,8 @@ static ADDRESS_MAP_START( malzak_map, AS_PROGRAM, 8, malzak_state )
AM_RANGE(0x1200, 0x12ff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x1300, 0x13ff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x14cb, 0x14cb) AM_MIRROR(0x6000) AM_READ(fake_VRLE_r)
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read, write)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read, write)
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read_data, write_data)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read_data, write_data)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_RAM_WRITE(malzak_playfield_w)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x1800, 0x1fff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("videoram")
@ -127,8 +127,8 @@ static ADDRESS_MAP_START( malzak2_map, AS_PROGRAM, 8, malzak_state )
AM_RANGE(0x1300, 0x13ff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x14cb, 0x14cb) AM_MIRROR(0x6000) AM_READ(fake_VRLE_r)
AM_RANGE(0x14cc, 0x14cc) AM_MIRROR(0x6000) AM_READ(s2636_portA_r)
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read, write)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read, write)
AM_RANGE(0x1400, 0x14ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_0", s2636_device, read_data, write_data)
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE("s2636_1", s2636_device, read_data, write_data)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_RAM_WRITE(malzak_playfield_w)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("nvram")
AM_RANGE(0x1800, 0x1fff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("videoram")

View File

@ -261,7 +261,7 @@ static ADDRESS_MAP_START( seabattl_map, AS_PROGRAM, 8, seabattl_state )
AM_RANGE(0x1e06, 0x1e06) AM_MIRROR(0x20f0) AM_READ_PORT("DIPS1") AM_WRITE(sound_w)
AM_RANGE(0x1e07, 0x1e07) AM_MIRROR(0x20f0) AM_READ_PORT("DIPS0") AM_WRITE(sound2_w)
AM_RANGE(0x1fcc, 0x1fcc) AM_MIRROR(0x2000) AM_READ_PORT("IN1")
AM_RANGE(0x1f00, 0x1fff) AM_MIRROR(0x2000) AM_DEVREADWRITE("s2636", s2636_device, read, write)
AM_RANGE(0x1f00, 0x1fff) AM_MIRROR(0x2000) AM_DEVREADWRITE("s2636", s2636_device, read_data, write_data)
ADDRESS_MAP_END
static ADDRESS_MAP_START( seabattl_io_map, AS_IO, 8, seabattl_state )

View File

@ -35,7 +35,7 @@ WRITE8_MEMBER(zac2650_state::zac_s2636_w)
m_gfxdecode->gfx(2)->mark_dirty(offset/8);
if (offset == 0xc7)
{
m_s2636->write(space, offset, data);
m_s2636->write_data(space, offset, data);
}
}