Previous 15994 Revisions Next

r12640 Tuesday 16th August, 2011 at 17:05:12 UTC by Fabio Priuli
sms.c: removed duplicated source and renamed a couple of files to their original names
[src/mess]mess.mak
[src/mess/drivers]segasms.c {sms.c}
[src/mess/machine]segasms.c sms.c*

src/mess/machine/segasms.c
r12639r12640
1#include "emu.h"
2#include "crsshair.h"
3#include "image.h"
4#include "includes/segasms.h"
5#include "video/smsvdp.h"
6#include "sound/2413intf.h"
7#include "imagedev/cartslot.h"
8#include "hashfile.h"
9
10#define VERBOSE 0
11#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
12
13#define CF_CODEMASTERS_MAPPER    0x01
14#define CF_KOREAN_MAPPER         0x02
15#define CF_KOREAN_ZEMINA_MAPPER  0x04
16#define CF_KOREAN_NOBANK_MAPPER  0x08
17#define CF_93C46_EEPROM          0x10
18#define CF_ONCART_RAM            0x20
19#define CF_GG_SMS_MODE           0x40
20
21#define LGUN_RADIUS           6
22#define LGUN_X_INTERVAL       4
23
24
25static void setup_rom(address_space *space);
26
27
28static TIMER_CALLBACK( rapid_fire_callback )
29{
30   sms_state *state = machine.driver_data<sms_state>();
31   state->m_rapid_fire_state_1 ^= 0xff;
32   state->m_rapid_fire_state_2 ^= 0xff;
33}
34
35
36static WRITE8_HANDLER( sms_input_write )
37{
38   sms_state *state = space->machine().driver_data<sms_state>();
39
40   switch (offset)
41   {
42   case 0:
43      switch (input_port_read_safe(space->machine(), "CTRLSEL", 0x00) & 0x0f)
44      {
45      case 0x04:   /* Sports Pad */
46         if (data != state->m_sports_pad_last_data_1)
47         {
48            UINT32 cpu_cycles = downcast<cpu_device *>(&space->device())->total_cycles();
49
50            state->m_sports_pad_last_data_1 = data;
51            if (cpu_cycles - state->m_last_sports_pad_time_1 > 512)
52            {
53               state->m_sports_pad_state_1 = 3;
54               state->m_sports_pad_1_x = input_port_read(space->machine(), "SPORT0");
55               state->m_sports_pad_1_y = input_port_read(space->machine(), "SPORT1");
56            }
57            state->m_last_sports_pad_time_1 = cpu_cycles;
58            state->m_sports_pad_state_1 = (state->m_sports_pad_state_1 + 1) & 3;
59         }
60         break;
61      }
62      break;
63
64   case 1:
65      switch (input_port_read_safe(space->machine(), "CTRLSEL", 0x00) & 0xf0)
66      {
67      case 0x40:   /* Sports Pad */
68         if (data != state->m_sports_pad_last_data_2)
69         {
70            UINT32 cpu_cycles = downcast<cpu_device *>(&space->device())->total_cycles();
71
72            state->m_sports_pad_last_data_2 = data;
73            if (cpu_cycles - state->m_last_sports_pad_time_2 > 2048)
74            {
75               state->m_sports_pad_state_2 = 3;
76               state->m_sports_pad_2_x = input_port_read(space->machine(), "SPORT2");
77               state->m_sports_pad_2_y = input_port_read(space->machine(), "SPORT3");
78            }
79            state->m_last_sports_pad_time_2 = cpu_cycles;
80            state->m_sports_pad_state_2 = (state->m_sports_pad_state_2 + 1) & 3;
81         }
82         break;
83      }
84      break;
85   }
86}
87
88/* FIXME: this function is a hack for Light Phaser emulation. Theoretically
89   sms_vdp_hcount_latch() should be used instead, but it returns incorrect
90   position for unknown reason (timing?) */
91static void sms_vdp_hcount_lphaser( running_machine &machine, int hpos )
92{
93   sms_state *state = machine.driver_data<sms_state>();
94   int hpos_tmp = hpos + state->m_lphaser_x_offs;
95   UINT8 tmp = ((hpos_tmp - 46) >> 1) & 0xff;
96
97   //printf ("sms_vdp_hcount_lphaser: hpos %3d hpos_tmp %3d => hcount %2X\n", hpos, hpos_tmp, tmp);
98   sms_vdp_hcount_latch_w(state->m_vdp, 0, tmp);
99}
100
101
102/*
103    Light Phaser (light gun) emulation notes:
104    - The sensor is activated based on color brightness of some individual
105      pixels being drawn by the beam, at circular area where the gun is aiming.
106    - Currently, brightness is calculated based only on single pixels.
107    - In general, after the trigger is pressed, games draw the next frame using
108      a light color pattern, to make sure sensor will be activated. If emulation
109      skips that frame, sensor may stay deactivated. Frameskip set to 0 (no skip) is
110      recommended to avoid problems.
111    - When sensor switches from off to on, a value is latched for HCount register
112      and a flag is set. The emulation uses the flag to avoid sequential latches and
113      to signal that TH line is activated when the status of the input port is read.
114      When the status is read, the flag is cleared, or else it is cleared later when
115      the Pause status is read (end of a frame). This is necessary because the
116      "Color & Switch Test" ROM only reads the TH bit after the VINT line.
117    - The gun test of "Color & Switch Test" is an example that requires checks
118      of sensor status independent of other events, like trigger press or TH bit
119      reads. Another example is the title screen of "Hang-On & Safari Hunt", where
120      the game only reads HCount register in a loop, expecting a latch by the gun.
121    - The whole procedure is managed by a timer callback, that always reschedule
122      itself to run in some intervals when the beam is at the circular area.
123*/
124static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int lgun_x, int lgun_y )
125{
126   sms_state *state = machine.driver_data<sms_state>();
127   const int r_x_r = LGUN_RADIUS * LGUN_RADIUS;
128   screen_device *screen = machine.first_screen();
129   const rectangle &visarea = screen->visible_area();
130   int beam_x = screen->hpos();
131   int beam_y = screen->vpos();
132   int dx, dy;
133   int result = 0;
134   int pos_changed = 0;
135   double dx_circ;
136
137    while (1)
138   {
139      dy = abs(beam_y - lgun_y);
140
141      if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y)
142      {
143         beam_y = lgun_y - LGUN_RADIUS;
144         if (beam_y < visarea.min_y)
145            beam_y = visarea.min_y;
146         dy = abs(beam_y - lgun_y);
147         pos_changed = 1;
148      }
149      /* step 1: r^2 = dx^2 + dy^2 */
150      /* step 2: dx^2 = r^2 - dy^2 */
151      /* step 3: dx = sqrt(r^2 - dy^2) */
152      dx_circ = ceil((float) sqrt((float) (r_x_r - (dy * dy))));
153      dx = abs(beam_x - lgun_x);
154
155      if (dx > dx_circ || beam_x < visarea.min_x || beam_x > visarea.max_x)
156      {
157         if (beam_x > lgun_x)
158         {
159            beam_x = 0;
160            beam_y++;
161            continue;
162         }
163         beam_x = lgun_x - dx_circ;
164         if (beam_x < visarea.min_x)
165            beam_x = visarea.min_x;
166         pos_changed = 1;
167      }
168
169      if (!pos_changed)
170      {
171         result = sms_vdp_check_brightness(state->m_vdp, beam_x, beam_y);
172         /* next check at same line */
173         beam_x += LGUN_X_INTERVAL;
174         pos_changed = 1;
175      }
176      else
177         break;
178   }
179   timer->adjust(machine.first_screen()->time_until_pos(beam_y, beam_x));
180
181   return result;
182}
183
184static UINT8 sms_vdp_hcount( running_machine &machine )
185{
186   UINT8 tmp;
187   screen_device *screen = machine.first_screen();
188   int hpos = screen->hpos();
189
190   /* alternative method: pass HCounter test, but some others fail */
191   //int hpos_tmp = hpos;
192   //if ((hpos + 2) % 6 == 0) hpos_tmp--;
193   //tmp = ((hpos_tmp - 46) >> 1) & 0xff;
194
195   UINT64 calc_cycles;
196   attotime time_end;
197   int vpos = screen->vpos();
198   int max_hpos = screen->width() - 1;
199
200   if (hpos == max_hpos)
201      time_end = attotime::zero;
202   else
203      time_end = screen->time_until_pos(vpos, max_hpos);
204   calc_cycles = machine.device<cpu_device>("maincpu")->attotime_to_clocks(time_end);
205
206   /* equation got from SMSPower forum, posted by Flubba. */
207   tmp = ((590 - (calc_cycles * 3)) / 4) & 0xff;
208
209   //printf ("sms_vdp_hcount: hpos %3d => hcount %2X\n", hpos, tmp);
210   return tmp;
211}
212
213
214static void sms_vdp_hcount_latch( running_machine &machine )
215{
216   sms_state *state = machine.driver_data<sms_state>();
217   UINT8 value = sms_vdp_hcount(machine);
218
219   sms_vdp_hcount_latch_w(state->m_vdp, 0, value);
220}
221
222
223static UINT16 screen_hpos_nonscaled( screen_device *screen, int scaled_hpos )
224{
225   const rectangle &visarea = screen->visible_area();
226   int offset_x = (scaled_hpos * (visarea.max_x - visarea.min_x)) / 255;
227   return visarea.min_x + offset_x;
228}
229
230
231static UINT16 screen_vpos_nonscaled( screen_device *screen, int scaled_vpos )
232{
233   const rectangle &visarea = screen->visible_area();
234   int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255;
235   return visarea.min_y + offset_y;
236}
237
238
239static void lphaser1_sensor_check( running_machine &machine )
240{
241   sms_state *state = machine.driver_data<sms_state>();
242   const int x = screen_hpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER0"));
243   const int y = screen_vpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER1"));
244
245   if (lgun_bright_aim_area(machine, state->m_lphaser_1_timer, x, y))
246   {
247      if (state->m_lphaser_1_latch == 0)
248      {
249         state->m_lphaser_1_latch = 1;
250         sms_vdp_hcount_lphaser(machine, x);
251      }
252   }
253}
254
255static void lphaser2_sensor_check( running_machine &machine )
256{
257   sms_state *state = machine.driver_data<sms_state>();
258   const int x = screen_hpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER2"));
259   const int y = screen_vpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER3"));
260
261   if (lgun_bright_aim_area(machine, state->m_lphaser_2_timer, x, y))
262   {
263      if (state->m_lphaser_2_latch == 0)
264      {
265         state->m_lphaser_2_latch = 1;
266         sms_vdp_hcount_lphaser(machine, x);
267      }
268   }
269}
270
271
272// at each input port read we check if lightguns are enabled in one of the ports:
273// if so, we turn on crosshair and the lightgun timer
274static TIMER_CALLBACK( lightgun_tick )
275{
276   sms_state *state = machine.driver_data<sms_state>();
277
278   if ((input_port_read_safe(machine, "CTRLSEL", 0x00) & 0x0f) == 0x01)
279   {
280      /* enable crosshair */
281      crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL);
282      if (!state->m_lphaser_1_timer->enabled())
283         lphaser1_sensor_check(machine);
284   }
285   else
286   {
287      /* disable crosshair */
288      crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE);
289      state->m_lphaser_1_timer->enable(0);
290   }
291
292   if ((input_port_read_safe(machine, "CTRLSEL", 0x00) & 0xf0) == 0x10)
293   {
294      /* enable crosshair */
295      crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_ALL);
296      if (!state->m_lphaser_2_timer->enabled())
297         lphaser2_sensor_check(machine);
298   }
299   else
300   {
301      /* disable crosshair */
302      crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_NONE);
303      state->m_lphaser_2_timer->enable(0);
304   }
305}
306
307
308static TIMER_CALLBACK( lphaser_1_callback )
309{
310   lphaser1_sensor_check(machine);
311}
312
313
314static TIMER_CALLBACK( lphaser_2_callback )
315{
316   lphaser2_sensor_check(machine);
317}
318
319
320INPUT_CHANGED( lgun1_changed )
321{
322   sms_state *state = field.machine().driver_data<sms_state>();
323   if (!state->m_lphaser_1_timer ||
324      (input_port_read_safe(field.machine(), "CTRLSEL", 0x00) & 0x0f) != 0x01)
325      return;
326
327   if (newval != oldval)
328      lphaser1_sensor_check(field.machine());
329}
330
331INPUT_CHANGED( lgun2_changed )
332{
333   sms_state *state = field.machine().driver_data<sms_state>();
334   if (!state->m_lphaser_2_timer ||
335      (input_port_read_safe(field.machine(), "CTRLSEL", 0x00) & 0xf0) != 0x10)
336      return;
337
338   if (newval != oldval)
339      lphaser2_sensor_check(field.machine());
340}
341
342
343static void sms_get_inputs( address_space *space )
344{
345   sms_state *state = space->machine().driver_data<sms_state>();
346   UINT8 data = 0x00;
347   UINT32 cpu_cycles = downcast<cpu_device *>(&space->device())->total_cycles();
348   running_machine &machine = space->machine();
349
350   state->m_input_port0 = 0xff;
351   state->m_input_port1 = 0xff;
352
353   if (cpu_cycles - state->m_last_paddle_read_time > 256)
354   {
355      state->m_paddle_read_state ^= 0xff;
356      state->m_last_paddle_read_time = cpu_cycles;
357   }
358
359   /* Check if lightgun has been chosen as input: if so, enable crosshair */
360   machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick));
361
362   /* Player 1 */
363   switch (input_port_read_safe(machine, "CTRLSEL", 0x00) & 0x0f)
364   {
365   case 0x00:  /* Joystick */
366      data = input_port_read(machine, "PORT_DC");
367      /* Check Rapid Fire setting for Button A */
368      if (!(data & 0x10) && (input_port_read(machine, "RFU") & 0x01))
369         data |= state->m_rapid_fire_state_1 & 0x10;
370
371      /* Check Rapid Fire setting for Button B */
372      if (!(data & 0x20) && (input_port_read(machine, "RFU") & 0x02))
373         data |= state->m_rapid_fire_state_1 & 0x20;
374
375      state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f);
376      break;
377
378   case 0x01:  /* Light Phaser */
379      data = (input_port_read(machine, "CTRLIPT") & 0x01) << 4;
380      if (!(data & 0x10))
381      {
382         if (input_port_read(machine, "RFU") & 0x01)
383            data |= state->m_rapid_fire_state_1 & 0x10;
384      }
385      /* just consider the button (trigger) bit */
386      data |= ~0x10;
387      state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f);
388      break;
389
390   case 0x02:  /* Paddle Control */
391      /* Get button A state */
392      data = input_port_read(machine, "PADDLE0");
393
394      if (state->m_paddle_read_state)
395         data = data >> 4;
396
397      state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x0f) | (state->m_paddle_read_state & 0x20)
398                      | ((input_port_read(machine, "CTRLIPT") & 0x02) << 3);
399      break;
400
401   case 0x04:   /* Sega Sports Pad */
402      switch (state->m_sports_pad_state_1)
403      {
404      case 0:
405         data = (state->m_sports_pad_1_x >> 4) & 0x0f;
406         break;
407      case 1:
408         data = state->m_sports_pad_1_x & 0x0f;
409         break;
410      case 2:
411         data = (state->m_sports_pad_1_y >> 4) & 0x0f;
412         break;
413      case 3:
414         data = state->m_sports_pad_1_y & 0x0f;
415         break;
416      }
417      state->m_input_port0 = (state->m_input_port0 & 0xc0) | data | ((input_port_read(machine, "CTRLIPT") & 0x0c) << 2);
418      break;
419   }
420
421   /* Player 2 */
422   switch (input_port_read_safe(machine, "CTRLSEL", 0x00)  & 0xf0)
423   {
424   case 0x00:   /* Joystick */
425      data = input_port_read(machine, "PORT_DC");
426      state->m_input_port0 = (state->m_input_port0 & 0x3f) | (data & 0xc0);
427
428      data = input_port_read(machine, "PORT_DD");
429      /* Check Rapid Fire setting for Button A */
430      if (!(data & 0x04) && (input_port_read(machine, "RFU") & 0x04))
431         data |= state->m_rapid_fire_state_2 & 0x04;
432
433      /* Check Rapid Fire setting for Button B */
434      if (!(data & 0x08) && (input_port_read(machine, "RFU") & 0x08))
435         data |= state->m_rapid_fire_state_2 & 0x08;
436
437      state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f);
438      break;
439
440   case 0x10:   /* Light Phaser */
441      data = (input_port_read(machine, "CTRLIPT") & 0x10) >> 2;
442      if (!(data & 0x04))
443      {
444         if (input_port_read(machine, "RFU") & 0x04)
445            data |= state->m_rapid_fire_state_2 & 0x04;
446      }
447      /* just consider the button (trigger) bit */
448      data |= ~0x04;
449      state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f);
450      break;
451
452   case 0x20:   /* Paddle Control */
453      /* Get button A state */
454      data = input_port_read(machine, "PADDLE1");
455      if (state->m_paddle_read_state)
456         data = data >> 4;
457
458      state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6);
459      state->m_input_port1 = (state->m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (state->m_paddle_read_state & 0x08)
460                      | ((input_port_read(machine, "CTRLIPT") & 0x20) >> 3);
461      break;
462
463   case 0x40:   /* Sega Sports Pad */
464      switch (state->m_sports_pad_state_2)
465      {
466      case 0:
467         data = state->m_sports_pad_2_x & 0x0f;
468         break;
469      case 1:
470         data = (state->m_sports_pad_2_x >> 4) & 0x0f;
471         break;
472      case 2:
473         data = state->m_sports_pad_2_y & 0x0f;
474         break;
475      case 3:
476         data = (state->m_sports_pad_2_y >> 4) & 0x0f;
477         break;
478      }
479      state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6);
480      state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data >> 2) | ((input_port_read(machine, "CTRLIPT") & 0xc0) >> 4);
481      break;
482   }
483}
484
485
486WRITE8_HANDLER( sms_fm_detect_w )
487{
488   sms_state *state = space->machine().driver_data<sms_state>();
489
490   if (state->m_has_fm)
491      state->m_fm_detect = (data & 0x01);
492}
493
494
495READ8_HANDLER( sms_fm_detect_r )
496{
497   sms_state *state = space->machine().driver_data<sms_state>();
498
499   if (state->m_has_fm)
500   {
501      return state->m_fm_detect;
502   }
503   else
504   {
505      if (state->m_bios_port & IO_CHIP)
506      {
507         return 0xff;
508      }
509      else
510      {
511         sms_get_inputs(space);
512         return state->m_input_port0;
513      }
514   }
515}
516
517WRITE8_HANDLER( sms_io_control_w )
518{
519   sms_state *state = space->machine().driver_data<sms_state>();
520
521   if (data & 0x08)
522   {
523      /* check if TH pin level is high (1) and was low last time */
524      if (data & 0x80 && !(state->m_ctrl_reg & 0x80))
525      {
526         sms_vdp_hcount_latch(space->machine());
527      }
528      sms_input_write(space, 0, (data & 0x20) >> 5);
529   }
530
531   if (data & 0x02)
532   {
533      if (data & 0x20 && !(state->m_ctrl_reg & 0x20))
534      {
535         sms_vdp_hcount_latch(space->machine());
536      }
537      sms_input_write(space, 1, (data & 0x80) >> 7);
538   }
539
540   state->m_ctrl_reg = data;
541}
542
543
544READ8_HANDLER( sms_count_r )
545{
546   sms_state *state = space->machine().driver_data<sms_state>();
547
548   if (offset & 0x01)
549      return sms_vdp_hcount_latch_r(state->m_vdp, offset);
550   else
551      return sms_vdp_vcount_r(state->m_vdp, offset);
552}
553
554
555/*
556 Check if the pause button is pressed.
557 If the gamegear is in sms mode, check if the start button is pressed.
558 */
559void sms_pause_callback( running_machine &machine )
560{
561   sms_state *state = machine.driver_data<sms_state>();
562
563   if (state->m_is_gamegear && !(state->m_cartridge[state->m_current_cartridge].features & CF_GG_SMS_MODE))
564      return;
565
566   if (!(input_port_read(machine, state->m_is_gamegear ? "START" : "PAUSE") & 0x80))
567   {
568      if (!state->m_paused)
569      {
570         cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE);
571      }
572      state->m_paused = 1;
573   }
574   else
575   {
576      state->m_paused = 0;
577   }
578
579   /* clear Light Phaser latch flags for next frame */
580   state->m_lphaser_1_latch = 0;
581   state->m_lphaser_2_latch = 0;
582}
583
584READ8_HANDLER( sms_input_port_0_r )
585{
586   sms_state *state = space->machine().driver_data<sms_state>();
587
588   if (state->m_bios_port & IO_CHIP)
589   {
590      return 0xff;
591   }
592   else
593   {
594      sms_get_inputs(space);
595      return state->m_input_port0;
596   }
597}
598
599
600READ8_HANDLER( sms_input_port_1_r )
601{
602   sms_state *state = space->machine().driver_data<sms_state>();
603
604   if (state->m_bios_port & IO_CHIP)
605      return 0xff;
606
607   sms_get_inputs(space);
608
609   /* Reset Button */
610   state->m_input_port1 = (state->m_input_port1 & 0xef) | (input_port_read_safe(space->machine(), "RESET", 0x01) & 0x01) << 4;
611
612   /* Do region detection if TH of ports A and B are set to output (0) */
613   if (!(state->m_ctrl_reg & 0x0a))
614   {
615      /* Move bits 7,5 of IO control port into bits 7, 6 */
616      state->m_input_port1 = (state->m_input_port1 & 0x3f) | (state->m_ctrl_reg & 0x80) | (state->m_ctrl_reg & 0x20) << 1;
617
618      /* Inverse region detect value for Japanese machines */
619      if (state->m_is_region_japan)
620         state->m_input_port1 ^= 0xc0;
621   }
622   else
623   {
624      if (state->m_ctrl_reg & 0x02 && state->m_lphaser_1_latch)
625      {
626         state->m_input_port1 &= ~0x40;
627         state->m_lphaser_1_latch = 0;
628      }
629
630      if (state->m_ctrl_reg & 0x08 && state->m_lphaser_2_latch)
631      {
632         state->m_input_port1 &= ~0x80;
633         state->m_lphaser_2_latch = 0;
634      }
635   }
636
637   return state->m_input_port1;
638}
639
640
641
642WRITE8_HANDLER( sms_ym2413_register_port_0_w )
643{
644   sms_state *state = space->machine().driver_data<sms_state>();
645
646   if (state->m_has_fm)
647      ym2413_w(state->m_ym, 0, (data & 0x3f));
648}
649
650
651WRITE8_HANDLER( sms_ym2413_data_port_0_w )
652{
653   sms_state *state = space->machine().driver_data<sms_state>();
654
655   if (state->m_has_fm)
656   {
657      logerror("data_port_0_w %x %x\n", offset, data);
658      ym2413_w(state->m_ym, 1, data);
659   }
660}
661
662
663READ8_HANDLER( gg_input_port_2_r )
664{
665   sms_state *state = space->machine().driver_data<sms_state>();
666
667   //logerror("joy 2 read, val: %02x, pc: %04x\n", ((state->m_is_region_japan ? 0x00 : 0x40) | (input_port_read(machine, "START") & 0x80)), activecpu_get_pc());
668   return ((state->m_is_region_japan ? 0x00 : 0x40) | (input_port_read(space->machine(), "START") & 0x80));
669}
670
671
672READ8_HANDLER( sms_sscope_r )
673{
674   sms_state *state = space->machine().driver_data<sms_state>();
675   return state->m_sscope_state;
676}
677
678
679WRITE8_HANDLER( sms_sscope_w )
680{
681   sms_state *state = space->machine().driver_data<sms_state>();
682   state->m_sscope_state = data;
683}
684
685
686READ8_HANDLER( sms_mapper_r )
687{
688   sms_state *state = space->machine().driver_data<sms_state>();
689   return state->m_mapper[offset];
690}
691
692/* Terebi Oekaki */
693/* The following code comes from sg1000.c. We should eventually merge these TV Draw implementations */
694static WRITE8_HANDLER( sms_tvdraw_axis_w )
695{
696   sms_state *state = space->machine().driver_data<sms_state>();
697   UINT8 tvboard_on = input_port_read_safe(space->machine(), "TVDRAW", 0x00);
698
699   if (data & 0x01)
700   {
701      state->m_tvdraw_data = tvboard_on ? input_port_read(space->machine(), "TVDRAW_X") : 0x80;
702
703      if (state->m_tvdraw_data < 4) state->m_tvdraw_data = 4;
704      if (state->m_tvdraw_data > 251) state->m_tvdraw_data = 251;
705   }
706   else
707   {
708      state->m_tvdraw_data = tvboard_on ? input_port_read(space->machine(), "TVDRAW_Y") + 0x20 : 0x80;
709   }
710}
711
712static READ8_HANDLER( sms_tvdraw_status_r )
713{
714   UINT8 tvboard_on = input_port_read_safe(space->machine(), "TVDRAW", 0x00);
715   return tvboard_on ? input_port_read(space->machine(), "TVDRAW_PEN") : 0x01;
716}
717
718static READ8_HANDLER( sms_tvdraw_data_r )
719{
720   sms_state *state = space->machine().driver_data<sms_state>();
721   return state->m_tvdraw_data;
722}
723
724
725WRITE8_HANDLER( sms_mapper_w )
726{
727   sms_state *state = space->machine().driver_data<sms_state>();
728   int page;
729   UINT8 *SOURCE_BIOS;
730   UINT8 *SOURCE_CART;
731   UINT8 *SOURCE;
732   UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
733
734   offset &= 3;
735
736   state->m_mapper[offset] = data;
737   state->m_mapper_ram[offset] = data;
738
739   if (state->m_cartridge[state->m_current_cartridge].ROM)
740   {
741      SOURCE_CART = state->m_cartridge[state->m_current_cartridge].ROM + (( rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000;
742   }
743   else
744   {
745      SOURCE_CART = state->m_banking_none[1];
746   }
747
748   if (state->m_BIOS)
749   {
750      SOURCE_BIOS = state->m_BIOS + ((state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0) * 0x4000;
751   }
752   else
753   {
754      SOURCE_BIOS = state->m_banking_none[1];
755   }
756
757   if (state->m_bios_port & IO_BIOS_ROM || (state->m_is_gamegear && state->m_BIOS == NULL))
758   {
759      if (!(state->m_bios_port & IO_CARTRIDGE) || (state->m_is_gamegear && state->m_BIOS == NULL))
760      {
761         page = (rom_page_count > 0) ? data % rom_page_count : 0;
762         if (!state->m_cartridge[state->m_current_cartridge].ROM)
763            return;
764         SOURCE = SOURCE_CART;
765      }
766      else
767      {
768         /* nothing to page in */
769         return;
770      }
771   }
772   else
773   {
774      page = (state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0;
775      if (!state->m_BIOS)
776         return;
777      SOURCE = SOURCE_BIOS;
778   }
779
780   switch (offset)
781   {
782   case 0: /* Control */
783      /* Is it ram or rom? */
784      if (data & 0x08) /* it's ram */
785      {
786         state->m_cartridge[state->m_current_cartridge].sram_save = 1;         /* SRAM should be saved on exit. */
787         if (data & 0x04)
788         {
789            LOG(("ram 1 paged.\n"));
790            SOURCE = state->m_cartridge[state->m_current_cartridge].cartSRAM + 0x4000;
791         }
792         else
793         {
794            LOG(("ram 0 paged.\n"));
795            SOURCE = state->m_cartridge[state->m_current_cartridge].cartSRAM;
796         }
797         memory_set_bankptr(space->machine(),  "bank5", SOURCE);
798         memory_set_bankptr(space->machine(),  "bank6", SOURCE + 0x2000);
799      }
800      else /* it's rom */
801      {
802         if (state->m_bios_port & IO_BIOS_ROM || ! state->m_has_bios)
803         {
804            page = (rom_page_count > 0) ? state->m_mapper[3] % rom_page_count : 0;
805            SOURCE = state->m_banking_cart[5];
806         }
807         else
808         {
809            page = (state->m_bios_page_count > 0) ? state->m_mapper[3] % state->m_bios_page_count : 0;
810            SOURCE = state->m_banking_bios[5];
811         }
812         LOG(("rom 2 paged in %x.\n", page));
813         memory_set_bankptr(space->machine(), "bank5", SOURCE);
814         memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
815      }
816      break;
817
818   case 1: /* Select 16k ROM bank for 0400-3FFF */
819      LOG(("rom 0 paged in %x.\n", page));
820      state->m_banking_bios[2] = SOURCE_BIOS + 0x0400;
821      state->m_banking_cart[2] = SOURCE_CART + 0x0400;
822      if (state->m_is_gamegear)
823         SOURCE = SOURCE_CART;
824
825      memory_set_bankptr(space->machine(), "bank2", SOURCE + 0x0400);
826      break;
827
828   case 2: /* Select 16k ROM bank for 4000-7FFF */
829      LOG(("rom 1 paged in %x.\n", page));
830      state->m_banking_bios[3] = SOURCE_BIOS;
831      state->m_banking_cart[3] = SOURCE_CART;
832      if (state->m_is_gamegear)
833         SOURCE = SOURCE_CART;
834
835      memory_set_bankptr(space->machine(), "bank3", SOURCE);
836      memory_set_bankptr(space->machine(), "bank4", SOURCE + 0x2000);
837      break;
838
839   case 3: /* Select 16k ROM bank for 8000-BFFF */
840      state->m_banking_bios[5] = SOURCE_BIOS;
841      if (state->m_is_gamegear)
842         SOURCE = SOURCE_CART;
843
844      if ( state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
845      {
846         if (SOURCE == SOURCE_CART)
847         {
848            SOURCE = state->m_banking_cart[5];
849         }
850      }
851      else
852      {
853         state->m_banking_cart[5] = SOURCE_CART;
854      }
855
856      if (!(state->m_mapper[0] & 0x08)) /* is RAM disabled? */
857      {
858         LOG(("rom 2 paged in %x.\n", page));
859         memory_set_bankptr(space->machine(), "bank5", SOURCE);
860         memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
861      }
862      break;
863   }
864}
865
866#ifdef MESS
867static WRITE8_HANDLER( sms_korean_zemina_banksw_w )
868{
869   sms_state *state = space->machine().driver_data<sms_state>();
870
871   if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_MAPPER)
872   {
873      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x2000;
874      int page = (rom_page_count > 0) ? data % rom_page_count : 0;
875
876      if (!state->m_cartridge[state->m_current_cartridge].ROM)
877         return;
878
879      switch (offset & 3)
880      {
881         case 0:
882            state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
883            memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]);
884            break;
885         case 1:
886            state->m_banking_cart[6] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
887            memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[6]);
888            break;
889         case 2:
890            state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
891            memory_set_bankptr(space->machine(), "bank3", state->m_banking_cart[3]);
892            break;
893         case 3:
894            state->m_banking_cart[4] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
895            memory_set_bankptr(space->machine(), "bank4", state->m_banking_cart[4]);
896            break;
897      }
898      LOG(("Zemina mapper write: offset %x data %x.\n", offset, page));
899   }
900}
901
902static WRITE8_HANDLER( sms_codemasters_page0_w )
903{
904   sms_state *state = space->machine().driver_data<sms_state>();
905
906   if (state->m_cartridge[state->m_current_cartridge].ROM && state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
907   {
908      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
909      state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM + ((rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000;
910      state->m_banking_cart[2] = state->m_banking_cart[1] + 0x0400;
911      memory_set_bankptr(space->machine(), "bank1", state->m_banking_cart[1]);
912      memory_set_bankptr(space->machine(), "bank2", state->m_banking_cart[2]);
913   }
914}
915
916
917static WRITE8_HANDLER( sms_codemasters_page1_w )
918{
919   sms_state *state = space->machine().driver_data<sms_state>();
920
921   if (state->m_cartridge[state->m_current_cartridge].ROM && state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
922   {
923      /* Check if we need to switch in some RAM */
924      if (data & 0x80)
925      {
926         state->m_cartridge[state->m_current_cartridge].ram_page = data & 0x07;
927         memory_set_bankptr(space->machine(), "bank6", state->m_cartridge[state->m_current_cartridge].cartRAM + state->m_cartridge[state->m_current_cartridge].ram_page * 0x2000);
928      }
929      else
930      {
931         UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
932         state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000;
933         memory_set_bankptr(space->machine(), "bank3", state->m_banking_cart[3]);
934         memory_set_bankptr(space->machine(), "bank4", state->m_banking_cart[3] + 0x2000);
935         memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000);
936      }
937   }
938}
939#endif
940
941static READ8_HANDLER( sms_kor_nobank_r )
942{
943//  printf("read %x\n", offset);
944   return space->read_byte(0xdffc + offset);
945}
946
947static WRITE8_HANDLER( sms_kor_nobank_w )
948{
949   sms_state *state = space->machine().driver_data<sms_state>();
950   UINT8 *SOURCE_BIOS;
951   UINT8 *SOURCE = NULL;
952
953   space->write_byte(0xdffc + offset, data);
954   state->m_mapper[offset] = data;
955
956   // FIXME: the code below (which only handles the BIOS bankswitch at start) should be cleaned up
957   // currently, it's just a stripped down version of sms_mapper_w
958   if (state->m_BIOS)
959      SOURCE_BIOS = state->m_BIOS + ((state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0) * 0x4000;
960   else
961      SOURCE_BIOS = state->m_banking_none[1];
962
963   if (state->m_bios_port & IO_BIOS_ROM || (state->m_is_gamegear && state->m_BIOS == NULL))
964      return;
965   else
966   {
967      if (!state->m_BIOS)
968         return;
969      SOURCE = SOURCE_BIOS;
970   }
971
972//  printf("write %x, %x\n", offset, data);
973
974   switch (offset)
975   {
976      case 0: /* Control */
977         if (!(data & 0x08)) /* it's not ram */
978         {
979            if (!(state->m_bios_port & IO_BIOS_ROM) && state->m_has_bios)
980            {
981               SOURCE = state->m_banking_bios[5];
982               memory_set_bankptr(space->machine(), "bank5", SOURCE);
983               memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
984            }
985         }
986         break;
987
988      case 1: /* Select 16k ROM bank for 0400-3FFF */
989         state->m_banking_bios[2] = SOURCE_BIOS + 0x0400;
990         memory_set_bankptr(space->machine(), "bank2", SOURCE + 0x0400);
991         break;
992
993      case 2: /* Select 16k ROM bank for 4000-7FFF */
994         state->m_banking_bios[3] = SOURCE_BIOS;
995         memory_set_bankptr(space->machine(), "bank3", SOURCE);
996         memory_set_bankptr(space->machine(), "bank4", SOURCE + 0x2000);
997         break;
998
999      case 3: /* Select 16k ROM bank for 8000-BFFF */
1000         state->m_banking_bios[5] = SOURCE_BIOS;
1001         if (!(state->m_mapper[0] & 0x08)) /* is RAM disabled? */
1002         {
1003            memory_set_bankptr(space->machine(), "bank5", SOURCE);
1004            memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
1005         }
1006         break;
1007   }
1008}
1009
1010WRITE8_HANDLER( sms_bios_w )
1011{
1012   sms_state *state = space->machine().driver_data<sms_state>();
1013   state->m_bios_port = data;
1014
1015   logerror("bios write %02x, pc: %04x\n", data, cpu_get_pc(&space->device()));
1016
1017   setup_rom(space);
1018}
1019
1020
1021WRITE8_HANDLER( sms_cartram2_w )
1022{
1023   sms_state *state = space->machine().driver_data<sms_state>();
1024
1025   if (state->m_mapper[0] & 0x08)
1026   {
1027      logerror("write %02X to cartram at offset #%04X\n", data, offset + 0x2000);
1028      if (state->m_mapper[0] & 0x04)
1029      {
1030         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x6000] = data;
1031      }
1032      else
1033      {
1034         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x2000] = data;
1035      }
1036   }
1037
1038   if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
1039   {
1040      state->m_cartridge[state->m_current_cartridge].cartRAM[state->m_cartridge[state->m_current_cartridge].ram_page * 0x2000 + offset] = data;
1041   }
1042
1043   if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_MAPPER && offset == 0) /* Dodgeball King mapper */
1044   {
1045      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
1046      int page = (rom_page_count > 0) ? data % rom_page_count : 0;
1047
1048      if (!state->m_cartridge[state->m_current_cartridge].ROM)
1049         return;
1050
1051      state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x4000;
1052      memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]);
1053      memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000);
1054      LOG(("rom 2 paged in %x (Korean mapper).\n", page));
1055   }
1056}
1057
1058
1059WRITE8_HANDLER( sms_cartram_w )
1060{
1061   sms_state *state = space->machine().driver_data<sms_state>();
1062   int page;
1063
1064   if (state->m_mapper[0] & 0x08)
1065   {
1066      logerror("write %02X to cartram at offset #%04X\n", data, offset);
1067      if (state->m_mapper[0] & 0x04)
1068      {
1069         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x4000] = data;
1070      }
1071      else
1072      {
1073         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset] = data;
1074      }
1075   }
1076   else
1077   {
1078      if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER && offset == 0) /* Codemasters mapper */
1079      {
1080         UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
1081         page = (rom_page_count > 0) ? data % rom_page_count : 0;
1082         if (!state->m_cartridge[state->m_current_cartridge].ROM)
1083            return;
1084         state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x4000;
1085         memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]);
1086         memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000);
1087         LOG(("rom 2 paged in %x (Codemasters mapper).\n", page));
1088      }
1089      else if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM)
1090      {
1091         state->m_cartridge[state->m_current_cartridge].cartRAM[offset & (state->m_cartridge[state->m_current_cartridge].ram_size - 1)] = data;
1092      }
1093      else
1094      {
1095         logerror("INVALID write %02X to cartram at offset #%04X\n", data, offset);
1096      }
1097   }
1098}
1099
1100
1101WRITE8_HANDLER( gg_sio_w )
1102{
1103   sms_state *state = space->machine().driver_data<sms_state>();
1104   logerror("*** write %02X to SIO register #%d\n", data, offset);
1105
1106   state->m_gg_sio[offset & 0x07] = data;
1107   switch (offset & 7)
1108   {
1109      case 0x00: /* Parallel Data */
1110         break;
1111
1112      case 0x01: /* Data Direction/ NMI Enable */
1113         break;
1114
1115      case 0x02: /* Serial Output */
1116         break;
1117
1118      case 0x03: /* Serial Input */
1119         break;
1120
1121      case 0x04: /* Serial Control / Status */
1122         break;
1123   }
1124}
1125
1126
1127READ8_HANDLER( gg_sio_r )
1128{
1129   sms_state *state = space->machine().driver_data<sms_state>();
1130   logerror("*** read SIO register #%d\n", offset);
1131
1132   switch (offset & 7)
1133   {
1134      case 0x00: /* Parallel Data */
1135         break;
1136
1137      case 0x01: /* Data Direction/ NMI Enable */
1138         break;
1139
1140      case 0x02: /* Serial Output */
1141         break;
1142
1143      case 0x03: /* Serial Input */
1144         break;
1145
1146      case 0x04: /* Serial Control / Status */
1147         break;
1148   }
1149
1150   return state->m_gg_sio[offset];
1151}
1152
1153static void sms_machine_stop( running_machine &machine )
1154{
1155   sms_state *state = machine.driver_data<sms_state>();
1156
1157   /* Does the cartridge have SRAM that should be saved? */
1158   if (state->m_cartridge[state->m_current_cartridge].sram_save) {
1159      device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart1"));
1160      image->battery_save(state->m_cartridge[state->m_current_cartridge].cartSRAM, sizeof(UINT8) * NVRAM_SIZE );
1161   }
1162}
1163
1164
1165static void setup_rom( address_space *space )
1166{
1167   sms_state *state = space->machine().driver_data<sms_state>();
1168   running_machine &machine = space->machine();
1169
1170   /* 1. set up bank pointers to point to nothing */
1171   memory_set_bankptr(machine, "bank1", state->m_banking_none[1]);
1172   memory_set_bankptr(machine, "bank2", state->m_banking_none[2]);
1173   memory_set_bankptr(machine, "bank3", state->m_banking_none[3]);
1174   memory_set_bankptr(machine, "bank4", state->m_banking_none[3] + 0x2000);
1175   memory_set_bankptr(machine, "bank5", state->m_banking_none[5]);
1176   memory_set_bankptr(machine, "bank6", state->m_banking_none[5] + 0x2000);
1177
1178   /* 2. check and set up expansion port */
1179   if (!(state->m_bios_port & IO_EXPANSION) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_CARD))
1180   {
1181      /* TODO: Implement me */
1182      logerror("Switching to unsupported expansion port.\n");
1183   }
1184
1185   /* 3. check and set up card rom */
1186   if (!(state->m_bios_port & IO_CARD) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_EXPANSION))
1187   {
1188      /* TODO: Implement me */
1189      logerror("Switching to unsupported card rom port.\n");
1190   }
1191
1192   /* 4. check and set up cartridge rom */
1193   /* if ((!(bios_port & IO_CARTRIDGE) && (bios_port & IO_EXPANSION) && (bios_port & IO_CARD)) || state->m_is_gamegear) { */
1194   /* Out Run Europa initially writes a value to port 3E where IO_CARTRIDGE, IO_EXPANSION and IO_CARD are reset */
1195   if ((!(state->m_bios_port & IO_CARTRIDGE)) || state->m_is_gamegear)
1196   {
1197      memory_set_bankptr(machine, "bank1", state->m_banking_cart[1]);
1198      memory_set_bankptr(machine, "bank2", state->m_banking_cart[2]);
1199      memory_set_bankptr(machine, "bank3", state->m_banking_cart[3]);
1200      memory_set_bankptr(machine, "bank4", state->m_banking_cart[3] + 0x2000);
1201      memory_set_bankptr(machine, "bank5", state->m_banking_cart[5]);
1202      memory_set_bankptr(machine, "bank6", state->m_banking_cart[5] + 0x2000);
1203      logerror("Switched in cartridge rom.\n");
1204   }
1205
1206   /* 5. check and set up bios rom */
1207   if (!(state->m_bios_port & IO_BIOS_ROM))
1208   {
1209      /* 0x0400 bioses */
1210      if (state->m_has_bios_0400)
1211      {
1212         memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]);
1213         logerror("Switched in 0x0400 bios.\n");
1214      }
1215      /* 0x2000 bioses */
1216      if (state->m_has_bios_2000)
1217      {
1218         memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]);
1219         memory_set_bankptr(machine, "bank2", state->m_banking_bios[2]);
1220         logerror("Switched in 0x2000 bios.\n");
1221      }
1222      if (state->m_has_bios_full)
1223      {
1224         memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]);
1225         memory_set_bankptr(machine, "bank2", state->m_banking_bios[2]);
1226         memory_set_bankptr(machine, "bank3", state->m_banking_bios[3]);
1227         memory_set_bankptr(machine, "bank4", state->m_banking_bios[3] + 0x2000);
1228         memory_set_bankptr(machine, "bank5", state->m_banking_bios[5]);
1229         memory_set_bankptr(machine, "bank6", state->m_banking_bios[5] + 0x2000);
1230         logerror("Switched in full bios.\n");
1231      }
1232   }
1233
1234   if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM)
1235   {
1236      memory_set_bankptr(machine, "bank5", state->m_cartridge[state->m_current_cartridge].cartRAM);
1237      memory_set_bankptr(machine, "bank6", state->m_cartridge[state->m_current_cartridge].cartRAM);
1238   }
1239}
1240
1241
1242static int sms_verify_cart( UINT8 *magic, int size )
1243{
1244   int retval;
1245
1246   retval = IMAGE_VERIFY_FAIL;
1247
1248   /* Verify the file is a valid image - check $7ff0 for "TMR SEGA" */
1249   if (size >= 0x8000)
1250   {
1251      if (!strncmp((char*)&magic[0x7ff0], "TMR SEGA", 8))
1252      {
1253#if 0
1254         /* Technically, it should be this, but remove for now until verified: */
1255         if (!strcmp(sysname, "gamegear"))
1256         {
1257            if ((unsigned char)magic[0x7ffd] < 0x50)
1258               retval = IMAGE_VERIFY_PASS;
1259         }
1260         if (!strcmp(sysname, "sms"))
1261         {
1262            if ((unsigned char)magic[0x7ffd] >= 0x50)
1263               retval = IMAGE_VERIFY_PASS;
1264         }
1265#endif
1266         retval = IMAGE_VERIFY_PASS;
1267      }
1268
1269#if 0
1270      /* Check at $81f0 also */
1271      if (!retval)
1272      {
1273         if (!strncmp(&magic[0x81f0], "TMR SEGA", 8))
1274         {
1275#if 0
1276            /* Technically, it should be this, but remove for now until verified: */
1277            if (!strcmp(sysname, "gamegear"))
1278            {
1279               if ((unsigned char)magic[0x81fd] < 0x50)
1280                  retval = IMAGE_VERIFY_PASS;
1281            }
1282            if (!strcmp(sysname, "sms"))
1283            {
1284               if ((unsigned char)magic[0x81fd] >= 0x50)
1285                  retval = IMAGE_VERIFY_PASS;
1286            }
1287#endif
1288            retval = IMAGE_VERIFY_PASS;
1289         }
1290      }
1291#endif
1292
1293   }
1294
1295   return retval;
1296}
1297
1298#ifdef UNUSED_FUNCTION
1299// For the moment we switch to a different detection routine which allows to detect
1300// in a single run Codemasters mapper, Korean mapper (including Jang Pung 3 which
1301// uses a diff signature then the one below here) and Zemina mapper (used by Wonsiin, etc.).
1302// I leave these here to document alt. detection routines and in the case these functions
1303// can be updated
1304
1305/* Check for Codemasters mapper
1306  0x7FE3 - 93 - sms Cosmis Spacehead
1307              - sms Dinobasher
1308              - sms The Excellent Dizzy Collection
1309              - sms Fantastic Dizzy
1310              - sms Micro Machines
1311              - gamegear Cosmic Spacehead
1312              - gamegear Micro Machines
1313         - 94 - gamegear Dropzone
1314              - gamegear Ernie Els Golf (also has 64KB additional RAM on the cartridge)
1315              - gamegear Pete Sampras Tennis
1316              - gamegear S.S. Lucifer
1317         - 95 - gamegear Micro Machines 2 - Turbo Tournament
1318
1319The Korean game Jang Pung II also seems to use a codemasters style mapper.
1320 */
1321static int detect_codemasters_mapper( UINT8 *rom )
1322{
1323   static const UINT8 jang_pung2[16] = { 0x00, 0xba, 0x38, 0x0d, 0x00, 0xb8, 0x38, 0x0c, 0x00, 0xb6, 0x38, 0x0b, 0x00, 0xb4, 0x38, 0x0a };
1324
1325   if (((rom[0x7fe0] & 0x0f ) <= 9) && (rom[0x7fe3] == 0x93 || rom[0x7fe3] == 0x94 || rom[0x7fe3] == 0x95) &&  rom[0x7fef] == 0x00)
1326      return 1;
1327
1328   if (!memcmp(&rom[0x7ff0], jang_pung2, 16))
1329      return 1;
1330
1331   return 0;
1332}
1333
1334
1335static int detect_korean_mapper( UINT8 *rom )
1336{
1337   static const UINT8 signatures[2][16] =
1338   {
1339      { 0x3e, 0x11, 0x32, 0x00, 0xa0, 0x78, 0xcd, 0x84, 0x85, 0x3e, 0x02, 0x32, 0x00, 0xa0, 0xc9, 0xff }, /* Dodgeball King */
1340      { 0x41, 0x48, 0x37, 0x37, 0x44, 0x37, 0x4e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20 },   /* Sangokushi 3 */
1341   };
1342   int i;
1343
1344   for (i = 0; i < 2; i++)
1345   {
1346      if (!memcmp(&rom[0x7ff0], signatures[i], 16))
1347      {
1348         return 1;
1349      }
1350   }
1351   return 0;
1352}
1353#endif
1354
1355
1356static int detect_tvdraw( UINT8 *rom )
1357{
1358   static const UINT8 terebi_oekaki[7] = { 0x61, 0x6e, 0x6e, 0x61, 0x6b, 0x6d, 0x6e };   // "annakmn"
1359
1360   if (!memcmp(&rom[0x13b3], terebi_oekaki, 7))
1361      return 1;
1362
1363   return 0;
1364}
1365
1366
1367static int detect_lphaser_xoffset( running_machine &machine, UINT8 *rom )
1368{
1369   sms_state *state = machine.driver_data<sms_state>();
1370
1371   static const UINT8 signatures[6][16] =
1372   {
1373      /* Spacegun */
1374      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9d, 0x99, 0x10, 0x90, 0x00, 0x40 },
1375      /* Gangster Town */
1376      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x19, 0x87, 0x1b, 0xc9, 0x74, 0x50, 0x00, 0x4f },
1377      /* Shooting Gallery */
1378      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x20, 0x8a, 0x3a, 0x72, 0x50, 0x00, 0x4f },
1379      /* Rescue Mission */
1380      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x20, 0xfb, 0xd3, 0x06, 0x51, 0x00, 0x4f },
1381      /* Laser Ghost */
1382      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x00, 0x00, 0xb7, 0x55, 0x74, 0x70, 0x00, 0x40 },
1383      /* Assault City */
1384      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9f, 0x74, 0x34, 0x70, 0x00, 0x40 },
1385   };
1386
1387   if (!(state->m_bios_port & IO_CARTRIDGE) && state->m_cartridge[state->m_current_cartridge].size >= 0x8000)
1388   {
1389      if (!memcmp(&rom[0x7ff0], signatures[0], 16) || !memcmp(&rom[0x7ff0], signatures[1], 16))
1390         return 40;
1391
1392      if (!memcmp(&rom[0x7ff0], signatures[2], 16))
1393         return 49;
1394
1395      if (!memcmp(&rom[0x7ff0], signatures[3], 16))
1396         return 47;
1397
1398      if (!memcmp(&rom[0x7ff0], signatures[4], 16))
1399         return 44;
1400
1401      if (!memcmp(&rom[0x7ff0], signatures[5], 16))
1402         return 53;
1403
1404   }
1405   return 50;
1406}
1407
1408
1409DEVICE_START( sms_cart )
1410{
1411   sms_state *state = device->machine().driver_data<sms_state>();
1412   int i;
1413
1414   for (i = 0; i < MAX_CARTRIDGES; i++)
1415   {
1416      state->m_cartridge[i].ROM = NULL;
1417      state->m_cartridge[i].size = 0;
1418      state->m_cartridge[i].features = 0;
1419      state->m_cartridge[i].cartSRAM = NULL;
1420      state->m_cartridge[i].sram_save = 0;
1421      state->m_cartridge[i].cartRAM = NULL;
1422      state->m_cartridge[i].ram_size = 0;
1423      state->m_cartridge[i].ram_page = 0;
1424   }
1425   state->m_current_cartridge = 0;
1426
1427   state->m_bios_port = (IO_EXPANSION | IO_CARTRIDGE | IO_CARD);
1428   if (!state->m_is_gamegear && !state->m_has_bios)
1429   {
1430      state->m_bios_port &= ~(IO_CARTRIDGE);
1431      state->m_bios_port |= IO_BIOS_ROM;
1432   }
1433}
1434
1435
1436DEVICE_IMAGE_LOAD( sms_cart )
1437{
1438   running_machine &machine = image.device().machine();
1439   sms_state *state = machine.driver_data<sms_state>();
1440   int size, index = 0, offset = 0;
1441   const char *extrainfo = NULL;
1442
1443   if (strcmp(image.device().tag(), "cart1") == 0)
1444      index = 0;
1445   if (strcmp(image.device().tag(), "cart2") == 0)
1446      index = 1;
1447   if (strcmp(image.device().tag(), "cart3") == 0)
1448      index = 2;
1449   if (strcmp(image.device().tag(), "cart4") == 0)
1450      index = 3;
1451   if (strcmp(image.device().tag(), "cart5") == 0)
1452      index = 4;
1453   if (strcmp(image.device().tag(), "cart6") == 0)
1454      index = 5;
1455   if (strcmp(image.device().tag(), "cart7") == 0)
1456      index = 6;
1457   if (strcmp(image.device().tag(), "cart8") == 0)
1458      index = 7;
1459   if (strcmp(image.device().tag(), "cart9") == 0)
1460      index = 8;
1461   if (strcmp(image.device().tag(), "cart10") == 0)
1462      index = 9;
1463   if (strcmp(image.device().tag(), "cart11") == 0)
1464      index = 10;
1465   if (strcmp(image.device().tag(), "cart12") == 0)
1466      index = 11;
1467   if (strcmp(image.device().tag(), "cart13") == 0)
1468      index = 12;
1469   if (strcmp(image.device().tag(), "cart14") == 0)
1470      index = 13;
1471   if (strcmp(image.device().tag(), "cart15") == 0)
1472      index = 14;
1473   if (strcmp(image.device().tag(), "cart16") == 0)
1474      index = 15;
1475
1476   state->m_cartridge[index].features = 0;
1477
1478   if (image.software_entry() == NULL)
1479   {
1480      size = image.length();
1481      extrainfo = hashfile_extrainfo(image);
1482   }
1483   else
1484      size = image.get_software_region_length("rom");
1485
1486   /* Check for 512-byte header */
1487   if ((size / 512) & 1)
1488   {
1489      offset = 512;
1490      size -= 512;
1491   }
1492
1493   if (!size)
1494   {
1495      image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM image: ROM image is too small");
1496      return IMAGE_INIT_FAIL;
1497   }
1498
1499   /* Create a new memory region to hold the ROM. */
1500   /* Make sure the region holds only complete (0x4000) rom banks */
1501   state->m_cartridge[index].size = (size & 0x3fff) ? (((size >> 14) + 1) << 14) : size;
1502   state->m_cartridge[index].ROM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].size);
1503   state->m_cartridge[index].cartSRAM = auto_alloc_array(machine, UINT8, NVRAM_SIZE);
1504
1505   /* Load ROM banks */
1506   if (image.software_entry() == NULL)
1507   {
1508      image.fseek(offset, SEEK_SET);
1509
1510      if (image.fread( state->m_cartridge[index].ROM, size) != size)
1511         return IMAGE_INIT_FAIL;
1512   }
1513   else
1514   {
1515      memcpy(state->m_cartridge[index].ROM, image.get_software_region("rom") + offset, size);
1516
1517      // check for mapper feature (currently only KOREAN_NOBANK, but eventually we will add the other mappers as well)
1518      if (image.get_feature("pcb") != NULL)
1519      {
1520         const char *mapper = image.get_feature("pcb");
1521         if (!strcmp(mapper, "korean_nobank"))
1522            state->m_cartridge[index].features |= CF_KOREAN_NOBANK_MAPPER;
1523      }
1524   }
1525
1526   /* check the image */
1527   if (!state->m_has_bios)
1528   {
1529      if (sms_verify_cart(state->m_cartridge[index].ROM, size) == IMAGE_VERIFY_FAIL)
1530      {
1531         logerror("Warning loading image: sms_verify_cart failed\n");
1532      }
1533   }
1534
1535   /* Detect special features from the extrainfo field */
1536   if (extrainfo)
1537   {
1538      /* Check for codemasters mapper */
1539      if (strstr(extrainfo, "CODEMASTERS"))
1540         state->m_cartridge[index].features |= CF_CODEMASTERS_MAPPER;
1541
1542      /* Check for korean mapper */
1543      if (strstr(extrainfo, "KOREAN"))
1544         state->m_cartridge[index].features |= CF_KOREAN_MAPPER;
1545
1546      /* Check for special SMS Compatibility mode gamegear cartridges */
1547      if (state->m_is_gamegear && strstr(extrainfo, "GGSMS"))
1548         state->m_cartridge[index].features |= CF_GG_SMS_MODE;
1549
1550      /* Check for 93C46 eeprom */
1551      if (strstr(extrainfo, "93C46"))
1552         state->m_cartridge[index].features |= CF_93C46_EEPROM;
1553
1554      /* Check for 8KB on-cart RAM */
1555      if (strstr(extrainfo, "8KB_CART_RAM"))
1556      {
1557         state->m_cartridge[index].features |= CF_ONCART_RAM;
1558         state->m_cartridge[index].ram_size = 0x2000;
1559         state->m_cartridge[index].cartRAM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].ram_size);
1560      }
1561   }
1562   else
1563   {
1564      /* If no extrainfo information is available try to find special information out on our own */
1565      /* Check for special cartridge features (new routine, courtesy of Omar Cornut, from MEKA)  */
1566      if (size >= 0x8000)
1567      {
1568         int c0002 = 0, c8000 = 0, cA000 = 0, cFFFF = 0, i;
1569         for (i = 0; i < 0x8000; i++)
1570         {
1571            if (state->m_cartridge[index].ROM[i] == 0x32) // Z80 opcode for: LD (xxxx), A
1572            {
1573               UINT16 addr = (state->m_cartridge[index].ROM[i + 2] << 8) | state->m_cartridge[index].ROM[i + 1];
1574               if (addr == 0xFFFF)
1575               { i += 2; cFFFF++; continue; }
1576               if (addr == 0x0002 || addr == 0x0003 || addr == 0x0004)
1577               { i += 2; c0002++; continue; }
1578               if (addr == 0x8000)
1579               { i += 2; c8000++; continue; }
1580               if (addr == 0xA000)
1581               { i += 2; cA000++; continue; }
1582            }
1583         }
1584
1585         LOG(("Mapper test: c002 = %d, c8000 = %d, cA000 = %d, cFFFF = %d\n", c0002, c8000, cA000, cFFFF));
1586
1587         // 2 is a security measure, although tests on existing ROM showed it was not needed
1588         if (c0002 > cFFFF + 2 || (c0002 > 0 && cFFFF == 0))
1589            state->m_cartridge[index].features |= CF_KOREAN_ZEMINA_MAPPER;
1590         else if (c8000 > cFFFF + 2 || (c8000 > 0 && cFFFF == 0))
1591            state->m_cartridge[index].features |= CF_CODEMASTERS_MAPPER;
1592         else if (cA000 > cFFFF + 2 || (cA000 > 0 && cFFFF == 0))
1593            state->m_cartridge[index].features |= CF_KOREAN_MAPPER;
1594
1595      }
1596
1597      /* Check for special SMS Compatibility mode gamegear cartridges */
1598      if (state->m_is_gamegear && image.software_entry() == NULL)   // not sure about how to handle this with softlists
1599      {
1600         /* Just in case someone passes us an sms file */
1601         if (!mame_stricmp (image.filetype(), "sms"))
1602            state->m_cartridge[index].features |= CF_GG_SMS_MODE;
1603      }
1604   }
1605
1606   if (state->m_cartridge[index].features & CF_CODEMASTERS_MAPPER)
1607   {
1608      state->m_cartridge[index].ram_size = 0x10000;
1609      state->m_cartridge[index].cartRAM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].ram_size);
1610      state->m_cartridge[index].ram_page = 0;
1611   }
1612
1613   /* For Light Phaser games, we have to detect the x offset */
1614   state->m_lphaser_x_offs = detect_lphaser_xoffset(machine, state->m_cartridge[index].ROM);
1615
1616   /* Terebi Oekaki (TV Draw) is a SG1000 game with special input device which is compatible with SG1000 Mark III */
1617   if ((detect_tvdraw(state->m_cartridge[index].ROM)) && state->m_is_region_japan)
1618   {
1619      address_space *program = machine.device("maincpu")->memory().space(AS_PROGRAM);
1620      program->install_legacy_write_handler(0x6000, 0x6000, FUNC(sms_tvdraw_axis_w));
1621      program->install_legacy_read_handler(0x8000, 0x8000, FUNC(sms_tvdraw_status_r));
1622      program->install_legacy_read_handler(0xa000, 0xa000, FUNC(sms_tvdraw_data_r));
1623      program->nop_write(0xa000, 0xa000);
1624   }
1625
1626   if (state->m_cartridge[index].features & CF_KOREAN_NOBANK_MAPPER)
1627   {
1628      // FIXME: we should have by default FFFD-FFFF to be only a mirror for DFFD-DFFF (with no bankswitch logic)
1629      // and then the handlers should be installed here for all but the KOREAN_NOBANK carts
1630      // However, to avoid memory map breakage, we currently go the other way around
1631      address_space *program = machine.device("maincpu")->memory().space(AS_PROGRAM);
1632      program->install_legacy_readwrite_handler(0xfffc, 0xffff, FUNC(sms_kor_nobank_r), FUNC(sms_kor_nobank_w));
1633   }
1634
1635   LOG(("Cart Features: %x\n", state->m_cartridge[index].features));
1636
1637   /* Load battery backed RAM, if available */
1638   image.battery_load(state->m_cartridge[index].cartSRAM, sizeof(UINT8) * NVRAM_SIZE, 0x00);
1639
1640   return IMAGE_INIT_PASS;
1641}
1642
1643
1644static void setup_cart_banks( running_machine &machine )
1645{
1646   sms_state *state = machine.driver_data<sms_state>();
1647   if (state->m_cartridge[state->m_current_cartridge].ROM)
1648   {
1649      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
1650      state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM;
1651      state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + 0x0400;
1652      state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0);
1653      state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0);
1654      /* Codemasters mapper points to bank 0 for page 2 */
1655      if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
1656      {
1657         state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM;
1658      }
1659   }
1660   else
1661   {
1662      state->m_banking_cart[1] = state->m_banking_none[1];
1663      state->m_banking_cart[2] = state->m_banking_none[2];
1664      state->m_banking_cart[3] = state->m_banking_none[3];
1665      state->m_banking_cart[5] = state->m_banking_none[5];
1666   }
1667}
1668
1669#ifdef MESS
1670static void setup_banks( running_machine &machine )
1671{
1672   sms_state *state = machine.driver_data<sms_state>();
1673   UINT8 *mem = machine.region("maincpu")->base();
1674   state->m_banking_bios[1] = state->m_banking_cart[1] = state->m_banking_none[1] = mem;
1675   state->m_banking_bios[2] = state->m_banking_cart[2] = state->m_banking_none[2] = mem;
1676   state->m_banking_bios[3] = state->m_banking_cart[3] = state->m_banking_none[3] = mem;
1677   state->m_banking_bios[4] = state->m_banking_cart[4] = state->m_banking_none[4] = mem;
1678   state->m_banking_bios[5] = state->m_banking_cart[5] = state->m_banking_none[5] = mem;
1679   state->m_banking_bios[6] = state->m_banking_cart[6] = state->m_banking_none[6] = mem;
1680
1681   state->m_BIOS = machine.region("user1")->base();
1682
1683   state->m_bios_page_count = (state->m_BIOS ? machine.region("user1")->bytes() / 0x4000 : 0);
1684
1685   setup_cart_banks(machine);
1686
1687   if (state->m_BIOS == NULL || state->m_BIOS[0] == 0x00)
1688   {
1689      state->m_BIOS = NULL;
1690      state->m_bios_port |= IO_BIOS_ROM;
1691   }
1692
1693   if (state->m_BIOS)
1694   {
1695      state->m_banking_bios[1] = state->m_BIOS;
1696      state->m_banking_bios[2] = state->m_BIOS + 0x0400;
1697      state->m_banking_bios[3] = state->m_BIOS + ((1 < state->m_bios_page_count) ? 0x4000 : 0);
1698      state->m_banking_bios[5] = state->m_BIOS + ((2 < state->m_bios_page_count) ? 0x8000 : 0);
1699   }
1700}
1701#endif
1702
1703MACHINE_START( sms )
1704{
1705   sms_state *state = machine.driver_data<sms_state>();
1706
1707   machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sms_machine_stop),&machine));
1708   state->m_rapid_fire_timer = machine.scheduler().timer_alloc(FUNC(rapid_fire_callback));
1709   state->m_rapid_fire_timer->adjust(attotime::from_hz(10), 0, attotime::from_hz(10));
1710
1711   state->m_lphaser_1_timer = machine.scheduler().timer_alloc(FUNC(lphaser_1_callback));
1712   state->m_lphaser_2_timer = machine.scheduler().timer_alloc(FUNC(lphaser_2_callback));
1713
1714   state->m_main_cpu = machine.device("maincpu");
1715   state->m_control_cpu = machine.device("control");
1716   state->m_vdp = machine.device("sms_vdp");
1717   state->m_ym = machine.device("ym2413");
1718   state->m_main_scr = machine.device("screen");
1719   state->m_left_lcd = machine.device("left_lcd");
1720   state->m_right_lcd = machine.device("right_lcd");
1721
1722   /* Check if lightgun has been chosen as input: if so, enable crosshair */
1723   machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick));
1724}
1725
1726#ifdef MESS
1727MACHINE_RESET( sms )
1728{
1729   address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1730   sms_state *state = machine.driver_data<sms_state>();
1731
1732   state->m_ctrl_reg = 0xff;
1733   if (state->m_has_fm)
1734      state->m_fm_detect = 0x01;
1735
1736   state->m_mapper_ram = (UINT8*)space->get_write_ptr(0xdffc);
1737
1738   state->m_bios_port = 0;
1739
1740   if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
1741   {
1742      /* Install special memory handlers */
1743      space->install_legacy_write_handler(0x0000, 0x0000, FUNC(sms_codemasters_page0_w));
1744      space->install_legacy_write_handler(0x4000, 0x4000, FUNC(sms_codemasters_page1_w));
1745   }
1746
1747   if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_MAPPER)
1748      space->install_legacy_write_handler(0x0000, 0x0003, FUNC(sms_korean_zemina_banksw_w));
1749
1750   if (state->m_cartridge[state->m_current_cartridge].features & CF_GG_SMS_MODE)
1751      sms_vdp_set_ggsmsmode(state->m_vdp, 1);
1752
1753   /* Initialize SIO stuff for GG */
1754   state->m_gg_sio[0] = 0x7f;
1755   state->m_gg_sio[1] = 0xff;
1756   state->m_gg_sio[2] = 0x00;
1757   state->m_gg_sio[3] = 0xff;
1758   state->m_gg_sio[4] = 0x00;
1759
1760   state->m_store_control = 0;
1761
1762   setup_banks(machine);
1763
1764   setup_rom(space);
1765
1766   state->m_rapid_fire_state_1 = 0;
1767   state->m_rapid_fire_state_2 = 0;
1768
1769   state->m_last_paddle_read_time = 0;
1770   state->m_paddle_read_state = 0;
1771
1772   state->m_last_sports_pad_time_1 = 0;
1773   state->m_last_sports_pad_time_2 = 0;
1774   state->m_sports_pad_state_1 = 0;
1775   state->m_sports_pad_state_2 = 0;
1776   state->m_sports_pad_last_data_1 = 0;
1777   state->m_sports_pad_last_data_2 = 0;
1778   state->m_sports_pad_1_x = 0;
1779   state->m_sports_pad_1_y = 0;
1780   state->m_sports_pad_2_x = 0;
1781   state->m_sports_pad_2_y = 0;
1782
1783   state->m_lphaser_1_latch = 0;
1784   state->m_lphaser_2_latch = 0;
1785
1786   state->m_sscope_state = 0;
1787
1788   state->m_tvdraw_data = 0;
1789}
1790#endif
1791
1792READ8_HANDLER( sms_store_cart_select_r )
1793{
1794   return 0xff;
1795}
1796
1797
1798WRITE8_HANDLER( sms_store_cart_select_w )
1799{
1800   sms_state *state = space->machine().driver_data<sms_state>();
1801   UINT8 slot = data >> 4;
1802   UINT8 slottype = data & 0x08;
1803
1804   logerror("switching in part of %s slot #%d\n", slottype ? "card" : "cartridge", slot );
1805   /* cartridge? slot #0 */
1806   if (slottype == 0)
1807      state->m_current_cartridge = slot;
1808
1809   setup_cart_banks(space->machine());
1810   memory_set_bankptr(space->machine(), "bank10", state->m_banking_cart[3] + 0x2000);
1811   setup_rom(space);
1812}
1813
1814
1815READ8_HANDLER( sms_store_select1 )
1816{
1817   return 0xff;
1818}
1819
1820
1821READ8_HANDLER( sms_store_select2 )
1822{
1823   return 0xff;
1824}
1825
1826
1827READ8_HANDLER( sms_store_control_r )
1828{
1829   sms_state *state = space->machine().driver_data<sms_state>();
1830   return state->m_store_control;
1831}
1832
1833
1834WRITE8_HANDLER( sms_store_control_w )
1835{
1836   sms_state *state = space->machine().driver_data<sms_state>();
1837   logerror("0x%04X: sms_store_control write 0x%02X\n", cpu_get_pc(&space->device()), data);
1838   if (data & 0x02)
1839   {
1840      space->machine().device<cpu_device>("maincpu")->resume(SUSPEND_REASON_HALT);
1841   }
1842   else
1843   {
1844      /* Pull reset line of CPU #0 low */
1845      space->machine().device("maincpu")->reset();
1846      space->machine().device<cpu_device>("maincpu")->suspend(SUSPEND_REASON_HALT, 1);
1847   }
1848   state->m_store_control = data;
1849}
1850
1851void sms_store_int_callback( running_machine &machine, int state )
1852{
1853   sms_state *driver_state = machine.driver_data<sms_state>();
1854   device_set_input_line(driver_state->m_store_control & 0x01 ? driver_state->m_control_cpu : driver_state->m_main_cpu, 0, state);
1855}
1856
1857
1858static void sms_set_zero_flag( running_machine &machine )
1859{
1860   sms_state *state = machine.driver_data<sms_state>();
1861   state->m_is_gamegear = 0;
1862   state->m_is_region_japan = 0;
1863   state->m_has_bios_0400 = 0;
1864   state->m_has_bios_2000 = 0;
1865   state->m_has_bios_full = 0;
1866   state->m_has_bios = 0;
1867   state->m_has_fm = 0;
1868}
1869
1870DRIVER_INIT( sg1000m3 )
1871{
1872   sms_state *state = machine.driver_data<sms_state>();
1873   sms_set_zero_flag(machine);
1874   state->m_is_region_japan = 1;
1875   state->m_has_fm = 1;
1876}
1877
1878
1879DRIVER_INIT( sms1 )
1880{
1881   sms_state *state = machine.driver_data<sms_state>();
1882   sms_set_zero_flag(machine);
1883   state->m_has_bios_full = 1;
1884}
1885
1886
1887DRIVER_INIT( smsj )
1888{
1889   sms_state *state = machine.driver_data<sms_state>();
1890   sms_set_zero_flag(machine);
1891   state->m_is_region_japan = 1;
1892   state->m_has_bios_2000 = 1;
1893   state->m_has_fm = 1;
1894}
1895
1896
1897DRIVER_INIT( sms2kr )
1898{
1899   sms_state *state = machine.driver_data<sms_state>();
1900   sms_set_zero_flag(machine);
1901   state->m_is_region_japan = 1;
1902   state->m_has_bios_full = 1;
1903   state->m_has_fm = 1;
1904}
1905
1906
1907DRIVER_INIT( smssdisp )
1908{
1909   sms_set_zero_flag(machine);
1910}
1911
1912
1913DRIVER_INIT( gamegear )
1914{
1915   sms_state *state = machine.driver_data<sms_state>();
1916   sms_set_zero_flag(machine);
1917   state->m_is_gamegear = 1;
1918}
1919
1920
1921DRIVER_INIT( gamegeaj )
1922{
1923   sms_state *state = machine.driver_data<sms_state>();
1924   sms_set_zero_flag(machine);
1925   state->m_is_region_japan = 1;
1926   state->m_is_gamegear = 1;
1927   state->m_has_bios_0400 = 1;
1928}
1929
1930
1931static void sms_black_bitmap( const screen_device *screen, bitmap_t *bitmap )
1932{
1933   const int width = screen->width();
1934   const int height = screen->height();
1935   int x, y;
1936
1937   for (y = 0; y < height; y++)
1938      for (x = 0; x < width; x++)
1939         *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0);
1940}
1941
1942VIDEO_START( sms1 )
1943{
1944   sms_state *state = machine.driver_data<sms_state>();
1945   screen_device *screen = machine.first_screen();
1946   int width = screen->width();
1947   int height = screen->height();
1948
1949   state->m_prevleft_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
1950   state->m_prevright_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
1951   state->save_item(NAME(*state->m_prevleft_bitmap));
1952   state->save_item(NAME(*state->m_prevright_bitmap));
1953}
1954
1955SCREEN_UPDATE( sms1 )
1956{
1957   sms_state *state = screen->machine().driver_data<sms_state>();
1958   UINT8 sscope = input_port_read_safe(screen->machine(), "SEGASCOPE", 0x00);
1959   UINT8 sscope_binocular_hack = input_port_read_safe(screen->machine(), "SSCOPE_BINOCULAR", 0x00);
1960   UINT8 occluded_view = 0;
1961
1962   // without SegaScope, both LCDs for glasses go black
1963   if ((screen != state->m_main_scr) && !sscope)
1964      occluded_view = 1;
1965
1966   // with SegaScope, sscope_state 0 = left screen OFF, right screen ON
1967   if (!(state->m_sscope_state & 0x01) && (screen == state->m_left_lcd))
1968      occluded_view = 1;
1969
1970   // with SegaScope, sscope_state 1 = left screen ON, right screen OFF
1971   if ((state->m_sscope_state & 0x01) && (screen == state->m_right_lcd))
1972      occluded_view = 1;
1973
1974   if (!occluded_view)
1975   {
1976      sms_vdp_update(state->m_vdp, bitmap, cliprect);
1977
1978      // HACK: fake 3D->2D handling (if enabled, it repeats each frame twice on the selected lens)
1979      // save a copy of current bitmap for the binocular hack
1980      if (sscope && (screen == state->m_left_lcd) && (sscope_binocular_hack & 0x01))
1981         copybitmap(state->m_prevleft_bitmap, bitmap, 0, 0, 0, 0, cliprect);
1982      if (sscope && (screen == state->m_right_lcd) && (sscope_binocular_hack & 0x02))
1983         copybitmap(state->m_prevright_bitmap, bitmap, 0, 0, 0, 0, cliprect);
1984   }
1985   else
1986   {
1987      sms_black_bitmap(screen, bitmap);
1988
1989      // HACK: fake 3D->2D handling (if enabled, it repeats each frame twice on the selected lens)
1990      // use the copied bitmap for the binocular hack
1991      if (sscope && (screen == state->m_left_lcd) && (sscope_binocular_hack & 0x01))
1992         copybitmap(bitmap, state->m_prevleft_bitmap, 0, 0, 0, 0, cliprect);
1993      if (sscope && (screen == state->m_right_lcd) && (sscope_binocular_hack & 0x02))
1994         copybitmap(bitmap, state->m_prevright_bitmap, 0, 0, 0, 0, cliprect);
1995   }
1996
1997   return 0;
1998}
1999
2000SCREEN_UPDATE( sms )
2001{
2002   sms_state *state = screen->machine().driver_data<sms_state>();
2003   sms_vdp_update(state->m_vdp, bitmap, cliprect);
2004   return 0;
2005}
2006
2007VIDEO_START( gamegear )
2008{
2009   sms_state *state = machine.driver_data<sms_state>();
2010   screen_device *screen = machine.first_screen();
2011   int width = screen->width();
2012   int height = screen->height();
2013
2014   state->m_prev_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
2015   state->m_tmp_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
2016   state->save_item(NAME(*state->m_prev_bitmap));
2017}
2018
2019SCREEN_UPDATE( gamegear )
2020{
2021   sms_state *state = screen->machine().driver_data<sms_state>();
2022   int width = screen->width();
2023   int height = screen->height();
2024   int x, y;
2025
2026   sms_vdp_update(state->m_vdp, state->m_tmp_bitmap, cliprect);
2027
2028   // HACK: fake LCD persistence effect
2029   // (it would be better to generalize this in the core, to be used for all LCD systems)
2030   for (y = 0; y < height; y++)
2031   {
2032      UINT32 *line0 = BITMAP_ADDR32(state->m_tmp_bitmap, y, 0);
2033      UINT32 *line1 = BITMAP_ADDR32(state->m_prev_bitmap, y, 0);
2034      for (x = 0; x < width; x++)
2035      {
2036         UINT32 color0 = line0[x];
2037         UINT32 color1 = line1[x];
2038         UINT16 r0 = (color0 >> 16) & 0x000000ff;
2039         UINT16 g0 = (color0 >>  8) & 0x000000ff;
2040         UINT16 b0 = (color0 >>  0) & 0x000000ff;
2041         UINT16 r1 = (color1 >> 16) & 0x000000ff;
2042         UINT16 g1 = (color1 >>  8) & 0x000000ff;
2043         UINT16 b1 = (color1 >>  0) & 0x000000ff;
2044         UINT8 r = (UINT8)((r0 + r1) >> 1);
2045         UINT8 g = (UINT8)((g0 + g1) >> 1);
2046         UINT8 b = (UINT8)((b0 + b1) >> 1);
2047         *BITMAP_ADDR32(bitmap, y, x) = (r << 16) | (g << 8) | b;
2048      }
2049   }
2050   copybitmap(state->m_prev_bitmap, state->m_tmp_bitmap, 0, 0, 0, 0, cliprect);
2051
2052   return 0;
2053}
src/mess/machine/sms.c
r0r12640
1#include "emu.h"
2#include "crsshair.h"
3#include "image.h"
4#include "includes/segasms.h"
5#include "video/smsvdp.h"
6#include "sound/2413intf.h"
7#include "imagedev/cartslot.h"
8#include "hashfile.h"
9
10#define VERBOSE 0
11#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
12
13#define CF_CODEMASTERS_MAPPER    0x01
14#define CF_KOREAN_MAPPER         0x02
15#define CF_KOREAN_ZEMINA_MAPPER  0x04
16#define CF_KOREAN_NOBANK_MAPPER  0x08
17#define CF_93C46_EEPROM          0x10
18#define CF_ONCART_RAM            0x20
19#define CF_GG_SMS_MODE           0x40
20
21#define LGUN_RADIUS           6
22#define LGUN_X_INTERVAL       4
23
24
25static void setup_rom(address_space *space);
26
27
28static TIMER_CALLBACK( rapid_fire_callback )
29{
30   sms_state *state = machine.driver_data<sms_state>();
31   state->m_rapid_fire_state_1 ^= 0xff;
32   state->m_rapid_fire_state_2 ^= 0xff;
33}
34
35
36static WRITE8_HANDLER( sms_input_write )
37{
38   sms_state *state = space->machine().driver_data<sms_state>();
39
40   switch (offset)
41   {
42   case 0:
43      switch (input_port_read_safe(space->machine(), "CTRLSEL", 0x00) & 0x0f)
44      {
45      case 0x04:   /* Sports Pad */
46         if (data != state->m_sports_pad_last_data_1)
47         {
48            UINT32 cpu_cycles = downcast<cpu_device *>(&space->device())->total_cycles();
49
50            state->m_sports_pad_last_data_1 = data;
51            if (cpu_cycles - state->m_last_sports_pad_time_1 > 512)
52            {
53               state->m_sports_pad_state_1 = 3;
54               state->m_sports_pad_1_x = input_port_read(space->machine(), "SPORT0");
55               state->m_sports_pad_1_y = input_port_read(space->machine(), "SPORT1");
56            }
57            state->m_last_sports_pad_time_1 = cpu_cycles;
58            state->m_sports_pad_state_1 = (state->m_sports_pad_state_1 + 1) & 3;
59         }
60         break;
61      }
62      break;
63
64   case 1:
65      switch (input_port_read_safe(space->machine(), "CTRLSEL", 0x00) & 0xf0)
66      {
67      case 0x40:   /* Sports Pad */
68         if (data != state->m_sports_pad_last_data_2)
69         {
70            UINT32 cpu_cycles = downcast<cpu_device *>(&space->device())->total_cycles();
71
72            state->m_sports_pad_last_data_2 = data;
73            if (cpu_cycles - state->m_last_sports_pad_time_2 > 2048)
74            {
75               state->m_sports_pad_state_2 = 3;
76               state->m_sports_pad_2_x = input_port_read(space->machine(), "SPORT2");
77               state->m_sports_pad_2_y = input_port_read(space->machine(), "SPORT3");
78            }
79            state->m_last_sports_pad_time_2 = cpu_cycles;
80            state->m_sports_pad_state_2 = (state->m_sports_pad_state_2 + 1) & 3;
81         }
82         break;
83      }
84      break;
85   }
86}
87
88/* FIXME: this function is a hack for Light Phaser emulation. Theoretically
89   sms_vdp_hcount_latch() should be used instead, but it returns incorrect
90   position for unknown reason (timing?) */
91static void sms_vdp_hcount_lphaser( running_machine &machine, int hpos )
92{
93   sms_state *state = machine.driver_data<sms_state>();
94   int hpos_tmp = hpos + state->m_lphaser_x_offs;
95   UINT8 tmp = ((hpos_tmp - 46) >> 1) & 0xff;
96
97   //printf ("sms_vdp_hcount_lphaser: hpos %3d hpos_tmp %3d => hcount %2X\n", hpos, hpos_tmp, tmp);
98   sms_vdp_hcount_latch_w(state->m_vdp, 0, tmp);
99}
100
101
102/*
103    Light Phaser (light gun) emulation notes:
104    - The sensor is activated based on color brightness of some individual
105      pixels being drawn by the beam, at circular area where the gun is aiming.
106    - Currently, brightness is calculated based only on single pixels.
107    - In general, after the trigger is pressed, games draw the next frame using
108      a light color pattern, to make sure sensor will be activated. If emulation
109      skips that frame, sensor may stay deactivated. Frameskip set to 0 (no skip) is
110      recommended to avoid problems.
111    - When sensor switches from off to on, a value is latched for HCount register
112      and a flag is set. The emulation uses the flag to avoid sequential latches and
113      to signal that TH line is activated when the status of the input port is read.
114      When the status is read, the flag is cleared, or else it is cleared later when
115      the Pause status is read (end of a frame). This is necessary because the
116      "Color & Switch Test" ROM only reads the TH bit after the VINT line.
117    - The gun test of "Color & Switch Test" is an example that requires checks
118      of sensor status independent of other events, like trigger press or TH bit
119      reads. Another example is the title screen of "Hang-On & Safari Hunt", where
120      the game only reads HCount register in a loop, expecting a latch by the gun.
121    - The whole procedure is managed by a timer callback, that always reschedule
122      itself to run in some intervals when the beam is at the circular area.
123*/
124static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int lgun_x, int lgun_y )
125{
126   sms_state *state = machine.driver_data<sms_state>();
127   const int r_x_r = LGUN_RADIUS * LGUN_RADIUS;
128   screen_device *screen = machine.first_screen();
129   const rectangle &visarea = screen->visible_area();
130   int beam_x = screen->hpos();
131   int beam_y = screen->vpos();
132   int dx, dy;
133   int result = 0;
134   int pos_changed = 0;
135   double dx_circ;
136
137    while (1)
138   {
139      dy = abs(beam_y - lgun_y);
140
141      if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y)
142      {
143         beam_y = lgun_y - LGUN_RADIUS;
144         if (beam_y < visarea.min_y)
145            beam_y = visarea.min_y;
146         dy = abs(beam_y - lgun_y);
147         pos_changed = 1;
148      }
149      /* step 1: r^2 = dx^2 + dy^2 */
150      /* step 2: dx^2 = r^2 - dy^2 */
151      /* step 3: dx = sqrt(r^2 - dy^2) */
152      dx_circ = ceil((float) sqrt((float) (r_x_r - (dy * dy))));
153      dx = abs(beam_x - lgun_x);
154
155      if (dx > dx_circ || beam_x < visarea.min_x || beam_x > visarea.max_x)
156      {
157         if (beam_x > lgun_x)
158         {
159            beam_x = 0;
160            beam_y++;
161            continue;
162         }
163         beam_x = lgun_x - dx_circ;
164         if (beam_x < visarea.min_x)
165            beam_x = visarea.min_x;
166         pos_changed = 1;
167      }
168
169      if (!pos_changed)
170      {
171         result = sms_vdp_check_brightness(state->m_vdp, beam_x, beam_y);
172         /* next check at same line */
173         beam_x += LGUN_X_INTERVAL;
174         pos_changed = 1;
175      }
176      else
177         break;
178   }
179   timer->adjust(machine.first_screen()->time_until_pos(beam_y, beam_x));
180
181   return result;
182}
183
184static UINT8 sms_vdp_hcount( running_machine &machine )
185{
186   UINT8 tmp;
187   screen_device *screen = machine.first_screen();
188   int hpos = screen->hpos();
189
190   /* alternative method: pass HCounter test, but some others fail */
191   //int hpos_tmp = hpos;
192   //if ((hpos + 2) % 6 == 0) hpos_tmp--;
193   //tmp = ((hpos_tmp - 46) >> 1) & 0xff;
194
195   UINT64 calc_cycles;
196   attotime time_end;
197   int vpos = screen->vpos();
198   int max_hpos = screen->width() - 1;
199
200   if (hpos == max_hpos)
201      time_end = attotime::zero;
202   else
203      time_end = screen->time_until_pos(vpos, max_hpos);
204   calc_cycles = machine.device<cpu_device>("maincpu")->attotime_to_clocks(time_end);
205
206   /* equation got from SMSPower forum, posted by Flubba. */
207   tmp = ((590 - (calc_cycles * 3)) / 4) & 0xff;
208
209   //printf ("sms_vdp_hcount: hpos %3d => hcount %2X\n", hpos, tmp);
210   return tmp;
211}
212
213
214static void sms_vdp_hcount_latch( running_machine &machine )
215{
216   sms_state *state = machine.driver_data<sms_state>();
217   UINT8 value = sms_vdp_hcount(machine);
218
219   sms_vdp_hcount_latch_w(state->m_vdp, 0, value);
220}
221
222
223static UINT16 screen_hpos_nonscaled( screen_device *screen, int scaled_hpos )
224{
225   const rectangle &visarea = screen->visible_area();
226   int offset_x = (scaled_hpos * (visarea.max_x - visarea.min_x)) / 255;
227   return visarea.min_x + offset_x;
228}
229
230
231static UINT16 screen_vpos_nonscaled( screen_device *screen, int scaled_vpos )
232{
233   const rectangle &visarea = screen->visible_area();
234   int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255;
235   return visarea.min_y + offset_y;
236}
237
238
239static void lphaser1_sensor_check( running_machine &machine )
240{
241   sms_state *state = machine.driver_data<sms_state>();
242   const int x = screen_hpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER0"));
243   const int y = screen_vpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER1"));
244
245   if (lgun_bright_aim_area(machine, state->m_lphaser_1_timer, x, y))
246   {
247      if (state->m_lphaser_1_latch == 0)
248      {
249         state->m_lphaser_1_latch = 1;
250         sms_vdp_hcount_lphaser(machine, x);
251      }
252   }
253}
254
255static void lphaser2_sensor_check( running_machine &machine )
256{
257   sms_state *state = machine.driver_data<sms_state>();
258   const int x = screen_hpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER2"));
259   const int y = screen_vpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER3"));
260
261   if (lgun_bright_aim_area(machine, state->m_lphaser_2_timer, x, y))
262   {
263      if (state->m_lphaser_2_latch == 0)
264      {
265         state->m_lphaser_2_latch = 1;
266         sms_vdp_hcount_lphaser(machine, x);
267      }
268   }
269}
270
271
272// at each input port read we check if lightguns are enabled in one of the ports:
273// if so, we turn on crosshair and the lightgun timer
274static TIMER_CALLBACK( lightgun_tick )
275{
276   sms_state *state = machine.driver_data<sms_state>();
277
278   if ((input_port_read_safe(machine, "CTRLSEL", 0x00) & 0x0f) == 0x01)
279   {
280      /* enable crosshair */
281      crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL);
282      if (!state->m_lphaser_1_timer->enabled())
283         lphaser1_sensor_check(machine);
284   }
285   else
286   {
287      /* disable crosshair */
288      crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE);
289      state->m_lphaser_1_timer->enable(0);
290   }
291
292   if ((input_port_read_safe(machine, "CTRLSEL", 0x00) & 0xf0) == 0x10)
293   {
294      /* enable crosshair */
295      crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_ALL);
296      if (!state->m_lphaser_2_timer->enabled())
297         lphaser2_sensor_check(machine);
298   }
299   else
300   {
301      /* disable crosshair */
302      crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_NONE);
303      state->m_lphaser_2_timer->enable(0);
304   }
305}
306
307
308static TIMER_CALLBACK( lphaser_1_callback )
309{
310   lphaser1_sensor_check(machine);
311}
312
313
314static TIMER_CALLBACK( lphaser_2_callback )
315{
316   lphaser2_sensor_check(machine);
317}
318
319
320INPUT_CHANGED( lgun1_changed )
321{
322   sms_state *state = field.machine().driver_data<sms_state>();
323   if (!state->m_lphaser_1_timer ||
324      (input_port_read_safe(field.machine(), "CTRLSEL", 0x00) & 0x0f) != 0x01)
325      return;
326
327   if (newval != oldval)
328      lphaser1_sensor_check(field.machine());
329}
330
331INPUT_CHANGED( lgun2_changed )
332{
333   sms_state *state = field.machine().driver_data<sms_state>();
334   if (!state->m_lphaser_2_timer ||
335      (input_port_read_safe(field.machine(), "CTRLSEL", 0x00) & 0xf0) != 0x10)
336      return;
337
338   if (newval != oldval)
339      lphaser2_sensor_check(field.machine());
340}
341
342
343static void sms_get_inputs( address_space *space )
344{
345   sms_state *state = space->machine().driver_data<sms_state>();
346   UINT8 data = 0x00;
347   UINT32 cpu_cycles = downcast<cpu_device *>(&space->device())->total_cycles();
348   running_machine &machine = space->machine();
349
350   state->m_input_port0 = 0xff;
351   state->m_input_port1 = 0xff;
352
353   if (cpu_cycles - state->m_last_paddle_read_time > 256)
354   {
355      state->m_paddle_read_state ^= 0xff;
356      state->m_last_paddle_read_time = cpu_cycles;
357   }
358
359   /* Check if lightgun has been chosen as input: if so, enable crosshair */
360   machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick));
361
362   /* Player 1 */
363   switch (input_port_read_safe(machine, "CTRLSEL", 0x00) & 0x0f)
364   {
365   case 0x00:  /* Joystick */
366      data = input_port_read(machine, "PORT_DC");
367      /* Check Rapid Fire setting for Button A */
368      if (!(data & 0x10) && (input_port_read(machine, "RFU") & 0x01))
369         data |= state->m_rapid_fire_state_1 & 0x10;
370
371      /* Check Rapid Fire setting for Button B */
372      if (!(data & 0x20) && (input_port_read(machine, "RFU") & 0x02))
373         data |= state->m_rapid_fire_state_1 & 0x20;
374
375      state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f);
376      break;
377
378   case 0x01:  /* Light Phaser */
379      data = (input_port_read(machine, "CTRLIPT") & 0x01) << 4;
380      if (!(data & 0x10))
381      {
382         if (input_port_read(machine, "RFU") & 0x01)
383            data |= state->m_rapid_fire_state_1 & 0x10;
384      }
385      /* just consider the button (trigger) bit */
386      data |= ~0x10;
387      state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f);
388      break;
389
390   case 0x02:  /* Paddle Control */
391      /* Get button A state */
392      data = input_port_read(machine, "PADDLE0");
393
394      if (state->m_paddle_read_state)
395         data = data >> 4;
396
397      state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x0f) | (state->m_paddle_read_state & 0x20)
398                      | ((input_port_read(machine, "CTRLIPT") & 0x02) << 3);
399      break;
400
401   case 0x04:   /* Sega Sports Pad */
402      switch (state->m_sports_pad_state_1)
403      {
404      case 0:
405         data = (state->m_sports_pad_1_x >> 4) & 0x0f;
406         break;
407      case 1:
408         data = state->m_sports_pad_1_x & 0x0f;
409         break;
410      case 2:
411         data = (state->m_sports_pad_1_y >> 4) & 0x0f;
412         break;
413      case 3:
414         data = state->m_sports_pad_1_y & 0x0f;
415         break;
416      }
417      state->m_input_port0 = (state->m_input_port0 & 0xc0) | data | ((input_port_read(machine, "CTRLIPT") & 0x0c) << 2);
418      break;
419   }
420
421   /* Player 2 */
422   switch (input_port_read_safe(machine, "CTRLSEL", 0x00)  & 0xf0)
423   {
424   case 0x00:   /* Joystick */
425      data = input_port_read(machine, "PORT_DC");
426      state->m_input_port0 = (state->m_input_port0 & 0x3f) | (data & 0xc0);
427
428      data = input_port_read(machine, "PORT_DD");
429      /* Check Rapid Fire setting for Button A */
430      if (!(data & 0x04) && (input_port_read(machine, "RFU") & 0x04))
431         data |= state->m_rapid_fire_state_2 & 0x04;
432
433      /* Check Rapid Fire setting for Button B */
434      if (!(data & 0x08) && (input_port_read(machine, "RFU") & 0x08))
435         data |= state->m_rapid_fire_state_2 & 0x08;
436
437      state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f);
438      break;
439
440   case 0x10:   /* Light Phaser */
441      data = (input_port_read(machine, "CTRLIPT") & 0x10) >> 2;
442      if (!(data & 0x04))
443      {
444         if (input_port_read(machine, "RFU") & 0x04)
445            data |= state->m_rapid_fire_state_2 & 0x04;
446      }
447      /* just consider the button (trigger) bit */
448      data |= ~0x04;
449      state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f);
450      break;
451
452   case 0x20:   /* Paddle Control */
453      /* Get button A state */
454      data = input_port_read(machine, "PADDLE1");
455      if (state->m_paddle_read_state)
456         data = data >> 4;
457
458      state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6);
459      state->m_input_port1 = (state->m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (state->m_paddle_read_state & 0x08)
460                      | ((input_port_read(machine, "CTRLIPT") & 0x20) >> 3);
461      break;
462
463   case 0x40:   /* Sega Sports Pad */
464      switch (state->m_sports_pad_state_2)
465      {
466      case 0:
467         data = state->m_sports_pad_2_x & 0x0f;
468         break;
469      case 1:
470         data = (state->m_sports_pad_2_x >> 4) & 0x0f;
471         break;
472      case 2:
473         data = state->m_sports_pad_2_y & 0x0f;
474         break;
475      case 3:
476         data = (state->m_sports_pad_2_y >> 4) & 0x0f;
477         break;
478      }
479      state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6);
480      state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data >> 2) | ((input_port_read(machine, "CTRLIPT") & 0xc0) >> 4);
481      break;
482   }
483}
484
485
486WRITE8_HANDLER( sms_fm_detect_w )
487{
488   sms_state *state = space->machine().driver_data<sms_state>();
489
490   if (state->m_has_fm)
491      state->m_fm_detect = (data & 0x01);
492}
493
494
495READ8_HANDLER( sms_fm_detect_r )
496{
497   sms_state *state = space->machine().driver_data<sms_state>();
498
499   if (state->m_has_fm)
500   {
501      return state->m_fm_detect;
502   }
503   else
504   {
505      if (state->m_bios_port & IO_CHIP)
506      {
507         return 0xff;
508      }
509      else
510      {
511         sms_get_inputs(space);
512         return state->m_input_port0;
513      }
514   }
515}
516
517WRITE8_HANDLER( sms_io_control_w )
518{
519   sms_state *state = space->machine().driver_data<sms_state>();
520
521   if (data & 0x08)
522   {
523      /* check if TH pin level is high (1) and was low last time */
524      if (data & 0x80 && !(state->m_ctrl_reg & 0x80))
525      {
526         sms_vdp_hcount_latch(space->machine());
527      }
528      sms_input_write(space, 0, (data & 0x20) >> 5);
529   }
530
531   if (data & 0x02)
532   {
533      if (data & 0x20 && !(state->m_ctrl_reg & 0x20))
534      {
535         sms_vdp_hcount_latch(space->machine());
536      }
537      sms_input_write(space, 1, (data & 0x80) >> 7);
538   }
539
540   state->m_ctrl_reg = data;
541}
542
543
544READ8_HANDLER( sms_count_r )
545{
546   sms_state *state = space->machine().driver_data<sms_state>();
547
548   if (offset & 0x01)
549      return sms_vdp_hcount_latch_r(state->m_vdp, offset);
550   else
551      return sms_vdp_vcount_r(state->m_vdp, offset);
552}
553
554
555/*
556 Check if the pause button is pressed.
557 If the gamegear is in sms mode, check if the start button is pressed.
558 */
559void sms_pause_callback( running_machine &machine )
560{
561   sms_state *state = machine.driver_data<sms_state>();
562
563   if (state->m_is_gamegear && !(state->m_cartridge[state->m_current_cartridge].features & CF_GG_SMS_MODE))
564      return;
565
566   if (!(input_port_read(machine, state->m_is_gamegear ? "START" : "PAUSE") & 0x80))
567   {
568      if (!state->m_paused)
569      {
570         cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE);
571      }
572      state->m_paused = 1;
573   }
574   else
575   {
576      state->m_paused = 0;
577   }
578
579   /* clear Light Phaser latch flags for next frame */
580   state->m_lphaser_1_latch = 0;
581   state->m_lphaser_2_latch = 0;
582}
583
584READ8_HANDLER( sms_input_port_0_r )
585{
586   sms_state *state = space->machine().driver_data<sms_state>();
587
588   if (state->m_bios_port & IO_CHIP)
589   {
590      return 0xff;
591   }
592   else
593   {
594      sms_get_inputs(space);
595      return state->m_input_port0;
596   }
597}
598
599
600READ8_HANDLER( sms_input_port_1_r )
601{
602   sms_state *state = space->machine().driver_data<sms_state>();
603
604   if (state->m_bios_port & IO_CHIP)
605      return 0xff;
606
607   sms_get_inputs(space);
608
609   /* Reset Button */
610   state->m_input_port1 = (state->m_input_port1 & 0xef) | (input_port_read_safe(space->machine(), "RESET", 0x01) & 0x01) << 4;
611
612   /* Do region detection if TH of ports A and B are set to output (0) */
613   if (!(state->m_ctrl_reg & 0x0a))
614   {
615      /* Move bits 7,5 of IO control port into bits 7, 6 */
616      state->m_input_port1 = (state->m_input_port1 & 0x3f) | (state->m_ctrl_reg & 0x80) | (state->m_ctrl_reg & 0x20) << 1;
617
618      /* Inverse region detect value for Japanese machines */
619      if (state->m_is_region_japan)
620         state->m_input_port1 ^= 0xc0;
621   }
622   else
623   {
624      if (state->m_ctrl_reg & 0x02 && state->m_lphaser_1_latch)
625      {
626         state->m_input_port1 &= ~0x40;
627         state->m_lphaser_1_latch = 0;
628      }
629
630      if (state->m_ctrl_reg & 0x08 && state->m_lphaser_2_latch)
631      {
632         state->m_input_port1 &= ~0x80;
633         state->m_lphaser_2_latch = 0;
634      }
635   }
636
637   return state->m_input_port1;
638}
639
640
641
642WRITE8_HANDLER( sms_ym2413_register_port_0_w )
643{
644   sms_state *state = space->machine().driver_data<sms_state>();
645
646   if (state->m_has_fm)
647      ym2413_w(state->m_ym, 0, (data & 0x3f));
648}
649
650
651WRITE8_HANDLER( sms_ym2413_data_port_0_w )
652{
653   sms_state *state = space->machine().driver_data<sms_state>();
654
655   if (state->m_has_fm)
656   {
657      logerror("data_port_0_w %x %x\n", offset, data);
658      ym2413_w(state->m_ym, 1, data);
659   }
660}
661
662
663READ8_HANDLER( gg_input_port_2_r )
664{
665   sms_state *state = space->machine().driver_data<sms_state>();
666
667   //logerror("joy 2 read, val: %02x, pc: %04x\n", ((state->m_is_region_japan ? 0x00 : 0x40) | (input_port_read(machine, "START") & 0x80)), activecpu_get_pc());
668   return ((state->m_is_region_japan ? 0x00 : 0x40) | (input_port_read(space->machine(), "START") & 0x80));
669}
670
671
672READ8_HANDLER( sms_sscope_r )
673{
674   sms_state *state = space->machine().driver_data<sms_state>();
675   return state->m_sscope_state;
676}
677
678
679WRITE8_HANDLER( sms_sscope_w )
680{
681   sms_state *state = space->machine().driver_data<sms_state>();
682   state->m_sscope_state = data;
683}
684
685
686READ8_HANDLER( sms_mapper_r )
687{
688   sms_state *state = space->machine().driver_data<sms_state>();
689   return state->m_mapper[offset];
690}
691
692/* Terebi Oekaki */
693/* The following code comes from sg1000.c. We should eventually merge these TV Draw implementations */
694static WRITE8_HANDLER( sms_tvdraw_axis_w )
695{
696   sms_state *state = space->machine().driver_data<sms_state>();
697   UINT8 tvboard_on = input_port_read_safe(space->machine(), "TVDRAW", 0x00);
698
699   if (data & 0x01)
700   {
701      state->m_tvdraw_data = tvboard_on ? input_port_read(space->machine(), "TVDRAW_X") : 0x80;
702
703      if (state->m_tvdraw_data < 4) state->m_tvdraw_data = 4;
704      if (state->m_tvdraw_data > 251) state->m_tvdraw_data = 251;
705   }
706   else
707   {
708      state->m_tvdraw_data = tvboard_on ? input_port_read(space->machine(), "TVDRAW_Y") + 0x20 : 0x80;
709   }
710}
711
712static READ8_HANDLER( sms_tvdraw_status_r )
713{
714   UINT8 tvboard_on = input_port_read_safe(space->machine(), "TVDRAW", 0x00);
715   return tvboard_on ? input_port_read(space->machine(), "TVDRAW_PEN") : 0x01;
716}
717
718static READ8_HANDLER( sms_tvdraw_data_r )
719{
720   sms_state *state = space->machine().driver_data<sms_state>();
721   return state->m_tvdraw_data;
722}
723
724
725WRITE8_HANDLER( sms_mapper_w )
726{
727   sms_state *state = space->machine().driver_data<sms_state>();
728   int page;
729   UINT8 *SOURCE_BIOS;
730   UINT8 *SOURCE_CART;
731   UINT8 *SOURCE;
732   UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
733
734   offset &= 3;
735
736   state->m_mapper[offset] = data;
737   state->m_mapper_ram[offset] = data;
738
739   if (state->m_cartridge[state->m_current_cartridge].ROM)
740   {
741      SOURCE_CART = state->m_cartridge[state->m_current_cartridge].ROM + (( rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000;
742   }
743   else
744   {
745      SOURCE_CART = state->m_banking_none[1];
746   }
747
748   if (state->m_BIOS)
749   {
750      SOURCE_BIOS = state->m_BIOS + ((state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0) * 0x4000;
751   }
752   else
753   {
754      SOURCE_BIOS = state->m_banking_none[1];
755   }
756
757   if (state->m_bios_port & IO_BIOS_ROM || (state->m_is_gamegear && state->m_BIOS == NULL))
758   {
759      if (!(state->m_bios_port & IO_CARTRIDGE) || (state->m_is_gamegear && state->m_BIOS == NULL))
760      {
761         page = (rom_page_count > 0) ? data % rom_page_count : 0;
762         if (!state->m_cartridge[state->m_current_cartridge].ROM)
763            return;
764         SOURCE = SOURCE_CART;
765      }
766      else
767      {
768         /* nothing to page in */
769         return;
770      }
771   }
772   else
773   {
774      page = (state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0;
775      if (!state->m_BIOS)
776         return;
777      SOURCE = SOURCE_BIOS;
778   }
779
780   switch (offset)
781   {
782   case 0: /* Control */
783      /* Is it ram or rom? */
784      if (data & 0x08) /* it's ram */
785      {
786         state->m_cartridge[state->m_current_cartridge].sram_save = 1;         /* SRAM should be saved on exit. */
787         if (data & 0x04)
788         {
789            LOG(("ram 1 paged.\n"));
790            SOURCE = state->m_cartridge[state->m_current_cartridge].cartSRAM + 0x4000;
791         }
792         else
793         {
794            LOG(("ram 0 paged.\n"));
795            SOURCE = state->m_cartridge[state->m_current_cartridge].cartSRAM;
796         }
797         memory_set_bankptr(space->machine(),  "bank5", SOURCE);
798         memory_set_bankptr(space->machine(),  "bank6", SOURCE + 0x2000);
799      }
800      else /* it's rom */
801      {
802         if (state->m_bios_port & IO_BIOS_ROM || ! state->m_has_bios)
803         {
804            page = (rom_page_count > 0) ? state->m_mapper[3] % rom_page_count : 0;
805            SOURCE = state->m_banking_cart[5];
806         }
807         else
808         {
809            page = (state->m_bios_page_count > 0) ? state->m_mapper[3] % state->m_bios_page_count : 0;
810            SOURCE = state->m_banking_bios[5];
811         }
812         LOG(("rom 2 paged in %x.\n", page));
813         memory_set_bankptr(space->machine(), "bank5", SOURCE);
814         memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
815      }
816      break;
817
818   case 1: /* Select 16k ROM bank for 0400-3FFF */
819      LOG(("rom 0 paged in %x.\n", page));
820      state->m_banking_bios[2] = SOURCE_BIOS + 0x0400;
821      state->m_banking_cart[2] = SOURCE_CART + 0x0400;
822      if (state->m_is_gamegear)
823         SOURCE = SOURCE_CART;
824
825      memory_set_bankptr(space->machine(), "bank2", SOURCE + 0x0400);
826      break;
827
828   case 2: /* Select 16k ROM bank for 4000-7FFF */
829      LOG(("rom 1 paged in %x.\n", page));
830      state->m_banking_bios[3] = SOURCE_BIOS;
831      state->m_banking_cart[3] = SOURCE_CART;
832      if (state->m_is_gamegear)
833         SOURCE = SOURCE_CART;
834
835      memory_set_bankptr(space->machine(), "bank3", SOURCE);
836      memory_set_bankptr(space->machine(), "bank4", SOURCE + 0x2000);
837      break;
838
839   case 3: /* Select 16k ROM bank for 8000-BFFF */
840      state->m_banking_bios[5] = SOURCE_BIOS;
841      if (state->m_is_gamegear)
842         SOURCE = SOURCE_CART;
843
844      if ( state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
845      {
846         if (SOURCE == SOURCE_CART)
847         {
848            SOURCE = state->m_banking_cart[5];
849         }
850      }
851      else
852      {
853         state->m_banking_cart[5] = SOURCE_CART;
854      }
855
856      if (!(state->m_mapper[0] & 0x08)) /* is RAM disabled? */
857      {
858         LOG(("rom 2 paged in %x.\n", page));
859         memory_set_bankptr(space->machine(), "bank5", SOURCE);
860         memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
861      }
862      break;
863   }
864}
865
866#ifdef MESS
867static WRITE8_HANDLER( sms_korean_zemina_banksw_w )
868{
869   sms_state *state = space->machine().driver_data<sms_state>();
870
871   if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_MAPPER)
872   {
873      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x2000;
874      int page = (rom_page_count > 0) ? data % rom_page_count : 0;
875
876      if (!state->m_cartridge[state->m_current_cartridge].ROM)
877         return;
878
879      switch (offset & 3)
880      {
881         case 0:
882            state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
883            memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]);
884            break;
885         case 1:
886            state->m_banking_cart[6] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
887            memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[6]);
888            break;
889         case 2:
890            state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
891            memory_set_bankptr(space->machine(), "bank3", state->m_banking_cart[3]);
892            break;
893         case 3:
894            state->m_banking_cart[4] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000;
895            memory_set_bankptr(space->machine(), "bank4", state->m_banking_cart[4]);
896            break;
897      }
898      LOG(("Zemina mapper write: offset %x data %x.\n", offset, page));
899   }
900}
901
902static WRITE8_HANDLER( sms_codemasters_page0_w )
903{
904   sms_state *state = space->machine().driver_data<sms_state>();
905
906   if (state->m_cartridge[state->m_current_cartridge].ROM && state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
907   {
908      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
909      state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM + ((rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000;
910      state->m_banking_cart[2] = state->m_banking_cart[1] + 0x0400;
911      memory_set_bankptr(space->machine(), "bank1", state->m_banking_cart[1]);
912      memory_set_bankptr(space->machine(), "bank2", state->m_banking_cart[2]);
913   }
914}
915
916
917static WRITE8_HANDLER( sms_codemasters_page1_w )
918{
919   sms_state *state = space->machine().driver_data<sms_state>();
920
921   if (state->m_cartridge[state->m_current_cartridge].ROM && state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
922   {
923      /* Check if we need to switch in some RAM */
924      if (data & 0x80)
925      {
926         state->m_cartridge[state->m_current_cartridge].ram_page = data & 0x07;
927         memory_set_bankptr(space->machine(), "bank6", state->m_cartridge[state->m_current_cartridge].cartRAM + state->m_cartridge[state->m_current_cartridge].ram_page * 0x2000);
928      }
929      else
930      {
931         UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
932         state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000;
933         memory_set_bankptr(space->machine(), "bank3", state->m_banking_cart[3]);
934         memory_set_bankptr(space->machine(), "bank4", state->m_banking_cart[3] + 0x2000);
935         memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000);
936      }
937   }
938}
939#endif
940
941static READ8_HANDLER( sms_kor_nobank_r )
942{
943//  printf("read %x\n", offset);
944   return space->read_byte(0xdffc + offset);
945}
946
947static WRITE8_HANDLER( sms_kor_nobank_w )
948{
949   sms_state *state = space->machine().driver_data<sms_state>();
950   UINT8 *SOURCE_BIOS;
951   UINT8 *SOURCE = NULL;
952
953   space->write_byte(0xdffc + offset, data);
954   state->m_mapper[offset] = data;
955
956   // FIXME: the code below (which only handles the BIOS bankswitch at start) should be cleaned up
957   // currently, it's just a stripped down version of sms_mapper_w
958   if (state->m_BIOS)
959      SOURCE_BIOS = state->m_BIOS + ((state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0) * 0x4000;
960   else
961      SOURCE_BIOS = state->m_banking_none[1];
962
963   if (state->m_bios_port & IO_BIOS_ROM || (state->m_is_gamegear && state->m_BIOS == NULL))
964      return;
965   else
966   {
967      if (!state->m_BIOS)
968         return;
969      SOURCE = SOURCE_BIOS;
970   }
971
972//  printf("write %x, %x\n", offset, data);
973
974   switch (offset)
975   {
976      case 0: /* Control */
977         if (!(data & 0x08)) /* it's not ram */
978         {
979            if (!(state->m_bios_port & IO_BIOS_ROM) && state->m_has_bios)
980            {
981               SOURCE = state->m_banking_bios[5];
982               memory_set_bankptr(space->machine(), "bank5", SOURCE);
983               memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
984            }
985         }
986         break;
987
988      case 1: /* Select 16k ROM bank for 0400-3FFF */
989         state->m_banking_bios[2] = SOURCE_BIOS + 0x0400;
990         memory_set_bankptr(space->machine(), "bank2", SOURCE + 0x0400);
991         break;
992
993      case 2: /* Select 16k ROM bank for 4000-7FFF */
994         state->m_banking_bios[3] = SOURCE_BIOS;
995         memory_set_bankptr(space->machine(), "bank3", SOURCE);
996         memory_set_bankptr(space->machine(), "bank4", SOURCE + 0x2000);
997         break;
998
999      case 3: /* Select 16k ROM bank for 8000-BFFF */
1000         state->m_banking_bios[5] = SOURCE_BIOS;
1001         if (!(state->m_mapper[0] & 0x08)) /* is RAM disabled? */
1002         {
1003            memory_set_bankptr(space->machine(), "bank5", SOURCE);
1004            memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000);
1005         }
1006         break;
1007   }
1008}
1009
1010WRITE8_HANDLER( sms_bios_w )
1011{
1012   sms_state *state = space->machine().driver_data<sms_state>();
1013   state->m_bios_port = data;
1014
1015   logerror("bios write %02x, pc: %04x\n", data, cpu_get_pc(&space->device()));
1016
1017   setup_rom(space);
1018}
1019
1020
1021WRITE8_HANDLER( sms_cartram2_w )
1022{
1023   sms_state *state = space->machine().driver_data<sms_state>();
1024
1025   if (state->m_mapper[0] & 0x08)
1026   {
1027      logerror("write %02X to cartram at offset #%04X\n", data, offset + 0x2000);
1028      if (state->m_mapper[0] & 0x04)
1029      {
1030         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x6000] = data;
1031      }
1032      else
1033      {
1034         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x2000] = data;
1035      }
1036   }
1037
1038   if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
1039   {
1040      state->m_cartridge[state->m_current_cartridge].cartRAM[state->m_cartridge[state->m_current_cartridge].ram_page * 0x2000 + offset] = data;
1041   }
1042
1043   if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_MAPPER && offset == 0) /* Dodgeball King mapper */
1044   {
1045      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
1046      int page = (rom_page_count > 0) ? data % rom_page_count : 0;
1047
1048      if (!state->m_cartridge[state->m_current_cartridge].ROM)
1049         return;
1050
1051      state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x4000;
1052      memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]);
1053      memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000);
1054      LOG(("rom 2 paged in %x (Korean mapper).\n", page));
1055   }
1056}
1057
1058
1059WRITE8_HANDLER( sms_cartram_w )
1060{
1061   sms_state *state = space->machine().driver_data<sms_state>();
1062   int page;
1063
1064   if (state->m_mapper[0] & 0x08)
1065   {
1066      logerror("write %02X to cartram at offset #%04X\n", data, offset);
1067      if (state->m_mapper[0] & 0x04)
1068      {
1069         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x4000] = data;
1070      }
1071      else
1072      {
1073         state->m_cartridge[state->m_current_cartridge].cartSRAM[offset] = data;
1074      }
1075   }
1076   else
1077   {
1078      if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER && offset == 0) /* Codemasters mapper */
1079      {
1080         UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
1081         page = (rom_page_count > 0) ? data % rom_page_count : 0;
1082         if (!state->m_cartridge[state->m_current_cartridge].ROM)
1083            return;
1084         state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x4000;
1085         memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]);
1086         memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000);
1087         LOG(("rom 2 paged in %x (Codemasters mapper).\n", page));
1088      }
1089      else if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM)
1090      {
1091         state->m_cartridge[state->m_current_cartridge].cartRAM[offset & (state->m_cartridge[state->m_current_cartridge].ram_size - 1)] = data;
1092      }
1093      else
1094      {
1095         logerror("INVALID write %02X to cartram at offset #%04X\n", data, offset);
1096      }
1097   }
1098}
1099
1100
1101WRITE8_HANDLER( gg_sio_w )
1102{
1103   sms_state *state = space->machine().driver_data<sms_state>();
1104   logerror("*** write %02X to SIO register #%d\n", data, offset);
1105
1106   state->m_gg_sio[offset & 0x07] = data;
1107   switch (offset & 7)
1108   {
1109      case 0x00: /* Parallel Data */
1110         break;
1111
1112      case 0x01: /* Data Direction/ NMI Enable */
1113         break;
1114
1115      case 0x02: /* Serial Output */
1116         break;
1117
1118      case 0x03: /* Serial Input */
1119         break;
1120
1121      case 0x04: /* Serial Control / Status */
1122         break;
1123   }
1124}
1125
1126
1127READ8_HANDLER( gg_sio_r )
1128{
1129   sms_state *state = space->machine().driver_data<sms_state>();
1130   logerror("*** read SIO register #%d\n", offset);
1131
1132   switch (offset & 7)
1133   {
1134      case 0x00: /* Parallel Data */
1135         break;
1136
1137      case 0x01: /* Data Direction/ NMI Enable */
1138         break;
1139
1140      case 0x02: /* Serial Output */
1141         break;
1142
1143      case 0x03: /* Serial Input */
1144         break;
1145
1146      case 0x04: /* Serial Control / Status */
1147         break;
1148   }
1149
1150   return state->m_gg_sio[offset];
1151}
1152
1153static void sms_machine_stop( running_machine &machine )
1154{
1155   sms_state *state = machine.driver_data<sms_state>();
1156
1157   /* Does the cartridge have SRAM that should be saved? */
1158   if (state->m_cartridge[state->m_current_cartridge].sram_save) {
1159      device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device("cart1"));
1160      image->battery_save(state->m_cartridge[state->m_current_cartridge].cartSRAM, sizeof(UINT8) * NVRAM_SIZE );
1161   }
1162}
1163
1164
1165static void setup_rom( address_space *space )
1166{
1167   sms_state *state = space->machine().driver_data<sms_state>();
1168   running_machine &machine = space->machine();
1169
1170   /* 1. set up bank pointers to point to nothing */
1171   memory_set_bankptr(machine, "bank1", state->m_banking_none[1]);
1172   memory_set_bankptr(machine, "bank2", state->m_banking_none[2]);
1173   memory_set_bankptr(machine, "bank3", state->m_banking_none[3]);
1174   memory_set_bankptr(machine, "bank4", state->m_banking_none[3] + 0x2000);
1175   memory_set_bankptr(machine, "bank5", state->m_banking_none[5]);
1176   memory_set_bankptr(machine, "bank6", state->m_banking_none[5] + 0x2000);
1177
1178   /* 2. check and set up expansion port */
1179   if (!(state->m_bios_port & IO_EXPANSION) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_CARD))
1180   {
1181      /* TODO: Implement me */
1182      logerror("Switching to unsupported expansion port.\n");
1183   }
1184
1185   /* 3. check and set up card rom */
1186   if (!(state->m_bios_port & IO_CARD) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_EXPANSION))
1187   {
1188      /* TODO: Implement me */
1189      logerror("Switching to unsupported card rom port.\n");
1190   }
1191
1192   /* 4. check and set up cartridge rom */
1193   /* if ((!(bios_port & IO_CARTRIDGE) && (bios_port & IO_EXPANSION) && (bios_port & IO_CARD)) || state->m_is_gamegear) { */
1194   /* Out Run Europa initially writes a value to port 3E where IO_CARTRIDGE, IO_EXPANSION and IO_CARD are reset */
1195   if ((!(state->m_bios_port & IO_CARTRIDGE)) || state->m_is_gamegear)
1196   {
1197      memory_set_bankptr(machine, "bank1", state->m_banking_cart[1]);
1198      memory_set_bankptr(machine, "bank2", state->m_banking_cart[2]);
1199      memory_set_bankptr(machine, "bank3", state->m_banking_cart[3]);
1200      memory_set_bankptr(machine, "bank4", state->m_banking_cart[3] + 0x2000);
1201      memory_set_bankptr(machine, "bank5", state->m_banking_cart[5]);
1202      memory_set_bankptr(machine, "bank6", state->m_banking_cart[5] + 0x2000);
1203      logerror("Switched in cartridge rom.\n");
1204   }
1205
1206   /* 5. check and set up bios rom */
1207   if (!(state->m_bios_port & IO_BIOS_ROM))
1208   {
1209      /* 0x0400 bioses */
1210      if (state->m_has_bios_0400)
1211      {
1212         memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]);
1213         logerror("Switched in 0x0400 bios.\n");
1214      }
1215      /* 0x2000 bioses */
1216      if (state->m_has_bios_2000)
1217      {
1218         memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]);
1219         memory_set_bankptr(machine, "bank2", state->m_banking_bios[2]);
1220         logerror("Switched in 0x2000 bios.\n");
1221      }
1222      if (state->m_has_bios_full)
1223      {
1224         memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]);
1225         memory_set_bankptr(machine, "bank2", state->m_banking_bios[2]);
1226         memory_set_bankptr(machine, "bank3", state->m_banking_bios[3]);
1227         memory_set_bankptr(machine, "bank4", state->m_banking_bios[3] + 0x2000);
1228         memory_set_bankptr(machine, "bank5", state->m_banking_bios[5]);
1229         memory_set_bankptr(machine, "bank6", state->m_banking_bios[5] + 0x2000);
1230         logerror("Switched in full bios.\n");
1231      }
1232   }
1233
1234   if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM)
1235   {
1236      memory_set_bankptr(machine, "bank5", state->m_cartridge[state->m_current_cartridge].cartRAM);
1237      memory_set_bankptr(machine, "bank6", state->m_cartridge[state->m_current_cartridge].cartRAM);
1238   }
1239}
1240
1241
1242static int sms_verify_cart( UINT8 *magic, int size )
1243{
1244   int retval;
1245
1246   retval = IMAGE_VERIFY_FAIL;
1247
1248   /* Verify the file is a valid image - check $7ff0 for "TMR SEGA" */
1249   if (size >= 0x8000)
1250   {
1251      if (!strncmp((char*)&magic[0x7ff0], "TMR SEGA", 8))
1252      {
1253#if 0
1254         /* Technically, it should be this, but remove for now until verified: */
1255         if (!strcmp(sysname, "gamegear"))
1256         {
1257            if ((unsigned char)magic[0x7ffd] < 0x50)
1258               retval = IMAGE_VERIFY_PASS;
1259         }
1260         if (!strcmp(sysname, "sms"))
1261         {
1262            if ((unsigned char)magic[0x7ffd] >= 0x50)
1263               retval = IMAGE_VERIFY_PASS;
1264         }
1265#endif
1266         retval = IMAGE_VERIFY_PASS;
1267      }
1268
1269#if 0
1270      /* Check at $81f0 also */
1271      if (!retval)
1272      {
1273         if (!strncmp(&magic[0x81f0], "TMR SEGA", 8))
1274         {
1275#if 0
1276            /* Technically, it should be this, but remove for now until verified: */
1277            if (!strcmp(sysname, "gamegear"))
1278            {
1279               if ((unsigned char)magic[0x81fd] < 0x50)
1280                  retval = IMAGE_VERIFY_PASS;
1281            }
1282            if (!strcmp(sysname, "sms"))
1283            {
1284               if ((unsigned char)magic[0x81fd] >= 0x50)
1285                  retval = IMAGE_VERIFY_PASS;
1286            }
1287#endif
1288            retval = IMAGE_VERIFY_PASS;
1289         }
1290      }
1291#endif
1292
1293   }
1294
1295   return retval;
1296}
1297
1298#ifdef UNUSED_FUNCTION
1299// For the moment we switch to a different detection routine which allows to detect
1300// in a single run Codemasters mapper, Korean mapper (including Jang Pung 3 which
1301// uses a diff signature then the one below here) and Zemina mapper (used by Wonsiin, etc.).
1302// I leave these here to document alt. detection routines and in the case these functions
1303// can be updated
1304
1305/* Check for Codemasters mapper
1306  0x7FE3 - 93 - sms Cosmis Spacehead
1307              - sms Dinobasher
1308              - sms The Excellent Dizzy Collection
1309              - sms Fantastic Dizzy
1310              - sms Micro Machines
1311              - gamegear Cosmic Spacehead
1312              - gamegear Micro Machines
1313         - 94 - gamegear Dropzone
1314              - gamegear Ernie Els Golf (also has 64KB additional RAM on the cartridge)
1315              - gamegear Pete Sampras Tennis
1316              - gamegear S.S. Lucifer
1317         - 95 - gamegear Micro Machines 2 - Turbo Tournament
1318
1319The Korean game Jang Pung II also seems to use a codemasters style mapper.
1320 */
1321static int detect_codemasters_mapper( UINT8 *rom )
1322{
1323   static const UINT8 jang_pung2[16] = { 0x00, 0xba, 0x38, 0x0d, 0x00, 0xb8, 0x38, 0x0c, 0x00, 0xb6, 0x38, 0x0b, 0x00, 0xb4, 0x38, 0x0a };
1324
1325   if (((rom[0x7fe0] & 0x0f ) <= 9) && (rom[0x7fe3] == 0x93 || rom[0x7fe3] == 0x94 || rom[0x7fe3] == 0x95) &&  rom[0x7fef] == 0x00)
1326      return 1;
1327
1328   if (!memcmp(&rom[0x7ff0], jang_pung2, 16))
1329      return 1;
1330
1331   return 0;
1332}
1333
1334
1335static int detect_korean_mapper( UINT8 *rom )
1336{
1337   static const UINT8 signatures[2][16] =
1338   {
1339      { 0x3e, 0x11, 0x32, 0x00, 0xa0, 0x78, 0xcd, 0x84, 0x85, 0x3e, 0x02, 0x32, 0x00, 0xa0, 0xc9, 0xff }, /* Dodgeball King */
1340      { 0x41, 0x48, 0x37, 0x37, 0x44, 0x37, 0x4e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20 },   /* Sangokushi 3 */
1341   };
1342   int i;
1343
1344   for (i = 0; i < 2; i++)
1345   {
1346      if (!memcmp(&rom[0x7ff0], signatures[i], 16))
1347      {
1348         return 1;
1349      }
1350   }
1351   return 0;
1352}
1353#endif
1354
1355
1356static int detect_tvdraw( UINT8 *rom )
1357{
1358   static const UINT8 terebi_oekaki[7] = { 0x61, 0x6e, 0x6e, 0x61, 0x6b, 0x6d, 0x6e };   // "annakmn"
1359
1360   if (!memcmp(&rom[0x13b3], terebi_oekaki, 7))
1361      return 1;
1362
1363   return 0;
1364}
1365
1366
1367static int detect_lphaser_xoffset( running_machine &machine, UINT8 *rom )
1368{
1369   sms_state *state = machine.driver_data<sms_state>();
1370
1371   static const UINT8 signatures[6][16] =
1372   {
1373      /* Spacegun */
1374      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9d, 0x99, 0x10, 0x90, 0x00, 0x40 },
1375      /* Gangster Town */
1376      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x19, 0x87, 0x1b, 0xc9, 0x74, 0x50, 0x00, 0x4f },
1377      /* Shooting Gallery */
1378      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x20, 0x8a, 0x3a, 0x72, 0x50, 0x00, 0x4f },
1379      /* Rescue Mission */
1380      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x20, 0xfb, 0xd3, 0x06, 0x51, 0x00, 0x4f },
1381      /* Laser Ghost */
1382      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x00, 0x00, 0xb7, 0x55, 0x74, 0x70, 0x00, 0x40 },
1383      /* Assault City */
1384      { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9f, 0x74, 0x34, 0x70, 0x00, 0x40 },
1385   };
1386
1387   if (!(state->m_bios_port & IO_CARTRIDGE) && state->m_cartridge[state->m_current_cartridge].size >= 0x8000)
1388   {
1389      if (!memcmp(&rom[0x7ff0], signatures[0], 16) || !memcmp(&rom[0x7ff0], signatures[1], 16))
1390         return 40;
1391
1392      if (!memcmp(&rom[0x7ff0], signatures[2], 16))
1393         return 49;
1394
1395      if (!memcmp(&rom[0x7ff0], signatures[3], 16))
1396         return 47;
1397
1398      if (!memcmp(&rom[0x7ff0], signatures[4], 16))
1399         return 44;
1400
1401      if (!memcmp(&rom[0x7ff0], signatures[5], 16))
1402         return 53;
1403
1404   }
1405   return 50;
1406}
1407
1408
1409DEVICE_START( sms_cart )
1410{
1411   sms_state *state = device->machine().driver_data<sms_state>();
1412   int i;
1413
1414   for (i = 0; i < MAX_CARTRIDGES; i++)
1415   {
1416      state->m_cartridge[i].ROM = NULL;
1417      state->m_cartridge[i].size = 0;
1418      state->m_cartridge[i].features = 0;
1419      state->m_cartridge[i].cartSRAM = NULL;
1420      state->m_cartridge[i].sram_save = 0;
1421      state->m_cartridge[i].cartRAM = NULL;
1422      state->m_cartridge[i].ram_size = 0;
1423      state->m_cartridge[i].ram_page = 0;
1424   }
1425   state->m_current_cartridge = 0;
1426
1427   state->m_bios_port = (IO_EXPANSION | IO_CARTRIDGE | IO_CARD);
1428   if (!state->m_is_gamegear && !state->m_has_bios)
1429   {
1430      state->m_bios_port &= ~(IO_CARTRIDGE);
1431      state->m_bios_port |= IO_BIOS_ROM;
1432   }
1433}
1434
1435
1436DEVICE_IMAGE_LOAD( sms_cart )
1437{
1438   running_machine &machine = image.device().machine();
1439   sms_state *state = machine.driver_data<sms_state>();
1440   int size, index = 0, offset = 0;
1441   const char *extrainfo = NULL;
1442
1443   if (strcmp(image.device().tag(), "cart1") == 0)
1444      index = 0;
1445   if (strcmp(image.device().tag(), "cart2") == 0)
1446      index = 1;
1447   if (strcmp(image.device().tag(), "cart3") == 0)
1448      index = 2;
1449   if (strcmp(image.device().tag(), "cart4") == 0)
1450      index = 3;
1451   if (strcmp(image.device().tag(), "cart5") == 0)
1452      index = 4;
1453   if (strcmp(image.device().tag(), "cart6") == 0)
1454      index = 5;
1455   if (strcmp(image.device().tag(), "cart7") == 0)
1456      index = 6;
1457   if (strcmp(image.device().tag(), "cart8") == 0)
1458      index = 7;
1459   if (strcmp(image.device().tag(), "cart9") == 0)
1460      index = 8;
1461   if (strcmp(image.device().tag(), "cart10") == 0)
1462      index = 9;
1463   if (strcmp(image.device().tag(), "cart11") == 0)
1464      index = 10;
1465   if (strcmp(image.device().tag(), "cart12") == 0)
1466      index = 11;
1467   if (strcmp(image.device().tag(), "cart13") == 0)
1468      index = 12;
1469   if (strcmp(image.device().tag(), "cart14") == 0)
1470      index = 13;
1471   if (strcmp(image.device().tag(), "cart15") == 0)
1472      index = 14;
1473   if (strcmp(image.device().tag(), "cart16") == 0)
1474      index = 15;
1475
1476   state->m_cartridge[index].features = 0;
1477
1478   if (image.software_entry() == NULL)
1479   {
1480      size = image.length();
1481      extrainfo = hashfile_extrainfo(image);
1482   }
1483   else
1484      size = image.get_software_region_length("rom");
1485
1486   /* Check for 512-byte header */
1487   if ((size / 512) & 1)
1488   {
1489      offset = 512;
1490      size -= 512;
1491   }
1492
1493   if (!size)
1494   {
1495      image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM image: ROM image is too small");
1496      return IMAGE_INIT_FAIL;
1497   }
1498
1499   /* Create a new memory region to hold the ROM. */
1500   /* Make sure the region holds only complete (0x4000) rom banks */
1501   state->m_cartridge[index].size = (size & 0x3fff) ? (((size >> 14) + 1) << 14) : size;
1502   state->m_cartridge[index].ROM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].size);
1503   state->m_cartridge[index].cartSRAM = auto_alloc_array(machine, UINT8, NVRAM_SIZE);
1504
1505   /* Load ROM banks */
1506   if (image.software_entry() == NULL)
1507   {
1508      image.fseek(offset, SEEK_SET);
1509
1510      if (image.fread( state->m_cartridge[index].ROM, size) != size)
1511         return IMAGE_INIT_FAIL;
1512   }
1513   else
1514   {
1515      memcpy(state->m_cartridge[index].ROM, image.get_software_region("rom") + offset, size);
1516
1517      // check for mapper feature (currently only KOREAN_NOBANK, but eventually we will add the other mappers as well)
1518      if (image.get_feature("pcb") != NULL)
1519      {
1520         const char *mapper = image.get_feature("pcb");
1521         if (!strcmp(mapper, "korean_nobank"))
1522            state->m_cartridge[index].features |= CF_KOREAN_NOBANK_MAPPER;
1523      }
1524   }
1525
1526   /* check the image */
1527   if (!state->m_has_bios)
1528   {
1529      if (sms_verify_cart(state->m_cartridge[index].ROM, size) == IMAGE_VERIFY_FAIL)
1530      {
1531         logerror("Warning loading image: sms_verify_cart failed\n");
1532      }
1533   }
1534
1535   /* Detect special features from the extrainfo field */
1536   if (extrainfo)
1537   {
1538      /* Check for codemasters mapper */
1539      if (strstr(extrainfo, "CODEMASTERS"))
1540         state->m_cartridge[index].features |= CF_CODEMASTERS_MAPPER;
1541
1542      /* Check for korean mapper */
1543      if (strstr(extrainfo, "KOREAN"))
1544         state->m_cartridge[index].features |= CF_KOREAN_MAPPER;
1545
1546      /* Check for special SMS Compatibility mode gamegear cartridges */
1547      if (state->m_is_gamegear && strstr(extrainfo, "GGSMS"))
1548         state->m_cartridge[index].features |= CF_GG_SMS_MODE;
1549
1550      /* Check for 93C46 eeprom */
1551      if (strstr(extrainfo, "93C46"))
1552         state->m_cartridge[index].features |= CF_93C46_EEPROM;
1553
1554      /* Check for 8KB on-cart RAM */
1555      if (strstr(extrainfo, "8KB_CART_RAM"))
1556      {
1557         state->m_cartridge[index].features |= CF_ONCART_RAM;
1558         state->m_cartridge[index].ram_size = 0x2000;
1559         state->m_cartridge[index].cartRAM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].ram_size);
1560      }
1561   }
1562   else
1563   {
1564      /* If no extrainfo information is available try to find special information out on our own */
1565      /* Check for special cartridge features (new routine, courtesy of Omar Cornut, from MEKA)  */
1566      if (size >= 0x8000)
1567      {
1568         int c0002 = 0, c8000 = 0, cA000 = 0, cFFFF = 0, i;
1569         for (i = 0; i < 0x8000; i++)
1570         {
1571            if (state->m_cartridge[index].ROM[i] == 0x32) // Z80 opcode for: LD (xxxx), A
1572            {
1573               UINT16 addr = (state->m_cartridge[index].ROM[i + 2] << 8) | state->m_cartridge[index].ROM[i + 1];
1574               if (addr == 0xFFFF)
1575               { i += 2; cFFFF++; continue; }
1576               if (addr == 0x0002 || addr == 0x0003 || addr == 0x0004)
1577               { i += 2; c0002++; continue; }
1578               if (addr == 0x8000)
1579               { i += 2; c8000++; continue; }
1580               if (addr == 0xA000)
1581               { i += 2; cA000++; continue; }
1582            }
1583         }
1584
1585         LOG(("Mapper test: c002 = %d, c8000 = %d, cA000 = %d, cFFFF = %d\n", c0002, c8000, cA000, cFFFF));
1586
1587         // 2 is a security measure, although tests on existing ROM showed it was not needed
1588         if (c0002 > cFFFF + 2 || (c0002 > 0 && cFFFF == 0))
1589            state->m_cartridge[index].features |= CF_KOREAN_ZEMINA_MAPPER;
1590         else if (c8000 > cFFFF + 2 || (c8000 > 0 && cFFFF == 0))
1591            state->m_cartridge[index].features |= CF_CODEMASTERS_MAPPER;
1592         else if (cA000 > cFFFF + 2 || (cA000 > 0 && cFFFF == 0))
1593            state->m_cartridge[index].features |= CF_KOREAN_MAPPER;
1594
1595      }
1596
1597      /* Check for special SMS Compatibility mode gamegear cartridges */
1598      if (state->m_is_gamegear && image.software_entry() == NULL)   // not sure about how to handle this with softlists
1599      {
1600         /* Just in case someone passes us an sms file */
1601         if (!mame_stricmp (image.filetype(), "sms"))
1602            state->m_cartridge[index].features |= CF_GG_SMS_MODE;
1603      }
1604   }
1605
1606   if (state->m_cartridge[index].features & CF_CODEMASTERS_MAPPER)
1607   {
1608      state->m_cartridge[index].ram_size = 0x10000;
1609      state->m_cartridge[index].cartRAM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].ram_size);
1610      state->m_cartridge[index].ram_page = 0;
1611   }
1612
1613   /* For Light Phaser games, we have to detect the x offset */
1614   state->m_lphaser_x_offs = detect_lphaser_xoffset(machine, state->m_cartridge[index].ROM);
1615
1616   /* Terebi Oekaki (TV Draw) is a SG1000 game with special input device which is compatible with SG1000 Mark III */
1617   if ((detect_tvdraw(state->m_cartridge[index].ROM)) && state->m_is_region_japan)
1618   {
1619      address_space *program = machine.device("maincpu")->memory().space(AS_PROGRAM);
1620      program->install_legacy_write_handler(0x6000, 0x6000, FUNC(sms_tvdraw_axis_w));
1621      program->install_legacy_read_handler(0x8000, 0x8000, FUNC(sms_tvdraw_status_r));
1622      program->install_legacy_read_handler(0xa000, 0xa000, FUNC(sms_tvdraw_data_r));
1623      program->nop_write(0xa000, 0xa000);
1624   }
1625
1626   if (state->m_cartridge[index].features & CF_KOREAN_NOBANK_MAPPER)
1627   {
1628      // FIXME: we should have by default FFFD-FFFF to be only a mirror for DFFD-DFFF (with no bankswitch logic)
1629      // and then the handlers should be installed here for all but the KOREAN_NOBANK carts
1630      // However, to avoid memory map breakage, we currently go the other way around
1631      address_space *program = machine.device("maincpu")->memory().space(AS_PROGRAM);
1632      program->install_legacy_readwrite_handler(0xfffc, 0xffff, FUNC(sms_kor_nobank_r), FUNC(sms_kor_nobank_w));
1633   }
1634
1635   LOG(("Cart Features: %x\n", state->m_cartridge[index].features));
1636
1637   /* Load battery backed RAM, if available */
1638   image.battery_load(state->m_cartridge[index].cartSRAM, sizeof(UINT8) * NVRAM_SIZE, 0x00);
1639
1640   return IMAGE_INIT_PASS;
1641}
1642
1643
1644static void setup_cart_banks( running_machine &machine )
1645{
1646   sms_state *state = machine.driver_data<sms_state>();
1647   if (state->m_cartridge[state->m_current_cartridge].ROM)
1648   {
1649      UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000;
1650      state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM;
1651      state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + 0x0400;
1652      state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0);
1653      state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0);
1654      /* Codemasters mapper points to bank 0 for page 2 */
1655      if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
1656      {
1657         state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM;
1658      }
1659   }
1660   else
1661   {
1662      state->m_banking_cart[1] = state->m_banking_none[1];
1663      state->m_banking_cart[2] = state->m_banking_none[2];
1664      state->m_banking_cart[3] = state->m_banking_none[3];
1665      state->m_banking_cart[5] = state->m_banking_none[5];
1666   }
1667}
1668
1669#ifdef MESS
1670static void setup_banks( running_machine &machine )
1671{
1672   sms_state *state = machine.driver_data<sms_state>();
1673   UINT8 *mem = machine.region("maincpu")->base();
1674   state->m_banking_bios[1] = state->m_banking_cart[1] = state->m_banking_none[1] = mem;
1675   state->m_banking_bios[2] = state->m_banking_cart[2] = state->m_banking_none[2] = mem;
1676   state->m_banking_bios[3] = state->m_banking_cart[3] = state->m_banking_none[3] = mem;
1677   state->m_banking_bios[4] = state->m_banking_cart[4] = state->m_banking_none[4] = mem;
1678   state->m_banking_bios[5] = state->m_banking_cart[5] = state->m_banking_none[5] = mem;
1679   state->m_banking_bios[6] = state->m_banking_cart[6] = state->m_banking_none[6] = mem;
1680
1681   state->m_BIOS = machine.region("user1")->base();
1682
1683   state->m_bios_page_count = (state->m_BIOS ? machine.region("user1")->bytes() / 0x4000 : 0);
1684
1685   setup_cart_banks(machine);
1686
1687   if (state->m_BIOS == NULL || state->m_BIOS[0] == 0x00)
1688   {
1689      state->m_BIOS = NULL;
1690      state->m_bios_port |= IO_BIOS_ROM;
1691   }
1692
1693   if (state->m_BIOS)
1694   {
1695      state->m_banking_bios[1] = state->m_BIOS;
1696      state->m_banking_bios[2] = state->m_BIOS + 0x0400;
1697      state->m_banking_bios[3] = state->m_BIOS + ((1 < state->m_bios_page_count) ? 0x4000 : 0);
1698      state->m_banking_bios[5] = state->m_BIOS + ((2 < state->m_bios_page_count) ? 0x8000 : 0);
1699   }
1700}
1701#endif
1702
1703MACHINE_START( sms )
1704{
1705   sms_state *state = machine.driver_data<sms_state>();
1706
1707   machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sms_machine_stop),&machine));
1708   state->m_rapid_fire_timer = machine.scheduler().timer_alloc(FUNC(rapid_fire_callback));
1709   state->m_rapid_fire_timer->adjust(attotime::from_hz(10), 0, attotime::from_hz(10));
1710
1711   state->m_lphaser_1_timer = machine.scheduler().timer_alloc(FUNC(lphaser_1_callback));
1712   state->m_lphaser_2_timer = machine.scheduler().timer_alloc(FUNC(lphaser_2_callback));
1713
1714   state->m_main_cpu = machine.device("maincpu");
1715   state->m_control_cpu = machine.device("control");
1716   state->m_vdp = machine.device("sms_vdp");
1717   state->m_ym = machine.device("ym2413");
1718   state->m_main_scr = machine.device("screen");
1719   state->m_left_lcd = machine.device("left_lcd");
1720   state->m_right_lcd = machine.device("right_lcd");
1721
1722   /* Check if lightgun has been chosen as input: if so, enable crosshair */
1723   machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick));
1724}
1725
1726#ifdef MESS
1727MACHINE_RESET( sms )
1728{
1729   address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
1730   sms_state *state = machine.driver_data<sms_state>();
1731
1732   state->m_ctrl_reg = 0xff;
1733   if (state->m_has_fm)
1734      state->m_fm_detect = 0x01;
1735
1736   state->m_mapper_ram = (UINT8*)space->get_write_ptr(0xdffc);
1737
1738   state->m_bios_port = 0;
1739
1740   if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER)
1741   {
1742      /* Install special memory handlers */
1743      space->install_legacy_write_handler(0x0000, 0x0000, FUNC(sms_codemasters_page0_w));
1744      space->install_legacy_write_handler(0x4000, 0x4000, FUNC(sms_codemasters_page1_w));
1745   }
1746
1747   if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_MAPPER)
1748      space->install_legacy_write_handler(0x0000, 0x0003, FUNC(sms_korean_zemina_banksw_w));
1749
1750   if (state->m_cartridge[state->m_current_cartridge].features & CF_GG_SMS_MODE)
1751      sms_vdp_set_ggsmsmode(state->m_vdp, 1);
1752
1753   /* Initialize SIO stuff for GG */
1754   state->m_gg_sio[0] = 0x7f;
1755   state->m_gg_sio[1] = 0xff;
1756   state->m_gg_sio[2] = 0x00;
1757   state->m_gg_sio[3] = 0xff;
1758   state->m_gg_sio[4] = 0x00;
1759
1760   state->m_store_control = 0;
1761
1762   setup_banks(machine);
1763
1764   setup_rom(space);
1765
1766   state->m_rapid_fire_state_1 = 0;
1767   state->m_rapid_fire_state_2 = 0;
1768
1769   state->m_last_paddle_read_time = 0;
1770   state->m_paddle_read_state = 0;
1771
1772   state->m_last_sports_pad_time_1 = 0;
1773   state->m_last_sports_pad_time_2 = 0;
1774   state->m_sports_pad_state_1 = 0;
1775   state->m_sports_pad_state_2 = 0;
1776   state->m_sports_pad_last_data_1 = 0;
1777   state->m_sports_pad_last_data_2 = 0;
1778   state->m_sports_pad_1_x = 0;
1779   state->m_sports_pad_1_y = 0;
1780   state->m_sports_pad_2_x = 0;
1781   state->m_sports_pad_2_y = 0;
1782
1783   state->m_lphaser_1_latch = 0;
1784   state->m_lphaser_2_latch = 0;
1785
1786   state->m_sscope_state = 0;
1787
1788   state->m_tvdraw_data = 0;
1789}
1790#endif
1791
1792READ8_HANDLER( sms_store_cart_select_r )
1793{
1794   return 0xff;
1795}
1796
1797
1798WRITE8_HANDLER( sms_store_cart_select_w )
1799{
1800   sms_state *state = space->machine().driver_data<sms_state>();
1801   UINT8 slot = data >> 4;
1802   UINT8 slottype = data & 0x08;
1803
1804   logerror("switching in part of %s slot #%d\n", slottype ? "card" : "cartridge", slot );
1805   /* cartridge? slot #0 */
1806   if (slottype == 0)
1807      state->m_current_cartridge = slot;
1808
1809   setup_cart_banks(space->machine());
1810   memory_set_bankptr(space->machine(), "bank10", state->m_banking_cart[3] + 0x2000);
1811   setup_rom(space);
1812}
1813
1814
1815READ8_HANDLER( sms_store_select1 )
1816{
1817   return 0xff;
1818}
1819
1820
1821READ8_HANDLER( sms_store_select2 )
1822{
1823   return 0xff;
1824}
1825
1826
1827READ8_HANDLER( sms_store_control_r )
1828{
1829   sms_state *state = space->machine().driver_data<sms_state>();
1830   return state->m_store_control;
1831}
1832
1833
1834WRITE8_HANDLER( sms_store_control_w )
1835{
1836   sms_state *state = space->machine().driver_data<sms_state>();
1837   logerror("0x%04X: sms_store_control write 0x%02X\n", cpu_get_pc(&space->device()), data);
1838   if (data & 0x02)
1839   {
1840      space->machine().device<cpu_device>("maincpu")->resume(SUSPEND_REASON_HALT);
1841   }
1842   else
1843   {
1844      /* Pull reset line of CPU #0 low */
1845      space->machine().device("maincpu")->reset();
1846      space->machine().device<cpu_device>("maincpu")->suspend(SUSPEND_REASON_HALT, 1);
1847   }
1848   state->m_store_control = data;
1849}
1850
1851void sms_store_int_callback( running_machine &machine, int state )
1852{
1853   sms_state *driver_state = machine.driver_data<sms_state>();
1854   device_set_input_line(driver_state->m_store_control & 0x01 ? driver_state->m_control_cpu : driver_state->m_main_cpu, 0, state);
1855}
1856
1857
1858static void sms_set_zero_flag( running_machine &machine )
1859{
1860   sms_state *state = machine.driver_data<sms_state>();
1861   state->m_is_gamegear = 0;
1862   state->m_is_region_japan = 0;
1863   state->m_has_bios_0400 = 0;
1864   state->m_has_bios_2000 = 0;
1865   state->m_has_bios_full = 0;
1866   state->m_has_bios = 0;
1867   state->m_has_fm = 0;
1868}
1869
1870DRIVER_INIT( sg1000m3 )
1871{
1872   sms_state *state = machine.driver_data<sms_state>();
1873   sms_set_zero_flag(machine);
1874   state->m_is_region_japan = 1;
1875   state->m_has_fm = 1;
1876}
1877
1878
1879DRIVER_INIT( sms1 )
1880{
1881   sms_state *state = machine.driver_data<sms_state>();
1882   sms_set_zero_flag(machine);
1883   state->m_has_bios_full = 1;
1884}
1885
1886
1887DRIVER_INIT( smsj )
1888{
1889   sms_state *state = machine.driver_data<sms_state>();
1890   sms_set_zero_flag(machine);
1891   state->m_is_region_japan = 1;
1892   state->m_has_bios_2000 = 1;
1893   state->m_has_fm = 1;
1894}
1895
1896
1897DRIVER_INIT( sms2kr )
1898{
1899   sms_state *state = machine.driver_data<sms_state>();
1900   sms_set_zero_flag(machine);
1901   state->m_is_region_japan = 1;
1902   state->m_has_bios_full = 1;
1903   state->m_has_fm = 1;
1904}
1905
1906
1907DRIVER_INIT( smssdisp )
1908{
1909   sms_set_zero_flag(machine);
1910}
1911
1912
1913DRIVER_INIT( gamegear )
1914{
1915   sms_state *state = machine.driver_data<sms_state>();
1916   sms_set_zero_flag(machine);
1917   state->m_is_gamegear = 1;
1918}
1919
1920
1921DRIVER_INIT( gamegeaj )
1922{
1923   sms_state *state = machine.driver_data<sms_state>();
1924   sms_set_zero_flag(machine);
1925   state->m_is_region_japan = 1;
1926   state->m_is_gamegear = 1;
1927   state->m_has_bios_0400 = 1;
1928}
1929
1930
1931static void sms_black_bitmap( const screen_device *screen, bitmap_t *bitmap )
1932{
1933   const int width = screen->width();
1934   const int height = screen->height();
1935   int x, y;
1936
1937   for (y = 0; y < height; y++)
1938      for (x = 0; x < width; x++)
1939         *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0);
1940}
1941
1942VIDEO_START( sms1 )
1943{
1944   sms_state *state = machine.driver_data<sms_state>();
1945   screen_device *screen = machine.first_screen();
1946   int width = screen->width();
1947   int height = screen->height();
1948
1949   state->m_prevleft_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
1950   state->m_prevright_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
1951   state->save_item(NAME(*state->m_prevleft_bitmap));
1952   state->save_item(NAME(*state->m_prevright_bitmap));
1953}
1954
1955SCREEN_UPDATE( sms1 )
1956{
1957   sms_state *state = screen->machine().driver_data<sms_state>();
1958   UINT8 sscope = input_port_read_safe(screen->machine(), "SEGASCOPE", 0x00);
1959   UINT8 sscope_binocular_hack = input_port_read_safe(screen->machine(), "SSCOPE_BINOCULAR", 0x00);
1960   UINT8 occluded_view = 0;
1961
1962   // without SegaScope, both LCDs for glasses go black
1963   if ((screen != state->m_main_scr) && !sscope)
1964      occluded_view = 1;
1965
1966   // with SegaScope, sscope_state 0 = left screen OFF, right screen ON
1967   if (!(state->m_sscope_state & 0x01) && (screen == state->m_left_lcd))
1968      occluded_view = 1;
1969
1970   // with SegaScope, sscope_state 1 = left screen ON, right screen OFF
1971   if ((state->m_sscope_state & 0x01) && (screen == state->m_right_lcd))
1972      occluded_view = 1;
1973
1974   if (!occluded_view)
1975   {
1976      sms_vdp_update(state->m_vdp, bitmap, cliprect);
1977
1978      // HACK: fake 3D->2D handling (if enabled, it repeats each frame twice on the selected lens)
1979      // save a copy of current bitmap for the binocular hack
1980      if (sscope && (screen == state->m_left_lcd) && (sscope_binocular_hack & 0x01))
1981         copybitmap(state->m_prevleft_bitmap, bitmap, 0, 0, 0, 0, cliprect);
1982      if (sscope && (screen == state->m_right_lcd) && (sscope_binocular_hack & 0x02))
1983         copybitmap(state->m_prevright_bitmap, bitmap, 0, 0, 0, 0, cliprect);
1984   }
1985   else
1986   {
1987      sms_black_bitmap(screen, bitmap);
1988
1989      // HACK: fake 3D->2D handling (if enabled, it repeats each frame twice on the selected lens)
1990      // use the copied bitmap for the binocular hack
1991      if (sscope && (screen == state->m_left_lcd) && (sscope_binocular_hack & 0x01))
1992         copybitmap(bitmap, state->m_prevleft_bitmap, 0, 0, 0, 0, cliprect);
1993      if (sscope && (screen == state->m_right_lcd) && (sscope_binocular_hack & 0x02))
1994         copybitmap(bitmap, state->m_prevright_bitmap, 0, 0, 0, 0, cliprect);
1995   }
1996
1997   return 0;
1998}
1999
2000SCREEN_UPDATE( sms )
2001{
2002   sms_state *state = screen->machine().driver_data<sms_state>();
2003   sms_vdp_update(state->m_vdp, bitmap, cliprect);
2004   return 0;
2005}
2006
2007VIDEO_START( gamegear )
2008{
2009   sms_state *state = machine.driver_data<sms_state>();
2010   screen_device *screen = machine.first_screen();
2011   int width = screen->width();
2012   int height = screen->height();
2013
2014   state->m_prev_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
2015   state->m_tmp_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32);
2016   state->save_item(NAME(*state->m_prev_bitmap));
2017}
2018
2019SCREEN_UPDATE( gamegear )
2020{
2021   sms_state *state = screen->machine().driver_data<sms_state>();
2022   int width = screen->width();
2023   int height = screen->height();
2024   int x, y;
2025
2026   sms_vdp_update(state->m_vdp, state->m_tmp_bitmap, cliprect);
2027
2028   // HACK: fake LCD persistence effect
2029   // (it would be better to generalize this in the core, to be used for all LCD systems)
2030   for (y = 0; y < height; y++)
2031   {
2032      UINT32 *line0 = BITMAP_ADDR32(state->m_tmp_bitmap, y, 0);
2033      UINT32 *line1 = BITMAP_ADDR32(state->m_prev_bitmap, y, 0);
2034      for (x = 0; x < width; x++)
2035      {
2036         UINT32 color0 = line0[x];
2037         UINT32 color1 = line1[x];
2038         UINT16 r0 = (color0 >> 16) & 0x000000ff;
2039         UINT16 g0 = (color0 >>  8) & 0x000000ff;
2040         UINT16 b0 = (color0 >>  0) & 0x000000ff;
2041         UINT16 r1 = (color1 >> 16) & 0x000000ff;
2042         UINT16 g1 = (color1 >>  8) & 0x000000ff;
2043         UINT16 b1 = (color1 >>  0) & 0x000000ff;
2044         UINT8 r = (UINT8)((r0 + r1) >> 1);
2045         UINT8 g = (UINT8)((g0 + g1) >> 1);
2046         UINT8 b = (UINT8)((b0 + b1) >> 1);
2047         *BITMAP_ADDR32(bitmap, y, x) = (r << 16) | (g << 8) | b;
2048      }
2049   }
2050   copybitmap(state->m_prev_bitmap, state->m_tmp_bitmap, 0, 0, 0, 0, cliprect);
2051
2052   return 0;
2053}
src/mess/mess.mak
r12639r12640
13891389   $(MAME_MACHINE)/gdrom.o    \
13901390   $(MESS_MACHINE)/dccons.o   \
13911391   $(MESS_VIDEO)/smsvdp.o      \
1392   $(MESS_MACHINE)/segasms.o   \
1393   $(MESS_DRIVERS)/segasms.o   \
1392   $(MESS_MACHINE)/sms.o   \
1393   $(MESS_DRIVERS)/sms.o   \
13941394   $(MESS_DRIVERS)/sg1000.o   \
13951395
13961396$(MESSOBJ)/sgi.a:            \
r12639r12640
18891889$(MESS_DRIVERS)/sdk86.o:   $(MESS_LAYOUT)/sdk86.lh
18901890$(MESS_DRIVERS)/selz80.o:   $(MESS_LAYOUT)/selz80.lh
18911891$(MESS_DRIVERS)/slc1.o:      $(MESS_LAYOUT)/slc1.lh
1892$(MESS_DRIVERS)/segasms.o:   $(MAME_LAYOUT)/sms1.lh
1892$(MESS_DRIVERS)/sms.o:      $(MAME_LAYOUT)/sms1.lh
18931893$(MESS_DRIVERS)/stopthie.o:   $(MESS_LAYOUT)/stopthie.lh
18941894$(MESS_DRIVERS)/super80.o:   $(MESS_LAYOUT)/super80.lh
18951895$(MESS_DRIVERS)/supercon.o:   $(MESS_LAYOUT)/supercon.lh
src/mess/drivers/segasms.c
r12639r12640
1/******************************************************************************
2 Contributors:
3
4    Marat Fayzullin (MG source)
5    Charles MacDonald
6    Mathis Rosenhauer
7    Brad Oliver
8    Michael Luong
9
10 To do:
11
12 - SIO interface for Game Gear (needs netplay, I guess)
13 - SMS lightgun support
14 - LCD persistence emulation for GG
15 - SMS 3D glass support
16
17 The Game Gear SIO hardware is not emulated but has some
18 placeholders in 'machine/sms.c'
19
20 Changes:
21    Apr 02 - Added raster palette effects for SMS & GG (ML)
22                 - Added sprite collision (ML)
23                 - Added zoomed sprites (ML)
24    May 02 - Fixed paging bug (ML)
25                 - Fixed sprite and tile priority bug (ML)
26                 - Fixed bug #66 (ML)
27                 - Fixed bug #78 (ML)
28                 - try to implement LCD persistence emulation for GG (ML)
29    Jun 10, 02 - Added bios emulation (ML)
30    Jun 12, 02 - Added PAL & NTSC systems (ML)
31    Jun 25, 02 - Added border emulation (ML)
32    Jun 27, 02 - Version bits for Game Gear (bits 6 of port 00) (ML)
33    Nov-Dec, 05 - Numerous cleanups, fixes, updates (WP)
34    Mar, 07 - More cleanups, fixes, mapper additions, etc (WP)
35
36SMS Store Unit memory map for the second CPU:
37
380000-3FFF - BIOS
394000-47FF - RAM
408000      - System Control Register (R/W)
41            Reading:
42            bit7      - ready (0 = ready, 1 = not ready)
43            bit6-bit5 - unknown
44            bit4-bit3 - timer selection bit switches
45            bit2-bit0 - unknown
46            Writing:
47            bit7-bit4 - unknown, maybe led of selected game to set?
48            bit3      - unknown, 1 seems to be written all the time
49            bit2      - unknown, 1 seems to be written all the time
50            bit1      - reset signal for sms cpu, 0 = reset low, 1 = reset high
51            bit0      - which cpu receives interrupt signals, 0 = sms cpu, 1 = controlling cpu
52C000      - Card/Cartridge selction register (W)
53            bit7-bit4 - slot to select
54            bit3      - slot type (0 = cartridge, 1 = card ?)
55            bit2-bit0 - unknown
56C400      - ???? (used once)
57D800      - Selection buttons #1, 1-8 (R)
58DC00      - Selection buttons #2, 9-16 (R)
59
60 ******************************************************************************/
61
62#include "emu.h"
63#include "cpu/z80/z80.h"
64#include "sound/sn76496.h"
65#include "sound/2413intf.h"
66#include "includes/segasms.h"
67#include "video/smsvdp.h"
68#include "imagedev/cartslot.h"
69
70#include "sms1.lh"
71
72#define MASTER_CLOCK_PAL   53203400   /* This might be a tiny bit too low */
73
74
75static ADDRESS_MAP_START( sms1_mem, AS_PROGRAM, 8 )
76   AM_RANGE(0x0000, 0x03ff) AM_ROMBANK("bank1")               /* First 0x0400 part always points to first page */
77   AM_RANGE(0x0400, 0x3fff) AM_ROMBANK("bank2")               /* switchable rom bank */
78   AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank3")               /* switchable rom bank */
79   AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank4")               /* switchable rom bank */
80   AM_RANGE(0x8000, 0x9fff) AM_READ_BANK("bank5") AM_WRITE(sms_cartram_w)   /* ROM bank / on-cart RAM */
81   AM_RANGE(0xa000, 0xbfff) AM_READ_BANK("bank6") AM_WRITE(sms_cartram2_w)   /* ROM bank / on-cart RAM */
82   AM_RANGE(0xc000, 0xdff7) AM_MIRROR(0x2000) AM_RAM         /* RAM (mirror at 0xE000) */
83   AM_RANGE(0xdff8, 0xdfff) AM_RAM                  /* RAM "underneath" frame registers */
84   AM_RANGE(0xfff8, 0xfffb) AM_READWRITE(sms_sscope_r, sms_sscope_w)   /* 3-D glasses */
85   AM_RANGE(0xfffc, 0xffff) AM_READWRITE(sms_mapper_r, sms_mapper_w)   /* Bankswitch control */
86ADDRESS_MAP_END
87
88static ADDRESS_MAP_START( sms_mem, AS_PROGRAM, 8 )
89   AM_RANGE(0x0000, 0x03ff) AM_ROMBANK("bank1")               /* First 0x0400 part always points to first page */
90   AM_RANGE(0x0400, 0x3fff) AM_ROMBANK("bank2")               /* switchable rom bank */
91   AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank3")               /* switchable rom bank */
92   AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank4")               /* switchable rom bank */
93   AM_RANGE(0x8000, 0x9fff) AM_READ_BANK("bank5") AM_WRITE(sms_cartram_w)   /* ROM bank / on-cart RAM */
94   AM_RANGE(0xa000, 0xbfff) AM_READ_BANK("bank6") AM_WRITE(sms_cartram2_w)   /* ROM bank / on-cart RAM */
95   AM_RANGE(0xc000, 0xdffb) AM_MIRROR(0x2000) AM_RAM         /* RAM (mirror at 0xE000) */
96   AM_RANGE(0xdffc, 0xdfff) AM_RAM                  /* RAM "underneath" frame registers */
97   AM_RANGE(0xfffc, 0xffff) AM_READWRITE(sms_mapper_r, sms_mapper_w)   /* Bankswitch control */
98ADDRESS_MAP_END
99
100static ADDRESS_MAP_START( sms_store_mem, AS_PROGRAM, 8 )
101   AM_RANGE(0x0000, 0x3fff) AM_ROM                  /* BIOS */
102   AM_RANGE(0x4000, 0x47ff) AM_RAM                  /* RAM */
103   AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank10")               /* Cartridge/card peek area */
104   AM_RANGE(0x8000, 0x8000) AM_READWRITE(sms_store_control_r, sms_store_control_w)   /* Control */
105   AM_RANGE(0xc000, 0xc000) AM_READWRITE(sms_store_cart_select_r, sms_store_cart_select_w)    /* cartridge/card slot selector */
106   AM_RANGE(0xd800, 0xd800) AM_READ(sms_store_select1)         /* Game selector port #1 */
107   AM_RANGE(0xdc00, 0xdc00) AM_READ(sms_store_select2)         /* Game selector port #2 */
108ADDRESS_MAP_END
109
110static ADDRESS_MAP_START( sms_io, AS_IO, 8 )
111   ADDRESS_MAP_GLOBAL_MASK(0xff)
112   ADDRESS_MAP_UNMAP_HIGH
113   AM_RANGE(0x00, 0x00) AM_MIRROR(0x3e) AM_WRITE(sms_bios_w)
114   AM_RANGE(0x01, 0x01) AM_MIRROR(0x3e) AM_WRITE(sms_io_control_w)
115   AM_RANGE(0x40, 0x7f)                 AM_READ(sms_count_r)
116   AM_RANGE(0x40, 0x7f)                 AM_DEVWRITE("segapsg", sn76496_w)
117   AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_data_r, sms_vdp_data_w)
118   AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_ctrl_r, sms_vdp_ctrl_w)
119   AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_0_r)
120   AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_1_r)
121   AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_0_r)
122   AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_1_r)
123   AM_RANGE(0xf0, 0xf0)                 AM_READWRITE(sms_input_port_0_r, sms_ym2413_register_port_0_w)
124   AM_RANGE(0xf1, 0xf1)                 AM_READWRITE(sms_input_port_1_r, sms_ym2413_data_port_0_w)
125   AM_RANGE(0xf2, 0xf2)                 AM_READWRITE(sms_fm_detect_r, sms_fm_detect_w)
126   AM_RANGE(0xf3, 0xf3)                 AM_READ(sms_input_port_1_r)
127   AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_0_r)
128   AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_1_r)
129   AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_0_r)
130   AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_1_r)
131ADDRESS_MAP_END
132
133static ADDRESS_MAP_START( gg_io, AS_IO, 8 )
134   ADDRESS_MAP_GLOBAL_MASK(0xff)
135   ADDRESS_MAP_UNMAP_HIGH
136   AM_RANGE(0x00, 0x00)                 AM_READ(gg_input_port_2_r)
137   AM_RANGE(0x01, 0x05)                 AM_READWRITE(gg_sio_r, gg_sio_w)
138   AM_RANGE(0x06, 0x06)                 AM_DEVWRITE("gamegear", sn76496_stereo_w)
139   AM_RANGE(0x07, 0x07)                 AM_WRITE(sms_io_control_w)
140   AM_RANGE(0x08, 0x08) AM_MIRROR(0x06) AM_WRITE(sms_bios_w)
141   AM_RANGE(0x09, 0x09) AM_MIRROR(0x06) AM_WRITE(sms_io_control_w)
142   AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_WRITE(sms_bios_w)
143   AM_RANGE(0x11, 0x11) AM_MIRROR(0x0e) AM_WRITE(sms_io_control_w)
144   AM_RANGE(0x20, 0x20) AM_MIRROR(0x1e) AM_WRITE(sms_bios_w)
145   AM_RANGE(0x21, 0x21) AM_MIRROR(0x1e) AM_WRITE(sms_io_control_w)
146   AM_RANGE(0x40, 0x7f)                 AM_READ(sms_count_r)
147   AM_RANGE(0x40, 0x7f)                 AM_DEVWRITE("gamegear", sn76496_w)
148   AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_data_r, sms_vdp_data_w)
149   AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_ctrl_r, sms_vdp_ctrl_w)
150   AM_RANGE(0xc0, 0xc0)                 AM_READ_PORT("PORT_DC")
151   AM_RANGE(0xc1, 0xc1)                 AM_READ_PORT("PORT_DD")
152   AM_RANGE(0xdc, 0xdc)                 AM_READ_PORT("PORT_DC")
153   AM_RANGE(0xdd, 0xdd)                 AM_READ_PORT("PORT_DD")
154ADDRESS_MAP_END
155
156
157static INPUT_PORTS_START( sms )
158   PORT_START("PORT_DC")
159   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
160   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
161   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
162   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
163   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
164   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
165   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
166   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
167
168   PORT_START("PORT_DD")
169   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
170   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
171   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
172   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
173   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) /* Software Reset bit */
174   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
175   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port A TH */
176   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port B TH */
177
178   PORT_START("PAUSE")
179   PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED )
180   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START ) PORT_NAME(DEF_STR(Pause))
181
182   PORT_START("LPHASER0")   /* Light phaser X - player 1 */
183   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x01)
184
185   PORT_START("LPHASER1")   /* Light phaser Y - player 1 */
186   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x01)
187
188   PORT_START("LPHASER2")   /* Light phaser X - player 2 */
189   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x10)
190
191   PORT_START("LPHASER3")   /* Light phaser Y - player 2 */
192   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(25) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x10)
193
194   PORT_START("RFU")   /* Rapid Fire Unit */
195   PORT_CONFNAME( 0x03, 0x00, "Rapid Fire Unit - Player 1" )
196   PORT_CONFSETTING(   0x00, DEF_STR( Off ) )
197   PORT_CONFSETTING(   0x01, "Button A" )
198   PORT_CONFSETTING(   0x02, "Button B" )
199   PORT_CONFSETTING(   0x03, "Button A + B" )
200   PORT_CONFNAME( 0x0c, 0x00, "Rapid Fire Unit - Player 2" )
201   PORT_CONFSETTING(   0x00, DEF_STR( Off ) )
202   PORT_CONFSETTING(   0x04, "Button A" )
203   PORT_CONFSETTING(   0x08, "Button B" )
204   PORT_CONFSETTING(   0x0c, "Button A + B" )
205
206   PORT_START("PADDLE0")   /* Paddle player 1 */
207   PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x02)
208
209   PORT_START("PADDLE1")   /* Paddle player 2 */
210   PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x20)
211
212   PORT_START("CTRLIPT")   /* Light Phaser and Paddle Control buttons */
213   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x01)
214   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x02)
215   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
216   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
217   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x10)
218   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x20)
219   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
220   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
221
222   PORT_START("CTRLSEL")   /* Controller selection */
223   PORT_CONFNAME( 0x0f, 0x00, "Player 1 Controller" )
224   PORT_CONFSETTING( 0x00, DEF_STR( Joystick ) )
225   PORT_CONFSETTING( 0x01, "Light Phaser" )
226   PORT_CONFSETTING( 0x02, "Sega Paddle Control" )
227   PORT_CONFSETTING( 0x04, "Sega Sports Pad" )
228   PORT_CONFNAME( 0xf0, 0x00, "Player 2 Controller" )
229   PORT_CONFSETTING( 0x00, DEF_STR( Joystick ) )
230   PORT_CONFSETTING( 0x10, "Light Phaser" )
231   PORT_CONFSETTING( 0x20, "Sega Paddle Control" )
232   PORT_CONFSETTING( 0x40, "Sega Sports Pad" )
233
234   PORT_START("SPORT0")   /* Player 1 Sports Pad X axis */
235   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
236
237   PORT_START("SPORT1")   /* Player 1 Sports Pad Y axis */
238   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
239
240   PORT_START("SPORT2")   /* Player 2 Sports Pad X axis */
241   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
242
243   PORT_START("SPORT3")   /* Player 2 Sports Pad Y axis */
244   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
245INPUT_PORTS_END
246
247static INPUT_PORTS_START( sms1 )
248   PORT_INCLUDE( sms )
249
250   PORT_START("RESET")
251   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Reset Button")
252
253   PORT_START("SEGASCOPE")
254   PORT_CONFNAME( 0x01, 0x00, "SegaScope (3-D Glasses)" )
255   PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
256   PORT_CONFSETTING( 0x01, DEF_STR( On ) )
257
258   PORT_START("SSCOPE_BINOCULAR")
259   PORT_CONFNAME( 0x03, 0x00, "SegaScope - Binocular Hack" ) PORT_CONDITION("SEGASCOPE", 0x01, PORTCOND_EQUALS, 0x01)
260   PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
261   PORT_CONFSETTING( 0x01, "Left Lens" )
262   PORT_CONFSETTING( 0x02, "Right Lens" )
263   PORT_CONFSETTING( 0x03, "Both Lens" )
264   PORT_BIT( 0x03, 0x00, IPT_UNUSED ) PORT_CONDITION("SEGASCOPE", 0x01, PORTCOND_EQUALS, 0x00)
265INPUT_PORTS_END
266
267static INPUT_PORTS_START( smsj )
268   PORT_INCLUDE( sms1 )
269
270   PORT_START("TVDRAW")
271   PORT_CONFNAME( 0x01, 0x00, "Terebi Oekaki Graphics Tablet" )
272   PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
273   PORT_CONFSETTING( 0x01, DEF_STR( On ) )
274
275   PORT_START("TVDRAW_X")
276   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Tablet - X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
277   PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
278
279   PORT_START("TVDRAW_Y")
280   PORT_BIT( 0xff, 0x60, IPT_LIGHTGUN_Y ) PORT_NAME("Tablet - Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0, 191) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
281   PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
282
283   PORT_START("TVDRAW_PEN")
284   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Tablet - Pen") PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
285INPUT_PORTS_END
286
287static INPUT_PORTS_START( gg )
288   PORT_START("PORT_DC")
289   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY
290   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY
291   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY
292   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY
293   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
294   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
295   PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
296
297   PORT_START("PORT_DD")
298   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
299
300   PORT_START("START")
301   PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED )
302   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START ) PORT_NAME("Start") /* Game Gear START */
303INPUT_PORTS_END
304
305static PALETTE_INIT( sms )
306{
307   int i;
308   for (i = 0; i < 64; i++)
309   {
310      int r = i & 0x03;
311      int g = (i & 0x0c) >> 2;
312      int b = (i & 0x30) >> 4;
313      palette_set_color_rgb(machine, i, r << 6, g << 6, b << 6);
314   }
315   /* TMS9918 palette */
316   palette_set_color_rgb(machine, 64+ 0,   0,   0,   0);
317   palette_set_color_rgb(machine, 64+ 1,   0,   0,   0);
318   palette_set_color_rgb(machine, 64+ 2,  33, 200,  66);
319   palette_set_color_rgb(machine, 64+ 3,  94, 220, 120);
320   palette_set_color_rgb(machine, 64+ 4,  84,  85, 237);
321   palette_set_color_rgb(machine, 64+ 5, 125, 118, 252);
322   palette_set_color_rgb(machine, 64+ 6, 212,  82,  77);
323   palette_set_color_rgb(machine, 64+ 7,  66, 235, 245);
324   palette_set_color_rgb(machine, 64+ 8, 252,  85,  84);
325   palette_set_color_rgb(machine, 64+ 9, 255, 121, 120);
326   palette_set_color_rgb(machine, 64+10, 212, 193,  84);
327   palette_set_color_rgb(machine, 64+11, 230, 206, 128);
328   palette_set_color_rgb(machine, 64+12,  33, 176,  59);
329   palette_set_color_rgb(machine, 64+13, 201,  91, 186);
330   palette_set_color_rgb(machine, 64+14, 204, 204, 204);
331   palette_set_color_rgb(machine, 64+15, 255, 255, 255);
332}
333
334static PALETTE_INIT( gamegear )
335{
336   int i;
337   for (i = 0; i < 4096; i++)
338   {
339      int r = i & 0x000f;
340      int g = (i & 0x00f0) >> 4;
341      int b = (i & 0x0f00) >> 8;
342      palette_set_color_rgb(machine, i, r << 4, g << 4, b << 4);
343   }
344}
345
346
347
348static void sms_int_callback( running_machine &machine, int state )
349{
350   cputag_set_input_line(machine, "maincpu", 0, state);
351}
352
353static const smsvdp_interface _315_5124_intf =
354{
355   MODEL_315_5124,
356   sms_int_callback,
357   sms_pause_callback
358};
359
360static const smsvdp_interface _315_5246_intf =
361{
362   MODEL_315_5246,
363   sms_int_callback,
364   sms_pause_callback
365};
366
367static const smsvdp_interface _315_5378_intf =
368{
369   MODEL_315_5378,
370   sms_int_callback,
371   sms_pause_callback
372};
373
374static const smsvdp_interface sms_store_intf =
375{
376   MODEL_315_5124,
377   sms_store_int_callback,
378   sms_pause_callback
379};
380
381static MACHINE_CONFIG_FRAGMENT( sms_cartslot )
382   MCFG_CARTSLOT_ADD("cart1")
383   MCFG_CARTSLOT_EXTENSION_LIST("sms,bin")
384   MCFG_CARTSLOT_NOT_MANDATORY
385   MCFG_CARTSLOT_INTERFACE("sms_cart")
386   MCFG_CARTSLOT_START(sms_cart)
387   MCFG_CARTSLOT_LOAD(sms_cart)
388
389   MCFG_SOFTWARE_LIST_ADD("cart_list","sms")
390MACHINE_CONFIG_END
391
392static MACHINE_CONFIG_FRAGMENT( gg_cartslot )
393   MCFG_CARTSLOT_ADD("cart1")
394   MCFG_CARTSLOT_EXTENSION_LIST("gg,bin")
395   MCFG_CARTSLOT_MANDATORY
396   MCFG_CARTSLOT_INTERFACE("gamegear_cart")
397   MCFG_CARTSLOT_START(sms_cart)
398   MCFG_CARTSLOT_LOAD(sms_cart)
399
400   MCFG_SOFTWARE_LIST_ADD("cart_list","gamegear")
401MACHINE_CONFIG_END
402
403static MACHINE_CONFIG_START( sms_ntsc_base, sms_state )
404   /* basic machine hardware */
405   MCFG_CPU_ADD("maincpu", Z80, XTAL_53_693175MHz/15)
406   MCFG_CPU_PROGRAM_MAP(sms_mem)
407   MCFG_CPU_IO_MAP(sms_io)
408
409   MCFG_QUANTUM_TIME(attotime::from_hz(60))
410
411   MCFG_MACHINE_START(sms)
412   MCFG_MACHINE_RESET(sms)
413
414   /* sound hardware */
415   MCFG_SPEAKER_STANDARD_MONO("mono")
416   MCFG_SOUND_ADD("segapsg", SEGAPSG, XTAL_53_693175MHz/15)
417   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
418
419   MCFG_FRAGMENT_ADD( sms_cartslot )
420MACHINE_CONFIG_END
421
422static MACHINE_CONFIG_DERIVED( sms2_ntsc, sms_ntsc_base )
423   /* video hardware */
424   MCFG_SCREEN_ADD("screen", RASTER)
425   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
426   MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224)
427   MCFG_SCREEN_UPDATE(sms)
428
429   MCFG_PALETTE_LENGTH(64+16)
430   MCFG_PALETTE_INIT(sms)
431
432   MCFG_SMSVDP_ADD("sms_vdp", _315_5246_intf)
433MACHINE_CONFIG_END
434
435static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base )
436
437   MCFG_CPU_MODIFY("maincpu")
438   MCFG_CPU_PROGRAM_MAP(sms1_mem)   // This adds the SegaScope handlers for 3-D glasses
439   MCFG_CPU_IO_MAP(sms_io)
440
441   /* video hardware */
442   MCFG_SCREEN_ADD("screen", RASTER)
443   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
444   MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224)
445   MCFG_SCREEN_UPDATE(sms1)
446
447   MCFG_SCREEN_ADD("left_lcd", LCD)   // This is needed for SegaScope Left LCD
448   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
449   MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224)
450   MCFG_SCREEN_UPDATE(sms1)
451
452   MCFG_SCREEN_ADD("right_lcd", LCD)   // This is needed for SegaScope Right LCD
453   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
454   MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224)
455   MCFG_SCREEN_UPDATE(sms1)
456
457   MCFG_DEFAULT_LAYOUT(layout_sms1)
458
459   MCFG_PALETTE_LENGTH(64+16)
460   MCFG_PALETTE_INIT(sms)
461
462   MCFG_VIDEO_START(sms1)
463
464   MCFG_SMSVDP_ADD("sms_vdp", _315_5124_intf)
465MACHINE_CONFIG_END
466
467#define MCFG_SMSSDISP_CARTSLOT_ADD(_tag) \
468   MCFG_CARTSLOT_ADD(_tag) \
469   MCFG_CARTSLOT_EXTENSION_LIST("sms,bin") \
470   MCFG_CARTSLOT_NOT_MANDATORY \
471   MCFG_CARTSLOT_INTERFACE("sms_cart") \
472   MCFG_CARTSLOT_START(sms_cart) \
473   MCFG_CARTSLOT_LOAD(sms_cart)
474
475static MACHINE_CONFIG_DERIVED( sms_sdisp, sms2_ntsc )
476
477   MCFG_DEVICE_REMOVE("sms_vdp")
478   MCFG_SMSVDP_ADD("sms_vdp", sms_store_intf)
479
480   MCFG_CPU_ADD("control", Z80, XTAL_53_693175MHz/15)
481   MCFG_CPU_PROGRAM_MAP(sms_store_mem)
482   /* Both CPUs seem to communicate with the VDP etc? */
483   MCFG_CPU_IO_MAP(sms_io)
484
485   MCFG_CARTSLOT_MODIFY("cart1")
486   MCFG_CARTSLOT_EXTENSION_LIST("sms,bin")
487   MCFG_CARTSLOT_MANDATORY
488   MCFG_CARTSLOT_INTERFACE("sms_cart")
489   MCFG_CARTSLOT_START(sms_cart)
490   MCFG_CARTSLOT_LOAD(sms_cart)
491
492   MCFG_SMSSDISP_CARTSLOT_ADD("cart2")
493   MCFG_SMSSDISP_CARTSLOT_ADD("cart3")
494   MCFG_SMSSDISP_CARTSLOT_ADD("cart4")
495   MCFG_SMSSDISP_CARTSLOT_ADD("cart5")
496   MCFG_SMSSDISP_CARTSLOT_ADD("cart6")
497   MCFG_SMSSDISP_CARTSLOT_ADD("cart7")
498   MCFG_SMSSDISP_CARTSLOT_ADD("cart8")
499   MCFG_SMSSDISP_CARTSLOT_ADD("cart9")
500   MCFG_SMSSDISP_CARTSLOT_ADD("cart10")
501   MCFG_SMSSDISP_CARTSLOT_ADD("cart11")
502   MCFG_SMSSDISP_CARTSLOT_ADD("cart12")
503   MCFG_SMSSDISP_CARTSLOT_ADD("cart13")
504   MCFG_SMSSDISP_CARTSLOT_ADD("cart14")
505   MCFG_SMSSDISP_CARTSLOT_ADD("cart15")
506   MCFG_SMSSDISP_CARTSLOT_ADD("cart16")
507MACHINE_CONFIG_END
508
509static MACHINE_CONFIG_START( sms_pal_base, sms_state )
510   /* basic machine hardware */
511   MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK_PAL/15)
512   MCFG_CPU_PROGRAM_MAP(sms_mem)
513   MCFG_CPU_IO_MAP(sms_io)
514
515   MCFG_QUANTUM_TIME(attotime::from_hz(60))
516
517   MCFG_MACHINE_START(sms)
518   MCFG_MACHINE_RESET(sms)
519
520   /* sound hardware */
521   MCFG_SPEAKER_STANDARD_MONO("mono")
522   MCFG_SOUND_ADD("segapsg", SEGAPSG, MASTER_CLOCK_PAL/15)
523   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
524
525   MCFG_FRAGMENT_ADD( sms_cartslot )
526MACHINE_CONFIG_END
527
528static MACHINE_CONFIG_DERIVED( sms2_pal, sms_pal_base )
529
530   /* video hardware */
531   MCFG_SCREEN_ADD("screen", RASTER)
532   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
533   MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240)
534   MCFG_SCREEN_UPDATE(sms)
535
536   MCFG_PALETTE_LENGTH(64+16)
537   MCFG_PALETTE_INIT(sms)
538
539   MCFG_SMSVDP_ADD("sms_vdp", _315_5246_intf)
540MACHINE_CONFIG_END
541
542static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base )
543
544   MCFG_CPU_MODIFY("maincpu")
545   MCFG_CPU_PROGRAM_MAP(sms1_mem)   // This adds the SegaScope handlers for 3-D glasses
546   MCFG_CPU_IO_MAP(sms_io)
547
548   /* video hardware */
549   MCFG_SCREEN_ADD("screen", RASTER)
550   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
551   MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240)
552   MCFG_SCREEN_UPDATE(sms1)
553
554   MCFG_SCREEN_ADD("left_lcd", LCD)   // This is needed for SegaScope Left LCD
555   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
556   MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240)
557   MCFG_SCREEN_UPDATE(sms1)
558
559   MCFG_SCREEN_ADD("right_lcd", LCD)   // This is needed for SegaScope Right LCD
560   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
561   MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240)
562   MCFG_SCREEN_UPDATE(sms1)
563
564   MCFG_PALETTE_LENGTH(64+16)
565   MCFG_PALETTE_INIT(sms)
566
567   MCFG_DEFAULT_LAYOUT(layout_sms1)
568
569   MCFG_SMSVDP_ADD("sms_vdp", _315_5124_intf)
570MACHINE_CONFIG_END
571
572static MACHINE_CONFIG_DERIVED( sms_fm, sms1_ntsc )
573
574   MCFG_SOUND_ADD("ym2413", YM2413, XTAL_53_693175MHz/15)
575   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
576MACHINE_CONFIG_END
577
578static MACHINE_CONFIG_DERIVED( sg1000m3, sms_fm )
579
580   MCFG_CARTSLOT_MODIFY("cart1")
581   MCFG_CARTSLOT_EXTENSION_LIST("sms,bin,sg")
582   MCFG_CARTSLOT_MANDATORY
583   MCFG_CARTSLOT_START(sms_cart)
584   MCFG_CARTSLOT_LOAD(sms_cart)
585MACHINE_CONFIG_END
586
587static MACHINE_CONFIG_DERIVED( sms2_fm, sms2_ntsc )
588
589   MCFG_SOUND_ADD("ym2413", YM2413, XTAL_53_693175MHz/15)
590   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
591MACHINE_CONFIG_END
592
593static MACHINE_CONFIG_START( gamegear, sms_state )
594   /* basic machine hardware */
595   MCFG_CPU_ADD("maincpu", Z80, XTAL_53_693175MHz/15)
596   MCFG_CPU_PROGRAM_MAP(sms_mem)
597   MCFG_CPU_IO_MAP(gg_io)
598
599   MCFG_QUANTUM_TIME(attotime::from_hz(60))
600
601   MCFG_MACHINE_START(sms)
602   MCFG_MACHINE_RESET(sms)
603
604   /* video hardware */
605   MCFG_SCREEN_ADD("screen", LCD)
606   MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
607   MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS + 6*8, LBORDER_START + LBORDER_X_PIXELS + 26*8, NTSC_Y_PIXELS, TBORDER_START + NTSC_192_TBORDER_Y_PIXELS + 3*8, TBORDER_START + NTSC_192_TBORDER_Y_PIXELS + 21*8 )
608   MCFG_SCREEN_UPDATE(gamegear)
609
610   MCFG_PALETTE_LENGTH(4096)
611   MCFG_PALETTE_INIT(gamegear)
612
613   MCFG_VIDEO_START(gamegear)
614
615   MCFG_SMSVDP_ADD("sms_vdp", _315_5378_intf)
616
617   /* sound hardware */
618   MCFG_SPEAKER_STANDARD_STEREO("lspeaker","rspeaker")
619   MCFG_SOUND_ADD("gamegear", GAMEGEAR, XTAL_53_693175MHz/15)
620   MCFG_SOUND_ROUTE(0, "lspeaker", 1.00)
621   MCFG_SOUND_ROUTE(1, "rspeaker", 1.00)
622
623   /* cartridge */
624   MCFG_FRAGMENT_ADD( gg_cartslot )
625MACHINE_CONFIG_END
626
627
628ROM_START(sms1)
629   ROM_REGION(0x4000, "maincpu", 0)
630   ROM_FILL(0x0000, 0x4000, 0xff)
631
632   ROM_REGION(0x20000, "user1", 0)
633   ROM_SYSTEM_BIOS( 0, "bios13", "US/European BIOS v1.3 (1986)" )
634   ROMX_LOAD("bios13fx.rom", 0x0000, 0x2000, CRC(0072ED54) SHA1(c315672807d8ddb8d91443729405c766dd95cae7), ROM_BIOS(1))
635   ROM_SYSTEM_BIOS( 1, "hangonsh", "US/European BIOS v2.4 with Hang On and Safari Hunt (1988)" )
636   ROMX_LOAD("mpr-11459a.rom", 0x0000, 0x20000, CRC(91E93385) SHA1(9e179392cd416af14024d8f31c981d9ee9a64517), ROM_BIOS(2))
637   ROM_SYSTEM_BIOS( 2, "hangon", "US/European BIOS v3.4 with Hang On (1988)" )
638   ROMX_LOAD("mpr-11458.rom", 0x0000, 0x20000, CRC(8EDF7AC6) SHA1(51fd6d7990f62cd9d18c9ecfc62ed7936169107e), ROM_BIOS(3))
639   ROM_SYSTEM_BIOS( 3, "missiled", "US/European BIOS v4.4 with Missile Defense 3D (1988)" )
640   ROMX_LOAD("missiled.rom", 0x0000, 0x20000, CRC(E79BB689) SHA1(aa92ae576ca670b00855e278378d89e9f85e0351), ROM_BIOS(4))
641   ROM_SYSTEM_BIOS( 4, "proto", "US Master System Prototype BIOS" )
642   ROMX_LOAD("m404prot.rom", 0x0000, 0x2000, CRC(1a15dfcc) SHA1(4a06c8e66261611dce0305217c42138b71331701), ROM_BIOS(5))
643ROM_END
644
645ROM_START(sms)
646   ROM_REGION(0x4000, "maincpu", 0)
647   ROM_FILL(0x0000, 0x4000, 0xff)
648
649   ROM_REGION(0x20000, "user1", 0)
650   ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" )
651   ROMX_LOAD("mpr-12808.ic2", 0x0000, 0x20000, CRC(CF4A09EA) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) /* "SEGA // MPR-12808 W63 // 9114E9004" @ IC2 */
652ROM_END
653
654ROM_START(smssdisp)
655   ROM_REGION(0x4000, "maincpu", 0)
656   ROM_FILL(0x0000, 0x4000, 0x00)
657
658   ROM_REGION(0x4000, "user1", 0)
659   ROM_FILL(0x0000, 0x4000, 0xff)
660
661   ROM_REGION(0x4000, "control", 0)
662   ROM_LOAD("smssdisp.rom", 0x0000, 0x4000, CRC(ee2c29ba) SHA1(fc465122134d95363112eb51b9ab71db3576cefd))
663ROM_END
664
665ROM_START(sms1pal)
666   ROM_REGION(0x4000, "maincpu", 0)
667   ROM_FILL(0x0000, 0x4000, 0xff)
668
669   ROM_REGION(0x20000, "user1", 0)
670   ROM_SYSTEM_BIOS( 0, "bios13", "US/European BIOS v1.3 (1986)" )
671   ROMX_LOAD("bios13fx.rom", 0x0000, 0x2000, CRC(0072ED54) SHA1(c315672807d8ddb8d91443729405c766dd95cae7), ROM_BIOS(1))
672   ROM_SYSTEM_BIOS( 1, "hangonsh", "US/European BIOS v2.4 with Hang On and Safari Hunt (1988)" )
673   ROMX_LOAD("mpr-11459a.rom", 0x0000, 0x20000, CRC(91E93385) SHA1(9e179392cd416af14024d8f31c981d9ee9a64517), ROM_BIOS(2))
674   ROM_SYSTEM_BIOS( 2, "hangon", "Sega Master System - US/European BIOS v3.4 with Hang On (1988)" )
675   ROMX_LOAD("mpr-11458.rom", 0x0000, 0x20000, CRC(8EDF7AC6) SHA1(51fd6d7990f62cd9d18c9ecfc62ed7936169107e), ROM_BIOS(3))
676   ROM_SYSTEM_BIOS( 3, "missiled", "US/European BIOS v4.4 with Missile Defense 3D (1988)" )
677   ROMX_LOAD("missiled.rom", 0x0000, 0x20000, CRC(E79BB689) SHA1(aa92ae576ca670b00855e278378d89e9f85e0351), ROM_BIOS(4))
678ROM_END
679
680ROM_START(smspal)
681   ROM_REGION(0x4000, "maincpu", 0)
682   ROM_FILL(0x0000, 0x4000, 0xff)
683
684   ROM_REGION(0x40000, "user1", 0)
685   ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) /* PCB Label: SEGA // IC BD M4Jr. PAL" Master System II with 314-5246 (ZIP) VDP and 314-5237 (DIP48) IO */
686   ROMX_LOAD("mpr-12808.ic2", 0x0000, 0x20000, CRC(CF4A09EA) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) /* "SEGA // MPR-12808 W63 // 9114E9004" @ IC2 */
687   ROM_SYSTEM_BIOS( 1, "sonic", "European/Brazilian BIOS with Sonic the Hedgehog (1991)" )
688   ROMX_LOAD("sonbios.rom", 0x0000, 0x40000, CRC(81C3476B) SHA1(6aca0e3dffe461ba1cb11a86cd4caf5b97e1b8df), ROM_BIOS(2))
689ROM_END
690
691ROM_START(sg1000m3)
692   ROM_REGION(0x4000, "maincpu", 0)
693   ROM_FILL(0x0000, 0x4000, 0x00)
694ROM_END
695
696ROM_START(smsj) /* PCB Label: "SEGA(R) IC BOARD M4J MAIN // 837-6418"; has "YM2413 // 78 04 71 G" at IC10; Back of pcb has traces marked "171-5541 (C)SEGA 1987 MADE IN JAPAN"
697    see http://www.smspower.org/Development/JapaneseSMS837-6418 */
698   ROM_REGION(0x4000, "maincpu", 0)
699   ROM_FILL(0x0000, 0x4000, 0xff)
700
701   ROM_REGION(0x4000, "user1", 0)
702   ROM_SYSTEM_BIOS( 0, "jbios21", "Japanese BIOS v2.1 (1987)" )
703   ROMX_LOAD("mpr-11124.ic2", 0x0000, 0x2000, CRC(48D44A13) SHA1(a8c1b39a2e41137835eda6a5de6d46dd9fadbaf2), ROM_BIOS(1)) /* "SONY 7J06 // MPR-11124 // JAPAN 021" @ IC2 */
704ROM_END
705
706ROM_START(sms2kr)
707   ROM_REGION(0x4000, "maincpu", 0)
708   ROM_FILL(0x0000, 0x4000, 0xff)
709
710   ROM_REGION(0x20000, "user1", 0)
711   ROM_SYSTEM_BIOS( 0, "akbioskr", "Samsung Gam*Boy II with Alex Kidd in Miracle World (1990)" )
712   ROMX_LOAD("akbioskr.rom", 0x000, 0x20000, CRC(9c5bad91) SHA1(2feafd8f1c40fdf1bd5668f8c5c02e5560945b17), ROM_BIOS(1))
713ROM_END
714
715ROM_START(gamegear)
716   ROM_REGION(0x4000, "maincpu", 0)
717   ROM_FILL(0x0000, 0x4000, 0x00)
718
719   ROM_REGION(0x0400, "user1", 0)
720   ROM_SYSTEM_BIOS( 0, "none", "No BIOS" ) /* gamegear */
721   ROM_SYSTEM_BIOS( 1, "majesco", "Majesco BIOS" ) /* gamg */
722   ROMX_LOAD("majbios.rom", 0x0000, 0x0400, CRC(0EBEA9D4) SHA1(914aa165e3d879f060be77870d345b60cfeb4ede), ROM_BIOS(2))
723ROM_END
724
725#define rom_gamegeaj rom_gamegear
726
727/***************************************************************************
728
729  Game driver(s)
730
731  US
732   - Sega Master System I (sms1)
733     - prototype (M404) bios - 1986
734     - without built-in game v1.3 - 1986
735     - built-in Hang On/Safari Hunt v2.4 - 1988
736     - built-in Hang On v3.4 - 1988
737     - built-in Missile Defense 3-D v4.4 - 1988
738     - built-in Hang On/Astro Warrior ????
739   - Sega Master System II (sms)
740     - built-in Alex Kidd in Miracle World - 1990
741
742  JP
743   - Sega SG-1000 Mark III (sg1000m3)
744     - no bios
745   - Sega Master System (I) (smsj)
746     - without built-in game v2.1 - 1987
747
748  KR
749   - Sega Master System II (sms2kr)
750     - built-in Alex Kidd in Miracle World (Korean)
751
752  EU
753   - Sega Master System I (sms1pal)
754     - without built-in game v1.3 - 1986
755     - built-in Hang On/Safari Hunt v2.4 - 1988
756     - built-in Hang On v3.4 - 1988
757     - built-in Missile Defense 3-D v4.4 - 1988
758     - built-in Hang On/Astro Warrior ????
759   - Sega Master System II (smspal)
760     - built-in Alex Kidd in Miracle World - 1990
761     - built-in Sonic the Hedgehog - 1991
762
763  BR
764   - Sega Master System I - 1987
765   - Sega Master System II???
766   - Sega Master System III - Tec Toy, 1987
767   - Sega Master System Compact - Tec Toy, 1992
768   - Sega Master System Girl - Tec Toy, 1992
769
770***************************************************************************/
771
772/*    YEAR  NAME        PARENT      COMPAT  MACHINE      INPUT   INIT      COMPANY     FULLNAME                            FLAGS */
773CONS( 1984, sg1000m3,   sms,        0,      sg1000m3,    smsj,   sg1000m3, "Sega",     "SG-1000 Mark III",                 0 )
774CONS( 1986, sms1,       sms,        0,      sms1_ntsc,   sms1,   sms1,     "Sega",     "Master System I",                  0 )
775CONS( 1986, sms1pal,    sms,        0,      sms1_pal,    sms1,   sms1,     "Sega",     "Master System I (PAL)" ,           0 )
776CONS( 1986, smssdisp,   sms,        0,      sms_sdisp,   sms,    smssdisp, "Sega",     "Master System Store Display Unit", GAME_NOT_WORKING )
777CONS( 1987, smsj,       sms,        0,      sms_fm,      smsj,   smsj,     "Sega",     "Master System (Japan)",            0 )
778CONS( 1990, sms,        0,          0,      sms2_ntsc,   sms,    sms1,     "Sega",     "Master System II",                 0 )
779CONS( 1990, smspal,     sms,        0,      sms2_pal,    sms,    sms1,     "Sega",     "Master System II (PAL)",           0 )
780CONS( 1990, sms2kr,     sms,        0,      sms2_fm,     sms,    sms2kr,   "Samsung",  "Gam*Boy II (Korea)",               0 )
781
782CONS( 1990, gamegear,   0,          sms,    gamegear,    gg,     gamegear, "Sega",     "Game Gear (Europe/America)",       0 )
783CONS( 1990, gamegeaj,   gamegear,   0,      gamegear,    gg,     gamegeaj, "Sega",     "Game Gear (Japan)",                0 )
src/mess/drivers/sms.c
r12639r12640
6363#include "cpu/z80/z80.h"
6464#include "sound/sn76496.h"
6565#include "sound/2413intf.h"
66#include "includes/sms.h"
66#include "includes/segasms.h"
6767#include "video/smsvdp.h"
6868#include "imagedev/cartslot.h"
6969
r12639r12640
156156
157157static INPUT_PORTS_START( sms )
158158   PORT_START("PORT_DC")
159   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY
160   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY
161   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY
162   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY
163   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(10) PORT_PLAYER(1)
164   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(10) PORT_PLAYER(1)
165   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY
166   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY
159   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
160   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
161   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
162   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
163   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
164   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x00)
165   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
166   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
167167
168168   PORT_START("PORT_DD")
169   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY
170   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY
171   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(20) PORT_PLAYER(2)
172   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(20) PORT_PLAYER(2)
169   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
170   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
171   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
172   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x00)
173173   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) /* Software Reset bit */
174174   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
175175   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port A TH */
r12639r12640
180180   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START ) PORT_NAME(DEF_STR(Pause))
181181
182182   PORT_START("LPHASER0")   /* Light phaser X - player 1 */
183   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CATEGORY(11) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL)
183   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x01)
184184
185185   PORT_START("LPHASER1")   /* Light phaser Y - player 1 */
186   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CATEGORY(11) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL)
186   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x01)
187187
188188   PORT_START("LPHASER2")   /* Light phaser X - player 2 */
189   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CATEGORY(21) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL)
189   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x10)
190190
191191   PORT_START("LPHASER3")   /* Light phaser Y - player 2 */
192   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(25) PORT_CATEGORY(21) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL)
192   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(25) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x10)
193193
194194   PORT_START("RFU")   /* Rapid Fire Unit */
195195   PORT_CONFNAME( 0x03, 0x00, "Rapid Fire Unit - Player 1" )
r12639r12640
204204   PORT_CONFSETTING(   0x0c, "Button A + B" )
205205
206206   PORT_START("PADDLE0")   /* Paddle player 1 */
207   PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_CATEGORY(12) PORT_PLAYER(1)
207   PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x02)
208208
209209   PORT_START("PADDLE1")   /* Paddle player 2 */
210   PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_CATEGORY(22) PORT_PLAYER(2)
210   PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x20)
211211
212212   PORT_START("CTRLIPT")   /* Light Phaser and Paddle Control buttons */
213   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(11) PORT_PLAYER(1)
214   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(12) PORT_PLAYER(1)
215   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(13) PORT_PLAYER(1)
216   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(13) PORT_PLAYER(1)
217   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(21) PORT_PLAYER(2)
218   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(22) PORT_PLAYER(2)
219   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(23) PORT_PLAYER(2)
220   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(23) PORT_PLAYER(2)
213   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x01)
214   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x02)
215   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
216   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
217   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x10)
218   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x20)
219   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
220   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
221221
222222   PORT_START("CTRLSEL")   /* Controller selection */
223   PORT_CATEGORY_CLASS( 0x0f, 0x00, "Player 1 Controller" )
224   PORT_CATEGORY_ITEM( 0x00, DEF_STR( Joystick ), 10 )
225   PORT_CATEGORY_ITEM( 0x01, "Light Phaser", 11 )
226   PORT_CATEGORY_ITEM( 0x02, "Sega Paddle Control", 12 )
227   PORT_CATEGORY_ITEM( 0x03, "Sega Sports Pad", 13 )
228   PORT_CATEGORY_CLASS( 0xf0, 0x00, "Player 2 Controller" )
229   PORT_CATEGORY_ITEM( 0x00, DEF_STR( Joystick ), 20 )
230   PORT_CATEGORY_ITEM( 0x10, "Light Phaser", 21 )
231   PORT_CATEGORY_ITEM( 0x20, "Sega Paddle Control", 22 )
232   PORT_CATEGORY_ITEM( 0x30, "Sega Sports Pad", 23 )
223   PORT_CONFNAME( 0x0f, 0x00, "Player 1 Controller" )
224   PORT_CONFSETTING( 0x00, DEF_STR( Joystick ) )
225   PORT_CONFSETTING( 0x01, "Light Phaser" )
226   PORT_CONFSETTING( 0x02, "Sega Paddle Control" )
227   PORT_CONFSETTING( 0x04, "Sega Sports Pad" )
228   PORT_CONFNAME( 0xf0, 0x00, "Player 2 Controller" )
229   PORT_CONFSETTING( 0x00, DEF_STR( Joystick ) )
230   PORT_CONFSETTING( 0x10, "Light Phaser" )
231   PORT_CONFSETTING( 0x20, "Sega Paddle Control" )
232   PORT_CONFSETTING( 0x40, "Sega Sports Pad" )
233233
234234   PORT_START("SPORT0")   /* Player 1 Sports Pad X axis */
235   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(13) PORT_PLAYER(1)
235   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
236236
237237   PORT_START("SPORT1")   /* Player 1 Sports Pad Y axis */
238   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(13) PORT_PLAYER(1)
238   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, PORTCOND_EQUALS, 0x04)
239239
240240   PORT_START("SPORT2")   /* Player 2 Sports Pad X axis */
241   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(23) PORT_PLAYER(2)
241   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
242242
243243   PORT_START("SPORT3")   /* Player 2 Sports Pad Y axis */
244   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(23) PORT_PLAYER(2)
244   PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, PORTCOND_EQUALS, 0x40)
245245INPUT_PORTS_END
246246
247247static INPUT_PORTS_START( sms1 )
r12639r12640
274274
275275   PORT_START("TVDRAW_X")
276276   PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Tablet - X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
277      PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
277   PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
278278
279279   PORT_START("TVDRAW_Y")
280280   PORT_BIT( 0xff, 0x60, IPT_LIGHTGUN_Y ) PORT_NAME("Tablet - Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0, 191) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
281      PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
281   PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)
282282
283283   PORT_START("TVDRAW_PEN")
284284   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Tablet - Pen") PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team