mirror of
https://github.com/holub/mame
synced 2025-07-15 22:45:02 +03:00
(MESS) odyssey2, videopac: Updated drivers to use the i8244/i8245 device implementation. [Wilbert Pol]
This commit is contained in:
parent
9cb42d805f
commit
bd391081b7
@ -47,7 +47,7 @@ static ADDRESS_MAP_START( g7400_io , AS_IO, 8, odyssey2_state )
|
||||
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_read, p2_write)
|
||||
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_read, bus_write)
|
||||
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_read)
|
||||
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_read_g7400)
|
||||
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_read)
|
||||
AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_DEVWRITE("i8243", i8243_device, i8243_prog_w);
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -137,12 +137,6 @@ WRITE_LINE_MEMBER(odyssey2_state::irq_callback)
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::lum_write)
|
||||
{
|
||||
m_lum = ( data & 0x01 ) << 3;
|
||||
}
|
||||
|
||||
|
||||
WRITE16_MEMBER(odyssey2_state::scanline_postprocess)
|
||||
{
|
||||
int vpos = data;
|
||||
@ -156,7 +150,7 @@ WRITE16_MEMBER(odyssey2_state::scanline_postprocess)
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::t1_read_g7400)
|
||||
READ8_MEMBER(odyssey2_state::t1_read)
|
||||
{
|
||||
if ( m_i8244->vblank() || m_i8244->hblank() )
|
||||
{
|
||||
@ -166,6 +160,143 @@ READ8_MEMBER(odyssey2_state::t1_read_g7400)
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::p1_read)
|
||||
{
|
||||
UINT8 data = m_p1;
|
||||
|
||||
logerror("%.9f p1 read %.2x\n", machine().time().as_double(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::p1_write)
|
||||
{
|
||||
m_p1 = data;
|
||||
m_lum = ( data & 0x80 ) >> 4;
|
||||
|
||||
switch_banks();
|
||||
|
||||
logerror("%.6f p1 written %.2x\n", machine().time().as_double(), data);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::p2_read)
|
||||
{
|
||||
UINT8 h = 0xFF;
|
||||
int i, j;
|
||||
static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5" };
|
||||
|
||||
if (!(m_p1 & P1_KEYBOARD_SCAN_ENABLE))
|
||||
{
|
||||
if ((m_p2 & P2_KEYBOARD_SELECT_MASK) <= 5) /* read keyboard */
|
||||
{
|
||||
h &= ioport(keynames[m_p2 & P2_KEYBOARD_SELECT_MASK])->read();
|
||||
}
|
||||
|
||||
for (i= 0x80, j = 0; i > 0; i >>= 1, j++)
|
||||
{
|
||||
if (!(h & i))
|
||||
{
|
||||
m_p2 &= ~0x10; /* set key was pressed indicator */
|
||||
m_p2 = (m_p2 & ~0xE0) | (j << 5); /* column that was pressed */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (h == 0xFF) /* active low inputs, so no keypresses */
|
||||
{
|
||||
m_p2 = m_p2 | 0xF0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_p2 = m_p2 | 0xF0;
|
||||
}
|
||||
|
||||
logerror("%.6f p2 read %.2x\n", machine().time().as_double(), m_p2);
|
||||
return m_p2;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::p2_write)
|
||||
{
|
||||
m_p2 = data;
|
||||
|
||||
if ( m_i8243 )
|
||||
{
|
||||
m_i8243->i8243_p2_w( space, 0, m_p2 & 0x0f );
|
||||
}
|
||||
|
||||
logerror("%.6f p2 written %.2x\n", machine().time().as_double(), data);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::bus_read)
|
||||
{
|
||||
UINT8 data = 0xff;
|
||||
|
||||
if ((m_p2 & P2_KEYBOARD_SELECT_MASK) == 1)
|
||||
{
|
||||
data &= ioport("JOY0")->read(); /* read joystick 1 */
|
||||
}
|
||||
|
||||
if ((m_p2 & P2_KEYBOARD_SELECT_MASK) == 0)
|
||||
{
|
||||
data &= ioport("JOY1")->read(); /* read joystick 2 */
|
||||
}
|
||||
|
||||
logerror("%.6f bus read %.2x\n", machine().time().as_double(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::bus_write)
|
||||
{
|
||||
logerror("%.6f bus written %.2x\n", machine().time().as_double(), data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
i8243 in the g7400
|
||||
*/
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::i8243_port_w)
|
||||
{
|
||||
switch ( offset & 3 )
|
||||
{
|
||||
case 0: // "port 4"
|
||||
m_g7400_ic674_decode[4] = BIT(data,0);
|
||||
m_g7400_ic674_decode[5] = BIT(data,1);
|
||||
m_g7400_ic674_decode[6] = BIT(data,2);
|
||||
m_g7400_ic674_decode[7] = BIT(data,3);
|
||||
break;
|
||||
|
||||
case 1: // "port 5"
|
||||
m_g7400_ic674_decode[0] = BIT(data,0);
|
||||
m_g7400_ic674_decode[1] = BIT(data,1);
|
||||
m_g7400_ic674_decode[2] = BIT(data,2);
|
||||
m_g7400_ic674_decode[3] = BIT(data,3);
|
||||
break;
|
||||
|
||||
case 2: // "port 6"
|
||||
m_g7400_ic678_decode[4] = BIT(data,0);
|
||||
m_g7400_ic678_decode[5] = BIT(data,1);
|
||||
m_g7400_ic678_decode[6] = BIT(data,2);
|
||||
m_g7400_ic678_decode[7] = BIT(data,3);
|
||||
break;
|
||||
|
||||
case 3: // "port 7"
|
||||
m_g7400_ic678_decode[0] = BIT(data,0);
|
||||
m_g7400_ic678_decode[1] = BIT(data,1);
|
||||
m_g7400_ic678_decode[2] = BIT(data,2);
|
||||
m_g7400_ic678_decode[3] = BIT(data,3);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const gfx_layout odyssey2_graphicslayout =
|
||||
{
|
||||
8,1,
|
||||
@ -234,7 +365,7 @@ static MACHINE_CONFIG_START( odyssey2, odyssey2_state )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS( XTAL_7_15909MHz/2, I824X_LINE_CLOCKS, I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN, 262, I824X_START_Y, I824X_START_Y + I824X_SCREEN_HEIGHT )
|
||||
MCFG_SCREEN_RAW_PARAMS( XTAL_7_15909MHz/2, i8244_device::LINE_CLOCKS, i8244_device::START_ACTIVE_SCAN, i8244_device::END_ACTIVE_SCAN, i8244_device::LINES, i8244_device::START_Y, i8244_device::START_Y + i8244_device::SCREEN_HEIGHT )
|
||||
MCFG_SCREEN_UPDATE_DRIVER(odyssey2_state, screen_update_odyssey2)
|
||||
|
||||
MCFG_GFXDECODE( odyssey2 )
|
||||
@ -242,7 +373,7 @@ static MACHINE_CONFIG_START( odyssey2, odyssey2_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("custom", ODYSSEY2, XTAL_7_15909MHz/2)
|
||||
MCFG_I8244_ADD( "i8244", XTAL_17_73447MHz/5, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
|
||||
|
||||
MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
|
||||
@ -263,7 +394,7 @@ static MACHINE_CONFIG_START( videopac, odyssey2_state )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS( XTAL_17_73447MHz/5, I824X_LINE_CLOCKS, I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN, 312, I824X_START_Y, I824X_START_Y + I824X_SCREEN_HEIGHT )
|
||||
MCFG_SCREEN_RAW_PARAMS( XTAL_17_73447MHz/5, i8244_device::LINE_CLOCKS, i8244_device::START_ACTIVE_SCAN, i8244_device::END_ACTIVE_SCAN, i8245_device::LINES, i8244_device::START_Y, i8244_device::START_Y + i8244_device::SCREEN_HEIGHT )
|
||||
MCFG_SCREEN_UPDATE_DRIVER(odyssey2_state, screen_update_odyssey2)
|
||||
|
||||
MCFG_GFXDECODE( odyssey2 )
|
||||
@ -271,7 +402,7 @@ static MACHINE_CONFIG_START( videopac, odyssey2_state )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("custom", ODYSSEY2, XTAL_17_73447MHz/5)
|
||||
MCFG_I8245_ADD( "i8244", XTAL_17_73447MHz/5, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
|
||||
|
||||
MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000)
|
||||
@ -302,7 +433,7 @@ static MACHINE_CONFIG_START( g7400, odyssey2_state )
|
||||
MCFG_I8243_ADD( "i8243", NOOP, WRITE8(odyssey2_state,i8243_port_w))
|
||||
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_I8244_ADD( "i8244", 3540000, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
|
||||
MCFG_I8245_ADD( "i8244", 3540000, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) )
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
|
||||
|
||||
MCFG_FRAGMENT_ADD(odyssey2_cartslot)
|
||||
|
@ -20,44 +20,12 @@
|
||||
|
||||
#define P2_KEYBOARD_SELECT_MASK (0x07) /* select row to scan */
|
||||
|
||||
#define OLD_VDC_CONTROL_REG_STROBE_XY (0x02)
|
||||
|
||||
#define I824X_START_ACTIVE_SCAN 6
|
||||
#define I824X_END_ACTIVE_SCAN (6 + 160)
|
||||
#define I824X_START_Y 1
|
||||
#define I824X_SCREEN_HEIGHT 243
|
||||
#define I824X_LINE_CLOCKS 228
|
||||
|
||||
union o2_vdc_t {
|
||||
UINT8 reg[0x100];
|
||||
struct {
|
||||
struct {
|
||||
UINT8 y,x,color,res;
|
||||
} sprites[4];
|
||||
struct {
|
||||
UINT8 y,x,ptr,color;
|
||||
} foreground[12];
|
||||
struct {
|
||||
struct {
|
||||
UINT8 y,x,ptr,color;
|
||||
} single[4];
|
||||
} quad[4];
|
||||
UINT8 shape[4][8];
|
||||
UINT8 control;
|
||||
UINT8 status;
|
||||
UINT8 collision;
|
||||
UINT8 color;
|
||||
UINT8 y;
|
||||
UINT8 x;
|
||||
UINT8 res;
|
||||
UINT8 shift1,shift2,shift3;
|
||||
UINT8 sound;
|
||||
UINT8 res2[5+0x10];
|
||||
UINT8 hgrid[2][0x10];
|
||||
UINT8 vgrid[0x10];
|
||||
} s;
|
||||
};
|
||||
|
||||
struct ef9341_t
|
||||
{
|
||||
UINT8 TA;
|
||||
@ -89,26 +57,17 @@ public:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
optional_device<i8243_device> m_i8243;
|
||||
optional_device<i8244_device> m_i8244;
|
||||
required_device<i8244_device> m_i8244;
|
||||
|
||||
int m_the_voice_lrq_state;
|
||||
UINT8 *m_ram;
|
||||
UINT8 m_p1;
|
||||
UINT8 m_p2;
|
||||
size_t m_cart_size;
|
||||
o2_vdc_t m_o2_vdc;
|
||||
UINT32 m_o2_snd_shift[2];
|
||||
UINT8 m_x_beam_pos;
|
||||
UINT8 m_y_beam_pos;
|
||||
UINT8 m_control_status;
|
||||
UINT8 m_collision_status;
|
||||
int m_iff;
|
||||
bitmap_ind16 m_tmp_bitmap;
|
||||
int m_start_vpos;
|
||||
int m_start_vblank;
|
||||
UINT8 m_lum;
|
||||
sound_stream *m_sh_channel;
|
||||
UINT16 m_sh_count;
|
||||
DECLARE_READ8_MEMBER(t0_read);
|
||||
DECLARE_READ8_MEMBER(io_read);
|
||||
DECLARE_WRITE8_MEMBER(io_write);
|
||||
@ -120,11 +79,7 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(p1_write);
|
||||
DECLARE_READ8_MEMBER(p2_read);
|
||||
DECLARE_WRITE8_MEMBER(p2_write);
|
||||
DECLARE_READ8_MEMBER(video_read);
|
||||
DECLARE_WRITE8_MEMBER(video_write);
|
||||
DECLARE_WRITE8_MEMBER(lum_write);
|
||||
DECLARE_READ8_MEMBER(t1_read);
|
||||
DECLARE_READ8_MEMBER(t1_read_g7400);
|
||||
DECLARE_DRIVER_INIT(odyssey2);
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
@ -156,7 +111,6 @@ protected:
|
||||
// Calculate the external chargen address for a character and slice
|
||||
inline UINT16 external_chargen_address(UINT8 b, UINT8 slice);
|
||||
|
||||
void i824x_scanline(int vpos);
|
||||
void ef9340_scanline(int vpos);
|
||||
|
||||
/* timers */
|
||||
@ -171,29 +125,4 @@ protected:
|
||||
void switch_banks();
|
||||
};
|
||||
|
||||
|
||||
/*----------- defined in video/odyssey2.c -----------*/
|
||||
|
||||
|
||||
STREAM_UPDATE( odyssey2_sh_update );
|
||||
|
||||
class odyssey2_sound_device : public device_t,
|
||||
public device_sound_interface
|
||||
{
|
||||
public:
|
||||
odyssey2_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete();
|
||||
virtual void device_start();
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
private:
|
||||
// internal state
|
||||
};
|
||||
|
||||
extern const device_type ODYSSEY2;
|
||||
|
||||
|
||||
#endif /* ODYSSEY2_H_ */
|
||||
|
@ -97,6 +97,8 @@ void odyssey2_state::machine_start()
|
||||
|
||||
void odyssey2_state::machine_reset()
|
||||
{
|
||||
m_lum = 0;
|
||||
|
||||
/* jump to "last" bank, will work for all sizes due to being mirrored */
|
||||
m_p1 = 0xFF;
|
||||
m_p2 = 0xFF;
|
||||
@ -115,7 +117,7 @@ READ8_MEMBER(odyssey2_state::io_read)
|
||||
{
|
||||
if ((m_p1 & (P1_VDC_COPY_MODE_ENABLE | P1_VDC_ENABLE)) == 0)
|
||||
{
|
||||
return video_read(space, offset); /* seems to have higher priority than ram??? */
|
||||
return m_i8244->read(space, offset); /* seems to have higher priority than ram??? */
|
||||
}
|
||||
if (!(m_p1 & P1_EXT_RAM_ENABLE))
|
||||
{
|
||||
@ -146,7 +148,7 @@ WRITE8_MEMBER(odyssey2_state::io_write)
|
||||
}
|
||||
else if (!(m_p1 & P1_VDC_ENABLE))
|
||||
{
|
||||
video_write(space, offset, data);
|
||||
m_i8244->write(space, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,101 +188,3 @@ WRITE8_MEMBER(odyssey2_state::g7400_io_write)
|
||||
}
|
||||
}
|
||||
|
||||
/***** 8048 Ports ************************/
|
||||
|
||||
READ8_MEMBER(odyssey2_state::p1_read)
|
||||
{
|
||||
UINT8 data = m_p1;
|
||||
|
||||
logerror("%.9f p1 read %.2x\n", machine().time().as_double(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::p1_write)
|
||||
{
|
||||
m_p1 = data;
|
||||
|
||||
switch_banks();
|
||||
|
||||
lum_write(space, 0, m_p1 >> 7);
|
||||
|
||||
logerror("%.6f p1 written %.2x\n", machine().time().as_double(), data);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::p2_read)
|
||||
{
|
||||
UINT8 h = 0xFF;
|
||||
int i, j;
|
||||
static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5" };
|
||||
|
||||
if (!(m_p1 & P1_KEYBOARD_SCAN_ENABLE))
|
||||
{
|
||||
if ((m_p2 & P2_KEYBOARD_SELECT_MASK) <= 5) /* read keyboard */
|
||||
{
|
||||
h &= ioport(keynames[m_p2 & P2_KEYBOARD_SELECT_MASK])->read();
|
||||
}
|
||||
|
||||
for (i= 0x80, j = 0; i > 0; i >>= 1, j++)
|
||||
{
|
||||
if (!(h & i))
|
||||
{
|
||||
m_p2 &= ~0x10; /* set key was pressed indicator */
|
||||
m_p2 = (m_p2 & ~0xE0) | (j << 5); /* column that was pressed */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (h == 0xFF) /* active low inputs, so no keypresses */
|
||||
{
|
||||
m_p2 = m_p2 | 0xF0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_p2 = m_p2 | 0xF0;
|
||||
}
|
||||
|
||||
logerror("%.6f p2 read %.2x\n", machine().time().as_double(), m_p2);
|
||||
return m_p2;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::p2_write)
|
||||
{
|
||||
m_p2 = data;
|
||||
|
||||
if ( m_i8243 )
|
||||
{
|
||||
m_i8243->i8243_p2_w( space, 0, m_p2 & 0x0f );
|
||||
}
|
||||
|
||||
logerror("%.6f p2 written %.2x\n", machine().time().as_double(), data);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::bus_read)
|
||||
{
|
||||
UINT8 data = 0xff;
|
||||
|
||||
if ((m_p2 & P2_KEYBOARD_SELECT_MASK) == 1)
|
||||
{
|
||||
data &= ioport("JOY0")->read(); /* read joystick 1 */
|
||||
}
|
||||
|
||||
if ((m_p2 & P2_KEYBOARD_SELECT_MASK) == 0)
|
||||
{
|
||||
data &= ioport("JOY1")->read(); /* read joystick 2 */
|
||||
}
|
||||
|
||||
logerror("%.6f bus read %.2x\n", machine().time().as_double(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::bus_write)
|
||||
{
|
||||
logerror("%.6f bus written %.2x\n", machine().time().as_double(), data);
|
||||
}
|
||||
|
@ -74,72 +74,6 @@ const UINT8 odyssey2_colors[] =
|
||||
0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
static const UINT8 o2_shape[0x40][8]={
|
||||
{ 0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00 }, // 0
|
||||
{ 0x18,0x38,0x18,0x18,0x18,0x18,0x3C,0x00 },
|
||||
{ 0x3C,0x66,0x0C,0x18,0x30,0x60,0x7E,0x00 },
|
||||
{ 0x7C,0xC6,0x06,0x3C,0x06,0xC6,0x7C,0x00 },
|
||||
{ 0xCC,0xCC,0xCC,0xFE,0x0C,0x0C,0x0C,0x00 },
|
||||
{ 0xFE,0xC0,0xC0,0x7C,0x06,0xC6,0x7C,0x00 },
|
||||
{ 0x7C,0xC6,0xC0,0xFC,0xC6,0xC6,0x7C,0x00 },
|
||||
{ 0xFE,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00 },
|
||||
{ 0x7C,0xC6,0xC6,0x7C,0xC6,0xC6,0x7C,0x00 },
|
||||
{ 0x7C,0xC6,0xC6,0x7E,0x06,0xC6,0x7C,0x00 },
|
||||
{ 0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00 },
|
||||
{ 0x18,0x7E,0x58,0x7E,0x1A,0x7E,0x18,0x00 },
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||
{ 0x3C,0x66,0x0C,0x18,0x18,0x00,0x18,0x00 },
|
||||
{ 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFE,0x00 },
|
||||
{ 0xFC,0xC6,0xC6,0xFC,0xC0,0xC0,0xC0,0x00 },
|
||||
{ 0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00 },
|
||||
{ 0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00 },
|
||||
{ 0xFE,0xC0,0xC0,0xF8,0xC0,0xC0,0xFE,0x00 },
|
||||
{ 0xFC,0xC6,0xC6,0xFC,0xD8,0xCC,0xC6,0x00 },
|
||||
{ 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00 },
|
||||
{ 0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00 },
|
||||
{ 0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00 },
|
||||
{ 0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00 },
|
||||
{ 0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x76,0x00 },
|
||||
{ 0x7C,0xC6,0xC0,0x7C,0x06,0xC6,0x7C,0x00 },
|
||||
{ 0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0xFC,0x00 },
|
||||
{ 0xFE,0xC0,0xC0,0xF8,0xC0,0xC0,0xC0,0x00 },
|
||||
{ 0x7C,0xC6,0xC0,0xC0,0xCE,0xC6,0x7E,0x00 },
|
||||
{ 0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00 },
|
||||
{ 0x06,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00 },
|
||||
{ 0xC6,0xCC,0xD8,0xF0,0xD8,0xCC,0xC6,0x00 },
|
||||
{ 0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00 },
|
||||
{ 0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00 },
|
||||
{ 0xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0x00 },
|
||||
{ 0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00 },
|
||||
{ 0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00 },
|
||||
{ 0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00 },
|
||||
{ 0xC6,0xEE,0xFE,0xD6,0xC6,0xC6,0xC6,0x00 },
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00 },
|
||||
{ 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00 },
|
||||
{ 0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00 },
|
||||
{ 0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00 },
|
||||
{ 0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00 },
|
||||
{ 0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00 },
|
||||
{ 0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00 },
|
||||
{ 0x03,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00 },
|
||||
{ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00 },
|
||||
{ 0xCE,0xDB,0xDB,0xDB,0xDB,0xDB,0xCE,0x00 },
|
||||
{ 0x00,0x00,0x3C,0x7E,0x7E,0x7E,0x3C,0x00 },
|
||||
{ 0x1C,0x1C,0x18,0x1E,0x18,0x18,0x1C,0x00 },
|
||||
{ 0x1C,0x1C,0x18,0x1E,0x18,0x34,0x26,0x00 },
|
||||
{ 0x38,0x38,0x18,0x78,0x18,0x2C,0x64,0x00 },
|
||||
{ 0x38,0x38,0x18,0x78,0x18,0x18,0x38,0x00 },
|
||||
{ 0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00 },
|
||||
{ 0x18,0x3C,0x7E,0xFF,0xFF,0x18,0x18,0x00 },
|
||||
{ 0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x00 },
|
||||
{ 0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x00 },
|
||||
{ 0x38,0x38,0x12,0xFE,0xB8,0x28,0x6C,0x00 },
|
||||
{ 0xC0,0x60,0x30,0x18,0x0C,0x06,0x03,0x00 },
|
||||
{ 0x00,0x00,0x0C,0x08,0x08,0x7F,0x3E,0x00 },
|
||||
{ 0x00,0x03,0x63,0xFF,0xFF,0x18,0x08,0x00 },
|
||||
{ 0x00,0x00,0x00,0x10,0x38,0xFF,0x7E,0x00 }
|
||||
};
|
||||
|
||||
|
||||
void odyssey2_state::palette_init()
|
||||
{
|
||||
@ -152,399 +86,6 @@ void odyssey2_state::palette_init()
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::video_read)
|
||||
{
|
||||
UINT8 data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0xa1:
|
||||
data = m_control_status;
|
||||
m_iff = 0;
|
||||
m_maincpu->set_input_line(0, CLEAR_LINE);
|
||||
m_control_status &= ~ 0x08;
|
||||
if ( m_screen->hpos() < I824X_START_ACTIVE_SCAN || m_screen->hpos() > I824X_END_ACTIVE_SCAN )
|
||||
{
|
||||
data |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xa2:
|
||||
data = m_collision_status;
|
||||
m_collision_status = 0;
|
||||
break;
|
||||
|
||||
case 0xa4:
|
||||
if (m_o2_vdc.s.control & OLD_VDC_CONTROL_REG_STROBE_XY)
|
||||
{
|
||||
m_y_beam_pos = m_screen->vpos() - m_start_vpos;
|
||||
}
|
||||
|
||||
data = m_y_beam_pos;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 0xa5:
|
||||
|
||||
if ((m_o2_vdc.s.control & OLD_VDC_CONTROL_REG_STROBE_XY))
|
||||
{
|
||||
m_x_beam_pos = m_screen->hpos();
|
||||
if ( m_x_beam_pos < I824X_START_ACTIVE_SCAN )
|
||||
{
|
||||
m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN + I824X_LINE_CLOCKS;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN;
|
||||
}
|
||||
}
|
||||
|
||||
data = m_x_beam_pos;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
data = m_o2_vdc.reg[offset];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::video_write)
|
||||
{
|
||||
/* Update the sound */
|
||||
if( offset >= 0xa7 && offset <= 0xaa )
|
||||
m_sh_channel->update();
|
||||
|
||||
if (offset == 0xa0) {
|
||||
if ( m_o2_vdc.s.control & OLD_VDC_CONTROL_REG_STROBE_XY
|
||||
&& !(data & OLD_VDC_CONTROL_REG_STROBE_XY))
|
||||
{
|
||||
/* Toggling strobe bit, tuck away values */
|
||||
m_x_beam_pos = m_screen->hpos();
|
||||
if ( m_x_beam_pos < I824X_START_ACTIVE_SCAN )
|
||||
{
|
||||
m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN + 228;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN;
|
||||
}
|
||||
|
||||
m_y_beam_pos = m_screen->vpos() - m_start_vpos;
|
||||
}
|
||||
}
|
||||
|
||||
m_o2_vdc.reg[offset] = data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(odyssey2_state::t1_read)
|
||||
{
|
||||
if ( m_screen->vpos() > m_start_vpos && m_screen->vpos() < m_start_vblank )
|
||||
{
|
||||
if ( m_screen->hpos() >= I824X_START_ACTIVE_SCAN && m_screen->hpos() < I824X_END_ACTIVE_SCAN )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void odyssey2_state::i824x_scanline(int vpos)
|
||||
{
|
||||
UINT8 collision_map[160];
|
||||
|
||||
if ( vpos < m_start_vpos )
|
||||
return;
|
||||
|
||||
if ( vpos == m_start_vpos )
|
||||
{
|
||||
m_control_status &= ~0x08;
|
||||
}
|
||||
|
||||
if ( vpos < m_start_vblank )
|
||||
{
|
||||
rectangle rect;
|
||||
//static const int sprite_width[4] = { 8, 8, 8, 8 };
|
||||
int i;
|
||||
|
||||
m_control_status &= ~ 0x01;
|
||||
|
||||
/* Draw a line */
|
||||
rect.set(I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN - 1, vpos, vpos);
|
||||
m_tmp_bitmap.fill(( (m_o2_vdc.s.color >> 3) & 0x7 ) | ( ( m_lum << 3 ) ^ 0x08 ), rect );
|
||||
|
||||
/* Clear collision map */
|
||||
memset( collision_map, 0, sizeof( collision_map ) );
|
||||
|
||||
/* Display grid if enabled */
|
||||
if ( m_o2_vdc.s.control & 0x08 )
|
||||
{
|
||||
UINT16 color = ( m_o2_vdc.s.color & 7 ) | ( ( m_o2_vdc.s.color >> 3 ) & 0x08 ) | ( ( m_lum << 3 ) ^ 0x08 );
|
||||
int x_grid_offset = 8;
|
||||
int y_grid_offset = 24;
|
||||
int width = 16;
|
||||
int height = 24;
|
||||
int w = ( m_o2_vdc.s.control & 0x80 ) ? width : 2;
|
||||
int j, k, y;
|
||||
|
||||
/* Draw horizontal part of grid */
|
||||
for ( j = 1, y = 0; y < 9; y++, j <<= 1 )
|
||||
{
|
||||
if ( y_grid_offset + y * height <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y_grid_offset + y * height + 3 )
|
||||
{
|
||||
for ( i = 0; i < 9; i++ )
|
||||
{
|
||||
if ( ( m_o2_vdc.s.hgrid[0][i] & j ) || ( m_o2_vdc.s.hgrid[1][i] & ( j >> 8 ) ) )
|
||||
{
|
||||
for ( k = 0; k < width + 2; k++ )
|
||||
{
|
||||
int px = x_grid_offset + i * width + k;
|
||||
collision_map[ px ] |= COLLISION_HORIZ_GRID_DOTS;
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + px ) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw vertical part of grid */
|
||||
for( j = 1, y = 0; y < 8; y++, j <<= 1 )
|
||||
{
|
||||
if ( y_grid_offset + y * height <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y_grid_offset + ( y + 1 ) * height )
|
||||
{
|
||||
for ( i = 0; i < 10; i++ )
|
||||
{
|
||||
if ( m_o2_vdc.s.vgrid[i] & j )
|
||||
{
|
||||
for ( k = 0; k < w; k++ )
|
||||
{
|
||||
int px = x_grid_offset + i * width + k;
|
||||
|
||||
/* Check if we collide with an already drawn source object */
|
||||
if ( collision_map[ px ] & m_o2_vdc.s.collision )
|
||||
{
|
||||
m_collision_status |= COLLISION_VERTICAL_GRID;
|
||||
}
|
||||
/* Check if an already drawn object would collide with us */
|
||||
if ( COLLISION_VERTICAL_GRID & m_o2_vdc.s.collision && collision_map[ px ] )
|
||||
{
|
||||
m_collision_status |= collision_map[ px ];
|
||||
}
|
||||
collision_map[ px ] |= COLLISION_VERTICAL_GRID;
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + px ) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Display objects if enabled */
|
||||
if ( m_o2_vdc.s.control & 0x20 )
|
||||
{
|
||||
/* Regular foreground objects */
|
||||
for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.foreground ); i++ )
|
||||
{
|
||||
int y = m_o2_vdc.s.foreground[i].y;
|
||||
int height = 8 - ( ( ( y >> 1 ) + m_o2_vdc.s.foreground[i].ptr ) & 7 );
|
||||
|
||||
if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 )
|
||||
{
|
||||
UINT16 color = 16 + ( ( m_o2_vdc.s.foreground[i].color & 0x0E ) >> 1 );
|
||||
int offset = ( m_o2_vdc.s.foreground[i].ptr | ( ( m_o2_vdc.s.foreground[i].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - m_start_vpos - y ) >> 1 );
|
||||
UINT8 chr = ((char*)o2_shape)[ offset & 0x1FF ];
|
||||
int x = m_o2_vdc.s.foreground[i].x;
|
||||
UINT8 m;
|
||||
|
||||
for ( m = 0x80; m > 0; m >>= 1, x++ )
|
||||
{
|
||||
if ( chr & m )
|
||||
{
|
||||
if ( x >= 0 && x < 160 )
|
||||
{
|
||||
/* Check if we collide with an already drawn source object */
|
||||
if ( collision_map[ x ] & m_o2_vdc.s.collision )
|
||||
{
|
||||
m_collision_status |= COLLISION_CHARACTERS;
|
||||
}
|
||||
/* Check if an already drawn object would collide with us */
|
||||
if ( COLLISION_CHARACTERS & m_o2_vdc.s.collision && collision_map[ x ] )
|
||||
{
|
||||
m_collision_status |= collision_map[ x ];
|
||||
}
|
||||
collision_map[ x ] |= COLLISION_CHARACTERS;
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Quad objects */
|
||||
for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.quad ); i++ )
|
||||
{
|
||||
int y = m_o2_vdc.s.quad[i].single[0].y;
|
||||
int height = 8;
|
||||
|
||||
if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 )
|
||||
{
|
||||
int x = m_o2_vdc.s.quad[i].single[0].x;
|
||||
int j;
|
||||
|
||||
// Charaecter height is always determined by the height of the 4th character
|
||||
int char_height = 8 - ( ( ( y >> 1 ) + m_o2_vdc.s.quad[i].single[3].ptr ) & 7 );
|
||||
|
||||
for ( j = 0; j < ARRAY_LENGTH( m_o2_vdc.s.quad[0].single ); j++, x += 8 )
|
||||
{
|
||||
if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + char_height * 2 )
|
||||
{
|
||||
UINT16 color = 16 + ( ( m_o2_vdc.s.quad[i].single[j].color & 0x0E ) >> 1 );
|
||||
|
||||
|
||||
int offset = ( m_o2_vdc.s.quad[i].single[j].ptr | ( ( m_o2_vdc.s.quad[i].single[j].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - m_start_vpos - y ) >> 1 );
|
||||
|
||||
UINT8 chr = ((char*)o2_shape)[ offset & 0x1FF ];
|
||||
|
||||
UINT8 m;
|
||||
for ( m = 0x80; m > 0; m >>= 1, x++ )
|
||||
{
|
||||
if ( chr & m )
|
||||
{
|
||||
if ( x >= 0 && x < 160 )
|
||||
{
|
||||
/* Check if we collide with an already drawn source object */
|
||||
if ( collision_map[ x ] & m_o2_vdc.s.collision )
|
||||
{
|
||||
m_collision_status |= COLLISION_CHARACTERS;
|
||||
}
|
||||
/* Check if an already drawn object would collide with us */
|
||||
if ( COLLISION_CHARACTERS & m_o2_vdc.s.collision && collision_map[ x ] )
|
||||
{
|
||||
m_collision_status |= collision_map[ x ];
|
||||
}
|
||||
collision_map[ x ] |= COLLISION_CHARACTERS;
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sprites */
|
||||
for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.sprites ); i++ )
|
||||
{
|
||||
int y = m_o2_vdc.s.sprites[i].y;
|
||||
int height = 8;
|
||||
if ( m_o2_vdc.s.sprites[i].color & 4 )
|
||||
{
|
||||
/* Zoomed sprite */
|
||||
//sprite_width[i] = 16;
|
||||
if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 4 )
|
||||
{
|
||||
UINT16 color = 16 + ( ( m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 );
|
||||
UINT8 chr = m_o2_vdc.s.shape[i][ ( ( vpos - m_start_vpos - y ) >> 2 ) ];
|
||||
int x = m_o2_vdc.s.sprites[i].x;
|
||||
UINT8 m;
|
||||
|
||||
for ( m = 0x01; m > 0; m <<= 1, x += 2 )
|
||||
{
|
||||
if ( chr & m )
|
||||
{
|
||||
if ( x >= 0 && x < 160 )
|
||||
{
|
||||
/* Check if we collide with an already drawn source object */
|
||||
if ( collision_map[ x ] & m_o2_vdc.s.collision )
|
||||
{
|
||||
m_collision_status |= ( 1 << i );
|
||||
}
|
||||
/* Check if an already drawn object would collide with us */
|
||||
if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] )
|
||||
{
|
||||
m_collision_status |= collision_map[ x ];
|
||||
}
|
||||
collision_map[ x ] |= ( 1 << i );
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color;
|
||||
}
|
||||
if ( x >= -1 && x < 159 )
|
||||
{
|
||||
/* Check if we collide with an already drawn source object */
|
||||
if ( collision_map[ x ] & m_o2_vdc.s.collision )
|
||||
{
|
||||
m_collision_status |= ( 1 << i );
|
||||
}
|
||||
/* Check if an already drawn object would collide with us */
|
||||
if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] )
|
||||
{
|
||||
m_collision_status |= collision_map[ x ];
|
||||
}
|
||||
collision_map[ x ] |= ( 1 << i );
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x + 1 ) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Regular sprite */
|
||||
if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 )
|
||||
{
|
||||
UINT16 color = 16 + ( ( m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 );
|
||||
UINT8 chr = m_o2_vdc.s.shape[i][ ( ( vpos - m_start_vpos - y ) >> 1 ) ];
|
||||
int x = m_o2_vdc.s.sprites[i].x;
|
||||
UINT8 m;
|
||||
|
||||
for ( m = 0x01; m > 0; m <<= 1, x++ )
|
||||
{
|
||||
if ( chr & m )
|
||||
{
|
||||
if ( x >= 0 && x < 160 )
|
||||
{
|
||||
/* Check if we collide with an already drawn source object */
|
||||
if ( collision_map[ x ] & m_o2_vdc.s.collision )
|
||||
{
|
||||
m_collision_status |= ( 1 << i );
|
||||
}
|
||||
/* Check if an already drawn object would collide with us */
|
||||
if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] )
|
||||
{
|
||||
m_collision_status |= collision_map[ x ];
|
||||
}
|
||||
collision_map[ x ] |= ( 1 << i );
|
||||
m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for start of VBlank */
|
||||
if ( vpos == m_start_vblank )
|
||||
{
|
||||
m_control_status |= 0x08;
|
||||
if ( ! m_iff )
|
||||
{
|
||||
m_maincpu->set_input_line(0, ASSERT_LINE);
|
||||
m_iff = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
int vpos = m_screen->vpos();
|
||||
@ -552,8 +93,6 @@ void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
switch ( id )
|
||||
{
|
||||
case TIMER_LINE:
|
||||
// handle i824x line timer
|
||||
i824x_scanline(vpos);
|
||||
if ( m_g7400 )
|
||||
{
|
||||
ef9340_scanline(vpos);
|
||||
@ -561,16 +100,6 @@ void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
break;
|
||||
|
||||
case TIMER_HBLANK:
|
||||
// handle i824x HBlank timer
|
||||
if ( vpos < m_start_vpos - 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vpos < m_start_vblank - 1 )
|
||||
{
|
||||
m_control_status |= 0x01;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -584,25 +113,8 @@ void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
|
||||
void odyssey2_state::video_start()
|
||||
{
|
||||
memset(m_o2_vdc.reg, 0, 0x100);
|
||||
|
||||
m_o2_snd_shift[0] = m_o2_snd_shift[1] = 0;
|
||||
m_x_beam_pos = 0;
|
||||
m_y_beam_pos = 0;
|
||||
m_control_status = 0;
|
||||
m_collision_status = 0;
|
||||
m_iff = 0;
|
||||
m_start_vpos = 0;
|
||||
m_start_vblank = 0;
|
||||
m_lum = 0;
|
||||
|
||||
m_o2_snd_shift[0] = machine().sample_rate() / 983;
|
||||
m_o2_snd_shift[1] = machine().sample_rate() / 3933;
|
||||
|
||||
m_start_vpos = I824X_START_Y;
|
||||
m_start_vblank = I824X_START_Y + I824X_SCREEN_HEIGHT;
|
||||
m_control_status = 0;
|
||||
m_iff = 0;
|
||||
|
||||
m_screen->register_screen_bitmap(m_tmp_bitmap);
|
||||
|
||||
@ -639,116 +151,7 @@ void odyssey2_state::video_start_g7400()
|
||||
|
||||
UINT32 odyssey2_state::screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap( bitmap, m_tmp_bitmap, 0, 0, 0, 0, cliprect );
|
||||
|
||||
if ( m_i8244 )
|
||||
{
|
||||
return m_i8244->screen_update(screen, bitmap, cliprect);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_START( odyssey2_sound )
|
||||
{
|
||||
odyssey2_state *state = device->machine().driver_data<odyssey2_state>();
|
||||
state->m_sh_channel = device->machine().sound().stream_alloc(*device, 0, 1, device->clock()/(I824X_LINE_CLOCKS*4), 0, odyssey2_sh_update );
|
||||
}
|
||||
|
||||
|
||||
STREAM_UPDATE( odyssey2_sh_update )
|
||||
{
|
||||
odyssey2_state *state = device->machine().driver_data<odyssey2_state>();
|
||||
UINT32 old_signal, signal;
|
||||
int ii;
|
||||
int period;
|
||||
stream_sample_t *buffer = outputs[0];
|
||||
|
||||
/* Generate the signal */
|
||||
old_signal = signal = state->m_o2_vdc.s.shift3 | (state->m_o2_vdc.s.shift2 << 8) | (state->m_o2_vdc.s.shift1 << 16);
|
||||
|
||||
if( state->m_o2_vdc.s.sound & 0x80 ) /* Sound is enabled */
|
||||
{
|
||||
for( ii = 0; ii < samples; ii++, buffer++ )
|
||||
{
|
||||
*buffer = 0;
|
||||
*buffer = signal & 0x1;
|
||||
period = (state->m_o2_vdc.s.sound & 0x20) ? 1 : 4;
|
||||
if( ++state->m_sh_count >= period )
|
||||
{
|
||||
state->m_sh_count = 0;
|
||||
signal >>= 1;
|
||||
/* Loop sound */
|
||||
signal |= *buffer << 23;
|
||||
/* Check if noise should be applied */
|
||||
if ( state->m_o2_vdc.s.sound & 0x10 )
|
||||
{
|
||||
/* Noise tap is on bits 0 and 5 and fed back to bits 15 (and 23!) */
|
||||
UINT32 new_bit = ( ( old_signal ) ^ ( old_signal >> 5 ) ) & 0x01;
|
||||
signal = ( old_signal & 0xFF0000 ) | ( ( old_signal & 0xFFFF ) >> 1 ) | ( new_bit << 15 ) | ( new_bit << 23 );
|
||||
}
|
||||
state->m_o2_vdc.s.shift3 = signal & 0xFF;
|
||||
state->m_o2_vdc.s.shift2 = ( signal >> 8 ) & 0xFF;
|
||||
state->m_o2_vdc.s.shift1 = ( signal >> 16 ) & 0xFF;
|
||||
old_signal = signal;
|
||||
}
|
||||
|
||||
/* Throw an interrupt if enabled */
|
||||
if( state->m_o2_vdc.s.control & 0x4 )
|
||||
{
|
||||
state->m_maincpu->set_input_line(1, HOLD_LINE); /* Is this right? */
|
||||
}
|
||||
|
||||
/* Adjust volume */
|
||||
*buffer *= state->m_o2_vdc.s.sound & 0xf;
|
||||
/* Pump the volume up */
|
||||
*buffer <<= 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Sound disabled, so clear the buffer */
|
||||
for( ii = 0; ii < samples; ii++, buffer++ )
|
||||
*buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
i8243 in the g7400
|
||||
*/
|
||||
|
||||
WRITE8_MEMBER(odyssey2_state::i8243_port_w)
|
||||
{
|
||||
switch ( offset & 3 )
|
||||
{
|
||||
case 0: // "port 4"
|
||||
m_g7400_ic674_decode[4] = BIT(data,0);
|
||||
m_g7400_ic674_decode[5] = BIT(data,1);
|
||||
m_g7400_ic674_decode[6] = BIT(data,2);
|
||||
m_g7400_ic674_decode[7] = BIT(data,3);
|
||||
break;
|
||||
|
||||
case 1: // "port 5"
|
||||
m_g7400_ic674_decode[0] = BIT(data,0);
|
||||
m_g7400_ic674_decode[1] = BIT(data,1);
|
||||
m_g7400_ic674_decode[2] = BIT(data,2);
|
||||
m_g7400_ic674_decode[3] = BIT(data,3);
|
||||
break;
|
||||
|
||||
case 2: // "port 6"
|
||||
m_g7400_ic678_decode[4] = BIT(data,0);
|
||||
m_g7400_ic678_decode[5] = BIT(data,1);
|
||||
m_g7400_ic678_decode[6] = BIT(data,2);
|
||||
m_g7400_ic678_decode[7] = BIT(data,3);
|
||||
break;
|
||||
|
||||
case 3: // "port 7"
|
||||
m_g7400_ic678_decode[0] = BIT(data,0);
|
||||
m_g7400_ic678_decode[1] = BIT(data,1);
|
||||
m_g7400_ic678_decode[2] = BIT(data,2);
|
||||
m_g7400_ic678_decode[3] = BIT(data,3);
|
||||
break;
|
||||
|
||||
}
|
||||
return m_i8244->screen_update(screen, bitmap, cliprect);
|
||||
}
|
||||
|
||||
|
||||
@ -1007,40 +410,3 @@ void odyssey2_state::ef9340_scanline(int vpos)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const device_type ODYSSEY2 = &device_creator<odyssey2_sound_device>;
|
||||
|
||||
odyssey2_sound_device::odyssey2_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, ODYSSEY2, "P8244/P8245", tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void odyssey2_sound_device::device_config_complete()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void odyssey2_sound_device::device_start()
|
||||
{
|
||||
DEVICE_START_NAME( odyssey2_sound )(this);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - handle a stream update
|
||||
//-------------------------------------------------
|
||||
|
||||
void odyssey2_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// should never get here
|
||||
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user