Previous 15994 Revisions Next

r11531 Thursday 12th May, 2011 at 20:05:06 UTC by Angelo Salese
Fix compile
[src/mame/includes]msx.h msx_slot.h
[src/mame/machine]msx.c
[src/mess]mess.mak
[src/mess/includes]msx.h* msx_slot.h*
[src/mess/machine]msx.c*

src/mame/machine/msx.c
r11530r11531
1/*
2 * msx.c: MSX emulation
3 *
4 * Copyright (C) 2004 Sean Young
5 *
6 * Todo:
7 *
8 * - fix mouse support
9 * - cassette support doesn't work
10 * - Ensure changing cartridge after boot works
11 * - wd2793, nms8255
12 */
13
14#include "emu.h"
15#include "machine/i8255.h"
16#include "includes/msx_slot.h"
17#include "includes/msx.h"
18#include "machine/rp5c01.h"
19#include "machine/wd17xx.h"
20#include "imagedev/flopdrv.h"
21#include "formats/basicdsk.h"
22#include "video/tms9928a.h"
23#include "cpu/z80/z80.h"
24#include "video/v9938.h"
25#include "machine/ctronics.h"
26#include "imagedev/cassette.h"
27#include "osdepend.h"
28#include "sound/ay8910.h"
29#include "sound/2413intf.h"
30#include "sound/dac.h"
31#include "hashfile.h"
32
33#define VERBOSE 0
34
35static void msx_memory_map_all (running_machine &machine);
36static void msx_memory_map_page (running_machine &machine, int page);
37static void msx_memory_init (running_machine &machine);
38static void msx_memory_set_carts (running_machine &machine);
39static void msx_memory_reset (running_machine &machine);
40
41
42
43static int msx_probe_type (UINT8* pmem, int size)
44{
45   int kon4, kon5, asc8, asc16, i;
46
47   if (size <= 0x10000) return 0;
48
49   if ( (pmem[0x10] == 'Y') && (pmem[0x11] == 'Z') && (size > 0x18000) )
50      return 6;
51
52   kon4 = kon5 = asc8 = asc16 = 0;
53
54   for (i=0;i<size-3;i++)
55   {
56      if (pmem[i] == 0x32 && pmem[i+1] == 0)
57      {
58         switch (pmem[i+2]) {
59         case 0x60:
60         case 0x70:
61            asc16++;
62            asc8++;
63            break;
64         case 0x68:
65         case 0x78:
66            asc8++;
67            asc16--;
68         }
69
70         switch (pmem[i+2]) {
71         case 0x60:
72         case 0x80:
73         case 0xa0:
74            kon4++;
75            break;
76         case 0x50:
77         case 0x70:
78         case 0x90:
79         case 0xb0:
80            kon5++;
81         }
82      }
83   }
84
85   if (MAX (kon4, kon5) > MAX (asc8, asc16) )
86      return (kon5 > kon4) ? 2 : 3;
87   else
88      return (asc8 > asc16) ? 4 : 5;
89}
90
91DEVICE_IMAGE_LOAD (msx_cart)
92{
93   msx_state *state = image.device().machine().driver_data<msx_state>();
94   int size;
95   int size_aligned;
96   UINT8 *mem;
97   int type;
98   const char *extra = NULL;
99   char *sramfile;
100   slot_state *st;
101   int id = -1;
102
103   if (strcmp(image.device().tag(),"cart1")==0) {
104      id = 0;
105   }
106   if (strcmp(image.device().tag(),"cart2")==0) {
107      id = 1;
108   }
109
110   if( id == -1 ) {
111      //logerror ("error: invalid cart tag '%s'\n", image->tag);
112      return IMAGE_INIT_FAIL;
113   }
114
115   size = image.length ();
116   if (size < 0x2000) {
117      logerror ("cart #%d: error: file is smaller than 2kb, too small "
118              "to be true!\n", id);
119      return IMAGE_INIT_FAIL;
120   }
121
122   /* allocate memory and load */
123   size_aligned = 0x2000;
124   while (size_aligned < size) {
125      size_aligned *= 2;
126   }
127   mem = (UINT8*)image.image_malloc(size_aligned);
128   if (!mem) {
129      logerror ("cart #%d: error: failed to allocate memory for cartridge\n",
130                  id);
131      return IMAGE_INIT_FAIL;
132   }
133   if (size < size_aligned) {
134      memset (mem, 0xff, size_aligned);
135   }
136   if (image.fread(mem, size) != size) {
137      logerror ("cart #%d: %s: can't read full %d bytes\n",
138                  id, image.filename (), size);
139      return IMAGE_INIT_FAIL;
140   }
141
142   /* see if msx.crc will tell us more */
143   extra = hashfile_extrainfo(image);
144
145   if (!extra)
146   {
147      logerror("cart #%d: warning: no information in crc file\n", id);
148      type = -1;
149   }
150   else if ((1 != sscanf(extra, "%d", &type) ) ||
151         type < 0 || type > SLOT_LAST_CARTRIDGE_TYPE)
152   {
153      logerror("cart #%d: warning: information in crc file not valid\n", id);
154      type = -1;
155   }
156   else
157   {
158      logerror ("cart #%d: info: cart extra info: '%s' = %s\n", id, extra,
159                  msx_slot_list[type].name);
160   }
161
162   /* if not, attempt autodetection */
163   if (type < 0)
164   {
165      type = msx_probe_type (mem, size);
166
167      if (mem[0] != 'A' || mem[1] != 'B') {
168         logerror("cart #%d: %s: May not be a valid ROM file\n",
169                     id, image.filename ());
170      }
171
172      logerror("cart #%d: Probed cartridge mapper %d/%s\n", id,
173                  type, msx_slot_list[type].name);
174   }
175
176   /* mapper type 0 always needs 64kB */
177   if (!type && size_aligned != 0x10000)
178   {
179      size_aligned = 0x10000;
180      mem = (UINT8*)image.image_realloc(mem, 0x10000);
181      if (!mem) {
182         logerror ("cart #%d: error: cannot allocate memory\n", id);
183         return IMAGE_INIT_FAIL;
184      }
185
186      if (size < 0x10000) {
187         memset (mem + size, 0xff, 0x10000 - size);
188      }
189      if (size > 0x10000) {
190         logerror ("cart #%d: warning: rom truncated to 64kb due to "
191                 "mapperless type (possibly detected)\n", id);
192
193         size = 0x10000;
194      }
195   }
196
197   /* mapper type 0 (ROM) might need moving around a bit */
198   if (!type) {
199      int i, page = 1;
200
201      /* find the correct page */
202      if (mem[0] == 'A' && mem[1] == 'B') {
203         for (i=2; i<=8; i += 2) {
204            if (mem[i] || mem[i+1]) {
205               page = mem[i+1] / 0x40;
206               break;
207            }
208         }
209      }
210
211      if (size <= 0x4000) {
212         if (page == 1 || page == 2) {
213            /* copy to the respective page */
214            memcpy (mem + (page * 0x4000), mem, 0x4000);
215            memset (mem, 0xff, 0x4000);
216         }
217         else {
218            /* memory is repeated 4 times */
219            page = -1;
220            memcpy (mem + 0x4000, mem, 0x4000);
221            memcpy (mem + 0x8000, mem, 0x4000);
222            memcpy (mem + 0xc000, mem, 0x4000);
223         }
224      }
225      else /*if (size <= 0xc000) */ {
226         if (page) {
227            /* shift up 16kB; custom memcpy so overlapping memory
228                   isn't corrupted. ROM starts in page 1 (0x4000) */
229            UINT8 *m;
230
231            page = 1;
232            i = 0xc000; m = mem + 0xffff;
233            while (i--) {
234               *m = *(m - 0x4000); m--;
235            }
236            memset (mem, 0xff, 0x4000);
237         }
238      }
239
240      if (page) {
241         logerror ("cart #%d: info: rom in page %d\n", id, page);
242      }
243      else {
244         logerror ("cart #%d: info: rom duplicted in all pages\n", id);
245      }
246   }
247
248   /* kludge */
249   if (type == 0) {
250      type = SLOT_ROM;
251   }
252
253   /* allocate and set slot_state for this cartridge */
254   st = (slot_state*) image.image_malloc(sizeof (slot_state));
255   if (!st)
256   {
257      logerror ("cart #%d: error: cannot allocate memory for "
258              "cartridge state\n", id);
259      return IMAGE_INIT_FAIL;
260   }
261   memset (st, 0, sizeof (slot_state));
262
263   st->m_type = type;
264   sramfile = (char*)image.image_malloc(strlen (image.filename () + 1));
265
266   if (sramfile) {
267      char *ext;
268
269      strcpy (sramfile, image.basename ());
270      ext = strrchr (sramfile, '.');
271      if (ext) {
272         *ext = 0;
273      }
274      st->m_sramfile = sramfile;
275   }
276
277   if (msx_slot_list[type].init (image.device().machine(), st, 0, mem, size_aligned)) {
278      return IMAGE_INIT_FAIL;
279   }
280   if (msx_slot_list[type].loadsram) {
281      msx_slot_list[type].loadsram (image.device().machine(), st);
282   }
283
284   state->m_cart_state[id] = st;
285   msx_memory_set_carts (image.device().machine());
286
287   return IMAGE_INIT_PASS;
288}
289
290DEVICE_IMAGE_UNLOAD (msx_cart)
291{
292   msx_state *state = image.device().machine().driver_data<msx_state>();
293   int id = -1;
294
295   if (strcmp(image.device().tag(),"cart1")==0) {
296      id = 0;
297   }
298   if (strcmp(image.device().tag(),"cart2")==0) {
299      id = 1;
300   }
301
302   if( id == -1 ) {
303      //logerror ("error: invalid cart tag '%s'\n", image->tag);
304      return;
305   }
306
307   if (msx_slot_list[state->m_cart_state[id]->m_type].savesram)
308   {
309      msx_slot_list[state->m_cart_state[id]->m_type].savesram (image.device().machine(), state->m_cart_state[id]);
310   }
311}
312
313void msx_vdp_interrupt(running_machine &machine, int i)
314{
315   cputag_set_input_line (machine, "maincpu", 0, (i ? HOLD_LINE : CLEAR_LINE));
316}
317
318static void msx_ch_reset_core (running_machine &machine)
319{
320   msx_memory_reset (machine);
321   msx_memory_map_all (machine);
322}
323
324static const TMS9928a_interface tms9928a_interface =
325{
326   TMS99x8A,
327   0x4000,
328   0, 0,
329   msx_vdp_interrupt
330};
331
332MACHINE_START( msx )
333{
334   TMS9928A_configure(&tms9928a_interface);
335   MACHINE_START_CALL( msx2 );
336}
337
338MACHINE_START( msx2 )
339{
340   msx_state *state = machine.driver_data<msx_state>();
341   state->m_port_c_old = 0xff;
342   state->m_dsk_stat = 0x7f;
343}
344
345MACHINE_RESET( msx )
346{
347   TMS9928A_reset ();
348   msx_ch_reset_core (machine);
349}
350
351MACHINE_RESET( msx2 )
352{
353   v9938_reset (0);
354   msx_ch_reset_core (machine);
355}
356
357static WRITE8_DEVICE_HANDLER ( msx_ppi_port_a_w );
358static WRITE8_DEVICE_HANDLER ( msx_ppi_port_c_w );
359static READ8_DEVICE_HANDLER (msx_ppi_port_b_r );
360
361I8255_INTERFACE( msx_ppi8255_interface )
362{
363   DEVCB_NULL,
364   DEVCB_HANDLER(msx_ppi_port_a_w),
365   DEVCB_HANDLER(msx_ppi_port_b_r),
366   DEVCB_NULL,
367   DEVCB_NULL,
368   DEVCB_HANDLER(msx_ppi_port_c_w)
369};
370
371
372static const UINT8 cc_op[0x100] = {
373 4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
374 8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
375 7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1,
376 7+1,10+1,13+1, 6+1,11+1,11+1,10+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1,
377 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
378 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
379 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
380 7+1, 7+1, 7+1, 7+1, 7+1, 7+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
381 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
382 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
383 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
384 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
385 5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 0+1,10+1,17+1, 7+1,11+1,
386 5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 0+1, 7+1,11+1,
387 5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 0+1, 7+1,11+1,
388 5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 0+1, 7+1,11+1
389};
390
391static const UINT8 cc_cb[0x100] = {
392 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
393 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
394 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
395 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
396 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
397 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
398 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
399 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
400 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
401 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
402 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
403 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
404 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
405 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
406 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
407 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2
408};
409
410static const UINT8 cc_ed[0x100] = {
411 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
412 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
413 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
414 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
41512+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
41612+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
41712+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,
41812+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,
419 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
420 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
42116+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
42216+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
423 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
424 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
425 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
426 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2
427};
428
429static const UINT8 cc_xy[0x100] = {
430 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
431 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
432 4+2,14+2,20+2,10+2, 9+2, 9+2, 9+2, 4+2, 4+2,15+2,20+2,10+2, 9+2, 9+2, 9+2, 4+2,
433 4+2, 4+2, 4+2, 4+2,23+2,23+2,19+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
434 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
435 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
436 9+2, 9+2, 9+2, 9+2, 9+2, 9+2,19+2, 9+2, 9+2, 9+2, 9+2, 9+2, 9+2, 9+2,19+2, 9+2,
43719+2,19+2,19+2,19+2,19+2,19+2, 4+2,19+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
438 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
439 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
440 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
441 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
442 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 0+2, 4+2, 4+2, 4+2, 4+2,
443 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
444 4+2,14+2, 4+2,23+2, 4+2,15+2, 4+2, 4+2, 4+2, 8+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
445 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,10+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2
446};
447
448static const UINT8 cc_xycb[0x100] = {
44923+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45023+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45123+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45223+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45320+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45420+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45520+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45620+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45723+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45823+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45923+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46023+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46123+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46223+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46323+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46423+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2
465};
466
467/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
468static const UINT8 cc_ex[0x100] = {
469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
470 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* DJNZ */
471 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,   /* JR NZ/JR Z */
472 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,   /* JR NC/JR C */
473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
474 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
475 0, 0, 0, 0, 0, 0, 0+1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
476 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
477 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
479 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
480 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0,   /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
481 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
482 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
483 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
484 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2+1
485};
486
487
488DRIVER_INIT( msx )
489{
490   device_set_input_line_vector (machine.device("maincpu"), 0, 0xff);
491
492   msx_memory_init (machine);
493
494   z80_set_cycle_tables( machine.device("maincpu"), cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex );
495}
496
497INTERRUPT_GEN( msx2_interrupt )
498{
499   v9938_set_sprite_limit(0, input_port_read(device->machine(), "DSW") & 0x20);
500   v9938_set_resolution(0, input_port_read(device->machine(), "DSW") & 0x03);
501   v9938_interrupt(device->machine(), 0);
502}
503
504INTERRUPT_GEN( msx_interrupt )
505{
506   msx_state *state = device->machine().driver_data<msx_state>();
507   int i;
508
509   for (i=0; i<2; i++)
510   {
511      state->m_mouse[i] = input_port_read(device->machine(), i ? "MOUSE1" : "MOUSE0");
512      state->m_mouse_stat[i] = -1;
513   }
514
515   TMS9928A_set_spriteslimit (input_port_read(device->machine(), "DSW") & 0x20);
516   TMS9928A_interrupt(device->machine());
517}
518
519/*
520** The I/O funtions
521*/
522
523static device_t *cassette_device_image(running_machine &machine)
524{
525   return machine.device("cassette");
526}
527
528READ8_HANDLER ( msx_psg_port_a_r )
529{
530   msx_state *state = space->machine().driver_data<msx_state>();
531   int data, inp;
532
533   data = (cassette_input(cassette_device_image(space->machine())) > 0.0038 ? 0x80 : 0);
534
535   if ( (state->m_psg_b ^ input_port_read(space->machine(), "DSW") ) & 0x40)
536      {
537      /* game port 2 */
538      inp = input_port_read(space->machine(), "JOY1") & 0x7f;
539#if 0
540      if ( !(inp & 0x80) )
541         {
542#endif
543         /* joystick */
544         return (inp & 0x7f) | data;
545#if 0
546         }
547      else
548         {
549         /* mouse */
550         data |= inp & 0x70;
551         if (state->m_mouse_stat[1] < 0)
552            inp = 0xf;
553         else
554            inp = ~(state->m_mouse[1] >> (4*state->m_mouse_stat[1]) ) & 15;
555
556         return data | inp;
557         }
558#endif
559      }
560   else
561      {
562      /* game port 1 */
563      inp = input_port_read(space->machine(), "JOY0") & 0x7f;
564#if 0
565      if ( !(inp & 0x80) )
566         {
567#endif
568         /* joystick */
569         return (inp & 0x7f) | data;
570#if 0
571         }
572      else
573         {
574         /* mouse */
575         data |= inp & 0x70;
576         if (state->m_mouse_stat[0] < 0)
577            inp = 0xf;
578         else
579            inp = ~(state->m_mouse[0] >> (4*state->m_mouse_stat[0]) ) & 15;
580
581         return data | inp;
582         }
583#endif
584      }
585
586   return 0;
587}
588
589READ8_HANDLER ( msx_psg_port_b_r )
590{
591   msx_state *state = space->machine().driver_data<msx_state>();
592   return state->m_psg_b;
593}
594
595WRITE8_HANDLER ( msx_psg_port_a_w )
596{
597}
598
599WRITE8_HANDLER ( msx_psg_port_b_w )
600{
601   msx_state *state = space->machine().driver_data<msx_state>();
602   /* Arabic or kana mode led */
603   if ( (data ^ state->m_psg_b) & 0x80)
604      set_led_status (space->machine(), 2, !(data & 0x80) );
605
606   if ( (state->m_psg_b ^ data) & 0x10)
607   {
608      if (++state->m_mouse_stat[0] > 3) state->m_mouse_stat[0] = -1;
609   }
610   if ( (state->m_psg_b ^ data) & 0x20)
611   {
612      if (++state->m_mouse_stat[1] > 3) state->m_mouse_stat[1] = -1;
613   }
614
615   state->m_psg_b = data;
616}
617
618WRITE8_DEVICE_HANDLER( msx_printer_strobe_w )
619{
620   centronics_strobe_w(device, BIT(data, 1));
621}
622
623WRITE8_DEVICE_HANDLER( msx_printer_data_w )
624{
625   if (input_port_read(device->machine(), "DSW") & 0x80)
626   {
627      /* SIMPL emulation */
628      dac_signed_data_w(device->machine().device("dac"), data);
629   }
630   else
631   {
632      centronics_data_w(device, 0, data);
633   }
634}
635
636READ8_DEVICE_HANDLER( msx_printer_status_r )
637{
638   UINT8 result = 0xfd;
639
640   if (input_port_read(device->machine(), "DSW") & 0x80)
641      return 0xff;
642
643   result |= centronics_busy_r(device) << 1;
644
645   return result;
646}
647
648WRITE8_HANDLER (msx_fmpac_w)
649{
650   msx_state *state = space->machine().driver_data<msx_state>();
651   if (state->m_opll_active)
652   {
653      device_t *ym = space->machine().device("ym2413");
654
655      if (offset == 1)
656         ym2413_w (ym, 1, data);
657      else
658         ym2413_w (ym, 0, data);
659   }
660}
661
662/*
663** RTC functions
664*/
665
666WRITE8_HANDLER (msx_rtc_latch_w)
667{
668   msx_state *state = space->machine().driver_data<msx_state>();
669   state->m_rtc_latch = data & 15;
670}
671
672WRITE8_HANDLER (msx_rtc_reg_w)
673{
674   msx_state *state = space->machine().driver_data<msx_state>();
675   rp5c01_device *rtc = space->machine().device<rp5c01_device>(TC8521_TAG);
676   rtc->write(*space, state->m_rtc_latch, data);
677}
678
679READ8_HANDLER (msx_rtc_reg_r)
680{
681   msx_state *state = space->machine().driver_data<msx_state>();
682   rp5c01_device *rtc = space->machine().device<rp5c01_device>(TC8521_TAG);
683   return rtc->read(*space, state->m_rtc_latch);
684}
685
686/*
687From: erbo@xs4all.nl (erik de boer)
688
689sony and philips have used (almost) the same design
690and this is the memory layout
691but it is not a msx standard !
692
693WD1793 or wd2793 registers
694
695adress
696
6977FF8H read  status register
698      write command register
6997FF9H  r/w  track register (r/o on NMS 8245 and Sony)
7007FFAH  r/w  sector register (r/o on NMS 8245 and Sony)
7017FFBH  r/w  data register
702
703
704hardware registers
705
706adress
707
7087FFCH r/w  bit 0 side select
7097FFDH r/w  b7>M-on , b6>in-use , b1>ds1 , b0>ds0  (all neg. logic)
7107FFEH         not used
7117FFFH read b7>drq , b6>intrq
712
713set on 7FFDH bit 2 always to 0 (some use it as disk change reset)
714
715*/
716
717static WRITE_LINE_DEVICE_HANDLER( msx_wd179x_intrq_w )
718{
719   msx_state *drvstate = device->machine().driver_data<msx_state>();
720   if (state)
721      drvstate->m_dsk_stat &= ~0x40;
722   else
723      drvstate->m_dsk_stat |= 0x40;
724}
725
726static WRITE_LINE_DEVICE_HANDLER( msx_wd179x_drq_w )
727{
728   msx_state *drvstate = device->machine().driver_data<msx_state>();
729   if (state)
730      drvstate->m_dsk_stat &= ~0x80;
731   else
732      drvstate->m_dsk_stat |= 0x80;
733}
734
735const wd17xx_interface msx_wd17xx_interface =
736{
737   DEVCB_LINE_VCC,
738   DEVCB_LINE(msx_wd179x_intrq_w),
739   DEVCB_LINE(msx_wd179x_drq_w),
740   {FLOPPY_0, FLOPPY_1, NULL, NULL}
741};
742
743FLOPPY_OPTIONS_START(msx)
744   FLOPPY_OPTION(msx, "dsk", "MSX SS", basicdsk_identify_default, basicdsk_construct_default, NULL,
745      HEADS([1])
746      TRACKS([80])
747      SECTORS([9])
748      SECTOR_LENGTH([512])
749      FIRST_SECTOR_ID([1]))
750   FLOPPY_OPTION(msx, "dsk", "MSX DS", basicdsk_identify_default, basicdsk_construct_default, NULL,
751      HEADS([2])
752      TRACKS([80])
753      SECTORS([9])
754      SECTOR_LENGTH([512])
755      FIRST_SECTOR_ID([1]))
756FLOPPY_OPTIONS_END
757
758/*
759** The PPI functions
760*/
761
762static WRITE8_DEVICE_HANDLER ( msx_ppi_port_a_w )
763{
764   msx_state *state = device->machine().driver_data<msx_state>();
765   state->m_primary_slot = data;
766
767   if (VERBOSE)
768      logerror ("write to primary slot select: %02x\n", state->m_primary_slot);
769   msx_memory_map_all (device->machine());
770}
771
772static WRITE8_DEVICE_HANDLER ( msx_ppi_port_c_w )
773{
774   msx_state *state = device->machine().driver_data<msx_state>();
775
776   state->keylatch = data & 0x0f;
777
778   /* caps lock */
779   if ( (state->m_port_c_old ^ data) & 0x40)
780      set_led_status (device->machine(),1, !(data & 0x40) );
781
782   /* key click */
783   if ( (state->m_port_c_old ^ data) & 0x80)
784      dac_signed_data_w (device->machine().device("dac"), (data & 0x80 ? 0x7f : 0));
785
786   /* cassette motor on/off */
787   if ( (state->m_port_c_old ^ data) & 0x10)
788      cassette_change_state(cassette_device_image(device->machine()),
789                  (data & 0x10) ? CASSETTE_MOTOR_DISABLED :
790                              CASSETTE_MOTOR_ENABLED,
791                  CASSETTE_MASK_MOTOR);
792
793   /* cassette signal write */
794   if ( (state->m_port_c_old ^ data) & 0x20)
795      cassette_output(cassette_device_image(device->machine()), (data & 0x20) ? -1.0 : 1.0);
796
797   state->m_port_c_old = data;
798}
799
800static READ8_DEVICE_HANDLER( msx_ppi_port_b_r )
801{
802   msx_state *state = device->machine().driver_data<msx_state>();
803   UINT8 result = 0xff;
804   int row, data;
805   static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5" };
806
807   row = state->keylatch;
808   if (row <= 10)
809   {
810      data = input_port_read(device->machine(), keynames[row / 2]);
811
812      if (row & 1)
813         data >>= 8;
814      result = data & 0xff;
815   }
816   return result;
817}
818
819/************************************************************************
820 *
821 * New memory emulation !!
822 *
823 ***********************************************************************/
824
825static void msx_memory_init (running_machine &machine)
826{
827   msx_state *state = machine.driver_data<msx_state>();
828   int   prim, sec, page, extent, option;
829   int size = 0;
830   const msx_slot_layout *layout= (msx_slot_layout*)NULL;
831   const msx_slot *slot;
832   const msx_driver_struct *driver;
833   slot_state *st;
834   UINT8 *mem = NULL;
835
836   state->m_empty = auto_alloc_array(machine, UINT8, 0x4000);
837   memset (state->m_empty, 0xff, 0x4000);
838
839   for (prim=0; prim<4; prim++) {
840      for (sec=0; sec<4; sec++) {
841         for (page=0; page<4; page++) {
842            state->m_all_state[prim][sec][page]= (slot_state*)NULL;
843         }
844      }
845   }
846
847   for (driver = msx_driver_list; driver->name[0]; driver++) {
848      if (!strcmp (driver->name, machine.system().name)) {
849         layout = driver->layout;
850      }
851   }
852
853   if (!layout) {
854      logerror ("msx_memory_init: error: missing layout definition in "
855              "msx_driver_list\n");
856      return;
857   }
858
859   state->layout = layout;
860
861   for (; layout->entry != MSX_LAYOUT_LAST; layout++) {
862
863      switch (layout->entry) {
864      case MSX_LAYOUT_SLOT_ENTRY:
865         prim = layout->slot_primary;
866         sec = layout->slot_secondary;
867         page = layout->slot_page;
868         extent = layout->page_extent;
869
870         if (layout->slot_secondary) {
871            state->m_slot_expanded[layout->slot_primary]= TRUE;
872         }
873
874         slot = &msx_slot_list[layout->type];
875         if (slot->slot_type != layout->type) {
876            logerror ("internal error: msx_slot_list[%d].type != %d\n",
877                     slot->slot_type, slot->slot_type);
878         }
879
880         size = layout->size;
881         option = layout->option;
882
883         if (VERBOSE)
884         {
885            logerror ("slot %d/%d/%d-%d: type %s, size 0x%x\n",
886               prim, sec, page, page + extent - 1, slot->name, size);
887         }
888
889         st = (slot_state*)NULL;
890         if (layout->type == SLOT_CARTRIDGE1) {
891            st = state->m_cart_state[0];
892            if (!st) {
893               slot = &msx_slot_list[SLOT_SOUNDCARTRIDGE];
894               size = 0x20000;
895            }
896         }
897         if (layout->type == SLOT_CARTRIDGE2) {
898            st = state->m_cart_state[1];
899            if (!st) {
900               /* Check whether the optional FM-PAC rom is present */
901               option = 0x10000;
902               size = 0x10000;
903               mem = machine.region("maincpu")->base() + option;
904               if (machine.region("maincpu")->bytes() >= size + option && mem[0] == 'A' && mem[1] == 'B') {
905                  slot = &msx_slot_list[SLOT_FMPAC];
906               }
907               else {
908                  slot = &msx_slot_list[SLOT_EMPTY];
909               }
910            }
911         }
912
913         if (!st) {
914            switch (slot->mem_type) {
915
916            case MSX_MEM_HANDLER:
917            case MSX_MEM_ROM:
918               mem = machine.region("maincpu")->base() + option;
919               break;
920            case MSX_MEM_RAM:
921               mem = NULL;
922               break;
923            }
924            st = auto_alloc_clear (machine, slot_state);
925            memset (st, 0, sizeof (slot_state));
926
927            if (slot->init (machine, st, layout->slot_page, mem, size)) {
928               continue;
929            }
930         }
931
932         while (extent--) {
933            if (page > 3) {
934               logerror ("internal error: msx_slot_layout wrong, "
935                   "page + extent > 3\n");
936               break;
937            }
938            state->m_all_state[prim][sec][page] = st;
939            page++;
940         }
941         break;
942      case MSX_LAYOUT_KANJI_ENTRY:
943         state->m_kanji_mem = machine.region("maincpu")->base() + layout->option;
944         break;
945      case MSX_LAYOUT_RAMIO_SET_BITS_ENTRY:
946         state->m_ramio_set_bits = (UINT8)layout->option;
947         break;
948      }
949   }
950}
951
952static void msx_memory_reset (running_machine &machine)
953{
954   msx_state *state = machine.driver_data<msx_state>();
955   slot_state *st, *last_st = (slot_state*)NULL;
956   int prim, sec, page;
957
958   state->m_primary_slot = 0;
959
960   for (prim=0; prim<4; prim++) {
961      state->m_secondary_slot[prim] = 0;
962      for (sec=0; sec<4; sec++) {
963         for (page=0; page<4; page++) {
964            st = state->m_all_state[prim][sec][page];
965            if (st && st != last_st) {
966               msx_slot_list[st->m_type].reset (machine, st);
967            }
968            last_st = st;
969         }
970      }
971   }
972}
973
974static void msx_memory_set_carts (running_machine &machine)
975{
976   msx_state *state = machine.driver_data<msx_state>();
977   const msx_slot_layout *layout;
978   int page;
979
980   if (!state->layout) {
981      return;
982   }
983
984   for (layout = state->layout; layout->entry != MSX_LAYOUT_LAST; layout++) {
985
986      if (layout->entry == MSX_LAYOUT_SLOT_ENTRY) {
987
988         switch (layout->type) {
989         case SLOT_CARTRIDGE1:
990            for (page=0; page<4; page++) {
991               state->m_all_state[layout->slot_primary]
992                          [layout->slot_secondary]
993                          [page] = state->m_cart_state[0];
994            }
995            break;
996         case SLOT_CARTRIDGE2:
997            for (page=0; page<4; page++) {
998               state->m_all_state[layout->slot_primary]
999                          [layout->slot_secondary]
1000                          [page] = state->m_cart_state[1];
1001            }
1002            break;
1003         }
1004      }
1005   }
1006}
1007
1008static void msx_memory_map_page (running_machine &machine, int page)
1009{
1010   msx_state *state = machine.driver_data<msx_state>();
1011   int slot_primary;
1012   int slot_secondary;
1013   slot_state *st;
1014   const msx_slot *slot;
1015
1016   slot_primary = (state->m_primary_slot >> (page * 2)) & 3;
1017   slot_secondary = (state->m_secondary_slot[slot_primary] >> (page * 2)) & 3;
1018
1019   st = state->m_all_state[slot_primary][slot_secondary][page];
1020   slot = st ? &msx_slot_list[st->m_type] : &msx_slot_list[SLOT_EMPTY];
1021   state->m_state[page] = st;
1022   state->m_slot[page] = slot;
1023
1024   if (VERBOSE)
1025   {
1026      logerror ("mapping %s in %d/%d/%d\n", slot->name, slot_primary,
1027         slot_secondary, page);
1028   }
1029   slot->map (machine, st, page);
1030}
1031
1032static void msx_memory_map_all (running_machine &machine)
1033{
1034   int i;
1035
1036   for (i=0; i<4; i++) {
1037      msx_memory_map_page (machine, i);
1038   }
1039}
1040
1041WRITE8_HANDLER (msx_page0_w)
1042{
1043   msx_state *state = space->machine().driver_data<msx_state>();
1044   if ( offset == 0 )
1045   {
1046      state->m_superloadrunner_bank = data;
1047      if (state->m_slot[2]->slot_type == SLOT_SUPERLOADRUNNER) {
1048         state->m_slot[2]->map (space->machine(), state->m_state[2], 2);
1049      }
1050   }
1051
1052   switch (state->m_slot[0]->mem_type) {
1053   case MSX_MEM_RAM:
1054      state->m_ram_pages[0][offset] = data;
1055      break;
1056   case MSX_MEM_HANDLER:
1057      state->m_slot[0]->write (space->machine(), state->m_state[0], offset, data);
1058   }
1059}
1060
1061WRITE8_HANDLER (msx_page0_1_w)
1062{
1063   msx_page0_w( space, 0x2000 + offset, data );
1064}
1065
1066WRITE8_HANDLER (msx_page1_w)
1067{
1068   msx_state *state = space->machine().driver_data<msx_state>();
1069   switch (state->m_slot[1]->mem_type) {
1070   case MSX_MEM_RAM:
1071      state->m_ram_pages[1][offset] = data;
1072      break;
1073   case MSX_MEM_HANDLER:
1074      state->m_slot[1]->write (space->machine(), state->m_state[1], 0x4000 + offset, data);
1075   }
1076}
1077
1078WRITE8_HANDLER (msx_page1_1_w)
1079{
1080   msx_page1_w( space, 0x2000 + offset, data );
1081}
1082
1083WRITE8_HANDLER (msx_page1_2_w)
1084{
1085   msx_page1_w( space, 0x3ff8 + offset, data );
1086}
1087
1088WRITE8_HANDLER (msx_page2_w)
1089{
1090   msx_state *state = space->machine().driver_data<msx_state>();
1091   switch (state->m_slot[2]->mem_type) {
1092   case MSX_MEM_RAM:
1093      state->m_ram_pages[2][offset] = data;
1094      break;
1095   case MSX_MEM_HANDLER:
1096      state->m_slot[2]->write (space->machine(), state->m_state[2], 0x8000 + offset, data);
1097   }
1098}
1099
1100WRITE8_HANDLER (msx_page2_1_w)
1101{
1102   msx_page2_w( space, 0x1800 + offset, data );
1103}
1104
1105WRITE8_HANDLER (msx_page2_2_w)
1106{
1107   msx_page2_w( space, 0x2000 + offset, data );
1108}
1109
1110WRITE8_HANDLER (msx_page2_3_w)
1111{
1112   msx_page2_w( space, 0x3800 + offset, data );
1113}
1114
1115WRITE8_HANDLER (msx_page3_w)
1116{
1117   msx_state *state = space->machine().driver_data<msx_state>();
1118   switch (state->m_slot[3]->mem_type) {
1119   case MSX_MEM_RAM:
1120      state->m_ram_pages[3][offset] = data;
1121      break;
1122   case MSX_MEM_HANDLER:
1123      state->m_slot[3]->write (space->machine(), state->m_state[3], 0xc000 + offset, data);
1124   }
1125}
1126
1127WRITE8_HANDLER (msx_page3_1_w)
1128{
1129   msx_page3_w( space, 0x2000 + offset, data );
1130}
1131
1132WRITE8_HANDLER (msx_sec_slot_w)
1133{
1134   msx_state *state = space->machine().driver_data<msx_state>();
1135   int slot = state->m_primary_slot >> 6;
1136   if (state->m_slot_expanded[slot])
1137   {
1138      if (VERBOSE)
1139         logerror ("write to secondary slot %d select: %02x\n", slot, data);
1140
1141      state->m_secondary_slot[slot] = data;
1142      msx_memory_map_all (space->machine());
1143   }
1144   else {
1145      msx_page3_w(space, 0x3fff, data);
1146   }
1147}
1148
1149READ8_HANDLER (msx_sec_slot_r)
1150{
1151   msx_state *state = space->machine().driver_data<msx_state>();
1152   UINT8 result;
1153   int slot = state->m_primary_slot >> 6;
1154
1155   if (state->m_slot_expanded[slot])
1156      result = ~state->m_secondary_slot[slot];
1157   else
1158      result = state->m_top_page[0x1fff];
1159
1160   return result;
1161}
1162
1163WRITE8_HANDLER (msx_ram_mapper_w)
1164{
1165   msx_state *state = space->machine().driver_data<msx_state>();
1166   state->m_ram_mapper[offset] = data;
1167   if (state->m_slot[offset]->slot_type == SLOT_RAM_MM) {
1168      state->m_slot[offset]->map (space->machine(), state->m_state[offset], offset);
1169   }
1170}
1171
1172READ8_HANDLER (msx_ram_mapper_r)
1173{
1174   msx_state *state = space->machine().driver_data<msx_state>();
1175   return state->m_ram_mapper[offset] | state->m_ramio_set_bits;
1176}
1177
1178WRITE8_HANDLER (msx_90in1_w)
1179{
1180   msx_state *state = space->machine().driver_data<msx_state>();
1181   state->m_korean90in1_bank = data;
1182   if (state->m_slot[1]->slot_type == SLOT_KOREAN_90IN1)
1183   {
1184      state->m_slot[1]->map (space->machine(), state->m_state[1], 1);
1185   }
1186   if (state->m_slot[2]->slot_type == SLOT_KOREAN_90IN1)
1187   {
1188      state->m_slot[2]->map (space->machine(), state->m_state[2], 2);
1189   }
1190}
1191
1192READ8_HANDLER (msx_kanji_r)
1193{
1194   msx_state *state = space->machine().driver_data<msx_state>();
1195   UINT8 result = 0xff;
1196
1197   if (offset && state->m_kanji_mem)
1198   {
1199      int latch;
1200      UINT8 ret;
1201
1202      latch = state->m_kanji_latch;
1203      ret = state->m_kanji_mem[latch++];
1204
1205      state->m_kanji_latch &= ~0x1f;
1206      state->m_kanji_latch |= latch & 0x1f;
1207
1208      result = ret;
1209   }
1210   return result;
1211}
1212
1213WRITE8_HANDLER (msx_kanji_w)
1214{
1215   msx_state *state = space->machine().driver_data<msx_state>();
1216   if (offset)
1217   {
1218      state->m_kanji_latch =
1219            (state->m_kanji_latch & 0x007E0) | ((data & 0x3f) << 11);
1220   }
1221   else
1222   {
1223      state->m_kanji_latch =
1224            (state->m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
1225   }
1226}
src/mame/includes/msx_slot.h
r11530r11531
1/*****************************************************************************
2 *
3 * includes/msx_slot.h
4 *
5 ****************************************************************************/
6
7#ifndef MSX_SLOT_H_
8#define MSX_SLOT_H_
9
10
11enum {
12   MSX_LAYOUT_SLOT_ENTRY,
13   MSX_LAYOUT_KANJI_ENTRY,
14   MSX_LAYOUT_RAMIO_SET_BITS_ENTRY,
15   MSX_LAYOUT_LAST
16};
17
18typedef struct {
19   int entry;
20   int type;
21   int slot_primary, slot_secondary, slot_page, page_extent;
22   int size, option;
23} msx_slot_layout;
24
25#define MSX_LAYOUT_INIT(msx) \
26static const msx_slot_layout msx_slot_layout_##msx[] = {
27
28#define MSX_LAYOUT_SLOT(prim, sec, page, extend, type, size, option) \
29   {                        \
30      MSX_LAYOUT_SLOT_ENTRY,      \
31      SLOT_##type,            \
32      prim,                  \
33      sec,                  \
34      page,                  \
35      extend,                  \
36      size,                  \
37      option                  \
38   },
39
40#define MSX_LAYOUT_KANJI(offset) \
41   {                        \
42      MSX_LAYOUT_KANJI_ENTRY,      \
43      SLOT_EMPTY,               \
44      0,                     \
45      0,                     \
46      0,                     \
47      0,                     \
48      0,                     \
49      offset                  \
50   },
51
52#define MSX_LAYOUT_RAMIO_SET_BITS(offset) \
53   {                        \
54      MSX_LAYOUT_RAMIO_SET_BITS_ENTRY,      \
55      SLOT_EMPTY,               \
56      0,                     \
57      0,                     \
58      0,                     \
59      0,                     \
60      0,                     \
61      offset                  \
62   },
63
64#define MSX_LAYOUT_END \
65   {                        \
66      MSX_LAYOUT_LAST,         \
67      SLOT_END,               \
68      0,                     \
69      0,                     \
70      0,                     \
71      0,                     \
72      0,                     \
73      0                     \
74   }                        \
75};
76
77
78enum msx_slot_type {
79   SLOT_EMPTY = 0,
80   SLOT_MSXDOS2,
81   SLOT_KONAMI_SCC,
82   SLOT_KONAMI,
83   SLOT_ASCII8,
84   SLOT_ASCII16,
85   SLOT_GAMEMASTER2,
86   SLOT_ASCII8_SRAM,
87   SLOT_ASCII16_SRAM,
88   SLOT_RTYPE,
89   SLOT_MAJUTSUSHI,
90   SLOT_FMPAC,
91   SLOT_SUPERLOADRUNNER,
92   SLOT_SYNTHESIZER,
93   SLOT_CROSS_BLAIM,
94   SLOT_DISK_ROM,
95   SLOT_KOREAN_80IN1,
96   SLOT_KOREAN_126IN1,
97   SLOT_KOREAN_90IN1,
98   SLOT_LAST_CARTRIDGE_TYPE = SLOT_KOREAN_90IN1,
99   SLOT_SOUNDCARTRIDGE,
100   SLOT_ROM,
101   SLOT_RAM,
102   SLOT_RAM_MM,
103   SLOT_CARTRIDGE1,
104   SLOT_CARTRIDGE2,
105        SLOT_DISK_ROM2,
106   SLOT_END
107};
108
109enum msx_mem_type {
110   MSX_MEM_ROM,
111   MSX_MEM_RAM,
112   MSX_MEM_HANDLER
113};
114
115typedef struct {
116   int m_type;
117   int m_start_page;
118   int m_bank_mask;
119   int m_banks[4];
120   int m_size;
121   UINT8 *m_mem;
122   const char *m_sramfile;
123   union {
124      struct {
125         UINT8 *mem;
126         int sram_support;
127         int sram_active;
128         int opll_active;
129      } fmpac;
130      struct {
131         int active;
132      } scc;
133      struct {
134         UINT8 *mem;
135         int sram_mask;
136         int empty_mask;
137      } sram;
138      struct {
139         int scc_active;
140         int sccp_active;
141         int ram_mode[4];
142         int banks_saved[4];
143         int mode;
144      } sccp;
145   } m_cart;
146} slot_state;
147
148typedef struct {
149   int slot_type;
150   int mem_type;
151   char name[32];
152   int (*init)(running_machine &machine, slot_state*, int page, UINT8 *mem, int size);
153   void (*reset)(running_machine &machine, slot_state*);
154   void (*map)(running_machine &machine, slot_state*, int page);
155   void (*write)(running_machine &machine, slot_state*, UINT16, UINT8);
156   int (*loadsram)(running_machine &machine, slot_state*);
157   int (*savesram)(running_machine &machine, slot_state*);
158} msx_slot;
159
160extern const msx_slot msx_slot_list[];
161
162#define MSX_SLOT_START \
163const msx_slot msx_slot_list[] = {
164
165#define MSX_SLOT_ROM(type, ent) { \
166   type,                     \
167   MSX_MEM_ROM,               \
168   #type,                     \
169   slot_##ent##_init,            \
170   slot_##ent##_reset,            \
171   slot_##ent##_map,            \
172   NULL,                     \
173   NULL,                     \
174   NULL                     \
175},
176
177#define MSX_SLOT_RAM(type, ent) { \
178   type,                     \
179   MSX_MEM_RAM,               \
180   #type,                     \
181   slot_##ent##_init,            \
182   slot_##ent##_reset,            \
183   slot_##ent##_map,            \
184   NULL,                     \
185   NULL,                     \
186   NULL                     \
187},
188
189#define MSX_SLOT(type, ent) { \
190   type,                     \
191   MSX_MEM_HANDLER,            \
192   #type,                     \
193   slot_##ent##_init,            \
194   slot_##ent##_reset,            \
195   slot_##ent##_map,            \
196   slot_##ent##_write,            \
197   NULL,                     \
198   NULL                     \
199},
200
201#define MSX_SLOT_SRAM(type, ent) { \
202   type,                     \
203   MSX_MEM_HANDLER,            \
204   #type,                     \
205   slot_##ent##_init,            \
206   slot_##ent##_reset,            \
207   slot_##ent##_map,            \
208   slot_##ent##_write,            \
209   slot_##ent##_loadsram,         \
210   slot_##ent##_savesram         \
211},
212
213#define MSX_SLOT_NULL(type) { \
214   type,                     \
215   MSX_MEM_ROM,               \
216   #type,                     \
217   NULL,                     \
218   NULL,                     \
219   NULL,                     \
220   NULL,                     \
221   NULL,                     \
222   NULL                     \
223},
224
225#define MSX_SLOT_END \
226   { SLOT_END, 0, "", NULL, NULL, NULL, NULL, NULL } \
227};
228
229#define MSX_SLOT_INIT(nm)          static int \
230   slot_##nm##_init (running_machine &machine, slot_state *state, int page, UINT8 *mem, int size)
231#define MSX_SLOT_MAP(nm)         \
232   static void slot_##nm##_map (running_machine &machine, slot_state *state, int page)
233#define MSX_SLOT_WRITE(nm)         \
234   static void slot_##nm##_write (running_machine &machine, slot_state *state, UINT16 addr, UINT8 val)
235#define MSX_SLOT_RESET(nm)         \
236   static void slot_##nm##_reset (running_machine &machine, slot_state *state)
237#define MSX_SLOT_LOADSRAM(nm)      \
238   static int slot_##nm##_loadsram (running_machine &machine, slot_state *state)
239#define MSX_SLOT_SAVESRAM(nm)      \
240   static int slot_##nm##_savesram (running_machine &machine, slot_state *state)
241
242typedef struct {
243   char name[9];
244   const msx_slot_layout *layout;
245} msx_driver_struct;
246
247extern const msx_driver_struct msx_driver_list[];
248
249#define MSX_DRIVER_LIST      \
250const msx_driver_struct msx_driver_list[] = {
251#define MSX_DRIVER(foo)      \
252      { #foo, msx_slot_layout_##foo },
253#define MSX_DRIVER_END      \
254      { "", NULL }      \
255};
256
257
258#endif /* MSX_SLOT_H_ */
src/mame/includes/msx.h
r11530r11531
1/*****************************************************************************
2 *
3 * includes/msx.h
4 *
5 ****************************************************************************/
6
7#ifndef __MSX_H__
8#define __MSX_H__
9
10#include "machine/wd17xx.h"
11#include "formats/flopimg.h"
12
13#define MSX_MAX_CARTS   (2)
14
15#define TC8521_TAG   "rtc"
16
17class msx_state : public driver_device
18{
19public:
20   msx_state(const machine_config &mconfig, device_type type, const char *tag)
21      : driver_device(mconfig, type, tag) { }
22
23   /* PSG */
24   int m_psg_b;
25   int m_opll_active;
26   /* mouse */
27   UINT16 m_mouse[2];
28   int m_mouse_stat[2];
29   /* rtc */
30   int m_rtc_latch;
31   /* disk */
32   UINT8 m_dsk_stat;
33   /* kanji */
34   UINT8 *m_kanji_mem;
35   int m_kanji_latch;
36   /* memory */
37   const msx_slot_layout *layout;
38   slot_state *m_cart_state[MSX_MAX_CARTS];
39   slot_state *m_state[4];
40   const msx_slot *m_slot[4];
41   UINT8 *m_ram_pages[4];
42   UINT8 *m_empty, m_ram_mapper[4];
43   UINT8 m_ramio_set_bits;
44   slot_state *m_all_state[4][4][4];
45   int m_slot_expanded[4];
46   UINT8 m_primary_slot;
47   UINT8 m_secondary_slot[4];
48   UINT8 m_superloadrunner_bank;
49   UINT8 m_korean90in1_bank;
50   UINT8 *m_top_page;
51   int m_port_c_old;
52   int keylatch;
53};
54
55
56/*----------- defined in machine/msx.c -----------*/
57
58extern const i8255_interface msx_ppi8255_interface;
59extern const wd17xx_interface msx_wd17xx_interface;
60/* start/stop functions */
61extern DRIVER_INIT( msx );
62extern MACHINE_START( msx );
63extern MACHINE_START( msx2 );
64extern MACHINE_RESET( msx );
65extern MACHINE_RESET( msx2 );
66extern INTERRUPT_GEN( msx_interrupt );
67extern INTERRUPT_GEN( msx2_interrupt );
68
69DEVICE_IMAGE_LOAD( msx_cart );
70DEVICE_IMAGE_UNLOAD( msx_cart );
71
72void msx_vdp_interrupt(running_machine &machine, int i);
73
74/* I/O functions */
75READ8_DEVICE_HANDLER( msx_printer_status_r );
76WRITE8_DEVICE_HANDLER( msx_printer_strobe_w );
77WRITE8_DEVICE_HANDLER( msx_printer_data_w );
78
79WRITE8_HANDLER ( msx_psg_port_a_w );
80READ8_HANDLER ( msx_psg_port_a_r );
81WRITE8_HANDLER ( msx_psg_port_b_w );
82READ8_HANDLER ( msx_psg_port_b_r );
83WRITE8_HANDLER ( msx_fmpac_w );
84READ8_HANDLER ( msx_rtc_reg_r );
85WRITE8_HANDLER ( msx_rtc_reg_w );
86WRITE8_HANDLER ( msx_rtc_latch_w );
87WRITE8_HANDLER ( msx_90in1_w );
88
89/* new memory emulation */
90WRITE8_HANDLER (msx_page0_w);
91WRITE8_HANDLER (msx_page0_1_w);
92WRITE8_HANDLER (msx_page1_w);
93WRITE8_HANDLER (msx_page1_1_w);
94WRITE8_HANDLER (msx_page1_2_w);
95WRITE8_HANDLER (msx_page2_w);
96WRITE8_HANDLER (msx_page2_1_w);
97WRITE8_HANDLER (msx_page2_2_w);
98WRITE8_HANDLER (msx_page2_3_w);
99WRITE8_HANDLER (msx_page3_w);
100WRITE8_HANDLER (msx_page3_1_w);
101WRITE8_HANDLER (msx_sec_slot_w);
102 READ8_HANDLER (msx_sec_slot_r);
103WRITE8_HANDLER (msx_ram_mapper_w);
104 READ8_HANDLER (msx_ram_mapper_r);
105 READ8_HANDLER (msx_kanji_r);
106WRITE8_HANDLER (msx_kanji_w);
107
108#endif /* __MSX_H__ */
src/mess/machine/msx.c
r0r11531
1/*
2 * msx.c: MSX emulation
3 *
4 * Copyright (C) 2004 Sean Young
5 *
6 * Todo:
7 *
8 * - fix mouse support
9 * - cassette support doesn't work
10 * - Ensure changing cartridge after boot works
11 * - wd2793, nms8255
12 */
13
14#include "emu.h"
15#include "machine/i8255.h"
16#include "includes/msx_slot.h"
17#include "includes/msx.h"
18#include "machine/rp5c01.h"
19#include "machine/wd17xx.h"
20#include "imagedev/flopdrv.h"
21#include "formats/basicdsk.h"
22#include "video/tms9928a.h"
23#include "cpu/z80/z80.h"
24#include "video/v9938.h"
25#include "machine/ctronics.h"
26#include "imagedev/cassette.h"
27#include "osdepend.h"
28#include "sound/ay8910.h"
29#include "sound/2413intf.h"
30#include "sound/dac.h"
31#include "hashfile.h"
32
33#define VERBOSE 0
34
35static void msx_memory_map_all (running_machine &machine);
36static void msx_memory_map_page (running_machine &machine, int page);
37static void msx_memory_init (running_machine &machine);
38static void msx_memory_set_carts (running_machine &machine);
39static void msx_memory_reset (running_machine &machine);
40
41
42
43static int msx_probe_type (UINT8* pmem, int size)
44{
45   int kon4, kon5, asc8, asc16, i;
46
47   if (size <= 0x10000) return 0;
48
49   if ( (pmem[0x10] == 'Y') && (pmem[0x11] == 'Z') && (size > 0x18000) )
50      return 6;
51
52   kon4 = kon5 = asc8 = asc16 = 0;
53
54   for (i=0;i<size-3;i++)
55   {
56      if (pmem[i] == 0x32 && pmem[i+1] == 0)
57      {
58         switch (pmem[i+2]) {
59         case 0x60:
60         case 0x70:
61            asc16++;
62            asc8++;
63            break;
64         case 0x68:
65         case 0x78:
66            asc8++;
67            asc16--;
68         }
69
70         switch (pmem[i+2]) {
71         case 0x60:
72         case 0x80:
73         case 0xa0:
74            kon4++;
75            break;
76         case 0x50:
77         case 0x70:
78         case 0x90:
79         case 0xb0:
80            kon5++;
81         }
82      }
83   }
84
85   if (MAX (kon4, kon5) > MAX (asc8, asc16) )
86      return (kon5 > kon4) ? 2 : 3;
87   else
88      return (asc8 > asc16) ? 4 : 5;
89}
90
91DEVICE_IMAGE_LOAD (msx_cart)
92{
93   msx_state *state = image.device().machine().driver_data<msx_state>();
94   int size;
95   int size_aligned;
96   UINT8 *mem;
97   int type;
98   const char *extra = NULL;
99   char *sramfile;
100   slot_state *st;
101   int id = -1;
102
103   if (strcmp(image.device().tag(),"cart1")==0) {
104      id = 0;
105   }
106   if (strcmp(image.device().tag(),"cart2")==0) {
107      id = 1;
108   }
109
110   if( id == -1 ) {
111      //logerror ("error: invalid cart tag '%s'\n", image->tag);
112      return IMAGE_INIT_FAIL;
113   }
114
115   size = image.length ();
116   if (size < 0x2000) {
117      logerror ("cart #%d: error: file is smaller than 2kb, too small "
118              "to be true!\n", id);
119      return IMAGE_INIT_FAIL;
120   }
121
122   /* allocate memory and load */
123   size_aligned = 0x2000;
124   while (size_aligned < size) {
125      size_aligned *= 2;
126   }
127   mem = (UINT8*)image.image_malloc(size_aligned);
128   if (!mem) {
129      logerror ("cart #%d: error: failed to allocate memory for cartridge\n",
130                  id);
131      return IMAGE_INIT_FAIL;
132   }
133   if (size < size_aligned) {
134      memset (mem, 0xff, size_aligned);
135   }
136   if (image.fread(mem, size) != size) {
137      logerror ("cart #%d: %s: can't read full %d bytes\n",
138                  id, image.filename (), size);
139      return IMAGE_INIT_FAIL;
140   }
141
142   /* see if msx.crc will tell us more */
143   extra = hashfile_extrainfo(image);
144
145   if (!extra)
146   {
147      logerror("cart #%d: warning: no information in crc file\n", id);
148      type = -1;
149   }
150   else if ((1 != sscanf(extra, "%d", &type) ) ||
151         type < 0 || type > SLOT_LAST_CARTRIDGE_TYPE)
152   {
153      logerror("cart #%d: warning: information in crc file not valid\n", id);
154      type = -1;
155   }
156   else
157   {
158      logerror ("cart #%d: info: cart extra info: '%s' = %s\n", id, extra,
159                  msx_slot_list[type].name);
160   }
161
162   /* if not, attempt autodetection */
163   if (type < 0)
164   {
165      type = msx_probe_type (mem, size);
166
167      if (mem[0] != 'A' || mem[1] != 'B') {
168         logerror("cart #%d: %s: May not be a valid ROM file\n",
169                     id, image.filename ());
170      }
171
172      logerror("cart #%d: Probed cartridge mapper %d/%s\n", id,
173                  type, msx_slot_list[type].name);
174   }
175
176   /* mapper type 0 always needs 64kB */
177   if (!type && size_aligned != 0x10000)
178   {
179      size_aligned = 0x10000;
180      mem = (UINT8*)image.image_realloc(mem, 0x10000);
181      if (!mem) {
182         logerror ("cart #%d: error: cannot allocate memory\n", id);
183         return IMAGE_INIT_FAIL;
184      }
185
186      if (size < 0x10000) {
187         memset (mem + size, 0xff, 0x10000 - size);
188      }
189      if (size > 0x10000) {
190         logerror ("cart #%d: warning: rom truncated to 64kb due to "
191                 "mapperless type (possibly detected)\n", id);
192
193         size = 0x10000;
194      }
195   }
196
197   /* mapper type 0 (ROM) might need moving around a bit */
198   if (!type) {
199      int i, page = 1;
200
201      /* find the correct page */
202      if (mem[0] == 'A' && mem[1] == 'B') {
203         for (i=2; i<=8; i += 2) {
204            if (mem[i] || mem[i+1]) {
205               page = mem[i+1] / 0x40;
206               break;
207            }
208         }
209      }
210
211      if (size <= 0x4000) {
212         if (page == 1 || page == 2) {
213            /* copy to the respective page */
214            memcpy (mem + (page * 0x4000), mem, 0x4000);
215            memset (mem, 0xff, 0x4000);
216         }
217         else {
218            /* memory is repeated 4 times */
219            page = -1;
220            memcpy (mem + 0x4000, mem, 0x4000);
221            memcpy (mem + 0x8000, mem, 0x4000);
222            memcpy (mem + 0xc000, mem, 0x4000);
223         }
224      }
225      else /*if (size <= 0xc000) */ {
226         if (page) {
227            /* shift up 16kB; custom memcpy so overlapping memory
228                   isn't corrupted. ROM starts in page 1 (0x4000) */
229            UINT8 *m;
230
231            page = 1;
232            i = 0xc000; m = mem + 0xffff;
233            while (i--) {
234               *m = *(m - 0x4000); m--;
235            }
236            memset (mem, 0xff, 0x4000);
237         }
238      }
239
240      if (page) {
241         logerror ("cart #%d: info: rom in page %d\n", id, page);
242      }
243      else {
244         logerror ("cart #%d: info: rom duplicted in all pages\n", id);
245      }
246   }
247
248   /* kludge */
249   if (type == 0) {
250      type = SLOT_ROM;
251   }
252
253   /* allocate and set slot_state for this cartridge */
254   st = (slot_state*) image.image_malloc(sizeof (slot_state));
255   if (!st)
256   {
257      logerror ("cart #%d: error: cannot allocate memory for "
258              "cartridge state\n", id);
259      return IMAGE_INIT_FAIL;
260   }
261   memset (st, 0, sizeof (slot_state));
262
263   st->m_type = type;
264   sramfile = (char*)image.image_malloc(strlen (image.filename () + 1));
265
266   if (sramfile) {
267      char *ext;
268
269      strcpy (sramfile, image.basename ());
270      ext = strrchr (sramfile, '.');
271      if (ext) {
272         *ext = 0;
273      }
274      st->m_sramfile = sramfile;
275   }
276
277   if (msx_slot_list[type].init (image.device().machine(), st, 0, mem, size_aligned)) {
278      return IMAGE_INIT_FAIL;
279   }
280   if (msx_slot_list[type].loadsram) {
281      msx_slot_list[type].loadsram (image.device().machine(), st);
282   }
283
284   state->m_cart_state[id] = st;
285   msx_memory_set_carts (image.device().machine());
286
287   return IMAGE_INIT_PASS;
288}
289
290DEVICE_IMAGE_UNLOAD (msx_cart)
291{
292   msx_state *state = image.device().machine().driver_data<msx_state>();
293   int id = -1;
294
295   if (strcmp(image.device().tag(),"cart1")==0) {
296      id = 0;
297   }
298   if (strcmp(image.device().tag(),"cart2")==0) {
299      id = 1;
300   }
301
302   if( id == -1 ) {
303      //logerror ("error: invalid cart tag '%s'\n", image->tag);
304      return;
305   }
306
307   if (msx_slot_list[state->m_cart_state[id]->m_type].savesram)
308   {
309      msx_slot_list[state->m_cart_state[id]->m_type].savesram (image.device().machine(), state->m_cart_state[id]);
310   }
311}
312
313void msx_vdp_interrupt(running_machine &machine, int i)
314{
315   cputag_set_input_line (machine, "maincpu", 0, (i ? HOLD_LINE : CLEAR_LINE));
316}
317
318static void msx_ch_reset_core (running_machine &machine)
319{
320   msx_memory_reset (machine);
321   msx_memory_map_all (machine);
322}
323
324static const TMS9928a_interface tms9928a_interface =
325{
326   TMS99x8A,
327   0x4000,
328   0, 0,
329   msx_vdp_interrupt
330};
331
332MACHINE_START( msx )
333{
334   TMS9928A_configure(&tms9928a_interface);
335   MACHINE_START_CALL( msx2 );
336}
337
338MACHINE_START( msx2 )
339{
340   msx_state *state = machine.driver_data<msx_state>();
341   state->m_port_c_old = 0xff;
342   state->m_dsk_stat = 0x7f;
343}
344
345MACHINE_RESET( msx )
346{
347   TMS9928A_reset ();
348   msx_ch_reset_core (machine);
349}
350
351MACHINE_RESET( msx2 )
352{
353   v9938_reset (0);
354   msx_ch_reset_core (machine);
355}
356
357static WRITE8_DEVICE_HANDLER ( msx_ppi_port_a_w );
358static WRITE8_DEVICE_HANDLER ( msx_ppi_port_c_w );
359static READ8_DEVICE_HANDLER (msx_ppi_port_b_r );
360
361I8255_INTERFACE( msx_ppi8255_interface )
362{
363   DEVCB_NULL,
364   DEVCB_HANDLER(msx_ppi_port_a_w),
365   DEVCB_HANDLER(msx_ppi_port_b_r),
366   DEVCB_NULL,
367   DEVCB_NULL,
368   DEVCB_HANDLER(msx_ppi_port_c_w)
369};
370
371
372static const UINT8 cc_op[0x100] = {
373 4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
374 8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
375 7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1,
376 7+1,10+1,13+1, 6+1,11+1,11+1,10+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1,
377 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
378 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
379 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
380 7+1, 7+1, 7+1, 7+1, 7+1, 7+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
381 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
382 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
383 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
384 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
385 5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 0+1,10+1,17+1, 7+1,11+1,
386 5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 0+1, 7+1,11+1,
387 5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 0+1, 7+1,11+1,
388 5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 0+1, 7+1,11+1
389};
390
391static const UINT8 cc_cb[0x100] = {
392 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
393 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
394 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
395 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
396 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
397 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
398 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
399 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
400 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
401 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
402 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
403 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
404 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
405 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
406 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
407 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2
408};
409
410static const UINT8 cc_ed[0x100] = {
411 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
412 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
413 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
414 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
41512+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
41612+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
41712+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,
41812+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,
419 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
420 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
42116+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
42216+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
423 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
424 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
425 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
426 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2
427};
428
429static const UINT8 cc_xy[0x100] = {
430 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
431 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
432 4+2,14+2,20+2,10+2, 9+2, 9+2, 9+2, 4+2, 4+2,15+2,20+2,10+2, 9+2, 9+2, 9+2, 4+2,
433 4+2, 4+2, 4+2, 4+2,23+2,23+2,19+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
434 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
435 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
436 9+2, 9+2, 9+2, 9+2, 9+2, 9+2,19+2, 9+2, 9+2, 9+2, 9+2, 9+2, 9+2, 9+2,19+2, 9+2,
43719+2,19+2,19+2,19+2,19+2,19+2, 4+2,19+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
438 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
439 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
440 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
441 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
442 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 0+2, 4+2, 4+2, 4+2, 4+2,
443 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
444 4+2,14+2, 4+2,23+2, 4+2,15+2, 4+2, 4+2, 4+2, 8+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
445 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,10+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2
446};
447
448static const UINT8 cc_xycb[0x100] = {
44923+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45023+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45123+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45223+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45320+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45420+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45520+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45620+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
45723+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45823+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
45923+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46023+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46123+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46223+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46323+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
46423+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2
465};
466
467/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
468static const UINT8 cc_ex[0x100] = {
469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
470 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   /* DJNZ */
471 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,   /* JR NZ/JR Z */
472 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,   /* JR NC/JR C */
473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
474 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
475 0, 0, 0, 0, 0, 0, 0+1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
476 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
477 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
479 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
480 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0,   /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
481 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
482 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
483 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
484 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2+1
485};
486
487
488DRIVER_INIT( msx )
489{
490   device_set_input_line_vector (machine.device("maincpu"), 0, 0xff);
491
492   msx_memory_init (machine);
493
494   z80_set_cycle_tables( machine.device("maincpu"), cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex );
495}
496
497INTERRUPT_GEN( msx2_interrupt )
498{
499   v9938_set_sprite_limit(0, input_port_read(device->machine(), "DSW") & 0x20);
500   v9938_set_resolution(0, input_port_read(device->machine(), "DSW") & 0x03);
501   v9938_interrupt(device->machine(), 0);
502}
503
504INTERRUPT_GEN( msx_interrupt )
505{
506   msx_state *state = device->machine().driver_data<msx_state>();
507   int i;
508
509   for (i=0; i<2; i++)
510   {
511      state->m_mouse[i] = input_port_read(device->machine(), i ? "MOUSE1" : "MOUSE0");
512      state->m_mouse_stat[i] = -1;
513   }
514
515   TMS9928A_set_spriteslimit (input_port_read(device->machine(), "DSW") & 0x20);
516   TMS9928A_interrupt(device->machine());
517}
518
519/*
520** The I/O funtions
521*/
522
523static device_t *cassette_device_image(running_machine &machine)
524{
525   return machine.device("cassette");
526}
527
528READ8_HANDLER ( msx_psg_port_a_r )
529{
530   msx_state *state = space->machine().driver_data<msx_state>();
531   int data, inp;
532
533   data = (cassette_input(cassette_device_image(space->machine())) > 0.0038 ? 0x80 : 0);
534
535   if ( (state->m_psg_b ^ input_port_read(space->machine(), "DSW") ) & 0x40)
536      {
537      /* game port 2 */
538      inp = input_port_read(space->machine(), "JOY1") & 0x7f;
539#if 0
540      if ( !(inp & 0x80) )
541         {
542#endif
543         /* joystick */
544         return (inp & 0x7f) | data;
545#if 0
546         }
547      else
548         {
549         /* mouse */
550         data |= inp & 0x70;
551         if (state->m_mouse_stat[1] < 0)
552            inp = 0xf;
553         else
554            inp = ~(state->m_mouse[1] >> (4*state->m_mouse_stat[1]) ) & 15;
555
556         return data | inp;
557         }
558#endif
559      }
560   else
561      {
562      /* game port 1 */
563      inp = input_port_read(space->machine(), "JOY0") & 0x7f;
564#if 0
565      if ( !(inp & 0x80) )
566         {
567#endif
568         /* joystick */
569         return (inp & 0x7f) | data;
570#if 0
571         }
572      else
573         {
574         /* mouse */
575         data |= inp & 0x70;
576         if (state->m_mouse_stat[0] < 0)
577            inp = 0xf;
578         else
579            inp = ~(state->m_mouse[0] >> (4*state->m_mouse_stat[0]) ) & 15;
580
581         return data | inp;
582         }
583#endif
584      }
585
586   return 0;
587}
588
589READ8_HANDLER ( msx_psg_port_b_r )
590{
591   msx_state *state = space->machine().driver_data<msx_state>();
592   return state->m_psg_b;
593}
594
595WRITE8_HANDLER ( msx_psg_port_a_w )
596{
597}
598
599WRITE8_HANDLER ( msx_psg_port_b_w )
600{
601   msx_state *state = space->machine().driver_data<msx_state>();
602   /* Arabic or kana mode led */
603   if ( (data ^ state->m_psg_b) & 0x80)
604      set_led_status (space->machine(), 2, !(data & 0x80) );
605
606   if ( (state->m_psg_b ^ data) & 0x10)
607   {
608      if (++state->m_mouse_stat[0] > 3) state->m_mouse_stat[0] = -1;
609   }
610   if ( (state->m_psg_b ^ data) & 0x20)
611   {
612      if (++state->m_mouse_stat[1] > 3) state->m_mouse_stat[1] = -1;
613   }
614
615   state->m_psg_b = data;
616}
617
618WRITE8_DEVICE_HANDLER( msx_printer_strobe_w )
619{
620   centronics_strobe_w(device, BIT(data, 1));
621}
622
623WRITE8_DEVICE_HANDLER( msx_printer_data_w )
624{
625   if (input_port_read(device->machine(), "DSW") & 0x80)
626   {
627      /* SIMPL emulation */
628      dac_signed_data_w(device->machine().device("dac"), data);
629   }
630   else
631   {
632      centronics_data_w(device, 0, data);
633   }
634}
635
636READ8_DEVICE_HANDLER( msx_printer_status_r )
637{
638   UINT8 result = 0xfd;
639
640   if (input_port_read(device->machine(), "DSW") & 0x80)
641      return 0xff;
642
643   result |= centronics_busy_r(device) << 1;
644
645   return result;
646}
647
648WRITE8_HANDLER (msx_fmpac_w)
649{
650   msx_state *state = space->machine().driver_data<msx_state>();
651   if (state->m_opll_active)
652   {
653      device_t *ym = space->machine().device("ym2413");
654
655      if (offset == 1)
656         ym2413_w (ym, 1, data);
657      else
658         ym2413_w (ym, 0, data);
659   }
660}
661
662/*
663** RTC functions
664*/
665
666WRITE8_HANDLER (msx_rtc_latch_w)
667{
668   msx_state *state = space->machine().driver_data<msx_state>();
669   state->m_rtc_latch = data & 15;
670}
671
672WRITE8_HANDLER (msx_rtc_reg_w)
673{
674   msx_state *state = space->machine().driver_data<msx_state>();
675   rp5c01_device *rtc = space->machine().device<rp5c01_device>(TC8521_TAG);
676   rtc->write(*space, state->m_rtc_latch, data);
677}
678
679READ8_HANDLER (msx_rtc_reg_r)
680{
681   msx_state *state = space->machine().driver_data<msx_state>();
682   rp5c01_device *rtc = space->machine().device<rp5c01_device>(TC8521_TAG);
683   return rtc->read(*space, state->m_rtc_latch);
684}
685
686/*
687From: erbo@xs4all.nl (erik de boer)
688
689sony and philips have used (almost) the same design
690and this is the memory layout
691but it is not a msx standard !
692
693WD1793 or wd2793 registers
694
695adress
696
6977FF8H read  status register
698      write command register
6997FF9H  r/w  track register (r/o on NMS 8245 and Sony)
7007FFAH  r/w  sector register (r/o on NMS 8245 and Sony)
7017FFBH  r/w  data register
702
703
704hardware registers
705
706adress
707
7087FFCH r/w  bit 0 side select
7097FFDH r/w  b7>M-on , b6>in-use , b1>ds1 , b0>ds0  (all neg. logic)
7107FFEH         not used
7117FFFH read b7>drq , b6>intrq
712
713set on 7FFDH bit 2 always to 0 (some use it as disk change reset)
714
715*/
716
717static WRITE_LINE_DEVICE_HANDLER( msx_wd179x_intrq_w )
718{
719   msx_state *drvstate = device->machine().driver_data<msx_state>();
720   if (state)
721      drvstate->m_dsk_stat &= ~0x40;
722   else
723      drvstate->m_dsk_stat |= 0x40;
724}
725
726static WRITE_LINE_DEVICE_HANDLER( msx_wd179x_drq_w )
727{
728   msx_state *drvstate = device->machine().driver_data<msx_state>();
729   if (state)
730      drvstate->m_dsk_stat &= ~0x80;
731   else
732      drvstate->m_dsk_stat |= 0x80;
733}
734
735const wd17xx_interface msx_wd17xx_interface =
736{
737   DEVCB_LINE_VCC,
738   DEVCB_LINE(msx_wd179x_intrq_w),
739   DEVCB_LINE(msx_wd179x_drq_w),
740   {FLOPPY_0, FLOPPY_1, NULL, NULL}
741};
742
743FLOPPY_OPTIONS_START(msx)
744   FLOPPY_OPTION(msx, "dsk", "MSX SS", basicdsk_identify_default, basicdsk_construct_default, NULL,
745      HEADS([1])
746      TRACKS([80])
747      SECTORS([9])
748      SECTOR_LENGTH([512])
749      FIRST_SECTOR_ID([1]))
750   FLOPPY_OPTION(msx, "dsk", "MSX DS", basicdsk_identify_default, basicdsk_construct_default, NULL,
751      HEADS([2])
752      TRACKS([80])
753      SECTORS([9])
754      SECTOR_LENGTH([512])
755      FIRST_SECTOR_ID([1]))
756FLOPPY_OPTIONS_END
757
758/*
759** The PPI functions
760*/
761
762static WRITE8_DEVICE_HANDLER ( msx_ppi_port_a_w )
763{
764   msx_state *state = device->machine().driver_data<msx_state>();
765   state->m_primary_slot = data;
766
767   if (VERBOSE)
768      logerror ("write to primary slot select: %02x\n", state->m_primary_slot);
769   msx_memory_map_all (device->machine());
770}
771
772static WRITE8_DEVICE_HANDLER ( msx_ppi_port_c_w )
773{
774   msx_state *state = device->machine().driver_data<msx_state>();
775
776   state->keylatch = data & 0x0f;
777
778   /* caps lock */
779   if ( (state->m_port_c_old ^ data) & 0x40)
780      set_led_status (device->machine(),1, !(data & 0x40) );
781
782   /* key click */
783   if ( (state->m_port_c_old ^ data) & 0x80)
784      dac_signed_data_w (device->machine().device("dac"), (data & 0x80 ? 0x7f : 0));
785
786   /* cassette motor on/off */
787   if ( (state->m_port_c_old ^ data) & 0x10)
788      cassette_change_state(cassette_device_image(device->machine()),
789                  (data & 0x10) ? CASSETTE_MOTOR_DISABLED :
790                              CASSETTE_MOTOR_ENABLED,
791                  CASSETTE_MASK_MOTOR);
792
793   /* cassette signal write */
794   if ( (state->m_port_c_old ^ data) & 0x20)
795      cassette_output(cassette_device_image(device->machine()), (data & 0x20) ? -1.0 : 1.0);
796
797   state->m_port_c_old = data;
798}
799
800static READ8_DEVICE_HANDLER( msx_ppi_port_b_r )
801{
802   msx_state *state = device->machine().driver_data<msx_state>();
803   UINT8 result = 0xff;
804   int row, data;
805   static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5" };
806
807   row = state->keylatch;
808   if (row <= 10)
809   {
810      data = input_port_read(device->machine(), keynames[row / 2]);
811
812      if (row & 1)
813         data >>= 8;
814      result = data & 0xff;
815   }
816   return result;
817}
818
819/************************************************************************
820 *
821 * New memory emulation !!
822 *
823 ***********************************************************************/
824
825static void msx_memory_init (running_machine &machine)
826{
827   msx_state *state = machine.driver_data<msx_state>();
828   int   prim, sec, page, extent, option;
829   int size = 0;
830   const msx_slot_layout *layout= (msx_slot_layout*)NULL;
831   const msx_slot *slot;
832   const msx_driver_struct *driver;
833   slot_state *st;
834   UINT8 *mem = NULL;
835
836   state->m_empty = auto_alloc_array(machine, UINT8, 0x4000);
837   memset (state->m_empty, 0xff, 0x4000);
838
839   for (prim=0; prim<4; prim++) {
840      for (sec=0; sec<4; sec++) {
841         for (page=0; page<4; page++) {
842            state->m_all_state[prim][sec][page]= (slot_state*)NULL;
843         }
844      }
845   }
846
847   for (driver = msx_driver_list; driver->name[0]; driver++) {
848      if (!strcmp (driver->name, machine.system().name)) {
849         layout = driver->layout;
850      }
851   }
852
853   if (!layout) {
854      logerror ("msx_memory_init: error: missing layout definition in "
855              "msx_driver_list\n");
856      return;
857   }
858
859   state->layout = layout;
860
861   for (; layout->entry != MSX_LAYOUT_LAST; layout++) {
862
863      switch (layout->entry) {
864      case MSX_LAYOUT_SLOT_ENTRY:
865         prim = layout->slot_primary;
866         sec = layout->slot_secondary;
867         page = layout->slot_page;
868         extent = layout->page_extent;
869
870         if (layout->slot_secondary) {
871            state->m_slot_expanded[layout->slot_primary]= TRUE;
872         }
873
874         slot = &msx_slot_list[layout->type];
875         if (slot->slot_type != layout->type) {
876            logerror ("internal error: msx_slot_list[%d].type != %d\n",
877                     slot->slot_type, slot->slot_type);
878         }
879
880         size = layout->size;
881         option = layout->option;
882
883         if (VERBOSE)
884         {
885            logerror ("slot %d/%d/%d-%d: type %s, size 0x%x\n",
886               prim, sec, page, page + extent - 1, slot->name, size);
887         }
888
889         st = (slot_state*)NULL;
890         if (layout->type == SLOT_CARTRIDGE1) {
891            st = state->m_cart_state[0];
892            if (!st) {
893               slot = &msx_slot_list[SLOT_SOUNDCARTRIDGE];
894               size = 0x20000;
895            }
896         }
897         if (layout->type == SLOT_CARTRIDGE2) {
898            st = state->m_cart_state[1];
899            if (!st) {
900               /* Check whether the optional FM-PAC rom is present */
901               option = 0x10000;
902               size = 0x10000;
903               mem = machine.region("maincpu")->base() + option;
904               if (machine.region("maincpu")->bytes() >= size + option && mem[0] == 'A' && mem[1] == 'B') {
905                  slot = &msx_slot_list[SLOT_FMPAC];
906               }
907               else {
908                  slot = &msx_slot_list[SLOT_EMPTY];
909               }
910            }
911         }
912
913         if (!st) {
914            switch (slot->mem_type) {
915
916            case MSX_MEM_HANDLER:
917            case MSX_MEM_ROM:
918               mem = machine.region("maincpu")->base() + option;
919               break;
920            case MSX_MEM_RAM:
921               mem = NULL;
922               break;
923            }
924            st = auto_alloc_clear (machine, slot_state);
925            memset (st, 0, sizeof (slot_state));
926
927            if (slot->init (machine, st, layout->slot_page, mem, size)) {
928               continue;
929            }
930         }
931
932         while (extent--) {
933            if (page > 3) {
934               logerror ("internal error: msx_slot_layout wrong, "
935                   "page + extent > 3\n");
936               break;
937            }
938            state->m_all_state[prim][sec][page] = st;
939            page++;
940         }
941         break;
942      case MSX_LAYOUT_KANJI_ENTRY:
943         state->m_kanji_mem = machine.region("maincpu")->base() + layout->option;
944         break;
945      case MSX_LAYOUT_RAMIO_SET_BITS_ENTRY:
946         state->m_ramio_set_bits = (UINT8)layout->option;
947         break;
948      }
949   }
950}
951
952static void msx_memory_reset (running_machine &machine)
953{
954   msx_state *state = machine.driver_data<msx_state>();
955   slot_state *st, *last_st = (slot_state*)NULL;
956   int prim, sec, page;
957
958   state->m_primary_slot = 0;
959
960   for (prim=0; prim<4; prim++) {
961      state->m_secondary_slot[prim] = 0;
962      for (sec=0; sec<4; sec++) {
963         for (page=0; page<4; page++) {
964            st = state->m_all_state[prim][sec][page];
965            if (st && st != last_st) {
966               msx_slot_list[st->m_type].reset (machine, st);
967            }
968            last_st = st;
969         }
970      }
971   }
972}
973
974static void msx_memory_set_carts (running_machine &machine)
975{
976   msx_state *state = machine.driver_data<msx_state>();
977   const msx_slot_layout *layout;
978   int page;
979
980   if (!state->layout) {
981      return;
982   }
983
984   for (layout = state->layout; layout->entry != MSX_LAYOUT_LAST; layout++) {
985
986      if (layout->entry == MSX_LAYOUT_SLOT_ENTRY) {
987
988         switch (layout->type) {
989         case SLOT_CARTRIDGE1:
990            for (page=0; page<4; page++) {
991               state->m_all_state[layout->slot_primary]
992                          [layout->slot_secondary]
993                          [page] = state->m_cart_state[0];
994            }
995            break;
996         case SLOT_CARTRIDGE2:
997            for (page=0; page<4; page++) {
998               state->m_all_state[layout->slot_primary]
999                          [layout->slot_secondary]
1000                          [page] = state->m_cart_state[1];
1001            }
1002            break;
1003         }
1004      }
1005   }
1006}
1007
1008static void msx_memory_map_page (running_machine &machine, int page)
1009{
1010   msx_state *state = machine.driver_data<msx_state>();
1011   int slot_primary;
1012   int slot_secondary;
1013   slot_state *st;
1014   const msx_slot *slot;
1015
1016   slot_primary = (state->m_primary_slot >> (page * 2)) & 3;
1017   slot_secondary = (state->m_secondary_slot[slot_primary] >> (page * 2)) & 3;
1018
1019   st = state->m_all_state[slot_primary][slot_secondary][page];
1020   slot = st ? &msx_slot_list[st->m_type] : &msx_slot_list[SLOT_EMPTY];
1021   state->m_state[page] = st;
1022   state->m_slot[page] = slot;
1023
1024   if (VERBOSE)
1025   {
1026      logerror ("mapping %s in %d/%d/%d\n", slot->name, slot_primary,
1027         slot_secondary, page);
1028   }
1029   slot->map (machine, st, page);
1030}
1031
1032static void msx_memory_map_all (running_machine &machine)
1033{
1034   int i;
1035
1036   for (i=0; i<4; i++) {
1037      msx_memory_map_page (machine, i);
1038   }
1039}
1040
1041WRITE8_HANDLER (msx_page0_w)
1042{
1043   msx_state *state = space->machine().driver_data<msx_state>();
1044   if ( offset == 0 )
1045   {
1046      state->m_superloadrunner_bank = data;
1047      if (state->m_slot[2]->slot_type == SLOT_SUPERLOADRUNNER) {
1048         state->m_slot[2]->map (space->machine(), state->m_state[2], 2);
1049      }
1050   }
1051
1052   switch (state->m_slot[0]->mem_type) {
1053   case MSX_MEM_RAM:
1054      state->m_ram_pages[0][offset] = data;
1055      break;
1056   case MSX_MEM_HANDLER:
1057      state->m_slot[0]->write (space->machine(), state->m_state[0], offset, data);
1058   }
1059}
1060
1061WRITE8_HANDLER (msx_page0_1_w)
1062{
1063   msx_page0_w( space, 0x2000 + offset, data );
1064}
1065
1066WRITE8_HANDLER (msx_page1_w)
1067{
1068   msx_state *state = space->machine().driver_data<msx_state>();
1069   switch (state->m_slot[1]->mem_type) {
1070   case MSX_MEM_RAM:
1071      state->m_ram_pages[1][offset] = data;
1072      break;
1073   case MSX_MEM_HANDLER:
1074      state->m_slot[1]->write (space->machine(), state->m_state[1], 0x4000 + offset, data);
1075   }
1076}
1077
1078WRITE8_HANDLER (msx_page1_1_w)
1079{
1080   msx_page1_w( space, 0x2000 + offset, data );
1081}
1082
1083WRITE8_HANDLER (msx_page1_2_w)
1084{
1085   msx_page1_w( space, 0x3ff8 + offset, data );
1086}
1087
1088WRITE8_HANDLER (msx_page2_w)
1089{
1090   msx_state *state = space->machine().driver_data<msx_state>();
1091   switch (state->m_slot[2]->mem_type) {
1092   case MSX_MEM_RAM:
1093      state->m_ram_pages[2][offset] = data;
1094      break;
1095   case MSX_MEM_HANDLER:
1096      state->m_slot[2]->write (space->machine(), state->m_state[2], 0x8000 + offset, data);
1097   }
1098}
1099
1100WRITE8_HANDLER (msx_page2_1_w)
1101{
1102   msx_page2_w( space, 0x1800 + offset, data );
1103}
1104
1105WRITE8_HANDLER (msx_page2_2_w)
1106{
1107   msx_page2_w( space, 0x2000 + offset, data );
1108}
1109
1110WRITE8_HANDLER (msx_page2_3_w)
1111{
1112   msx_page2_w( space, 0x3800 + offset, data );
1113}
1114
1115WRITE8_HANDLER (msx_page3_w)
1116{
1117   msx_state *state = space->machine().driver_data<msx_state>();
1118   switch (state->m_slot[3]->mem_type) {
1119   case MSX_MEM_RAM:
1120      state->m_ram_pages[3][offset] = data;
1121      break;
1122   case MSX_MEM_HANDLER:
1123      state->m_slot[3]->write (space->machine(), state->m_state[3], 0xc000 + offset, data);
1124   }
1125}
1126
1127WRITE8_HANDLER (msx_page3_1_w)
1128{
1129   msx_page3_w( space, 0x2000 + offset, data );
1130}
1131
1132WRITE8_HANDLER (msx_sec_slot_w)
1133{
1134   msx_state *state = space->machine().driver_data<msx_state>();
1135   int slot = state->m_primary_slot >> 6;
1136   if (state->m_slot_expanded[slot])
1137   {
1138      if (VERBOSE)
1139         logerror ("write to secondary slot %d select: %02x\n", slot, data);
1140
1141      state->m_secondary_slot[slot] = data;
1142      msx_memory_map_all (space->machine());
1143   }
1144   else {
1145      msx_page3_w(space, 0x3fff, data);
1146   }
1147}
1148
1149READ8_HANDLER (msx_sec_slot_r)
1150{
1151   msx_state *state = space->machine().driver_data<msx_state>();
1152   UINT8 result;
1153   int slot = state->m_primary_slot >> 6;
1154
1155   if (state->m_slot_expanded[slot])
1156      result = ~state->m_secondary_slot[slot];
1157   else
1158      result = state->m_top_page[0x1fff];
1159
1160   return result;
1161}
1162
1163WRITE8_HANDLER (msx_ram_mapper_w)
1164{
1165   msx_state *state = space->machine().driver_data<msx_state>();
1166   state->m_ram_mapper[offset] = data;
1167   if (state->m_slot[offset]->slot_type == SLOT_RAM_MM) {
1168      state->m_slot[offset]->map (space->machine(), state->m_state[offset], offset);
1169   }
1170}
1171
1172READ8_HANDLER (msx_ram_mapper_r)
1173{
1174   msx_state *state = space->machine().driver_data<msx_state>();
1175   return state->m_ram_mapper[offset] | state->m_ramio_set_bits;
1176}
1177
1178WRITE8_HANDLER (msx_90in1_w)
1179{
1180   msx_state *state = space->machine().driver_data<msx_state>();
1181   state->m_korean90in1_bank = data;
1182   if (state->m_slot[1]->slot_type == SLOT_KOREAN_90IN1)
1183   {
1184      state->m_slot[1]->map (space->machine(), state->m_state[1], 1);
1185   }
1186   if (state->m_slot[2]->slot_type == SLOT_KOREAN_90IN1)
1187   {
1188      state->m_slot[2]->map (space->machine(), state->m_state[2], 2);
1189   }
1190}
1191
1192READ8_HANDLER (msx_kanji_r)
1193{
1194   msx_state *state = space->machine().driver_data<msx_state>();
1195   UINT8 result = 0xff;
1196
1197   if (offset && state->m_kanji_mem)
1198   {
1199      int latch;
1200      UINT8 ret;
1201
1202      latch = state->m_kanji_latch;
1203      ret = state->m_kanji_mem[latch++];
1204
1205      state->m_kanji_latch &= ~0x1f;
1206      state->m_kanji_latch |= latch & 0x1f;
1207
1208      result = ret;
1209   }
1210   return result;
1211}
1212
1213WRITE8_HANDLER (msx_kanji_w)
1214{
1215   msx_state *state = space->machine().driver_data<msx_state>();
1216   if (offset)
1217   {
1218      state->m_kanji_latch =
1219            (state->m_kanji_latch & 0x007E0) | ((data & 0x3f) << 11);
1220   }
1221   else
1222   {
1223      state->m_kanji_latch =
1224            (state->m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
1225   }
1226}
src/mess/includes/msx_slot.h
r0r11531
1/*****************************************************************************
2 *
3 * includes/msx_slot.h
4 *
5 ****************************************************************************/
6
7#ifndef MSX_SLOT_H_
8#define MSX_SLOT_H_
9
10
11enum {
12   MSX_LAYOUT_SLOT_ENTRY,
13   MSX_LAYOUT_KANJI_ENTRY,
14   MSX_LAYOUT_RAMIO_SET_BITS_ENTRY,
15   MSX_LAYOUT_LAST
16};
17
18typedef struct {
19   int entry;
20   int type;
21   int slot_primary, slot_secondary, slot_page, page_extent;
22   int size, option;
23} msx_slot_layout;
24
25#define MSX_LAYOUT_INIT(msx) \
26static const msx_slot_layout msx_slot_layout_##msx[] = {
27
28#define MSX_LAYOUT_SLOT(prim, sec, page, extend, type, size, option) \
29   {                        \
30      MSX_LAYOUT_SLOT_ENTRY,      \
31      SLOT_##type,            \
32      prim,                  \
33      sec,                  \
34      page,                  \
35      extend,                  \
36      size,                  \
37      option                  \
38   },
39
40#define MSX_LAYOUT_KANJI(offset) \
41   {                        \
42      MSX_LAYOUT_KANJI_ENTRY,      \
43      SLOT_EMPTY,               \
44      0,                     \
45      0,                     \
46      0,                     \
47      0,                     \
48      0,                     \
49      offset                  \
50   },
51
52#define MSX_LAYOUT_RAMIO_SET_BITS(offset) \
53   {                        \
54      MSX_LAYOUT_RAMIO_SET_BITS_ENTRY,      \
55      SLOT_EMPTY,               \
56      0,                     \
57      0,                     \
58      0,                     \
59      0,                     \
60      0,                     \
61      offset                  \
62   },
63
64#define MSX_LAYOUT_END \
65   {                        \
66      MSX_LAYOUT_LAST,         \
67      SLOT_END,               \
68      0,                     \
69      0,                     \
70      0,                     \
71      0,                     \
72      0,                     \
73      0                     \
74   }                        \
75};
76
77
78enum msx_slot_type {
79   SLOT_EMPTY = 0,
80   SLOT_MSXDOS2,
81   SLOT_KONAMI_SCC,
82   SLOT_KONAMI,
83   SLOT_ASCII8,
84   SLOT_ASCII16,
85   SLOT_GAMEMASTER2,
86   SLOT_ASCII8_SRAM,
87   SLOT_ASCII16_SRAM,
88   SLOT_RTYPE,
89   SLOT_MAJUTSUSHI,
90   SLOT_FMPAC,
91   SLOT_SUPERLOADRUNNER,
92   SLOT_SYNTHESIZER,
93   SLOT_CROSS_BLAIM,
94   SLOT_DISK_ROM,
95   SLOT_KOREAN_80IN1,
96   SLOT_KOREAN_126IN1,
97   SLOT_KOREAN_90IN1,
98   SLOT_LAST_CARTRIDGE_TYPE = SLOT_KOREAN_90IN1,
99   SLOT_SOUNDCARTRIDGE,
100   SLOT_ROM,
101   SLOT_RAM,
102   SLOT_RAM_MM,
103   SLOT_CARTRIDGE1,
104   SLOT_CARTRIDGE2,
105        SLOT_DISK_ROM2,
106   SLOT_END
107};
108
109enum msx_mem_type {
110   MSX_MEM_ROM,
111   MSX_MEM_RAM,
112   MSX_MEM_HANDLER
113};
114
115typedef struct {
116   int m_type;
117   int m_start_page;
118   int m_bank_mask;
119   int m_banks[4];
120   int m_size;
121   UINT8 *m_mem;
122   const char *m_sramfile;
123   union {
124      struct {
125         UINT8 *mem;
126         int sram_support;
127         int sram_active;
128         int opll_active;
129      } fmpac;
130      struct {
131         int active;
132      } scc;
133      struct {
134         UINT8 *mem;
135         int sram_mask;
136         int empty_mask;
137      } sram;
138      struct {
139         int scc_active;
140         int sccp_active;
141         int ram_mode[4];
142         int banks_saved[4];
143         int mode;
144      } sccp;
145   } m_cart;
146} slot_state;
147
148typedef struct {
149   int slot_type;
150   int mem_type;
151   char name[32];
152   int (*init)(running_machine &machine, slot_state*, int page, UINT8 *mem, int size);
153   void (*reset)(running_machine &machine, slot_state*);
154   void (*map)(running_machine &machine, slot_state*, int page);
155   void (*write)(running_machine &machine, slot_state*, UINT16, UINT8);
156   int (*loadsram)(running_machine &machine, slot_state*);
157   int (*savesram)(running_machine &machine, slot_state*);
158} msx_slot;
159
160extern const msx_slot msx_slot_list[];
161
162#define MSX_SLOT_START \
163const msx_slot msx_slot_list[] = {
164
165#define MSX_SLOT_ROM(type, ent) { \
166   type,                     \
167   MSX_MEM_ROM,               \
168   #type,                     \
169   slot_##ent##_init,            \
170   slot_##ent##_reset,            \
171   slot_##ent##_map,            \
172   NULL,                     \
173   NULL,                     \
174   NULL                     \
175},
176
177#define MSX_SLOT_RAM(type, ent) { \
178   type,                     \
179   MSX_MEM_RAM,               \
180   #type,                     \
181   slot_##ent##_init,            \
182   slot_##ent##_reset,            \
183   slot_##ent##_map,            \
184   NULL,                     \
185   NULL,                     \
186   NULL                     \
187},
188
189#define MSX_SLOT(type, ent) { \
190   type,                     \
191   MSX_MEM_HANDLER,            \
192   #type,                     \
193   slot_##ent##_init,            \
194   slot_##ent##_reset,            \
195   slot_##ent##_map,            \
196   slot_##ent##_write,            \
197   NULL,                     \
198   NULL                     \
199},
200
201#define MSX_SLOT_SRAM(type, ent) { \
202   type,                     \
203   MSX_MEM_HANDLER,            \
204   #type,                     \
205   slot_##ent##_init,            \
206   slot_##ent##_reset,            \
207   slot_##ent##_map,            \
208   slot_##ent##_write,            \
209   slot_##ent##_loadsram,         \
210   slot_##ent##_savesram         \
211},
212
213#define MSX_SLOT_NULL(type) { \
214   type,                     \
215   MSX_MEM_ROM,               \
216   #type,                     \
217   NULL,                     \
218   NULL,                     \
219   NULL,                     \
220   NULL,                     \
221   NULL,                     \
222   NULL                     \
223},
224
225#define MSX_SLOT_END \
226   { SLOT_END, 0, "", NULL, NULL, NULL, NULL, NULL } \
227};
228
229#define MSX_SLOT_INIT(nm)          static int \
230   slot_##nm##_init (running_machine &machine, slot_state *state, int page, UINT8 *mem, int size)
231#define MSX_SLOT_MAP(nm)         \
232   static void slot_##nm##_map (running_machine &machine, slot_state *state, int page)
233#define MSX_SLOT_WRITE(nm)         \
234   static void slot_##nm##_write (running_machine &machine, slot_state *state, UINT16 addr, UINT8 val)
235#define MSX_SLOT_RESET(nm)         \
236   static void slot_##nm##_reset (running_machine &machine, slot_state *state)
237#define MSX_SLOT_LOADSRAM(nm)      \
238   static int slot_##nm##_loadsram (running_machine &machine, slot_state *state)
239#define MSX_SLOT_SAVESRAM(nm)      \
240   static int slot_##nm##_savesram (running_machine &machine, slot_state *state)
241
242typedef struct {
243   char name[9];
244   const msx_slot_layout *layout;
245} msx_driver_struct;
246
247extern const msx_driver_struct msx_driver_list[];
248
249#define MSX_DRIVER_LIST      \
250const msx_driver_struct msx_driver_list[] = {
251#define MSX_DRIVER(foo)      \
252      { #foo, msx_slot_layout_##foo },
253#define MSX_DRIVER_END      \
254      { "", NULL }      \
255};
256
257
258#endif /* MSX_SLOT_H_ */
src/mess/includes/msx.h
r0r11531
1/*****************************************************************************
2 *
3 * includes/msx.h
4 *
5 ****************************************************************************/
6
7#ifndef __MSX_H__
8#define __MSX_H__
9
10#include "machine/wd17xx.h"
11#include "formats/flopimg.h"
12
13#define MSX_MAX_CARTS   (2)
14
15#define TC8521_TAG   "rtc"
16
17class msx_state : public driver_device
18{
19public:
20   msx_state(const machine_config &mconfig, device_type type, const char *tag)
21      : driver_device(mconfig, type, tag) { }
22
23   /* PSG */
24   int m_psg_b;
25   int m_opll_active;
26   /* mouse */
27   UINT16 m_mouse[2];
28   int m_mouse_stat[2];
29   /* rtc */
30   int m_rtc_latch;
31   /* disk */
32   UINT8 m_dsk_stat;
33   /* kanji */
34   UINT8 *m_kanji_mem;
35   int m_kanji_latch;
36   /* memory */
37   const msx_slot_layout *layout;
38   slot_state *m_cart_state[MSX_MAX_CARTS];
39   slot_state *m_state[4];
40   const msx_slot *m_slot[4];
41   UINT8 *m_ram_pages[4];
42   UINT8 *m_empty, m_ram_mapper[4];
43   UINT8 m_ramio_set_bits;
44   slot_state *m_all_state[4][4][4];
45   int m_slot_expanded[4];
46   UINT8 m_primary_slot;
47   UINT8 m_secondary_slot[4];
48   UINT8 m_superloadrunner_bank;
49   UINT8 m_korean90in1_bank;
50   UINT8 *m_top_page;
51   int m_port_c_old;
52   int keylatch;
53};
54
55
56/*----------- defined in machine/msx.c -----------*/
57
58extern const i8255_interface msx_ppi8255_interface;
59extern const wd17xx_interface msx_wd17xx_interface;
60/* start/stop functions */
61extern DRIVER_INIT( msx );
62extern MACHINE_START( msx );
63extern MACHINE_START( msx2 );
64extern MACHINE_RESET( msx );
65extern MACHINE_RESET( msx2 );
66extern INTERRUPT_GEN( msx_interrupt );
67extern INTERRUPT_GEN( msx2_interrupt );
68
69DEVICE_IMAGE_LOAD( msx_cart );
70DEVICE_IMAGE_UNLOAD( msx_cart );
71
72void msx_vdp_interrupt(running_machine &machine, int i);
73
74/* I/O functions */
75READ8_DEVICE_HANDLER( msx_printer_status_r );
76WRITE8_DEVICE_HANDLER( msx_printer_strobe_w );
77WRITE8_DEVICE_HANDLER( msx_printer_data_w );
78
79WRITE8_HANDLER ( msx_psg_port_a_w );
80READ8_HANDLER ( msx_psg_port_a_r );
81WRITE8_HANDLER ( msx_psg_port_b_w );
82READ8_HANDLER ( msx_psg_port_b_r );
83WRITE8_HANDLER ( msx_fmpac_w );
84READ8_HANDLER ( msx_rtc_reg_r );
85WRITE8_HANDLER ( msx_rtc_reg_w );
86WRITE8_HANDLER ( msx_rtc_latch_w );
87WRITE8_HANDLER ( msx_90in1_w );
88
89/* new memory emulation */
90WRITE8_HANDLER (msx_page0_w);
91WRITE8_HANDLER (msx_page0_1_w);
92WRITE8_HANDLER (msx_page1_w);
93WRITE8_HANDLER (msx_page1_1_w);
94WRITE8_HANDLER (msx_page1_2_w);
95WRITE8_HANDLER (msx_page2_w);
96WRITE8_HANDLER (msx_page2_1_w);
97WRITE8_HANDLER (msx_page2_2_w);
98WRITE8_HANDLER (msx_page2_3_w);
99WRITE8_HANDLER (msx_page3_w);
100WRITE8_HANDLER (msx_page3_1_w);
101WRITE8_HANDLER (msx_sec_slot_w);
102 READ8_HANDLER (msx_sec_slot_r);
103WRITE8_HANDLER (msx_ram_mapper_w);
104 READ8_HANDLER (msx_ram_mapper_r);
105 READ8_HANDLER (msx_kanji_r);
106WRITE8_HANDLER (msx_kanji_w);
107
108#endif /* __MSX_H__ */
src/mess/mess.mak
r11530r11531
266266   $(MESSOBJ)/apple.a \
267267   $(MESSOBJ)/applied.a \
268268   $(MESSOBJ)/arcadia.a \
269   $(MESSOBJ)/ascii.a \
269270   $(MESSOBJ)/at.a \
270271   $(MESSOBJ)/atari.a \
271272   $(MESSOBJ)/att.a \
273   $(MESSOBJ)/bally.a \
272274   $(MESSOBJ)/bandai.a \
273275   $(MESSOBJ)/be.a \
274276   $(MESSOBJ)/bnpo.a \
r11530r11531
505507   $(MAME_DRIVERS)/amiga.o      \
506508   $(MAME_DRIVERS)/a3000.o      \
507509   $(MAME_DRIVERS)/ami1200.o   \
508   $(MAME_MACHINE)/msx.o      \
509510   $(MAME_MACHINE)/ataricrt.o   \
510511   $(MAME_MACHINE)/atarifdc.o   \
511512   $(MAME_DRIVERS)/atari400.o   \
r11530r11531
665666
666667$(MESSOBJ)/ascii.a:                     \
667668   $(MESS_DRIVERS)/msx.o      \
669   $(MESS_MACHINE)/msx.o      \
668670   $(MESS_MACHINE)/msx_slot.o   \
669671
670672$(MESSOBJ)/at.a:            \

Previous 15994 Revisions Next


© 1998-2018 The MESS Team