~ubuntu-branches/ubuntu/raring/mame/raring-proposed

« back to all changes in this revision

Viewing changes to mess/src/mame/machine/segamsys.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    SMS code from HazeMD
3
 
     - used by Syetem E
4
 
     - Megatech / Megaplay
5
 
 
6
 
    this contains common code to support those systems
7
 
 
8
 
    (not currently very good / accurate, should be rewritten)
9
 
 
10
 
*/
11
 
 
12
 
#include "emu.h"
13
 
#include "cpu/z80/z80.h"
14
 
#include "sound/sn76496.h"
15
 
#include "machine/mc8123.h"
16
 
#include "machine/segacrpt.h"
17
 
#include "includes/segamsys.h"
18
 
 
19
 
 
20
 
//static UINT8* sms_rom;
21
 
UINT8* sms_mainram;
22
 
UINT8* smsgg_backupram = 0;
23
 
static TIMER_CALLBACK( sms_scanline_timer_callback );
24
 
static struct sms_vdp *vdp2;
25
 
static struct sms_vdp *vdp1;
26
 
 
27
 
static struct sms_vdp *md_sms_vdp;
28
 
 
29
 
/* All Accesses to VRAM go through here for safety */
30
 
#define SMS_VDP_VRAM(address) chip->vram[(address)&0x3fff]
31
 
 
32
 
#ifdef UNUSED_FUNCTION
33
 
static ADDRESS_MAP_START( sms_map, AS_PROGRAM, 8 )
34
 
//  AM_RANGE(0x0000 , 0xbfff) AM_ROM
35
 
//  AM_RANGE(0xc000 , 0xdfff) AM_RAM AM_MIRROR(0x2000)
36
 
ADDRESS_MAP_END
37
 
#endif
38
 
 
39
 
 
40
 
ADDRESS_MAP_START( sms_io_map, AS_IO, 8 )
41
 
        ADDRESS_MAP_GLOBAL_MASK(0xff)
42
 
ADDRESS_MAP_END
43
 
 
44
 
static INPUT_PORTS_START( sms_common )
45
 
        PORT_START("PAD1")              /* Joypad 1 (2 button) NOT READ DIRECTLY */
46
 
        PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
47
 
        PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
48
 
        PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
49
 
        PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
50
 
        PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 B") // a
51
 
        PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 C") // b
52
 
        PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )
53
 
        PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
54
 
 
55
 
        PORT_START("PAD2")              /* Joypad 2 (2 button) NOT READ DIRECTLY */
56
 
        PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
57
 
        PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
58
 
        PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
59
 
        PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
60
 
        PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 B") // a
61
 
        PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 C") // b
62
 
        PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )
63
 
        PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
64
 
INPUT_PORTS_END
65
 
 
66
 
INPUT_PORTS_START( sms )
67
 
        PORT_INCLUDE( sms_common )
68
 
 
69
 
        PORT_START("PAUSE")             /* Buttons on SMS Console */
70
 
        PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Pause Button") PORT_IMPULSE(1)
71
 
INPUT_PORTS_END
72
 
 
73
 
INPUT_PORTS_START( gamegear )
74
 
        PORT_INCLUDE( sms_common )
75
 
 
76
 
        PORT_START("GGSTART")           /* Extra GameGear button */
77
 
        PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Start Button")
78
 
INPUT_PORTS_END
79
 
 
80
 
/* Precalculated tables for H/V counters.  Note the position the counter 'jumps' is marked with with
81
 
   an empty comment */
82
 
static const UINT8 hc_256[] =
83
 
{
84
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,    0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
85
 
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,    0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
86
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,    0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
87
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,    0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
88
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,    0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
89
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,    0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
90
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,    0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
91
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,    0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
92
 
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,    0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
93
 
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,    0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
94
 
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,    0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
95
 
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,    0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
96
 
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,    0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
97
 
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,    0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
98
 
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,/**/0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
99
 
    0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3,    0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
100
 
    0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,    0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
101
 
    0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,    0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
102
 
    0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,    0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
103
 
    0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,    0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
104
 
    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,    0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
105
 
    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
106
 
};
107
 
 
108
 
 
109
 
static const UINT8 vc_ntsc_192[] =
110
 
{
111
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,    0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
112
 
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,    0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
113
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,    0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
114
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,    0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
115
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,    0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
116
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,    0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
117
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,    0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
118
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,    0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
119
 
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,    0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
120
 
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,    0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
121
 
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,    0xab, 0xac, 0xad, 0xae, 0xaf,
122
 
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,    0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
123
 
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,    0xcb, 0xcc, 0xcd, 0xce, 0xcf,
124
 
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,/**/0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
125
 
    0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4,    0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
126
 
    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,    0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
127
 
    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
128
 
};
129
 
 
130
 
static const UINT8 vc_ntsc_224[] =
131
 
{
132
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,    0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
133
 
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,    0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
134
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,    0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
135
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,    0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
136
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,    0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
137
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,    0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
138
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,    0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
139
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,    0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
140
 
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,    0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
141
 
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,    0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
142
 
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,    0xab, 0xac, 0xad, 0xae, 0xaf,
143
 
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,    0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
144
 
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,    0xcb, 0xcc, 0xcd, 0xce, 0xcf,
145
 
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,    0xdb, 0xdc, 0xdd, 0xde, 0xdf,
146
 
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,/**/0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
147
 
    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,    0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
148
 
    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
149
 
};
150
 
 
151
 
static const UINT8 vc_ntsc_240[] =
152
 
{
153
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
154
 
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
155
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
156
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
157
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
158
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
159
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
160
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
161
 
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
162
 
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
163
 
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
164
 
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
165
 
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
166
 
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
167
 
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
168
 
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
169
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05
170
 
};
171
 
 
172
 
 
173
 
 
174
 
static const UINT8 vc_pal_192[] =
175
 
{
176
 
    0x00, 0x01, 0x02,    0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
177
 
    0x10, 0x11, 0x12,    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
178
 
    0x20, 0x21, 0x22,    0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
179
 
    0x30, 0x31, 0x32,    0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
180
 
    0x40, 0x41, 0x42,    0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
181
 
    0x50, 0x51, 0x52,    0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
182
 
    0x60, 0x61, 0x62,    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
183
 
    0x70, 0x71, 0x72,    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
184
 
    0x80, 0x81, 0x82,    0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
185
 
    0x90, 0x91, 0x92,    0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
186
 
    0xa0, 0xa1, 0xa2,    0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
187
 
    0xb0, 0xb1, 0xb2,    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
188
 
    0xc0, 0xc1, 0xc2,    0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
189
 
    0xd0, 0xd1, 0xd2,    0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
190
 
    0xe0, 0xe1, 0xe2,    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
191
 
    0xf0, 0xf1, 0xf2,/**/0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
192
 
    0xc7, 0xc8, 0xc9,    0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
193
 
    0xd7, 0xd8, 0xd9,    0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
194
 
    0xe7, 0xe8, 0xe9,    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
195
 
    0xf7, 0xf8, 0xf9,    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
196
 
};
197
 
 
198
 
 
199
 
static const UINT8 vc_pal_224[] =
200
 
{
201
 
    0x00, 0x01, 0x02,    0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
202
 
    0x10, 0x11, 0x12,    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
203
 
    0x20, 0x21, 0x22,    0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
204
 
    0x30, 0x31, 0x32,    0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
205
 
    0x40, 0x41, 0x42,    0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
206
 
    0x50, 0x51, 0x52,    0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
207
 
    0x60, 0x61, 0x62,    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
208
 
    0x70, 0x71, 0x72,    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
209
 
    0x80, 0x81, 0x82,    0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
210
 
    0x90, 0x91, 0x92,    0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
211
 
    0xa0, 0xa1, 0xa2,    0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
212
 
    0xb0, 0xb1, 0xb2,    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
213
 
    0xc0, 0xc1, 0xc2,    0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
214
 
    0xd0, 0xd1, 0xd2,    0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
215
 
    0xe0, 0xe1, 0xe2,    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
216
 
    0xf0, 0xf1, 0xf2,    0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
217
 
    0x00, 0x01, 0x02,/**/0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
218
 
    0xd7, 0xd8, 0xd9,    0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
219
 
    0xe7, 0xe8, 0xe9,    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
220
 
    0xf7, 0xf8, 0xf9,    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
221
 
};
222
 
 
223
 
static const UINT8 vc_pal_240[] =
224
 
{
225
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,    0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
226
 
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,    0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
227
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,    0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
228
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,    0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
229
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,    0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
230
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,    0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
231
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,    0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
232
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,    0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
233
 
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,    0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
234
 
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,    0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
235
 
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,    0xab, 0xac, 0xad, 0xae, 0xaf,
236
 
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,    0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
237
 
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,    0xcb, 0xcc, 0xcd, 0xce, 0xcf,
238
 
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,    0xdb, 0xdc, 0xdd, 0xde, 0xdf,
239
 
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,    0xeb, 0xec, 0xed, 0xee, 0xef,
240
 
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,    0xfb, 0xfc, 0xfd, 0xfe, 0xff,
241
 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,/**/0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
242
 
    0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1,    0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
243
 
    0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1,    0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
244
 
    0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
245
 
};
246
 
 
247
 
static const struct
248
 
{
249
 
        UINT8 sms2_name[40];
250
 
        int sms2_valid;
251
 
        int sms2_height;
252
 
        int sms2_tilemap_height;
253
 
        const UINT8* sms_vcounter_table;
254
 
        const UINT8* sms_hcounter_table;
255
 
 
256
 
} sms_mode_table[] =
257
 
{
258
 
        /* NTSC Modes */
259
 
        { "Graphic 1 (NTSC)",         0, 192, 224, vc_ntsc_192, hc_256 },
260
 
        { "Text (NTSC)",              0, 192, 224, vc_ntsc_192, hc_256 },
261
 
        { "Graphic 2 (NTSC)",         0, 192, 224, vc_ntsc_192, hc_256 },
262
 
        { "Mode 1+2 (NTSC)" ,         0, 192, 224, vc_ntsc_192, hc_256 },
263
 
        { "Multicolor (NTSC)",        0, 192, 224, vc_ntsc_192, hc_256 },
264
 
        { "Mode 1+3 (NTSC)",          0, 192, 224, vc_ntsc_192, hc_256 },
265
 
        { "Mode 2+3 (NTSC)",          0, 192, 224, vc_ntsc_192, hc_256 },
266
 
        { "Mode 1+2+3 (NTSC)",        0, 192, 224, vc_ntsc_192, hc_256 },
267
 
        { "Mode 4 (NTSC)",            1, 192, 224, vc_ntsc_192, hc_256 },
268
 
        { "Invalid Text (NTSC)",      0, 192, 224, vc_ntsc_192, hc_256 },
269
 
        { "Mode 4 (NTSC)",            1, 192, 224, vc_ntsc_192, hc_256 },
270
 
        { "Mode 4 (224-line) (NTSC)", 1, 224, 256, vc_ntsc_224, hc_256 },
271
 
        { "Mode 4 (NTSC)",            1, 192, 224, vc_ntsc_192, hc_256 },
272
 
        { "Invalid Text (NTSC)",      0, 192, 224, vc_ntsc_192, hc_256 },
273
 
        { "Mode 4 (240-line) (NTSC)", 1, 240, 256, vc_ntsc_240, hc_256 },
274
 
        { "Mode 4 (NTSC)",            1, 192, 244, vc_ntsc_192, hc_256 },
275
 
 
276
 
        /* Pal Modes (different Vcounter) */
277
 
        { "Graphic 1 (PAL)",         0, 192, 224, vc_pal_192, hc_256 },
278
 
        { "Text (PAL)",              0, 192, 224, vc_pal_192, hc_256 },
279
 
        { "Graphic 2 (PAL)",         0, 192, 224, vc_pal_192, hc_256 },
280
 
        { "Mode 1+2 (PAL)" ,         0, 192, 224, vc_pal_192, hc_256 },
281
 
        { "Multicolor (PAL)",        0, 192, 224, vc_pal_192, hc_256 },
282
 
        { "Mode 1+3 (PAL)",          0, 192, 224, vc_pal_192, hc_256 },
283
 
        { "Mode 2+3 (PAL)",          0, 192, 224, vc_pal_192, hc_256 },
284
 
        { "Mode 1+2+3 (PAL)",        0, 192, 224, vc_pal_192, hc_256 },
285
 
        { "Mode 4 (PAL)",            1, 192, 224, vc_pal_192, hc_256 },
286
 
        { "Invalid Text (PAL)",      0, 192, 224, vc_pal_192, hc_256 },
287
 
        { "Mode 4 (PAL)",            1, 192, 224, vc_pal_192, hc_256 },
288
 
        { "Mode 4 (224-line) (PAL)", 1, 224, 256, vc_pal_224, hc_256 },
289
 
        { "Mode 4 (PAL)",            1, 192, 224, vc_pal_192, hc_256 },
290
 
        { "Invalid Text (PAL)",      0, 192, 224, vc_pal_192, hc_256 },
291
 
        { "Mode 4 (240-line) (PAL)", 1, 240, 256, vc_pal_240, hc_256 },
292
 
        { "Mode 4 (PAL)",            1, 192, 244, vc_pal_192, hc_256 }
293
 
};
294
 
 
295
 
enum
296
 
{
297
 
        SMS_VDP = 0,  // SMS1 VDP
298
 
        SMS2_VDP = 1, // SMS2 VDP, or Game Gear VDP running in SMS2 Mode
299
 
        GG_VDP = 2,   // Game Gear VDP running in Game Gear Mode
300
 
        GEN_VDP = 3   // Genesis VDP running in SMS2 Mode
301
 
};
302
 
 
303
 
static int sms_vdp_null_irq_callback(running_machine &machine, int status)
304
 
{
305
 
        return -1;
306
 
}
307
 
 
308
 
static int sms_vdp_cpu0_irq_callback(running_machine &machine, int status)
309
 
{
310
 
        if (status == 1)
311
 
                cputag_set_input_line(machine, "maincpu", 0, HOLD_LINE);
312
 
        else
313
 
                cputag_set_input_line(machine, "maincpu", 0, CLEAR_LINE);
314
 
 
315
 
        return 0;
316
 
}
317
 
 
318
 
static int sms_vdp_cpu1_irq_callback(running_machine &machine, int status)
319
 
{
320
 
        if (status == 1)
321
 
                cputag_set_input_line(machine, "genesis_snd_z80", 0, HOLD_LINE);
322
 
        else
323
 
                cputag_set_input_line(machine, "genesis_snd_z80", 0, CLEAR_LINE);
324
 
 
325
 
        return 0;
326
 
}
327
 
 
328
 
 
329
 
static int sms_vdp_cpu2_irq_callback(running_machine &machine, int status)
330
 
{
331
 
        if (status == 1)
332
 
                cputag_set_input_line(machine, "mtbios", 0, HOLD_LINE);
333
 
        else
334
 
                cputag_set_input_line(machine, "mtbios", 0, CLEAR_LINE);
335
 
 
336
 
        return 0;
337
 
}
338
 
 
339
 
 
340
 
 
341
 
 
342
 
struct sms_vdp
343
 
{
344
 
        UINT8 chip_id;
345
 
 
346
 
        UINT8  cmd_pend;
347
 
        UINT8  cmd_part1;
348
 
        UINT8  cmd_part2;
349
 
        UINT16 addr_reg;
350
 
        UINT8  cmd_reg;
351
 
        UINT8  regs[0x10];
352
 
        UINT8  readbuf;
353
 
        UINT8* vram;
354
 
        UINT8* cram;
355
 
        UINT8  writemode;
356
 
        bitmap_t* r_bitmap;
357
 
        UINT8* tile_renderline;
358
 
        UINT8* sprite_renderline;
359
 
 
360
 
        UINT8 sprite_collision;
361
 
        UINT8 sprite_overflow;
362
 
 
363
 
        UINT8  yscroll;
364
 
        UINT8  hint_counter;
365
 
 
366
 
        UINT8 frame_irq_pending;
367
 
        UINT8 line_irq_pending;
368
 
 
369
 
        UINT8 vdp_type;
370
 
 
371
 
        UINT8 gg_cram_latch; // gamegear specific.
372
 
 
373
 
        /* below are MAME specific, to make things easier */
374
 
        UINT8 screen_mode;
375
 
        UINT8 is_pal;
376
 
        int sms_scanline_counter;
377
 
        int sms_total_scanlines;
378
 
        int sms_framerate;
379
 
        emu_timer* sms_scanline_timer;
380
 
        UINT16* cram_mamecolours; // for use on RGB_DIRECT screen
381
 
        int      (*set_irq)(running_machine &machine, int state);
382
 
 
383
 
};
384
 
 
385
 
 
386
 
 
387
 
static void *start_vdp(running_machine &machine, int type)
388
 
{
389
 
        struct sms_vdp *chip;
390
 
 
391
 
        chip = auto_alloc_clear(machine, struct sms_vdp);
392
 
 
393
 
        chip->vdp_type = type;
394
 
 
395
 
        chip->set_irq = sms_vdp_null_irq_callback;
396
 
 
397
 
        chip->cmd_pend = 0;
398
 
        chip->cmd_part1 = 0;
399
 
        chip->cmd_part2 = 0;
400
 
        chip->addr_reg = 0;
401
 
        chip->cmd_reg = 0;
402
 
 
403
 
        chip->regs[0x0] = 0x06; // mode 4
404
 
        chip->regs[0x1] = 0x18; // mode 4
405
 
        chip->regs[0x2] = 0;
406
 
        chip->regs[0x3] = 0;
407
 
        chip->regs[0x4] = 0;
408
 
        chip->regs[0x5] = 0;
409
 
        chip->regs[0x6] = 0;
410
 
        chip->regs[0x7] = 0;
411
 
        chip->regs[0x8] = 0;
412
 
        chip->regs[0x9] = 0;
413
 
        chip->regs[0xa] = 0;
414
 
        /* b-f don't matter */
415
 
        chip->readbuf = 0;
416
 
        chip->vram = auto_alloc_array_clear(machine, UINT8, 0x4000);
417
 
 
418
 
        //printf("%d\n", (*chip->set_irq)(machine, 200));
419
 
 
420
 
        if (chip->vdp_type==GG_VDP)
421
 
        {
422
 
                chip->cram = auto_alloc_array_clear(machine, UINT8, 0x0040);
423
 
                chip->cram_mamecolours = auto_alloc_array_clear(machine, UINT16, 0x0080/2);
424
 
                chip->gg_cram_latch = 0;
425
 
        }
426
 
        else
427
 
        {
428
 
                chip->cram = auto_alloc_array_clear(machine, UINT8, 0x0020);
429
 
                chip->cram_mamecolours = auto_alloc_array(machine, UINT16, 0x0040/2);
430
 
        }
431
 
 
432
 
        chip->tile_renderline = auto_alloc_array(machine, UINT8, 256+8);
433
 
        memset(chip->tile_renderline,0x00,256+8);
434
 
 
435
 
        chip->sprite_renderline = auto_alloc_array(machine, UINT8, 256+32);
436
 
        memset(chip->sprite_renderline,0x00,256+32);
437
 
 
438
 
        chip->writemode = 0;
439
 
        chip->r_bitmap = auto_bitmap_alloc(machine, 256, 256, BITMAP_FORMAT_RGB15);
440
 
 
441
 
        chip->sms_scanline_timer = machine.scheduler().timer_alloc(FUNC(sms_scanline_timer_callback), chip);
442
 
 
443
 
        return chip;
444
 
}
445
 
 
446
 
/* stop timer and clear ram.. used on megatech when we switch between genesis and sms mode */
447
 
void segae_md_sms_stop_scanline_timer(void)
448
 
{
449
 
        md_sms_vdp->sms_scanline_timer->adjust(attotime::never);
450
 
        memset(md_sms_vdp->vram,0x00,0x4000);
451
 
}
452
 
 
453
 
 
454
 
#ifdef UNUSED_FUNCTION
455
 
static READ8_HANDLER( z80_unmapped_r )
456
 
{
457
 
        printf("unmapped z80 read %04x\n",offset);
458
 
        return 0;
459
 
}
460
 
 
461
 
static WRITE8_HANDLER( z80_unmapped_w )
462
 
{
463
 
        printf("unmapped z80 write %04x\n",offset);
464
 
}
465
 
#endif
466
 
 
467
 
static UINT8 vcounter_r(struct sms_vdp *chip)
468
 
{
469
 
//  return vc_pal_224[sms_scanline_counter%(sizeof vc_pal_224)];
470
 
        UINT8 retvalue;
471
 
        int scanline = chip->sms_scanline_counter%chip->sms_total_scanlines;
472
 
 
473
 
        retvalue = sms_mode_table[chip->screen_mode].sms_vcounter_table[scanline];
474
 
 
475
 
        return retvalue;
476
 
        //printf("retvalue %d\n";
477
 
}
478
 
 
479
 
 
480
 
static UINT8 vdp_data_r(struct sms_vdp *chip)
481
 
{
482
 
        UINT8 retdata = chip->readbuf;
483
 
        chip->readbuf = SMS_VDP_VRAM(chip->addr_reg);
484
 
        chip->addr_reg++; chip->addr_reg&=0x3fff;
485
 
        return retdata;
486
 
}
487
 
 
488
 
static void vdp_data_w(address_space *space, UINT8 data, struct sms_vdp* chip)
489
 
{
490
 
        /* data writes clear the pending flag */
491
 
        chip->cmd_pend = 0;
492
 
 
493
 
        if (chip->writemode==0)
494
 
        { /* Write to VRAM */
495
 
                SMS_VDP_VRAM(chip->addr_reg)=data;
496
 
                chip->addr_reg++; chip->addr_reg&=0x3fff;
497
 
                chip->readbuf = data; // quirk of the VDP
498
 
        }
499
 
        else if (chip->writemode==1)
500
 
        {
501
 
                if (chip->vdp_type==GG_VDP)
502
 
                {
503
 
                        if (!(chip->addr_reg&1))
504
 
                        { /* Even address, value latched */
505
 
                                chip->gg_cram_latch = data;
506
 
                        }
507
 
                        else
508
 
                        {
509
 
                                chip->cram[(chip->addr_reg&0x3e)+1]=data;
510
 
                                chip->cram[(chip->addr_reg&0x3e)+0]=chip->gg_cram_latch;
511
 
 
512
 
                                /* Set Colour */
513
 
                                {
514
 
                                        UINT16 palword;
515
 
                                        UINT8 r,g,b;
516
 
 
517
 
                                        palword = ((chip->cram[(chip->addr_reg&0x3e)+1])<<8)|(chip->cram[(chip->addr_reg&0x3e)+0]);
518
 
 
519
 
                                        //printf("addr %04x palword %04x\n", chip->addr_reg&0x3f, palword);
520
 
 
521
 
                                        r = (palword & 0x000f)>>0;
522
 
                                        g = (palword & 0x00f0)>>4;
523
 
                                        b = (palword & 0x0f00)>>8;
524
 
                                        palette_set_color_rgb(space->machine(),(chip->addr_reg&0x3e)/2, pal4bit(r), pal4bit(g), pal4bit(b));
525
 
                                        chip->cram_mamecolours[(chip->addr_reg&0x3e)/2]=(b<<1)|(g<<6)|(r<<11);
526
 
                                }
527
 
                        }
528
 
                }
529
 
                else
530
 
                {
531
 
                        chip->cram[chip->addr_reg&0x1f]=data;
532
 
 
533
 
                        /* Set Colour */
534
 
                        {
535
 
                                UINT8 r,g,b;
536
 
                                r = (data & 0x03)>>0;
537
 
                                g = (data & 0x0c)>>2;
538
 
                                b = (data & 0x30)>>4;
539
 
                                palette_set_color_rgb(space->machine(),chip->addr_reg&0x1f, pal2bit(r), pal2bit(g), pal2bit(b));
540
 
                                chip->cram_mamecolours[chip->addr_reg&0x1f]=(b<<3)|(g<<8)|(r<<13);
541
 
                        }
542
 
 
543
 
                }
544
 
 
545
 
                chip->addr_reg++; chip->addr_reg&=0x3fff;
546
 
                chip->readbuf = data; // quirk of the VDP
547
 
 
548
 
        }
549
 
 
550
 
}
551
 
 
552
 
static UINT8 vdp_ctrl_r(address_space *space, struct sms_vdp *chip)
553
 
{
554
 
        UINT8 retvalue;
555
 
 
556
 
        retvalue = (chip->frame_irq_pending<<7) |
557
 
                       (chip->sprite_overflow<<6) |
558
 
                   (chip->sprite_collision<<5);
559
 
 
560
 
        chip->cmd_pend = 0;
561
 
        chip->frame_irq_pending = 0;
562
 
        chip->line_irq_pending = 0;
563
 
        chip->sprite_collision = 0;
564
 
        chip->sprite_overflow = 0;
565
 
 
566
 
        (chip->set_irq)(space->machine(), 0); // clear IRQ;
567
 
 
568
 
 
569
 
        return retvalue;
570
 
}
571
 
 
572
 
/* check me */
573
 
static void vdp_update_code_addr_regs(struct sms_vdp *chip)
574
 
{
575
 
        chip->addr_reg = ((chip->cmd_part2&0x3f)<<8) | chip->cmd_part1;
576
 
        chip->cmd_reg = (chip->cmd_part2&0xc0)>>6;
577
 
}
578
 
 
579
 
static void vdp_set_register(running_machine &machine, struct sms_vdp *chip)
580
 
{
581
 
        UINT8 reg = chip->cmd_part2&0x0f;
582
 
        chip->regs[reg] = chip->cmd_part1;
583
 
 
584
 
        //if(reg==0) printf("setting reg 0 to %02x\n",chip->cmd_part1);
585
 
 
586
 
        //if (reg>0xa) printf("Invalid register write to register %01x\n",reg);
587
 
 
588
 
        if(reg==1)
589
 
        {
590
 
                if ((chip->regs[0x1]&0x20) && chip->frame_irq_pending)
591
 
                {
592
 
                        (chip->set_irq)(machine, 1); // set IRQ;
593
 
                }
594
 
                else
595
 
                {
596
 
                        (chip->set_irq)(machine, 0); // clear IRQ;
597
 
                }
598
 
        }
599
 
 
600
 
        if(reg==0)
601
 
        {
602
 
                if ((chip->regs[0x0]&0x10) && chip->line_irq_pending)
603
 
                {
604
 
                        (chip->set_irq)(machine, 1); // set IRQ;
605
 
                }
606
 
                else
607
 
                {
608
 
                        (chip->set_irq)(machine, 0); // clear IRQ;
609
 
                }
610
 
        }
611
 
 
612
 
 
613
 
//  printf("VDP: setting register %01x to %02x\n",reg, chip->cmd_part1);
614
 
}
615
 
 
616
 
static void vdp_ctrl_w(address_space *space, UINT8 data, struct sms_vdp *chip)
617
 
{
618
 
        if (chip->cmd_pend)
619
 
        { /* Part 2 of a command word write */
620
 
                chip->cmd_pend = 0;
621
 
                chip->cmd_part2 = data;
622
 
                vdp_update_code_addr_regs(chip);
623
 
 
624
 
                switch (chip->cmd_reg)
625
 
                {
626
 
                        case 0x0: /* VRAM read mode */
627
 
                                chip->readbuf = SMS_VDP_VRAM(chip->addr_reg);
628
 
                                chip->addr_reg++; chip->addr_reg&=0x3fff;
629
 
                                chip->writemode = 0;
630
 
                                break;
631
 
 
632
 
                        case 0x1: /* VRAM write mode */
633
 
                                chip->writemode = 0;
634
 
                                break;
635
 
 
636
 
                        case 0x2: /* REG setting */
637
 
                                vdp_set_register(space->machine(), chip);
638
 
                                chip->writemode = 0;
639
 
                                break;
640
 
 
641
 
                        case 0x3: /* CRAM write mode */
642
 
                                chip->writemode = 1;
643
 
                                break;
644
 
                }
645
 
        }
646
 
        else
647
 
        { /* Part 1 of a command word write */
648
 
                chip->cmd_pend = 1;
649
 
                chip->cmd_part1 = data;
650
 
                vdp_update_code_addr_regs(chip);
651
 
        }
652
 
}
653
 
 
654
 
/* for the Genesis */
655
 
 
656
 
READ8_HANDLER( md_sms_vdp_vcounter_r )
657
 
{
658
 
        return vcounter_r(md_sms_vdp);
659
 
}
660
 
 
661
 
READ8_HANDLER( md_sms_vdp_data_r )
662
 
{
663
 
        return vdp_data_r(md_sms_vdp);
664
 
}
665
 
 
666
 
WRITE8_HANDLER( md_sms_vdp_data_w )
667
 
{
668
 
        vdp_data_w(space, data, md_sms_vdp);
669
 
}
670
 
 
671
 
READ8_HANDLER( md_sms_vdp_ctrl_r )
672
 
{
673
 
        return vdp_ctrl_r(space, md_sms_vdp);
674
 
}
675
 
 
676
 
WRITE8_HANDLER( md_sms_vdp_ctrl_w )
677
 
{
678
 
        vdp_ctrl_w(space, data, md_sms_vdp);
679
 
}
680
 
 
681
 
 
682
 
/* Read / Write Handlers - call other functions */
683
 
 
684
 
READ8_HANDLER( sms_vcounter_r )
685
 
{
686
 
        return vcounter_r(vdp1);
687
 
}
688
 
 
689
 
READ8_HANDLER( sms_vdp_data_r )
690
 
{
691
 
        return vdp_data_r(vdp1);
692
 
}
693
 
 
694
 
WRITE8_HANDLER( sms_vdp_data_w )
695
 
{
696
 
        vdp_data_w(space, data, vdp1);
697
 
}
698
 
 
699
 
READ8_HANDLER( sms_vdp_ctrl_r )
700
 
{
701
 
        return vdp_ctrl_r(space, vdp1);
702
 
}
703
 
 
704
 
WRITE8_HANDLER( sms_vdp_ctrl_w )
705
 
{
706
 
        vdp_ctrl_w(space, data, vdp1);
707
 
}
708
 
 
709
 
static void draw_tile_line(int drawxpos, int tileline, UINT16 tiledata, UINT8* linebuf, struct sms_vdp* chip)
710
 
{
711
 
        int xx;
712
 
        UINT32 gfxdata;
713
 
        UINT16 gfx_base = (tiledata & 0x01ff)<<5;
714
 
        UINT8  flipx = (tiledata & 0x0200)>>9;
715
 
        UINT8  flipy = (tiledata & 0x0400)>>10;
716
 
        UINT8  pal   = (tiledata & 0x0800)>>11;
717
 
        UINT8  pri   = (tiledata & 0x1000)>>12;
718
 
 
719
 
        if (flipy)
720
 
        {
721
 
                gfx_base+=(7-tileline)*4;
722
 
        }
723
 
        else
724
 
        {
725
 
                gfx_base+=tileline*4;
726
 
        }
727
 
 
728
 
        gfxdata = (SMS_VDP_VRAM(gfx_base)<<24)|(SMS_VDP_VRAM(gfx_base+1)<<16)|(SMS_VDP_VRAM(gfx_base+2)<<8)|(SMS_VDP_VRAM(gfx_base+3)<<0);
729
 
 
730
 
        for (xx=0;xx<8;xx++)
731
 
        {
732
 
                UINT8 pixel;
733
 
 
734
 
                if (flipx)
735
 
                {
736
 
                        pixel = (( (gfxdata>>(0+xx)  ) &0x00000001)<<3)|
737
 
                            (( (gfxdata>>(8+xx)  ) &0x00000001)<<2)|
738
 
                            (( (gfxdata>>(16+xx) ) &0x00000001)<<1)|
739
 
                            (( (gfxdata>>(24+xx) ) &0x00000001)<<0);
740
 
                }
741
 
                else
742
 
                {
743
 
                        pixel = (( (gfxdata>>(7-xx)  ) &0x00000001)<<3)|
744
 
                                (( (gfxdata>>(15-xx) ) &0x00000001)<<2)|
745
 
                                (( (gfxdata>>(23-xx) ) &0x00000001)<<1)|
746
 
                                (( (gfxdata>>(31-xx) ) &0x00000001)<<0);
747
 
                }
748
 
 
749
 
                pixel += pal*0x10;
750
 
 
751
 
                if (!pri) linebuf[drawxpos+xx] = pixel;
752
 
                else
753
 
                {
754
 
                        if (pixel&0xf)
755
 
                                linebuf[drawxpos+xx] = pixel|0x80;
756
 
                        else
757
 
                                linebuf[drawxpos+xx] = pixel;
758
 
 
759
 
                }
760
 
        }
761
 
}
762
 
 
763
 
static void sms_render_spriteline(int scanline, struct sms_vdp* chip)
764
 
{
765
 
        int spritenum;
766
 
        int height = 8;
767
 
        int width = 8;
768
 
        int max_sprites = 8;
769
 
        int visible_line = 0;
770
 
 
771
 
        UINT16 table_base = (chip->regs[0x5]&0x7e) << 7;
772
 
        UINT8 pattern_bit = (chip->regs[0x6]&0x04) >> 2; // high bit of the tile # (because spriteram can only contain an 8-bit tile #)
773
 
 
774
 
 
775
 
        memset(chip->sprite_renderline, 0, 256+32);
776
 
 
777
 
        for (spritenum = 0;spritenum<64;spritenum++)
778
 
        {
779
 
                int xpos,ypos,num;
780
 
                /*
781
 
        00: yyyyyyyyyyyyyyyy
782
 
        10: yyyyyyyyyyyyyyyy
783
 
        20: yyyyyyyyyyyyyyyy
784
 
        30: yyyyyyyyyyyyyyyy
785
 
        40: ????????????????
786
 
        50: ????????????????
787
 
        60: ????????????????
788
 
        70: ????????????????
789
 
        80: xnxnxnxnxnxnxnxn
790
 
        90: xnxnxnxnxnxnxnxn
791
 
        A0: xnxnxnxnxnxnxnxn
792
 
        B0: xnxnxnxnxnxnxnxn
793
 
        C0: xnxnxnxnxnxnxnxn
794
 
        D0: xnxnxnxnxnxnxnxn
795
 
        E0: xnxnxnxnxnxnxnxn
796
 
        F0: xnxnxnxnxnxnxnxn
797
 
        */
798
 
 
799
 
                ypos = SMS_VDP_VRAM(table_base+spritenum);
800
 
                xpos = SMS_VDP_VRAM(table_base+0x80+spritenum*2+0);
801
 
                num  = SMS_VDP_VRAM(table_base+0x80+spritenum*2+1)|(pattern_bit<<8);
802
 
 
803
 
                if (chip->regs[0x1]&0x2)
804
 
                {
805
 
                        num &=0x1fe;
806
 
                        height=16;
807
 
                }
808
 
                else height = 8;
809
 
 
810
 
 
811
 
                xpos+=16; // allow room either side for clipping (avoids xdrawpos of -8 if bit below is set)
812
 
 
813
 
                if (chip->regs[0x0]&0x08) xpos-=8;
814
 
 
815
 
                if ((sms_mode_table[chip->screen_mode].sms2_height)==192)
816
 
                {
817
 
                        if (ypos == 0xd0)
818
 
                                return;
819
 
                }
820
 
 
821
 
                ypos++;
822
 
 
823
 
                num <<= 5;
824
 
                //num+=((scanline-ypos)&0x7)*4;
825
 
 
826
 
                visible_line = 0;
827
 
 
828
 
                if (ypos<=scanline && ypos+height>scanline)
829
 
                {
830
 
                        visible_line = 1;
831
 
                        num+=((scanline-ypos)&(height-1))*4;
832
 
 
833
 
                }
834
 
                else if (ypos+height>0x100)
835
 
                {
836
 
                        if (scanline< ypos+height-0x100)
837
 
                        {
838
 
                                visible_line = 1;
839
 
                                num+=((scanline-ypos)&(height-1))*4;
840
 
 
841
 
                        }
842
 
                }
843
 
 
844
 
                if (visible_line)
845
 
                {
846
 
                        int xx;
847
 
                        UINT32 gfxdata;
848
 
 
849
 
                        gfxdata = (SMS_VDP_VRAM(num&0x3fff)<<24)|(SMS_VDP_VRAM((num+1)&0x3fff)<<16)|(SMS_VDP_VRAM((num+2)&0x3fff)<<8)|(SMS_VDP_VRAM((num+3)&0x3fff)<<0);
850
 
 
851
 
 
852
 
                        for (xx=0;xx<8;xx++)
853
 
                        {
854
 
                                UINT8 pixel = (( (gfxdata>>(0+xx)  ) &0x00000001)<<3)|
855
 
                                              (( (gfxdata>>(8+xx)  ) &0x00000001)<<2)|
856
 
                                              (( (gfxdata>>(16+xx) ) &0x00000001)<<1)|
857
 
                                              (( (gfxdata>>(24+xx) ) &0x00000001)<<0);
858
 
 
859
 
                                if (pixel)
860
 
                                {
861
 
                                        if (!chip->sprite_renderline[xpos+((width-1)-xx)])
862
 
                                        {
863
 
                                                chip->sprite_renderline[xpos+((width-1)-xx)] = pixel;
864
 
                                        }
865
 
                                        else
866
 
                                        {
867
 
                                                chip->sprite_collision = 1;
868
 
                                        }
869
 
                                }
870
 
                        }
871
 
 
872
 
                        max_sprites--;
873
 
 
874
 
                        if (max_sprites==0)
875
 
                        {
876
 
                                chip->sprite_overflow = 1;
877
 
                                return;
878
 
                        }
879
 
 
880
 
                }
881
 
        }
882
 
}
883
 
 
884
 
static void sms_render_tileline(int scanline, struct sms_vdp* chip)
885
 
{
886
 
        int column = 0;
887
 
        int count = 32;
888
 
        int drawxpos;
889
 
 
890
 
        UINT8 xscroll = chip->regs[0x8];
891
 
        UINT8 yscroll = chip->yscroll;
892
 
        UINT16 table_base = (chip->regs[0x2]&0x0e)<<10;
893
 
        UINT16 our_base;
894
 
        UINT8  our_line = (scanline+yscroll) & 0x7;
895
 
 
896
 
        /* In 224 and 240 line modes the table base is different */
897
 
        if ((sms_mode_table[chip->screen_mode].sms2_height)!=192)
898
 
        {
899
 
                table_base &=0x3700; table_base|=0x700;
900
 
        }
901
 
 
902
 
        if ((chip->regs[0x0]&0x40) && scanline < 16)
903
 
        {
904
 
                xscroll = 0;
905
 
        }
906
 
 
907
 
//  xscroll = 0;
908
 
 
909
 
//  table_base -= 0x0100;
910
 
 
911
 
        our_base = table_base+(((scanline+yscroll)%sms_mode_table[chip->screen_mode].sms2_tilemap_height)>>3)*64;// + (yscroll>>3)*32;
912
 
 
913
 
        our_base &=0x3fff;
914
 
 
915
 
        memset(chip->tile_renderline, (chip->regs[0x7]&0x0f)+0x10, 256+8);
916
 
 
917
 
        drawxpos = xscroll&0x7;
918
 
        column = 32-(xscroll>>3);
919
 
 
920
 
        do
921
 
        {
922
 
                UINT16 tiledata = (SMS_VDP_VRAM((our_base+(column&0x1f)*2+1)&0x3fff) << 8) |
923
 
                                  (SMS_VDP_VRAM((our_base+(column&0x1f)*2+0)&0x3fff) << 0);
924
 
 
925
 
//      UINT16 pattern = ((column+((scanline>>3)*32)) & 0x01ff)<<5;
926
 
 
927
 
                draw_tile_line(drawxpos, our_line, tiledata, chip->tile_renderline, chip);
928
 
 
929
 
                drawxpos+=8;
930
 
                column++;
931
 
                column&=0x1f;
932
 
                count--;
933
 
        } while (count);
934
 
 
935
 
}
936
 
 
937
 
static void sms_copy_to_renderbuffer(int scanline, struct sms_vdp* chip)
938
 
{
939
 
        int x;
940
 
        UINT16* lineptr = BITMAP_ADDR16(chip->r_bitmap, scanline, 0);
941
 
 
942
 
        for (x=0;x<256;x++)
943
 
        {
944
 
                UINT8 dat = chip->tile_renderline[x];
945
 
                UINT8 col;
946
 
 
947
 
 
948
 
                col = (chip->regs[0x7]&0x0f)+0x10;
949
 
                lineptr[x] = chip->cram_mamecolours[col];
950
 
 
951
 
 
952
 
                if ((x<8 && (chip->regs[0x0]&0x20)) || !(chip->regs[0x1]&0x40))
953
 
                        continue;
954
 
 
955
 
 
956
 
                if (!(dat & 0x80))
957
 
                {
958
 
                        lineptr[x] = chip->cram_mamecolours[dat&0x1f];
959
 
                        if ((dat&0xf)==0x0) lineptr[x]|=0x8000;
960
 
 
961
 
                }
962
 
 
963
 
                if (chip->sprite_renderline[x+16])
964
 
                {
965
 
                        lineptr[x] =  chip->cram_mamecolours[chip->sprite_renderline[x+16]+0x10];
966
 
                }
967
 
 
968
 
                if (dat & 0x80)
969
 
                {
970
 
                        lineptr[x] = chip->cram_mamecolours[dat&0x1f];
971
 
                        if ((dat&0xf)==0x0) lineptr[x]|=0x8000;
972
 
                }
973
 
 
974
 
        }
975
 
 
976
 
}
977
 
 
978
 
static void sms_draw_scanline(int scanline, struct sms_vdp* chip)
979
 
{
980
 
 
981
 
        if (scanline>=0 && scanline<sms_mode_table[chip->screen_mode].sms2_height)
982
 
        {
983
 
                sms_render_spriteline(scanline, chip);
984
 
                sms_render_tileline(scanline, chip);
985
 
                sms_copy_to_renderbuffer(scanline, chip);
986
 
 
987
 
        }
988
 
}
989
 
 
990
 
 
991
 
static TIMER_CALLBACK( sms_scanline_timer_callback )
992
 
{
993
 
        /* This function is called at the very start of every scanline starting at the very
994
 
       top-left of the screen.  The first scanline is scanline 0 (we set scanline to -1 in
995
 
       VIDEO_EOF) */
996
 
 
997
 
        /* Compensate for some rounding errors
998
 
 
999
 
       When the counter reaches 314 (or whatever the max lines is) we should have reached the
1000
 
       end of the frame, however due to rounding errors in the timer calculation we're not quite
1001
 
       there.  Let's assume we are still in the previous scanline for now.
1002
 
 
1003
 
       The position to get the H position also has to compensate for a few errors
1004
 
    */
1005
 
//  printf("num %d\n",num );
1006
 
        struct sms_vdp *chip = (struct sms_vdp *)ptr;
1007
 
 
1008
 
        if (chip->sms_scanline_counter<(chip->sms_total_scanlines-1))
1009
 
        {
1010
 
                chip->sms_scanline_counter++;
1011
 
                chip->sms_scanline_timer->adjust(attotime::from_hz(chip->sms_framerate * chip->sms_total_scanlines));
1012
 
 
1013
 
                if (chip->sms_scanline_counter>sms_mode_table[chip->screen_mode].sms2_height)
1014
 
                {
1015
 
                        chip->hint_counter=chip->regs[0xa];
1016
 
                }
1017
 
 
1018
 
                if (chip->sms_scanline_counter==0)
1019
 
                {
1020
 
                        chip->hint_counter=chip->regs[0xa];
1021
 
                }
1022
 
 
1023
 
                if (chip->sms_scanline_counter<=192)
1024
 
                {
1025
 
                        chip->hint_counter--;
1026
 
 
1027
 
                        if (chip->hint_counter==0xff)
1028
 
                        {
1029
 
                                //if (chip->chip_id==2) printf("irq triggerd on scanline %d %d\n", vdp1->sms_scanline_counter, vdp2->sms_scanline_counter);
1030
 
 
1031
 
                                chip->line_irq_pending = 1;
1032
 
                                chip->hint_counter=chip->regs[0xa];
1033
 
                                if (chip->regs[0x0]&0x10)
1034
 
                                {
1035
 
                                        (chip->set_irq)(machine, 1); // set IRQ;
1036
 
                                }
1037
 
                                else
1038
 
                                {
1039
 
                                        (chip->set_irq)(machine, 0); // clear IRQ;
1040
 
                                }
1041
 
                        }
1042
 
 
1043
 
                }
1044
 
 
1045
 
 
1046
 
                sms_draw_scanline(chip->sms_scanline_counter, chip);
1047
 
 
1048
 
                //if(sms_scanline_counter==0) chip->sprite_collision = 0;
1049
 
 
1050
 
                if (chip->sms_scanline_counter==sms_mode_table[chip->screen_mode].sms2_height+1 )
1051
 
                {
1052
 
                        chip->frame_irq_pending = 1;
1053
 
                        if (chip->regs[0x1]&0x20)
1054
 
                        {
1055
 
                                (chip->set_irq)(machine, 1); // set IRQ;
1056
 
                        }
1057
 
                        else
1058
 
                        {
1059
 
                                (chip->set_irq)(machine, 0); // clear IRQ;
1060
 
                        }
1061
 
                }
1062
 
        }
1063
 
        else
1064
 
        {       /* if we're called passed the total number of scanlines then assume we're still on the last one.
1065
 
           this can happen due to rounding errors */
1066
 
                chip->sms_scanline_counter = chip->sms_total_scanlines-1;
1067
 
        }
1068
 
}
1069
 
 
1070
 
#ifdef UNUSED_FUNCTION
1071
 
static void show_tiles(struct sms_vdp* chip)
1072
 
{
1073
 
        int x,y,xx,yy;
1074
 
        UINT16 count = 0;
1075
 
 
1076
 
        for (y=0;y<16;y++)
1077
 
        {
1078
 
                for (x=0;x<32;x++)
1079
 
                {
1080
 
                        for (yy=0;yy<8;yy++)
1081
 
                        {
1082
 
                                int drawypos = y*8+yy;
1083
 
                                UINT16* lineptr = BITMAP_ADDR16(chip->r_bitmap, drawypos, 0);
1084
 
 
1085
 
                                UINT32 gfxdata = (SMS_VDP_VRAM(count)<<24)|(SMS_VDP_VRAM(count+1)<<16)|(SMS_VDP_VRAM(count+2)<<8)|(SMS_VDP_VRAM(count+3)<<0);
1086
 
 
1087
 
                                for (xx=0;xx<8;xx++)
1088
 
                                {
1089
 
                                        int drawxpos = x*8+xx;
1090
 
 
1091
 
                                        UINT8 pixel = (( (gfxdata>>(0+xx)  ) &0x00000001)<<3)|
1092
 
                                                      (( (gfxdata>>(8+xx)  ) &0x00000001)<<2)|
1093
 
                                                      (( (gfxdata>>(16+xx) ) &0x00000001)<<1)|
1094
 
                                                      (( (gfxdata>>(24+xx) ) &0x00000001)<<0);
1095
 
 
1096
 
                                        lineptr[drawxpos] = chip->cram_mamecolours[pixel+16];
1097
 
 
1098
 
                                }
1099
 
 
1100
 
 
1101
 
                                count+=4;count&=0x3fff;
1102
 
                        }
1103
 
                }
1104
 
        }
1105
 
}
1106
 
#endif
1107
 
 
1108
 
/*
1109
 
 Register $00 - Mode Control No. 1
1110
 
 
1111
 
 D7 - 1= Disable vertical scrolling for columns 24-31
1112
 
 D6 - 1= Disable horizontal scrolling for rows 0-1
1113
 
 D5 - 1= Mask column 0 with overscan color from register #7
1114
 
 D4 - (IE1) 1= Line interrupt enable
1115
 
 D3 - (EC) 1= Shift sprites left by 8 pixels
1116
 
 D2 - (M4) 1= Use Mode 4, 0= Use TMS9918 modes (selected with M1, M2, M3)
1117
 
 D1 - (M2) Must be 1 for M1/M3 to change screen height in Mode 4.
1118
 
      Otherwise has no effect.
1119
 
 D0 - 1= No sync, display is monochrome, 0= Normal display
1120
 
 
1121
 
 Bits 0 and 5 have no effect on the GameGear in either mode, while bit 6
1122
 
 has no effect in GG mode but works normally in SMS mode.
1123
 
 */
1124
 
 
1125
 
 /*
1126
 
  Register $01 - Mode Control No. 2
1127
 
 
1128
 
  D7 - No effect
1129
 
  D6 - (BLK) 1= Display visible, 0= display blanked.
1130
 
  D5 - (IE0) 1= Frame interrupt enable.
1131
 
  D4 - (M1) Selects 224-line screen for Mode 4 if M2=1, else has no effect.
1132
 
  D3 - (M3) Selects 240-line screen for Mode 4 if M2=1, else has no effect.
1133
 
  D2 - No effect
1134
 
  D1 - Sprites are 1=16x16,0=8x8 (TMS9918), Sprites are 1=8x16,0=8x8 (Mode 4)
1135
 
  D0 - Sprite pixels are doubled in size.
1136
 
 
1137
 
 Even though some games set bit 7, it does nothing.
1138
 
 */
1139
 
 
1140
 
static void end_of_frame(running_machine &machine, struct sms_vdp *chip)
1141
 
{
1142
 
        UINT8 m1 = (chip->regs[0x1]&0x10)>>4;
1143
 
        UINT8 m2 = (chip->regs[0x0]&0x02)>>1;
1144
 
        UINT8 m3 = (chip->regs[0x1]&0x08)>>3;
1145
 
        UINT8 m4 = (chip->regs[0x0]&0x04)>>2;
1146
 
        UINT8 m5 = chip->is_pal;
1147
 
        chip->screen_mode = m1|(m2<<1)|(m3<<2)|(m4<<3)|(m5<<4);
1148
 
 
1149
 
        if (chip->vdp_type!=GG_VDP) /* In GG mode the Game Gear resolution is fixed */
1150
 
        {
1151
 
                rectangle visarea;
1152
 
 
1153
 
                visarea.min_x = 0;
1154
 
                visarea.max_x = 256-1;
1155
 
                visarea.min_y = 0;
1156
 
                visarea.max_y = sms_mode_table[chip->screen_mode].sms2_height-1;
1157
 
 
1158
 
                if (chip->chip_id==3) machine.primary_screen->configure(256, 256, visarea, HZ_TO_ATTOSECONDS(chip->sms_framerate));
1159
 
 
1160
 
        }
1161
 
        else /* 160x144 */
1162
 
        {
1163
 
                rectangle visarea;
1164
 
                visarea.min_x = (256-160)/2;
1165
 
                visarea.max_x = (256-160)/2+160-1;
1166
 
                visarea.min_y = (192-144)/2;
1167
 
                visarea.max_y = (192-144)/2+144-1;
1168
 
 
1169
 
                machine.primary_screen->configure(256, 256, visarea, HZ_TO_ATTOSECONDS(chip->sms_framerate));
1170
 
        }
1171
 
 
1172
 
 
1173
 
 
1174
 
//  printf("Mode: %s is ok\n", sms_mode_table[chip->screen_mode].sms2_name);
1175
 
 
1176
 
        chip->sms_scanline_counter = -1;
1177
 
        chip->yscroll = chip->regs[0x9]; // this can't change mid-frame
1178
 
        chip->sms_scanline_timer->adjust(attotime::zero);
1179
 
}
1180
 
 
1181
 
 
1182
 
SCREEN_EOF(sms)
1183
 
{
1184
 
        end_of_frame(machine, md_sms_vdp);
1185
 
 
1186
 
        // the SMS has a 'RESET' button on the machine, it generates an NMI
1187
 
        if (input_port_read_safe(machine,"PAUSE",0x00))
1188
 
                cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE);
1189
 
 
1190
 
}
1191
 
 
1192
 
 
1193
 
VIDEO_START(sms)
1194
 
{
1195
 
 
1196
 
}
1197
 
 
1198
 
 
1199
 
MACHINE_RESET(sms)
1200
 
{
1201
 
        md_sms_vdp->sms_scanline_timer->adjust(attotime::zero);
1202
 
}
1203
 
 
1204
 
 
1205
 
 
1206
 
UINT8* vdp2_vram_bank0;
1207
 
UINT8* vdp2_vram_bank1;
1208
 
 
1209
 
UINT8* vdp1_vram_bank0;
1210
 
UINT8* vdp1_vram_bank1;
1211
 
 
1212
 
void segae_set_vram_banks(UINT8 data)
1213
 
{
1214
 
        if (data&0x80)
1215
 
        {
1216
 
                vdp1->vram = vdp1_vram_bank1;
1217
 
        }
1218
 
        else
1219
 
        {
1220
 
                vdp1->vram = vdp1_vram_bank0;
1221
 
        }
1222
 
 
1223
 
        if (data&0x40)
1224
 
        {
1225
 
                vdp2->vram = vdp2_vram_bank1;
1226
 
        }
1227
 
        else
1228
 
        {
1229
 
                vdp2->vram = vdp2_vram_bank0;
1230
 
        }
1231
 
 
1232
 
 
1233
 
}
1234
 
 
1235
 
MACHINE_RESET(systeme)
1236
 
{
1237
 
        vdp1->sms_scanline_timer->adjust(attotime::zero);
1238
 
        vdp2->sms_scanline_timer->adjust(attotime::zero);
1239
 
}
1240
 
 
1241
 
MACHINE_RESET(megatech_md_sms)
1242
 
{
1243
 
        md_sms_vdp->sms_scanline_timer->adjust(attotime::zero);
1244
 
}
1245
 
 
1246
 
MACHINE_RESET(megatech_bios)
1247
 
{
1248
 
        vdp1->sms_scanline_timer->adjust(attotime::zero);
1249
 
}
1250
 
 
1251
 
SCREEN_EOF(systeme)
1252
 
{
1253
 
        end_of_frame(machine, vdp1);
1254
 
        end_of_frame(machine, vdp2);
1255
 
}
1256
 
 
1257
 
 
1258
 
SCREEN_EOF(megatech_md_sms)
1259
 
{
1260
 
        end_of_frame(machine, md_sms_vdp);
1261
 
}
1262
 
 
1263
 
SCREEN_EOF(megatech_bios)
1264
 
{
1265
 
        end_of_frame(machine, vdp1);
1266
 
}
1267
 
 
1268
 
SCREEN_UPDATE(megatech_md_sms)
1269
 
{
1270
 
        int x,y;
1271
 
 
1272
 
        for (y=0;y<224;y++)
1273
 
        {
1274
 
                UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0);
1275
 
                UINT16* srcptr =  BITMAP_ADDR16(md_sms_vdp->r_bitmap, y, 0);
1276
 
 
1277
 
                for (x=0;x<256;x++)
1278
 
                {
1279
 
                        lineptr[x]=srcptr[x]&0x7fff;
1280
 
                }
1281
 
        }
1282
 
 
1283
 
        return 0;
1284
 
}
1285
 
 
1286
 
 
1287
 
SCREEN_UPDATE(megatech_bios)
1288
 
{
1289
 
        int x,y;
1290
 
 
1291
 
        for (y=0;y<224;y++)
1292
 
        {
1293
 
                UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0);
1294
 
                UINT16* srcptr =  BITMAP_ADDR16(vdp1->r_bitmap, y, 0);
1295
 
 
1296
 
                for (x=0;x<256;x++)
1297
 
                {
1298
 
                        lineptr[x]=srcptr[x]&0x7fff;
1299
 
                }
1300
 
        }
1301
 
 
1302
 
        return 0;
1303
 
}
1304
 
 
1305
 
SCREEN_UPDATE(megaplay_bios)
1306
 
{
1307
 
        int x,y;
1308
 
 
1309
 
        for (y=0;y<224;y++)
1310
 
        {
1311
 
                UINT16* lineptr = BITMAP_ADDR16(bitmap, y+16, 32);
1312
 
                UINT16* srcptr =  BITMAP_ADDR16(vdp1->r_bitmap, y, 0);
1313
 
 
1314
 
                for (x=0;x<256;x++)
1315
 
                {
1316
 
                        UINT16 src = srcptr[x]&0x7fff;
1317
 
 
1318
 
                        if (src)
1319
 
                                lineptr[x]=srcptr[x]&0x7fff;
1320
 
                }
1321
 
        }
1322
 
 
1323
 
        return 0;
1324
 
}
1325
 
 
1326
 
SCREEN_UPDATE(systeme)
1327
 
{
1328
 
//  show_tiles();
1329
 
        int x,y;
1330
 
 
1331
 
        for (y=0;y<192;y++)
1332
 
        {
1333
 
                UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0);
1334
 
                UINT16* srcptr =  BITMAP_ADDR16(vdp1->r_bitmap, y, 0);
1335
 
 
1336
 
                for (x=0;x<256;x++)
1337
 
                {
1338
 
                        lineptr[x]=srcptr[x]&0x7fff;
1339
 
                }
1340
 
 
1341
 
        }
1342
 
 
1343
 
        for (y=0;y<192;y++)
1344
 
        {
1345
 
                UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0);
1346
 
                UINT16* srcptr =  BITMAP_ADDR16(vdp2->r_bitmap, y, 0);
1347
 
 
1348
 
                for (x=0;x<256;x++)
1349
 
                {
1350
 
                        if(!(srcptr[x]&0x8000)) lineptr[x]=srcptr[x]&0x7fff;
1351
 
                }
1352
 
        }
1353
 
 
1354
 
 
1355
 
        return 0;
1356
 
}
1357
 
 
1358
 
 
1359
 
 
1360
 
 
1361
 
READ8_HANDLER( sms_vdp_2_data_r )
1362
 
{
1363
 
        return vdp_data_r(vdp2);
1364
 
}
1365
 
 
1366
 
WRITE8_HANDLER( sms_vdp_2_data_w )
1367
 
{
1368
 
        vdp_data_w(space, data, vdp2);
1369
 
}
1370
 
 
1371
 
READ8_HANDLER( sms_vdp_2_ctrl_r )
1372
 
{
1373
 
        return vdp_ctrl_r(space, vdp2);
1374
 
}
1375
 
 
1376
 
WRITE8_HANDLER( sms_vdp_2_ctrl_w )
1377
 
{
1378
 
        vdp_ctrl_w(space, data, vdp2);
1379
 
}
1380
 
 
1381
 
 
1382
 
void init_for_megadrive(running_machine &machine)
1383
 
{
1384
 
        md_sms_vdp = (struct sms_vdp *)start_vdp(machine, GEN_VDP);
1385
 
        md_sms_vdp->set_irq = sms_vdp_cpu1_irq_callback;
1386
 
        md_sms_vdp->is_pal = 0;
1387
 
        md_sms_vdp->sms_total_scanlines = 262;
1388
 
        md_sms_vdp->sms_framerate = 60;
1389
 
        md_sms_vdp->chip_id = 3;
1390
 
}
1391
 
 
1392
 
 
1393
 
 
1394
 
DRIVER_INIT( megatech_bios )
1395
 
{
1396
 
        vdp1 = (struct sms_vdp *)start_vdp(machine, SMS2_VDP);
1397
 
        vdp1->set_irq = sms_vdp_cpu2_irq_callback;
1398
 
        vdp1->is_pal = 0;
1399
 
        vdp1->sms_total_scanlines = 262;
1400
 
        vdp1->sms_framerate = 60;
1401
 
        vdp1->chip_id = 1;
1402
 
 
1403
 
        vdp1_vram_bank0 = vdp1->vram;
1404
 
        vdp1_vram_bank1 = auto_alloc_array(machine, UINT8, 0x4000);
1405
 
 
1406
 
        smsgg_backupram = 0;
1407
 
}
1408
 
 
1409
 
DRIVER_INIT( smscm )
1410
 
{
1411
 
        megatech_set_genz80_as_sms_standard_map(machine, "maincpu", MAPPER_CODEMASTERS);
1412
 
 
1413
 
        md_sms_vdp = (struct sms_vdp *)start_vdp(machine, SMS2_VDP);
1414
 
        md_sms_vdp->set_irq = sms_vdp_cpu0_irq_callback;
1415
 
        md_sms_vdp->is_pal = 1;
1416
 
        md_sms_vdp->sms_total_scanlines = 313;
1417
 
        md_sms_vdp->sms_framerate = 50;
1418
 
        md_sms_vdp->chip_id = 3;
1419
 
 
1420
 
        vdp1_vram_bank0 = md_sms_vdp->vram;
1421
 
        vdp1_vram_bank1 = auto_alloc_array(machine, UINT8, 0x4000);
1422
 
 
1423
 
        smsgg_backupram = 0;
1424
 
}
1425
 
 
1426
 
DRIVER_INIT( smspal )
1427
 
{
1428
 
        megatech_set_genz80_as_sms_standard_map(machine, "maincpu", MAPPER_STANDARD);
1429
 
 
1430
 
        md_sms_vdp = (struct sms_vdp *)start_vdp(machine, SMS2_VDP);
1431
 
        md_sms_vdp->set_irq = sms_vdp_cpu0_irq_callback;
1432
 
        md_sms_vdp->is_pal = 1;
1433
 
        md_sms_vdp->sms_total_scanlines = 313;
1434
 
        md_sms_vdp->sms_framerate = 50;
1435
 
        md_sms_vdp->chip_id = 3;
1436
 
 
1437
 
        vdp1_vram_bank0 = md_sms_vdp->vram;
1438
 
        vdp1_vram_bank1 = auto_alloc_array(machine, UINT8, 0x4000);
1439
 
 
1440
 
        smsgg_backupram = 0;
1441
 
}
1442
 
 
1443
 
DRIVER_INIT( sms )
1444
 
{
1445
 
        megatech_set_genz80_as_sms_standard_map(machine, "maincpu", MAPPER_STANDARD);
1446
 
 
1447
 
        md_sms_vdp = (struct sms_vdp *)start_vdp(machine, SMS2_VDP);
1448
 
        md_sms_vdp->set_irq = sms_vdp_cpu0_irq_callback;
1449
 
        md_sms_vdp->is_pal = 0;
1450
 
        md_sms_vdp->sms_total_scanlines = 262;
1451
 
        md_sms_vdp->sms_framerate = 60;
1452
 
        md_sms_vdp->chip_id = 3;
1453
 
 
1454
 
        vdp1_vram_bank0 = md_sms_vdp->vram;
1455
 
        vdp1_vram_bank1 = auto_alloc_array(machine, UINT8, 0x4000);
1456
 
 
1457
 
        smsgg_backupram = 0;
1458
 
}
1459
 
 
1460
 
static UINT8 ioport_gg00_r(running_machine& machine)
1461
 
{
1462
 
        UINT8 GG_START_BUTTON = input_port_read_safe(machine,"GGSTART",0x00);
1463
 
 
1464
 
        return (GG_START_BUTTON << 7) |
1465
 
                   (0               << 6) |
1466
 
                   (0               << 5) |
1467
 
                   (0               << 4) |
1468
 
                   (0               << 3) |
1469
 
                   (0               << 2) |
1470
 
                   (0               << 1) |
1471
 
                   (0               << 0);
1472
 
}
1473
 
 
1474
 
 
1475
 
READ8_HANDLER( sms_ioport_gg00_r )
1476
 
{
1477
 
        return ioport_gg00_r(space->machine());
1478
 
}
1479
 
 
1480
 
 
1481
 
void init_extra_gg_ports(running_machine& machine, const char* tag)
1482
 
{
1483
 
        address_space *io = machine.device(tag)->memory().space(AS_IO);
1484
 
        io->install_legacy_read_handler     (0x00, 0x00, FUNC(sms_ioport_gg00_r));
1485
 
}
1486
 
 
1487
 
DRIVER_INIT( smsgg )
1488
 
{
1489
 
        megatech_set_genz80_as_sms_standard_map(machine, "maincpu", MAPPER_STANDARD);
1490
 
        init_extra_gg_ports(machine, "maincpu");
1491
 
 
1492
 
        md_sms_vdp = (struct sms_vdp *)start_vdp(machine, GG_VDP);
1493
 
        md_sms_vdp->set_irq = sms_vdp_cpu0_irq_callback;
1494
 
        md_sms_vdp->is_pal = 0;
1495
 
        md_sms_vdp->sms_total_scanlines = 262;
1496
 
        md_sms_vdp->sms_framerate = 60;
1497
 
        md_sms_vdp->chip_id = 3;
1498
 
 
1499
 
        smsgg_backupram = 0;
1500
 
}
1501
 
 
1502
 
 
1503
 
DRIVER_INIT( hazemd_segasyse )
1504
 
{
1505
 
        vdp1 = (struct sms_vdp *)start_vdp(machine, SMS2_VDP);
1506
 
//  vdp1->set_irq = sms_vdp_cpu0_irq_callback;
1507
 
        vdp1->is_pal = 0;
1508
 
        vdp1->sms_total_scanlines = 262;
1509
 
        vdp1->sms_framerate = 60;
1510
 
        vdp1->chip_id = 1;
1511
 
 
1512
 
        vdp1_vram_bank0 = vdp1->vram;
1513
 
        vdp1_vram_bank1 = auto_alloc_array(machine, UINT8, 0x4000);
1514
 
 
1515
 
 
1516
 
        vdp2 = (struct sms_vdp *)start_vdp(machine, SMS2_VDP);
1517
 
        vdp2->set_irq = sms_vdp_cpu0_irq_callback;
1518
 
        vdp2->is_pal = 0;
1519
 
        vdp2->sms_total_scanlines = 262;
1520
 
        vdp2->sms_framerate = 60;
1521
 
        vdp2->chip_id = 2;
1522
 
 
1523
 
        vdp2_vram_bank0 = vdp2->vram;
1524
 
        vdp2_vram_bank1 = auto_alloc_array(machine, UINT8, 0x4000);
1525
 
}
1526
 
 
1527
 
/* Functions to set up the Memory Map
1528
 
 
1529
 
 -- these are needed because on a Genesis the Sound Z80 becomes the SMS Z80 in comptibility mode
1530
 
    so we need to be able to dynamically change the mapping
1531
 
 
1532
 
*/
1533
 
 
1534
 
static READ8_HANDLER( z80_unmapped_port_r )
1535
 
{
1536
 
//  printf("unmapped z80 port read %04x\n",offset);
1537
 
        return 0;
1538
 
}
1539
 
 
1540
 
static WRITE8_HANDLER( z80_unmapped_port_w )
1541
 
{
1542
 
//  printf("unmapped z80 port write %04x\n",offset);
1543
 
}
1544
 
 
1545
 
static READ8_HANDLER( z80_unmapped_r )
1546
 
{
1547
 
        printf("unmapped z80 read %04x\n",offset);
1548
 
        return 0;
1549
 
}
1550
 
 
1551
 
static WRITE8_HANDLER( z80_unmapped_w )
1552
 
{
1553
 
        printf("unmapped z80 write %04x\n",offset);
1554
 
}
1555
 
 
1556
 
static UINT8* sms_rom;
1557
 
 
1558
 
 
1559
 
/* the SMS inputs should be more complex, like the megadrive ones */
1560
 
READ8_HANDLER (megatech_sms_ioport_dc_r)
1561
 
{
1562
 
        running_machine &machine = space->machine();
1563
 
        /* 2009-05 FP: would it be worth to give separate inputs to SMS? SMS has only 2 keys A,B (which are B,C on megadrive) */
1564
 
        /* bit 4: TL-A; bit 5: TR-A */
1565
 
        return (input_port_read(machine, "PAD1") & 0x3f) | ((input_port_read(machine, "PAD2") & 0x03) << 6);
1566
 
}
1567
 
 
1568
 
READ8_HANDLER (megatech_sms_ioport_dd_r)
1569
 
{
1570
 
        running_machine &machine = space->machine();
1571
 
        /* 2009-05 FP: would it be worth to give separate inputs to SMS? SMS has only 2 keys A,B (which are B,C on megadrive) */
1572
 
        /* bit 2: TL-B; bit 3: TR-B; bit 4: RESET; bit 5: unused; bit 6: TH-A; bit 7: TH-B*/
1573
 
        return ((input_port_read(machine, "PAD2") & 0x3c) >> 2) | 0x10;
1574
 
}
1575
 
 
1576
 
 
1577
 
READ8_HANDLER( smsgg_backupram_r )
1578
 
{
1579
 
        return smsgg_backupram[offset];
1580
 
}
1581
 
 
1582
 
WRITE8_HANDLER( smsgg_backupram_w )
1583
 
{
1584
 
        smsgg_backupram[offset] = data;
1585
 
}
1586
 
 
1587
 
 
1588
 
static WRITE8_HANDLER( mt_sms_standard_rom_bank_w )
1589
 
{
1590
 
        int bank = data&0x1f;
1591
 
        //logerror("bank w %02x %02x\n", offset, data);
1592
 
 
1593
 
        sms_mainram[0x1ffc+offset] = data;
1594
 
        switch (offset)
1595
 
        {
1596
 
                case 0:
1597
 
                        logerror("bank w %02x %02x\n", offset, data);
1598
 
                        if ((data & 0x08) && smsgg_backupram)
1599
 
                        {
1600
 
                                space->install_legacy_readwrite_handler(0x8000, 0x9fff, FUNC(smsgg_backupram_r), FUNC(smsgg_backupram_w));
1601
 
                        }
1602
 
                        else
1603
 
                        {
1604
 
                                space->install_rom(0x0000, 0xbfff, sms_rom);
1605
 
                                space->unmap_write(0x0000, 0xbfff);
1606
 
                        }
1607
 
 
1608
 
                        //printf("bank ram??\n");
1609
 
                        break;
1610
 
                case 1:
1611
 
                        memcpy(sms_rom+0x0000, space->machine().region("maincpu")->base()+bank*0x4000, 0x4000);
1612
 
                        break;
1613
 
                case 2:
1614
 
                        memcpy(sms_rom+0x4000, space->machine().region("maincpu")->base()+bank*0x4000, 0x4000);
1615
 
                        break;
1616
 
                case 3:
1617
 
                        memcpy(sms_rom+0x8000, space->machine().region("maincpu")->base()+bank*0x4000, 0x4000);
1618
 
                        break;
1619
 
 
1620
 
        }
1621
 
}
1622
 
 
1623
 
static WRITE8_HANDLER( codemasters_rom_bank_0000_w )
1624
 
{
1625
 
        int bank = data&0x1f;
1626
 
        memcpy(sms_rom+0x0000, space->machine().region("maincpu")->base()+bank*0x4000, 0x4000);
1627
 
}
1628
 
 
1629
 
static WRITE8_HANDLER( codemasters_rom_bank_4000_w )
1630
 
{
1631
 
        int bank = data&0x1f;
1632
 
        memcpy(sms_rom+0x4000, space->machine().region("maincpu")->base()+bank*0x4000, 0x4000);
1633
 
}
1634
 
 
1635
 
static WRITE8_HANDLER( codemasters_rom_bank_8000_w )
1636
 
{
1637
 
        int bank = data&0x1f;
1638
 
        memcpy(sms_rom+0x8000, space->machine().region("maincpu")->base()+bank*0x4000, 0x4000);
1639
 
}
1640
 
 
1641
 
 
1642
 
static void megatech_set_genz80_as_sms_standard_ports(running_machine &machine, const char* tag)
1643
 
{
1644
 
        /* INIT THE PORTS *********************************************************************************************/
1645
 
 
1646
 
        address_space *io = machine.device(tag)->memory().space(AS_IO);
1647
 
        device_t *sn = machine.device("snsnd");
1648
 
 
1649
 
        io->install_legacy_readwrite_handler(0x0000, 0xffff, FUNC(z80_unmapped_port_r), FUNC(z80_unmapped_port_w));
1650
 
 
1651
 
        io->install_legacy_read_handler      (0x7e, 0x7e, FUNC(md_sms_vdp_vcounter_r));
1652
 
        io->install_legacy_write_handler(*sn, 0x7e, 0x7f, FUNC(sn76496_w));
1653
 
        io->install_legacy_readwrite_handler (0xbe, 0xbe, FUNC(md_sms_vdp_data_r), FUNC(md_sms_vdp_data_w));
1654
 
        io->install_legacy_readwrite_handler (0xbf, 0xbf, FUNC(md_sms_vdp_ctrl_r), FUNC(md_sms_vdp_ctrl_w));
1655
 
 
1656
 
        io->install_legacy_read_handler      (0x10, 0x10, FUNC(megatech_sms_ioport_dd_r)); // super tetris
1657
 
 
1658
 
        io->install_legacy_read_handler      (0xdc, 0xdc, FUNC(megatech_sms_ioport_dc_r));
1659
 
        io->install_legacy_read_handler      (0xdd, 0xdd, FUNC(megatech_sms_ioport_dd_r));
1660
 
        io->install_legacy_read_handler      (0xde, 0xde, FUNC(megatech_sms_ioport_dd_r));
1661
 
        io->install_legacy_read_handler      (0xdf, 0xdf, FUNC(megatech_sms_ioport_dd_r)); // adams family
1662
 
}
1663
 
 
1664
 
void megatech_set_genz80_as_sms_standard_map(running_machine &machine, const char* tag, int mapper)
1665
 
{
1666
 
        /* INIT THE MEMMAP / BANKING *********************************************************************************/
1667
 
 
1668
 
        /* catch any addresses that don't get mapped */
1669
 
        machine.device(tag)->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x0000, 0xffff, FUNC(z80_unmapped_r), FUNC(z80_unmapped_w));
1670
 
 
1671
 
        /* main ram area */
1672
 
        sms_mainram = (UINT8 *)machine.device(tag)->memory().space(AS_PROGRAM)->install_ram(0xc000, 0xdfff, 0, 0x2000);
1673
 
        memset(sms_mainram,0x00,0x2000);
1674
 
 
1675
 
        megatech_set_genz80_as_sms_standard_ports(machine,  tag);
1676
 
 
1677
 
        /* fixed rom bank area */
1678
 
        sms_rom = (UINT8 *)machine.device(tag)->memory().space(AS_PROGRAM)->install_rom(0x0000, 0xbfff, NULL);
1679
 
 
1680
 
        memcpy(sms_rom, machine.region("maincpu")->base(), 0xc000);
1681
 
 
1682
 
        if (mapper == MAPPER_STANDARD )
1683
 
        {
1684
 
 
1685
 
 
1686
 
                machine.device(tag)->memory().space(AS_PROGRAM)->install_legacy_write_handler(0xfffc, 0xffff, FUNC(mt_sms_standard_rom_bank_w));
1687
 
 
1688
 
        }
1689
 
        else if (mapper == MAPPER_CODEMASTERS )
1690
 
        {
1691
 
                machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x0000, 0x0000, FUNC(codemasters_rom_bank_0000_w));
1692
 
                machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x4000, 0x4000, FUNC(codemasters_rom_bank_4000_w));
1693
 
                machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_write_handler(0x8000, 0x8000, FUNC(codemasters_rom_bank_8000_w));
1694
 
        }
1695
 
//  smsgg_backupram = NULL;
1696
 
}
1697
 
 
1698
 
static NVRAM_HANDLER( sms )
1699
 
{
1700
 
        if (smsgg_backupram!=NULL)
1701
 
        {
1702
 
                if (read_or_write)
1703
 
                        file->write(smsgg_backupram, 0x2000);
1704
 
                else
1705
 
                {
1706
 
                        if (file)
1707
 
                        {
1708
 
                                file->read(smsgg_backupram, 0x2000);
1709
 
                        }
1710
 
                }
1711
 
        }
1712
 
}
1713
 
 
1714
 
MACHINE_CONFIG_START( sms, driver_device )
1715
 
        MCFG_CPU_ADD("maincpu", Z80, 3579540)
1716
 
        //MCFG_CPU_PROGRAM_MAP(sms_map)
1717
 
        MCFG_CPU_IO_MAP(sms_io_map)
1718
 
 
1719
 
        /* IRQ handled via the timers */
1720
 
        MCFG_MACHINE_RESET(sms)
1721
 
 
1722
 
        MCFG_SCREEN_ADD("screen", RASTER)
1723
 
        MCFG_SCREEN_REFRESH_RATE(60)
1724
 
        MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) // Vblank handled manually.
1725
 
        MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB15)
1726
 
        MCFG_SCREEN_SIZE(256, 256)
1727
 
        MCFG_SCREEN_VISIBLE_AREA(0, 255, 0, 223)
1728
 
//  MCFG_SCREEN_VISIBLE_AREA(0, 255, 0, 191)
1729
 
        MCFG_SCREEN_UPDATE(megatech_md_sms) /* Copies a bitmap */
1730
 
        MCFG_SCREEN_EOF(sms) /* Used to Sync the timing */
1731
 
 
1732
 
        MCFG_PALETTE_LENGTH(0x200)
1733
 
 
1734
 
        MCFG_VIDEO_START(sms)
1735
 
 
1736
 
        MCFG_NVRAM_HANDLER( sms )
1737
 
 
1738
 
        /* sound hardware */
1739
 
        MCFG_SPEAKER_STANDARD_MONO("mono")
1740
 
 
1741
 
        MCFG_SOUND_ADD("snsnd", SN76496, 3579540)
1742
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
1743
 
MACHINE_CONFIG_END
1744
 
 
1745