summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-03-13 15:04:33 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-03-13 15:04:33 +0000
commit9d3f7f8680637c4e5a49e45aa5891c32faaa47cd (patch)
treebd2a38330ab79353a899356daaece7f2625920f5 /src
parent834d773f26b24ac438202710127d49e236b6e2d1 (diff)
From: Mariusz Wojcieszek
Attached is update for Merit hardware based on V9938 (CRT-250 and CRT-260 - meritm.c). New playable games: Pit Boss II Super Pit Boss Pit Boss Megastar Megatouch IV Megatouch IV Tournament Edition Megatouch 6
Diffstat (limited to 'src')
-rw-r--r--src/emu/machine/pc16552d.c8
-rw-r--r--src/emu/machine/pc16552d.h2
-rw-r--r--src/emu/machine/z80pio.c77
-rw-r--r--src/emu/machine/z80pio.h12
-rw-r--r--src/emu/memory.c528
-rw-r--r--src/emu/memory.h307
-rw-r--r--src/emu/tilemap.c3
-rw-r--r--src/emu/video/v9938.c1160
-rw-r--r--src/emu/video/v9938.h33
-rw-r--r--src/emu/video/v9938mod.c288
-rw-r--r--src/mame/drivers/firebeat.c4
-rw-r--r--src/mame/drivers/meritm.c1272
-rw-r--r--src/mame/drivers/sangho.c34
-rw-r--r--src/mame/mamedriv.c2
14 files changed, 2561 insertions, 1169 deletions
diff --git a/src/emu/machine/pc16552d.c b/src/emu/machine/pc16552d.c
index 3860e1daded..ac649289ef9 100644
--- a/src/emu/machine/pc16552d.c
+++ b/src/emu/machine/pc16552d.c
@@ -55,6 +55,7 @@ typedef struct
PC16552D_CHANNEL ch[2];
int frequency;
void (* irq_handler)(int channel, int value);
+ void (* tx_callback)(int channel, int count, UINT8* data);
} PC16552D_REGS;
#define MAX_PC16552D_CHIPS 4
@@ -146,6 +147,9 @@ static TIMER_CALLBACK( tx_fifo_timer_callback )
ch = &duart[chip].ch[channel];
+ if (duart[chip].tx_callback)
+ duart[chip].tx_callback(channel, ch->tx_fifo_num, ch->tx_fifo);
+
ch->tx_fifo_num = 0;
// set transmitter empty interrupt
@@ -160,6 +164,7 @@ static void duart_push_tx_fifo(int chip, int channel, UINT8 data)
attotime period;
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
+ ch->tx_fifo[ch->tx_fifo_num] = data;
ch->tx_fifo_num++;
period = attotime_mul(ATTOTIME_IN_HZ(duart[chip].frequency), ch->divisor * 16 * 16 * 8);
@@ -379,12 +384,13 @@ static void duart_w(int chip, int reg, UINT8 data)
/*****************************************************************************/
-void pc16552d_init(int chip, int frequency, void (* irq_handler)(int channel, int value))
+void pc16552d_init(int chip, int frequency, void (* irq_handler)(int channel, int value), void (* tx_callback)(int channel, int count, UINT8* data))
{
memset(&duart[chip], 0, sizeof(PC16552D_REGS));
duart[chip].frequency = frequency;
duart[chip].irq_handler = irq_handler;
+ duart[chip].tx_callback = tx_callback;
// clear interrupts
duart[chip].ch[0].pending_interrupt = 0;
diff --git a/src/emu/machine/pc16552d.h b/src/emu/machine/pc16552d.h
index 1dd30017a7f..33b9ce7f94a 100644
--- a/src/emu/machine/pc16552d.h
+++ b/src/emu/machine/pc16552d.h
@@ -1,7 +1,7 @@
#ifndef PC16552D_H
#define PC16552D_H
-void pc16552d_init(int chip, int frequency, void (* irq_handler)(int channel, int value));
+void pc16552d_init(int chip, int frequency, void (* irq_handler)(int channel, int value), void (* tx_callback)(int channel, int count, UINT8* data));
void pc16552d_rx_data(int chip, int channel, UINT8 data);
READ8_HANDLER(pc16552d_0_r);
diff --git a/src/emu/machine/z80pio.c b/src/emu/machine/z80pio.c
index ab9f43ba65a..4f0504d0302 100644
--- a/src/emu/machine/z80pio.c
+++ b/src/emu/machine/z80pio.c
@@ -10,6 +10,7 @@
***************************************************************************/
#include "driver.h"
+#include "deprecat.h"
#include "z80pio.h"
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
@@ -57,6 +58,8 @@ struct _z80pio
UINT8 vector[2]; /* interrupt vector */
void (*intr)(int which); /* interrupt callbacks */
void (*rdyr[2])(int data); /* RDY active callback */
+ read8_machine_func port_read[2]; /* port read callbacks */
+ write8_machine_func port_write[2]; /* port write callbacks */
UINT8 mode[2]; /* mode 00=in,01=out,02=i/o,03=bit*/
UINT8 enable[2]; /* interrupt enable */
UINT8 mask[2]; /* mask folowers */
@@ -172,6 +175,10 @@ void z80pio_init(int which, const z80pio_interface *intf)
memset(pio, 0, sizeof(*pio));
pio->intr = intf->intr;
+ pio->port_read[0] = intf->portAread;
+ pio->port_read[1] = intf->portBread;
+ pio->port_write[0] = intf->portAwrite;
+ pio->port_write[1] = intf->portBwrite;
pio->rdyr[0] = intf->rdyA;
pio->rdyr[1] = intf->rdyB;
z80pio_reset(which);
@@ -221,7 +228,7 @@ void z80pio_c_w(int which, int ch, UINT8 data)
/* load direction phase ? */
if (pio->mode[ch] == 0x13)
{
- logerror("PIO-%c Bits %02x\n", 'A' + ch, data);
+ VPRINTF(("PIO-%c Bits %02x\n", 'A' + ch, data));
pio->dir[ch] = data;
pio->mode[ch] = 0x03;
return;
@@ -233,7 +240,7 @@ void z80pio_c_w(int which, int ch, UINT8 data)
/* load mask folows */
pio->mask[ch] = data;
pio->enable[ch] &= ~PIO_INT_MASK;
- logerror("PIO-%c interrupt mask %02x\n",'A'+ch,data );
+ VPRINTF(("PIO-%c interrupt mask %02x\n",'A'+ch,data ));
return;
}
@@ -241,7 +248,7 @@ void z80pio_c_w(int which, int ch, UINT8 data)
{
case PIO_OP_MODE: /* mode select 0=out,1=in,2=i/o,3=bit */
pio->mode[ch] = (data >> 6);
- logerror("PIO-%c Mode %x\n", 'A' + ch, pio->mode[ch]);
+ VPRINTF(("PIO-%c Mode %x\n", 'A' + ch, pio->mode[ch]));
if (pio->mode[ch] == 0x03)
pio->mode[ch] = 0x13;
return;
@@ -250,23 +257,23 @@ void z80pio_c_w(int which, int ch, UINT8 data)
pio->enable[ch] = data & 0xf0;
pio->mask[ch] = 0x00;
/* when interrupt enable , set vector request flag */
- logerror("PIO-%c Controll %02x\n", 'A' + ch, data);
+ VPRINTF(("PIO-%c Controll %02x\n", 'A' + ch, data));
break;
case PIO_OP_INTE: /* interrupt enable controll */
pio->enable[ch] &= ~PIO_INT_ENABLE;
pio->enable[ch] |= (data & PIO_INT_ENABLE);
- logerror("PIO-%c enable %02x\n", 'A' + ch, data & 0x80);
+ VPRINTF(("PIO-%c enable %02x\n", 'A' + ch, data & 0x80));
break;
default:
if (!(data & 1))
{
pio->vector[ch] = data;
- logerror("PIO-%c vector %02x\n", 'A' + ch, data);
+ VPRINTF(("PIO-%c vector %02x\n", 'A' + ch, data));
}
else
- logerror("PIO-%c illegal command %02x\n", 'A' + ch, data);
+ VPRINTF(("PIO-%c illegal command %02x\n", 'A' + ch, data));
break;
}
@@ -277,7 +284,7 @@ void z80pio_c_w(int which, int ch, UINT8 data)
UINT8 z80pio_c_r(int which, int ch)
{
- logerror("PIO-%c controll read\n", 'A' + ch );
+ VPRINTF(("PIO-%c controll read\n", 'A' + ch ));
return 0;
}
@@ -292,6 +299,9 @@ void z80pio_d_w(int which, int ch, UINT8 data)
z80pio *pio = pios + which;
pio->out[ch] = data; /* latch out data */
+ if(pio->port_write[ch])
+ pio->port_write[ch](Machine, 0, data);
+
switch (pio->mode[ch])
{
case PIO_MODE0: /* mode 0 output */
@@ -305,7 +315,7 @@ void z80pio_d_w(int which, int ch, UINT8 data)
return;
default:
- logerror("PIO-%c data write,bad mode\n",'A'+ch );
+ VPRINTF(("PIO-%c data write,bad mode\n",'A'+ch ));
}
}
@@ -321,19 +331,25 @@ UINT8 z80pio_d_r(int which, int ch)
case PIO_MODE1: /* mode 1 input */
set_rdy(pio, ch, 1); /* ready = H */
+ if(pio->port_read[ch])
+ pio->in[ch] = pio->port_read[ch](Machine, 0);
update_irq_state(pio, ch);
return pio->in[ch];
case PIO_MODE2: /* mode 2 i/o */
- if (ch) logerror("PIO-B mode 2 \n");
+ if (ch) VPRINTF(("PIO-B mode 2 \n"));
set_rdy(pio, 1, 1); /* brdy = H */
+ if(pio->port_read[ch])
+ pio->in[ch] = pio->port_read[ch](Machine, 0);
update_irq_state(pio, ch);
return pio->in[ch];
case PIO_MODE3: /* mode 3 bit */
+ if(pio->port_read[ch])
+ pio->in[ch] = pio->port_read[ch](Machine, 0);
return (pio->in[ch] & pio->dir[ch]) | (pio->out[ch] & ~pio->dir[ch]);
}
- logerror("PIO-%c data read,bad mode\n",'A'+ch );
+ VPRINTF(("PIO-%c data read,bad mode\n",'A'+ch ));
return 0;
}
@@ -351,7 +367,7 @@ void z80pio_p_w(int which, UINT8 ch, UINT8 data)
switch (pio->mode[ch])
{
case PIO_MODE0:
- logerror("PIO-%c OUTPUT mode and data write\n",'A'+ch );
+ VPRINTF(("PIO-%c OUTPUT mode and data write\n",'A'+ch ));
break;
case PIO_MODE2: /* only port A */
@@ -383,7 +399,7 @@ int z80pio_p_r(int which, UINT8 ch)
break;
case PIO_MODE1:
- logerror("PIO-%c INPUT mode and data read\n",'A'+ch );
+ VPRINTF(("PIO-%c INPUT mode and data read\n",'A'+ch ));
break;
case PIO_MODE3:
@@ -429,7 +445,7 @@ static void z80pio_update_strobe(int which, int ch, int state)
if (state != 0)
{
/* positive edge */
- logerror("PIO-%c positive strobe\n",'A' + ch);
+ VPRINTF(("PIO-%c positive strobe\n",'A' + ch));
/* ready is now inactive */
set_rdy(pio, ch, 0);
@@ -507,7 +523,7 @@ int z80pio_irq_ack(int which)
return pio->vector[ch];
}
- logerror("z80pio_irq_ack: failed to find an interrupt to ack!");
+ VPRINTF(("z80pio_irq_ack: failed to find an interrupt to ack!"));
return pio->vector[0];
}
@@ -529,5 +545,34 @@ void z80pio_irq_reti(int which)
return;
}
- logerror("z80pio_irq_reti: failed to find an interrupt to clear IEO on!");
+ VPRINTF(("z80pio_irq_reti: failed to find an interrupt to clear IEO on!"));
+}
+
+/***************************************************************************
+ READ/WRITE HANDLERS
+***************************************************************************/
+READ8_HANDLER(z80pio_0_r)
+{
+ return (offset & 2) ? z80pio_c_r(0, offset & 1) : z80pio_d_r(0, offset & 1);
+}
+
+WRITE8_HANDLER(z80pio_0_w)
+{
+ if (offset & 2)
+ z80pio_c_w(0, offset & 1, data);
+ else
+ z80pio_d_w(0, offset & 1, data);
+}
+
+READ8_HANDLER(z80pio_1_r)
+{
+ return (offset & 2) ? z80pio_c_r(1, offset & 1) : z80pio_d_r(1, offset & 1);
+}
+
+WRITE8_HANDLER(z80pio_1_w)
+{
+ if (offset & 2)
+ z80pio_c_w(1, offset & 1, data);
+ else
+ z80pio_d_w(1, offset & 1, data);
}
diff --git a/src/emu/machine/z80pio.h b/src/emu/machine/z80pio.h
index fee05dca0c4..8de4748419e 100644
--- a/src/emu/machine/z80pio.h
+++ b/src/emu/machine/z80pio.h
@@ -22,6 +22,10 @@
struct _z80pio_interface
{
void (*intr)(int which); /* callback when change interrupt status */
+ read8_machine_func portAread; /* port A read callback */
+ read8_machine_func portBread; /* port B read callback */
+ write8_machine_func portAwrite; /* port A write callback */
+ write8_machine_func portBwrite; /* port B write callback */
void (*rdyA)(int data); /* portA ready active callback (do not support yet)*/
void (*rdyB)(int data); /* portB ready active callback (do not support yet)*/
};
@@ -90,3 +94,11 @@ void z80pio_bstb_w(int which, int state);
int z80pio_irq_state(int which);
int z80pio_irq_ack(int which);
void z80pio_irq_reti(int which);
+
+/***************************************************************************
+ READ/WRITE HANDLERS
+***************************************************************************/
+READ8_HANDLER(z80pio_0_r);
+WRITE8_HANDLER(z80pio_0_w);
+READ8_HANDLER(z80pio_1_r);
+WRITE8_HANDLER(z80pio_1_w);
diff --git a/src/emu/memory.c b/src/emu/memory.c
index 396c4b72760..e91032ccb1b 100644
--- a/src/emu/memory.c
+++ b/src/emu/memory.c
@@ -476,6 +476,10 @@ INLINE void adjust_addresses(addrspace_data *space, offs_t *start, offs_t *end,
+/***************************************************************************
+ CORE SYSTEM OPERATIONS
+***************************************************************************/
+
/*-------------------------------------------------
memory_init - initialize the memory system
-------------------------------------------------*/
@@ -486,7 +490,7 @@ void memory_init(running_machine *machine)
add_exit_callback(machine, memory_exit);
- /* reset globals */
+ /* no current context to start */
cur_context = -1;
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
log_unmap[spacenum] = TRUE;
@@ -630,9 +634,277 @@ const data_accessors *memory_get_accessors(int spacenum, int databits, int endia
}
+
+/***************************************************************************
+ ADDRESS MAPS
+***************************************************************************/
+
+/*-------------------------------------------------
+ address_map_alloc - build and allocate an
+ address map for a CPU's address space
+-------------------------------------------------*/
+
+address_map *address_map_alloc(const machine_config *config, int cpunum, int spacenum)
+{
+ int cputype = config->cpu[cpunum].type;
+ const addrmap_token *internal_map = (const addrmap_token *)cputype_get_info_ptr(cputype, CPUINFO_PTR_INTERNAL_MEMORY_MAP + spacenum);
+ address_map *map;
+
+ map = malloc_or_die(sizeof(*map));
+ memset(map, 0, sizeof(*map));
+
+ /* start by constructing the internal CPU map */
+ if (internal_map != NULL)
+ address_map_detokenize(map, internal_map);
+
+ /* construct the standard map */
+ if (config->cpu[cpunum].address_map[spacenum][0] != NULL)
+ address_map_detokenize(map, config->cpu[cpunum].address_map[spacenum][0]);
+ if (config->cpu[cpunum].address_map[spacenum][1] != NULL)
+ address_map_detokenize(map, config->cpu[cpunum].address_map[spacenum][1]);
+
+ return map;
+}
+
+
+/*-------------------------------------------------
+ address_map_free - release allocated memory
+ for an address map
+-------------------------------------------------*/
+
+void address_map_free(address_map *map)
+{
+ /* free all entries */
+ while (map->entrylist != NULL)
+ {
+ address_map_entry *entry = map->entrylist;
+ map->entrylist = entry->next;
+ free(entry);
+ }
+
+ /* free the map */
+ free(map);
+}
+
+
+/*-------------------------------------------------
+ memory_get_address_map - return a pointer to
+ the constructed address map for a CPU's
+ address space
+-------------------------------------------------*/
+
+const address_map *memory_get_address_map(int cpunum, int spacenum)
+{
+ return cpudata[cpunum].space[spacenum].map;
+}
+
+
+/*-------------------------------------------------
+ address_map_detokenize - detokenize an array
+ of address map tokens
+-------------------------------------------------*/
+
+static void address_map_detokenize(address_map *map, const addrmap_token *tokens)
+{
+ address_map_entry **entryptr;
+ address_map_entry *entry;
+ UINT8 spacenum, databits;
+ UINT32 entrytype;
+
+ /* check the first token */
+ TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, spacenum, 8, databits, 8);
+ if (entrytype != ADDRMAP_TOKEN_START)
+ fatalerror("Address map missing ADDRMAP_TOKEN_START!");
+ if (spacenum >= ADDRESS_SPACES)
+ fatalerror("Invalid address space %d for memory map!", spacenum);
+ if (databits != 8 && databits != 16 && databits != 32 && databits != 64)
+ fatalerror("Invalid data bits %d for memory map!", databits);
+ if (map->spacenum != 0 && map->spacenum != spacenum)
+ fatalerror("Included a mismatched address map (space %d) for an existing map of type %d!\n", spacenum, map->spacenum);
+ if (map->databits != 0 && map->databits != databits)
+ fatalerror("Included a mismatched address map (databits %d) for an existing map with databits %d!\n", databits, map->databits);
+
+ /* fill in the map values */
+ map->spacenum = spacenum;
+ map->databits = databits;
+
+ /* find the end of the list */
+ for (entryptr = &map->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) ;
+ entry = NULL;
+
+ /* loop over tokens until we hit the end */
+ while (entrytype != ADDRMAP_TOKEN_END)
+ {
+ /* unpack the token from the first entry */
+ TOKEN_GET_UINT32_UNPACK1(tokens, entrytype, 8);
+ switch (entrytype)
+ {
+ /* end */
+ case ADDRMAP_TOKEN_END:
+ break;
+
+ /* including */
+ case ADDRMAP_TOKEN_INCLUDE:
+ address_map_detokenize(map, TOKEN_GET_PTR(tokens, tokenptr));
+ for (entryptr = &map->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) ;
+ entry = NULL;
+ break;
+
+ /* global flags */
+ case ADDRMAP_TOKEN_GLOBAL_MASK:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, map->globalmask, 32);
+ break;
+
+ case ADDRMAP_TOKEN_UNMAP_VALUE:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, map->unmapval, 1);
+ break;
+
+ /* start a new range */
+ case ADDRMAP_TOKEN_RANGE:
+ entry = *entryptr = malloc_or_die(sizeof(**entryptr));
+ entryptr = &entry->next;
+ memset(entry, 0, sizeof(*entry));
+ TOKEN_GET_UINT64_UNPACK2(tokens, entry->addrstart, 32, entry->addrend, 32);
+ break;
+
+ case ADDRMAP_TOKEN_MASK:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->addrmask, 32);
+ break;
+
+ case ADDRMAP_TOKEN_MIRROR:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->addrmirror, 32);
+ break;
+
+ case ADDRMAP_TOKEN_READ:
+ entry->read = TOKEN_GET_PTR(tokens, read);
+ entry->read_name = TOKEN_GET_STRING(tokens);
+ break;
+
+ case ADDRMAP_TOKEN_WRITE:
+ entry->write = TOKEN_GET_PTR(tokens, write);
+ entry->write_name = TOKEN_GET_STRING(tokens);
+ break;
+
+ case ADDRMAP_TOKEN_DEVICE_READ:
+ entry->read = TOKEN_GET_PTR(tokens, read);
+ entry->read_name = TOKEN_GET_STRING(tokens);
+ entry->read_devtype = TOKEN_GET_PTR(tokens, devtype);
+ entry->read_devtag = TOKEN_GET_STRING(tokens);
+ break;
+
+ case ADDRMAP_TOKEN_DEVICE_WRITE:
+ entry->write = TOKEN_GET_PTR(tokens, write);
+ entry->write_name = TOKEN_GET_STRING(tokens);
+ entry->write_devtype = TOKEN_GET_PTR(tokens, devtype);
+ entry->write_devtag = TOKEN_GET_STRING(tokens);
+ break;
+
+ case ADDRMAP_TOKEN_READ_PORT:
+ switch (map->databits)
+ {
+ case 8: entry->read.mhandler8 = port_tag_to_handler8(TOKEN_GET_STRING(tokens)); break;
+ case 16: entry->read.mhandler16 = port_tag_to_handler16(TOKEN_GET_STRING(tokens)); break;
+ case 32: entry->read.mhandler32 = port_tag_to_handler32(TOKEN_GET_STRING(tokens)); break;
+ case 64: entry->read.mhandler64 = port_tag_to_handler64(TOKEN_GET_STRING(tokens)); break;
+ }
+ break;
+
+ case ADDRMAP_TOKEN_REGION:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT64_UNPACK3(tokens, entrytype, 8, entry->region, 24, entry->region_offs, 32);
+ break;
+
+ case ADDRMAP_TOKEN_SHARE:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->share, 24);
+ break;
+
+ case ADDRMAP_TOKEN_BASEPTR:
+ entry->baseptr = (void **)TOKEN_GET_PTR(tokens, voidptr);
+ break;
+
+ case ADDRMAP_TOKEN_BASE_MEMBER:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->baseptroffs_plus1, 24);
+ entry->baseptroffs_plus1++;
+ break;
+
+ case ADDRMAP_TOKEN_SIZEPTR:
+ entry->sizeptr = TOKEN_GET_PTR(tokens, sizeptr);
+ break;
+
+ case ADDRMAP_TOKEN_SIZE_MEMBER:
+ TOKEN_UNGET_UINT32(tokens);
+ TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->sizeptroffs_plus1, 24);
+ entry->sizeptroffs_plus1++;
+ break;
+
+ default:
+ fatalerror("Invalid token %d in address map\n", entrytype);
+ break;
+ }
+ }
+}
+
+
+
+/***************************************************************************
+ OPCODE BASE CONTROL
+***************************************************************************/
+
+/*-------------------------------------------------
+ memory_set_decrypted_region - registers an
+ address range as having a decrypted data
+ pointer
+-------------------------------------------------*/
+
+void memory_set_decrypted_region(int cpunum, offs_t addrstart, offs_t addrend, void *base)
+{
+ addrspace_data *space = &cpudata[cpunum].space[ADDRESS_SPACE_PROGRAM];
+ offs_t bytestart = ADDR2BYTE(space, addrstart);
+ offs_t byteend = ADDR2BYTE_END(space, addrend);
+ int banknum, found = FALSE;
+
+ /* loop over banks looking for a match */
+ for (banknum = 0; banknum < STATIC_COUNT; banknum++)
+ {
+ bank_info *bank = &bankdata[banknum];
+
+ /* consider this bank if it is used for reading and matches the CPU/address space */
+ if (bank->used && bank->read && bank->cpunum == cpunum && bank->spacenum == ADDRESS_SPACE_PROGRAM)
+ {
+ /* verify that the region fully covers the decrypted range */
+ if (bank->bytestart >= bytestart && bank->byteend <= byteend)
+ {
+ /* set the decrypted pointer for the corresponding memory bank */
+ bankd_ptr[banknum] = (UINT8 *)base + bank->bytestart - bytestart;
+ found = TRUE;
+
+ /* if we are executing from here, force an opcode base update */
+ if (cpu_getactivecpu() >= 0 && cpunum == cur_context && opcode_entry == banknum)
+ force_opbase_update();
+ }
+
+ /* fatal error if the decrypted region straddles the bank */
+ else if (bank->bytestart < byteend && bank->byteend > bytestart)
+ fatalerror("memory_set_decrypted_region found straddled region %08X-%08X for CPU %d", bytestart, byteend, cpunum);
+ }
+ }
+
+ /* fatal error as well if we didn't find any relevant memory banks */
+ if (!found)
+ fatalerror("memory_set_decrypted_region unable to find matching region %08X-%08X for CPU %d", bytestart, byteend, cpunum);
+}
+
+
/*-------------------------------------------------
- memory_set_opbase_handler - change op-code
- memory base
+ memory_set_opbase_handler - register a
+ handler for opcode base changes on a given
+ CPU
-------------------------------------------------*/
opbase_handler_func memory_set_opbase_handler(int cpunum, opbase_handler_func function)
@@ -646,7 +918,8 @@ opbase_handler_func memory_set_opbase_handler(int cpunum, opbase_handler_func fu
/*-------------------------------------------------
- memory_set_opbase - generic opcode base changer
+ memory_set_opbase - called by CPU cores to
+ update the opcode base for the given address
-------------------------------------------------*/
void memory_set_opbase(offs_t byteaddress)
@@ -710,39 +983,10 @@ void memory_set_opbase(offs_t byteaddress)
}
-/*-------------------------------------------------
- memory_set_decrypted_region - sets the
- decrypted region for the given CPU
--------------------------------------------------*/
-
-void memory_set_decrypted_region(int cpunum, offs_t bytestart, offs_t byteend, void *base)
-{
- int banknum, found = FALSE;
-
- /* loop over banks looking for a match */
- for (banknum = 0; banknum < STATIC_COUNT; banknum++)
- {
- bank_info *bank = &bankdata[banknum];
- if (bank->used && bank->cpunum == cpunum && bank->spacenum == ADDRESS_SPACE_PROGRAM && bank->read)
- {
- if (bank->bytestart >= bytestart && bank->byteend <= byteend)
- {
- bankd_ptr[banknum] = (UINT8 *)base + bank->bytestart - bytestart;
- found = TRUE;
-
- /* if this is live, adjust now */
- if (cpu_getactivecpu() >= 0 && cpunum == cur_context && opcode_entry == banknum)
- force_opbase_update();
- }
- else if (bank->bytestart < byteend && bank->byteend > bytestart)
- fatalerror("memory_set_decrypted_region found straddled region %08X-%08X for CPU %d", bytestart, byteend, cpunum);
- }
- }
-
- if (!found)
- fatalerror("memory_set_decrypted_region unable to find matching region %08X-%08X for CPU %d", bytestart, byteend, cpunum);
-}
+/***************************************************************************
+ OPCODE BASE CONTROL
+***************************************************************************/
/*-------------------------------------------------
memory_get_read_ptr - return a pointer to the
@@ -1164,218 +1408,6 @@ UINT64 *_memory_install_readwrite64_handler(int cpunum, int spacenum, offs_t add
/*-------------------------------------------------
- address_map_alloc - build and allocate an
- address map for a CPU's address space
--------------------------------------------------*/
-
-address_map *address_map_alloc(const machine_config *config, int cpunum, int spacenum)
-{
- int cputype = config->cpu[cpunum].type;
- const addrmap_token *internal_map = (const addrmap_token *)cputype_get_info_ptr(cputype, CPUINFO_PTR_INTERNAL_MEMORY_MAP + spacenum);
- address_map *map;
-
- map = malloc_or_die(sizeof(*map));
- memset(map, 0, sizeof(*map));
-
- /* start by constructing the internal CPU map */
- if (internal_map != NULL)
- address_map_detokenize(map, internal_map);
-
- /* construct the standard map */
- if (config->cpu[cpunum].address_map[spacenum][0] != NULL)
- address_map_detokenize(map, config->cpu[cpunum].address_map[spacenum][0]);
- if (config->cpu[cpunum].address_map[spacenum][1] != NULL)
- address_map_detokenize(map, config->cpu[cpunum].address_map[spacenum][1]);
-
- return map;
-}
-
-
-/*-------------------------------------------------
- address_map_free - release allocated memory
- for an address map
--------------------------------------------------*/
-
-void address_map_free(address_map *map)
-{
- /* free all entries */
- while (map->entrylist != NULL)
- {
- address_map_entry *entry = map->entrylist;
- map->entrylist = entry->next;
- free(entry);
- }
-
- /* free the map */
- free(map);
-}
-
-
-/*-------------------------------------------------
- memory_get_address_map - return a pointer to
- the constructed address map for a CPU's
- address space
--------------------------------------------------*/
-
-const address_map *memory_get_address_map(int cpunum, int spacenum)
-{
- return cpudata[cpunum].space[spacenum].map;
-}
-
-
-/*-------------------------------------------------
- address_map_detokenize - detokenize an array
- of address map tokens
--------------------------------------------------*/
-
-static void address_map_detokenize(address_map *map, const addrmap_token *tokens)
-{
- address_map_entry **entryptr;
- address_map_entry *entry;
- UINT8 spacenum, databits;
- UINT32 entrytype;
-
- /* check the first token */
- TOKEN_GET_UINT32_UNPACK3(tokens, entrytype, 8, spacenum, 8, databits, 8);
- if (entrytype != ADDRMAP_TOKEN_START)
- fatalerror("Address map missing ADDRMAP_TOKEN_START!");
- if (spacenum >= ADDRESS_SPACES)
- fatalerror("Invalid address space %d for memory map!", spacenum);
- if (databits != 8 && databits != 16 && databits != 32 && databits != 64)
- fatalerror("Invalid data bits %d for memory map!", databits);
- if (map->spacenum != 0 && map->spacenum != spacenum)
- fatalerror("Included a mismatched address map (space %d) for an existing map of type %d!\n", spacenum, map->spacenum);
- if (map->databits != 0 && map->databits != databits)
- fatalerror("Included a mismatched address map (databits %d) for an existing map with databits %d!\n", databits, map->databits);
-
- /* fill in the map values */
- map->spacenum = spacenum;
- map->databits = databits;
-
- /* find the end of the list */
- for (entryptr = &map->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) ;
- entry = NULL;
-
- /* loop over tokens until we hit the end */
- while (entrytype != ADDRMAP_TOKEN_END)
- {
- /* unpack the token from the first entry */
- TOKEN_GET_UINT32_UNPACK1(tokens, entrytype, 8);
- switch (entrytype)
- {
- /* end */
- case ADDRMAP_TOKEN_END:
- break;
-
- /* including */
- case ADDRMAP_TOKEN_INCLUDE:
- address_map_detokenize(map, TOKEN_GET_PTR(tokens, tokenptr));
- for (entryptr = &map->entrylist; *entryptr != NULL; entryptr = &(*entryptr)->next) ;
- entry = NULL;
- break;
-
- /* global flags */
- case ADDRMAP_TOKEN_GLOBAL_MASK:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, map->globalmask, 32);
- break;
-
- case ADDRMAP_TOKEN_UNMAP_VALUE:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, map->unmapval, 1);
- break;
-
- /* start a new range */
- case ADDRMAP_TOKEN_RANGE:
- entry = *entryptr = malloc_or_die(sizeof(**entryptr));
- entryptr = &entry->next;
- memset(entry, 0, sizeof(*entry));
- TOKEN_GET_UINT64_UNPACK2(tokens, entry->addrstart, 32, entry->addrend, 32);
- break;
-
- case ADDRMAP_TOKEN_MASK:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->addrmask, 32);
- break;
-
- case ADDRMAP_TOKEN_MIRROR:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK2(tokens, entrytype, 8, entry->addrmirror, 32);
- break;
-
- case ADDRMAP_TOKEN_READ:
- entry->read = TOKEN_GET_PTR(tokens, read);
- entry->read_name = TOKEN_GET_STRING(tokens);
- break;
-
- case ADDRMAP_TOKEN_WRITE:
- entry->write = TOKEN_GET_PTR(tokens, write);
- entry->write_name = TOKEN_GET_STRING(tokens);
- break;
-
- case ADDRMAP_TOKEN_DEVICE_READ:
- entry->read = TOKEN_GET_PTR(tokens, read);
- entry->read_name = TOKEN_GET_STRING(tokens);
- entry->read_devtype = TOKEN_GET_PTR(tokens, devtype);
- entry->read_devtag = TOKEN_GET_STRING(tokens);
- break;
-
- case ADDRMAP_TOKEN_DEVICE_WRITE:
- entry->write = TOKEN_GET_PTR(tokens, write);
- entry->write_name = TOKEN_GET_STRING(tokens);
- entry->write_devtype = TOKEN_GET_PTR(tokens, devtype);
- entry->write_devtag = TOKEN_GET_STRING(tokens);
- break;
-
- case ADDRMAP_TOKEN_READ_PORT:
- switch (map->databits)
- {
- case 8: entry->read.mhandler8 = port_tag_to_handler8(TOKEN_GET_STRING(tokens)); break;
- case 16: entry->read.mhandler16 = port_tag_to_handler16(TOKEN_GET_STRING(tokens)); break;
- case 32: entry->read.mhandler32 = port_tag_to_handler32(TOKEN_GET_STRING(tokens)); break;
- case 64: entry->read.mhandler64 = port_tag_to_handler64(TOKEN_GET_STRING(tokens)); break;
- }
- break;
-
- case ADDRMAP_TOKEN_REGION:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT64_UNPACK3(tokens, entrytype, 8, entry->region, 24, entry->region_offs, 32);
- break;
-
- case ADDRMAP_TOKEN_SHARE:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->share, 24);
- break;
-
- case ADDRMAP_TOKEN_BASEPTR:
- entry->baseptr = (void **)TOKEN_GET_PTR(tokens, voidptr);
- break;
-
- case ADDRMAP_TOKEN_BASE_MEMBER:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->baseptroffs_plus1, 24);
- entry->baseptroffs_plus1++;
- break;
-
- case ADDRMAP_TOKEN_SIZEPTR:
- entry->sizeptr = TOKEN_GET_PTR(tokens, sizeptr);
- break;
-
- case ADDRMAP_TOKEN_SIZE_MEMBER:
- TOKEN_UNGET_UINT32(tokens);
- TOKEN_GET_UINT32_UNPACK2(tokens, entrytype, 8, entry->sizeptroffs_plus1, 24);
- entry->sizeptroffs_plus1++;
- break;
-
- default:
- fatalerror("Invalid token %d in address map\n", entrytype);
- break;
- }
- }
-}
-
-
-/*-------------------------------------------------
memory_init_cpudata - initialize the cpudata
structure for each CPU
-------------------------------------------------*/
diff --git a/src/emu/memory.h b/src/emu/memory.h
index 63a0c6287dd..ce1aaa38065 100644
--- a/src/emu/memory.h
+++ b/src/emu/memory.h
@@ -431,10 +431,6 @@ union _addrmap64_token
#define change_pc(byteaddress) memory_set_opbase(byteaddress)
-/* forces the next branch to generate a call to the opbase handler */
-#define catch_nextBranch() do { opcode_entry = 0xff; } while (0)
-
-
/* opcode range safety check */
#define address_is_unsafe(A) ((UNEXPECTED((A) < opcode_memory_min) || UNEXPECTED((A) > opcode_memory_max)))
@@ -639,6 +635,165 @@ union _addrmap64_token
/***************************************************************************
+ GLOBAL VARIABLES
+***************************************************************************/
+
+extern UINT8 opcode_entry; /* current entry for opcode fetching */
+extern UINT8 * opcode_base; /* opcode ROM base */
+extern UINT8 * opcode_arg_base; /* opcode RAM base */
+extern offs_t opcode_mask; /* mask to apply to the opcode address */
+extern offs_t opcode_memory_min; /* opcode memory minimum */
+extern offs_t opcode_memory_max; /* opcode memory maximum */
+extern address_space active_address_space[]; /* address spaces */
+
+extern const char *const address_space_names[ADDRESS_SPACES];
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES FOR CORE MEMORY FUNCTIONS
+***************************************************************************/
+
+
+/* ----- core system operations ----- */
+
+/* initialize the memory system */
+void memory_init(running_machine *machine);
+
+/* set the current memory context */
+void memory_set_context(int activecpu);
+
+/* get a pointer to the set of memory accessor functions based on the address space,
+ databus width, and endianness */
+const data_accessors *memory_get_accessors(int spacenum, int databits, int endianness);
+
+
+
+/* ----- address maps ----- */
+
+/* build and allocate an address map for a CPU's address space */
+address_map *address_map_alloc(const machine_config *drv, int cpunum, int spacenum);
+
+/* release allocated memory for an address map */
+void address_map_free(address_map *map);
+
+/* return a pointer to the constructed address map for a CPU's address space */
+const address_map *memory_get_address_map(int cpunum, int spacenum);
+
+
+
+/* ----- opcode base control ----- */
+
+/* registers an address range as having a decrypted data pointer */
+void memory_set_decrypted_region(int cpunum, offs_t addrstart, offs_t addrend, void *base);
+
+/* register a handler for opcode base changes on a given CPU */
+opbase_handler_func memory_set_opbase_handler(int cpunum, opbase_handler_func function);
+
+/* called by CPU cores to update the opcode base for the given address */
+void memory_set_opbase(offs_t byteaddress);
+
+
+
+/* return a base pointer to memory */
+void * memory_get_read_ptr(int cpunum, int spacenum, offs_t byteaddress);
+void * memory_get_write_ptr(int cpunum, int spacenum, offs_t byteaddress);
+void * memory_get_op_ptr(int cpunum, offs_t byteaddress, int arg);
+
+/* memory banking */
+void memory_configure_bank(int banknum, int startentry, int numentries, void *base, offs_t stride);
+void memory_configure_bank_decrypted(int banknum, int startentry, int numentries, void *base, offs_t stride);
+void memory_set_bank(int banknum, int entrynum);
+int memory_get_bank(int banknum);
+void memory_set_bankptr(int banknum, void *base);
+
+
+/* debugging */
+void memory_set_debugger_access(int debugger);
+void memory_set_log_unmap(int spacenum, int log);
+int memory_get_log_unmap(int spacenum);
+
+/* dynamic address space mapping */
+void * _memory_install_read_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR handler, const char *handler_name);
+UINT8 * _memory_install_read8_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_machine_func handler, const char *handler_name);
+UINT16 * _memory_install_read16_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_machine_func handler, const char *handler_name);
+UINT32 * _memory_install_read32_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_machine_func handler, const char *handler_name);
+UINT64 * _memory_install_read64_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_machine_func handler, const char *handler_name);
+void * _memory_install_write_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR handler, const char *handler_name);
+UINT8 * _memory_install_write8_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_machine_func handler, const char *handler_name);
+UINT16 * _memory_install_write16_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_machine_func handler, const char *handler_name);
+UINT32 * _memory_install_write32_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_machine_func handler, const char *handler_name);
+UINT64 * _memory_install_write64_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_machine_func handler, const char *handler_name);
+void * _memory_install_readwrite_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR rhandler, FPTR whandler, const char *rhandler_name, const char *whandler_name);
+UINT8 * _memory_install_readwrite8_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_machine_func rhandler, write8_machine_func whandler, const char *rhandler_name, const char *whandler_name);
+UINT16 * _memory_install_readwrite16_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_machine_func rhandler, write16_machine_func whandler, const char *rhandler_name, const char *whandler_name);
+UINT32 * _memory_install_readwrite32_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_machine_func rhandler, write32_machine_func whandler, const char *rhandler_name, const char *whandler_name);
+UINT64 * _memory_install_readwrite64_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_machine_func rhandler, write64_machine_func whandler, const char *rhandler_name, const char *whandler_name);
+
+/* memory debugging */
+void memory_dump(FILE *file);
+const char *memory_get_handler_string(int read0_or_write1, int cpunum, int spacenum, offs_t byteaddress);
+
+
+
+/***************************************************************************
+ HELPER MACROS AND INLINES
+***************************************************************************/
+
+/* generic memory access */
+INLINE UINT8 program_read_byte (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_byte)(byteaddress); }
+INLINE UINT16 program_read_word (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_word)(byteaddress); }
+INLINE UINT32 program_read_dword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_dword)(byteaddress); }
+INLINE UINT64 program_read_qword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_qword)(byteaddress); }
+
+INLINE void program_write_byte (offs_t byteaddress, UINT8 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_byte)(byteaddress, data); }
+INLINE void program_write_word (offs_t byteaddress, UINT16 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_word)(byteaddress, data); }
+INLINE void program_write_dword(offs_t byteaddress, UINT32 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_dword)(byteaddress, data); }
+INLINE void program_write_qword(offs_t byteaddress, UINT64 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_qword)(byteaddress, data); }
+
+INLINE UINT8 data_read_byte (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_byte)(byteaddress); }
+INLINE UINT16 data_read_word (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_word)(byteaddress); }
+INLINE UINT32 data_read_dword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_dword)(byteaddress); }
+INLINE UINT64 data_read_qword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_qword)(byteaddress); }
+
+INLINE void data_write_byte (offs_t byteaddress, UINT8 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_byte)(byteaddress, data); }
+INLINE void data_write_word (offs_t byteaddress, UINT16 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_word)(byteaddress, data); }
+INLINE void data_write_dword(offs_t byteaddress, UINT32 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_dword)(byteaddress, data); }
+INLINE void data_write_qword(offs_t byteaddress, UINT64 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_qword)(byteaddress, data); }
+
+INLINE UINT8 io_read_byte (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_byte)(byteaddress); }
+INLINE UINT16 io_read_word (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_word)(byteaddress); }
+INLINE UINT32 io_read_dword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_dword)(byteaddress); }
+INLINE UINT64 io_read_qword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_qword)(byteaddress); }
+
+INLINE void io_write_byte (offs_t byteaddress, UINT8 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_byte)(byteaddress, data); }
+INLINE void io_write_word (offs_t byteaddress, UINT16 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_word)(byteaddress, data); }
+INLINE void io_write_dword(offs_t byteaddress, UINT32 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_dword)(byteaddress, data); }
+INLINE void io_write_qword(offs_t byteaddress, UINT64 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_qword)(byteaddress, data); }
+
+/* safe opcode and opcode argument reading */
+UINT8 cpu_readop_safe(offs_t byteaddress);
+UINT16 cpu_readop16_safe(offs_t byteaddress);
+UINT32 cpu_readop32_safe(offs_t byteaddress);
+UINT64 cpu_readop64_safe(offs_t byteaddress);
+UINT8 cpu_readop_arg_safe(offs_t byteaddress);
+UINT16 cpu_readop_arg16_safe(offs_t byteaddress);
+UINT32 cpu_readop_arg32_safe(offs_t byteaddress);
+UINT64 cpu_readop_arg64_safe(offs_t byteaddress);
+
+/* opcode and opcode argument reading */
+INLINE void * cpu_opptr(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_opptr_unsafe(byteaddress); }
+INLINE UINT8 cpu_readop(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_unsafe(byteaddress); }
+INLINE UINT16 cpu_readop16(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop16_unsafe(byteaddress); }
+INLINE UINT32 cpu_readop32(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop32_unsafe(byteaddress); }
+INLINE UINT64 cpu_readop64(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop64_unsafe(byteaddress); }
+INLINE UINT8 cpu_readop_arg(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg_unsafe(byteaddress); }
+INLINE UINT16 cpu_readop_arg16(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg16_unsafe(byteaddress); }
+INLINE UINT32 cpu_readop_arg32(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg32_unsafe(byteaddress); }
+INLINE UINT64 cpu_readop_arg64(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg64_unsafe(byteaddress); }
+
+
+/***************************************************************************
FUNCTION PROTOTYPES FOR CORE READ/WRITE ROUTINES
***************************************************************************/
@@ -805,148 +960,4 @@ void io_write_qword_64le(offs_t address, UINT64 data);
void io_write_masked_64le(offs_t address, UINT64 data, UINT64 mem_mask);
-
-/***************************************************************************
- FUNCTION PROTOTYPES FOR CORE MEMORY FUNCTIONS
-***************************************************************************/
-
-/* memory setup function */
-void memory_init(running_machine *machine);
-void memory_set_context(int activecpu);
-
-
-
-/* ----- address maps ----- */
-
-/* build and allocate an address map for a CPU's address space */
-address_map *address_map_alloc(const machine_config *drv, int cpunum, int spacenum);
-
-/* release allocated memory for an address map */
-void address_map_free(address_map *map);
-
-/* return a pointer to the constructed address map for a CPU's address space */
-const address_map *memory_get_address_map(int cpunum, int spacenum);
-
-
-/* opcode base control */
-opbase_handler_func memory_set_opbase_handler(int cpunum, opbase_handler_func function);
-void memory_set_opbase(offs_t byteaddress);
-
-/* separate opcode/data encryption helper */
-void memory_set_decrypted_region(int cpunum, offs_t bytestart, offs_t byteend, void *base);
-
-/* return a base pointer to memory */
-void * memory_get_read_ptr(int cpunum, int spacenum, offs_t byteaddress);
-void * memory_get_write_ptr(int cpunum, int spacenum, offs_t byteaddress);
-void * memory_get_op_ptr(int cpunum, offs_t byteaddress, int arg);
-
-/* memory banking */
-void memory_configure_bank(int banknum, int startentry, int numentries, void *base, offs_t stride);
-void memory_configure_bank_decrypted(int banknum, int startentry, int numentries, void *base, offs_t stride);
-void memory_set_bank(int banknum, int entrynum);
-int memory_get_bank(int banknum);
-void memory_set_bankptr(int banknum, void *base);
-
-const data_accessors *memory_get_accessors(int spacenum, int databits, int endianness);
-
-/* debugging */
-void memory_set_debugger_access(int debugger);
-void memory_set_log_unmap(int spacenum, int log);
-int memory_get_log_unmap(int spacenum);
-
-/* dynamic address space mapping */
-void * _memory_install_read_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR handler, const char *handler_name);
-UINT8 * _memory_install_read8_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_machine_func handler, const char *handler_name);
-UINT16 * _memory_install_read16_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_machine_func handler, const char *handler_name);
-UINT32 * _memory_install_read32_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_machine_func handler, const char *handler_name);
-UINT64 * _memory_install_read64_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_machine_func handler, const char *handler_name);
-void * _memory_install_write_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR handler, const char *handler_name);
-UINT8 * _memory_install_write8_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write8_machine_func handler, const char *handler_name);
-UINT16 * _memory_install_write16_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write16_machine_func handler, const char *handler_name);
-UINT32 * _memory_install_write32_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write32_machine_func handler, const char *handler_name);
-UINT64 * _memory_install_write64_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, write64_machine_func handler, const char *handler_name);
-void * _memory_install_readwrite_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, FPTR rhandler, FPTR whandler, const char *rhandler_name, const char *whandler_name);
-UINT8 * _memory_install_readwrite8_handler (int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read8_machine_func rhandler, write8_machine_func whandler, const char *rhandler_name, const char *whandler_name);
-UINT16 * _memory_install_readwrite16_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read16_machine_func rhandler, write16_machine_func whandler, const char *rhandler_name, const char *whandler_name);
-UINT32 * _memory_install_readwrite32_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read32_machine_func rhandler, write32_machine_func whandler, const char *rhandler_name, const char *whandler_name);
-UINT64 * _memory_install_readwrite64_handler(int cpunum, int spacenum, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, read64_machine_func rhandler, write64_machine_func whandler, const char *rhandler_name, const char *whandler_name);
-
-/* memory debugging */
-void memory_dump(FILE *file);
-const char *memory_get_handler_string(int read0_or_write1, int cpunum, int spacenum, offs_t byteaddress);
-
-
-
-/***************************************************************************
- GLOBAL VARIABLES
-***************************************************************************/
-
-extern UINT8 opcode_entry; /* current entry for opcode fetching */
-extern UINT8 * opcode_base; /* opcode ROM base */
-extern UINT8 * opcode_arg_base; /* opcode RAM base */
-extern offs_t opcode_mask; /* mask to apply to the opcode address */
-extern offs_t opcode_memory_min; /* opcode memory minimum */
-extern offs_t opcode_memory_max; /* opcode memory maximum */
-extern address_space active_address_space[]; /* address spaces */
-
-extern const char *const address_space_names[ADDRESS_SPACES];
-
-
-/***************************************************************************
- HELPER MACROS AND INLINES
-***************************************************************************/
-
-/* generic memory access */
-INLINE UINT8 program_read_byte (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_byte)(byteaddress); }
-INLINE UINT16 program_read_word (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_word)(byteaddress); }
-INLINE UINT32 program_read_dword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_dword)(byteaddress); }
-INLINE UINT64 program_read_qword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->read_qword)(byteaddress); }
-
-INLINE void program_write_byte (offs_t byteaddress, UINT8 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_byte)(byteaddress, data); }
-INLINE void program_write_word (offs_t byteaddress, UINT16 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_word)(byteaddress, data); }
-INLINE void program_write_dword(offs_t byteaddress, UINT32 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_dword)(byteaddress, data); }
-INLINE void program_write_qword(offs_t byteaddress, UINT64 data) { (*active_address_space[ADDRESS_SPACE_PROGRAM].accessors->write_qword)(byteaddress, data); }
-
-INLINE UINT8 data_read_byte (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_byte)(byteaddress); }
-INLINE UINT16 data_read_word (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_word)(byteaddress); }
-INLINE UINT32 data_read_dword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_dword)(byteaddress); }
-INLINE UINT64 data_read_qword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_DATA].accessors->read_qword)(byteaddress); }
-
-INLINE void data_write_byte (offs_t byteaddress, UINT8 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_byte)(byteaddress, data); }
-INLINE void data_write_word (offs_t byteaddress, UINT16 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_word)(byteaddress, data); }
-INLINE void data_write_dword(offs_t byteaddress, UINT32 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_dword)(byteaddress, data); }
-INLINE void data_write_qword(offs_t byteaddress, UINT64 data) { (*active_address_space[ADDRESS_SPACE_DATA].accessors->write_qword)(byteaddress, data); }
-
-INLINE UINT8 io_read_byte (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_byte)(byteaddress); }
-INLINE UINT16 io_read_word (offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_word)(byteaddress); }
-INLINE UINT32 io_read_dword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_dword)(byteaddress); }
-INLINE UINT64 io_read_qword(offs_t byteaddress) { return (*active_address_space[ADDRESS_SPACE_IO].accessors->read_qword)(byteaddress); }
-
-INLINE void io_write_byte (offs_t byteaddress, UINT8 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_byte)(byteaddress, data); }
-INLINE void io_write_word (offs_t byteaddress, UINT16 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_word)(byteaddress, data); }
-INLINE void io_write_dword(offs_t byteaddress, UINT32 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_dword)(byteaddress, data); }
-INLINE void io_write_qword(offs_t byteaddress, UINT64 data) { (*active_address_space[ADDRESS_SPACE_IO].accessors->write_qword)(byteaddress, data); }
-
-/* safe opcode and opcode argument reading */
-UINT8 cpu_readop_safe(offs_t byteaddress);
-UINT16 cpu_readop16_safe(offs_t byteaddress);
-UINT32 cpu_readop32_safe(offs_t byteaddress);
-UINT64 cpu_readop64_safe(offs_t byteaddress);
-UINT8 cpu_readop_arg_safe(offs_t byteaddress);
-UINT16 cpu_readop_arg16_safe(offs_t byteaddress);
-UINT32 cpu_readop_arg32_safe(offs_t byteaddress);
-UINT64 cpu_readop_arg64_safe(offs_t byteaddress);
-
-/* opcode and opcode argument reading */
-INLINE void * cpu_opptr(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_opptr_unsafe(byteaddress); }
-INLINE UINT8 cpu_readop(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_unsafe(byteaddress); }
-INLINE UINT16 cpu_readop16(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop16_unsafe(byteaddress); }
-INLINE UINT32 cpu_readop32(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop32_unsafe(byteaddress); }
-INLINE UINT64 cpu_readop64(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop64_unsafe(byteaddress); }
-INLINE UINT8 cpu_readop_arg(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg_unsafe(byteaddress); }
-INLINE UINT16 cpu_readop_arg16(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg16_unsafe(byteaddress); }
-INLINE UINT32 cpu_readop_arg32(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg32_unsafe(byteaddress); }
-INLINE UINT64 cpu_readop_arg64(offs_t byteaddress) { if (address_is_unsafe(byteaddress)) { memory_set_opbase(byteaddress); } return cpu_readop_arg64_unsafe(byteaddress); }
-
-
#endif /* __MEMORY_H__ */
diff --git a/src/emu/tilemap.c b/src/emu/tilemap.c
index 809b4fec858..5f18ae59da2 100644
--- a/src/emu/tilemap.c
+++ b/src/emu/tilemap.c
@@ -263,6 +263,9 @@ INLINE tilemap *indexed_tilemap(int index)
void tilemap_init(running_machine *machine)
{
+ if (machine->primary_screen == NULL)
+ return;
+
screen_width = video_screen_get_width(machine->primary_screen);
screen_height = video_screen_get_height(machine->primary_screen);
diff --git a/src/emu/video/v9938.c b/src/emu/video/v9938.c
index 76e1524cd63..ba0f95d1279 100644
--- a/src/emu/video/v9938.c
+++ b/src/emu/video/v9938.c
@@ -18,6 +18,14 @@
#include "deprecat.h"
#include "v9938.h"
+#define VERBOSE 0
+
+#if VERBOSE
+#define LOG(x) logerror x
+#else
+#define LOG(x)
+#endif
+
typedef struct {
/* general */
int model;
@@ -44,11 +52,32 @@ typedef struct {
UINT8 mx_delta, my_delta;
/* mouse & lightpen */
UINT8 button_state;
+ /* palette */
+ UINT16 pal_ind16[16];
+ UINT16 pal_ind256[256];
+ /* render bitmap */
+ bitmap_t *bitmap;
+ /* Command unit */
+ struct {
+ int SX,SY;
+ int DX,DY;
+ int TX,TY;
+ int NX,NY;
+ int MX;
+ int ASX,ADX,ANX;
+ UINT8 CL;
+ UINT8 LO;
+ UINT8 CM;
+ UINT8 MXS, MXD;
+ } MMC;
+ int VdpOpsCnt;
+ void (*VdpEngine)(void);
} V9938;
-static V9938 vdp;
+static UINT16 *pal_indYJK;
-static UINT16 pal_ind16[16], pal_ind256[256], *pal_indYJK;
+static V9938 vdps[2];
+static V9938 *vdp = NULL;
#define V9938_MODE_TEXT1 (0)
#define V9938_MODE_MULTI (1)
@@ -141,7 +170,7 @@ PALETTE_INIT( v9958 )
/* set up YJK table */
pal_indYJK = auto_malloc(0x20000 * sizeof(UINT16));
- logerror ("Building YJK table for V9958 screens, may take a while ... \n");
+ LOG(("Building YJK table for V9958 screens, may take a while ... \n"));
i = 0;
for (y=0;y<32;y++) for (k=0;k<64;k++) for (j=0;j<64;j++)
{
@@ -183,7 +212,7 @@ PALETTE_INIT( v9958 )
}
if (i != 19268)
- logerror ("Table creation failed - %d colours out of 19286 created\n", i);
+ LOG( ("Table creation failed - %d colours out of 19286 created\n", i));
}
/*
@@ -209,31 +238,43 @@ pixel3 = *(data+3) & 8 ? pal_ind16[*(data+3) >> 4] : pal_indYJK[ind | *(data+3)
*/
-WRITE8_HANDLER (v9938_palette_w)
+static void v9938_palette_w(UINT8 data)
{
int indexp;
- if (vdp.pal_write_first)
+ if (vdp->pal_write_first)
{
/* store in register */
- indexp = vdp.contReg[0x10] & 15;
- vdp.palReg[indexp*2] = vdp.pal_write & 0x77;
- vdp.palReg[indexp*2+1] = data & 0x07;
+ indexp = vdp->contReg[0x10] & 15;
+ vdp->palReg[indexp*2] = vdp->pal_write & 0x77;
+ vdp->palReg[indexp*2+1] = data & 0x07;
/* update palette */
- pal_ind16[indexp] = (((int)vdp.pal_write << 2) & 0x01c0) |
+ vdp->pal_ind16[indexp] = (((int)vdp->pal_write << 2) & 0x01c0) |
(((int)data << 3) & 0x0038) |
- ((int)vdp.pal_write & 0x0007);
+ ((int)vdp->pal_write & 0x0007);
- vdp.contReg[0x10] = (vdp.contReg[0x10] + 1) & 15;
- vdp.pal_write_first = 0;
+ vdp->contReg[0x10] = (vdp->contReg[0x10] + 1) & 15;
+ vdp->pal_write_first = 0;
}
else
{
- vdp.pal_write = data;
- vdp.pal_write_first = 1;
+ vdp->pal_write = data;
+ vdp->pal_write_first = 1;
}
}
+WRITE8_HANDLER( v9938_0_palette_w )
+{
+ vdp = &vdps[0];
+ v9938_palette_w(data);
+};
+
+WRITE8_HANDLER( v9938_1_palette_w )
+{
+ vdp = &vdps[1];
+ v9938_palette_w(data);
+}
+
static void v9938_reset_palette (void)
{
/* taken from V9938 Technical Data book, page 148. it's in G-R-B format */
@@ -260,10 +301,10 @@ static void v9938_reset_palette (void)
for (i=0;i<16;i++)
{
/* set the palette registers */
- vdp.palReg[i*2+0] = pal16[i*3+1] << 4 | pal16[i*3+2];
- vdp.palReg[i*2+1] = pal16[i*3];
+ vdp->palReg[i*2+0] = pal16[i*3+1] << 4 | pal16[i*3+2];
+ vdp->palReg[i*2+1] = pal16[i*3];
/* set the reference table */
- pal_ind16[i] = pal16[i*3+1] << 6 | pal16[i*3] << 3 | pal16[i*3+2];
+ vdp->pal_ind16[i] = pal16[i*3+1] << 6 | pal16[i*3] << 3 | pal16[i*3+2];
}
/* set internal palette GRAPHIC 7 */
@@ -274,7 +315,7 @@ static void v9938_reset_palette (void)
red = (i << 1) & 6; if (red == 6) red++;
ind |= red;
- pal_ind256[i] = ind;
+ vdp->pal_ind256[i] = ind;
}
}
@@ -288,183 +329,277 @@ static void v9938_vram_write (int offset, int data)
{
int newoffset;
- if ( (vdp.mode == V9938_MODE_GRAPHIC6) || (vdp.mode == V9938_MODE_GRAPHIC7) )
+ if ( (vdp->mode == V9938_MODE_GRAPHIC6) || (vdp->mode == V9938_MODE_GRAPHIC7) )
{
newoffset = ((offset & 1) << 16) | (offset >> 1);
- if (newoffset < vdp.vram_size)
- vdp.vram[newoffset] = data;
+ if (newoffset < vdp->vram_size)
+ vdp->vram[newoffset] = data;
}
else
{
- if (offset < vdp.vram_size)
- vdp.vram[offset] = data;
+ if (offset < vdp->vram_size)
+ vdp->vram[offset] = data;
}
}
static int v9938_vram_read (int offset)
{
- if ( (vdp.mode == V9938_MODE_GRAPHIC6) || (vdp.mode == V9938_MODE_GRAPHIC7) )
- return vdp.vram[((offset & 1) << 16) | (offset >> 1)];
+ if ( (vdp->mode == V9938_MODE_GRAPHIC6) || (vdp->mode == V9938_MODE_GRAPHIC7) )
+ return vdp->vram[((offset & 1) << 16) | (offset >> 1)];
else
- return vdp.vram[offset];
+ return vdp->vram[offset];
}
-WRITE8_HANDLER (v9938_vram_w)
+void v9938_vram_w( UINT8 data )
{
int address;
/*v9938_update_command ();*/
- vdp.cmd_write_first = 0;
+ vdp->cmd_write_first = 0;
- address = ((int)vdp.contReg[14] << 14) | vdp.address_latch;
+ address = ((int)vdp->contReg[14] << 14) | vdp->address_latch;
- if (vdp.contReg[45] & 0x40)
+ if (vdp->contReg[45] & 0x40)
{
- if ( (vdp.mode == V9938_MODE_GRAPHIC6) || (vdp.mode == V9938_MODE_GRAPHIC7) )
+ if ( (vdp->mode == V9938_MODE_GRAPHIC6) || (vdp->mode == V9938_MODE_GRAPHIC7) )
address >>= 1; /* correct? */
- if (vdp.vram_exp && address < 0x10000)
- vdp.vram_exp[address] = data;
+ if (vdp->vram_exp && address < 0x10000)
+ vdp->vram_exp[address] = data;
}
else
{
v9938_vram_write (address, data);
}
- vdp.address_latch = (vdp.address_latch + 1) & 0x3fff;
- if ((!vdp.address_latch) && (vdp.contReg[0] & 0x0c) ) /* correct ??? */
+ vdp->address_latch = (vdp->address_latch + 1) & 0x3fff;
+ if ((!vdp->address_latch) && (vdp->contReg[0] & 0x0c) ) /* correct ??? */
{
- vdp.contReg[14] = (vdp.contReg[14] + 1) & 7;
+ vdp->contReg[14] = (vdp->contReg[14] + 1) & 7;
}
}
- READ8_HANDLER (v9938_vram_r)
+ WRITE8_HANDLER (v9938_0_vram_w)
+ {
+ vdp = &vdps[0];
+ v9938_vram_w( data );
+ }
+
+ WRITE8_HANDLER (v9938_1_vram_w)
+ {
+ vdp = &vdps[1];
+ v9938_vram_w( data );
+ }
+
+ static UINT8 v9938_vram_r(void)
{
UINT8 ret;
int address;
- address = ((int)vdp.contReg[14] << 14) | vdp.address_latch;
+ address = ((int)vdp->contReg[14] << 14) | vdp->address_latch;
- vdp.cmd_write_first = 0;
+ vdp->cmd_write_first = 0;
- ret = vdp.read_ahead;
+ ret = vdp->read_ahead;
- if (vdp.contReg[45] & 0x40)
+ if (vdp->contReg[45] & 0x40)
{
- if ( (vdp.mode == V9938_MODE_GRAPHIC6) || (vdp.mode == V9938_MODE_GRAPHIC7) )
+ if ( (vdp->mode == V9938_MODE_GRAPHIC6) || (vdp->mode == V9938_MODE_GRAPHIC7) )
address >>= 1; /* correct? */
/* correct? */
- if (vdp.vram_exp && address < 0x10000)
- vdp.read_ahead = vdp.vram_exp[address];
+ if (vdp->vram_exp && address < 0x10000)
+ vdp->read_ahead = vdp->vram_exp[address];
else
- vdp.read_ahead = 0xff;
+ vdp->read_ahead = 0xff;
}
else
{
- vdp.read_ahead = v9938_vram_read (address);
+ vdp->read_ahead = v9938_vram_read (address);
}
- vdp.address_latch = (vdp.address_latch + 1) & 0x3fff;
- if ((!vdp.address_latch) && (vdp.contReg[0] & 0x0c) ) /* correct ??? */
+ vdp->address_latch = (vdp->address_latch + 1) & 0x3fff;
+ if ((!vdp->address_latch) && (vdp->contReg[0] & 0x0c) ) /* correct ??? */
{
- vdp.contReg[14] = (vdp.contReg[14] + 1) & 7;
+ vdp->contReg[14] = (vdp->contReg[14] + 1) & 7;
}
return ret;
}
-WRITE8_HANDLER (v9938_command_w)
+READ8_HANDLER (v9938_0_vram_r)
+{
+ vdp = &vdps[0];
+ return v9938_vram_r();
+}
+
+READ8_HANDLER (v9938_1_vram_r)
+{
+ vdp = &vdps[1];
+ return v9938_vram_r();
+}
+
+static void v9938_command_w(UINT8 data)
{
- if (vdp.cmd_write_first)
+ if (vdp->cmd_write_first)
{
if (data & 0x80)
{
if (!(data & 0x40))
- v9938_register_write (data & 0x3f, vdp.cmd_write);
+ v9938_register_write (data & 0x3f, vdp->cmd_write);
}
else
{
- vdp.address_latch =
- (((UINT16)data << 8) | vdp.cmd_write) & 0x3fff;
- if ( !(data & 0x40) ) v9938_vram_r (machine,0); /* read ahead! */
+ vdp->address_latch =
+ (((UINT16)data << 8) | vdp->cmd_write) & 0x3fff;
+ if ( !(data & 0x40) ) v9938_vram_r (); /* read ahead! */
}
- vdp.cmd_write_first = 0;
+ vdp->cmd_write_first = 0;
}
else
{
- vdp.cmd_write = data;
- vdp.cmd_write_first = 1;
+ vdp->cmd_write = data;
+ vdp->cmd_write_first = 1;
}
}
+WRITE8_HANDLER (v9938_0_command_w)
+{
+ vdp = &vdps[0];
+ v9938_command_w(data);
+}
+
+WRITE8_HANDLER (v9938_1_command_w)
+{
+ vdp = &vdps[1];
+ v9938_command_w(data);
+}
+
/***************************************************************************
Init/stop/reset/Interrupt functions
***************************************************************************/
-void v9938_init (running_machine *machine, int model, int vram_size, void (*callback)(int) )
+void v9938_init (running_machine *machine, int which, bitmap_t *bitmap, int model, int vram_size, void (*callback)(int) )
{
- memset (&vdp, 0, sizeof (vdp) );
+ vdp = &vdps[which];
+
+ memset (vdp, 0, sizeof (*vdp) );
- vdp.model = model;
- vdp.vram_size = vram_size;
- vdp.INTCallback = callback;
- vdp.size_old = -1;
+ vdp->VdpOpsCnt = 1;
+ vdp->VdpEngine = NULL;
+
+ vdp->bitmap = bitmap;
+ vdp->model = model;
+ vdp->vram_size = vram_size;
+ vdp->INTCallback = callback;
+ vdp->size_old = -1;
/* allocate VRAM */
- vdp.vram = auto_malloc (0x20000);
- memset (vdp.vram, 0, 0x20000);
- if (vdp.vram_size < 0x20000)
+ vdp->vram = auto_malloc (0x20000);
+ memset (vdp->vram, 0, 0x20000);
+ if (vdp->vram_size < 0x20000)
{
/* set unavailable RAM to 0xff */
- memset (vdp.vram + vdp.vram_size, 0xff, (0x20000 - vdp.vram_size) );
+ memset (vdp->vram + vdp->vram_size, 0xff, (0x20000 - vdp->vram_size) );
}
/* do we have expanded memory? */
- if (vdp.vram_size > 0x20000)
+ if (vdp->vram_size > 0x20000)
{
- vdp.vram_exp = auto_malloc (0x10000);
- memset (vdp.vram_exp, 0, 0x10000);
+ vdp->vram_exp = auto_malloc (0x10000);
+ memset (vdp->vram_exp, 0, 0x10000);
}
else
- vdp.vram_exp = NULL;
-
- VIDEO_START_CALL(generic_bitmapped);
+ vdp->vram_exp = NULL;
+
+ state_save_register_item("v9938", which, vdp->offset_x);
+ state_save_register_item("v9938", which, vdp->offset_y);
+ state_save_register_item("v9938", which, vdp->visible_y);
+ state_save_register_item("v9938", which, vdp->mode);
+ state_save_register_item("v9938", which, vdp->pal_write_first);
+ state_save_register_item("v9938", which, vdp->cmd_write_first);
+ state_save_register_item("v9938", which, vdp->pal_write);
+ state_save_register_item("v9938", which, vdp->cmd_write);
+ state_save_register_item_array("v9938", which, vdp->palReg);
+ state_save_register_item_array("v9938", which, vdp->statReg);
+ state_save_register_item_array("v9938", which, vdp->contReg);
+ state_save_register_item("v9938", which, vdp->read_ahead);
+ state_save_register_item_pointer("v9938", which, vdp->vram, 0x20000);
+ if ( vdp->vram_exp != NULL )
+ state_save_register_item_pointer("v9938", which, vdp->vram_exp, 0x10000);
+ state_save_register_item("v9938", which, vdp->INT);
+ state_save_register_item("v9938", which, vdp->scanline);
+ state_save_register_item("v9938", which, vdp->blink);
+ state_save_register_item("v9938", which, vdp->blink_count);
+ state_save_register_item("v9938", which, vdp->size);
+ state_save_register_item("v9938", which, vdp->size_old);
+ state_save_register_item("v9938", which, vdp->size_auto);
+ state_save_register_item("v9938", which, vdp->size_now);
+ state_save_register_item("v9938", which, vdp->mx_delta);
+ state_save_register_item("v9938", which, vdp->my_delta);
+ state_save_register_item("v9938", which, vdp->button_state);
+ state_save_register_item_array("v9938", which, vdp->pal_ind16);
+ state_save_register_item_array("v9938", which, vdp->pal_ind256);
+ state_save_register_item("v9938", which, vdp->MMC.SX);
+ state_save_register_item("v9938", which, vdp->MMC.SY);
+ state_save_register_item("v9938", which, vdp->MMC.DX);
+ state_save_register_item("v9938", which, vdp->MMC.DY);
+ state_save_register_item("v9938", which, vdp->MMC.TX);
+ state_save_register_item("v9938", which, vdp->MMC.TY);
+ state_save_register_item("v9938", which, vdp->MMC.NX);
+ state_save_register_item("v9938", which, vdp->MMC.NY);
+ state_save_register_item("v9938", which, vdp->MMC.MX);
+ state_save_register_item("v9938", which, vdp->MMC.ASX);
+ state_save_register_item("v9938", which, vdp->MMC.ADX);
+ state_save_register_item("v9938", which, vdp->MMC.ANX);
+ state_save_register_item("v9938", which, vdp->MMC.CL);
+ state_save_register_item("v9938", which, vdp->MMC.LO);
+ state_save_register_item("v9938", which, vdp->MMC.CM);
+ state_save_register_item("v9938", which, vdp->MMC.MXS);
+ state_save_register_item("v9938", which, vdp->MMC.MXD);
+ state_save_register_item("v9938", which, vdp->VdpOpsCnt);
}
-void v9938_reset (void)
+void v9938_reset (int which)
{
int i;
+ vdp = &vdps[which];
+
/* offset reset */
- vdp.offset_x = 8;
- vdp.offset_y = 8 + 16;
- vdp.visible_y = 192;
+ vdp->offset_x = 8;
+ vdp->offset_y = 8 + 16;
+ vdp->visible_y = 192;
/* register reset */
v9938_reset_palette (); /* palette registers */
- for (i=0;i<10;i++) vdp.statReg[i] = 0;
- vdp.statReg[2] = 0x0c;
- if (vdp.model == MODEL_V9958) vdp.statReg[1] |= 4;
- for (i=0;i<48;i++) vdp.contReg[i] = 0;
- vdp.cmd_write_first = vdp.pal_write_first = 0;
- vdp.INT = 0;
- vdp.read_ahead = 0; vdp.address_latch = 0; /* ??? */
- vdp.scanline = 0;
+ for (i=0;i<10;i++) vdp->statReg[i] = 0;
+ vdp->statReg[2] = 0x0c;
+ if (vdp->model == MODEL_V9958) vdp->statReg[1] |= 4;
+ for (i=0;i<48;i++) vdp->contReg[i] = 0;
+ vdp->cmd_write_first = vdp->pal_write_first = 0;
+ vdp->INT = 0;
+ vdp->read_ahead = 0; vdp->address_latch = 0; /* ??? */
+ vdp->scanline = 0;
}
static void v9938_check_int (void)
{
UINT8 n;
- n = ( (vdp.contReg[1] & 0x20) && (vdp.statReg[0] & 0x80) ) ||
- ( (vdp.statReg[1] & 0x01) && (vdp.contReg[0] & 0x10) );
+ n = ( (vdp->contReg[1] & 0x20) && (vdp->statReg[0] & 0x80) /*&& vdp->vblank_int*/) ||
+ ( (vdp->statReg[1] & 0x01) && (vdp->contReg[0] & 0x10) );
+
+ /*if(n && vdp->vblank_int)
+ {
+ vdp->vblank_int = 0;
+ }*/
- if (n != vdp.INT)
+ if (n != vdp->INT)
{
- vdp.INT = n;
- logerror ("V9938: IRQ line %s\n", n ? "up" : "down");
+ vdp->INT = n;
+ LOG(("V9938: IRQ line %s\n", n ? "up" : "down"));
}
/*
@@ -472,24 +607,26 @@ static void v9938_check_int (void)
** called; because of this Mr. Ghost, Xevious and SD Snatcher don't
** run. As a patch it's called every scanline
*/
- vdp.INTCallback (n);
+ vdp->INTCallback (n);
}
-void v9938_set_sprite_limit (int i)
+void v9938_set_sprite_limit (int which, int i)
{
- vdp.sprite_limit = i;
+ vdp = &vdps[which];
+ vdp->sprite_limit = i;
}
-void v9938_set_resolution (int i)
+void v9938_set_resolution (int which, int i)
{
+ vdp = &vdps[which];
if (i == RENDER_AUTO)
{
- vdp.size_auto = 1;
+ vdp->size_auto = 1;
}
else
{
- vdp.size = i;
- vdp.size_auto = 0;
+ vdp->size = i;
+ vdp->size_auto = 0;
}
}
@@ -499,16 +636,28 @@ void v9938_set_resolution (int i)
***************************************************************************/
-WRITE8_HANDLER (v9938_register_w)
+static void v9938_register_w(UINT8 data)
{
int reg;
- reg = vdp.contReg[17] & 0x3f;
+ reg = vdp->contReg[17] & 0x3f;
if (reg != 17)
v9938_register_write (reg, data); /* true ? */
- if (!(vdp.contReg[17] & 0x80))
- vdp.contReg[17] = (vdp.contReg[17] + 1) & 0x3f;
+ if (!(vdp->contReg[17] & 0x80))
+ vdp->contReg[17] = (vdp->contReg[17] + 1) & 0x3f;
+}
+
+WRITE8_HANDLER (v9938_0_register_w)
+{
+ vdp = &vdps[0];
+ v9938_register_w(data);
+}
+
+WRITE8_HANDLER (v9938_1_register_w)
+{
+ vdp = &vdps[1];
+ v9938_register_w(data);
}
static void v9938_register_write (int reg, int data)
@@ -524,13 +673,13 @@ static void v9938_register_write (int reg, int data)
if (reg <= 27)
{
data &= reg_mask[reg];
- if (vdp.contReg[reg] == data)
+ if (vdp->contReg[reg] == data)
return;
}
if (reg > 46)
{
- logerror ("V9938: Attempted to write to non-existant R#%d\n", reg);
+ LOG(("V9938: Attempted to write to non-existant R#%d\n", reg));
return;
}
@@ -540,46 +689,46 @@ static void v9938_register_write (int reg, int data)
/* registers that affect interrupt and display mode */
case 0:
case 1:
- vdp.contReg[reg] = data;
+ vdp->contReg[reg] = data;
v9938_set_mode ();
v9938_check_int ();
- logerror ("V9938: mode = %s\n", v9938_modes[vdp.mode]);
+ LOG(("V9938: mode = %s\n", v9938_modes[vdp->mode]));
break;
case 18:
case 9:
- vdp.contReg[reg] = data;
+ vdp->contReg[reg] = data;
/* recalc offset */
- vdp.offset_x = (( (~vdp.contReg[18] - 8) & 0x0f) + 1);
- vdp.offset_y = ((~(vdp.contReg[18]>>4) - 8) & 0x0f) + 7;
- if (vdp.contReg[9] & 0x80)
+ vdp->offset_x = (( (~vdp->contReg[18] - 8) & 0x0f) + 1);
+ vdp->offset_y = ((~(vdp->contReg[18]>>4) - 8) & 0x0f) + 7;
+ if (vdp->contReg[9] & 0x80)
{
- vdp.visible_y = 212;
+ vdp->visible_y = 212;
}
else
{
- vdp.visible_y = 192;
- vdp.offset_y += 10;
+ vdp->visible_y = 192;
+ vdp->offset_y += 10;
}
break;
case 15:
- vdp.pal_write_first = 0;
+ vdp->pal_write_first = 0;
break;
/* color burst registers aren't emulated */
case 20:
case 21:
case 22:
- logerror ("V9938: Write %02xh to R#%d; color burst not emulated\n",
- data, reg);
+ LOG(("V9938: Write %02xh to R#%d; color burst not emulated\n",
+ data, reg));
break;
case 25:
case 26:
case 27:
- if (vdp.model != MODEL_V9958)
+ if (vdp->model != MODEL_V9958)
{
- logerror ("V9938: Attempting to write %02xh to V9958 R#%d\n", data, reg);
+ LOG(("V9938: Attempting to write %02xh to V9958 R#%d\n", data, reg));
data = 0;
}
break;
@@ -594,88 +743,101 @@ static void v9938_register_write (int reg, int data)
}
if (reg != 15)
- logerror("V9938: Write %02x to R#%d\n", data, reg);
+ LOG(("V9938: Write %02x to R#%d\n", data, reg));
- vdp.contReg[reg] = data;
+ vdp->contReg[reg] = data;
}
- READ8_HANDLER (v9938_status_r)
+ static UINT8 v9938_status_r(void)
{
int reg;
UINT8 ret;
- vdp.cmd_write_first = 0;
+ vdp->cmd_write_first = 0;
- reg = vdp.contReg[15] & 0x0f;
+ reg = vdp->contReg[15] & 0x0f;
if (reg > 9)
return 0xff;
switch (reg)
{
case 0:
- ret = vdp.statReg[0];
- vdp.statReg[0] &= 0x1f;
+ ret = vdp->statReg[0];
+ vdp->statReg[0] &= 0x1f;
break;
case 1:
- ret = vdp.statReg[1];
- vdp.statReg[1] &= 0xfe;
- if ((vdp.contReg[8] & 0xc0) == 0x80)
+ ret = vdp->statReg[1];
+ vdp->statReg[1] &= 0xfe;
+ if ((vdp->contReg[8] & 0xc0) == 0x80)
/* mouse mode: add button state */
- ret |= vdp.button_state & 0xc0;
+ ret |= vdp->button_state & 0xc0;
break;
case 2:
/*v9938_update_command ();*/
/*
WTF is this? Whatever this was intended to do, it is nonsensical.
Might as well pick a random number....
+ This was an attempt to emulate H-Blank flag ;)
n = cycles_currently_ran ();
if ( (n < 28) || (n > 199) ) vdp.statReg[2] |= 0x20;
else vdp.statReg[2] &= ~0x20;
*/
- if (mame_rand(Machine) & 1) vdp.statReg[2] |= 0x20;
- else vdp.statReg[2] &= ~0x20;
- ret = vdp.statReg[2];
+ if (mame_rand(Machine) & 1) vdp->statReg[2] |= 0x20;
+ else vdp->statReg[2] &= ~0x20;
+ ret = vdp->statReg[2];
break;
case 3:
- if ((vdp.contReg[8] & 0xc0) == 0x80)
+ if ((vdp->contReg[8] & 0xc0) == 0x80)
{ /* mouse mode: return x mouse delta */
- ret = vdp.mx_delta;
- vdp.mx_delta = 0;
+ ret = vdp->mx_delta;
+ vdp->mx_delta = 0;
}
else
- ret = vdp.statReg[3];
+ ret = vdp->statReg[3];
break;
case 5:
- if ((vdp.contReg[8] & 0xc0) == 0x80)
+ if ((vdp->contReg[8] & 0xc0) == 0x80)
{ /* mouse mode: return y mouse delta */
- ret = vdp.my_delta;
- vdp.my_delta = 0;
+ ret = vdp->my_delta;
+ vdp->my_delta = 0;
}
else
- ret = vdp.statReg[5];
+ ret = vdp->statReg[5];
break;
case 7:
- ret = vdp.statReg[7];
- vdp.statReg[7] = vdp.contReg[44] = v9938_vdp_to_cpu () ;
+ ret = vdp->statReg[7];
+ vdp->statReg[7] = vdp->contReg[44] = v9938_vdp_to_cpu () ;
break;
default:
- ret = vdp.statReg[reg];
+ ret = vdp->statReg[reg];
break;
}
- logerror ("V9938: Read %02x from S#%d\n", ret, reg);
+ LOG(("V9938: Read %02x from S#%d\n", ret, reg));
v9938_check_int ();
return ret;
}
+READ8_HANDLER( v9938_0_status_r )
+{
+ vdp = &vdps[0];
+ return v9938_status_r();
+}
+
+READ8_HANDLER( v9938_1_status_r )
+{
+ vdp = &vdps[1];
+ return v9938_status_r();
+}
+
/***************************************************************************
Refresh / render function
***************************************************************************/
-#define V9938_SECOND_FIELD ( !(((vdp.contReg[9] & 0x04) && !(vdp.statReg[2] & 2)) || vdp.blink))
+#define V9938_SECOND_FIELD ( !(((vdp->contReg[9] & 0x04) && !(vdp->statReg[2] & 2)) || vdp->blink))
#define V9938_BPP (16)
#define V9938_WIDTH (512 + 32)
@@ -694,22 +856,22 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
memset (col, 0, 256);
/* are sprites disabled? */
- if (vdp.contReg[8] & 0x02) return;
+ if (vdp->contReg[8] & 0x02) return;
- attrtbl = vdp.vram + (vdp.contReg[5] << 7) + (vdp.contReg[11] << 15);
- patterntbl = vdp.vram + (vdp.contReg[6] << 11);
+ attrtbl = vdp->vram + (vdp->contReg[5] << 7) + (vdp->contReg[11] << 15);
+ patterntbl = vdp->vram + (vdp->contReg[6] << 11);
/* 16x16 or 8x8 sprites */
- height = (vdp.contReg[1] & 2) ? 16 : 8;
+ height = (vdp->contReg[1] & 2) ? 16 : 8;
/* magnified sprites (zoomed) */
- if (vdp.contReg[1] & 1) height *= 2;
+ if (vdp->contReg[1] & 1) height *= 2;
p2 = p = 0;
while (1)
{
y = attrtbl[0];
if (y == 208) break;
- y = (y - vdp.contReg[23]) & 255;
+ y = (y - vdp->contReg[23]) & 255;
if (y > 208)
y = -(~y&255);
else
@@ -721,10 +883,10 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
if (p2 == 4)
{
/* max maximum sprites per line! */
- if ( !(vdp.statReg[0] & 0x40) )
- vdp.statReg[0] = (vdp.statReg[0] & 0xa0) | 0x40 | p;
+ if ( !(vdp->statReg[0] & 0x40) )
+ vdp->statReg[0] = (vdp->statReg[0] & 0xa0) | 0x40 | p;
- if (vdp.sprite_limit) break;
+ if (vdp->sprite_limit) break;
}
/* get x */
x = attrtbl[1];
@@ -732,11 +894,11 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
/* get pattern */
pattern = attrtbl[2];
- if (vdp.contReg[1] & 2)
+ if (vdp->contReg[1] & 2)
pattern &= 0xfc;
n = line - y;
patternptr = patterntbl + pattern * 8 +
- ((vdp.contReg[1] & 1) ? n/2 : n);
+ ((vdp->contReg[1] & 1) ? n/2 : n);
pattern = patternptr[0] << 8 | patternptr[16];
/* get colour */
@@ -747,7 +909,7 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
while (1)
{
if (n == 0) pattern = patternptr[0];
- else if ( (n == 1) && (vdp.contReg[1] & 2) ) pattern = patternptr[16];
+ else if ( (n == 1) && (vdp->contReg[1] & 2) ) pattern = patternptr[16];
else break;
n++;
@@ -762,28 +924,28 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
{
/* we have a collision! */
if (p2 < 4)
- vdp.statReg[0] |= 0x20;
+ vdp->statReg[0] |= 0x20;
}
if ( !(col[x] & 0x80) )
{
- if (c || (vdp.contReg[8] & 0x20) )
+ if (c || (vdp->contReg[8] & 0x20) )
col[x] |= 0xc0 | c;
else
col[x] |= 0x40;
}
/* if zoomed, draw another pixel */
- if (vdp.contReg[1] & 1)
+ if (vdp->contReg[1] & 1)
{
if (col[x+1] & 0x40)
{
/* we have a collision! */
if (p2 < 4)
- vdp.statReg[0] |= 0x20;
+ vdp->statReg[0] |= 0x20;
}
if ( !(col[x+1] & 0x80) )
{
- if (c || (vdp.contReg[8] & 0x20) )
+ if (c || (vdp->contReg[8] & 0x20) )
col[x+1] |= 0xc0 | c;
else
col[x+1] |= 0x80;
@@ -791,7 +953,7 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
}
}
}
- if (vdp.contReg[1] & 1) x += 2; else x++;
+ if (vdp->contReg[1] & 1) x += 2; else x++;
pattern <<= 1;
}
}
@@ -804,8 +966,8 @@ static void v9938_sprite_mode1 (int line, UINT8 *col)
attrtbl += 4;
}
- if ( !(vdp.statReg[0] & 0x40) )
- vdp.statReg[0] = (vdp.statReg[0] & 0xa0) | p;
+ if ( !(vdp->statReg[0] & 0x40) )
+ vdp->statReg[0] = (vdp->statReg[0] & 0xa0) | p;
}
static void v9938_sprite_mode2 (int line, UINT8 *col)
@@ -816,24 +978,24 @@ static void v9938_sprite_mode2 (int line, UINT8 *col)
memset (col, 0, 256);
/* are sprites disabled? */
- if (vdp.contReg[8] & 0x02) return;
+ if (vdp->contReg[8] & 0x02) return;
- attrtbl = ( (vdp.contReg[5] & 0xfc) << 7) + (vdp.contReg[11] << 15);
- colourtbl = ( (vdp.contReg[5] & 0xf8) << 7) + (vdp.contReg[11] << 15);
- patterntbl = (vdp.contReg[6] << 11);
- colourmask = ( (vdp.contReg[5] & 3) << 3) | 0x7; /* check this! */
+ attrtbl = ( (vdp->contReg[5] & 0xfc) << 7) + (vdp->contReg[11] << 15);
+ colourtbl = ( (vdp->contReg[5] & 0xf8) << 7) + (vdp->contReg[11] << 15);
+ patterntbl = (vdp->contReg[6] << 11);
+ colourmask = ( (vdp->contReg[5] & 3) << 3) | 0x7; /* check this! */
/* 16x16 or 8x8 sprites */
- height = (vdp.contReg[1] & 2) ? 16 : 8;
+ height = (vdp->contReg[1] & 2) ? 16 : 8;
/* magnified sprites (zoomed) */
- if (vdp.contReg[1] & 1) height *= 2;
+ if (vdp->contReg[1] & 1) height *= 2;
p2 = p = first_cc_seen = 0;
while (1)
{
y = v9938_vram_read (attrtbl);
if (y == 216) break;
- y = (y - vdp.contReg[23]) & 255;
+ y = (y - vdp->contReg[23]) & 255;
if (y > 216)
y = -(~y&255);
else
@@ -845,13 +1007,13 @@ static void v9938_sprite_mode2 (int line, UINT8 *col)
if (p2 == 8)
{
/* max maximum sprites per line! */
- if ( !(vdp.statReg[0] & 0x40) )
- vdp.statReg[0] = (vdp.statReg[0] & 0xa0) | 0x40 | p;
+ if ( !(vdp->statReg[0] & 0x40) )
+ vdp->statReg[0] = (vdp->statReg[0] & 0xa0) | 0x40 | p;
- if (vdp.sprite_limit) break;
+ if (vdp->sprite_limit) break;
}
- n = line - y; if (vdp.contReg[1] & 1) n /= 2;
+ n = line - y; if (vdp->contReg[1] & 1) n /= 2;
/* get colour */
c = v9938_vram_read (colourtbl + (((p&colourmask)*16) + n));
@@ -867,7 +1029,7 @@ static void v9938_sprite_mode2 (int line, UINT8 *col)
/* get pattern */
pattern = v9938_vram_read (attrtbl + 2);
- if (vdp.contReg[1] & 2)
+ if (vdp->contReg[1] & 2)
pattern &= 0xfc;
patternptr = patterntbl + pattern * 8 + n;
pattern = (v9938_vram_read (patternptr) << 8) |
@@ -877,16 +1039,16 @@ static void v9938_sprite_mode2 (int line, UINT8 *col)
x = v9938_vram_read (attrtbl + 1);
if (c & 0x80) x -= 32;
- n = (vdp.contReg[1] & 2) ? 16 : 8;
+ n = (vdp->contReg[1] & 2) ? 16 : 8;
while (n--)
{
- for (i=0;i<=(vdp.contReg[1] & 1);i++)
+ for (i=0;i<=(vdp->contReg[1] & 1);i++)
{
if ( (x >= 0) && (x < 256) )
{
if ( (pattern & 0x8000) && !(col[x] & 0x10) )
{
- if ( (c & 15) || (vdp.contReg[8] & 0x20) )
+ if ( (c & 15) || (vdp->contReg[8] & 0x20) )
{
if ( !(c & 0x40) )
{
@@ -912,7 +1074,7 @@ static void v9938_sprite_mode2 (int line, UINT8 *col)
{
/* sprite collision! */
if (p2 < 8)
- vdp.statReg[0] |= 0x20;
+ vdp->statReg[0] |= 0x20;
}
else
col[x] |= 0x40;
@@ -934,8 +1096,8 @@ skip_first_cc_set:
attrtbl += 4;
}
- if ( !(vdp.statReg[0] & 0x40) )
- vdp.statReg[0] = (vdp.statReg[0] & 0xa0) | p;
+ if ( !(vdp->statReg[0] & 0x40) )
+ vdp->statReg[0] = (vdp->statReg[0] & 0xa0) | p;
}
typedef struct {
@@ -1044,12 +1206,12 @@ static void v9938_set_mode (void)
{
int n,i;
- n = (((vdp.contReg[0] & 0x0e) << 1) | ((vdp.contReg[1] & 0x18) >> 3));
+ n = (((vdp->contReg[0] & 0x0e) << 1) | ((vdp->contReg[1] & 0x18) >> 3));
for (i=0;;i++)
{
if ( (modes[i].m == n) || (modes[i].m == 0xff) ) break;
}
- vdp.mode = i;
+ vdp->mode = i;
}
static void v9938_refresh_16 (bitmap_t *bmp, int line)
@@ -1060,12 +1222,12 @@ static void v9938_refresh_16 (bitmap_t *bmp, int line)
double_lines = 0;
- if (vdp.size == RENDER_HIGH)
+ if (vdp->size == RENDER_HIGH)
{
- if (vdp.contReg[9] & 0x08)
+ if (vdp->contReg[9] & 0x08)
{
- vdp.size_now = RENDER_HIGH;
- ln = BITMAP_ADDR16(bmp, line*2+((vdp.statReg[2]>>1)&1), 0);
+ vdp->size_now = RENDER_HIGH;
+ ln = BITMAP_ADDR16(bmp, line*2+((vdp->statReg[2]>>1)&1), 0);
}
else
{
@@ -1077,32 +1239,32 @@ static void v9938_refresh_16 (bitmap_t *bmp, int line)
else
ln = BITMAP_ADDR16(bmp, line, 0);
- if ( !(vdp.contReg[1] & 0x40) || (vdp.statReg[2] & 0x40) )
+ if ( !(vdp->contReg[1] & 0x40) || (vdp->statReg[2] & 0x40) )
{
- if (vdp.size == RENDER_HIGH)
- modes[vdp.mode].border_16 (ln);
+ if (vdp->size == RENDER_HIGH)
+ modes[vdp->mode].border_16 (ln);
else
- modes[vdp.mode].border_16s (ln);
+ modes[vdp->mode].border_16s (ln);
}
else
{
- i = (line - vdp.offset_y) & 255;
- if (vdp.size == RENDER_HIGH)
+ i = (line - vdp->offset_y) & 255;
+ if (vdp->size == RENDER_HIGH)
{
- modes[vdp.mode].visible_16 (ln, i);
- if (modes[vdp.mode].sprites)
+ modes[vdp->mode].visible_16 (ln, i);
+ if (modes[vdp->mode].sprites)
{
- modes[vdp.mode].sprites (i, col);
- modes[vdp.mode].draw_sprite_16 (ln, col);
+ modes[vdp->mode].sprites (i, col);
+ modes[vdp->mode].draw_sprite_16 (ln, col);
}
}
else
{
- modes[vdp.mode].visible_16s (ln, i);
- if (modes[vdp.mode].sprites)
+ modes[vdp->mode].visible_16s (ln, i);
+ if (modes[vdp->mode].sprites)
{
- modes[vdp.mode].sprites (i, col);
- modes[vdp.mode].draw_sprite_16s (ln, col);
+ modes[vdp->mode].sprites (i, col);
+ modes[vdp->mode].draw_sprite_16s (ln, col);
}
}
}
@@ -1115,21 +1277,21 @@ static void v9938_refresh_line (bitmap_t *bmp, int line)
{
int ind16, ind256;
- ind16 = pal_ind16[0];
- ind256 = pal_ind256[0];
+ ind16 = vdp->pal_ind16[0];
+ ind256 = vdp->pal_ind256[0];
- if ( !(vdp.contReg[8] & 0x20) && (vdp.mode != V9938_MODE_GRAPHIC5) )
+ if ( !(vdp->contReg[8] & 0x20) && (vdp->mode != V9938_MODE_GRAPHIC5) )
{
- pal_ind16[0] = pal_ind16[(vdp.contReg[7] & 0x0f)];
- pal_ind256[0] = pal_ind256[vdp.contReg[7]];
+ vdp->pal_ind16[0] = vdp->pal_ind16[(vdp->contReg[7] & 0x0f)];
+ vdp->pal_ind256[0] = vdp->pal_ind256[vdp->contReg[7]];
}
v9938_refresh_16 (bmp, line);
- if ( !(vdp.contReg[8] & 0x20) && (vdp.mode != V9938_MODE_GRAPHIC5) )
+ if ( !(vdp->contReg[8] & 0x20) && (vdp->mode != V9938_MODE_GRAPHIC5) )
{
- pal_ind16[0] = ind16;
- pal_ind256[0] = ind256;
+ vdp->pal_ind16[0] = ind16;
+ vdp->pal_ind256[0] = ind256;
}
}
@@ -1249,120 +1411,141 @@ static void v9938_interrupt_start_vblank (void)
fp = fopen ("vram.dmp", "wb");
if (fp)
{
- fwrite (vdp.vram, 0x10000, 1, fp);
+ fwrite (vdp->vram, 0x10000, 1, fp);
fclose (fp);
popmessage("saved");
}
- for (i=0;i<24;i++) mame_printf_debug ("R#%d = %02x\n", i, vdp.contReg[i]);
+ for (i=0;i<24;i++) mame_printf_debug ("R#%d = %02x\n", i, vdp->contReg[i]);
}
#endif
/* at every frame, vdp switches fields */
- vdp.statReg[2] = (vdp.statReg[2] & 0xfd) | (~vdp.statReg[2] & 2);
+ vdp->statReg[2] = (vdp->statReg[2] & 0xfd) | (~vdp->statReg[2] & 2);
/* color blinking */
- if (!(vdp.contReg[13] & 0xf0))
- vdp.blink = 0;
- else if (!(vdp.contReg[13] & 0x0f))
- vdp.blink = 1;
+ if (!(vdp->contReg[13] & 0xf0))
+ vdp->blink = 0;
+ else if (!(vdp->contReg[13] & 0x0f))
+ vdp->blink = 1;
else
{
/* both on and off counter are non-zero: timed blinking */
- if (vdp.blink_count)
- vdp.blink_count--;
- if (!vdp.blink_count)
+ if (vdp->blink_count)
+ vdp->blink_count--;
+ if (!vdp->blink_count)
{
- vdp.blink = !vdp.blink;
- if (vdp.blink)
- vdp.blink_count = (vdp.contReg[13] >> 4) * 10;
+ vdp->blink = !vdp->blink;
+ if (vdp->blink)
+ vdp->blink_count = (vdp->contReg[13] >> 4) * 10;
else
- vdp.blink_count = (vdp.contReg[13] & 0x0f) * 10;
+ vdp->blink_count = (vdp->contReg[13] & 0x0f) * 10;
}
}
/* check screen rendering size */
- if (vdp.size_auto && (vdp.size_now >= 0) && (vdp.size != vdp.size_now) )
- vdp.size = vdp.size_now;
+ if (vdp->size_auto && (vdp->size_now >= 0) && (vdp->size != vdp->size_now) )
+ vdp->size = vdp->size_now;
- if (vdp.size != vdp.size_old)
+ if (vdp->size != vdp->size_old)
{
- if (vdp.size == RENDER_HIGH)
+ if (vdp->size == RENDER_HIGH)
video_screen_set_visarea (0, 0, 512 + 32 - 1, 0, 424 + 56 - 1);
else
video_screen_set_visarea (0, 0, 256 + 16 - 1, 0, 212 + 28 - 1);
- vdp.size_old = vdp.size;
+ vdp->size_old = vdp->size;
}
- vdp.size_now = -1;
+ vdp->size_now = -1;
}
-int v9938_interrupt (void)
+int v9938_interrupt (int which)
{
int scanline, max, pal, scanline_start;
+ vdp = &vdps[which];
+
v9938_update_command ();
- pal = vdp.contReg[9] & 2;
+ pal = vdp->contReg[9] & 2;
if (pal) scanline_start = 53; else scanline_start = 22;
/* set flags */
- if (vdp.scanline == (vdp.offset_y + scanline_start) )
+ if (vdp->scanline == (vdp->offset_y + scanline_start) )
{
- vdp.statReg[2] &= ~0x40;
+ vdp->statReg[2] &= ~0x40;
}
- else if (vdp.scanline == (vdp.offset_y + vdp.visible_y + scanline_start) )
+ else if (vdp->scanline == (vdp->offset_y + vdp->visible_y + scanline_start) )
{
- vdp.statReg[2] |= 0x40;
- vdp.statReg[0] |= 0x80;
+ vdp->statReg[2] |= 0x40;
+ vdp->statReg[0] |= 0x80;
}
- max = (pal) ? 255 : (vdp.contReg[9] & 0x80) ? 234 : 244;
- scanline = (vdp.scanline - scanline_start - vdp.offset_y);
+ max = (pal) ? 255 : (vdp->contReg[9] & 0x80) ? 234 : 244;
+ scanline = (vdp->scanline - scanline_start - vdp->offset_y);
if ( (scanline >= 0) && (scanline <= max) &&
- ( ( (scanline + vdp.contReg[23]) & 255) == vdp.contReg[19]) )
+ ( ( (scanline + vdp->contReg[23]) & 255) == vdp->contReg[19]) )
{
- vdp.statReg[1] |= 1;
- logerror ("V9938: scanline interrupt (%d)\n", scanline);
+ vdp->statReg[1] |= 1;
+ LOG(("V9938: scanline interrupt (%d)\n", scanline));
}
else
- if ( !(vdp.contReg[0] & 0x10) ) vdp.statReg[1] &= 0xfe;
+ if ( !(vdp->contReg[0] & 0x10) ) vdp->statReg[1] &= 0xfe;
v9938_check_int ();
/* check for start of vblank */
- if ((pal && (vdp.scanline == 310)) ||
- (!pal && (vdp.scanline == 259)))
+ if ((pal && (vdp->scanline == 310)) ||
+ (!pal && (vdp->scanline == 259)))
v9938_interrupt_start_vblank ();
/* render the current line */
- if ((vdp.scanline >= scanline_start) && (vdp.scanline < (212 + 28 + scanline_start)))
+ if ((vdp->scanline >= scanline_start) && (vdp->scanline < (212 + 28 + scanline_start)))
{
- scanline = (vdp.scanline - scanline_start) & 255;
+ scanline = (vdp->scanline - scanline_start) & 255;
- v9938_refresh_line (tmpbitmap, scanline);
+ v9938_refresh_line (vdp->bitmap, scanline);
}
- max = (vdp.contReg[9] & 2) ? 313 : 262;
- if (++vdp.scanline == max)
- vdp.scanline = 0;
+ max = (vdp->contReg[9] & 2) ? 313 : 262;
+ if (++vdp->scanline == max)
+ vdp->scanline = 0;
- return vdp.INT;
+ return vdp->INT;
+}
+
+/*
+ Not really right... won't work with sprites in graphics 7
+ and with palette updated mid-screen
+*/
+int v9938_get_transpen(int which)
+{
+ vdp = &vdps[which];
+ if (vdp->mode == V9938_MODE_GRAPHIC7)
+ {
+ return vdp->pal_ind256[0];
+ }
+ else
+ {
+ return vdp->pal_ind16[0];
+ }
}
/*
Driver-specific function: update the vdp mouse state
*/
-void v9938_update_mouse_state(int mx_delta, int my_delta, int button_state)
+void v9938_update_mouse_state(int which, int mx_delta, int my_delta, int button_state)
{
+ vdp = &vdps[which];
+
/* save button state */
- vdp.button_state = (button_state << 6) & 0xc0;
+ vdp->button_state = (button_state << 6) & 0xc0;
- if ((vdp.contReg[8] & 0xc0) == 0x80)
+ if ((vdp->contReg[8] & 0xc0) == 0x80)
{ /* vdp will process mouse deltas only if it is in mouse mode */
- vdp.mx_delta += mx_delta;
- vdp.my_delta += my_delta;
+ vdp->mx_delta += mx_delta;
+ vdp->my_delta += my_delta;
}
}
@@ -1372,11 +1555,11 @@ void v9938_update_mouse_state(int mx_delta, int my_delta, int button_state)
***************************************************************************/
-#define VDP vdp.contReg
-#define VDPStatus vdp.statReg
-#define VRAM vdp.vram
-#define VRAM_EXP vdp.vram_exp
-#define ScrMode vdp.mode
+#define VDP vdp->contReg
+#define VDPStatus vdp->statReg
+#define VRAM vdp->vram
+#define VRAM_EXP vdp->vram_exp
+#define ScrMode vdp->mode
/*************************************************************/
/** Completely rewritten by Alex Wulms: **/
@@ -1467,22 +1650,6 @@ void v9938_update_mouse_state(int mx_delta, int my_delta, int button_state)
}
/*************************************************************/
-/** Structures and stuff **/
-/*************************************************************/
-static struct {
- int SX,SY;
- int DX,DY;
- int TX,TY;
- int NX,NY;
- int MX;
- int ASX,ADX,ANX;
- UINT8 CL;
- UINT8 LO;
- UINT8 CM;
- UINT8 MXS, MXD;
-} MMC;
-
-/*************************************************************/
/** Function prototypes **/
/*************************************************************/
static UINT8 *VDPVRMP(register UINT8 M, register int MX, register int X, register int Y);
@@ -1532,8 +1699,6 @@ static void ReportVdpCommand(register UINT8 Op);
static const UINT8 Mask[4] = { 0x0F,0x03,0x0F,0xFF };
static const int PPB[4] = { 2,4,2,1 };
static const int PPL[4] = { 256,512,512,256 };
-static int VdpOpsCnt=1;
-static void (*VdpEngine)(void)=0;
/* SprOn SprOn SprOf SprOf */
/* ScrOf ScrOn ScrOf ScrOn */
@@ -1552,7 +1717,6 @@ static const int hmmm_timing[8]={ 818, 1111, 818, 854,
static const int lmmm_timing[8]={ 1160, 1599, 1160, 1172,
964, 1257, 964, 977 };
-
/** VDPVRMP() **********************************************/
/** Calculate addr of a pixel in vram **/
/*************************************************************/
@@ -1712,17 +1876,17 @@ static int GetVdpTimingValue(register const int *timing_values)
/*************************************************************/
void SrchEngine(void)
{
- register int SX=MMC.SX;
- register int SY=MMC.SY;
- register int TX=MMC.TX;
- register int ANX=MMC.ANX;
- register UINT8 CL=MMC.CL;
- register int MXD = MMC.MXD;
+ register int SX=vdp->MMC.SX;
+ register int SY=vdp->MMC.SY;
+ register int TX=vdp->MMC.TX;
+ register int ANX=vdp->MMC.ANX;
+ register UINT8 CL=vdp->MMC.CL;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(srch_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
#define pre_srch \
pre_loop \
@@ -1750,16 +1914,16 @@ void SrchEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
/* Update SX in VDP registers */
VDPStatus[8]=SX&0xFF;
VDPStatus[9]=(SX>>8)|0xFE;
}
else {
- MMC.SX=SX;
+ vdp->MMC.SX=SX;
}
}
@@ -1768,22 +1932,22 @@ void SrchEngine(void)
/*************************************************************/
void LineEngine(void)
{
- register int DX=MMC.DX;
- register int DY=MMC.DY;
- register int TX=MMC.TX;
- register int TY=MMC.TY;
- register int NX=MMC.NX;
- register int NY=MMC.NY;
- register int ASX=MMC.ASX;
- register int ADX=MMC.ADX;
- register UINT8 CL=MMC.CL;
- register UINT8 LO=MMC.LO;
- register int MXD = MMC.MXD;
+ register int DX=vdp->MMC.DX;
+ register int DY=vdp->MMC.DY;
+ register int TX=vdp->MMC.TX;
+ register int TY=vdp->MMC.TY;
+ register int NX=vdp->MMC.NX;
+ register int NY=vdp->MMC.NY;
+ register int ASX=vdp->MMC.ASX;
+ register int ADX=vdp->MMC.ADX;
+ register UINT8 CL=vdp->MMC.CL;
+ register UINT8 LO=vdp->MMC.LO;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(line_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
#define post_linexmaj(MX) \
DX+=TX; \
@@ -1833,18 +1997,18 @@ void LineEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
VDP[38]=DY & 0xFF;
VDP[39]=(DY>>8) & 0x03;
}
else {
- MMC.DX=DX;
- MMC.DY=DY;
- MMC.ASX=ASX;
- MMC.ADX=ADX;
+ vdp->MMC.DX=DX;
+ vdp->MMC.DY=DY;
+ vdp->MMC.ASX=ASX;
+ vdp->MMC.ADX=ADX;
}
}
@@ -1853,22 +2017,22 @@ void LineEngine(void)
/*************************************************************/
void LmmvEngine(void)
{
- register int DX=MMC.DX;
- register int DY=MMC.DY;
- register int TX=MMC.TX;
- register int TY=MMC.TY;
- register int NX=MMC.NX;
- register int NY=MMC.NY;
- register int ADX=MMC.ADX;
- register int ANX=MMC.ANX;
- register UINT8 CL=MMC.CL;
- register UINT8 LO=MMC.LO;
- register int MXD = MMC.MXD;
+ register int DX=vdp->MMC.DX;
+ register int DY=vdp->MMC.DY;
+ register int TX=vdp->MMC.TX;
+ register int TY=vdp->MMC.TY;
+ register int NX=vdp->MMC.NX;
+ register int NY=vdp->MMC.NY;
+ register int ADX=vdp->MMC.ADX;
+ register int ANX=vdp->MMC.ANX;
+ register UINT8 CL=vdp->MMC.CL;
+ register UINT8 LO=vdp->MMC.LO;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(lmmv_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
switch (ScrMode) {
default:
@@ -1882,10 +2046,10 @@ void LmmvEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
if (!NY)
DY+=TY;
VDP[38]=DY & 0xFF;
@@ -1894,10 +2058,10 @@ void LmmvEngine(void)
VDP[43]=(NY>>8) & 0x03;
}
else {
- MMC.DY=DY;
- MMC.NY=NY;
- MMC.ANX=ANX;
- MMC.ADX=ADX;
+ vdp->MMC.DY=DY;
+ vdp->MMC.NY=NY;
+ vdp->MMC.ANX=ANX;
+ vdp->MMC.ADX=ADX;
}
}
@@ -1906,25 +2070,25 @@ void LmmvEngine(void)
/*************************************************************/
void LmmmEngine(void)
{
- register int SX=MMC.SX;
- register int SY=MMC.SY;
- register int DX=MMC.DX;
- register int DY=MMC.DY;
- register int TX=MMC.TX;
- register int TY=MMC.TY;
- register int NX=MMC.NX;
- register int NY=MMC.NY;
- register int ASX=MMC.ASX;
- register int ADX=MMC.ADX;
- register int ANX=MMC.ANX;
- register UINT8 LO=MMC.LO;
- register int MXS = MMC.MXS;
- register int MXD = MMC.MXD;
+ register int SX=vdp->MMC.SX;
+ register int SY=vdp->MMC.SY;
+ register int DX=vdp->MMC.DX;
+ register int DY=vdp->MMC.DY;
+ register int TX=vdp->MMC.TX;
+ register int TY=vdp->MMC.TY;
+ register int NX=vdp->MMC.NX;
+ register int NY=vdp->MMC.NY;
+ register int ASX=vdp->MMC.ASX;
+ register int ADX=vdp->MMC.ADX;
+ register int ANX=vdp->MMC.ANX;
+ register UINT8 LO=vdp->MMC.LO;
+ register int MXS = vdp->MMC.MXS;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(lmmm_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
switch (ScrMode) {
default:
@@ -1938,10 +2102,10 @@ void LmmmEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
if (!NY) {
SY+=TY;
DY+=TY;
@@ -1957,12 +2121,12 @@ void LmmmEngine(void)
VDP[39]=(DY>>8) & 0x03;
}
else {
- MMC.SY=SY;
- MMC.DY=DY;
- MMC.NY=NY;
- MMC.ANX=ANX;
- MMC.ASX=ASX;
- MMC.ADX=ADX;
+ vdp->MMC.SY=SY;
+ vdp->MMC.DY=DY;
+ vdp->MMC.NY=NY;
+ vdp->MMC.ANX=ANX;
+ vdp->MMC.ASX=ASX;
+ vdp->MMC.ADX=ADX;
}
}
@@ -1973,24 +2137,24 @@ void LmcmEngine(void)
{
if ((VDPStatus[2]&0x80)!=0x80) {
- VDPStatus[7]=VDP[44]=VDP_POINT(((ScrMode >= 5) && (ScrMode <= 8)) ? (ScrMode-5) : 0, MMC.MXS, MMC.ASX, MMC.SY);
- VdpOpsCnt-=GetVdpTimingValue(lmmv_timing);
+ VDPStatus[7]=VDP[44]=VDP_POINT(((ScrMode >= 5) && (ScrMode <= 8)) ? (ScrMode-5) : 0, vdp->MMC.MXS, vdp->MMC.ASX, vdp->MMC.SY);
+ vdp->VdpOpsCnt-=GetVdpTimingValue(lmmv_timing);
VDPStatus[2]|=0x80;
- if (!--MMC.ANX || ((MMC.ASX+=MMC.TX)&MMC.MX)) {
- if (!(--MMC.NY & 1023) || (MMC.SY+=MMC.TY)==-1) {
+ if (!--vdp->MMC.ANX || ((vdp->MMC.ASX+=vdp->MMC.TX)&vdp->MMC.MX)) {
+ if (!(--vdp->MMC.NY & 1023) || (vdp->MMC.SY+=vdp->MMC.TY)==-1) {
VDPStatus[2]&=0xFE;
- VdpEngine=0;
- if (!MMC.NY)
- MMC.DY+=MMC.TY;
- VDP[42]=MMC.NY & 0xFF;
- VDP[43]=(MMC.NY>>8) & 0x03;
- VDP[34]=MMC.SY & 0xFF;
- VDP[35]=(MMC.SY>>8) & 0x03;
+ vdp->VdpEngine=0;
+ if (!vdp->MMC.NY)
+ vdp->MMC.DY+=vdp->MMC.TY;
+ VDP[42]=vdp->MMC.NY & 0xFF;
+ VDP[43]=(vdp->MMC.NY>>8) & 0x03;
+ VDP[34]=vdp->MMC.SY & 0xFF;
+ VDP[35]=(vdp->MMC.SY>>8) & 0x03;
}
else {
- MMC.ASX=MMC.SX;
- MMC.ANX=MMC.NX;
+ vdp->MMC.ASX=vdp->MMC.SX;
+ vdp->MMC.ANX=vdp->MMC.NX;
}
}
}
@@ -2005,24 +2169,24 @@ void LmmcEngine(void)
register UINT8 SM=((ScrMode >= 5) && (ScrMode <= 8)) ? (ScrMode-5) : 0;
VDPStatus[7]=VDP[44]&=Mask[SM];
- VDP_PSET(SM, MMC.MXD, MMC.ADX, MMC.DY, VDP[44], MMC.LO);
- VdpOpsCnt-=GetVdpTimingValue(lmmv_timing);
+ VDP_PSET(SM, vdp->MMC.MXD, vdp->MMC.ADX, vdp->MMC.DY, VDP[44], vdp->MMC.LO);
+ vdp->VdpOpsCnt-=GetVdpTimingValue(lmmv_timing);
VDPStatus[2]|=0x80;
- if (!--MMC.ANX || ((MMC.ADX+=MMC.TX)&MMC.MX)) {
- if (!(--MMC.NY&1023) || (MMC.DY+=MMC.TY)==-1) {
+ if (!--vdp->MMC.ANX || ((vdp->MMC.ADX+=vdp->MMC.TX)&vdp->MMC.MX)) {
+ if (!(--vdp->MMC.NY&1023) || (vdp->MMC.DY+=vdp->MMC.TY)==-1) {
VDPStatus[2]&=0xFE;
- VdpEngine=0;
- if (!MMC.NY)
- MMC.DY+=MMC.TY;
- VDP[42]=MMC.NY & 0xFF;
- VDP[43]=(MMC.NY>>8) & 0x03;
- VDP[38]=MMC.DY & 0xFF;
- VDP[39]=(MMC.DY>>8) & 0x03;
+ vdp->VdpEngine=0;
+ if (!vdp->MMC.NY)
+ vdp->MMC.DY+=vdp->MMC.TY;
+ VDP[42]=vdp->MMC.NY & 0xFF;
+ VDP[43]=(vdp->MMC.NY>>8) & 0x03;
+ VDP[38]=vdp->MMC.DY & 0xFF;
+ VDP[39]=(vdp->MMC.DY>>8) & 0x03;
}
else {
- MMC.ADX=MMC.DX;
- MMC.ANX=MMC.NX;
+ vdp->MMC.ADX=vdp->MMC.DX;
+ vdp->MMC.ANX=vdp->MMC.NX;
}
}
}
@@ -2033,21 +2197,21 @@ void LmmcEngine(void)
/*************************************************************/
void HmmvEngine(void)
{
- register int DX=MMC.DX;
- register int DY=MMC.DY;
- register int TX=MMC.TX;
- register int TY=MMC.TY;
- register int NX=MMC.NX;
- register int NY=MMC.NY;
- register int ADX=MMC.ADX;
- register int ANX=MMC.ANX;
- register UINT8 CL=MMC.CL;
- register int MXD = MMC.MXD;
+ register int DX=vdp->MMC.DX;
+ register int DY=vdp->MMC.DY;
+ register int TX=vdp->MMC.TX;
+ register int TY=vdp->MMC.TY;
+ register int NX=vdp->MMC.NX;
+ register int NY=vdp->MMC.NY;
+ register int ADX=vdp->MMC.ADX;
+ register int ANX=vdp->MMC.ANX;
+ register UINT8 CL=vdp->MMC.CL;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(hmmv_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
switch (ScrMode) {
default:
@@ -2061,10 +2225,10 @@ void HmmvEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
if (!NY)
DY+=TY;
VDP[42]=NY & 0xFF;
@@ -2073,10 +2237,10 @@ void HmmvEngine(void)
VDP[39]=(DY>>8) & 0x03;
}
else {
- MMC.DY=DY;
- MMC.NY=NY;
- MMC.ANX=ANX;
- MMC.ADX=ADX;
+ vdp->MMC.DY=DY;
+ vdp->MMC.NY=NY;
+ vdp->MMC.ANX=ANX;
+ vdp->MMC.ADX=ADX;
}
}
@@ -2085,24 +2249,24 @@ void HmmvEngine(void)
/*************************************************************/
void HmmmEngine(void)
{
- register int SX=MMC.SX;
- register int SY=MMC.SY;
- register int DX=MMC.DX;
- register int DY=MMC.DY;
- register int TX=MMC.TX;
- register int TY=MMC.TY;
- register int NX=MMC.NX;
- register int NY=MMC.NY;
- register int ASX=MMC.ASX;
- register int ADX=MMC.ADX;
- register int ANX=MMC.ANX;
- register int MXS = MMC.MXS;
- register int MXD = MMC.MXD;
+ register int SX=vdp->MMC.SX;
+ register int SY=vdp->MMC.SY;
+ register int DX=vdp->MMC.DX;
+ register int DY=vdp->MMC.DY;
+ register int TX=vdp->MMC.TX;
+ register int TY=vdp->MMC.TY;
+ register int NX=vdp->MMC.NX;
+ register int NY=vdp->MMC.NY;
+ register int ASX=vdp->MMC.ASX;
+ register int ADX=vdp->MMC.ADX;
+ register int ANX=vdp->MMC.ANX;
+ register int MXS = vdp->MMC.MXS;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(hmmm_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
switch (ScrMode) {
default:
@@ -2116,10 +2280,10 @@ void HmmmEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
if (!NY) {
SY+=TY;
DY+=TY;
@@ -2135,12 +2299,12 @@ void HmmmEngine(void)
VDP[39]=(DY>>8) & 0x03;
}
else {
- MMC.SY=SY;
- MMC.DY=DY;
- MMC.NY=NY;
- MMC.ANX=ANX;
- MMC.ASX=ASX;
- MMC.ADX=ADX;
+ vdp->MMC.SY=SY;
+ vdp->MMC.DY=DY;
+ vdp->MMC.NY=NY;
+ vdp->MMC.ANX=ANX;
+ vdp->MMC.ASX=ASX;
+ vdp->MMC.ADX=ADX;
}
}
@@ -2149,19 +2313,19 @@ void HmmmEngine(void)
/*************************************************************/
void YmmmEngine(void)
{
- register int SY=MMC.SY;
- register int DX=MMC.DX;
- register int DY=MMC.DY;
- register int TX=MMC.TX;
- register int TY=MMC.TY;
- register int NY=MMC.NY;
- register int ADX=MMC.ADX;
- register int MXD = MMC.MXD;
+ register int SY=vdp->MMC.SY;
+ register int DX=vdp->MMC.DX;
+ register int DY=vdp->MMC.DY;
+ register int TX=vdp->MMC.TX;
+ register int TY=vdp->MMC.TY;
+ register int NY=vdp->MMC.NY;
+ register int ADX=vdp->MMC.ADX;
+ register int MXD = vdp->MMC.MXD;
register int cnt;
register int delta;
delta = GetVdpTimingValue(ymmm_timing);
- cnt = VdpOpsCnt;
+ cnt = vdp->VdpOpsCnt;
switch (ScrMode) {
default:
@@ -2175,10 +2339,10 @@ void YmmmEngine(void)
break;
}
- if ((VdpOpsCnt=cnt)>0) {
+ if ((vdp->VdpOpsCnt=cnt)>0) {
/* Command execution done */
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
if (!NY) {
SY+=TY;
DY+=TY;
@@ -2194,10 +2358,10 @@ void YmmmEngine(void)
VDP[39]=(DY>>8) & 0x03;
}
else {
- MMC.SY=SY;
- MMC.DY=DY;
- MMC.NY=NY;
- MMC.ADX=ADX;
+ vdp->MMC.SY=SY;
+ vdp->MMC.DY=DY;
+ vdp->MMC.NY=NY;
+ vdp->MMC.ADX=ADX;
}
}
@@ -2208,37 +2372,37 @@ void HmmcEngine(void)
{
if ((VDPStatus[2]&0x80)!=0x80) {
- *VDP_VRMP(((ScrMode >= 5) && (ScrMode <= 8)) ? (ScrMode-5) : 0, MMC.MXD, MMC.ADX, MMC.DY)=VDP[44];
- VdpOpsCnt-=GetVdpTimingValue(hmmv_timing);
+ *VDP_VRMP(((ScrMode >= 5) && (ScrMode <= 8)) ? (ScrMode-5) : 0, vdp->MMC.MXD, vdp->MMC.ADX, vdp->MMC.DY)=VDP[44];
+ vdp->VdpOpsCnt-=GetVdpTimingValue(hmmv_timing);
VDPStatus[2]|=0x80;
- if (!--MMC.ANX || ((MMC.ADX+=MMC.TX)&MMC.MX)) {
- if (!(--MMC.NY&1023) || (MMC.DY+=MMC.TY)==-1) {
+ if (!--vdp->MMC.ANX || ((vdp->MMC.ADX+=vdp->MMC.TX)&vdp->MMC.MX)) {
+ if (!(--vdp->MMC.NY&1023) || (vdp->MMC.DY+=vdp->MMC.TY)==-1) {
VDPStatus[2]&=0xFE;
- VdpEngine=0;
- if (!MMC.NY)
- MMC.DY+=MMC.TY;
- VDP[42]=MMC.NY & 0xFF;
- VDP[43]=(MMC.NY>>8) & 0x03;
- VDP[38]=MMC.DY & 0xFF;
- VDP[39]=(MMC.DY>>8) & 0x03;
+ vdp->VdpEngine=0;
+ if (!vdp->MMC.NY)
+ vdp->MMC.DY+=vdp->MMC.TY;
+ VDP[42]=vdp->MMC.NY & 0xFF;
+ VDP[43]=(vdp->MMC.NY>>8) & 0x03;
+ VDP[38]=vdp->MMC.DY & 0xFF;
+ VDP[39]=(vdp->MMC.DY>>8) & 0x03;
}
else {
- MMC.ADX=MMC.DX;
- MMC.ANX=MMC.NX;
+ vdp->MMC.ADX=vdp->MMC.DX;
+ vdp->MMC.ANX=vdp->MMC.NX;
}
}
}
}
/** VDPWrite() ***********************************************/
-/** Use this function to transfer pixel(s) from CPU to VDP. **/
+/** Use this function to transfer pixel(s) from CPU to vdp-> **/
/*************************************************************/
static void v9938_cpu_to_vdp (UINT8 V)
{
VDPStatus[2]&=0x7F;
VDPStatus[7]=VDP[44]=V;
- if(VdpEngine&&(VdpOpsCnt>0)) VdpEngine();
+ if(vdp->VdpEngine&&(vdp->VdpOpsCnt>0)) vdp->VdpEngine();
}
/** VDPRead() ************************************************/
@@ -2247,7 +2411,7 @@ static void v9938_cpu_to_vdp (UINT8 V)
static UINT8 v9938_vdp_to_cpu (void)
{
VDPStatus[2]&=0x7F;
- if(VdpEngine&&(VdpOpsCnt>0)) VdpEngine();
+ if(vdp->VdpEngine&&(vdp->VdpOpsCnt>0)) vdp->VdpEngine();
return(VDP[44]);
}
@@ -2256,6 +2420,7 @@ static UINT8 v9938_vdp_to_cpu (void)
/*************************************************************/
static void ReportVdpCommand(register UINT8 Op)
{
+#if VERBOSE
static const char *const Ops[16] =
{
"SET ","AND ","OR ","XOR ","NOT ","NOP ","NOP ","NOP ",
@@ -2266,6 +2431,7 @@ static void ReportVdpCommand(register UINT8 Op)
" ABRT"," ????"," ????"," ????","POINT"," PSET"," SRCH"," LINE",
" LMMV"," LMMM"," LMCM"," LMMC"," HMMV"," HMMM"," YMMM"," HMMC"
};
+#endif
register UINT8 CL, CM, LO;
register int SX,SY, DX,DY, NX,NY;
@@ -2281,12 +2447,12 @@ static void ReportVdpCommand(register UINT8 Op)
CM = Op>>4;
LO = Op&0x0F;
- logerror ("V9938: Opcode %02Xh %s-%s (%d,%d)->(%d,%d),%d [%d,%d]%s\n",
+ LOG(("V9938: Opcode %02Xh %s-%s (%d,%d)->(%d,%d),%d [%d,%d]%s\n",
Op, Commands[CM], Ops[LO],
SX,SY, DX,DY, CL, VDP[45]&0x04? -NX:NX,
VDP[45]&0x08? -NY:NY,
VDP[45]&0x70? " on ExtVRAM":""
- );
+ ));
}
/** VDPDraw() ************************************************/
@@ -2302,8 +2468,8 @@ static UINT8 v9938_command_unit_w (UINT8 Op)
SM = ScrMode-5; /* Screen mode index 0..3 */
- MMC.CM = Op>>4;
- if ((MMC.CM & 0x0C) != 0x0C && MMC.CM != 0)
+ vdp->MMC.CM = Op>>4;
+ if ((vdp->MMC.CM & 0x0C) != 0x0C && vdp->MMC.CM != 0)
/* Dot operation: use only relevant bits of color */
VDPStatus[7]=(VDP[44]&=Mask[SM]);
@@ -2313,11 +2479,11 @@ static UINT8 v9938_command_unit_w (UINT8 Op)
switch(Op>>4) {
case CM_ABRT:
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
return 1;
case CM_POINT:
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
VDPStatus[7]=VDP[44]=
VDP_POINT(SM, (VDP[45] & 0x10) != 0,
VDP[32]+((int)VDP[33]<<8),
@@ -2325,7 +2491,7 @@ static UINT8 v9938_command_unit_w (UINT8 Op)
return 1;
case CM_PSET:
VDPStatus[2]&=0xFE;
- VdpEngine=0;
+ vdp->VdpEngine=0;
VDP_PSET(SM, (VDP[45] & 0x20) != 0,
VDP[36]+((int)VDP[37]<<8),
VDP[38]+((int)VDP[39]<<8),
@@ -2333,84 +2499,84 @@ static UINT8 v9938_command_unit_w (UINT8 Op)
Op&0x0F);
return 1;
case CM_SRCH:
- VdpEngine=SrchEngine;
+ vdp->VdpEngine=SrchEngine;
break;
case CM_LINE:
- VdpEngine=LineEngine;
+ vdp->VdpEngine=LineEngine;
break;
case CM_LMMV:
- VdpEngine=LmmvEngine;
+ vdp->VdpEngine=LmmvEngine;
break;
case CM_LMMM:
- VdpEngine=LmmmEngine;
+ vdp->VdpEngine=LmmmEngine;
break;
case CM_LMCM:
- VdpEngine=LmcmEngine;
+ vdp->VdpEngine=LmcmEngine;
break;
case CM_LMMC:
- VdpEngine=LmmcEngine;
+ vdp->VdpEngine=LmmcEngine;
break;
case CM_HMMV:
- VdpEngine=HmmvEngine;
+ vdp->VdpEngine=HmmvEngine;
break;
case CM_HMMM:
- VdpEngine=HmmmEngine;
+ vdp->VdpEngine=HmmmEngine;
break;
case CM_YMMM:
- VdpEngine=YmmmEngine;
+ vdp->VdpEngine=YmmmEngine;
break;
case CM_HMMC:
- VdpEngine=HmmcEngine;
+ vdp->VdpEngine=HmmcEngine;
break;
default:
- logerror("V9938: Unrecognized opcode %02Xh\n",Op);
+ LOG(("V9938: Unrecognized opcode %02Xh\n",Op));
return(0);
}
/* Fetch unconditional arguments */
- MMC.SX = (VDP[32]+((int)VDP[33]<<8)) & 511;
- MMC.SY = (VDP[34]+((int)VDP[35]<<8)) & 1023;
- MMC.DX = (VDP[36]+((int)VDP[37]<<8)) & 511;
- MMC.DY = (VDP[38]+((int)VDP[39]<<8)) & 1023;
- MMC.NY = (VDP[42]+((int)VDP[43]<<8)) & 1023;
- MMC.TY = VDP[45]&0x08? -1:1;
- MMC.MX = PPL[SM];
- MMC.CL = VDP[44];
- MMC.LO = Op&0x0F;
- MMC.MXS = (VDP[45] & 0x10) != 0;
- MMC.MXD = (VDP[45] & 0x20) != 0;
+ vdp->MMC.SX = (VDP[32]+((int)VDP[33]<<8)) & 511;
+ vdp->MMC.SY = (VDP[34]+((int)VDP[35]<<8)) & 1023;
+ vdp->MMC.DX = (VDP[36]+((int)VDP[37]<<8)) & 511;
+ vdp->MMC.DY = (VDP[38]+((int)VDP[39]<<8)) & 1023;
+ vdp->MMC.NY = (VDP[42]+((int)VDP[43]<<8)) & 1023;
+ vdp->MMC.TY = VDP[45]&0x08? -1:1;
+ vdp->MMC.MX = PPL[SM];
+ vdp->MMC.CL = VDP[44];
+ vdp->MMC.LO = Op&0x0F;
+ vdp->MMC.MXS = (VDP[45] & 0x10) != 0;
+ vdp->MMC.MXD = (VDP[45] & 0x20) != 0;
/* Argument depends on UINT8 or dot operation */
- if ((MMC.CM & 0x0C) == 0x0C) {
- MMC.TX = VDP[45]&0x04? -PPB[SM]:PPB[SM];
- MMC.NX = ((VDP[40]+((int)VDP[41]<<8)) & 1023)/PPB[SM];
+ if ((vdp->MMC.CM & 0x0C) == 0x0C) {
+ vdp->MMC.TX = VDP[45]&0x04? -PPB[SM]:PPB[SM];
+ vdp->MMC.NX = ((VDP[40]+((int)VDP[41]<<8)) & 1023)/PPB[SM];
}
else {
- MMC.TX = VDP[45]&0x04? -1:1;
- MMC.NX = (VDP[40]+((int)VDP[41]<<8)) & 1023;
+ vdp->MMC.TX = VDP[45]&0x04? -1:1;
+ vdp->MMC.NX = (VDP[40]+((int)VDP[41]<<8)) & 1023;
}
/* X loop variables are treated specially for LINE command */
- if (MMC.CM == CM_LINE) {
- MMC.ASX=((MMC.NX-1)>>1);
- MMC.ADX=0;
+ if (vdp->MMC.CM == CM_LINE) {
+ vdp->MMC.ASX=((vdp->MMC.NX-1)>>1);
+ vdp->MMC.ADX=0;
}
else {
- MMC.ASX = MMC.SX;
- MMC.ADX = MMC.DX;
+ vdp->MMC.ASX = vdp->MMC.SX;
+ vdp->MMC.ADX = vdp->MMC.DX;
}
/* NX loop variable is treated specially for SRCH command */
- if (MMC.CM == CM_SRCH)
- MMC.ANX=(VDP[45]&0x02)!=0; /* Do we look for "==" or "!="? */
+ if (vdp->MMC.CM == CM_SRCH)
+ vdp->MMC.ANX=(VDP[45]&0x02)!=0; /* Do we look for "==" or "!="? */
else
- MMC.ANX = MMC.NX;
+ vdp->MMC.ANX = vdp->MMC.NX;
/* Command execution started */
VDPStatus[2]|=0x01;
/* Start execution if we still have time slices */
- if(VdpEngine&&(VdpOpsCnt>0)) VdpEngine();
+ if(vdp->VdpEngine&&(vdp->VdpOpsCnt>0)) vdp->VdpEngine();
/* Operation successfull initiated */
return(1);
@@ -2421,15 +2587,15 @@ static UINT8 v9938_command_unit_w (UINT8 Op)
/*************************************************************/
static void v9938_update_command (void)
{
- if(VdpOpsCnt<=0)
+ if(vdp->VdpOpsCnt<=0)
{
- VdpOpsCnt+=13662;
- if(VdpEngine&&(VdpOpsCnt>0)) VdpEngine();
+ vdp->VdpOpsCnt+=13662;
+ if(vdp->VdpEngine&&(vdp->VdpOpsCnt>0)) vdp->VdpEngine();
}
else
{
- VdpOpsCnt=13662;
- if(VdpEngine) VdpEngine();
+ vdp->VdpOpsCnt=13662;
+ if(vdp->VdpEngine) vdp->VdpEngine();
}
}
diff --git a/src/emu/video/v9938.h b/src/emu/video/v9938.h
index 015fd2b8d91..f6b604de0bd 100644
--- a/src/emu/video/v9938.h
+++ b/src/emu/video/v9938.h
@@ -14,19 +14,26 @@
#define RENDER_LOW (1)
#define RENDER_AUTO (2)
-void v9938_init (running_machine *, int, int, void (*callback)(int));
-void v9938_reset (void);
-int v9938_interrupt (void);
-void v9938_set_sprite_limit (int);
-void v9938_set_resolution (int);
+void v9938_init (running_machine *, int which, bitmap_t *bitmap, int, int, void (*callback)(int));
+void v9938_reset (int which);
+int v9938_interrupt (int which);
+void v9938_set_sprite_limit (int which, int);
+void v9938_set_resolution (int which, int);
+int v9938_get_transpen(int which);
extern PALETTE_INIT( v9938 );
extern PALETTE_INIT( v9958 );
-extern WRITE8_HANDLER( v9938_palette_w );
-extern WRITE8_HANDLER( v9938_vram_w );
-extern READ8_HANDLER( v9938_vram_r );
-extern WRITE8_HANDLER( v9938_command_w );
-extern READ8_HANDLER( v9938_status_r );
-extern WRITE8_HANDLER( v9938_register_w );
-
-void v9938_update_mouse_state(int mx_delta, int my_delta, int button_state);
+extern WRITE8_HANDLER( v9938_0_palette_w );
+extern WRITE8_HANDLER( v9938_1_palette_w );
+extern WRITE8_HANDLER( v9938_0_vram_w );
+extern WRITE8_HANDLER( v9938_1_vram_w );
+extern READ8_HANDLER( v9938_0_vram_r );
+extern READ8_HANDLER( v9938_1_vram_r );
+extern WRITE8_HANDLER( v9938_0_command_w );
+extern WRITE8_HANDLER( v9938_1_command_w );
+extern READ8_HANDLER( v9938_0_status_r );
+extern READ8_HANDLER( v9938_1_status_r );
+extern WRITE8_HANDLER( v9938_0_register_w );
+extern WRITE8_HANDLER( v9938_1_register_w );
+
+void v9938_update_mouse_state(int which, int mx_delta, int my_delta, int button_state);
diff --git a/src/emu/video/v9938mod.c b/src/emu/video/v9938mod.c
index 8190bfacb01..be52843fc17 100644
--- a/src/emu/video/v9938mod.c
+++ b/src/emu/video/v9938mod.c
@@ -37,11 +37,11 @@ V9938_BORDER_FUNC (default_border)
PEN_TYPE pen;
int i;
- pen = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
i = V9938_WIDTH;
while (i--) *ln++ = pen;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_BORDER_FUNC (graphic7_border)
@@ -49,11 +49,11 @@ V9938_BORDER_FUNC (graphic7_border)
PEN_TYPE pen;
int i;
- pen = Machine->pens[pal_ind256[vdp.contReg[7]]];
+ pen = Machine->pens[vdp->pal_ind256[vdp->contReg[7]]];
i = V9938_WIDTH;
while (i--) *ln++ = pen;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_BORDER_FUNC (graphic5_border)
@@ -63,16 +63,16 @@ V9938_BORDER_FUNC (graphic5_border)
#if (V9938_WIDTH > 512)
PEN_TYPE pen1;
- pen1 = Machine->pens[pal_ind16[(vdp.contReg[7]&0x03)]];
- pen0 = Machine->pens[pal_ind16[((vdp.contReg[7]>>2)&0x03)]];
+ pen1 = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x03)]];
+ pen0 = Machine->pens[vdp->pal_ind16[((vdp->contReg[7]>>2)&0x03)]];
i = (V9938_WIDTH) / 2;
while (i--) { *ln++ = pen0; *ln++ = pen1; }
#else
- pen0 = Machine->pens[pal_ind16[((vdp.contReg[7]>>2)&0x03)]];
+ pen0 = Machine->pens[vdp->pal_ind16[((vdp->contReg[7]>>2)&0x03)]];
i = V9938_WIDTH;
while (i--) *ln++ = pen0;
#endif
- vdp.size_now = RENDER_HIGH;
+ vdp->size_now = RENDER_HIGH;
}
V9938_MODE_FUNC (mode_text1)
@@ -81,17 +81,17 @@ V9938_MODE_FUNC (mode_text1)
PEN_TYPE fg, bg, pen;
UINT8 *nametbl, *patterntbl;
- patterntbl = vdp.vram + (vdp.contReg[4] << 11);
- nametbl = vdp.vram + (vdp.contReg[2] << 10);
+ patterntbl = vdp->vram + (vdp->contReg[4] << 11);
+ nametbl = vdp->vram + (vdp->contReg[2] << 10);
- fg = Machine->pens[pal_ind16[vdp.contReg[7] >> 4]];
- bg = Machine->pens[pal_ind16[vdp.contReg[7] & 15]];
+ fg = Machine->pens[vdp->pal_ind16[vdp->contReg[7] >> 4]];
+ bg = Machine->pens[vdp->pal_ind16[vdp->contReg[7] & 15]];
name = (line/8)*40;
- pen = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
- xxx = vdp.offset_x + 8;
+ xxx = vdp->offset_x + 8;
#if (V9938_WIDTH > 512)
xxx *= 2;
#endif
@@ -100,7 +100,7 @@ V9938_MODE_FUNC (mode_text1)
for (x=0;x<40;x++)
{
pattern = patterntbl[(nametbl[name] * 8) +
- ((line + vdp.contReg[23]) & 7)];
+ ((line + vdp->contReg[23]) & 7)];
for (xx=0;xx<6;xx++)
{
*ln++ = (pattern & 0x80) ? fg : bg;
@@ -113,12 +113,12 @@ V9938_MODE_FUNC (mode_text1)
name = (name + 1) & 0x3ff;
}
- xxx = (16 - vdp.offset_x) + 8;
+ xxx = (16 - vdp->offset_x) + 8;
#if (V9938_WIDTH > 512)
xxx *= 2;
#endif
while (xxx--) *ln++ = pen;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_MODE_FUNC (mode_text2)
@@ -127,25 +127,25 @@ V9938_MODE_FUNC (mode_text2)
PEN_TYPE fg, bg, fg0, bg0, pen;
UINT8 *nametbl, *patterntbl, *colourtbl;
- patterntbl = vdp.vram + (vdp.contReg[4] << 11);
- colourtbl = vdp.vram + ((vdp.contReg[3] & 0xf8) << 6) + (vdp.contReg[10] << 14);
+ patterntbl = vdp->vram + (vdp->contReg[4] << 11);
+ colourtbl = vdp->vram + ((vdp->contReg[3] & 0xf8) << 6) + (vdp->contReg[10] << 14);
#if 0
- colourmask = ((vdp.contReg[3] & 7) << 5) | 0x1f; /* cause a bug in Forth+ v1.0 on Geneve */
+ colourmask = ((vdp->contReg[3] & 7) << 5) | 0x1f; /* cause a bug in Forth+ v1.0 on Geneve */
#else
- colourmask = ((vdp.contReg[3] & 7) << 6) | 0x3f; /* verify! */
+ colourmask = ((vdp->contReg[3] & 7) << 6) | 0x3f; /* verify! */
#endif
- nametbl = vdp.vram + ((vdp.contReg[2] & 0xfc) << 10);
- patternmask = ((vdp.contReg[2] & 3) << 10) | 0x3ff; /* seems correct */
+ nametbl = vdp->vram + ((vdp->contReg[2] & 0xfc) << 10);
+ patternmask = ((vdp->contReg[2] & 3) << 10) | 0x3ff; /* seems correct */
- fg = Machine->pens[pal_ind16[vdp.contReg[7] >> 4]];
- bg = Machine->pens[pal_ind16[vdp.contReg[7] & 15]];
- fg0 = Machine->pens[pal_ind16[vdp.contReg[12] >> 4]];
- bg0 = Machine->pens[pal_ind16[vdp.contReg[12] & 15]];
+ fg = Machine->pens[vdp->pal_ind16[vdp->contReg[7] >> 4]];
+ bg = Machine->pens[vdp->pal_ind16[vdp->contReg[7] & 15]];
+ fg0 = Machine->pens[vdp->pal_ind16[vdp->contReg[12] >> 4]];
+ bg0 = Machine->pens[vdp->pal_ind16[vdp->contReg[12] & 15]];
name = (line/8)*80;
- xxx = vdp.offset_x + 8;
- pen = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ xxx = vdp->offset_x + 8;
+ pen = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
#if (V9938_WIDTH > 512)
xxx *= 2;
#endif
@@ -154,13 +154,13 @@ V9938_MODE_FUNC (mode_text2)
for (x=0;x<80;x++)
{
charcode = nametbl[name&patternmask];
- if (vdp.blink)
+ if (vdp->blink)
{
pattern = colourtbl[(name/8)&colourmask];
if (pattern & (0x80 >> (name & 7) ) )
{
pattern = patterntbl[(charcode * 8) +
- ((line + vdp.contReg[23]) & 7)];
+ ((line + vdp->contReg[23]) & 7)];
#if (V9938_WIDTH > 512)
*ln++ = (pattern & 0x80) ? fg0 : bg0;
@@ -181,7 +181,7 @@ V9938_MODE_FUNC (mode_text2)
}
pattern = patterntbl[(charcode * 8) +
- ((line + vdp.contReg[23]) & 7)];
+ ((line + vdp->contReg[23]) & 7)];
#if (V9938_WIDTH > 512)
*ln++ = (pattern & 0x80) ? fg : bg;
@@ -199,12 +199,12 @@ V9938_MODE_FUNC (mode_text2)
name++;
}
- xxx = 16 - vdp.offset_x + 8;
+ xxx = 16 - vdp->offset_x + 8;
#if (V9938_WIDTH > 512)
xxx *= 2;
#endif
while (xxx--) *ln++ = pen;
- vdp.size_now = RENDER_HIGH;
+ vdp->size_now = RENDER_HIGH;
}
V9938_MODE_FUNC (mode_multi)
@@ -213,24 +213,24 @@ V9938_MODE_FUNC (mode_multi)
int name, line2, x, xx;
PEN_TYPE pen, pen_bg;
- nametbl = vdp.vram + (vdp.contReg[2] << 10);
- patterntbl = vdp.vram + (vdp.contReg[4] << 11);
+ nametbl = vdp->vram + (vdp->contReg[2] << 10);
+ patterntbl = vdp->vram + (vdp->contReg[4] << 11);
- line2 = (line - vdp.contReg[23]) & 255;
+ line2 = (line - vdp->contReg[23]) & 255;
name = (line2/8)*32;
- pen_bg = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen_bg = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
#if (V9938_WIDTH < 512)
- xx = vdp.offset_x;
+ xx = vdp->offset_x;
#else
- xx = vdp.offset_x * 2;
+ xx = vdp->offset_x * 2;
#endif
while (xx--) *ln++ = pen_bg;
for (x=0;x<32;x++)
{
colour = patterntbl[(nametbl[name] * 8) + ((line2/4)&7)];
- pen = Machine->pens[pal_ind16[colour>>4]];
+ pen = Machine->pens[vdp->pal_ind16[colour>>4]];
/* eight pixels */
*ln++ = pen;
*ln++ = pen;
@@ -242,7 +242,7 @@ V9938_MODE_FUNC (mode_multi)
*ln++ = pen;
*ln++ = pen;
#endif
- pen = Machine->pens[pal_ind16[colour&15]];
+ pen = Machine->pens[vdp->pal_ind16[colour&15]];
/* eight pixels */
*ln++ = pen;
*ln++ = pen;
@@ -257,12 +257,12 @@ V9938_MODE_FUNC (mode_multi)
name++;
}
- xx = 16 - vdp.offset_x;
+ xx = 16 - vdp->offset_x;
#if (V9938_WIDTH > 512)
xx *= 2;
#endif
while (xx--) *ln++ = pen_bg;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_MODE_FUNC (mode_graphic1)
@@ -271,19 +271,19 @@ V9938_MODE_FUNC (mode_graphic1)
UINT8 *nametbl, *patterntbl, *colourtbl;
int pattern, x, xx, line2, name, charcode, colour, xxx;
- nametbl = vdp.vram + (vdp.contReg[2] << 10);
- colourtbl = vdp.vram + (vdp.contReg[3] << 6) + (vdp.contReg[10] << 14);
- patterntbl = vdp.vram + (vdp.contReg[4] << 11);
+ nametbl = vdp->vram + (vdp->contReg[2] << 10);
+ colourtbl = vdp->vram + (vdp->contReg[3] << 6) + (vdp->contReg[10] << 14);
+ patterntbl = vdp->vram + (vdp->contReg[4] << 11);
- line2 = (line - vdp.contReg[23]) & 255;
+ line2 = (line - vdp->contReg[23]) & 255;
name = (line2/8)*32;
- pen = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
#if (V9938_WIDTH < 512)
- xxx = vdp.offset_x;
+ xxx = vdp->offset_x;
#else
- xxx = vdp.offset_x * 2;
+ xxx = vdp->offset_x * 2;
#endif
while (xxx--) *ln++ = pen;
@@ -291,8 +291,8 @@ V9938_MODE_FUNC (mode_graphic1)
{
charcode = nametbl[name];
colour = colourtbl[charcode/8];
- fg = Machine->pens[pal_ind16[colour>>4]];
- bg = Machine->pens[pal_ind16[colour&15]];
+ fg = Machine->pens[vdp->pal_ind16[colour>>4]];
+ bg = Machine->pens[vdp->pal_ind16[colour&15]];
pattern = patterntbl[charcode * 8 + (line2 & 7)];
for (xx=0;xx<8;xx++)
@@ -306,12 +306,12 @@ V9938_MODE_FUNC (mode_graphic1)
name++;
}
- xx = 16 - vdp.offset_x;
+ xx = 16 - vdp->offset_x;
#if (V9938_WIDTH > 512)
xx *= 2;
#endif
while (xx--) *ln++ = pen;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_MODE_FUNC (mode_graphic23)
@@ -321,21 +321,21 @@ V9938_MODE_FUNC (mode_graphic23)
int pattern, x, xx, line2, name, charcode,
colour, colourmask, patternmask, xxx;
- colourmask = (vdp.contReg[3] & 0x7f) * 8 | 7;
- patternmask = (vdp.contReg[4] & 0x03) * 256 | (colourmask & 255);
+ colourmask = (vdp->contReg[3] & 0x7f) * 8 | 7;
+ patternmask = (vdp->contReg[4] & 0x03) * 256 | (colourmask & 255);
- nametbl = vdp.vram + (vdp.contReg[2] << 10);
- colourtbl = vdp.vram + ((vdp.contReg[3] & 0x80) << 6) + (vdp.contReg[10] << 14);
- patterntbl = vdp.vram + ((vdp.contReg[4] & 0x3c) << 11);
+ nametbl = vdp->vram + (vdp->contReg[2] << 10);
+ colourtbl = vdp->vram + ((vdp->contReg[3] & 0x80) << 6) + (vdp->contReg[10] << 14);
+ patterntbl = vdp->vram + ((vdp->contReg[4] & 0x3c) << 11);
- line2 = (line + vdp.contReg[23]) & 255;
+ line2 = (line + vdp->contReg[23]) & 255;
name = (line2/8)*32;
- pen = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
#if (V9938_WIDTH < 512)
- xxx = vdp.offset_x;
+ xxx = vdp->offset_x;
#else
- xxx = vdp.offset_x * 2;
+ xxx = vdp->offset_x * 2;
#endif
while (xxx--) *ln++ = pen;
@@ -344,8 +344,8 @@ V9938_MODE_FUNC (mode_graphic23)
charcode = nametbl[name] + (line2&0xc0)*4;
colour = colourtbl[(charcode&colourmask)*8+(line2&7)];
pattern = patterntbl[(charcode&patternmask)*8+(line2&7)];
- fg = Machine->pens[pal_ind16[colour>>4]];
- bg = Machine->pens[pal_ind16[colour&15]];
+ fg = Machine->pens[vdp->pal_ind16[colour>>4]];
+ bg = Machine->pens[vdp->pal_ind16[colour&15]];
for (xx=0;xx<8;xx++)
{
*ln++ = (pattern & 0x80) ? fg : bg;
@@ -357,12 +357,12 @@ V9938_MODE_FUNC (mode_graphic23)
name++;
}
- xx = 16 - vdp.offset_x;
+ xx = 16 - vdp->offset_x;
#if (V9938_WIDTH > 512)
xx *= 2;
#endif
while (xx--) *ln++ = pen;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_MODE_FUNC (mode_graphic4)
@@ -371,43 +371,43 @@ V9938_MODE_FUNC (mode_graphic4)
int line2, linemask, x, xx;
PEN_TYPE pen, pen_bg;
- linemask = ((vdp.contReg[2] & 0x1f) << 3) | 7;
+ linemask = ((vdp->contReg[2] & 0x1f) << 3) | 7;
- line2 = ((line + vdp.contReg[23]) & linemask) & 255;
+ line2 = ((line + vdp->contReg[23]) & linemask) & 255;
- nametbl = vdp.vram + ((vdp.contReg[2] & 0x40) << 10) + line2 * 128;
- if ( (vdp.contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
+ nametbl = vdp->vram + ((vdp->contReg[2] & 0x40) << 10) + line2 * 128;
+ if ( (vdp->contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
nametbl += 0x8000;
- pen_bg = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen_bg = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
#if (V9938_WIDTH < 512)
- xx = vdp.offset_x;
+ xx = vdp->offset_x;
#else
- xx = vdp.offset_x * 2;
+ xx = vdp->offset_x * 2;
#endif
while (xx--) *ln++ = pen_bg;
for (x=0;x<128;x++)
{
colour = *nametbl++;
- pen = Machine->pens[pal_ind16[colour>>4]];
+ pen = Machine->pens[vdp->pal_ind16[colour>>4]];
*ln++ = pen;
#if (V9938_WIDTH > 512)
*ln++ = pen;
#endif
- pen = Machine->pens[pal_ind16[colour&15]];
+ pen = Machine->pens[vdp->pal_ind16[colour&15]];
*ln++ = pen;
#if (V9938_WIDTH > 512)
*ln++ = pen;
#endif
}
- xx = 16 - vdp.offset_x;
+ xx = 16 - vdp->offset_x;
#if (V9938_WIDTH > 512)
xx *= 2;
#endif
while (xx--) *ln++ = pen_bg;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_MODE_FUNC (mode_graphic5)
@@ -419,27 +419,27 @@ V9938_MODE_FUNC (mode_graphic5)
PEN_TYPE pen_bg1[4];
#endif
- linemask = ((vdp.contReg[2] & 0x1f) << 3) | 7;
+ linemask = ((vdp->contReg[2] & 0x1f) << 3) | 7;
- line2 = ((line + vdp.contReg[23]) & linemask) & 255;
+ line2 = ((line + vdp->contReg[23]) & linemask) & 255;
- nametbl = vdp.vram + ((vdp.contReg[2] & 0x40) << 10) + line2 * 128;
- if ( (vdp.contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
+ nametbl = vdp->vram + ((vdp->contReg[2] & 0x40) << 10) + line2 * 128;
+ if ( (vdp->contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
nametbl += 0x8000;
#if (V9938_WIDTH > 512)
- pen_bg1[0] = Machine->pens[pal_ind16[(vdp.contReg[7]&0x03)]];
- pen_bg0[0] = Machine->pens[pal_ind16[((vdp.contReg[7]>>2)&0x03)]];
+ pen_bg1[0] = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x03)]];
+ pen_bg0[0] = Machine->pens[vdp->pal_ind16[((vdp->contReg[7]>>2)&0x03)]];
- xx = vdp.offset_x;
+ xx = vdp->offset_x;
while (xx--) { *ln++ = pen_bg0[0]; *ln++ = pen_bg1[0]; }
- x = (vdp.contReg[8] & 0x20) ? 0 : 1;
+ x = (vdp->contReg[8] & 0x20) ? 0 : 1;
for (;x<4;x++)
{
- pen_bg0[x] = Machine->pens[pal_ind16[x]];
- pen_bg1[x] = Machine->pens[pal_ind16[x]];
+ pen_bg0[x] = Machine->pens[vdp->pal_ind16[x]];
+ pen_bg1[x] = Machine->pens[vdp->pal_ind16[x]];
}
for (x=0;x<128;x++)
@@ -452,19 +452,19 @@ V9938_MODE_FUNC (mode_graphic5)
*ln++ = pen_bg1[(colour&3)];
}
- pen_bg1[0] = Machine->pens[pal_ind16[(vdp.contReg[7]&0x03)]];
- pen_bg0[0] = Machine->pens[pal_ind16[((vdp.contReg[7]>>2)&0x03)]];
- xx = 16 - vdp.offset_x;
+ pen_bg1[0] = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x03)]];
+ pen_bg0[0] = Machine->pens[vdp->pal_ind16[((vdp->contReg[7]>>2)&0x03)]];
+ xx = 16 - vdp->offset_x;
while (xx--) { *ln++ = pen_bg0[0]; *ln++ = pen_bg1[0]; }
#else
- pen_bg0[0] = Machine->pens[pal_ind16[((vdp.contReg[7]>>2)&0x03)]];
+ pen_bg0[0] = Machine->pens[vdp->pal_ind16[((vdp->contReg[7]>>2)&0x03)]];
- x = (vdp.contReg[8] & 0x20) ? 0 : 1;
+ x = (vdp->contReg[8] & 0x20) ? 0 : 1;
for (;x<4;x++)
- pen_bg0[x] = Machine->pens[pal_ind16[x]];
+ pen_bg0[x] = Machine->pens[vdp->pal_ind16[x]];
- xx = vdp.offset_x;
+ xx = vdp->offset_x;
while (xx--) *ln++ = pen_bg0[0];
for (x=0;x<128;x++)
@@ -474,11 +474,11 @@ V9938_MODE_FUNC (mode_graphic5)
*ln++ = pen_bg0[(colour>>2)&3];
}
- pen_bg0[0] = Machine->pens[pal_ind16[((vdp.contReg[7]>>2)&0x03)]];
- xx = 16 - vdp.offset_x;
+ pen_bg0[0] = Machine->pens[vdp->pal_ind16[((vdp->contReg[7]>>2)&0x03)]];
+ xx = 16 - vdp->offset_x;
while (xx--) *ln++ = pen_bg0[0];
#endif
- vdp.size_now = RENDER_HIGH;
+ vdp->size_now = RENDER_HIGH;
}
V9938_MODE_FUNC (mode_graphic6)
@@ -490,36 +490,36 @@ V9938_MODE_FUNC (mode_graphic6)
PEN_TYPE fg1;
#endif
- linemask = ((vdp.contReg[2] & 0x1f) << 3) | 7;
+ linemask = ((vdp->contReg[2] & 0x1f) << 3) | 7;
- line2 = ((line + vdp.contReg[23]) & linemask) & 255;
+ line2 = ((line + vdp->contReg[23]) & linemask) & 255;
nametbl = line2 << 8 ;
- if ( (vdp.contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
+ if ( (vdp->contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
nametbl += 0x10000;
- pen_bg = Machine->pens[pal_ind16[(vdp.contReg[7]&0x0f)]];
+ pen_bg = Machine->pens[vdp->pal_ind16[(vdp->contReg[7]&0x0f)]];
#if (V9938_WIDTH < 512)
- xx = vdp.offset_x;
+ xx = vdp->offset_x;
#else
- xx = vdp.offset_x * 2;
+ xx = vdp->offset_x * 2;
#endif
while (xx--) *ln++ = pen_bg;
- if (vdp.contReg[2] & 0x40)
+ if (vdp->contReg[2] & 0x40)
{
for (x=0;x<32;x++)
{
nametbl++;
- colour = vdp.vram[((nametbl&1) << 16) | (nametbl>>1)];
- fg0 = Machine->pens[pal_ind16[colour>>4]];
+ colour = vdp->vram[((nametbl&1) << 16) | (nametbl>>1)];
+ fg0 = Machine->pens[vdp->pal_ind16[colour>>4]];
#if (V9938_WIDTH < 512)
*ln++ = fg0; *ln++ = fg0;
*ln++ = fg0; *ln++ = fg0;
*ln++ = fg0; *ln++ = fg0;
*ln++ = fg0; *ln++ = fg0;
#else
- fg1 = Machine->pens[pal_ind16[colour&15]];
+ fg1 = Machine->pens[vdp->pal_ind16[colour&15]];
*ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1;
*ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1;
*ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1;
@@ -532,21 +532,21 @@ V9938_MODE_FUNC (mode_graphic6)
{
for (x=0;x<256;x++)
{
- colour = vdp.vram[((nametbl&1) << 16) | (nametbl>>1)];
- *ln++ = Machine->pens[pal_ind16[colour>>4]];
+ colour = vdp->vram[((nametbl&1) << 16) | (nametbl>>1)];
+ *ln++ = Machine->pens[vdp->pal_ind16[colour>>4]];
#if (V9938_WIDTH > 512)
- *ln++ = Machine->pens[pal_ind16[colour&15]];
+ *ln++ = Machine->pens[vdp->pal_ind16[colour&15]];
#endif
nametbl++;
}
}
- xx = 16 - vdp.offset_x;
+ xx = 16 - vdp->offset_x;
#if (V9938_WIDTH > 512)
xx *= 2;
#endif
while (xx--) *ln++ = pen_bg;
- vdp.size_now = RENDER_HIGH;
+ vdp->size_now = RENDER_HIGH;
}
V9938_MODE_FUNC (mode_graphic7)
@@ -555,29 +555,29 @@ V9938_MODE_FUNC (mode_graphic7)
int line2, linemask, x, xx, nametbl;
PEN_TYPE pen, pen_bg;
- linemask = ((vdp.contReg[2] & 0x1f) << 3) | 7;
+ linemask = ((vdp->contReg[2] & 0x1f) << 3) | 7;
- line2 = ((line + vdp.contReg[23]) & linemask) & 255;
+ line2 = ((line + vdp->contReg[23]) & linemask) & 255;
nametbl = line2 << 8;
- if ( (vdp.contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
+ if ( (vdp->contReg[2] & 0x20) && (V9938_SECOND_FIELD) )
nametbl += 0x10000;
- pen_bg = Machine->pens[pal_ind256[vdp.contReg[7]]];
+ pen_bg = Machine->pens[vdp->pal_ind256[vdp->contReg[7]]];
#if (V9938_WIDTH < 512)
- xx = vdp.offset_x;
+ xx = vdp->offset_x;
#else
- xx = vdp.offset_x * 2;
+ xx = vdp->offset_x * 2;
#endif
while (xx--) *ln++ = pen_bg;
- if (vdp.contReg[2] & 0x40)
+ if (vdp->contReg[2] & 0x40)
{
for (x=0;x<32;x++)
{
nametbl++;
- colour = vdp.vram[((nametbl&1) << 16) | (nametbl>>1)];
- pen = Machine->pens[pal_ind256[colour]];
+ colour = vdp->vram[((nametbl&1) << 16) | (nametbl>>1)];
+ pen = Machine->pens[vdp->pal_ind256[colour]];
*ln++ = pen; *ln++ = pen;
*ln++ = pen; *ln++ = pen;
*ln++ = pen; *ln++ = pen;
@@ -595,8 +595,8 @@ V9938_MODE_FUNC (mode_graphic7)
{
for (x=0;x<256;x++)
{
- colour = vdp.vram[((nametbl&1) << 16) | (nametbl>>1)];
- pen = Machine->pens[pal_ind256[colour]];
+ colour = vdp->vram[((nametbl&1) << 16) | (nametbl>>1)];
+ pen = Machine->pens[vdp->pal_ind256[colour]];
*ln++ = pen;
#if (V9938_WIDTH > 512)
*ln++ = pen;
@@ -605,12 +605,12 @@ V9938_MODE_FUNC (mode_graphic7)
}
}
- xx = 16 - vdp.offset_x;
+ xx = 16 - vdp->offset_x;
#if (V9938_WIDTH > 512)
xx *= 2;
#endif
while (xx--) *ln++ = pen_bg;
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_MODE_FUNC (mode_unknown)
@@ -618,47 +618,47 @@ V9938_MODE_FUNC (mode_unknown)
PEN_TYPE fg, bg;
int x;
- fg = Machine->pens[pal_ind16[vdp.contReg[7] >> 4]];
- bg = Machine->pens[pal_ind16[vdp.contReg[7] & 15]];
+ fg = Machine->pens[vdp->pal_ind16[vdp->contReg[7] >> 4]];
+ bg = Machine->pens[vdp->pal_ind16[vdp->contReg[7] & 15]];
#if (V9938_WIDTH < 512)
- x = vdp.offset_x;
+ x = vdp->offset_x;
while (x--) *ln++ = bg;
x = 256;
while (x--) *ln++ = fg;
- x = 16 - vdp.offset_x;
+ x = 16 - vdp->offset_x;
while (x--) *ln++ = bg;
#else
- x = vdp.offset_x * 2;
+ x = vdp->offset_x * 2;
while (x--) *ln++ = bg;
x = 512;
while (x--) *ln++ = fg;
- x = (16 - vdp.offset_x) * 2;
+ x = (16 - vdp->offset_x) * 2;
while (x--) *ln++ = bg;
#endif
- if (vdp.size_now != RENDER_HIGH) vdp.size_now = RENDER_LOW;
+ if (vdp->size_now != RENDER_HIGH) vdp->size_now = RENDER_LOW;
}
V9938_SPRITE_FUNC (default_draw_sprite)
{
int i;
#if (V9938_WIDTH > 512)
- ln += vdp.offset_x * 2;
+ ln += vdp->offset_x * 2;
#else
- ln += vdp.offset_x;
+ ln += vdp->offset_x;
#endif
for (i=0;i<256;i++)
{
if (col[i] & 0x80)
{
- *ln++ = Machine->pens[pal_ind16[col[i]&0x0f]];
+ *ln++ = Machine->pens[vdp->pal_ind16[col[i]&0x0f]];
#if (V9938_WIDTH > 512)
- *ln++ = Machine->pens[pal_ind16[col[i]&0x0f]];
+ *ln++ = Machine->pens[vdp->pal_ind16[col[i]&0x0f]];
#endif
}
else
@@ -673,18 +673,18 @@ V9938_SPRITE_FUNC (graphic5_draw_sprite)
{
int i;
#if (V9938_WIDTH > 512)
- ln += vdp.offset_x * 2;
+ ln += vdp->offset_x * 2;
#else
- ln += vdp.offset_x;
+ ln += vdp->offset_x;
#endif
for (i=0;i<256;i++)
{
if (col[i] & 0x80)
{
- *ln++ = Machine->pens[pal_ind16[(col[i]>>2)&0x03]];
+ *ln++ = Machine->pens[vdp->pal_ind16[(col[i]>>2)&0x03]];
#if (V9938_WIDTH > 512)
- *ln++ = Machine->pens[pal_ind16[col[i]&0x03]];
+ *ln++ = Machine->pens[vdp->pal_ind16[col[i]&0x03]];
#endif
}
else
@@ -705,9 +705,9 @@ V9938_SPRITE_FUNC (graphic7_draw_sprite)
int i;
#if (V9938_WIDTH > 512)
- ln += vdp.offset_x * 2;
+ ln += vdp->offset_x * 2;
#else
- ln += vdp.offset_x;
+ ln += vdp->offset_x;
#endif
for (i=0;i<256;i++)
diff --git a/src/mame/drivers/firebeat.c b/src/mame/drivers/firebeat.c
index 6a24e333e22..91c8c88f952 100644
--- a/src/mame/drivers/firebeat.c
+++ b/src/mame/drivers/firebeat.c
@@ -2259,8 +2259,8 @@ static void init_firebeat(running_machine *machine)
rtc65271_init(xram, NULL);
- pc16552d_init(0, 19660800, comm_uart_irq_callback); // Network UART
- pc16552d_init(1, 24000000, midi_uart_irq_callback); // MIDI UART
+ pc16552d_init(0, 19660800, comm_uart_irq_callback, 0); // Network UART
+ pc16552d_init(1, 24000000, midi_uart_irq_callback, 0); // MIDI UART
extend_board_irq_enable = 0x3f;
extend_board_irq_active = 0x00;
diff --git a/src/mame/drivers/meritm.c b/src/mame/drivers/meritm.c
index 8fd7d423255..b107f99040d 100644
--- a/src/mame/drivers/meritm.c
+++ b/src/mame/drivers/meritm.c
@@ -1,82 +1,1097 @@
-/* Merit MSX Video based games
+/*
+ Merit CRT250 and CRT260 hardware
+
+ Driver by Mariusz Wojcieszek
+
+ CRT 250 (basic components, also used by CRT260)
+ Main CPU: 1xZ80B
+ Sound: 1xYM2149F (or compatible)
+ Video: 2xYamaha V9938 (MSX2 video chip!)
+ Other: 2xZ80APIO (I/O and interrupt controllers)
+ 1x8255 (I/O)
+
+ CRT 260 additional components:
+ - Microtouch touch screen controller (SMT-3)
+ - PC16550 UART (for communication with touch screen controller)
+ - DS1204 Electronic Key (for protection)
+ - DS1232 Reset and Watchdog
+ - DS1644 (megat4te) 32K NVRAM + RTC
+ - MAX232 (for MegaLink)
+
+ Known Games:
+
+ CRT 250:
+ Pit Boss II (c)1988
+ Super Pit Boss (c)1988
+ *Pit Boss Superstar (c)1989
+ *Pit Boss Superstar 30 (c)1993
+ Pit Boss Megastar (c)1994
+
+ CRT 260:
+ *Pit Boss Supertouch 30 (c)1994?
+ *Megatouch Video (c)1994?
+ *Megatouch II (c)1995
+ *Megatouch III (c)1995
+ *Megatouch IV (c)1996
+ Megatouch IV Tournament Edition (c)1996
+ *Super Megatouch IV (c) 1996
+ *Megatouch 5 (c)1997
+ Megatouch 6 (c)1998
+ *Megatouch 7 Encore (c)2000
+
+ * indicates that game needs to be dumped or redumped
+
+ Notes/ToDo:
+ - offset for top V9938 layer is hardcoded, probably should be taken from V9938 setup
+ - blinking on Meagtouch title screen is probably incorrect
+ - clean up V9938 interrupt implementation
+ - finish inputs, dsw, outputs (lamps)
+ - calibration mode in Microtouch emulation (command CX)
+ - problem with registering touches on the bottom of the screen (currently hacked to work)
+ - megat3: u37 has bad size, should be 8MBit
+ - megat4: rom u32 was bad, currently using u32 from megat4te
+ - megat5: has jmp $0000 in the initialization code causing infinite loop, is rom bad?
+ */
+
+#include "driver.h"
+#include "deprecat.h"
+#include "cpu/z80/z80.h"
+#include "cpu/z80/z80daisy.h"
+#include "sound/ay8910.h"
+#include "video/v9938.h"
+#include "machine/8255ppi.h"
+#include "machine/z80pio.h"
+#include "machine/pc16552d.h"
+
+/*************************************
+ *
+ * Globals
+ *
+ *************************************/
+
+
+#define SYSTEM_CLK 21470000
+#define UART_CLK XTAL_18_432MHz
+
+static UINT8* meritm_ram;
+
+/*************************************
+ *
+ * DS1204 Electronic Key
+ *
+ *************************************/
+
+#define DS1204_STATE_IDLE 0
+#define DS1204_STATE_COMMAND 1
+#define DS1204_STATE_READ_KEY 2
+#define DS1204_STATE_WRITE_SECURITY_MATCH 3
+#define DS1204_STATE_READ_NVRAM 4
+
+static struct
+{
+ int state;
+ int read_ptr;
+ int last_clk;
+ UINT8 key[8];
+ UINT8 nvram[16];
+ int out_bit;
+ UINT8 command[3];
+
+} ds1204;
+
+void ds1204_w( int rst, int clk, int dq )
+{
+ //logerror("ds1204_w: rst = %d, clk = %d, dq = %d\n", rst, clk, dq );
+ if ( rst == 0 )
+ {
+ ds1204.state = DS1204_STATE_COMMAND;
+ ds1204.read_ptr = 0;
+ }
+ else
+ {
+ if ( (ds1204.last_clk == 1) && (clk == 0) )
+ {
+ switch(ds1204.state)
+ {
+ case DS1204_STATE_COMMAND:
+ //logerror("Command bit %d = %d\n", ds1204.read_ptr, dq);
+ if ( ds1204.read_ptr < 24 )
+ {
+ if ( dq == 1 )
+ {
+ ds1204.command[ds1204.read_ptr >> 3] |= (1 << (ds1204.read_ptr & 0x7));
+ }
+ else
+ {
+ ds1204.command[ds1204.read_ptr >> 3] &= ~(1 << (ds1204.read_ptr & 0x7));
+ }
+ ds1204.read_ptr++;
+ }
+ if ( ds1204.read_ptr == 24 )
+ {
+ ds1204.state = DS1204_STATE_READ_KEY;
+ ds1204.read_ptr = 0;
+ }
+ break;
+ case DS1204_STATE_READ_KEY:
+ //logerror("Key bit %d\n", ds1204.read_ptr);
+ if (ds1204.read_ptr < 64)
+ {
+ ds1204.out_bit = (ds1204.key[ds1204.read_ptr >> 3] >> (ds1204.read_ptr & 0x7)) & 0x01;
+ ds1204.read_ptr++;
+ }
+ if (ds1204.read_ptr == 64)
+ {
+ ds1204.state = DS1204_STATE_WRITE_SECURITY_MATCH;
+ ds1204.read_ptr = 0;
+ }
+ break;
+ case DS1204_STATE_WRITE_SECURITY_MATCH:
+ //logerror( "Security match bit %d = %d\n", ds1204.read_ptr, dq);
+ if (ds1204.read_ptr < 64)
+ {
+ ds1204.read_ptr++;
+ }
+ if (ds1204.read_ptr == 64)
+ {
+ ds1204.state = DS1204_STATE_READ_NVRAM;
+ ds1204.read_ptr = 0;
+ }
+ break;
+ case DS1204_STATE_READ_NVRAM:
+ //logerror( "Read nvram bit = %d\n", ds1204.read_ptr );
+ if (ds1204.read_ptr < 128)
+ {
+ ds1204.out_bit = (ds1204.nvram[ds1204.read_ptr >> 3] >> (ds1204.read_ptr & 0x7)) & 0x01;
+ ds1204.read_ptr++;
+ }
+ if (ds1204.read_ptr == 128)
+ {
+ ds1204.state = DS1204_STATE_IDLE;
+ ds1204.read_ptr = 0;
+ }
+ break;
+
+ }
+ }
+ ds1204.last_clk = clk;
+ }
+};
+
+int ds1204_r(void)
+{
+ //logerror("ds1204_r\n");
+ return ds1204.out_bit;
+};
+
+void ds1204_init(const UINT8* key, const UINT8* nvram)
+{
+ memset(&ds1204, 0, sizeof(ds1204));
+ if (key)
+ memcpy(ds1204.key, key, sizeof(ds1204.key));
+ if (nvram)
+ memcpy(ds1204.nvram, nvram, sizeof(ds1204.nvram));
+
+ state_save_register_item("ds1204", 0, ds1204.state);
+ state_save_register_item("ds1204", 0, ds1204.read_ptr);
+ state_save_register_item("ds1204", 0, ds1204.last_clk);
+ state_save_register_item("ds1204", 0, ds1204.out_bit);
+ state_save_register_item_array("ds1204", 0, ds1204.command);
+};
+
+/*************************************
+ *
+ * Microtouch touch screen controller
+ *
+ *************************************/
+
+static struct
+{
+ UINT8 tx_buffer[16];
+ int tx_buffer_ptr;
+ emu_timer* timer;
+ int reset_done;
+ int format_tablet;
+ int mode_inactive;
+ int mode_stream;
+ int last_touch_state;
+ int last_x;
+ int last_y;
+ void (*tx_callback)(UINT8 data);
+ int (*touch_callback)(int *touch_x, int *touch_y);
+} microtouch;
+
+
+static int microtouch_check_command( const char* commandtocheck, int command_len, UINT8* command_data )
+ {
+ if ( (command_len == (strlen(commandtocheck) + 2)) &&
+ (command_data[0] == 0x01) &&
+ (strncmp(commandtocheck, (const char*)command_data + 1, strlen(commandtocheck)) == 0) &&
+ (command_data[command_len-1] == 0x0d) )
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+static void microtouch_send_format_table_packet(UINT8 flag, int x, int y)
+{
+ microtouch.tx_callback(flag);
+ // lower byte (7bits) of x coordinate
+ microtouch.tx_callback(x & 0x7f);
+ // higher byte (7bits) of x coordinate
+ microtouch.tx_callback((x >> 7) & 0x7f);
+ // lower byte (7bits) of y coordinate
+ microtouch.tx_callback(y & 0x7f);
+ // higher byte (7bits) of y coordinate
+ microtouch.tx_callback((y >> 7) & 0x7f);
+};
+
+static TIMER_CALLBACK(microtouch_timer_callback)
+{
+ if ( (microtouch.reset_done == 0) ||
+ (microtouch.format_tablet == 0) ||
+ (microtouch.mode_inactive == 1) ||
+ (microtouch.mode_stream == 0) )
+ {
+ return;
+ }
+
+ // send format tablet packet
+ if ( readinputportbytag("TOUCH") & 0x01 )
+ {
+ int tx = readinputportbytag("TOUCH_X");
+ int ty = readinputportbytag("TOUCH_Y");
+
+ if ( microtouch.touch_callback == NULL ||
+ microtouch.touch_callback( &tx, &ty ) != 0 )
+ {
+ ty = 0x4000 - ty;
+
+ microtouch_send_format_table_packet(0xc0, tx, ty);
+ microtouch.last_touch_state = 1;
+ microtouch.last_x = tx;
+ microtouch.last_y = ty;
+ }
+ }
+ else
+ {
+ if ( microtouch.last_touch_state == 1 )
+ {
+ microtouch.last_touch_state = 0;
+ microtouch_send_format_table_packet(0x80, microtouch.last_x, microtouch.last_y);
+ }
+ }
+};
+
+static void microtouch_init(void (*tx_cb)(UINT8 data),
+ int (*touch_cb)(int *touch_x, int *touch_y))
+{
+ memset(&microtouch, 0, sizeof(microtouch));
- The actual name of the hardware is unknown.
- Merit have several boards with the same basic specification.
+ microtouch.last_touch_state = -1;
+ microtouch.tx_callback = tx_cb;
+ microtouch.touch_callback = touch_cb;
- Main CPU: 1xZ80B
- Sound: 1xYM2149F
- Video: 2xYamaha V9938 (MSX2 video chip!)
- Other: 2xZ80APIO
+ microtouch.timer = timer_alloc(microtouch_timer_callback, NULL);
+ timer_adjust_periodic(microtouch.timer, ATTOTIME_IN_HZ(167), 0, ATTOTIME_IN_HZ(167));
- Other components vary, however, the MegaTouch games appear to use a Dallas chip for protection
- The later PCBs are of a different design use less roms of a higher capacity, however they still
- have the same basic chips. Some of the readmes with the sets give inaccurate information.
+ state_save_register_item("microtouch", 0, microtouch.reset_done);
+ state_save_register_item("microtouch", 0, microtouch.format_tablet);
+ state_save_register_item("microtouch", 0, microtouch.mode_inactive);
+ state_save_register_item("microtouch", 0, microtouch.mode_stream);
+ state_save_register_item("microtouch", 0, microtouch.last_touch_state);
+ state_save_register_item("microtouch", 0, microtouch.last_x);
+ state_save_register_item("microtouch", 0, microtouch.last_y);
+ state_save_register_item_array("microtouch", 0, microtouch.tx_buffer);
+ state_save_register_item("microtouch", 0, microtouch.tx_buffer_ptr);
- Known Games using this basic hardware:
+};
- Type 1:
- Pitboss II (c)1988
- Super Pitboss (c)19??
- Type 2:
- Pitboss Megastar (c)1994
+static void microtouch_rx(int count, UINT8* data)
+{
+ int i;
+
+ for ( i = 0; (i < count) && ((microtouch.tx_buffer_ptr + i) < 16); i++ )
+ {
+ microtouch.tx_buffer[i+microtouch.tx_buffer_ptr] = data[i];
+ microtouch.tx_buffer_ptr++;
+ }
+
+ if (microtouch.tx_buffer_ptr > 0 && (microtouch.tx_buffer[microtouch.tx_buffer_ptr-1] == 0x0d))
+ {
+ // check command
+ if ( microtouch_check_command( "MS", microtouch.tx_buffer_ptr, microtouch.tx_buffer ) )
+ {
+ microtouch.mode_stream = 1;
+ microtouch.mode_inactive = 0;
+ }
+ else if ( microtouch_check_command( "MI", microtouch.tx_buffer_ptr, microtouch.tx_buffer ) )
+ {
+ microtouch.mode_inactive = 1;
+ }
+ else if ( microtouch_check_command( "R", microtouch.tx_buffer_ptr, microtouch.tx_buffer ) )
+ {
+ microtouch.reset_done = 1;
+ }
+ else if ( microtouch_check_command( "FT", microtouch.tx_buffer_ptr, microtouch.tx_buffer ) )
+ {
+ microtouch.format_tablet = 1;
+ }
+ // send response
+ microtouch.tx_callback(0x01);
+ microtouch.tx_callback(0x30);
+ microtouch.tx_callback(0x0d);
+ microtouch.tx_buffer_ptr = 0;
+ }
+};
+
+INPUT_PORTS_START(microtouch)
+ PORT_START_TAG("TOUCH")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_IMPULSE(10) PORT_NAME( "Touch screen" )
+ PORT_START_TAG("TOUCH_X")
+ PORT_BIT( 0x3fff, 0x2000, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
+ PORT_START_TAG("TOUCH_Y")
+ PORT_BIT( 0x3fff, 0x2000, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
+INPUT_PORTS_END
- Type 3:
- Megatouch 3 (c)1995
- Megatouch 5 (c)1997
+/*************************************
+ *
+ * Microtouch <-> pc16650 interface
+ *
+ *************************************/
- This is currently just a placeholder for games using this hardware, everything still to do
+static void pc16650d_tx_callback(int channel, int count, UINT8* data)
+{
+ microtouch_rx(count, data);
+};
- */
+static void meritm_microtouch_tx_callback(UINT8 data)
+{
+ pc16552d_rx_data(0, 0, data);
+};
+
+/*************************************
+ *
+ * Microtouch touch coordinate transformation
+ *
+ *************************************/
+static int meritm_touch_coord_transform(int *touch_x, int *touch_y)
+{
+ int xscr = (int)((double)(*touch_x)/0x4000*544);
+ int yscr = (int)((double)(*touch_y)/0x4000*480);
+
+ if( (xscr < 16) ||
+ (xscr > 544-16) ||
+ (yscr < 16) ||
+ (yscr > 480-16))
+ {
+ return 0;
+ }
+ if ( yscr > 480-63 )
+ {
+ *touch_y = 0x3fff;
+ }
+ else
+ {
+ *touch_y = (int)((double)(yscr - 16)*0x4000/(480-16-63));
+ }
+ *touch_x = (int)((double)(xscr - 16)*0x4000/(544-16-16));
+
+ return 1;
+}
-#include "driver.h"
+/*************************************
+ *
+ * Video
+ *
+ *************************************/
+
+static int meritm_vint = 0x00;
+static int meritm_interrupt_vdp0_state = 0;
+static int meritm_interrupt_vdp1_state = 0;
+static bitmap_t *vdp0_bitmap, *vdp1_bitmap;
+
+static INTERRUPT_GEN( meritm_interrupt )
+{
+ v9938_set_sprite_limit(0, 0);
+ v9938_set_resolution(0, RENDER_HIGH);
+ v9938_interrupt(0);
+
+ v9938_set_sprite_limit(1, 0);
+ v9938_set_resolution(1, RENDER_HIGH);
+ v9938_interrupt(1);
+}
-static VIDEO_START(meritm)
+static void meritm_vdp0_interrupt(int i)
{
+ if ( meritm_interrupt_vdp0_state != i )
+ {
+ meritm_interrupt_vdp0_state = i;
+ if (i)
+ meritm_vint &= ~0x08;
+ else
+ meritm_vint |= 0x08;
+
+ if(i)
+ z80pio_p_w(0, 0, meritm_vint);
+ }
}
-static VIDEO_UPDATE(meritm)
+static void meritm_vdp1_interrupt(int i)
{
+ if ( meritm_interrupt_vdp1_state != i )
+ {
+ meritm_interrupt_vdp1_state = i;
+ if (i)
+ meritm_vint &= ~0x10;
+ else
+ meritm_vint |= 0x10;
+
+ if(i)
+ z80pio_p_w(0, 0, meritm_vint);
+ }
+}
+
+static VIDEO_START( meritm )
+{
+ vdp0_bitmap = video_screen_auto_bitmap_alloc(machine->primary_screen);
+ v9938_init (machine, 0, vdp0_bitmap, MODEL_V9938, 0x20000, meritm_vdp0_interrupt);
+ v9938_reset(0);
+
+ vdp1_bitmap = video_screen_auto_bitmap_alloc(machine->primary_screen);
+ v9938_init (machine, 1, vdp1_bitmap, MODEL_V9938, 0x20000, meritm_vdp1_interrupt);
+ v9938_reset(1);
+
+ state_save_register_global(meritm_vint);
+ state_save_register_global(meritm_interrupt_vdp0_state);
+ state_save_register_global(meritm_interrupt_vdp1_state);
+ state_save_register_global_bitmap(vdp0_bitmap);
+ state_save_register_global_bitmap(vdp1_bitmap);
+
+}
+
+static int layer0_enabled = 1, layer1_enabled = 1;
+
+static VIDEO_UPDATE( meritm )
+{
+ if(input_code_pressed_once(KEYCODE_Q))
+ {
+ layer0_enabled^=1;
+ popmessage("Layer 0 %sabled",layer0_enabled ? "en" : "dis");
+ }
+ if(input_code_pressed_once(KEYCODE_W))
+ {
+ layer1_enabled^=1;
+ popmessage("Layer 1 %sabled",layer1_enabled ? "en" : "dis");
+ }
+
+ fillbitmap(bitmap, get_black_pen(screen->machine), cliprect);
+
+ if ( layer0_enabled )
+ {
+ copybitmap(bitmap, vdp0_bitmap, 0, 0, 0, 0, cliprect);
+ }
+
+ if ( layer1_enabled )
+ {
+ copybitmap_trans(bitmap, vdp1_bitmap, 0, 0, -6, -12, cliprect, v9938_get_transpen(1));
+ }
return 0;
}
-static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 )
- AM_RANGE(0x0000, 0x7fff) AM_READ(SMH_ROM)
+/*************************************
+ *
+ * Bank switching (ROM/RAM)
+ *
+ *************************************/
+
+static int meritm_bank;
+static int meritm_psd_a15;
+
+void meritm_crt250_switch_banks( void )
+{
+ int rombank = (meritm_bank & 0x07) ^ 0x07;
+
+ //logerror( "CRT250: Switching banks: rom = %0x (bank = %x)\n", rombank, meritm_bank );
+ memory_set_bank(1, rombank );
+};
+
+static WRITE8_HANDLER(meritm_crt250_bank_w)
+{
+ meritm_crt250_switch_banks();
+};
+
+void meritm_switch_banks( void )
+{
+ int rambank = (meritm_psd_a15 >> 2) & 0x3;
+ int rombank = (((meritm_bank >> 3) & 0x3) << 5) |
+ (((meritm_psd_a15 >> 1) & 0x1) << 4) |
+ (((meritm_bank & 0x07) ^ 0x07) << 1) |
+ (meritm_psd_a15 & 0x1);
+
+ //logerror( "Switching banks: rom = %0x (bank = %x), ram = %0x\n", rombank, meritm_bank, rambank);
+ memory_set_bank(1, rombank );
+ memory_set_bank(2, rombank | 0x01);
+ memory_set_bank(3, rambank);
+};
+
+static WRITE8_HANDLER(meritm_psd_a15_w)
+{
+ meritm_psd_a15 = data;
+ //logerror( "Writing PSD_A15 with %02x at PC=%04X\n", data, activecpu_get_pc() );
+ meritm_switch_banks();
+};
+
+static WRITE8_HANDLER(meritm_bank_w)
+{
+ meritm_switch_banks();
+};
+
+/*************************************
+ *
+ * CRT250 question roms reading
+ *
+ *************************************/
+
+static UINT16 questions_loword_address;
+
+static WRITE8_HANDLER(meritm_crt250_questions_lo_w)
+{
+ questions_loword_address &= 0xff00;
+ questions_loword_address |= data;
+};
+
+static WRITE8_HANDLER(meritm_crt250_questions_hi_w)
+{
+ questions_loword_address &= 0x00ff;
+ questions_loword_address |= (data << 8);
+};
+
+static WRITE8_HANDLER(meritm_crt250_questions_bank_w)
+{
+ UINT32 questions_address;
+ UINT8 *dst;
+
+ if (meritm_bank != 0)
+ {
+ logerror("meritm_crt250_questions_bank_w: bank is %d\n", meritm_bank);
+ return;
+ }
+
+ dst = memory_region(REGION_CPU1) + 0x70000 + 2;
+
+ if (data == 0)
+ {
+ *dst = 0xff;
+ }
+ else if (data == 0xff)
+ {
+ // ignore
+ }
+ else
+ {
+ switch(data)
+ {
+ case 0x6c: questions_address = 0x00000; break;
+ case 0x6d: questions_address = 0x10000; break;
+ case 0x6e: questions_address = 0x20000; break;
+ case 0x6f: questions_address = 0x30000; break;
+ case 0x5c: questions_address = 0x40000; break;
+ case 0x5d: questions_address = 0x50000; break;
+ case 0x5e: questions_address = 0x60000; break;
+ case 0x5f: questions_address = 0x70000; break;
+ case 0x3c: questions_address = 0x80000; break;
+ case 0x3d: questions_address = 0x90000; break;
+ case 0x3e: questions_address = 0xa0000; break;
+ case 0x3f: questions_address = 0xb0000; break;
+ default: logerror( "meritm_crt250_questions_bank_w: unknown data = %02x\n", data ); return;
+ }
+ logerror( "Reading question byte at %06X\n", questions_address | questions_loword_address);
+ *dst = memory_region(REGION_USER1)[questions_address | questions_loword_address];
+ }
+};
+
+
+/*************************************
+ *
+ * DS1644 RTC
+ *
+ *************************************/
+
+WRITE8_HANDLER(meritm_ds1644_w)
+{
+ int rambank = (meritm_psd_a15 >> 2) & 0x3;
+ if (rambank < 3)
+ {
+ meritm_ram[rambank*0x2000 + 0x1ff8 + offset] = data;
+ }
+ else
+ {
+ if (offset == 0)
+ {
+ meritm_ram[0x7ff8] = data;
+ }
+ //logerror( "Writing RTC, reg = %d, data = %x\n", offset, data);
+ }
+};
+
+static UINT8 binary_to_BCD(UINT8 data)
+{
+ data %= 100;
+
+ return ((data / 10) << 4) | (data %10);
+}
+
+READ8_HANDLER(meritm_ds1644_r)
+{
+ mame_system_time systime;
+ int rambank = (meritm_psd_a15 >> 2) & 0x3;
+ if (rambank == 3)
+ {
+ //logerror( "Reading RTC, reg = %x\n", offset);
+
+ mame_get_current_datetime(machine, &systime);
+ meritm_ram[0x7ff9] = binary_to_BCD(systime.local_time.second);
+ meritm_ram[0x7ffa] = binary_to_BCD(systime.local_time.minute);
+ meritm_ram[0x7ffb] = binary_to_BCD(systime.local_time.hour);
+ meritm_ram[0x7ffc] = binary_to_BCD(systime.local_time.weekday+1);
+ meritm_ram[0x7ffd] = binary_to_BCD(systime.local_time.mday);
+ meritm_ram[0x7ffe] = binary_to_BCD(systime.local_time.month+1);
+ meritm_ram[0x7fff] = binary_to_BCD(systime.local_time.year % 100);
+ }
+ return meritm_ram[rambank*0x2000 + 0x1ff8 + offset];
+};
+
+/*************************************
+ *
+ * Memory maps
+ *
+ *************************************/
+
+static ADDRESS_MAP_START( meritm_crt250_map, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x0000, 0xdfff) AM_ROMBANK(1)
+ AM_RANGE(0xe000, 0xffff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( meritm_crt250_questions_map, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x0000, 0xdfff) AM_ROMBANK(1)
+ AM_RANGE(0x0000, 0x0000) AM_WRITE(meritm_crt250_questions_lo_w)
+ AM_RANGE(0x0001, 0x0001) AM_WRITE(meritm_crt250_questions_hi_w)
+ AM_RANGE(0x0002, 0x0002) AM_WRITE(meritm_crt250_questions_bank_w)
+ AM_RANGE(0xe000, 0xffff) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 8 )
- AM_RANGE(0x0000, 0x7fff) AM_WRITE(SMH_ROM)
+static ADDRESS_MAP_START( meritm_crt250_io_map, ADDRESS_SPACE_IO, 8 )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x10, 0x10) AM_READWRITE(v9938_0_vram_r, v9938_0_vram_w)
+ AM_RANGE(0x11, 0x11) AM_READWRITE(v9938_0_status_r, v9938_0_command_w)
+ AM_RANGE(0x12, 0x12) AM_WRITE(v9938_0_palette_w)
+ AM_RANGE(0x13, 0x13) AM_WRITE(v9938_0_register_w)
+ AM_RANGE(0x20, 0x20) AM_READWRITE(v9938_1_vram_r, v9938_1_vram_w)
+ AM_RANGE(0x21, 0x21) AM_READWRITE(v9938_1_status_r, v9938_1_command_w)
+ AM_RANGE(0x22, 0x22) AM_WRITE(v9938_1_palette_w)
+ AM_RANGE(0x23, 0x23) AM_WRITE(v9938_1_register_w)
+ AM_RANGE(0x30, 0x33) AM_READWRITE(ppi8255_0_r, ppi8255_0_w)
+ AM_RANGE(0x40, 0x43) AM_READWRITE(z80pio_0_r, z80pio_0_w)
+ AM_RANGE(0x50, 0x53) AM_READWRITE(z80pio_1_r, z80pio_1_w)
+ AM_RANGE(0x80, 0x80) AM_READWRITE(AY8910_read_port_0_r, AY8910_control_port_0_w)
+ AM_RANGE(0x81, 0x81) AM_WRITE(AY8910_write_port_0_w)
+ AM_RANGE(0xff, 0xff) AM_WRITE(meritm_crt250_bank_w)
ADDRESS_MAP_END
+static ADDRESS_MAP_START( meritm_map, ADDRESS_SPACE_PROGRAM, 8 )
+ AM_RANGE(0x0000, 0x7fff) AM_ROMBANK(1)
+ AM_RANGE(0x8000, 0xdfff) AM_ROMBANK(2)
+ AM_RANGE(0xe000, 0xffff) AM_RAMBANK(3)
+ADDRESS_MAP_END
+static ADDRESS_MAP_START( meritm_io_map, ADDRESS_SPACE_IO, 8 )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x00) AM_WRITE(meritm_psd_a15_w)
+ AM_RANGE(0x01, 0x01) AM_WRITE(watchdog_reset_w)
+ AM_RANGE(0x10, 0x10) AM_READWRITE(v9938_0_vram_r, v9938_0_vram_w)
+ AM_RANGE(0x11, 0x11) AM_READWRITE(v9938_0_status_r, v9938_0_command_w)
+ AM_RANGE(0x12, 0x12) AM_WRITE(v9938_0_palette_w)
+ AM_RANGE(0x13, 0x13) AM_WRITE(v9938_0_register_w)
+ AM_RANGE(0x20, 0x20) AM_READWRITE(v9938_1_vram_r, v9938_1_vram_w)
+ AM_RANGE(0x21, 0x21) AM_READWRITE(v9938_1_status_r, v9938_1_command_w)
+ AM_RANGE(0x22, 0x22) AM_WRITE(v9938_1_palette_w)
+ AM_RANGE(0x23, 0x23) AM_WRITE(v9938_1_register_w)
+ AM_RANGE(0x30, 0x33) AM_READWRITE(ppi8255_0_r, ppi8255_0_w)
+ AM_RANGE(0x40, 0x43) AM_READWRITE(z80pio_0_r, z80pio_0_w)
+ AM_RANGE(0x50, 0x53) AM_READWRITE(z80pio_1_r, z80pio_1_w)
+ AM_RANGE(0x60, 0x67) AM_READWRITE(pc16552d_0_r,pc16552d_0_w)
+ AM_RANGE(0x80, 0x80) AM_READWRITE(AY8910_read_port_0_r, AY8910_control_port_0_w)
+ AM_RANGE(0x81, 0x81) AM_WRITE(AY8910_write_port_0_w)
+ AM_RANGE(0xff, 0xff) AM_WRITE(meritm_bank_w)
+ADDRESS_MAP_END
-static INPUT_PORTS_START( meritm )
+/*************************************
+ *
+ * Input ports
+ *
+ *************************************/
+
+static INPUT_PORTS_START(meritm_crt260)
+ PORT_INCLUDE(microtouch)
+
+ PORT_START_TAG("PIO1_PORTA")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START_TAG("PIO1_PORTB")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME( "Calibration" ) PORT_CODE(KEYCODE_C)
INPUT_PORTS_END
+static INPUT_PORTS_START(meritm_crt250)
+ PORT_START_TAG("PIO1_PORTA")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON6 )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON7 )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START_TAG("PIO1_PORTB")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN)
+INPUT_PORTS_END
+
+static INPUT_PORTS_START(pitbossm)
+ PORT_INCLUDE(meritm_crt250)
+
+ PORT_START_TAG("DSW")
+ PORT_DIPNAME( 0x01, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "Run 21 and Trivia Whiz 2000: Coins to start" )
+ PORT_DIPSETTING( 0x00, "2 Coins" )
+ PORT_DIPSETTING( 0x10, "1 Coin" )
+ PORT_DIPNAME( 0x20, 0x20, "Great Solitaire: Coins to start" )
+ PORT_DIPSETTING( 0x00, "4 Coins" )
+ PORT_DIPSETTING( 0x20, "2 Coins" )
+ PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( On ) )
+INPUT_PORTS_END
+
+/*************************************
+ *
+ * 8255
+ *
+ *************************************/
+
+READ8_HANDLER(meritm_8255_port_c_r)
+{
+ //logerror( "8255 port C read\n" );
+ return 0xff;
+};
+
+WRITE8_HANDLER(meritm_crt250_port_b_w)
+{
+ //popmessage("Lamps: %d %d %d %d %d %d %d", BIT(data,0), BIT(data,1), BIT(data,2), BIT(data,3), BIT(data,4), BIT(data,5), BIT(data,6) );
+ output_set_value("P1 DISC 1 LAMP", !BIT(data,0));
+ output_set_value("P1 DISC 2 LAMP", !BIT(data,1));
+ output_set_value("P1 DISC 3 LAMP", !BIT(data,2));
+ output_set_value("P1 DISC 4 LAMP", !BIT(data,3));
+ output_set_value("P1 DISC 5 LAMP", !BIT(data,4));
+ output_set_value("P1 PLAY LAMP", !BIT(data,5));
+ output_set_value("P1 CANCEL LAMP", !BIT(data,6));
+}
+
+static const ppi8255_interface crt260_ppi8255_intf =
+{
+ 1,
+ { 0 }, /* Port A read */
+ { 0 }, /* Port B read */
+ { meritm_8255_port_c_r }, /* Port C read */
+ { 0 }, /* Port A write (used) */
+ { 0 }, /* Port B write (used LMP x DRIVE) */
+ { 0 } /* Port C write */
+};
+
+static const ppi8255_interface crt250_ppi8255_intf =
+{
+ 1,
+ { 0 }, /* Port A read */
+ { 0 }, /* Port B read */
+ { meritm_8255_port_c_r }, /* Port C read */
+ { 0 }, /* Port A write (used) */
+ { meritm_crt250_port_b_w }, /* Port B write (used LMP x DRIVE) */
+ { 0 } /* Port C write */
+};
+
+/*************************************
+ *
+ * AY8930
+ *
+ *************************************/
+
+/*
+ Port A: DSW
+ Port B: Bits 0,1 used
+*/
+
+READ8_HANDLER(meritm_ay8930_port_a_r)
+{
+ return readinputportbytag_safe("DSW", 0);
+};
+
+WRITE8_HANDLER(meritm_ay8930_port_b_w)
+{
+ // lamps
+};
+
+static const struct AY8910interface ay8910_interface =
+{
+ meritm_ay8930_port_a_r, /* Port A read */
+ 0, /* Port B read */
+ 0, /* Port A write */
+ meritm_ay8930_port_b_w /* Port B write */
+};
+
+/*************************************
+ *
+ * PIOs
+ *
+ *************************************/
+
+static void meritm_audio_pio_interrupt(int state)
+{
+ //logerror( "PIO(0) interrupt line: %d, V = %d, H = %d\n", state, video_screen_get_vpos(0), video_screen_get_hpos(0) );
+ cpunum_set_input_line(Machine, 0, 0, state);
+}
+
+static void meritm_io_pio_interrupt(int state)
+{
+ //logerror( "PIO(1) interrupt line: %d, V = %d, H = %d\n", state, video_screen_get_vpos(0), video_screen_get_hpos(0) );
+ cpunum_set_input_line(Machine, 0, 0, state);
+}
+
+
+static READ8_HANDLER(meritm_audio_pio_port_a_r)
+{
+ return meritm_vint;
+};
+
+static READ8_HANDLER(meritm_audio_pio_port_b_r)
+{
+ return ds1204_r();
+};
+
+static WRITE8_HANDLER(meritm_audio_pio_port_a_w)
+{
+ meritm_bank = (data & 7) | ((data >> 2) & 0x18);
+ //logerror("Writing BANK with %x (raw = %x)\n", meritm_bank, data);
+};
+
+static WRITE8_HANDLER(meritm_audio_pio_port_b_w)
+{
+ ds1204_w((data & 0x4) >> 2, (data & 0x2) >> 1, data & 0x01);
+};
+
+static READ8_HANDLER(meritm_io_pio_port_a_r)
+{
+ return readinputportbytag("PIO1_PORTA");
+};
-static MACHINE_DRIVER_START( meritm )
- /* basic machine hardware */
- MDRV_CPU_ADD(Z80,6000000)
- MDRV_CPU_PROGRAM_MAP(readmem,writemem)
-// MDRV_CPU_VBLANK_INT("main", irq0_line_hold)
+static READ8_HANDLER(meritm_io_pio_port_b_r)
+{
+ return readinputportbytag("PIO1_PORTB");
+};
+
+static WRITE8_HANDLER(meritm_io_pio_port_a_w)
+{
+};
- /* video hardware */
- MDRV_SCREEN_ADD("main", RASTER)
+static WRITE8_HANDLER(meritm_io_pio_port_b_w)
+{
+};
+
+static const z80pio_interface meritm_audio_pio_intf =
+{
+ meritm_audio_pio_interrupt,
+ meritm_audio_pio_port_a_r,
+ meritm_audio_pio_port_b_r,
+ meritm_audio_pio_port_a_w,
+ meritm_audio_pio_port_b_w,
+ 0,
+ 0
+};
+
+static const z80pio_interface meritm_io_pio_intf =
+{
+ meritm_io_pio_interrupt,
+ meritm_io_pio_port_a_r,
+ meritm_io_pio_port_b_r,
+ meritm_io_pio_port_a_w,
+ meritm_io_pio_port_b_w,
+ 0,
+ 0
+};
+
+/*
+static void meritm_pio1_portb_input_changed_callback(void *param, UINT32 oldval, UINT32 newval)
+{
+ z80pio_p_w(1, 1, (UINT8)newval);
+}
+*/
+
+static const struct z80_irq_daisy_chain meritm_daisy_chain[] =
+{
+ { z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 1 }, /* PIO number 1 */
+ { z80pio_reset, z80pio_irq_state, z80pio_irq_ack, z80pio_irq_reti, 0 }, /* PIO number 0 */
+ { 0, 0, 0, 0, -1 } /* end mark */
+};
+
+static MACHINE_START(merit_common)
+{
+ z80pio_init(0, &meritm_audio_pio_intf);
+ z80pio_init(1, &meritm_io_pio_intf);
+ //input_port_set_changed_callback(port_tag_to_index("PIO1_PORTB"), 0xff, meritm_pio1_portb_input_changed_callback, NULL);
+
+};
+
+static MACHINE_START(meritm_crt250)
+{
+ ppi8255_init(&crt250_ppi8255_intf);
+ memory_configure_bank(1, 0, 8, memory_region(REGION_CPU1), 0x10000);
+ meritm_bank = 0xff;
+ meritm_crt250_switch_banks();
+ machine_start_merit_common(machine);
+ state_save_register_global(meritm_bank);
+
+};
+
+static MACHINE_START(meritm_crt250_questions)
+{
+ machine_start_meritm_crt250(machine);
+ state_save_register_global(questions_loword_address);
+};
+
+static MACHINE_START(meritm_crt260)
+{
+ ppi8255_init(&crt260_ppi8255_intf);
+ meritm_ram = auto_malloc( 0x8000 );
+ memset( meritm_ram, 0x8000, 0x00 );
+ memory_configure_bank(1, 0, 128, memory_region(REGION_CPU1), 0x8000);
+ memory_configure_bank(2, 0, 128, memory_region(REGION_CPU1), 0x8000);
+ memory_configure_bank(3, 0, 4, meritm_ram, 0x2000);
+ meritm_bank = 0xff;
+ meritm_psd_a15 = 0;
+ meritm_switch_banks();
+ machine_start_merit_common(machine);
+ pc16552d_init(0, UART_CLK, NULL, pc16650d_tx_callback);
+ microtouch_init(meritm_microtouch_tx_callback, meritm_touch_coord_transform);
+ state_save_register_global(meritm_bank);
+ state_save_register_global(meritm_psd_a15);
+ state_save_register_global_pointer(meritm_ram, 0x8000);
+};
+
+static NVRAM_HANDLER(meritm_crt260)
+{
+ if (read_or_write)
+ mame_fwrite(file, meritm_ram, 0x8000);
+ else
+ if (file)
+ mame_fread(file, meritm_ram, 0x8000);
+ else
+ if ( memory_region(REGION_USER1) )
+ memcpy(meritm_ram, memory_region(REGION_USER1), 0x8000);
+};
+
+// from MSX2 driver, may be not accurate for merit games
+#define MSX2_XBORDER_PIXELS 16
+#define MSX2_YBORDER_PIXELS 28
+#define MSX2_TOTAL_XRES_PIXELS 256 * 2 + (MSX2_XBORDER_PIXELS * 2)
+#define MSX2_TOTAL_YRES_PIXELS 212 * 2 + (MSX2_YBORDER_PIXELS * 2)
+#define MSX2_VISIBLE_XBORDER_PIXELS 8 * 2
+#define MSX2_VISIBLE_YBORDER_PIXELS 14 * 2
+
+static MACHINE_DRIVER_START(meritm_crt250)
+ MDRV_CPU_ADD_TAG("main", Z80, SYSTEM_CLK/6)
+ MDRV_CPU_PROGRAM_MAP(meritm_crt250_map,0)
+ MDRV_CPU_IO_MAP(meritm_crt250_io_map,0)
+ MDRV_CPU_CONFIG(meritm_daisy_chain)
+ MDRV_CPU_VBLANK_INT_HACK(meritm_interrupt,262)
+
+ MDRV_MACHINE_START(meritm_crt250)
+
+ MDRV_NVRAM_HANDLER(generic_0fill)
+
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
+
+ MDRV_SCREEN_ADD("main",RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
- MDRV_SCREEN_SIZE(256, 256)
- MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 16, 256-16-1)
-
- MDRV_PALETTE_LENGTH(0x100)
- /* no gfx decode, MSX video chip doesn't use tiles, roms are memory mapped */
+ MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
+ MDRV_SCREEN_SIZE(MSX2_TOTAL_XRES_PIXELS, MSX2_TOTAL_YRES_PIXELS)
+ MDRV_SCREEN_VISIBLE_AREA(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1)
+ MDRV_PALETTE_LENGTH(512)
+
+ MDRV_PALETTE_INIT( v9938 )
MDRV_VIDEO_START(meritm)
MDRV_VIDEO_UPDATE(meritm)
+
+ /* sound hardware */
+ MDRV_SPEAKER_STANDARD_MONO("mono")
+ MDRV_SOUND_ADD(AY8910, SYSTEM_CLK/6)
+ MDRV_SOUND_CONFIG(ay8910_interface)
+ MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+MACHINE_DRIVER_END
+
+static MACHINE_DRIVER_START(meritm_crt250_questions)
+ MDRV_IMPORT_FROM(meritm_crt250)
+ MDRV_CPU_MODIFY("main")
+ MDRV_CPU_PROGRAM_MAP(meritm_crt250_questions_map,0)
+ MDRV_MACHINE_START(meritm_crt250_questions)
+MACHINE_DRIVER_END
+
+static MACHINE_DRIVER_START(meritm_crt260)
+ MDRV_IMPORT_FROM(meritm_crt250)
+ MDRV_CPU_MODIFY("main")
+ MDRV_CPU_PROGRAM_MAP(meritm_map,0)
+ MDRV_CPU_IO_MAP(meritm_io_map,0)
+
+ MDRV_WATCHDOG_TIME_INIT(UINT64_ATTOTIME_IN_MSEC(1200)) // DS1232, TD connected to VCC
+ MDRV_MACHINE_START(meritm_crt260)
+
+ MDRV_NVRAM_HANDLER(meritm_crt260)
+
MACHINE_DRIVER_END
-/* Type 1 */
/*
Pit Boss II - Merit Industries Inc. 1988
@@ -127,8 +1142,6 @@ ROM_START( spitboss )
ROM_LOAD( "u16", 0x70000, 0x10000, CRC(574fb3c7) SHA1(213741df3055b97ddd9889c2aa3d3e863e2c86d3) ) // matches pitboss2
ROM_END
-/* Type 2 */
-
/*
Pit Boss Megastar - Merit Industries Inc. 1994
@@ -168,16 +1181,17 @@ ROM_START( pitbossm )
ROM_LOAD( "6", 0x20000, 0x10000, CRC(47a9dfc7) SHA1(eca100003f5605bcf405f610a0458ccb67894d35) )
ROM_LOAD( "7", 0x30000, 0x10000, CRC(b9fb4203) SHA1(84b514d9739d9c2ab1081cfc7cdedb41155ee038) )
ROM_LOAD( "8", 0x40000, 0x10000, CRC(574fb3c7) SHA1(213741df3055b97ddd9889c2aa3d3e863e2c86d3) ) // == u16 on pitboss2/spitboss
- ROM_LOAD( "9", 0x50000, 0x10000, CRC(27034061) SHA1(cff6be592a4a3ab01c204b081470f224e6186c4d) )
+ ROM_RELOAD( 0x50000, 0x10000)
+ ROM_LOAD( "9", 0x60000, 0x10000, CRC(27034061) SHA1(cff6be592a4a3ab01c204b081470f224e6186c4d) )
+ ROM_RELOAD( 0x70000, 0x10000)
+
ROM_REGION( 0xc0000, REGION_USER1, 0 ) // extra data / extra banks?
- ROM_LOAD( "1", 0x00000, 0x40000, CRC(590a1565) SHA1(b80ea967b6153847b2594e9c59bfe87559022b6c) )
+ ROM_LOAD( "3", 0x00000, 0x40000, CRC(35f4ca46) SHA1(87917b3017f505fae65d6bfa2c7d6fb503c2da6a) )
ROM_LOAD( "2", 0x40000, 0x40000, CRC(606f1656) SHA1(7f1e3a698a34d3c3b8f9f2cd8d5224b6c096e941) )
- ROM_LOAD( "3", 0x80000, 0x40000, CRC(35f4ca46) SHA1(87917b3017f505fae65d6bfa2c7d6fb503c2da6a) )
+ ROM_LOAD( "1", 0x80000, 0x40000, CRC(590a1565) SHA1(b80ea967b6153847b2594e9c59bfe87559022b6c) )
ROM_END
-/* Type 3 */
-
/*
Mega Touch 3
by Merit Industries
@@ -202,13 +1216,64 @@ ROM_END
*/
ROM_START( megat3 )
- ROM_REGION( 0x180000, REGION_CPU1, 0 )
- ROM_LOAD( "megat3.u38", 0x00000, 0x80000, CRC(85f48b91) SHA1(7a38644ac7ee55a254c037122af919fb268744a1) )
- ROM_LOAD( "megat3.u37", 0x00000, 0x80000, CRC(96680164) SHA1(dfb8e07ba0e87316a947238e7a00fbf4d6ed5fe4) )
- ROM_LOAD( "megat3.u36", 0x00000, 0x80000, CRC(96bb501e) SHA1(f48ef238e8543676c42e3b85464a25ac179dcdd1) )
+ ROM_REGION( 0x400000, REGION_CPU1, 0 )
+ ROM_LOAD( "megat3.u32", 0x000000, 0x80000, CRC(ac969296) SHA1(7e09e9141637339b83c21f2488560cdf8a460069) )
+ ROM_RELOAD( 0x080000, 0x80000)
+ ROM_LOAD( "megat3.u36", 0x100000, 0x80000, CRC(96bb501e) SHA1(f48ef238e8543676c42e3b85464a25ac179dcdd1) )
+ ROM_RELOAD( 0x180000, 0x80000)
+ ROM_LOAD( "megat3.u37", 0x200000, 0x80000, BAD_DUMP CRC(96680164) SHA1(dfb8e07ba0e87316a947238e7a00fbf4d6ed5fe4) ) // should be 8MBit
+ ROM_RELOAD( 0x280000, 0x80000)
+ ROM_LOAD( "megat3.u38", 0x300000, 0x80000, CRC(85f48b91) SHA1(7a38644ac7ee55a254c037122af919fb268744a1) )
+ ROM_RELOAD( 0x380000, 0x80000)
+ROM_END
+
+ROM_START( megat4 )
+ ROM_REGION( 0x400000, REGION_CPU1, 0 )
+ ROM_LOAD( "megat4.u32", 0x000000, 0x100000, BAD_DUMP CRC(08b1b8fe) SHA1(c562f2e065d6d7f753f6fd1d0b8355b01cb089ec) ) // from megat4te dump
+ ROM_LOAD( "qs9255-02u36.bin", 0x100000, 0x80000, CRC(57322328) SHA1(12bc604c9d34cde431ef7cd2aa33c7b12ac01833) )
+ ROM_RELOAD( 0x180000, 0x80000)
+ ROM_LOAD( "qs9255-02u37.bin", 0x200000, 0x80000, CRC(f2e8bb4e) SHA1(5c5475b3c176a6aca9b2c6aa4aee422675d20bd1) )
+ ROM_RELOAD( 0x280000, 0x80000)
+ ROM_LOAD( "9255-40-01u38.bin", 0x300000, 0x80000, CRC(0d098424) SHA1(ef2810ccd636e69378fd353c8a95605274bb227f) )
+ ROM_RELOAD( 0x380000, 0x80000)
+ROM_END
+
+/*
+ Mega Touch 4
+ by Merit Industries
+
+ Dumped by Hugh McLenaghan!
+ on 08/29/2007
+
+
+ System Info
+ -----------
+ This is a counter top Touch screen game.
+
+ processor.. Z80
+ sound processor- YM2149
+ other chips- two Yamaha V9938
+ one LM1203
+ one PC165500N
+ one PB255a or L5220574
+ One Dallas DS1204 Data Key
+ One dallas DS1235Y 32k Non-volitile RAM
+ Two Z80APIO
+*/
+
+ROM_START( megat4te )
+ ROM_REGION( 0x400000, REGION_CPU1, 0 )
+ ROM_LOAD( "megat4.u32", 0x000000, 0x100000, CRC(08b1b8fe) SHA1(c562f2e065d6d7f753f6fd1d0b8355b01cb089ec) )
+ ROM_LOAD( "megat4.u36", 0x100000, 0x080000, CRC(57322328) SHA1(12bc604c9d34cde431ef7cd2aa33c7b12ac01833) )
+ ROM_RELOAD( 0x180000, 0x080000 )
+ ROM_LOAD( "megat4.u37", 0x200000, 0x080000, CRC(f2e8bb4e) SHA1(5c5475b3c176a6aca9b2c6aa4aee422675d20bd1) )
+ ROM_RELOAD( 0x280000, 0x080000 )
+ ROM_LOAD( "megat4.u38", 0x300000, 0x080000, CRC(124d5b84) SHA1(3c2117f56d0dc406bfb508989729e36781e215a4) )
+ ROM_RELOAD( 0x380000, 0x080000 )
+
+ ROM_REGION( 0x8000, REGION_USER1, 0 ) // DS1644 nv ram
+ ROM_LOAD( "ds1644.u31", 0x00000, 0x8000, CRC(0908bc39) SHA1(e6ec6238d6bf5c802e046407c0f25a83b09f6135) )
- ROM_REGION( 0x80000, REGION_USER1, 0 ) // extra data / extra banks?
- ROM_LOAD( "megat3.u32", 0x00000, 0x80000, CRC(ac969296) SHA1(7e09e9141637339b83c21f2488560cdf8a460069) )
ROM_END
/*
@@ -235,13 +1300,15 @@ ROM_END
*/
ROM_START( megat5 )
- ROM_REGION( 0x180000, REGION_CPU1, 0 )
- ROM_LOAD( "megat5.u38", 0x00000, 0x80000, CRC(018e36c7) SHA1(8e9b457238a40b10d59887d13bac9c0a05c73614) )
- ROM_LOAD( "megat5.u37", 0x00000, 0x80000, CRC(b713a1c5) SHA1(d6ccba2ea90fd0e2ecf15249514231eed54000c1) )
- ROM_LOAD( "megat5.u36", 0x00000, 0x80000, CRC(0bed9e27) SHA1(1414385ce562b127e1ddeccc20ea4ff2a7098b7e) )
-
- ROM_REGION( 0x80000, REGION_USER1, 0 ) // extra data / extra banks?
- ROM_LOAD( "megat5.u32", 0x00000, 0x80000, CRC(89932443) SHA1(68d2fbf2a5050fc5371595a105fe06f4276b0b67) )
+ ROM_REGION( 0x400000, REGION_CPU1, 0 )
+ ROM_LOAD( "megat5.u32", 0x000000, 0x80000, BAD_DUMP CRC(89932443) SHA1(68d2fbf2a5050fc5371595a105fe06f4276b0b67) )
+ ROM_RELOAD( 0x080000, 0x80000)
+ ROM_LOAD( "megat5.u36", 0x100000, 0x80000, BAD_DUMP CRC(0bed9e27) SHA1(1414385ce562b127e1ddeccc20ea4ff2a7098b7e) )
+ ROM_RELOAD( 0x180000, 0x80000)
+ ROM_LOAD( "megat5.u37", 0x200000, 0x80000, BAD_DUMP CRC(b713a1c5) SHA1(d6ccba2ea90fd0e2ecf15249514231eed54000c1) )
+ ROM_RELOAD( 0x280000, 0x80000)
+ ROM_LOAD( "megat5.u38", 0x300000, 0x80000, BAD_DUMP CRC(018e36c7) SHA1(8e9b457238a40b10d59887d13bac9c0a05c73614) )
+ ROM_RELOAD( 0x380000, 0x80000)
ROM_END
/*
@@ -290,32 +1357,73 @@ SC3943.u20 = ATF16V8B25PC
*/
ROM_START( megat6 )
- ROM_REGION( 0x280000, REGION_CPU1, 0 )
- ROM_LOAD( "u38-r0", 0x000000, 0x100000, CRC(3df6b840) SHA1(31ba1ac04eed3e76cdf637507dedcc5f7e22c919) )
- ROM_LOAD( "u37-r0", 0x100000, 0x100000, CRC(5ba01949) SHA1(1598949ea18d07bbc78af0ddd279a687173c1229) )
- ROM_LOAD( "u36-r0", 0x200000, 0x080000, CRC(800f5a1f) SHA1(4d3ee6fb896d6452aab1f279a3ee878284bd1acc) )
-
- ROM_REGION( 0x100000, REGION_USER1, 0 ) // extra data / extra banks?
- ROM_LOAD( "u32-r0", 0x00000, 0x100000, CRC(f8f7f48e) SHA1(1bebe1f8898c60b795a0f794ca9b79e03d2744e4) )
-
- ROM_REGION( 0x8000, REGION_USER2, 0 ) // DS1230 nv ram
+ ROM_REGION( 0x400000, REGION_CPU1, 0 )
+ ROM_LOAD( "u32-r0", 0x000000, 0x100000, CRC(f8f7f48e) SHA1(1bebe1f8898c60b795a0f794ca9b79e03d2744e4) )
+ ROM_LOAD( "u36-r0", 0x100000, 0x080000, CRC(800f5a1f) SHA1(4d3ee6fb896d6452aab1f279a3ee878284bd1acc) )
+ ROM_RELOAD( 0x180000, 0x080000 )
+ ROM_LOAD( "u37-r0", 0x200000, 0x100000, CRC(5ba01949) SHA1(1598949ea18d07bbc78af0ddd279a687173c1229) )
+ ROM_LOAD( "u38-r0", 0x300000, 0x100000, CRC(3df6b840) SHA1(31ba1ac04eed3e76cdf637507dedcc5f7e22c919) )
+
+ ROM_REGION( 0x8000, REGION_USER1, 0 ) // DS1230 nv ram
ROM_LOAD( "ds1230y.u31", 0x00000, 0x8000, CRC(51b6da5c) SHA1(1d53af89d7867bb48b9d46feff6fc3b7e8e80ac8) )
- ROM_REGION( 0x1000, REGION_USER3, 0 ) // PALs
+ ROM_REGION( 0x1000, REGION_USER2, 0 ) // PALs
ROM_LOAD( "sc3943.u20.bin", 0x000, 0x117, CRC(5a72fe78) SHA1(4b1a36904eb7048518507fe14bdade5c2589dbd7) )
ROM_LOAD( "sc3944-0a.bin", 0x000, 0x2dd, CRC(4cc46c5e) SHA1(0bab970df1539ce905f43603ad13171b05449a01) )
ROM_LOAD( "sc3980.bin", 0x000, 0x117, CRC(ee0cdab5) SHA1(216fef50a8a0f6a33b704d3501a4c5c3cbac2bad) )
ROM_LOAD( "sc39810a.bin", 0x000, 0x117, CRC(4fc750d0) SHA1(d09ff7a8c66aeb5c49e9fec84bd1521e3f5d8d0a) )
ROM_END
+static DRIVER_INIT(megat3)
+{
+ static const UINT8 megat3_ds1204_key[8] =
+ { 0xf0, 0xaa, 0x0f, 0x0f, 0x55, 0x55, 0xff, 0xab };
+
+ static const UINT8 megat3_ds1204_nvram[16] =
+ { 0x51, 0xa1, 0xc0, 0x7c, 0x27, 0x6e, 0x51, 0xb9, 0xa5, 0xb2, 0x27, 0x0c, 0xb9, 0x88, 0x82, 0x2c };
+
+ ds1204_init(megat3_ds1204_key, megat3_ds1204_nvram);
+
+ // patch for rom check (?) (Question Set Error)
+ ((UINT8*)memory_region( REGION_CPU1 ))[0x300217] = 0xc3;
+};
+
+static DRIVER_INIT(megat4)
+{
+ static const UINT8 megat4_ds1204_nvram[16] =
+ { 0xe3, 0x08, 0x39, 0xd8, 0x4c, 0xbb, 0xc4, 0xf8, 0xf0, 0xe2, 0xd8, 0x77, 0xa8, 0x3d, 0x95, 0x02 };
+
+ ds1204_init(0, megat4_ds1204_nvram);
+}
+
+static DRIVER_INIT(megat4te)
+{
+ static const UINT8 megat4te_ds1204_nvram[16] =
+ { 0x05, 0x21, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
+
+ ds1204_init(0, megat4te_ds1204_nvram);
+ memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xfff8, 0xffff, 0, 0, meritm_ds1644_w );
+ memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0xfff8, 0xffff, 0, 0, meritm_ds1644_r );
-/* Type 1 */
-GAME( 1988, pitboss2, 0, meritm, meritm, 0, ROT0, "Merit", "Pitboss II", GAME_NO_SOUND|GAME_NOT_WORKING )
-GAME( 198?, spitboss, 0, meritm, meritm, 0, ROT0, "Merit", "Super Pitboss", GAME_NO_SOUND|GAME_NOT_WORKING )
-/* Type 2 */
-GAME( 1994, pitbossm, 0, meritm, meritm, 0, ROT0, "Merit", "Pitboss Megastar", GAME_NO_SOUND|GAME_NOT_WORKING )
-/* Type 3 */
-GAME( 1995, megat3, 0, meritm, meritm, 0, ROT0, "Merit", "Megatouch 3", GAME_NO_SOUND|GAME_NOT_WORKING )
-GAME( 1997, megat5, 0, meritm, meritm, 0, ROT0, "Merit", "Megatouch 5", GAME_NO_SOUND|GAME_NOT_WORKING )
-GAME( 1998, megat6, 0, meritm, meritm, 0, ROT0, "Merit", "Megatouch 6", GAME_NO_SOUND|GAME_NOT_WORKING )
+};
+
+static DRIVER_INIT(megat6)
+{
+ static const UINT8 megat6_ds1204_nvram[16] =
+ { 0x07, 0x15, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
+
+ ds1204_init(0, megat6_ds1204_nvram);
+
+}
+/* CRT 250 */
+GAME( 1988, pitboss2, 0, meritm_crt250, meritm_crt250, 0, ROT0, "Merit", "Pit Boss II", GAME_IMPERFECT_GRAPHICS )
+GAME( 1988, spitboss, 0, meritm_crt250, meritm_crt250, 0, ROT0, "Merit", "Super Pit Boss", GAME_IMPERFECT_GRAPHICS )
+/* CRT 250 + question roms */
+GAME( 1994, pitbossm, 0, meritm_crt250_questions, pitbossm, 0, ROT0, "Merit", "Pit Boss Megastar", GAME_IMPERFECT_GRAPHICS )
+/* CRT 260 */
+GAME( 1995, megat3, 0, meritm_crt260, meritm_crt260, megat3, ROT0, "Merit", "Megatouch III", GAME_IMPERFECT_GRAPHICS|GAME_NOT_WORKING )
+GAME( 1996, megat4, 0, meritm_crt260, meritm_crt260, megat4, ROT0, "Merit", "Megatouch IV", GAME_IMPERFECT_GRAPHICS )
+GAME( 1996, megat4te, 0, meritm_crt260, meritm_crt260, megat4te, ROT0, "Merit", "Megatouch IV Tournament Edition", GAME_IMPERFECT_GRAPHICS )
+GAME( 1997, megat5, 0, meritm_crt260, meritm_crt260, 0, ROT0, "Merit", "Megatouch 5", GAME_IMPERFECT_GRAPHICS|GAME_NOT_WORKING )
+GAME( 1998, megat6, 0, meritm_crt260, meritm_crt260, megat6, ROT0, "Merit", "Megatouch 6", GAME_IMPERFECT_GRAPHICS )
diff --git a/src/mame/drivers/sangho.c b/src/mame/drivers/sangho.c
index dce8bbabd9e..5d80f5b7019 100644
--- a/src/mame/drivers/sangho.c
+++ b/src/mame/drivers/sangho.c
@@ -78,8 +78,8 @@ static WRITE8_HANDLER(pzlestar_bank_w)
static ADDRESS_MAP_START (readport_pzlestar, ADDRESS_SPACE_IO, 8)
ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE( 0x98, 0x98) AM_READ( v9938_vram_r )
- AM_RANGE( 0x99, 0x99) AM_READ( v9938_status_r )
+ AM_RANGE( 0x98, 0x98) AM_READ( v9938_0_vram_r )
+ AM_RANGE( 0x99, 0x99) AM_READ( v9938_0_status_r )
AM_RANGE( 0xa0, 0xa0) AM_READ( input_port_0_r )
AM_RANGE( 0xa1, 0xa1) AM_READ( input_port_1_r )
AM_RANGE( 0xf7, 0xf7) AM_READ( input_port_2_r )
@@ -90,10 +90,10 @@ static ADDRESS_MAP_START (writeport_pzlestar, ADDRESS_SPACE_IO, 8)
AM_RANGE( 0x91, 0x91) AM_WRITE( pzlestar_bank_w )
AM_RANGE( 0x7c, 0x7c) AM_WRITE( YM2413_register_port_0_w )
AM_RANGE( 0x7d, 0x7d) AM_WRITE( YM2413_data_port_0_w )
- AM_RANGE( 0x98, 0x98) AM_WRITE( v9938_vram_w )
- AM_RANGE( 0x99, 0x99) AM_WRITE( v9938_command_w )
- AM_RANGE( 0x9a, 0x9a) AM_WRITE( v9938_palette_w )
- AM_RANGE( 0x9b, 0x9b) AM_WRITE( v9938_register_w )
+ AM_RANGE( 0x98, 0x98) AM_WRITE( v9938_0_vram_w )
+ AM_RANGE( 0x99, 0x99) AM_WRITE( v9938_0_command_w )
+ AM_RANGE( 0x9a, 0x9a) AM_WRITE( v9938_0_palette_w )
+ AM_RANGE( 0x9b, 0x9b) AM_WRITE( v9938_0_register_w )
ADDRESS_MAP_END
/* Sexy Boom Ports */
@@ -103,18 +103,18 @@ static ADDRESS_MAP_START (readport_sexyboom, ADDRESS_SPACE_IO, 8)
AM_RANGE( 0xa0, 0xa0) AM_READ( input_port_0_r )
AM_RANGE( 0xa1, 0xa1) AM_READ( input_port_1_r )
AM_RANGE( 0xf7, 0xf7) AM_READ( input_port_2_r )
- AM_RANGE( 0xf0, 0xf0) AM_READ( v9938_vram_r )
- AM_RANGE( 0xf1, 0xf1) AM_READ( v9938_status_r )
+ AM_RANGE( 0xf0, 0xf0) AM_READ( v9938_0_vram_r )
+ AM_RANGE( 0xf1, 0xf1) AM_READ( v9938_0_status_r )
ADDRESS_MAP_END
static ADDRESS_MAP_START (writeport_sexyboom, ADDRESS_SPACE_IO, 8)
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE( 0x7c, 0x7c) AM_WRITE( YM2413_register_port_0_w )
AM_RANGE( 0x7d, 0x7d) AM_WRITE( YM2413_data_port_0_w )
- AM_RANGE( 0xf0, 0xf0) AM_WRITE( v9938_vram_w )
- AM_RANGE( 0xf1, 0xf1) AM_WRITE( v9938_command_w )
- AM_RANGE( 0xf2, 0xf2) AM_WRITE( v9938_palette_w )
- AM_RANGE( 0xf3, 0xf3) AM_WRITE( v9938_register_w )
+ AM_RANGE( 0xf0, 0xf0) AM_WRITE( v9938_0_vram_w )
+ AM_RANGE( 0xf1, 0xf1) AM_WRITE( v9938_0_command_w )
+ AM_RANGE( 0xf2, 0xf2) AM_WRITE( v9938_0_palette_w )
+ AM_RANGE( 0xf3, 0xf3) AM_WRITE( v9938_0_register_w )
//bank f8-ff ???
ADDRESS_MAP_END
@@ -185,7 +185,7 @@ static void sangho_common_machine_reset(void)
memory_set_bankptr(2,&sangho_ram[0x4000]);
memory_set_bankptr(3,&sangho_ram[0x8000]);
memory_set_bankptr(4,&sangho_ram[0xc000]);
- v9938_reset();
+ v9938_reset(0);
}
@@ -219,15 +219,15 @@ static void msx_vdp_interrupt(int i)
static INTERRUPT_GEN( sangho_interrupt )
{
- v9938_set_sprite_limit(0);
- v9938_set_resolution(2);
- v9938_interrupt();
+ v9938_set_sprite_limit(0, 0);
+ v9938_set_resolution(0, 2);
+ v9938_interrupt(0);
}
static VIDEO_START( sangho )
{
- v9938_init (machine, MODEL_V9938, 0x20000, msx_vdp_interrupt);
+ v9938_init (machine, 0, tmpbitmap, MODEL_V9938, 0x20000, msx_vdp_interrupt);
}
static MACHINE_DRIVER_START(pzlestar)
diff --git a/src/mame/mamedriv.c b/src/mame/mamedriv.c
index 4878759354b..365ce23f3e2 100644
--- a/src/mame/mamedriv.c
+++ b/src/mame/mamedriv.c
@@ -7767,6 +7767,8 @@ Other Sun games
DRIVER( spitboss ) /* (c) 198? Merit */
DRIVER( pitbossm ) /* (c) 1994 Merit */
DRIVER( megat3 ) /* (c) 1995 Merit */
+ DRIVER( megat4 ) /* (c) 1996 Merit */
+ DRIVER( megat4te ) /* (c) 1996 Merit */
DRIVER( megat5 ) /* (c) 1997 Merit */
DRIVER( megat6 ) /* (c) 1998 Merit */
DRIVER( suprgolf ) /* (c) 19?? Nasco */