Previous 199869 Revisions Next

r19908 Friday 28th December, 2012 at 21:56:04 UTC by Wilbert Pol
(MESS)New NOT WORKING system
------------------------------

Milton Bradley MicroVision [kevtris, Wilbert Pol]

Because of the tiny screen use -prescale 3 to
get decent video output.
[src/mess]mess.lst mess.mak
[src/mess/drivers]microvsn.c*

trunk/src/mess/drivers/microvsn.c
r0r19908
1/***************************************************************************
2
3    Milton Bradley MicroVision
4
5    To Do:
6    * Add support for the paddle control
7    * Finish support for i8021 based cartridges
8
9****************************************************************************/
10
11#include "emu.h"
12#include "cpu/mcs48/mcs48.h"
13#include "cpu/tms0980/tms0980.h"
14#include "sound/dac.h"
15#include "imagedev/cartslot.h"
16#include "rendlay.h"
17
18
19enum cpu_type
20{
21   CPU_TYPE_I8021,
22   CPU_TYPE_TMS1100
23};
24
25
26class microvision_state : public driver_device
27{
28public:
29   microvision_state(const machine_config &mconfig, device_type type, const char *tag)
30      : driver_device(mconfig, type, tag)
31      , m_dac( *this, "dac" )
32      , m_i8021( *this, "maincpu1" )
33      , m_tms1100( *this, "maincpu2" )
34   { }
35
36   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
37
38   DECLARE_PALETTE_INIT(microvision);
39   DECLARE_MACHINE_START(microvision);
40   DECLARE_MACHINE_RESET(microvision);
41
42   void screen_vblank(screen_device &screen, bool state);
43
44   // i8021 interface
45   DECLARE_WRITE8_MEMBER(i8021_p0_write);
46   DECLARE_WRITE8_MEMBER(i8021_p1_write);
47   DECLARE_READ8_MEMBER(i8021_bus_read);
48
49   // TMS1100 interface
50   DECLARE_READ8_MEMBER(tms1100_read_k);
51   DECLARE_WRITE16_MEMBER(tms1100_write_o);
52   DECLARE_WRITE16_MEMBER(tms1100_write_r);
53
54   cpu_type   m_cpu_type;
55
56protected:
57   required_device<dac_device> m_dac;
58   required_device<cpu_device> m_i8021;
59   required_device<cpu_device> m_tms1100;
60
61   // i8021 variables
62   UINT8   m_p0;
63
64   // tms1100 variables
65   UINT16   m_r;
66   UINT16   m_o;
67
68   // generic variables
69   void   lcd_write(UINT8 control, UINT8 data);
70   void   speaker_write(UINT8 speaker);
71
72   UINT8   m_lcd_latch[8];
73   UINT8   m_lcd_latch_index;
74   UINT8   m_lcd[16][16];
75   UINT8   m_lcd_control_old;
76};
77
78
79PALETTE_INIT_MEMBER(microvision_state,microvision)
80{
81   palette_set_color_rgb( machine(), 15, 0x00, 0x00, 0x00 );
82   palette_set_color_rgb( machine(), 14, 0x11, 0x11, 0x11 );
83   palette_set_color_rgb( machine(), 13, 0x22, 0x22, 0x22 );
84   palette_set_color_rgb( machine(), 12, 0x33, 0x33, 0x33 );
85   palette_set_color_rgb( machine(), 11, 0x44, 0x44, 0x44 );
86   palette_set_color_rgb( machine(), 10, 0x55, 0x55, 0x55 );
87   palette_set_color_rgb( machine(),  9, 0x66, 0x66, 0x66 );
88   palette_set_color_rgb( machine(),  8, 0x77, 0x77, 0x77 );
89   palette_set_color_rgb( machine(),  7, 0x88, 0x88, 0x88 );
90   palette_set_color_rgb( machine(),  6, 0x99, 0x99, 0x99 );
91   palette_set_color_rgb( machine(),  5, 0xaa, 0xaa, 0xaa );
92   palette_set_color_rgb( machine(),  4, 0xbb, 0xbb, 0xbb );
93   palette_set_color_rgb( machine(),  3, 0xcc, 0xcc, 0xcc );
94   palette_set_color_rgb( machine(),  2, 0xdd, 0xdd, 0xdd );
95   palette_set_color_rgb( machine(),  1, 0xee, 0xee, 0xee );
96   palette_set_color_rgb( machine(),  0, 0xff, 0xff, 0xff );
97}
98
99
100MACHINE_START_MEMBER(microvision_state, microvision)
101{
102   save_item(NAME(m_p0));
103   save_item(NAME(m_r));
104   save_item(NAME(m_o));
105   save_item(NAME(m_lcd_latch));
106   save_item(NAME(m_lcd_latch_index));
107   save_item(NAME(m_lcd));
108   save_item(NAME(m_lcd_control_old));
109}
110
111
112MACHINE_RESET_MEMBER(microvision_state, microvision)
113{
114   for( int i = 0; i < 8; i++ )
115   {
116      m_lcd_latch[i] = 0;
117   }
118
119   for( int i = 0; i < 16; i++ )
120   {
121      for ( int j = 0; j < 16; j++ )
122      {
123         m_lcd[i][j] = 0;
124      }
125   }
126
127   m_o = 0;
128   m_r = 0;
129
130   switch ( m_cpu_type )
131   {
132      case CPU_TYPE_I8021:
133         m_i8021->resume( SUSPEND_REASON_DISABLE );
134         m_tms1100->suspend( SUSPEND_REASON_DISABLE, 0 );
135         break;
136
137      case CPU_TYPE_TMS1100:
138         m_i8021->suspend( SUSPEND_REASON_DISABLE, 0 );
139         m_tms1100->resume( SUSPEND_REASON_DISABLE );
140         break;
141   }
142}
143
144
145UINT32 microvision_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
146{
147   for ( int i = 0; i < 16; i++ )
148   {
149      for ( int j = 0; j < 16; j++ )
150      {
151         bitmap.pix16(i,j) = m_lcd[i][j];
152      }
153   }
154
155   return 0;
156}
157
158
159void microvision_state::screen_vblank(screen_device &screen, bool state)
160{
161   if ( state )
162   {
163      for ( int i = 0; i < 16; i++ )
164      {
165         for ( int j= 0; j < 16; j++ )
166         {
167            if ( m_lcd[i][j] )
168            {
169               m_lcd[i][j]--;
170            }
171         }
172      }
173   }
174}
175
176
177/*
178control is signals LCD5 LCD4
179data is signals LCD3 LCD2 LCD1 LCD0
180*/
181void microvision_state::lcd_write(UINT8 control, UINT8 data)
182{
183   data &= 0xf;
184   if ( ( control == 2 ) && ( m_lcd_control_old == 0 ) )
185   {
186      m_lcd_latch[ m_lcd_latch_index & 0x07 ] = data;
187      m_lcd_latch_index++;
188   }
189   else if ( ( control == 3 ) && ( m_lcd_control_old == 2 ) )
190   {
191      m_lcd_latch_index = 0;
192
193      UINT16 row = ( m_lcd_latch[0] << 12 ) | ( m_lcd_latch[1] << 8 ) | ( m_lcd_latch[2] << 4 ) | m_lcd_latch[3];
194      UINT16 col = ( m_lcd_latch[4] << 12 ) | ( m_lcd_latch[5] << 8 ) | ( m_lcd_latch[6] << 4 ) | m_lcd_latch[7];
195
196      //logerror("row = %04x, col = %04x\n", row, col );
197      for ( int i = 0; i < 16; i++ )
198      {
199         UINT16 temp = row;
200
201         for ( int j = 0; j < 16; j++ )
202         {
203            if ( ( temp & col ) & 0x8000 )
204            {
205               m_lcd[j][i] = 15;
206            }
207            temp <<= 1;
208         }
209         col <<= 1;
210      }
211   }
212   m_lcd_control_old = control;
213}
214
215
216/*
217speaker is SPKR1 SPKR0
218*/
219void microvision_state::speaker_write(UINT8 speaker)
220{
221   const INT8 speaker_level[4] = { 0, 127, -128, 0 };
222
223   m_dac->write_signed8( speaker_level[ speaker & 0x03 ] );
224}
225
226
227/*
228 x--- ---- KEY3
229 -x-- ---- KEY4
230 --x- ---- KEY5
231 ---x ---- KEY6
232 ---- x---
233 ---- -x-- KEY0
234 ---- --x- KEY1
235 ---- ---x KEY2
236*/
237WRITE8_MEMBER( microvision_state::i8021_p0_write )
238{
239   logerror( "p0_write: %02x\n", data );
240
241   m_p0 = data;
242}
243
244
245/*
246 x--- ---- LCD3
247 -x-- ---- LCD2
248 --x- ---- LCD1
249 ---x ---- LCD0
250 ---- --x- LCD5
251 ---- ---x LCD4
252*/
253WRITE8_MEMBER( microvision_state::i8021_p1_write )
254{
255   logerror( "p1_write: %02x\n", data );
256
257   lcd_write( data & 0x03, data >> 4 );
258}
259
260
261READ8_MEMBER( microvision_state::i8021_bus_read )
262{
263   UINT8 data = m_p0;
264
265   UINT8 col0 = ioport("COL0")->read();
266   UINT8 col1 = ioport("COL1")->read();
267   UINT8 col2 = ioport("COL2")->read();
268
269   // Row scanning
270   if ( ! ( m_p0 & 0x80 ) )
271   {
272      UINT8 t = ( ( col0 & 0x01 ) << 2 ) | ( ( col1 & 0x01 ) << 1 ) | ( col2 & 0x01 );
273
274      data &= ( t ^ 0xFF );
275   }
276   if ( ! ( m_p0 & 0x40 ) )
277   {
278      UINT8 t = ( ( col0 & 0x02 ) << 1 ) | ( col1 & 0x02 ) | ( ( col2 & 0x02 ) >> 1 );
279
280      data &= ( t ^ 0xFF );
281   }
282   if ( ! ( m_p0 & 0x20 ) )
283   {
284      UINT8 t = ( col0 & 0x04 ) | ( ( col1 & 0x04 ) >> 1 ) | ( ( col2 & 0x04 ) >> 2 );
285
286      data &= ( t ^ 0xFF );
287   }
288   if ( ! ( m_p0 & 0x10 ) )
289   {
290      UINT8 t = ( ( col0 & 0x08 ) >> 1 ) | ( ( col1 & 0x08 ) >> 2 ) | ( ( col2 & 0x08 ) >> 3 );
291
292      data &= ( t ^ 0xFF );
293   }
294   return data;
295}
296
297
298READ8_MEMBER( microvision_state::tms1100_read_k )
299{
300   UINT8 data = 0;
301
302   //logerror("read_k\n");
303
304   if ( m_r & 0x100 )
305   {
306      data |= ioport("COL0")->read();
307   }
308   if ( m_r & 0x200 )
309   {
310      data |= ioport("COL1")->read();
311   }
312   if ( m_r & 0x400 )
313   {
314      data |= ioport("COL2")->read();
315   }
316   return data;
317}
318
319
320WRITE16_MEMBER( microvision_state::tms1100_write_o )
321{
322   logerror("write_o: %04x\n", data);
323
324   m_o = data;
325
326   lcd_write( ( m_r >> 6 ) & 0x03, m_o & 0x0f );
327}
328
329
330/*
331x-- ---- ---- KEY2
332-x- ---- ---- KEY1
333--x ---- ---- KEY0
334--- x--- ---- LCD5
335--- -x-- ---- LCD4
336--- ---- --x- SPKR0
337--- ---- ---x SPKR1
338*/
339WRITE16_MEMBER( microvision_state::tms1100_write_r )
340{
341   logerror("write_r: %04x\n", data);
342
343   m_r = data;
344
345   speaker_write( ( ( m_r & 0x01 ) << 1 ) | ( ( m_r & 0x02 ) >> 1 ) );
346   lcd_write( ( m_r >> 6 ) & 0x03, m_o & 0x0f );
347}
348
349
350static DEVICE_IMAGE_LOAD(microvision_cart)
351{
352   microvision_state *state = image.device().machine().driver_data<microvision_state>();
353   UINT8 *rom1 = state->memregion("maincpu1")->base();
354   UINT8 *rom2 = state->memregion("maincpu2")->base();
355   UINT32 file_size;
356
357   if (image.software_entry() == NULL)
358   {
359      file_size = image.length();
360   }
361   else
362   {
363      file_size = image.get_software_region_length("rom");
364   }
365
366   if ( file_size != 1024 && file_size != 2048 )
367   {
368      image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid rom file size");
369      return IMAGE_INIT_FAIL;
370   }
371
372   /* Read cartridge */
373   if (image.software_entry() == NULL)
374   {
375      if (image.fread( rom1, file_size) != file_size)
376      {
377         image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read from file");
378         return IMAGE_INIT_FAIL;
379      }
380   }
381   else
382   {
383      memcpy(rom1, image.get_software_region("rom"), file_size);
384   }
385   memcpy( rom2, rom1, file_size );
386
387   // Based on file size select cpu:
388   // - 1024 -> I8021
389   // - 2048 -> TI TMS1100
390
391   switch ( file_size )
392   {
393      case 1024:
394         state->m_cpu_type = CPU_TYPE_I8021;
395         break;
396
397      case 2048:
398         state->m_cpu_type = CPU_TYPE_TMS1100;
399         break;
400   }
401   return IMAGE_INIT_PASS;
402}
403
404
405static INPUT_PORTS_START( microvision )
406   PORT_START("COL0")
407   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON1)  PORT_CODE(KEYCODE_3) PORT_NAME("B01")
408   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4)  PORT_CODE(KEYCODE_E) PORT_NAME("B04")
409   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON7)  PORT_CODE(KEYCODE_D) PORT_NAME("B07")
410   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_CODE(KEYCODE_C) PORT_NAME("B10")
411
412   PORT_START("COL1")
413   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON2)  PORT_CODE(KEYCODE_4) PORT_NAME("B02")
414   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON5)  PORT_CODE(KEYCODE_R) PORT_NAME("B05")
415   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON8)  PORT_CODE(KEYCODE_F) PORT_NAME("B08")
416   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON11) PORT_CODE(KEYCODE_V) PORT_NAME("B11")
417
418   PORT_START("COL2")
419   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON3)  PORT_CODE(KEYCODE_5) PORT_NAME("B03")
420   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON6)  PORT_CODE(KEYCODE_T) PORT_NAME("B06")
421   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON9)  PORT_CODE(KEYCODE_G) PORT_NAME("B09")
422   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_CODE(KEYCODE_B) PORT_NAME("B12")
423INPUT_PORTS_END
424
425
426static ADDRESS_MAP_START( microvision_8021_io, AS_IO, 8, microvision_state )
427   AM_RANGE( 0x00, 0xFF ) AM_WRITE( i8021_p0_write )
428   AM_RANGE( MCS48_PORT_P0, MCS48_PORT_P0 ) AM_WRITE( i8021_p0_write )
429   AM_RANGE( MCS48_PORT_P1, MCS48_PORT_P1 ) AM_WRITE( i8021_p1_write )
430   AM_RANGE( MCS48_PORT_BUS, MCS48_PORT_BUS ) AM_READ( i8021_bus_read )
431ADDRESS_MAP_END
432
433
434static const tms0980_config microvision_tms0980_config =
435{
436   {
437      /* O output PLA configuration currently unknown */
438      0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E,
439      0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F,
440      0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00,
441      0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00, 0xFF00
442   },
443   DEVCB_DRIVER_MEMBER(microvision_state, tms1100_read_k),
444   DEVCB_DRIVER_MEMBER16(microvision_state, tms1100_write_o),
445   DEVCB_DRIVER_MEMBER16(microvision_state, tms1100_write_r)
446};
447
448
449static MACHINE_CONFIG_START( microvision, microvision_state )
450   MCFG_CPU_ADD("maincpu1", I8021, 400000)   // totally wild guess, needs to be verified
451   MCFG_CPU_IO_MAP( microvision_8021_io )
452   MCFG_CPU_ADD("maincpu2", TMS1100, 400000)
453   MCFG_CPU_CONFIG( microvision_tms0980_config ) // totally wild guess, needs to be verified
454
455   MCFG_SCREEN_ADD("screen", LCD)
456   MCFG_SCREEN_REFRESH_RATE(60)
457   MCFG_SCREEN_VBLANK_TIME(0)
458   MCFG_QUANTUM_TIME(attotime::from_hz(60))
459
460   MCFG_MACHINE_START_OVERRIDE(microvision_state, microvision )
461   MCFG_MACHINE_RESET_OVERRIDE(microvision_state, microvision )
462
463   MCFG_SCREEN_UPDATE_DRIVER(microvision_state, screen_update)
464   MCFG_SCREEN_VBLANK_DRIVER(microvision_state, screen_vblank)
465   MCFG_SCREEN_SIZE(16, 16)
466   MCFG_SCREEN_VISIBLE_AREA(0, 15, 0, 15)
467
468   MCFG_PALETTE_LENGTH(16)
469   MCFG_PALETTE_INIT_OVERRIDE(microvision_state,microvision)
470
471   MCFG_DEFAULT_LAYOUT(layout_lcd)
472
473   /* sound hardware */
474   MCFG_SPEAKER_STANDARD_MONO("mono")
475   MCFG_SOUND_ADD("dac", DAC, 0)
476   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
477
478   MCFG_CARTSLOT_ADD("cart")
479   MCFG_CARTSLOT_EXTENSION_LIST("bin")
480   MCFG_CARTSLOT_MANDATORY
481   MCFG_CARTSLOT_INTERFACE("microvision_cart")
482   MCFG_CARTSLOT_LOAD(microvision_cart)
483MACHINE_CONFIG_END
484
485
486ROM_START( microvsn )
487   ROM_REGION( 0x800, "maincpu1", ROMREGION_ERASE00 )
488   ROM_REGION( 0x800, "maincpu2", ROMREGION_ERASE00 )
489ROM_END
490
491
492CONS( 1979, microvsn, 0, 0, microvision, microvision, driver_device, 0, "Milton Bradley", "MicroVision", GAME_NOT_WORKING )
493
trunk/src/mess/mess.mak
r19907r19908
322322   $(MESSOBJ)/magnavox.a \
323323   $(MESSOBJ)/matsushi.a \
324324   $(MESSOBJ)/mattel.a \
325   $(MESSOBJ)/mb.a \
325326   $(MESSOBJ)/mchester.a \
326327   $(MESSOBJ)/memotech.a \
327328   $(MESSOBJ)/mgu.a \
r19907r19908
13131314   $(MESS_DRIVERS)/jr200.o      \
13141315   $(MESS_DRIVERS)/myb3k.o         \
13151316
1317$(MESSOBJ)/mb.a:            \
1318   $(MESS_DRIVERS)/microvsn.o   \
1319
13161320$(MESSOBJ)/mchester.a:         \
13171321   $(MESS_DRIVERS)/ssem.o      \
13181322
trunk/src/mess/mess.lst
r19907r19908
293293intv2     // Mattel Intellivision II- 1982?
294294intvsrs   // Intellivision (Sears License) - 19??
295295
296// Milton Bradley
297microvsn  // MicroVision - 1979
298
296299// Entex
297300advision  // Adventurevision
298301

Previous 199869 Revisions Next


© 1997-2024 The MAME Team