📄 neogeo.c
字号:
/***************************************************************************
M.A.M.E. Neo Geo driver presented to you by the Shin Emu Keikaku team.
The following people have all spent probably far too much time on this:
AVDB
Bryan McPhail
Fuzz
Ernesto Corvi
Andrew Prime
Plus rom-loaders and testing from Santeri Saarimaa, Rodimus Prime and
probably others :)
TODO :
- Properly emulate the uP4990.
- What does 0x3c0006-7 *REALLY* do?
=============================================================================
Points to note, known and proven information deleted from this map:
0x3000001 Dipswitches
bit 0 : Selftest
bit 1 : Unknown (Unused ?) \ something to do with
bit 2 : Unknown (Unused ?) / auto repeating keys ?
bit 3 : \
bit 4 : | communication setting ?
bit 5 : /
bit 6 : free play
bit 7 : stop mode ?
0x320001 bit 0 : COIN 1
bit 1 : COIN 2
bit 2 : SERVICE
bit 3 : UNKNOWN
bit 4 : UNKNOWN
bit 5 : UNKNOWN
bit 6 : 4990 test pulse bit.
bit 7 : 4990 data bit.
0x380051 4990 control write register
bit 0: C0
bit 1: C1
bit 2: C2
bit 3-7: unused.
0x02 = shift.
0x00 = register hold.
0x04 = ????.
0x03 = time read (reset register).
0x3c000c IRQ acknowledge
0x380011 Backup bank select
0x3a0001 Enable display.
0x3a0011 Disable display
0x3a0003 Swap in Bios (0x80 bytes vector table of BIOS)
0x3a0013 Swap in Rom (0x80 bytes vector table of ROM bank)
0x3a000d lock backup ram
0x3a001d unlock backup ram
0x3a000b set game vector table (?) mirror ?
0x3a001b set bios vector table (?) mirror ?
0x3a000c Unknown (ghost pilots)
0x31001c Unknown (ghost pilots)
IO word read
0x3c0002 return vidram word (pointed to by 0x3c0000)
0x3c0006 ?????.
0x3c0008 shadow adress for 0x3c0000 (not confirmed).
0x3c000a shadow adress for 0x3c0002 (confirmed, see
Puzzle de Pon).
IO word write
0x3c0006 Unknown, set vblank counter (?)
0x3c0008 shadow address for 0x3c0000 (not confirmed)
0x3c000a shadow address for 0x3c0002 (not confirmed)
The Neo Geo contains an NEC 4990 Serial I/O calendar & clock.
accesed through 0x320001, 0x380050, 0x280050 (shadow adress).
A schematic for this device can be found on the NEC webpages.
******************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "machine/pd4990a.h"
extern unsigned char *vidram;
extern unsigned char *neogeo_ram;
extern unsigned char *neogeo_sram;
void neogeo_sram_lock_w(int offset,int data);
void neogeo_sram_unlock_w(int offset,int data);
int neogeo_sram_r(int offset);
void neogeo_sram_w(int offset,int data);
int neogeo_sram_load(void);
void neogeo_sram_save(void);
/* from vidhrdw/neogeo.c */
void neogeo_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
int neogeo_mvs_vh_start(void);
int neogeo_mgd2_vh_start(void);
void neogeo_vh_stop(void);
void neogeo_paletteram_w(int offset,int data);
int neogeo_paletteram_r(int offset);
void neogeo_setpalbank0(int offset, int data);
void neogeo_setpalbank1(int offset, int data);
void neo_board_fix(int offset, int data);
void neo_game_fix(int offset, int data);
void vidram_modulo_w(int offset, int data);
void vidram_data_w(int offset, int data);
void vidram_offset_w(int offset, int data);
int vidram_data_r(int offset);
int vidram_modulo_r(int offset);
/* debug, used to 'see' the locations mapped in ROM space */
/* with the debugger */
int mish_vid_r(int offset);
void mish_vid_w(int offset, int data);
/* end debug */
void neo_unknown1(int offset, int data);
void neo_unknown2(int offset, int data);
void neo_unknown3(int offset, int data);
void neo_unknown4(int offset, int data);
/* from machine/neogeo.c */
void neogeo_init_machine(void);
void neogeo_onetime_init_machine(void);
/******************************************************************************/
unsigned int neogeo_frame_counter;
unsigned int neogeo_frame_counter_speed=4;
/******************************************************************************/
static int irq2_enable;
static int neogeo_interrupt(void)
{
static int fc=0;
/* Add a timer tick to the pd4990a */
addretrace();
/* Animation counter, 1 once per frame is too fast, every 4 seems good */
if (fc>=neogeo_frame_counter_speed) {
fc=0;
neogeo_frame_counter++;
}
fc++;
if (irq2_enable || osd_key_pressed(OSD_KEY_F1)) cpu_cause_interrupt(0,2);
/* return a standard vblank interrupt */
return(1); /* vertical blank */
}
/* Move to calendar file later */
static void neo_pd4990a_control_w(int offset, int data)
{
int a=0;
a++;
}
static int pending_command;
static int result_code;
/* Calendar, coins + Z80 communication */
static int timer_r (int offset)
{
int res;
/* This is just for testing purposes */
/* not real correct code */
int coinflip = read_4990_testbit();
res = readinputport(4) ^ (coinflip << 6) ^ (coinflip << 7);
if (Machine->sample_rate)
{
res |= result_code << 8;
if (pending_command) res &= 0x7fff;
}
else
res |= 0x0100;
return res;
}
static void neo_z80_w(int offset, int data)
{
soundlatch_w(0,(data>>8)&0xff);
pending_command = 1;
cpu_cause_interrupt(1,-2/*Z80_NMI_INT*/);
}
static int controller1_r (int offset) { return ( (readinputport(0) << 8) + readinputport(3) ); }
static int controller2_r (int offset) { return (readinputport(1) << 8); }
static int controller3_r (int offset) { return (readinputport(2) << 8); }
static int controller4_r (int offset) { return readinputport(6); }
static void neo_bankswitch_w(int offset, int data)
{
unsigned char *RAM = Machine->memory_region[0];
int bankaddress;
if (Machine->memory_region_length[0] <= 0x100000)
{
return;
}
data = data&0x7;
bankaddress = (data+1)*0x100000;
if (bankaddress >= Machine->memory_region_length[0])
{
bankaddress = 0x100000;
}
cpu_setbank(4,&RAM[bankaddress]);
}
extern int neogeo_game_fix;
/* Temporary, Todo: Figure out how this really works! :) */
static int neo_control_r(int offset)
{
switch(neogeo_game_fix)
{
case 0:
return (neogeo_frame_counter) & 0x0007; /* Blazing Stars */
case 1:
if (cpu_getpc() == 0x1b04) return 0x8000; /* Fix for Voltage Fighter */
case 2:
return 0x2000; /* real bout 2 */
case 3:
return 0x80; /* sam sho3 */
case 4:
return 0xb801; /* overtop */
case 5:
return 0x7000; /* Fix for KOF97 */
case 6:
return 0x8000; /* Money Idol Exchanger */
case 8:
return 0xffff; /* Ninja Command */
}
return(0x8000); /* anything 0x8000 seems better than 0*/
}
/* this does much more than this, but I'm not sure exactly what */
void neo_control_w(int offset, int data)
{
/* I'm waving my hands in a big way here... */
/* Games which definitely need IRQ2:
sengoku2
spinmast
ridhero
turfmast
*/
if ((data & 0xff) == 0xd0) /* certainly wrong, but fixes spinmast & sengoku2 */
irq2_enable = 1;
else
irq2_enable = 0;
if((data & 0xf0ff) == 0)
{
/* Auto-Anim Speed Control ? */
int speed = (data >> 8) & 0xf;
if(speed!=0) neogeo_frame_counter_speed=speed;
}
}
static void neo_irq2pos_w(int offset,int data)
{
static int value;
if (offset == 0)
value = (value & 0x0000ffff) | (data << 16);
else
value = (value & 0xffff0000) | data;
}
/******************************************************************************/
static struct MemoryReadAddress neogeo_readmem[] =
{
{ 0x000000, 0x0fffff, MRA_ROM }, /* Rom bank 1 */
{ 0x100000, 0x10ffff, MRA_BANK1 }, /* Ram bank 1 */
{ 0x200000, 0x2fffff, MRA_BANK4 }, /* Rom bank 2 */
{ 0x300000, 0x300001, controller1_r },
{ 0x300080, 0x300081, controller4_r }, /* Test switch in here */
{ 0x320000, 0x320001, timer_r }, /* Coins, Calendar, Z80 communication */
{ 0x340000, 0x340001, controller2_r },
{ 0x380000, 0x380001, controller3_r },
{ 0x3c0000, 0x3c0001, vidram_data_r }, /* Baseball Stars */
{ 0x3c0002, 0x3c0003, vidram_data_r },
{ 0x3c0004, 0x3c0005, vidram_modulo_r },
{ 0x3c0006, 0x3c0007, neo_control_r },
{ 0x3c000a, 0x3c000b, vidram_data_r }, /* Puzzle de Pon */
{ 0x400000, 0x401fff, neogeo_paletteram_r },
{ 0x600000, 0x61ffff, mish_vid_r },
{ 0xc00000, 0xc1ffff, MRA_BANK3 }, /* system bios rom */
{ 0xd00000, 0xd0ffff, neogeo_sram_r }, /* 64k battery backed SRAM */
{ -1 } /* end of table */
};
static struct MemoryWriteAddress neogeo_writemem[] =
{
{ 0x000000, 0x0fffff, MWA_ROM }, /* ghost pilots writes to ROM */
{ 0x100000, 0x10ffff, MWA_BANK1 },
/* { 0x200000, 0x200fff, whp copies ROM data here. Why? Is there RAM in the banked ROM space? */
/* trally writes to 200000-200003 as well */
/* both games write to 0000fe before writing to 200000. The two things could be related. */
{ 0x2ffff0, 0x2fffff, neo_bankswitch_w }, /* NOTE THIS CHANGE TO END AT FF !!! */
{ 0x300000, 0x300001, watchdog_reset_w },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -