Previous 199869 Revisions Next

r19933 Saturday 29th December, 2012 at 22:21:42 UTC by Wilbert Pol
(MESS) odyssey2.c: Several small cleanups, no funcitonal changes. (nw)
[src/mess/drivers]odyssey2.c
[src/mess/includes]odyssey2.h
[src/mess/machine]odyssey2.c
[src/mess/video]odyssey2.c

trunk/src/mess/drivers/odyssey2.c
r19932r19933
77  Minor update to "the voice" rom names, and add comment about
88  the older revision of "the voice" - LN, 10/03/08
99
10  TODO:
11  - Reimplement the cartridge slot, and thus also the voice, as a slot device
12  - In case any more machines turn up using the i8245, reimplemnt it as a
13    real device.
14  - In case any more machines (TVs?) turn up using the EF9340 and/or EF9341,
15    reimplement as a real device.
16
1017***************************************************************************/
1118
1219#include "emu.h"
r19932r19933
1522#include "imagedev/cartslot.h"
1623#include "sound/sp0256.h"
1724
25
1826static ADDRESS_MAP_START( odyssey2_mem , AS_PROGRAM, 8, odyssey2_state )
19   AM_RANGE( 0x0000, 0x03FF) AM_ROM
20   AM_RANGE( 0x0400, 0x0BFF) AM_RAMBANK("bank1")
21   AM_RANGE( 0x0C00, 0x0FFF) AM_RAMBANK("bank2")
27   AM_RANGE(0x0000, 0x03FF) AM_ROM
28   AM_RANGE(0x0400, 0x0BFF) AM_RAMBANK("bank1")
29   AM_RANGE(0x0C00, 0x0FFF) AM_RAMBANK("bank2")
2230ADDRESS_MAP_END
2331
32
2433static ADDRESS_MAP_START( odyssey2_io , AS_IO, 8, odyssey2_state )
25   AM_RANGE( 0x00,       0xff)      AM_READWRITE(odyssey2_bus_r, odyssey2_bus_w)
26   AM_RANGE( MCS48_PORT_P1,   MCS48_PORT_P1)   AM_READWRITE(odyssey2_getp1, odyssey2_putp1 )
27   AM_RANGE( MCS48_PORT_P2,   MCS48_PORT_P2)   AM_READWRITE(odyssey2_getp2, odyssey2_putp2 )
28   AM_RANGE( MCS48_PORT_BUS,   MCS48_PORT_BUS)   AM_READWRITE(odyssey2_getbus, odyssey2_putbus )
29   AM_RANGE( MCS48_PORT_T0,   MCS48_PORT_T0)  AM_READ(odyssey2_t0_r )
30   AM_RANGE( MCS48_PORT_T1,   MCS48_PORT_T1)   AM_READ(odyssey2_t1_r )
34   AM_RANGE(0x00,           0xff)           AM_READWRITE(io_read, io_write)
35   AM_RANGE(MCS48_PORT_P1,  MCS48_PORT_P1)  AM_READWRITE(p1_read, p1_write)
36   AM_RANGE(MCS48_PORT_P2,  MCS48_PORT_P2)  AM_READWRITE(p2_read, p2_write)
37   AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_read, bus_write)
38   AM_RANGE(MCS48_PORT_T0,  MCS48_PORT_T0)  AM_READ(t0_read)
39   AM_RANGE(MCS48_PORT_T1,  MCS48_PORT_T1)  AM_READ(t1_read)
3140ADDRESS_MAP_END
3241
42
3343static ADDRESS_MAP_START( g7400_io , AS_IO, 8, odyssey2_state )
34   AM_RANGE( 0x00,      0xff)      AM_READWRITE(g7400_bus_r, g7400_bus_w)
35   AM_RANGE( MCS48_PORT_P1,   MCS48_PORT_P1)  AM_READWRITE(odyssey2_getp1, odyssey2_putp1 )
36   AM_RANGE( MCS48_PORT_P2,   MCS48_PORT_P2)  AM_READWRITE(odyssey2_getp2, odyssey2_putp2 )
37   AM_RANGE( MCS48_PORT_BUS,   MCS48_PORT_BUS) AM_READWRITE(odyssey2_getbus, odyssey2_putbus )
38   AM_RANGE( MCS48_PORT_T0,   MCS48_PORT_T0)  AM_READ(odyssey2_t0_r )
39   AM_RANGE( MCS48_PORT_T1,   MCS48_PORT_T1)  AM_READ(odyssey2_t1_r )
40   //AM_RANGE( MCS_MCS48_PORT_PROG, MCS48_PORT_PROG ) //write to 8243 with low four bits from P2
44   AM_RANGE(0x00,            0xff)            AM_READWRITE(g7400_io_read, g7400_io_write)
45   AM_RANGE(MCS48_PORT_P1,   MCS48_PORT_P1)   AM_READWRITE(p1_read, p1_write)
46   AM_RANGE(MCS48_PORT_P2,   MCS48_PORT_P2)   AM_READWRITE(p2_read, p2_write)
47   AM_RANGE(MCS48_PORT_BUS,  MCS48_PORT_BUS)  AM_READWRITE(bus_read, bus_write)
48   AM_RANGE(MCS48_PORT_T0,   MCS48_PORT_T0)   AM_READ(t0_read)
49   AM_RANGE(MCS48_PORT_T1,   MCS48_PORT_T1)   AM_READ(t1_read)
50   //AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) //write to 8243 with low four bits from P2
4151ADDRESS_MAP_END
4252
53
4354static INPUT_PORTS_START( odyssey2 )
4455   PORT_START("KEY0")      /* IN0 */
4556   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
r19932r19933
118129   PORT_BIT( 0xe0, 0xe0,    IPT_UNUSED )
119130INPUT_PORTS_END
120131
132
121133static const gfx_layout odyssey2_graphicslayout =
122134{
123135   8,1,
r19932r19933
156168   1*8
157169};
158170
171
159172static GFXDECODE_START( odyssey2 )
160173   GFXDECODE_ENTRY( "gfx1", 0x0000, odyssey2_graphicslayout, 0, 2 )
161174   GFXDECODE_ENTRY( "gfx1", 0x0000, odyssey2_spritelayout, 0, 2 )
162175GFXDECODE_END
163176
177
164178static const sp0256_interface the_voice_sp0256 =
165179{
166   DEVCB_LINE(odyssey2_the_voice_lrq_callback),
180   DEVCB_DRIVER_LINE_MEMBER(odyssey2_state,the_voice_lrq_callback),
167181   DEVCB_NULL
168182};
169183
184
170185static MACHINE_CONFIG_FRAGMENT( odyssey2_cartslot )
171186   MCFG_CARTSLOT_ADD("cart")
172187   MCFG_CARTSLOT_EXTENSION_LIST("bin,rom")
173188   MCFG_CARTSLOT_NOT_MANDATORY
174189MACHINE_CONFIG_END
175190
191
176192static MACHINE_CONFIG_START( odyssey2, odyssey2_state )
177193   /* basic machine hardware */
178194   MCFG_CPU_ADD("maincpu", I8048, ( ( XTAL_7_15909MHz * 3 ) / 4 ) )
r19932r19933
180196   MCFG_CPU_IO_MAP(odyssey2_io)
181197   MCFG_QUANTUM_TIME(attotime::from_hz(60))
182198
183
184199    /* video hardware */
185200   MCFG_SCREEN_ADD("screen", RASTER)
186201   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 )
r19932r19933
189204   MCFG_GFXDECODE( odyssey2 )
190205   MCFG_PALETTE_LENGTH(24)
191206
192
193207   /* sound hardware */
194208   MCFG_SPEAKER_STANDARD_MONO("mono")
195209   MCFG_SOUND_ADD("custom", ODYSSEY2, XTAL_7_15909MHz/2)
r19932r19933
203217   MCFG_FRAGMENT_ADD(odyssey2_cartslot)
204218MACHINE_CONFIG_END
205219
220
206221static MACHINE_CONFIG_START( videopac, odyssey2_state )
207222   /* basic machine hardware */
208223   MCFG_CPU_ADD("maincpu", I8048, ( XTAL_17_73447MHz / 3 ) )
r19932r19933
210225   MCFG_CPU_IO_MAP(odyssey2_io)
211226   MCFG_QUANTUM_TIME(attotime::from_hz(60))
212227
213
214228   /* video hardware */
215229   MCFG_SCREEN_ADD("screen", RASTER)
216230   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 )
r19932r19933
219233   MCFG_GFXDECODE( odyssey2 )
220234   MCFG_PALETTE_LENGTH(24)
221235
222
223236   /* sound hardware */
224237   MCFG_SPEAKER_STANDARD_MONO("mono")
225238   MCFG_SOUND_ADD("custom", ODYSSEY2, XTAL_17_73447MHz/5)
r19932r19933
232245   MCFG_FRAGMENT_ADD(odyssey2_cartslot)
233246MACHINE_CONFIG_END
234247
248
235249static MACHINE_CONFIG_START( g7400, odyssey2_state )
236250   /* basic machine hardware */
237251   MCFG_CPU_ADD("maincpu", I8048, XTAL_5_911MHz )
r19932r19933
239253   MCFG_CPU_IO_MAP(g7400_io)
240254   MCFG_QUANTUM_TIME(attotime::from_hz(60))
241255
242
243256   /* video hardware */
244257   MCFG_SCREEN_ADD("screen", RASTER)
245   MCFG_SCREEN_RAW_PARAMS( 3547000*2, 448, 96, 416, 312, 39, 289 )   /* EF9340 doubles the input clock into dot clocks internally */
258   MCFG_SCREEN_RAW_PARAMS( 3547000*2, 2*I824X_LINE_CLOCKS, 2*I824X_START_ACTIVE_SCAN, 2*I824X_END_ACTIVE_SCAN, 312, I824X_START_Y, I824X_START_Y + I824X_SCREEN_HEIGHT )
246259   MCFG_SCREEN_UPDATE_DRIVER(odyssey2_state, screen_update_odyssey2)
247260
261   MCFG_VIDEO_START_OVERRIDE(odyssey2_state,g7400)
262
248263   MCFG_GFXDECODE( odyssey2 )
249264   MCFG_PALETTE_LENGTH(24)
250265
251
252266   /* sound hardware */
253267   MCFG_SPEAKER_STANDARD_MONO("mono")
254268   MCFG_SOUND_ADD("custom", ODYSSEY2, 3547000)
r19932r19933
257271   MCFG_FRAGMENT_ADD(odyssey2_cartslot)
258272MACHINE_CONFIG_END
259273
274
260275ROM_START (odyssey2)
261276    ROM_REGION(0x10000,"maincpu",0)    /* safer for the memory handler/bankswitching??? */
262277    ROM_LOAD ("o2bios.rom", 0x0000, 0x0400, CRC(8016a315) SHA1(b2e1955d957a475de2411770452eff4ea19f4cee))
r19932r19933
283298   ROM_LOAD( "spr128-004.bin",   0x8000, 0x4000, CRC(e79dfb75) SHA1(37f33d79ffd1739d7c2f226b010a1eac28d74ca0) )
284299ROM_END
285300
301
286302ROM_START (videopac)
287303   ROM_REGION(0x10000,"maincpu",0)    /* safer for the memory handler/bankswitching??? */
288304   ROM_SYSTEM_BIOS( 0, "g7000", "g7000" )
r19932r19933
303319   ROM_LOAD( "spr128-004.bin",   0x8000, 0x4000, CRC(e79dfb75) SHA1(37f33d79ffd1739d7c2f226b010a1eac28d74ca0) )
304320ROM_END
305321
322
306323ROM_START (g7400)
307324   ROM_REGION(0x10000,"maincpu",0)    /* safer for the memory handler/bankswitching??? */
308325   ROM_LOAD ("g7400.bin", 0x0000, 0x0400, CRC(e20a9f41) SHA1(5130243429b40b01a14e1304d0394b8459a6fbae))
r19932r19933
312329   ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_MIRROR)
313330ROM_END
314331
332
315333ROM_START (jopac)
316334   ROM_REGION(0x10000,"maincpu",0)    /* safer for the memory handler/bankswitching??? */
317335   ROM_LOAD ("jopac.bin", 0x0000, 0x0400, CRC(11647ca5) SHA1(54b8d2c1317628de51a85fc1c424423a986775e4))
r19932r19933
321339   ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_MIRROR)
322340ROM_END
323341
342
324343/*     YEAR  NAME      PARENT   COMPAT  MACHINE   INPUT     INIT      COMPANY     FULLNAME     FLAGS */
325344COMP( 1978, odyssey2, 0,      0,      odyssey2, odyssey2, odyssey2_state, odyssey2, "Magnavox", "Odyssey 2", 0 )
326345COMP( 1979, videopac, odyssey2,   0,      videopac, odyssey2, odyssey2_state, odyssey2, "Philips", "Videopac G7000/C52", 0 )
trunk/src/mess/machine/odyssey2.c
r19932r19933
1313
1414
1515
16static void odyssey2_switch_banks(running_machine &machine)
16void odyssey2_state::switch_banks()
1717{
18   odyssey2_state *state = machine.driver_data<odyssey2_state>();
19   switch ( state->m_cart_size )
18   switch ( m_cart_size )
2019   {
2120      case 12288:
2221         /* 12KB cart support (for instance, KTAA as released) */
23         state->membank( "bank1" )->set_base( machine.root_device().memregion("user1")->base() + (state->m_p1 & 0x03) * 0xC00 );
24         state->membank( "bank2" )->set_base( machine.root_device().memregion("user1")->base() + (state->m_p1 & 0x03) * 0xC00 + 0x800 );
22         membank( "bank1" )->set_base( memregion("user1")->base() + (m_p1 & 0x03) * 0xC00 );
23         membank( "bank2" )->set_base( memregion("user1")->base() + (m_p1 & 0x03) * 0xC00 + 0x800 );
2524         break;
2625
2726      case 16384:
2827         /* 16KB cart support (for instance, full sized version KTAA) */
29         state->membank( "bank1" )->set_base( machine.root_device().memregion("user1")->base() + (state->m_p1 & 0x03) * 0x1000 + 0x400 );
30         state->membank( "bank2" )->set_base( machine.root_device().memregion("user1")->base() + (state->m_p1 & 0x03) * 0x1000 + 0xC00 );
28         membank( "bank1" )->set_base( memregion("user1")->base() + (m_p1 & 0x03) * 0x1000 + 0x400 );
29         membank( "bank2" )->set_base( memregion("user1")->base() + (m_p1 & 0x03) * 0x1000 + 0xC00 );
3130         break;
3231
3332      default:
34         state->membank("bank1")->set_base(machine.root_device().memregion("user1")->base() + (state->m_p1 & 0x03) * 0x800);
35         state->membank("bank2")->set_base(state->memregion("user1")->base() + (state->m_p1 & 0x03) * 0x800 );
33         membank("bank1")->set_base(memregion("user1")->base() + (m_p1 & 0x03) * 0x800);
34         membank("bank2")->set_base(memregion("user1")->base() + (m_p1 & 0x03) * 0x800 );
3635         break;
3736   }
3837}
3938
40void odyssey2_the_voice_lrq_callback(device_t *device, int state)
39
40WRITE_LINE_MEMBER(odyssey2_state::the_voice_lrq_callback)
4141{
42   odyssey2_state *drvstate = device->machine().driver_data<odyssey2_state>();
43   drvstate->m_the_voice_lrq_state = state;
42   m_the_voice_lrq_state = state;
4443}
4544
46READ8_MEMBER(odyssey2_state::odyssey2_t0_r)
45
46READ8_MEMBER(odyssey2_state::t0_read)
4747{
4848   return ( m_the_voice_lrq_state == ASSERT_LINE ) ? 0 : 1;
4949}
5050
51
5152DRIVER_INIT_MEMBER(odyssey2_state,odyssey2)
5253{
5354   int i;
r19932r19933
7778   m_cart_size = size;
7879}
7980
81
8082void odyssey2_state::machine_reset()
8183{
8284   /* jump to "last" bank, will work for all sizes due to being mirrored */
8385   m_p1 = 0xFF;
8486   m_p2 = 0xFF;
85   odyssey2_switch_banks(machine());
87   switch_banks();
8688}
8789
8890/****** External RAM ******************************/
8991
90READ8_MEMBER(odyssey2_state::odyssey2_bus_r)
92READ8_MEMBER(odyssey2_state::io_read)
9193{
9294   if ((m_p1 & (P1_VDC_COPY_MODE_ENABLE | P1_VDC_ENABLE)) == 0)
9395   {
94      return odyssey2_video_r(space, offset); /* seems to have higher priority than ram??? */
96      return video_read(space, offset); /* seems to have higher priority than ram??? */
9597   }
9698   if (!(m_p1 & P1_EXT_RAM_ENABLE))
9799   {
r19932r19933
101103   return 0;
102104}
103105
104WRITE8_MEMBER(odyssey2_state::odyssey2_bus_w)
106
107WRITE8_MEMBER(odyssey2_state::io_write)
105108{
106109   if ((m_p1 & (P1_EXT_RAM_ENABLE | P1_VDC_COPY_MODE_ENABLE)) == 0x00)
107110   {
r19932r19933
121124   }
122125   else if (!(m_p1 & P1_VDC_ENABLE))
123126   {
124      odyssey2_video_w(space, offset, data);
127      video_write(space, offset, data);
125128   }
126129}
127130
128READ8_MEMBER(odyssey2_state::g7400_bus_r)
131
132READ8_MEMBER(odyssey2_state::g7400_io_read)
129133{
130134   if ((m_p1 & (P1_VDC_COPY_MODE_ENABLE | P1_VDC_ENABLE)) == 0)
131135   {
132      return odyssey2_video_r(space, offset); /* seems to have higher priority than ram??? */
136      return video_read(space, offset); /* seems to have higher priority than ram??? */
133137   }
134138   else if (!(m_p1 & P1_EXT_RAM_ENABLE))
135139   {
r19932r19933
137141   }
138142   else
139143   {
140      //return ef9341_r( offset & 0x02, offset & 0x01 );
144      return ef9341_r( offset & 0x02, offset & 0x01 );
141145   }
142146
143147   return 0;
144148}
145149
146WRITE8_MEMBER(odyssey2_state::g7400_bus_w)
150
151WRITE8_MEMBER(odyssey2_state::g7400_io_write)
147152{
148153   if ((m_p1 & (P1_EXT_RAM_ENABLE | P1_VDC_COPY_MODE_ENABLE)) == 0x00)
149154   {
r19932r19933
151156   }
152157   else if (!(m_p1 & P1_VDC_ENABLE))
153158   {
154      odyssey2_video_w(space, offset, data);
159      video_write(space, offset, data);
155160   }
156161   else
157162   {
158      //ef9341_w( offset & 0x02, offset & 0x01, data );
163      ef9341_w( offset & 0x02, offset & 0x01, data );
159164   }
160165}
161166
162167/***** 8048 Ports ************************/
163168
164READ8_MEMBER(odyssey2_state::odyssey2_getp1)
169READ8_MEMBER(odyssey2_state::p1_read)
165170{
166171   UINT8 data = m_p1;
167172
r19932r19933
169174   return data;
170175}
171176
172WRITE8_MEMBER(odyssey2_state::odyssey2_putp1)
177
178WRITE8_MEMBER(odyssey2_state::p1_write)
173179{
174180   m_p1 = data;
175181
176   odyssey2_switch_banks(machine());
182   switch_banks();
177183
178   odyssey2_lum_w ( space, 0, m_p1 >> 7 );
184   lum_write(space, 0, m_p1 >> 7);
179185
180186   logerror("%.6f p1 written %.2x\n", machine().time().as_double(), data);
181187}
182188
183READ8_MEMBER(odyssey2_state::odyssey2_getp2)
189
190READ8_MEMBER(odyssey2_state::p2_read)
184191{
185192   UINT8 h = 0xFF;
186193   int i, j;
r19932r19933
218225   return m_p2;
219226}
220227
221WRITE8_MEMBER(odyssey2_state::odyssey2_putp2)
228
229WRITE8_MEMBER(odyssey2_state::p2_write)
222230{
223231   m_p2 = data;
224232
225233   logerror("%.6f p2 written %.2x\n", machine().time().as_double(), data);
226234}
227235
228READ8_MEMBER(odyssey2_state::odyssey2_getbus)
236
237READ8_MEMBER(odyssey2_state::bus_read)
229238{
230239   UINT8 data = 0xff;
231240
r19932r19933
243252   return data;
244253}
245254
246WRITE8_MEMBER(odyssey2_state::odyssey2_putbus)
255
256WRITE8_MEMBER(odyssey2_state::bus_write)
247257{
248258   logerror("%.6f bus written %.2x\n", machine().time().as_double(), data);
249259}
250260
251///////////////////////////////////
252
253#ifdef UNUSED_FUNCTION
254int odyssey2_cart_verify(const UINT8 *cartdata, size_t size)
255{
256   odyssey2_state *state = machine.driver_data<odyssey2_state>();
257   state->m_cart_size = size;
258   if (   (size == 2048)
259       || (size == 4096)
260       || (size == 8192)
261      || (size == 12288)
262      || (size == 16384))
263   {
264      return IMAGE_VERIFY_PASS;
265   }
266
267   return IMAGE_VERIFY_FAIL;
268}
269#endif
trunk/src/mess/includes/odyssey2.h
r19932r19933
5656
5757struct ef9341_t
5858{
59   UINT8   TA;
60   UINT8   TB;
61   UINT8   busy;
62};
63
64struct ef9340_t
65{
5966   UINT8   X;
6067   UINT8   Y;
6168   UINT8   Y0;
6269   UINT8   R;
6370   UINT8   M;
64   UINT8   TA;
65   UINT8   TB;
66   UINT8   busy;
67   UINT8   ram[1024];
6871};
6972
70
7173class odyssey2_state : public driver_device
7274{
7375public:
7476   odyssey2_state(const machine_config &mconfig, device_type type, const char *tag)
75      : driver_device(mconfig, type, tag) { }
77      : driver_device(mconfig, type, tag)
78      , m_maincpu(*this, "maincpu")
79      , m_screen(*this, "screen")
80      , m_g7400(false)
81      { }
7682
83   required_device<cpu_device> m_maincpu;
84   required_device<screen_device> m_screen;
85
7786   int m_the_voice_lrq_state;
7887   UINT8 *m_ram;
7988   UINT8 m_p1;
r19932r19933
8695   UINT8 m_control_status;
8796   UINT8 m_collision_status;
8897   int m_iff;
89   emu_timer *m_i824x_line_timer;
90   emu_timer *m_i824x_hblank_timer;
9198   bitmap_ind16 m_tmp_bitmap;
9299   int m_start_vpos;
93100   int m_start_vblank;
94101   UINT8 m_lum;
95102   sound_stream *m_sh_channel;
96103   UINT16 m_sh_count;
97   //ef9341_t ef9341;
98   DECLARE_READ8_MEMBER(odyssey2_t0_r);
99   DECLARE_READ8_MEMBER(odyssey2_bus_r);
100   DECLARE_WRITE8_MEMBER(odyssey2_bus_w);
101   DECLARE_READ8_MEMBER(g7400_bus_r);
102   DECLARE_WRITE8_MEMBER(g7400_bus_w);
103   DECLARE_READ8_MEMBER(odyssey2_getp1);
104   DECLARE_WRITE8_MEMBER(odyssey2_putp1);
105   DECLARE_READ8_MEMBER(odyssey2_getp2);
106   DECLARE_WRITE8_MEMBER(odyssey2_putp2);
107   DECLARE_READ8_MEMBER(odyssey2_getbus);
108   DECLARE_WRITE8_MEMBER(odyssey2_putbus);
109   DECLARE_READ8_MEMBER(odyssey2_video_r);
110   DECLARE_WRITE8_MEMBER(odyssey2_video_w);
111   DECLARE_WRITE8_MEMBER(odyssey2_lum_w);
112   DECLARE_READ8_MEMBER(odyssey2_t1_r);
104   DECLARE_READ8_MEMBER(t0_read);
105   DECLARE_READ8_MEMBER(io_read);
106   DECLARE_WRITE8_MEMBER(io_write);
107   DECLARE_READ8_MEMBER(bus_read);
108   DECLARE_WRITE8_MEMBER(bus_write);
109   DECLARE_READ8_MEMBER(g7400_io_read);
110   DECLARE_WRITE8_MEMBER(g7400_io_write);
111   DECLARE_READ8_MEMBER(p1_read);
112   DECLARE_WRITE8_MEMBER(p1_write);
113   DECLARE_READ8_MEMBER(p2_read);
114   DECLARE_WRITE8_MEMBER(p2_write);
115   DECLARE_READ8_MEMBER(video_read);
116   DECLARE_WRITE8_MEMBER(video_write);
117   DECLARE_WRITE8_MEMBER(lum_write);
118   DECLARE_READ8_MEMBER(t1_read);
113119   DECLARE_DRIVER_INIT(odyssey2);
114120   virtual void machine_reset();
115121   virtual void video_start();
122   void video_start_g7400();
116123   virtual void palette_init();
117124   UINT32 screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
118   TIMER_CALLBACK_MEMBER(i824x_scanline_callback);
119   TIMER_CALLBACK_MEMBER(i824x_hblank_callback);
120};
125   DECLARE_WRITE_LINE_MEMBER(the_voice_lrq_callback);
121126
127   void ef9341_w( UINT8 command, UINT8 b, UINT8 data );
128   UINT8 ef9341_r( UINT8 command, UINT8 b );
122129
123/*----------- defined in video/odyssey2.c -----------*/
130protected:
131   ef9340_t m_ef9340;
132   ef9341_t m_ef9341;
133   UINT8   m_ef934x_ram_a[1024];
134   UINT8   m_ef934x_ram_b[1024];
135   bool   m_g7400;
124136
125extern const UINT8 odyssey2_colors[];
137   inline UINT16 ef9340_get_c_addr();
138   inline void ef9340_inc_c();
126139
140   void i824x_scanline(int vpos);
141   void er9340_scanline(int vpos);
127142
143   /* timers */
144   static const device_timer_id TIMER_LINE = 0;
145   static const device_timer_id TIMER_HBLANK = 1;
128146
147   emu_timer *m_line_timer;
148   emu_timer *m_hblank_timer;
129149
150   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
130151
152   void switch_banks();
153};
154
155
156/*----------- defined in video/odyssey2.c -----------*/
157
158
131159STREAM_UPDATE( odyssey2_sh_update );
132160
133void odyssey2_ef9341_w( running_machine &machine, int command, int b, UINT8 data );
134UINT8 odyssey2_ef9341_r( running_machine &machine, int command, int b );
135
136161class odyssey2_sound_device : public device_t,
137162                                  public device_sound_interface
138163{
r19932r19933
152177extern const device_type ODYSSEY2;
153178
154179
155/*----------- defined in machine/odyssey2.c -----------*/
156
157
158
159/* i/o ports */
160
161
162
163
164void odyssey2_the_voice_lrq_callback( device_t *device, int state );
165
166
167int odyssey2_cart_verify(const UINT8 *cartdata, size_t size);
168
169
170180#endif /* ODYSSEY2_H_ */
trunk/src/mess/video/odyssey2.c
r19932r19933
130130};
131131
132132
133
134
135133void odyssey2_state::palette_init()
136134{
137135   int i;
r19932r19933
142140   }
143141}
144142
145READ8_MEMBER(odyssey2_state::odyssey2_video_r)
143
144READ8_MEMBER(odyssey2_state::video_read)
146145{
147    UINT8 data = 0;
146   UINT8 data = 0;
148147
149    switch (offset)
150    {
151        case 0xa1:
148   switch (offset)
149   {
150      case 0xa1:
152151         data = m_control_status;
153152         m_iff = 0;
154         machine().device("maincpu")->execute().set_input_line(0, CLEAR_LINE);
153         m_maincpu->set_input_line(0, CLEAR_LINE);
155154         m_control_status &= ~ 0x08;
156         if ( machine().primary_screen->hpos() < I824X_START_ACTIVE_SCAN || machine().primary_screen->hpos() > I824X_END_ACTIVE_SCAN )
155         if ( m_screen->hpos() < I824X_START_ACTIVE_SCAN || m_screen->hpos() > I824X_END_ACTIVE_SCAN )
157156         {
158157            data |= 1;
159158         }
159         break;
160160
161            break;
162
163        case 0xa2:
161      case 0xa2:
164162         data = m_collision_status;
165163         m_collision_status = 0;
164         break;
166165
167            break;
166      case 0xa4:
167         if (m_o2_vdc.s.control & VDC_CONTROL_REG_STROBE_XY)
168         {
169            m_y_beam_pos = m_screen->vpos() - m_start_vpos;
170         }
168171
169        case 0xa4:
172         data = m_y_beam_pos;
170173
171            if ((m_o2_vdc.s.control & VDC_CONTROL_REG_STROBE_XY))
172                m_y_beam_pos = machine().primary_screen->vpos() - m_start_vpos;
174         break;
173175
174            data = m_y_beam_pos;
175176
176            break;
177
178
179177        case 0xa5:
180178
181179            if ((m_o2_vdc.s.control & VDC_CONTROL_REG_STROBE_XY))
182180         {
183                m_x_beam_pos = machine().primary_screen->hpos();
181                m_x_beam_pos = m_screen->hpos();
184182            if ( m_x_beam_pos < I824X_START_ACTIVE_SCAN )
185183            {
186184               m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN + I824X_LINE_CLOCKS;
r19932r19933
202200    return data;
203201}
204202
205WRITE8_MEMBER(odyssey2_state::odyssey2_video_w)
203
204WRITE8_MEMBER(odyssey2_state::video_write)
206205{
207206   /* Update the sound */
208207   if( offset >= 0xa7 && offset <= 0xaa )
r19932r19933
215214             && !(data & VDC_CONTROL_REG_STROBE_XY))
216215        {
217216            /* Toggling strobe bit, tuck away values */
218            m_x_beam_pos = machine().primary_screen->hpos();
217            m_x_beam_pos = m_screen->hpos();
219218         if ( m_x_beam_pos < I824X_START_ACTIVE_SCAN )
220219         {
221220            m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN + 228;
r19932r19933
225224            m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN;
226225         }
227226
228            m_y_beam_pos = machine().primary_screen->vpos() - m_start_vpos;
227            m_y_beam_pos = m_screen->vpos() - m_start_vpos;
229228        }
230229    }
231230
232231    m_o2_vdc.reg[offset] = data;
233232}
234233
235WRITE8_MEMBER(odyssey2_state::odyssey2_lum_w)
234
235WRITE8_MEMBER(odyssey2_state::lum_write)
236236{
237237   m_lum = data;
238238}
239239
240READ8_MEMBER(odyssey2_state::odyssey2_t1_r)
240
241READ8_MEMBER(odyssey2_state::t1_read)
241242{
242   if ( machine().primary_screen->vpos() > m_start_vpos && machine().primary_screen->vpos() < m_start_vblank )
243   if ( m_screen->vpos() > m_start_vpos && m_screen->vpos() < m_start_vblank )
243244   {
244      if ( machine().primary_screen->hpos() >= I824X_START_ACTIVE_SCAN && machine().primary_screen->hpos() < I824X_END_ACTIVE_SCAN )
245      if ( m_screen->hpos() >= I824X_START_ACTIVE_SCAN && m_screen->hpos() < I824X_END_ACTIVE_SCAN )
245246      {
246247         return 1;
247248      }
r19932r19933
249250   return 0;
250251}
251252
252TIMER_CALLBACK_MEMBER(odyssey2_state::i824x_scanline_callback)
253
254void odyssey2_state::i824x_scanline(int vpos)
253255{
254256   UINT8   collision_map[160];
255   int      vpos = machine().primary_screen->vpos();
256257
257258   if ( vpos < m_start_vpos )
258259      return;
r19932r19933
537538      m_control_status |= 0x08;
538539      if ( ! m_iff )
539540      {
540         machine().device("maincpu")->execute().set_input_line(0, ASSERT_LINE);
541         m_maincpu->set_input_line(0, ASSERT_LINE);
541542         m_iff = 1;
542543      }
543544   }
544545}
545546
546TIMER_CALLBACK_MEMBER(odyssey2_state::i824x_hblank_callback)
547
548void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
547549{
548   int vpos = machine().primary_screen->vpos();
550   int vpos = m_screen->vpos();
549551
550   if ( vpos < m_start_vpos - 1 )
551      return;
552   switch ( id )
553   {
554      case TIMER_LINE:
555         // handle i824x line timer
556         i824x_scanline(vpos);
557         break;
552558
553   if ( vpos < m_start_vblank - 1 )
554   {
555      m_control_status |= 0x01;
559      case TIMER_HBLANK:
560         // handle i824x HBlank timer
561         if ( vpos < m_start_vpos - 1 )
562         {
563            return;
564         }
565
566         if ( vpos < m_start_vblank - 1 )
567         {
568            m_control_status |= 0x01;
569         }
570         break;
556571   }
557572}
558573
574
559575/***************************************************************************
560576
561577  Start the video hardware emulation.
r19932r19933
564580
565581void odyssey2_state::video_start()
566582{
567   screen_device *screen = machine().first_screen();
568
569583   memset(m_o2_vdc.reg, 0, 0x100);
570584
571585   m_o2_snd_shift[0] = m_o2_snd_shift[1] = 0;
r19932r19933
586600   m_control_status = 0;
587601   m_iff = 0;
588602
589   screen->register_screen_bitmap(m_tmp_bitmap);
603   m_screen->register_screen_bitmap(m_tmp_bitmap);
590604
591   m_i824x_line_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(odyssey2_state::i824x_scanline_callback),this));
592   m_i824x_line_timer->adjust( machine().primary_screen->time_until_pos(1, I824X_START_ACTIVE_SCAN ), 0,  machine().primary_screen->scan_period() );
605   m_line_timer = timer_alloc(TIMER_LINE);
606   m_line_timer->adjust( m_screen->time_until_pos(1, I824X_START_ACTIVE_SCAN ), 0,  m_screen->scan_period() );
593607
594   m_i824x_hblank_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(odyssey2_state::i824x_hblank_callback),this));
595   m_i824x_hblank_timer->adjust( machine().primary_screen->time_until_pos(1, I824X_END_ACTIVE_SCAN + 18 ), 0, machine().primary_screen->scan_period() );
608   m_hblank_timer = timer_alloc(TIMER_HBLANK);
609   m_hblank_timer->adjust( m_screen->time_until_pos(1, I824X_END_ACTIVE_SCAN + 18 ), 0, m_screen->scan_period() );
596610}
597611
612
613void odyssey2_state::video_start_g7400()
614{
615   video_start();
616
617   m_ef9340.X = 0;
618   m_ef9340.Y = 0;
619   m_ef9340.Y0 = 0;
620   m_ef9340.R = 0;
621   m_ef9340.M = 0;
622   m_ef9341.TA = 0;
623   m_ef9341.TB = 0;
624   m_ef9341.busy = 0;
625
626   m_g7400 = true;
627}
628
629
598630/***************************************************************************
599631
600632  Refresh the video screen
r19932r19933
655687         /* Throw an interrupt if enabled */
656688         if( state->m_o2_vdc.s.control & 0x4 )
657689         {
658            device->machine().device("maincpu")->execute().set_input_line(1, HOLD_LINE); /* Is this right? */
690            state->m_maincpu->set_input_line(1, HOLD_LINE); /* Is this right? */
659691         }
660692
661693         /* Adjust volume */
r19932r19933
676708    Thomson EF9340/EF9341 extra chips in the g7400
677709 */
678710
679#ifdef UNUSED_FUNCTION
680INLINE UINT16 ef9341_get_c_addr( odyssey2_state *state )
711UINT16 odyssey2_state::ef9340_get_c_addr()
681712{
682   if ( ( state->m_ef9341.Y & 0x0C ) == 0x0C )
713   if ( ( m_ef9340.Y & 0x0C ) == 0x0C )
683714   {
684      return 0x318 | ( ( state->m_ef9341.X & 0x38 ) << 2 ) | ( state->m_ef9341.X & 0x07 );
715      return 0x318 | ( ( m_ef9340.X & 0x38 ) << 2 ) | ( m_ef9340.X & 0x07 );
685716   }
686   if ( state->m_ef9341.X & 0x20 )
717   if ( m_ef9340.X & 0x20 )
687718   {
688      return 0x300 | ( ( state->m_ef9341.Y & 0x07 ) << 5 ) | ( state->m_ef9341.Y & 0x18 ) | ( state->m_ef9341.X & 0x07 );
719      return 0x300 | ( ( m_ef9340.Y & 0x07 ) << 5 ) | ( m_ef9340.Y & 0x18 ) | ( m_ef9340.X & 0x07 );
689720   }
690   return ( state->m_ef9341.Y << 5 ) | state->m_ef9341.X;
721   return ( m_ef9340.Y << 5 ) | m_ef9340.X;
691722}
692723
693INLINE void ef9341_inc_c( odyssey2_state *state )
724void odyssey2_state::ef9340_inc_c()
694725{
695   state->m_ef9341.X++;
696   if ( state->m_ef9341.X >= 40 )
726   m_ef9340.X++;
727   if ( m_ef9340.X >= 40 )
697728   {
698      state->m_ef9341.Y = ( state->m_ef9341.Y + 1 ) % 24;
729      m_ef9340.Y = ( m_ef9340.Y + 1 ) % 24;
699730   }
700731}
701732
702void odyssey2_ef9341_w( running_machine &machine, int command, int b, UINT8 data )
733void odyssey2_state::ef9341_w( UINT8 command, UINT8 b, UINT8 data )
703734{
704   odyssey2_state *state = machine.driver_data<odyssey2_state>();
705735   logerror("ef9341 %s write, t%s, data %02X\n", command ? "command" : "data", b ? "B" : "A", data );
706736
707737   if ( command )
708738   {
709739      if ( b )
710740      {
711         state->m_ef9341.TB = data;
712         state->m_ef9341.busy = 0x80;
713         switch( state->m_ef9341.TB & 0xE0 )
741         m_ef9341.TB = data;
742         m_ef9341.busy = 0x80;
743         switch( m_ef9341.TB & 0xE0 )
714744         {
715745         case 0x00:   /* Begin row */
716            state->m_ef9341.X = 0;
717            state->m_ef9341.Y = state->m_ef9341.TA & 0x1F;
746            m_ef9340.X = 0;
747            m_ef9340.Y = m_ef9341.TA & 0x1F;
718748            break;
719749         case 0x20:   /* Load Y */
720            state->m_ef9341.Y = state->m_ef9341.TA & 0x1F;
750            m_ef9340.Y = m_ef9341.TA & 0x1F;
721751            break;
722752         case 0x40:   /* Load X */
723            state->m_ef9341.X = state->m_ef9341.TA & 0x3F;
753            m_ef9340.X = m_ef9341.TA & 0x3F;
724754            break;
725755         case 0x60:   /* INC C */
726            ef9341_inc_c(state);
756            ef9340_inc_c();
727757            break;
728758         case 0x80:   /* Load M */
729            state->m_ef9341.M = state->m_ef9341.TA;
759            m_ef9340.M = m_ef9341.TA;
730760            break;
731761         case 0xA0:   /* Load R */
732            state->m_ef9341.R = state->m_ef9341.TA;
762            m_ef9340.R = m_ef9341.TA;
733763            break;
734764         case 0xC0:   /* Load Y0 */
735            state->m_ef9341.Y0 = state->m_ef9341.TA & 0x3F;
765            m_ef9340.Y0 = m_ef9341.TA & 0x3F;
736766            break;
737767         }
738         state->m_ef9341.busy = 0;
768         m_ef9341.busy = 0;
739769      }
740770      else
741771      {
742         state->m_ef9341.TA = data;
772         m_ef9341.TA = data;
743773      }
744774   }
745775   else
746776   {
747777      if ( b )
748778      {
749         state->m_ef9341.TB = data;
750         state->m_ef9341.busy = 0x80;
751         switch ( state->m_ef9341.M & 0xE0 )
779         m_ef9341.TB = data;
780         m_ef9341.busy = 0x80;
781         switch ( m_ef9340.M & 0xE0 )
752782         {
753783         case 0x00:   /* Write */
754            state->m_ef9341.ram[ ef9341_get_c_addr(state) ] = state->m_ef9341.TB;
755            ef9341_inc_c(state);
784            m_ef934x_ram_b[ ef9340_get_c_addr() & 0x3ff ] = m_ef9341.TB;
785            ef9340_inc_c();
756786            break;
757787         case 0x20:   /* Read */
758            logerror("ef9341 unimplemented data action %02X\n", state->m_ef9341.M & 0xE0 );
759            ef9341_inc_c(state);
788            logerror("ef9341 unimplemented data action %02X\n", m_ef9340.M & 0xE0 );
789            ef9340_inc_c();
760790            break;
761791         case 0x40:   /* Write without increment */
762792         case 0x60:   /* Read without increment */
763793         case 0x80:   /* Write slice */
764794         case 0xA0:   /* Read slice */
765            logerror("ef9341 unimplemented data action %02X\n", state->m_ef9341.M & 0xE0 );
795            logerror("ef9341 unimplemented data action %02X\n", m_ef9340.M & 0xE0 );
766796            break;
767797         }
768         state->m_ef9341.busy = 0;
798         m_ef9341.busy = 0;
769799      }
770800      else
771801      {
772         state->m_ef9341.TA = data;
802         m_ef9341.TA = data;
773803      }
774804   }
775805}
776806
777UINT8 odyssey2_ef9341_r( running_machine &machine, int command, int b )
807UINT8 odyssey2_state::ef9341_r( UINT8 command, UINT8 b )
778808{
779   odyssey2_state *state = machine.driver_data<odyssey2_state>();
780809   UINT8   data = 0xFF;
781810
782811   logerror("ef9341 %s read, t%s\n", command ? "command" : "data", b ? "B" : "A" );
r19932r19933
788817      }
789818      else
790819      {
791         data = state->m_ef9341.busy;
820         data = m_ef9341.busy;
792821      }
793822   }
794823   else
795824   {
796825      if ( b )
797826      {
798         data = state->m_ef9341.TB;
799         state->m_ef9341.busy = 0x80;
827         data = m_ef9341.TB;
828         m_ef9341.busy = 0x80;
800829      }
801830      else
802831      {
803         data = state->m_ef9341.TA;
832         data = m_ef9341.TA;
804833      }
805834   }
806835   return data;
807836}
808#endif
809837
838
839void odyssey2_state::er9340_scanline(int vpos)
840{
841   if ( vpos < m_start_vpos )
842   {
843      return;
844   }
845
846   if ( vpos < m_start_vblank )
847   {
848   }
849}
850
851
810852const device_type ODYSSEY2 = &device_creator<odyssey2_sound_device>;
811853
812854odyssey2_sound_device::odyssey2_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team