diff options
| author | 2008-03-13 15:04:33 +0000 | |
|---|---|---|
| committer | 2008-03-13 15:04:33 +0000 | |
| commit | 9d3f7f8680637c4e5a49e45aa5891c32faaa47cd (patch) | |
| tree | bd2a38330ab79353a899356daaece7f2625920f5 /src | |
| parent | 834d773f26b24ac438202710127d49e236b6e2d1 (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.c | 8 | ||||
| -rw-r--r-- | src/emu/machine/pc16552d.h | 2 | ||||
| -rw-r--r-- | src/emu/machine/z80pio.c | 77 | ||||
| -rw-r--r-- | src/emu/machine/z80pio.h | 12 | ||||
| -rw-r--r-- | src/emu/memory.c | 528 | ||||
| -rw-r--r-- | src/emu/memory.h | 307 | ||||
| -rw-r--r-- | src/emu/tilemap.c | 3 | ||||
| -rw-r--r-- | src/emu/video/v9938.c | 1160 | ||||
| -rw-r--r-- | src/emu/video/v9938.h | 33 | ||||
| -rw-r--r-- | src/emu/video/v9938mod.c | 288 | ||||
| -rw-r--r-- | src/mame/drivers/firebeat.c | 4 | ||||
| -rw-r--r-- | src/mame/drivers/meritm.c | 1272 | ||||
| -rw-r--r-- | src/mame/drivers/sangho.c | 34 | ||||
| -rw-r--r-- | src/mame/mamedriv.c | 2 |
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(µtouch, 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 */ |
