naomi: Initial support for TARGET_NAOMI, windows only
- Import naomi code from nullDC, modify and cleanup - Only unprotected dimm-board support, custom lst files - Still a compile option - Boots naomi bios and some games, no input yet
This commit is contained in:
parent
9bc0a8ff0f
commit
7d0d2ba572
15
core/build.h
15
core/build.h
|
@ -118,16 +118,13 @@
|
||||||
#define NO_MMU
|
#define NO_MMU
|
||||||
|
|
||||||
#define DC_PLATFORM_MASK 7
|
#define DC_PLATFORM_MASK 7
|
||||||
#define DC_PLATFORM_NORMAL 0 /* Works, for the most part */
|
#define DC_PLATFORM_DREAMCAST 0 /* Works, for the most part */
|
||||||
#define DC_PLATFORM_DEV_UNIT 1 /* This is missing hardware */
|
#define DC_PLATFORM_DEV_UNIT 1 /* This is missing hardware */
|
||||||
#define DC_PLATFORM_NAOMI 2 /* Works, for the most part */
|
#define DC_PLATFORM_NAOMI 2 /* Works, for the most part */
|
||||||
#define DC_PLATFORM_NAOMI2 3 /* Needs to be done, 2xsh4 + 2xpvr + custom TNL */
|
#define DC_PLATFORM_NAOMI2 3 /* Needs to be done, 2xsh4 + 2xpvr + custom TNL */
|
||||||
#define DC_PLATFORM_ATOMISWAVE 4 /* Needs to be done, DC-like hardware with possibly more ram */
|
#define DC_PLATFORM_ATOMISWAVE 4 /* Needs to be done, DC-like hardware with possibly more ram */
|
||||||
#define DC_PLATFORM_HIKARU 5 /* Needs to be done, 2xsh4, 2x aica , custom vpu */
|
#define DC_PLATFORM_HIKARU 5 /* Needs to be done, 2xsh4, 2x aica , custom vpu */
|
||||||
#define DC_PLATFORM_AURORA 6 /* Needs to be done, Uses newer 300 mhz sh4 + 150 mhz pvr mbx SoC */
|
#define DC_PLATFORM_AURORA 6 /* Needs to be done, Uses newer 300 mhz sh4 + 150 mhz pvr mbx SoC */
|
||||||
|
|
||||||
|
|
||||||
#define DC_PLATFORM DC_PLATFORM_NORMAL
|
|
||||||
|
|
||||||
|
|
||||||
//HOST_OS
|
//HOST_OS
|
||||||
|
@ -206,6 +203,11 @@
|
||||||
#error Invalid Target: TARGET_* not defined
|
#error Invalid Target: TARGET_* not defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TARGET_NAOMI)
|
||||||
|
#define DC_PLATFORM DC_PLATFORM_NAOMI
|
||||||
|
#undef TARGET_NAOMI
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TARGET_NO_REC)
|
#if defined(TARGET_NO_REC)
|
||||||
#define FEAT_SHREC DYNAREC_NONE
|
#define FEAT_SHREC DYNAREC_NONE
|
||||||
#define FEAT_AREC DYNAREC_NONE
|
#define FEAT_AREC DYNAREC_NONE
|
||||||
|
@ -234,6 +236,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//defaults
|
//defaults
|
||||||
|
|
||||||
|
#ifndef DC_PLATFORM
|
||||||
|
#define DC_PLATFORM DC_PLATFORM_DREAMCAST
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FEAT_SHREC
|
#ifndef FEAT_SHREC
|
||||||
#define FEAT_SHREC DYNAREC_JIT
|
#define FEAT_SHREC DYNAREC_JIT
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,7 +172,7 @@ struct DCFlashChip : MemChip // I think its Micronix :p
|
||||||
{
|
{
|
||||||
u32 rv=MemChip::Read8(addr);
|
u32 rv=MemChip::Read8(addr);
|
||||||
|
|
||||||
#if DC_PLATFORM==DC_PLATFORM_NORMAL
|
#if DC_PLATFORM==DC_PLATFORM_DREAMCAST
|
||||||
if ((addr==0x1A002 || addr==0x1A0A2) && settings.dreamcast.region<=2)
|
if ((addr==0x1A002 || addr==0x1A0A2) && settings.dreamcast.region<=2)
|
||||||
return '0' + settings.dreamcast.region;
|
return '0' + settings.dreamcast.region;
|
||||||
else if ((addr==0x1A004 || addr==0x1A0A4) && settings.dreamcast.broadcast<=3)
|
else if ((addr==0x1A004 || addr==0x1A0A4) && settings.dreamcast.broadcast<=3)
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
#include "hw/maple/maple_if.h"
|
#include "hw/maple/maple_if.h"
|
||||||
#include "hw/aica/aica_if.h"
|
#include "hw/aica/aica_if.h"
|
||||||
|
|
||||||
#if defined(BUILD_NAOMI) || defined(BUILD_ATOMISWAVE)
|
#include "hw/naomi/naomi.h"
|
||||||
#include "../../naomi/naomi.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Array<RegisterStruct> sb_regs(0x540);
|
Array<RegisterStruct> sb_regs(0x540);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "hw/pvr/pvr_mem.h"
|
#include "hw/pvr/pvr_mem.h"
|
||||||
#include "hw/gdrom/gdrom_if.h"
|
#include "hw/gdrom/gdrom_if.h"
|
||||||
#include "hw/aica/aica_if.h"
|
#include "hw/aica/aica_if.h"
|
||||||
//#include "naomi/naomi.h"
|
#include "hw/naomi/naomi.h"
|
||||||
|
|
||||||
#include "hw/flashrom/flashrom.h"
|
#include "hw/flashrom/flashrom.h"
|
||||||
#include "reios/reios.h"
|
#include "reios/reios.h"
|
||||||
|
@ -63,7 +63,7 @@ bool LoadHle(const string& root) {
|
||||||
return reios_init(sys_rom.data, sys_nvmem.data);
|
return reios_init(sys_rom.data, sys_nvmem.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (DC_PLATFORM == DC_PLATFORM_NORMAL) || (DC_PLATFORM == DC_PLATFORM_DEV_UNIT) || (DC_PLATFORM == DC_PLATFORM_NAOMI) || (DC_PLATFORM == DC_PLATFORM_NAOMI2)
|
#if (DC_PLATFORM == DC_PLATFORM_DREAMCAST) || (DC_PLATFORM == DC_PLATFORM_DEV_UNIT) || (DC_PLATFORM == DC_PLATFORM_NAOMI) || (DC_PLATFORM == DC_PLATFORM_NAOMI2)
|
||||||
|
|
||||||
u32 ReadBios(u32 addr,u32 sz) { return sys_rom.Read(addr,sz); }
|
u32 ReadBios(u32 addr,u32 sz) { return sys_rom.Read(addr,sz); }
|
||||||
void WriteBios(u32 addr,u32 data,u32 sz) { EMUERROR4("Write to [Boot ROM] is not possible, addr=%x,data=%x,size=%d",addr,data,sz); }
|
void WriteBios(u32 addr,u32 data,u32 sz) { EMUERROR4("Write to [Boot ROM] is not possible, addr=%x,data=%x,size=%d",addr,data,sz); }
|
||||||
|
@ -151,7 +151,7 @@ T DYNACALL ReadMem_area0(u32 addr)
|
||||||
else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM
|
else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM
|
||||||
{
|
{
|
||||||
//EMUERROR3("Read from area0_32 not implemented [GD-ROM], addr=%x,size=%d",addr,sz);
|
//EMUERROR3("Read from area0_32 not implemented [GD-ROM], addr=%x,size=%d",addr,sz);
|
||||||
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||||
return (T)ReadMem_naomi(addr,sz);
|
return (T)ReadMem_naomi(addr,sz);
|
||||||
#else
|
#else
|
||||||
return (T)ReadMem_gdrom(addr,sz);
|
return (T)ReadMem_gdrom(addr,sz);
|
||||||
|
@ -238,7 +238,7 @@ void DYNACALL WriteMem_area0(u32 addr,T data)
|
||||||
else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM
|
else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM
|
||||||
{
|
{
|
||||||
//EMUERROR4("Write to area0_32 not implemented [GD-ROM], addr=%x,data=%x,size=%d",addr,data,sz);
|
//EMUERROR4("Write to area0_32 not implemented [GD-ROM], addr=%x,data=%x,size=%d",addr,data,sz);
|
||||||
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE
|
||||||
WriteMem_naomi(addr,data,sz);
|
WriteMem_naomi(addr,data,sz);
|
||||||
#else
|
#else
|
||||||
WriteMem_gdrom(addr,data,sz);
|
WriteMem_gdrom(addr,data,sz);
|
||||||
|
|
|
@ -66,25 +66,17 @@ void mcfg_Create(MapleDeviceType type,u32 bus,u32 port)
|
||||||
MapleDevices[bus][port]=dev;
|
MapleDevices[bus][port]=dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _ANDROID
|
|
||||||
void mcfg_CreateDevices()
|
void mcfg_CreateDevices()
|
||||||
{
|
{
|
||||||
|
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
|
||||||
mcfg_Create(MDT_SegaController,0,5);
|
mcfg_Create(MDT_SegaController,0,5);
|
||||||
|
|
||||||
#ifdef HAS_VMU
|
|
||||||
mcfg_Create(MDT_SegaVMU,0,0);
|
mcfg_Create(MDT_SegaVMU,0,0);
|
||||||
mcfg_Create(MDT_SegaVMU,0,1);
|
mcfg_Create(MDT_SegaVMU,0,1);
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
void mcfg_CreateDevices()
|
mcfg_Create(MDT_NaomiJamma, 0, 5);
|
||||||
{
|
|
||||||
mcfg_Create(MDT_SegaController,0,5);
|
|
||||||
|
|
||||||
mcfg_Create(MDT_SegaVMU,0,0);
|
|
||||||
mcfg_Create(MDT_SegaVMU,0,1);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void mcfg_DestroyDevices()
|
void mcfg_DestroyDevices()
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,8 +25,6 @@ const char* maple_sega_mic_name = "MicDevice for Dreameye";
|
||||||
|
|
||||||
const char* maple_sega_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD.";
|
const char* maple_sega_brand = "Produced By or Under License From SEGA ENTERPRISES,LTD.";
|
||||||
|
|
||||||
#define HAS_VMU
|
|
||||||
|
|
||||||
enum MapleFunctionID
|
enum MapleFunctionID
|
||||||
{
|
{
|
||||||
MFID_0_Input = 0x01000000, //DC Controller, Lightgun buttons, arcade stick .. stuff like that
|
MFID_0_Input = 0x01000000, //DC Controller, Lightgun buttons, arcade stick .. stuff like that
|
||||||
|
@ -243,7 +241,7 @@ struct maple_sega_controller: maple_base
|
||||||
Sega Dreamcast Visual Memory Unit
|
Sega Dreamcast Visual Memory Unit
|
||||||
This is pretty much done (?)
|
This is pretty much done (?)
|
||||||
*/
|
*/
|
||||||
#ifdef HAS_VMU
|
|
||||||
|
|
||||||
u8 vmu_default[] = {
|
u8 vmu_default[] = {
|
||||||
0x78,0x9c,0xed,0xd2,0x31,0x4e,0x02,0x61,0x10,0x06,0xd0,0x8f,0x04,0x28,0x4c,0x2c,
|
0x78,0x9c,0xed,0xd2,0x31,0x4e,0x02,0x61,0x10,0x06,0xd0,0x8f,0x04,0x28,0x4c,0x2c,
|
||||||
|
@ -664,7 +662,7 @@ struct maple_sega_vmu: maple_base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
struct maple_microphone: maple_base
|
struct maple_microphone: maple_base
|
||||||
{
|
{
|
||||||
|
@ -846,6 +844,441 @@ struct maple_microphone: maple_base
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
char EEPROM[0x100];
|
||||||
|
bool EEPROM_loaded = false;
|
||||||
|
|
||||||
|
struct _NaomiState
|
||||||
|
{
|
||||||
|
BYTE Cmd;
|
||||||
|
BYTE Mode;
|
||||||
|
BYTE Node;
|
||||||
|
};
|
||||||
|
_NaomiState State;
|
||||||
|
|
||||||
|
|
||||||
|
enum NAOMI_KEYS
|
||||||
|
{
|
||||||
|
NAOMI_SERVICE_KEY_1 = 1 << 0,
|
||||||
|
NAOMI_TEST_KEY_1 = 1 << 1,
|
||||||
|
NAOMI_SERVICE_KEY_2 = 1 << 2,
|
||||||
|
NAOMI_TEST_KEY_2 = 1 << 3,
|
||||||
|
|
||||||
|
NAOMI_START_KEY = 1 << 4,
|
||||||
|
|
||||||
|
NAOMI_UP_KEY = 1 << 5,
|
||||||
|
NAOMI_DOWN_KEY = 1 << 6,
|
||||||
|
NAOMI_LEFT_KEY = 1 << 7,
|
||||||
|
NAOMI_RIGHT_KEY = 1 << 8,
|
||||||
|
|
||||||
|
NAOMI_BTN0_KEY = 1 << 9,
|
||||||
|
NAOMI_BTN1_KEY = 1 << 10,
|
||||||
|
NAOMI_BTN2_KEY = 1 << 11,
|
||||||
|
NAOMI_BTN3_KEY = 1 << 12,
|
||||||
|
NAOMI_BTN4_KEY = 1 << 13,
|
||||||
|
NAOMI_BTN5_KEY = 1 << 14,
|
||||||
|
NAOMI_COIN_KEY = 1 << 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void printState(u32 cmd, u32* buffer_in, u32 buffer_in_len)
|
||||||
|
{
|
||||||
|
printf("Command : 0x%X", cmd);
|
||||||
|
if (buffer_in_len>0)
|
||||||
|
printf(",Data : %d bytes\n", buffer_in_len);
|
||||||
|
else
|
||||||
|
printf("\n");
|
||||||
|
buffer_in_len >>= 2;
|
||||||
|
while (buffer_in_len-->0)
|
||||||
|
{
|
||||||
|
printf("%08X ", *buffer_in++);
|
||||||
|
if (buffer_in_len == 0)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sega Dreamcast Controller
|
||||||
|
No error checking of any kind, but works just fine
|
||||||
|
*/
|
||||||
|
struct maple_naomi_jamma : maple_sega_controller
|
||||||
|
{
|
||||||
|
virtual u32 dma(u32 cmd)
|
||||||
|
{
|
||||||
|
u32* buffer_in = (u32*)dma_buffer_in;
|
||||||
|
u32* buffer_out = (u32*)dma_buffer_out;
|
||||||
|
|
||||||
|
u8* buffer_in_b = dma_buffer_in;
|
||||||
|
u8* buffer_out_b = dma_buffer_out;
|
||||||
|
|
||||||
|
u32& buffer_out_len = *dma_count_out;
|
||||||
|
u32 buffer_in_len = dma_count_in;
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case 0x86:
|
||||||
|
{
|
||||||
|
u32 subcode = *(u8*)buffer_in;
|
||||||
|
//printf("Naomi 0x86 : %x\n",SubCode);
|
||||||
|
switch (subcode)
|
||||||
|
{
|
||||||
|
case 0x15:
|
||||||
|
case 0x33:
|
||||||
|
{
|
||||||
|
buffer_out[0] = 0xffffffff;
|
||||||
|
buffer_out[1] = 0xffffffff;
|
||||||
|
u32 keycode = 0;// ~kcode[0];
|
||||||
|
u32 keycode2 = 0;// ~kcode[1];
|
||||||
|
/*
|
||||||
|
if (keycode&NAOMI_SERVICE_KEY_2) //Service
|
||||||
|
buffer_out[0] &= ~(1 << 0x1b);
|
||||||
|
|
||||||
|
if (keycode&NAOMI_TEST_KEY_2) //Test
|
||||||
|
buffer_out[0] &= ~(1 << 0x1a);
|
||||||
|
*/
|
||||||
|
if (State.Mode == 0 && subcode != 0x33) //Get Caps
|
||||||
|
{
|
||||||
|
buffer_out_b[0x11 + 1] = 0x8E; //Valid data check
|
||||||
|
buffer_out_b[0x11 + 2] = 0x01;
|
||||||
|
buffer_out_b[0x11 + 3] = 0x00;
|
||||||
|
buffer_out_b[0x11 + 4] = 0xFF;
|
||||||
|
buffer_out_b[0x11 + 5] = 0xE0;
|
||||||
|
buffer_out_b[0x11 + 8] = 0x01;
|
||||||
|
|
||||||
|
switch (State.Cmd)
|
||||||
|
{
|
||||||
|
//Reset, in : 2 bytes, out : 0
|
||||||
|
case 0xF0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Find nodes?
|
||||||
|
//In addressing Slave address, in : 2 bytes, out : 1
|
||||||
|
case 0xF1:
|
||||||
|
{
|
||||||
|
buffer_out_len = 4 * 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Speed Change, in : 2 bytes, out : 0
|
||||||
|
case 0xF2:
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Name
|
||||||
|
//"In the I / O ID" "Reading each slave ID data"
|
||||||
|
//"NAMCO LTD.; I / O PCB-1000; ver1.0; for domestic only, no analog input"
|
||||||
|
//in : 1 byte, out : max 102
|
||||||
|
case 0x10:
|
||||||
|
{
|
||||||
|
static char ID1[102] = "nullDC Team; I/O Plugin-1; ver0.2; for nullDC or other emus";
|
||||||
|
buffer_out_b[0x8 + 0x10] = (BYTE)strlen(ID1) + 3;
|
||||||
|
for (int i = 0; ID1[i] != 0; ++i)
|
||||||
|
{
|
||||||
|
buffer_out_b[0x8 + 0x13 + i] = ID1[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//CMD Version
|
||||||
|
//REV in command|Format command to read the (revision)|One|Two
|
||||||
|
//in : 1 byte, out : 2 bytes
|
||||||
|
case 0x11:
|
||||||
|
{
|
||||||
|
buffer_out_b[0x8 + 0x13] = 0x13;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//JVS Version
|
||||||
|
//In JV REV|JAMMA VIDEO standard reading (revision)|One|Two
|
||||||
|
//in : 1 byte, out : 2 bytes
|
||||||
|
case 0x12:
|
||||||
|
{
|
||||||
|
buffer_out_b[0x8 + 0x13] = 0x30;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//COM Version
|
||||||
|
//VER in the communication system|Read a communication system compliant version of |One|Two
|
||||||
|
//in : 1 byte, out : 2 bytes
|
||||||
|
case 0x13:
|
||||||
|
{
|
||||||
|
buffer_out_b[0x8 + 0x13] = 0x10;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Features
|
||||||
|
//Check in feature |Each features a slave to read |One |6 to
|
||||||
|
//in : 1 byte, out : 6 + (?)
|
||||||
|
case 0x14:
|
||||||
|
{
|
||||||
|
unsigned char *FeatPtr = buffer_out_b + 0x8 + 0x13;
|
||||||
|
buffer_out_b[0x8 + 0x9 + 0x3] = 0x0;
|
||||||
|
buffer_out_b[0x8 + 0x9 + 0x9] = 0x1;
|
||||||
|
#define ADDFEAT(Feature,Count1,Count2,Count3) *FeatPtr++=Feature; *FeatPtr++=Count1; *FeatPtr++=Count2; *FeatPtr++=Count3;
|
||||||
|
ADDFEAT(1, 2, 12, 0); //Feat 1=Digital Inputs. 2 Players. 10 bits
|
||||||
|
ADDFEAT(2, 2, 0, 0); //Feat 2=Coin inputs. 2 Inputs
|
||||||
|
ADDFEAT(3, 2, 0, 0); //Feat 3=Analog. 2 Chans
|
||||||
|
|
||||||
|
ADDFEAT(0, 0, 0, 0); //End of list
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown CAP %X\n", State.Cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
buffer_out_len = 4 * 4;
|
||||||
|
}
|
||||||
|
else if (State.Mode == 1 || State.Mode == 2 || subcode == 0x33) //Get Data
|
||||||
|
{
|
||||||
|
unsigned char glbl = 0x00;
|
||||||
|
unsigned char p1_1 = 0x00;
|
||||||
|
unsigned char p1_2 = 0x00;
|
||||||
|
unsigned char p2_1 = 0x00;
|
||||||
|
unsigned char p2_2 = 0x00;
|
||||||
|
static unsigned char LastKey[256];
|
||||||
|
static unsigned short coin1 = 0x0000;
|
||||||
|
static unsigned short coin2 = 0x0000;
|
||||||
|
unsigned char Key[256];
|
||||||
|
GetKeyboardState(Key);
|
||||||
|
|
||||||
|
if (keycode&NAOMI_SERVICE_KEY_1) //Service ?
|
||||||
|
glbl |= 0x80;
|
||||||
|
if (keycode&NAOMI_TEST_KEY_1) //Test
|
||||||
|
p1_1 |= 0x40;
|
||||||
|
if (keycode&NAOMI_START_KEY) //start ?
|
||||||
|
p1_1 |= 0x80;
|
||||||
|
if (keycode&NAOMI_UP_KEY) //up
|
||||||
|
p1_1 |= 0x20;
|
||||||
|
if (keycode&NAOMI_DOWN_KEY) //down
|
||||||
|
p1_1 |= 0x10;
|
||||||
|
if (keycode&NAOMI_LEFT_KEY) //left
|
||||||
|
p1_1 |= 0x08;
|
||||||
|
if (keycode&NAOMI_RIGHT_KEY) //right
|
||||||
|
p1_1 |= 0x04;
|
||||||
|
if (keycode&NAOMI_BTN0_KEY) //btn1
|
||||||
|
p1_1 |= 0x02;
|
||||||
|
if (keycode&NAOMI_BTN1_KEY) //btn2
|
||||||
|
p1_1 |= 0x01;
|
||||||
|
if (keycode&NAOMI_BTN2_KEY) //btn3
|
||||||
|
p1_2 |= 0x80;
|
||||||
|
if (keycode&NAOMI_BTN3_KEY) //btn4
|
||||||
|
p1_2 |= 0x40;
|
||||||
|
if (keycode&NAOMI_BTN4_KEY) //btn5
|
||||||
|
p1_2 |= 0x20;
|
||||||
|
if (keycode&NAOMI_BTN5_KEY) //btn6
|
||||||
|
p1_2 |= 0x10;
|
||||||
|
|
||||||
|
if (keycode2&NAOMI_TEST_KEY_1) //Test
|
||||||
|
p2_1 |= 0x40;
|
||||||
|
if (keycode2&NAOMI_START_KEY) //start ?
|
||||||
|
p2_1 |= 0x80;
|
||||||
|
if (keycode2&NAOMI_UP_KEY) //up
|
||||||
|
p2_1 |= 0x20;
|
||||||
|
if (keycode2&NAOMI_DOWN_KEY) //down
|
||||||
|
p2_1 |= 0x10;
|
||||||
|
if (keycode2&NAOMI_LEFT_KEY) //left
|
||||||
|
p2_1 |= 0x08;
|
||||||
|
if (keycode2&NAOMI_RIGHT_KEY) //right
|
||||||
|
p2_1 |= 0x04;
|
||||||
|
if (keycode2&NAOMI_BTN0_KEY) //btn1
|
||||||
|
p2_1 |= 0x02;
|
||||||
|
if (keycode2&NAOMI_BTN1_KEY) //btn2
|
||||||
|
p2_1 |= 0x01;
|
||||||
|
if (keycode2&NAOMI_BTN2_KEY) //btn3
|
||||||
|
p2_2 |= 0x80;
|
||||||
|
if (keycode2&NAOMI_BTN3_KEY) //btn4
|
||||||
|
p2_2 |= 0x40;
|
||||||
|
if (keycode2&NAOMI_BTN4_KEY) //btn5
|
||||||
|
p2_2 |= 0x20;
|
||||||
|
if (keycode2&NAOMI_BTN5_KEY) //btn6
|
||||||
|
p2_2 |= 0x10;
|
||||||
|
|
||||||
|
static bool old_coin = false;
|
||||||
|
static bool old_coin2 = false;
|
||||||
|
|
||||||
|
if ((old_coin == false) && (keycode&NAOMI_COIN_KEY))
|
||||||
|
coin1++;
|
||||||
|
old_coin = (keycode&NAOMI_COIN_KEY) ? true : false;
|
||||||
|
|
||||||
|
if ((old_coin2 == false) && (keycode2&NAOMI_COIN_KEY))
|
||||||
|
coin2++;
|
||||||
|
old_coin2 = (keycode2&NAOMI_COIN_KEY) ? true : false;
|
||||||
|
|
||||||
|
buffer_out_b[0x11 + 0] = 0x00;
|
||||||
|
buffer_out_b[0x11 + 1] = 0x8E; //Valid data check
|
||||||
|
buffer_out_b[0x11 + 2] = 0x01;
|
||||||
|
buffer_out_b[0x11 + 3] = 0x00;
|
||||||
|
buffer_out_b[0x11 + 4] = 0xFF;
|
||||||
|
buffer_out_b[0x11 + 5] = 0xE0;
|
||||||
|
buffer_out_b[0x11 + 8] = 0x01;
|
||||||
|
|
||||||
|
//memset(OutData+8+0x11,0x00,0x100);
|
||||||
|
|
||||||
|
buffer_out_b[8 + 0x12 + 0] = 1;
|
||||||
|
buffer_out_b[8 + 0x12 + 1] = glbl;
|
||||||
|
buffer_out_b[8 + 0x12 + 2] = p1_1;
|
||||||
|
buffer_out_b[8 + 0x12 + 3] = p1_2;
|
||||||
|
buffer_out_b[8 + 0x12 + 4] = p2_1;
|
||||||
|
buffer_out_b[8 + 0x12 + 5] = p2_2;
|
||||||
|
buffer_out_b[8 + 0x12 + 6] = 1;
|
||||||
|
buffer_out_b[8 + 0x12 + 7] = coin1 >> 8;
|
||||||
|
buffer_out_b[8 + 0x12 + 8] = coin1 & 0xff;
|
||||||
|
buffer_out_b[8 + 0x12 + 9] = coin2 >> 8;
|
||||||
|
buffer_out_b[8 + 0x12 + 10] = coin2 & 0xff;
|
||||||
|
buffer_out_b[8 + 0x12 + 11] = 1;
|
||||||
|
buffer_out_b[8 + 0x12 + 12] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 13] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 14] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 15] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 16] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 17] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 18] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 19] = 0x00;
|
||||||
|
buffer_out_b[8 + 0x12 + 20] = 0x00;
|
||||||
|
|
||||||
|
memcpy(LastKey, Key, sizeof(Key));
|
||||||
|
|
||||||
|
if (State.Mode == 1)
|
||||||
|
{
|
||||||
|
buffer_out_b[0x11 + 0x7] = 19;
|
||||||
|
buffer_out_b[0x11 + 0x4] = 19 + 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer_out_b[0x11 + 0x7] = 17;
|
||||||
|
buffer_out_b[0x11 + 0x4] = 17 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//OutLen=8+0x11+16;
|
||||||
|
buffer_out_len = 8 + 0x12 + 22;
|
||||||
|
}
|
||||||
|
/*ID.Keys=0xFFFFFFFF;
|
||||||
|
if(GetKeyState(VK_F1)&0x8000) //Service
|
||||||
|
ID.Keys&=~(1<<0x1b);
|
||||||
|
if(GetKeyState(VK_F2)&0x8000) //Test
|
||||||
|
ID.Keys&=~(1<<0x1a);
|
||||||
|
memcpy(OutData,&ID,sizeof(ID));
|
||||||
|
OutData[0x12]=0x8E;
|
||||||
|
OutLen=sizeof(ID);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
case 0x17: //Select Subdevice
|
||||||
|
{
|
||||||
|
State.Mode = 0;
|
||||||
|
State.Cmd = buffer_in_b[8];
|
||||||
|
State.Node = buffer_in_b[9];
|
||||||
|
buffer_out_len = 0;
|
||||||
|
}
|
||||||
|
return (7);
|
||||||
|
|
||||||
|
case 0x27: //Transfer request
|
||||||
|
{
|
||||||
|
State.Mode = 1;
|
||||||
|
State.Cmd = buffer_in_b[8];
|
||||||
|
State.Node = buffer_in_b[9];
|
||||||
|
buffer_out_len = 0;
|
||||||
|
}
|
||||||
|
return (7);
|
||||||
|
case 0x21: //Transfer request with repeat
|
||||||
|
{
|
||||||
|
State.Mode = 2;
|
||||||
|
State.Cmd = buffer_in_b[8];
|
||||||
|
State.Node = buffer_in_b[9];
|
||||||
|
buffer_out_len = 0;
|
||||||
|
}
|
||||||
|
return (7);
|
||||||
|
|
||||||
|
case 0x0B: //EEPROM write
|
||||||
|
{
|
||||||
|
int address = buffer_in_b[1];
|
||||||
|
int size = buffer_in_b[2];
|
||||||
|
//printf("EEprom write %08X %08X\n",address,size);
|
||||||
|
//printState(Command,buffer_in,buffer_in_len);
|
||||||
|
memcpy(EEPROM + address, buffer_in_b + 4, size);
|
||||||
|
|
||||||
|
#ifdef SAVE_EPPROM
|
||||||
|
wchar eeprom_file[512];
|
||||||
|
host.ConfigLoadStr(L"emu", L"gamefile", eeprom_file, L"");
|
||||||
|
wcscat(eeprom_file, L".eeprom");
|
||||||
|
FILE* f = _wfopen(eeprom_file, L"wb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
fwrite(EEPROM, 1, 0x80, f);
|
||||||
|
fclose(f);
|
||||||
|
wprintf(L"SAVED EEPROM to %s\n", eeprom_file);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return (7);
|
||||||
|
case 0x3: //EEPROM read
|
||||||
|
{
|
||||||
|
#ifdef SAVE_EPPROM
|
||||||
|
if (!EEPROM_loaded)
|
||||||
|
{
|
||||||
|
EEPROM_loaded = true;
|
||||||
|
wchar eeprom_file[512];
|
||||||
|
host.ConfigLoadStr(L"emu", L"gamefile", eeprom_file, L"");
|
||||||
|
wcscat(eeprom_file, L".eeprom");
|
||||||
|
FILE* f = _wfopen(eeprom_file, L"rb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
fread(EEPROM, 1, 0x80, f);
|
||||||
|
fclose(f);
|
||||||
|
wprintf(L"LOADED EEPROM from %s\n", eeprom_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//printf("EEprom READ ?\n");
|
||||||
|
int address = buffer_in_b[1];
|
||||||
|
//printState(Command,buffer_in,buffer_in_len);
|
||||||
|
memcpy(buffer_out, EEPROM + address, 0x80);
|
||||||
|
buffer_out_len = 0x80;
|
||||||
|
}
|
||||||
|
return 8;
|
||||||
|
//IF I return all FF, then board runs in low res
|
||||||
|
case 0x31:
|
||||||
|
{
|
||||||
|
buffer_out[0] = 0xffffffff;
|
||||||
|
buffer_out[1] = 0xffffffff;
|
||||||
|
}
|
||||||
|
return (8);
|
||||||
|
|
||||||
|
//case 0x3:
|
||||||
|
// break;
|
||||||
|
|
||||||
|
//case 0x1:
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
printf("Unknown 0x86 : SubCommand 0x%X - State: Cmd 0x%X Mode : 0x%X Node : 0x%X\n", subcode, State.Cmd, State.Mode, State.Node);
|
||||||
|
printState(cmd, buffer_in, buffer_in_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 8;//MAPLE_RESPONSE_DATATRF
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x82:
|
||||||
|
{
|
||||||
|
const char *ID = "315-6149 COPYRIGHT SEGA E\x83\x00\x20\x05NTERPRISES CO,LTD. ";
|
||||||
|
memset(buffer_out_b, 0x20, 256);
|
||||||
|
memcpy(buffer_out_b, ID, 0x38 - 4);
|
||||||
|
buffer_out_len = 256;
|
||||||
|
return (0x83);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 9:
|
||||||
|
return maple_sega_controller::dma(cmd);
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown MAPLE Frame\n");
|
||||||
|
//printState(Command, buffer_in, buffer_in_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return MDRE_UnknownFunction;
|
||||||
|
}
|
||||||
|
};
|
||||||
maple_device* maple_Create(MapleDeviceType type)
|
maple_device* maple_Create(MapleDeviceType type)
|
||||||
{
|
{
|
||||||
maple_device* rv=0;
|
maple_device* rv=0;
|
||||||
|
@ -854,14 +1287,19 @@ maple_device* maple_Create(MapleDeviceType type)
|
||||||
case MDT_SegaController:
|
case MDT_SegaController:
|
||||||
rv=new maple_sega_controller();
|
rv=new maple_sega_controller();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MDT_Microphone:
|
case MDT_Microphone:
|
||||||
rv=new maple_microphone();
|
rv=new maple_microphone();
|
||||||
break;
|
break;
|
||||||
#ifdef HAS_VMU
|
|
||||||
case MDT_SegaVMU:
|
case MDT_SegaVMU:
|
||||||
rv = new maple_sega_vmu();
|
rv = new maple_sega_vmu();
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
case MDT_NaomiJamma:
|
||||||
|
rv = new maple_naomi_jamma();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -7,6 +7,8 @@ enum MapleDeviceType
|
||||||
MDT_SegaVMU,
|
MDT_SegaVMU,
|
||||||
MDT_Microphone,
|
MDT_Microphone,
|
||||||
|
|
||||||
|
MDT_NaomiJamma,
|
||||||
|
|
||||||
MDT_Count
|
MDT_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,995 @@
|
||||||
|
/*
|
||||||
|
This file is a mix of my code, Zezu's, and duno wtf-else (most likely ElSemi's ?)
|
||||||
|
*/
|
||||||
|
#include "types.h"
|
||||||
|
#include "cfg/cfg.h"
|
||||||
|
#include "hw/holly/sb.h"
|
||||||
|
#include "hw/sh4/sh4_mem.h"
|
||||||
|
#include "hw/holly/holly_intc.h"
|
||||||
|
#include "naomi.h"
|
||||||
|
#include "naomi_regs.h"
|
||||||
|
|
||||||
|
u32 naomi_updates;
|
||||||
|
//For file memory mapping :p
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
//#define NAOMI_COMM
|
||||||
|
|
||||||
|
u8* RomPtr;
|
||||||
|
HANDLE* RomCacheMap;
|
||||||
|
u32 RomCacheMapCount;
|
||||||
|
|
||||||
|
u32 RomPioOffset=0;
|
||||||
|
|
||||||
|
DWORD DmaOffset;
|
||||||
|
DWORD DmaCount;
|
||||||
|
|
||||||
|
DWORD BoardID=0x980055AA;
|
||||||
|
DWORD GSerialBuffer=0,BSerialBuffer=0;
|
||||||
|
int GBufPos=0,BBufPos=0;
|
||||||
|
int GState=0,BState=0;
|
||||||
|
int GOldClk=0,BOldClk=0;
|
||||||
|
int BControl=0,BCmd=0,BLastCmd=0;
|
||||||
|
int GControl=0,GCmd=0,GLastCmd=0;
|
||||||
|
int SerStep=0,SerStep2=0;
|
||||||
|
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
u32 CommOffset;
|
||||||
|
u32* CommSharedMem;
|
||||||
|
HANDLE CommMapFile=INVALID_HANDLE_VALUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
El numero de serie solo puede contener:
|
||||||
|
0-9 (0x30-0x39)
|
||||||
|
A-H (0x41-0x48)
|
||||||
|
J-N (0x4A-0x4E)
|
||||||
|
P-Z (0x50-0x5A)
|
||||||
|
*/
|
||||||
|
static unsigned char BSerial[]="\xB7"/*CRC1*/"\x19"/*CRC2*/"0123234437897584372973927387463782196719782697849162342198671923649";
|
||||||
|
static unsigned char GSerial[]="\xB7"/*CRC1*/"\x19"/*CRC2*/"0123234437897584372973927387463782196719782697849162342198671923649";
|
||||||
|
|
||||||
|
unsigned int ShiftCRC(unsigned int CRC,unsigned int rounds)
|
||||||
|
{
|
||||||
|
const unsigned int Magic=0x10210000;
|
||||||
|
unsigned int i;
|
||||||
|
for(i=0;i<rounds;++i)
|
||||||
|
{
|
||||||
|
if(CRC&0x80000000)
|
||||||
|
CRC=(CRC<<1)+Magic;
|
||||||
|
else
|
||||||
|
CRC=(CRC<<1);
|
||||||
|
}
|
||||||
|
return CRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short CRCSerial(unsigned char *Serial,unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int CRC=0xDEBDEB00;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i=0;i<len;++i)
|
||||||
|
{
|
||||||
|
unsigned char c=Serial[i];
|
||||||
|
//CRC&=0xFFFFFF00;
|
||||||
|
CRC|=c;
|
||||||
|
CRC=ShiftCRC(CRC,8);
|
||||||
|
}
|
||||||
|
CRC=ShiftCRC(CRC,8);
|
||||||
|
return (u16)(CRC>>16);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NaomiInit()
|
||||||
|
{
|
||||||
|
//RomOffset=0;
|
||||||
|
DmaCount=0xffff;
|
||||||
|
DmaOffset=0;
|
||||||
|
|
||||||
|
WORD CRC;
|
||||||
|
CRC=CRCSerial(BSerial+2,0x2E);
|
||||||
|
BSerial[0]=(u8)(CRC>>8);
|
||||||
|
BSerial[1]=(u8)(CRC);
|
||||||
|
|
||||||
|
CRC=CRCSerial(GSerial+2,0x2E);
|
||||||
|
GSerial[0]=(u8)(CRC>>8);
|
||||||
|
GSerial[1]=(u8)(CRC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void NaomiBoardIDWrite(const u16 Data)
|
||||||
|
{
|
||||||
|
int Dat=Data&8;
|
||||||
|
int Clk=Data&4;
|
||||||
|
int Rst=Data&0x20;
|
||||||
|
int Sta=Data&0x10;
|
||||||
|
|
||||||
|
|
||||||
|
if(Rst)
|
||||||
|
{
|
||||||
|
BState=0;
|
||||||
|
BBufPos=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(Clk!=BOldClk && !Clk) //Falling Edge clock
|
||||||
|
{
|
||||||
|
//State change
|
||||||
|
if(BState==0 && Sta)
|
||||||
|
BState=1;
|
||||||
|
if(BState==1 && !Sta)
|
||||||
|
BState=2;
|
||||||
|
|
||||||
|
if((BControl&0xfff)==0xFF0) //Command mode
|
||||||
|
{
|
||||||
|
BCmd<<=1;
|
||||||
|
if(Dat)
|
||||||
|
BCmd|=1;
|
||||||
|
else
|
||||||
|
BCmd&=0xfffffffe;
|
||||||
|
}
|
||||||
|
|
||||||
|
//State processing
|
||||||
|
if(BState==1) //LoadBoardID
|
||||||
|
{
|
||||||
|
BSerialBuffer=BoardID;
|
||||||
|
BBufPos=0; //??
|
||||||
|
}
|
||||||
|
if(BState==2) //ShiftBoardID
|
||||||
|
{
|
||||||
|
BBufPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOldClk=Clk;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 NaomiBoardIDRead()
|
||||||
|
{
|
||||||
|
if((BControl&0xff)==0xFE)
|
||||||
|
return 0xffff;
|
||||||
|
return (BSerialBuffer&(1<<(31-BBufPos)))?8:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD AdaptByte(BYTE val)
|
||||||
|
{
|
||||||
|
return val<<24;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NaomiBoardIDWriteControl(const u16 Data)
|
||||||
|
{
|
||||||
|
if((Data&0xfff)==0xF30 && BCmd!=BLastCmd)
|
||||||
|
{
|
||||||
|
if((BCmd&0x81)==0x81)
|
||||||
|
{
|
||||||
|
SerStep2=(BCmd>>1)&0x3f;
|
||||||
|
|
||||||
|
BSerialBuffer=0x00000000; //First block contains CRC
|
||||||
|
BBufPos=0;
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0x55) //Load Offset 0
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2])>>1;
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0xAA) //Load Offset 1
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+1]);
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0x54)
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+2]);
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0xA8)
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+3]);
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0x50)
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+4]);
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0xA0)
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+5]);
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0x40)
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+6]);
|
||||||
|
}
|
||||||
|
if((BCmd&0xff)==0x80)
|
||||||
|
{
|
||||||
|
BState=2;
|
||||||
|
BBufPos=0;
|
||||||
|
BSerialBuffer=AdaptByte(BSerial[8*SerStep2+7]);
|
||||||
|
}
|
||||||
|
BLastCmd=BCmd;
|
||||||
|
}
|
||||||
|
BControl=Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NaomiGameIDProcessCmd()
|
||||||
|
{
|
||||||
|
if(GCmd!=GLastCmd)
|
||||||
|
{
|
||||||
|
if((GCmd&0x81)==0x81)
|
||||||
|
{
|
||||||
|
SerStep=(GCmd>>1)&0x3f;
|
||||||
|
|
||||||
|
GSerialBuffer=0x00000000; //First block contains CRC
|
||||||
|
GBufPos=0;
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0x55) //Load Offset 0
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep])>>0;
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0xAA) //Load Offset 1
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+1]);
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0x54)
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+2]);
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0xA8)
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+3]);
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0x50)
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+4]);
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0xA0)
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+5]);
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0x40)
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+6]);
|
||||||
|
}
|
||||||
|
if((GCmd&0xff)==0x80)
|
||||||
|
{
|
||||||
|
GState=2;
|
||||||
|
GBufPos=0;
|
||||||
|
GSerialBuffer=AdaptByte(GSerial[8*SerStep+7]);
|
||||||
|
}
|
||||||
|
GLastCmd=GCmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NaomiGameIDWrite(const WORD Data)
|
||||||
|
{
|
||||||
|
int Dat=Data&0x01;
|
||||||
|
int Clk=Data&0x02;
|
||||||
|
int Rst=Data&0x04;
|
||||||
|
int Sta=Data&0x08;
|
||||||
|
int Cmd=Data&0x10;
|
||||||
|
|
||||||
|
|
||||||
|
if(Rst)
|
||||||
|
{
|
||||||
|
GState=0;
|
||||||
|
GBufPos=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(Clk!=GOldClk && !Clk) //Falling Edge clock
|
||||||
|
{
|
||||||
|
//State change
|
||||||
|
if(GState==0 && Sta)
|
||||||
|
GState=1;
|
||||||
|
if(GState==1 && !Sta)
|
||||||
|
GState=2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//State processing
|
||||||
|
if(GState==1) //LoadBoardID
|
||||||
|
{
|
||||||
|
GSerialBuffer=BoardID;
|
||||||
|
GBufPos=0; //??
|
||||||
|
}
|
||||||
|
if(GState==2) //ShiftBoardID
|
||||||
|
GBufPos++;
|
||||||
|
|
||||||
|
if(GControl!=Cmd && !Cmd)
|
||||||
|
{
|
||||||
|
NaomiGameIDProcessCmd();
|
||||||
|
}
|
||||||
|
GControl=Cmd;
|
||||||
|
}
|
||||||
|
if(Clk!=GOldClk && Clk) //Rising Edge clock
|
||||||
|
{
|
||||||
|
if(Cmd) //Command mode
|
||||||
|
{
|
||||||
|
GCmd<<=1;
|
||||||
|
if(Dat)
|
||||||
|
GCmd|=1;
|
||||||
|
else
|
||||||
|
GCmd&=0xfffffffe;
|
||||||
|
GControl=Cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GOldClk=Clk;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WORD NaomiGameIDRead()
|
||||||
|
{
|
||||||
|
return (GSerialBuffer&(1<<(31-GBufPos)))?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
u32 _ReadMem_naomi(u32 Addr, u32 sz)
|
||||||
|
{
|
||||||
|
verify(sz!=1);
|
||||||
|
|
||||||
|
printf("naomi?WTF? ReadMem: %X, %d\n", Addr, sz);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
void _WriteMem_naomi(u32 Addr, u32 data, u32 sz)
|
||||||
|
{
|
||||||
|
printf("naomi?WTF? WriteMem: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//DIMM board
|
||||||
|
//Uses interrupt ext#3 (holly_EXT_PCI)
|
||||||
|
|
||||||
|
//status/flags ? 0x1 is some completion/init flag(?), 0x100 is the interrupt disable flag (?)
|
||||||
|
//n1 bios rev g (n2/epr-23605b has similar behavior of not same):
|
||||||
|
//3c=0x1E03
|
||||||
|
//40=0
|
||||||
|
//44=0
|
||||||
|
//48=0
|
||||||
|
//read 4c
|
||||||
|
//wait for 4c not 0
|
||||||
|
//4c=[4c]-1
|
||||||
|
|
||||||
|
//Naomi 2 bios epr-23609
|
||||||
|
//read 3c
|
||||||
|
//wait 4c to be non 0
|
||||||
|
//
|
||||||
|
|
||||||
|
//SO the writes to 3c/stuff are not relaced with 4c '1'
|
||||||
|
//If the dimm board has some internal cpu/pic logic
|
||||||
|
//4c '1' seems to be the init done bit (?)
|
||||||
|
//n1/n2 clears it after getting a non 0 value
|
||||||
|
//n1 bios writes the value -1, meaning it expects the bit 0 to be set
|
||||||
|
//.//
|
||||||
|
|
||||||
|
u32 reg_dimm_3c; //IO window ! writen, 0x1E03 some flag ?
|
||||||
|
u32 reg_dimm_40; //parameters
|
||||||
|
u32 reg_dimm_44; //parameters
|
||||||
|
u32 reg_dimm_48; //parameters
|
||||||
|
|
||||||
|
u32 reg_dimm_4c=0x11; //status/control reg ?
|
||||||
|
|
||||||
|
bool NaomiDataRead = false;
|
||||||
|
|
||||||
|
void naomi_process(u32 r3c,u32 r40,u32 r44, u32 r48)
|
||||||
|
{
|
||||||
|
printf("Naomi process 0x%04X 0x%04X 0x%04X 0x%04X\n",r3c,r40,r44,r48);
|
||||||
|
printf("Possible format 0 %d 0x%02X 0x%04X\n",r3c>>15,(r3c&0x7e00)>>9,r3c&0x1FF);
|
||||||
|
printf("Possible format 1 0x%02X 0x%02X\n",(r3c&0xFF00)>>8,r3c&0xFF);
|
||||||
|
|
||||||
|
u32 param=(r3c&0xFF);
|
||||||
|
if (param==0xFF)
|
||||||
|
{
|
||||||
|
printf("invalid opcode or smth ?");
|
||||||
|
}
|
||||||
|
static int opcd=0;
|
||||||
|
//else if (param!=3)
|
||||||
|
if (opcd<255)
|
||||||
|
{
|
||||||
|
reg_dimm_3c=0x8000 | (opcd%12<<9) | (0x0);
|
||||||
|
printf("new reg is 0x%X\n",reg_dimm_3c);
|
||||||
|
asic_RaiseInterrupt(holly_EXP_PCI);
|
||||||
|
printf("Interrupt raised\n");
|
||||||
|
opcd++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u32 ReadMem_naomi(u32 Addr, u32 sz)
|
||||||
|
{
|
||||||
|
verify(sz!=1);
|
||||||
|
// printf("+naomi?WTF? ReadMem: %X, %d\n", Addr, sz);
|
||||||
|
switch(Addr&255)
|
||||||
|
{
|
||||||
|
case 0x3c:
|
||||||
|
printf("naomi GD? READ: %X, %d\n", Addr, sz);
|
||||||
|
return reg_dimm_3c | (NaomiDataRead ? 0 : -1); //pretend the board isn't there for the bios
|
||||||
|
case 0x40:
|
||||||
|
printf("naomi GD? READ: %X, %d\n", Addr, sz);
|
||||||
|
return reg_dimm_40;
|
||||||
|
case 0x44:
|
||||||
|
printf("naomi GD? READ: %X, %d\n", Addr, sz);
|
||||||
|
return reg_dimm_44;
|
||||||
|
case 0x48:
|
||||||
|
printf("naomi GD? READ: %X, %d\n", Addr, sz);
|
||||||
|
return reg_dimm_48;
|
||||||
|
|
||||||
|
//These are known to be valid on normal ROMs and DIMM board
|
||||||
|
case NAOMI_ROM_OFFSETH_addr&255:
|
||||||
|
return RomPioOffset>>16;
|
||||||
|
|
||||||
|
case NAOMI_ROM_OFFSETL_addr&255:
|
||||||
|
return RomPioOffset&0xFFFF;
|
||||||
|
|
||||||
|
case NAOMI_ROM_DATA_addr&255:
|
||||||
|
u32 rv;
|
||||||
|
if (RomPtr)
|
||||||
|
rv=*(u16*)&RomPtr[RomPioOffset&0x0FFFffff];
|
||||||
|
else
|
||||||
|
rv=0;
|
||||||
|
RomPioOffset+=2;
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
case NAOMI_DMA_COUNT_addr&255:
|
||||||
|
return (WORD) DmaCount;
|
||||||
|
|
||||||
|
case NAOMI_BOARDID_READ_addr&255:
|
||||||
|
return NaomiGameIDRead()?0x8000:0x0000;
|
||||||
|
|
||||||
|
//What should i do to emulate 'nothing' ?
|
||||||
|
case NAOMI_COMM_OFFSET_addr&255:
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
printf("naomi COMM offs READ: %X, %d\n", Addr, sz);
|
||||||
|
return CommOffset;
|
||||||
|
#endif
|
||||||
|
case NAOMI_COMM_DATA_addr&255:
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
printf("naomi COMM data read: %X, %d\n", CommOffset, sz);
|
||||||
|
if (CommSharedMem)
|
||||||
|
{
|
||||||
|
return CommSharedMem[CommOffset&0xF];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
|
//This should be valid
|
||||||
|
case NAOMI_DMA_OFFSETH_addr&255:
|
||||||
|
return DmaOffset>>16;
|
||||||
|
case NAOMI_DMA_OFFSETL_addr&255:
|
||||||
|
return DmaOffset&0xFFFF;
|
||||||
|
|
||||||
|
case NAOMI_BOARDID_WRITE_addr&255:
|
||||||
|
printf("naomi ReadMem: %X, %d\n", Addr, sz);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case 0x04C:
|
||||||
|
printf("naomi GD? READ: %X, %d\n", Addr, sz);
|
||||||
|
return reg_dimm_4c;
|
||||||
|
|
||||||
|
case 0x18:
|
||||||
|
printf("naomi reg 0x18 : returning random data\n");
|
||||||
|
return 0x4000^rand();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
printf("naomi?WTF? ReadMem: %X, %d\n", Addr, sz);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
void WriteMem_naomi(u32 Addr, u32 data, u32 sz)
|
||||||
|
{
|
||||||
|
// printf("+naomi WriteMem: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
switch(Addr&255)
|
||||||
|
{
|
||||||
|
case 0x3c:
|
||||||
|
if (0x1E03==data)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (!(reg_dimm_4c&0x100))
|
||||||
|
asic_RaiseInterrupt(holly_EXP_PCI);
|
||||||
|
reg_dimm_4c|=1;*/
|
||||||
|
}
|
||||||
|
reg_dimm_3c=data;
|
||||||
|
printf("naomi GD? Write: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x40:
|
||||||
|
reg_dimm_40=data;
|
||||||
|
printf("naomi GD? Write: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
case 0x44:
|
||||||
|
reg_dimm_44=data;
|
||||||
|
printf("naomi GD? Write: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
case 0x48:
|
||||||
|
reg_dimm_48=data;
|
||||||
|
printf("naomi GD? Write: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x4C:
|
||||||
|
if (data&0x100)
|
||||||
|
{
|
||||||
|
asic_CancelInterrupt(holly_EXP_PCI);
|
||||||
|
naomi_updates=100;
|
||||||
|
}
|
||||||
|
else if ((data&1)==0)
|
||||||
|
{
|
||||||
|
/*FILE* ramd=fopen("c:\\ndc.ram.bin","wb");
|
||||||
|
fwrite(mem_b.data,1,RAM_SIZE,ramd);
|
||||||
|
fclose(ramd);*/
|
||||||
|
naomi_process(reg_dimm_3c,reg_dimm_40,reg_dimm_44,reg_dimm_48);
|
||||||
|
}
|
||||||
|
reg_dimm_4c=data&~0x100;
|
||||||
|
printf("naomi GD? Write: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
|
||||||
|
//These are known to be valid on normal ROMs and DIMM board
|
||||||
|
case NAOMI_ROM_OFFSETH_addr&255:
|
||||||
|
RomPioOffset&=0x0000ffff;
|
||||||
|
RomPioOffset|=(data<<16)&0x7fff0000;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NAOMI_ROM_OFFSETL_addr&255:
|
||||||
|
RomPioOffset&=0xffff0000;
|
||||||
|
RomPioOffset|=data;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NAOMI_ROM_DATA_addr&255:
|
||||||
|
printf("naomi WriteMem:Write to rom ? sure ? no , i dont think so %%) %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NAOMI_DMA_OFFSETH_addr&255:
|
||||||
|
DmaOffset&=0x0000ffff;
|
||||||
|
DmaOffset|=(data&0x7fff)<<16;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NAOMI_DMA_OFFSETL_addr&255:
|
||||||
|
DmaOffset&=0xffff0000;
|
||||||
|
DmaOffset|=data;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NAOMI_DMA_COUNT_addr&255:
|
||||||
|
{
|
||||||
|
DmaCount=data;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case NAOMI_BOARDID_WRITE_addr&255:
|
||||||
|
NaomiGameIDWrite((u16)data);
|
||||||
|
return;
|
||||||
|
|
||||||
|
//What should i do to emulate 'nothing' ?
|
||||||
|
case NAOMI_COMM_OFFSET_addr&255:
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
printf("naomi COMM ofset Write: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
CommOffset=data&0xFFFF;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
|
case NAOMI_COMM_DATA_addr&255:
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
printf("naomi COMM data Write: %X <= %X, %d\n", CommOffset, data, sz);
|
||||||
|
if (CommSharedMem)
|
||||||
|
{
|
||||||
|
CommSharedMem[CommOffset&0xF]=data;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
|
//This should be valid
|
||||||
|
case NAOMI_BOARDID_READ_addr&255:
|
||||||
|
printf("naomi WriteMem: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
printf("naomi?WTF? WriteMem: %X <= %X, %d\n", Addr, data, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
u32 NAOMI_ROM_OFFSETH;
|
||||||
|
u32 NAOMI_ROM_OFFSETL;
|
||||||
|
u32 NAOMI_ROM_DATA;
|
||||||
|
u32 NAOMI_DMA_OFFSETH;
|
||||||
|
u32 NAOMI_DMA_OFFSETL;
|
||||||
|
u32 NAOMI_DMA_COUNT;
|
||||||
|
u32 NAOMI_BOARDID_WRITE;
|
||||||
|
u32 NAOMI_BOARDID_READ;
|
||||||
|
u32 NAOMI_COMM_OFFSET;
|
||||||
|
u32 NAOMI_COMM_DATA;
|
||||||
|
|
||||||
|
char SelectedFile[512];
|
||||||
|
|
||||||
|
OPENFILENAME ofn;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool naomi_LoadRom(char* file)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("\nnullDC-Naomi rom loader v1.2\n");
|
||||||
|
|
||||||
|
size_t folder_pos=strlen(file)-1;
|
||||||
|
while(folder_pos>1 && file[folder_pos]!='\\')
|
||||||
|
folder_pos--;
|
||||||
|
|
||||||
|
folder_pos++;
|
||||||
|
|
||||||
|
char t[512];
|
||||||
|
strcpy(t,file);
|
||||||
|
FILE* fl=fopen(t,"r");
|
||||||
|
if (!fl)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char* line=fgets(t,512,fl);
|
||||||
|
if (!line)
|
||||||
|
{
|
||||||
|
fclose(fl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* eon=strstr(line,"\n");
|
||||||
|
if (!eon)
|
||||||
|
printf("+Loading naomi rom that has no name\n",line);
|
||||||
|
else
|
||||||
|
*eon=0;
|
||||||
|
|
||||||
|
printf("+Loading naomi rom : %s\n",line);
|
||||||
|
|
||||||
|
line=fgets(t,512,fl);
|
||||||
|
if (!line)
|
||||||
|
{
|
||||||
|
fclose(fl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> files;
|
||||||
|
vector<u32> fstart;
|
||||||
|
vector<u32> fsize;
|
||||||
|
|
||||||
|
u32 setsize=0;
|
||||||
|
u32 max_load_addr=0;
|
||||||
|
|
||||||
|
while(line)
|
||||||
|
{
|
||||||
|
char filename[512];
|
||||||
|
u32 addr,sz;
|
||||||
|
sscanf(line,"\"%[^\"]\",%x,%x",filename,&addr,&sz);
|
||||||
|
files.push_back(filename);
|
||||||
|
fstart.push_back(addr);
|
||||||
|
fsize.push_back(sz);
|
||||||
|
setsize+=sz;
|
||||||
|
max_load_addr=max(max_load_addr,(addr+sz));
|
||||||
|
line=fgets(t,512,fl);
|
||||||
|
}
|
||||||
|
fclose(fl);
|
||||||
|
|
||||||
|
printf("+%d romfiles, %.2f MB set size, %.2f MB set address space\n",files.size(),setsize/1024.f/1024.f,max_load_addr/1024.f/1024.f);
|
||||||
|
|
||||||
|
if (RomCacheMap)
|
||||||
|
{
|
||||||
|
RomCacheMapCount=0;
|
||||||
|
delete RomCacheMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
RomCacheMapCount = (u32)files.size();
|
||||||
|
RomCacheMap = new HANDLE[files.size()];
|
||||||
|
|
||||||
|
strcpy(t, file);
|
||||||
|
t[folder_pos]=0;
|
||||||
|
strcat(t,"ndcn-composed.cache");
|
||||||
|
|
||||||
|
//Allocate space for the ram, so we are sure we have a segment of continius ram
|
||||||
|
RomPtr=(u8*)VirtualAlloc(0,max_load_addr,MEM_RESERVE,PAGE_NOACCESS);
|
||||||
|
verify(RomPtr!=0);
|
||||||
|
|
||||||
|
strcpy(t,file);
|
||||||
|
|
||||||
|
//Create File Mapping Objects
|
||||||
|
for (size_t i=0;i<files.size();i++)
|
||||||
|
{
|
||||||
|
t[folder_pos]=0;
|
||||||
|
strcat(t,files[i].c_str());
|
||||||
|
HANDLE RomCache;
|
||||||
|
|
||||||
|
if (strcmp(files[i].c_str(),"null")==0)
|
||||||
|
{
|
||||||
|
RomCacheMap[i]=INVALID_HANDLE_VALUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RomCache=CreateFile(t,FILE_READ_ACCESS,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
|
||||||
|
|
||||||
|
if (RomCache==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
wprintf(L"-Unable to read file %s\n",files[i].c_str());
|
||||||
|
RomCacheMap[i]=INVALID_HANDLE_VALUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RomCacheMap[i]=CreateFileMapping(RomCache,0,PAGE_READONLY,0,fsize[i],0);
|
||||||
|
verify(RomCacheMap[i]!=INVALID_HANDLE_VALUE);
|
||||||
|
wprintf(L"-Preparing \"%s\" at 0x%08X, size 0x%08X\n",files[i].c_str(),fstart[i],fsize[i]);
|
||||||
|
|
||||||
|
verify(CloseHandle(RomCache));
|
||||||
|
}
|
||||||
|
|
||||||
|
//We have all file mapping objects, we start to map the ram
|
||||||
|
printf("+Mapping ROM\n");
|
||||||
|
//Release the segment we reserved so we can map the files there
|
||||||
|
verify(VirtualFree(RomPtr,0,MEM_RELEASE));
|
||||||
|
|
||||||
|
//Map the files into the segment of the ram that was reserved
|
||||||
|
for (size_t i=0;i<RomCacheMapCount;i++)
|
||||||
|
{
|
||||||
|
u8* RomDest=RomPtr+fstart[i];
|
||||||
|
|
||||||
|
if (RomCacheMap[i]==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
wprintf(L"-Reserving ram at 0x%08X, size 0x%08X\n",fstart[i],fsize[i]);
|
||||||
|
verify(VirtualAlloc(RomDest,fsize[i],MEM_RESERVE,PAGE_NOACCESS));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wprintf(L"-Mapping \"%s\" at 0x%08X, size 0x%08X\n",files[i].c_str(),fstart[i],fsize[i]);
|
||||||
|
if (RomDest!=MapViewOfFileEx(RomCacheMap[i],FILE_MAP_READ,0,0,fsize[i],RomDest))
|
||||||
|
{
|
||||||
|
printf("-Mapping ROM FAILED\n");
|
||||||
|
//unmap file
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//done :)
|
||||||
|
printf("\nMapped ROM Successfully !\n\n");
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NaomiSelectFile(void* handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||||
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||||
|
ofn.hInstance = (HINSTANCE)GetModuleHandle(0);
|
||||||
|
ofn.lpstrFile = SelectedFile;
|
||||||
|
ofn.nMaxFile = MAX_PATH;
|
||||||
|
ofn.lpstrFilter = "*.lst\0*.lst\0\0";
|
||||||
|
ofn.nFilterIndex = 0;
|
||||||
|
ofn.hwndOwner =(HWND)handle;
|
||||||
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||||
|
|
||||||
|
if(GetOpenFileName(&ofn)<=0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!naomi_LoadRom(SelectedFile))
|
||||||
|
{
|
||||||
|
cfgSaveStr("emu","gamefile","naomi_bios");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cfgSaveStr("emu","gamefile",SelectedFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("EEPROM file : %s.eeprom\n",SelectedFile);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//Dma Start
|
||||||
|
void Naomi_DmaStart(u32 addr, u32 data)
|
||||||
|
{
|
||||||
|
if (SB_GDEN==0)
|
||||||
|
{
|
||||||
|
printf("Invalid (NAOMI)GD-DMA start, SB_GDEN=0.Ingoring it.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NaomiDataRead = true;
|
||||||
|
SB_GDST|=data&1;
|
||||||
|
|
||||||
|
if (SB_GDST==1)
|
||||||
|
{
|
||||||
|
verify(1 == SB_GDDIR );
|
||||||
|
|
||||||
|
SB_GDSTARD=SB_GDSTAR+SB_GDLEN;
|
||||||
|
|
||||||
|
SB_GDLEND=SB_GDLEN;
|
||||||
|
SB_GDST=0;
|
||||||
|
WriteMemBlock_nommu_ptr(SB_GDSTAR,(u32*)(RomPtr+(DmaOffset&0x0FFFffff)),SB_GDLEN);
|
||||||
|
|
||||||
|
asic_RaiseInterrupt(holly_GDROM_DMA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Naomi_DmaEnable(u32 addr, u32 data)
|
||||||
|
{
|
||||||
|
SB_GDEN=data&1;
|
||||||
|
if (SB_GDEN==0 && SB_GDST==1)
|
||||||
|
{
|
||||||
|
printf("(NAOMI)GD-DMA aborted\n");
|
||||||
|
SB_GDST=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void naomi_reg_Init()
|
||||||
|
{
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
CommMapFile = CreateFileMapping(
|
||||||
|
INVALID_HANDLE_VALUE, // use paging file
|
||||||
|
NULL, // default security
|
||||||
|
PAGE_READWRITE, // read/write access
|
||||||
|
0, // max. object size
|
||||||
|
0x1000*4, // buffer size
|
||||||
|
L"Global\\nullDC_103_naomi_comm"); // name of mapping object
|
||||||
|
|
||||||
|
if (CommMapFile == NULL || CommMapFile==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
_tprintf(TEXT("Could not create file mapping object (%d).\nTrying to open existing one\n"), GetLastError());
|
||||||
|
|
||||||
|
CommMapFile=OpenFileMapping(
|
||||||
|
FILE_MAP_ALL_ACCESS, // read/write access
|
||||||
|
FALSE, // do not inherit the name
|
||||||
|
L"Global\\nullDC_103_naomi_comm"); // name of mapping object
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommMapFile == NULL || CommMapFile==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
_tprintf(TEXT("Could not open existing file either\n"), GetLastError());
|
||||||
|
CommMapFile=INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("NAOMI: Created \"Global\\nullDC_103_naomi_comm\"\n");
|
||||||
|
CommSharedMem = (u32*) MapViewOfFile(CommMapFile, // handle to map object
|
||||||
|
FILE_MAP_ALL_ACCESS, // read/write permission
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0x1000*4);
|
||||||
|
|
||||||
|
if (CommSharedMem == NULL)
|
||||||
|
{
|
||||||
|
_tprintf(TEXT("Could not map view of file (%d).\n"),
|
||||||
|
GetLastError());
|
||||||
|
|
||||||
|
CloseHandle(CommMapFile);
|
||||||
|
CommMapFile=INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("NAOMI: Mapped CommSharedMem\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
NaomiInit();
|
||||||
|
|
||||||
|
sb_rio_register(SB_GDST_addr, RIO_WF, 0, &Naomi_DmaStart);
|
||||||
|
|
||||||
|
sb_rio_register(SB_GDEN_addr, RIO_WF, 0, &Naomi_DmaEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void naomi_reg_Term()
|
||||||
|
{
|
||||||
|
#ifdef NAOMI_COMM
|
||||||
|
if (CommSharedMem)
|
||||||
|
{
|
||||||
|
UnmapViewOfFile(CommSharedMem);
|
||||||
|
}
|
||||||
|
if (CommMapFile!=INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
CloseHandle(CommMapFile);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void naomi_reg_Reset(bool Manual)
|
||||||
|
{
|
||||||
|
NaomiDataRead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update_naomi()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (naomi_updates>1)
|
||||||
|
{
|
||||||
|
naomi_updates--;
|
||||||
|
}
|
||||||
|
else if (naomi_updates==1)
|
||||||
|
{
|
||||||
|
naomi_updates=0;
|
||||||
|
asic_RaiseInterrupt(holly_EXP_PCI);
|
||||||
|
}*/
|
||||||
|
#if 0
|
||||||
|
if(!(SB_GDST&1) || !(SB_GDEN &1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//SB_GDST=0;
|
||||||
|
|
||||||
|
//TODO : Fix dmaor
|
||||||
|
u32 dmaor = DMAC_DMAOR.full;
|
||||||
|
|
||||||
|
u32 src = SB_GDSTARD,
|
||||||
|
len = SB_GDLEN-SB_GDLEND ;
|
||||||
|
|
||||||
|
//len=min(len,(u32)32);
|
||||||
|
// do we need to do this for gdrom dma ?
|
||||||
|
if(0x8201 != (dmaor &DMAOR_MASK)) {
|
||||||
|
printf("\n!\tGDROM: DMAOR has invalid settings (%X) !\n", dmaor);
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
if(len & 0x1F) {
|
||||||
|
printf("\n!\tGDROM: SB_GDLEN has invalid size (%X) !\n", len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 == len)
|
||||||
|
{
|
||||||
|
printf("\n!\tGDROM: Len: %X, Abnormal Termination !\n", len);
|
||||||
|
}
|
||||||
|
u32 len_backup=len;
|
||||||
|
if( 1 == SB_GDDIR )
|
||||||
|
{
|
||||||
|
WriteMemBlock_nommu_ptr(dst,NaomiRom+(DmaOffset&0x7ffffff),size);
|
||||||
|
|
||||||
|
DmaCount=0xffff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msgboxf(L"GDROM: SB_GDDIR %X (TO AICA WAVE MEM?)",MBX_ICONERROR, SB_GDDIR);
|
||||||
|
|
||||||
|
//SB_GDLEN = 0x00000000; //13/5/2k7 -> acording to docs these regs are not updated by hardware
|
||||||
|
//SB_GDSTAR = (src + len_backup);
|
||||||
|
|
||||||
|
SB_GDLEND+= len_backup;
|
||||||
|
SB_GDSTARD+= len_backup;//(src + len_backup)&0x1FFFFFFF;
|
||||||
|
|
||||||
|
if (SB_GDLEND==SB_GDLEN)
|
||||||
|
{
|
||||||
|
//printf("Streamed GDMA end - %d bytes trasnfered\n",SB_GDLEND);
|
||||||
|
SB_GDST=0;//done
|
||||||
|
// The DMA end interrupt flag
|
||||||
|
asic_RaiseInterrupt(holly_GDROM_DMA);
|
||||||
|
}
|
||||||
|
//Readed ALL sectors
|
||||||
|
if (read_params.remaining_sectors==0)
|
||||||
|
{
|
||||||
|
u32 buff_size =read_buff.cache_size - read_buff.cache_index;
|
||||||
|
//And all buffer :p
|
||||||
|
if (buff_size==0)
|
||||||
|
{
|
||||||
|
verify(!SB_GDST&1)
|
||||||
|
gd_set_state(gds_procpacketdone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
** naomi.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void naomi_reg_Init();
|
||||||
|
void naomi_reg_Term();
|
||||||
|
void naomi_reg_Reset(bool Manual);
|
||||||
|
|
||||||
|
void Update_naomi();
|
||||||
|
|
||||||
|
u32 ReadMem_naomi(u32 Addr, u32 sz);
|
||||||
|
void WriteMem_naomi(u32 Addr, u32 data, u32 sz);
|
||||||
|
|
||||||
|
void NaomiBoardIDWrite(const u16 Data);
|
||||||
|
void NaomiBoardIDWriteControl(const u16 Data);
|
||||||
|
u16 NaomiBoardIDRead();
|
||||||
|
bool NaomiSelectFile(void* handle);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "hw/sh4/sh4_mmr.h"
|
#include "hw/sh4/sh4_mmr.h"
|
||||||
|
|
||||||
|
#include "hw/naomi/naomi.h"
|
||||||
|
|
||||||
BSC_PDTRA_type BSC_PDTRA;
|
BSC_PDTRA_type BSC_PDTRA;
|
||||||
|
|
||||||
|
|
||||||
void write_BSC_PCTRA(u32 addr, u32 data)
|
void write_BSC_PCTRA(u32 addr, u32 data)
|
||||||
{
|
{
|
||||||
BSC_PCTRA.full=(u16)data;
|
BSC_PCTRA.full=(u16)data;
|
||||||
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||||
NaomiBoardIDWriteControl((u16)data);
|
NaomiBoardIDWriteControl((u16)data);
|
||||||
#else
|
#else
|
||||||
//printf("C:BSC_PCTRA = %08X\n",data);
|
//printf("C:BSC_PCTRA = %08X\n",data);
|
||||||
|
@ -21,14 +23,14 @@ void write_BSC_PDTRA(u32 addr, u32 data)
|
||||||
BSC_PDTRA.full=(u16)data;
|
BSC_PDTRA.full=(u16)data;
|
||||||
//printf("D:BSC_PDTRA = %08X\n",data);
|
//printf("D:BSC_PDTRA = %08X\n",data);
|
||||||
|
|
||||||
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||||
NaomiBoardIDWrite((u16)data);
|
NaomiBoardIDWrite((u16)data);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 read_BSC_PDTRA(u32 addr)
|
u32 read_BSC_PDTRA(u32 addr)
|
||||||
{
|
{
|
||||||
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||||
|
|
||||||
return NaomiBoardIDRead();
|
return NaomiBoardIDRead();
|
||||||
|
|
||||||
|
@ -111,6 +113,11 @@ void bsc_init()
|
||||||
sh4_rio_reg(BSC,BSC_GPIOIC_addr,RIO_DATA,16);
|
sh4_rio_reg(BSC,BSC_GPIOIC_addr,RIO_DATA,16);
|
||||||
|
|
||||||
//note: naomi//aw might depend on rfcr
|
//note: naomi//aw might depend on rfcr
|
||||||
|
|
||||||
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||||
|
sh4_rio_reg(BSC, BSC_RFCR_addr, RIO_RO, 16);
|
||||||
|
BSC_RFCR.full = 17;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "hw/sh4/sh4_mem.h"
|
#include "hw/sh4/sh4_mem.h"
|
||||||
|
|
||||||
#include "webui/server.h"
|
#include "webui/server.h"
|
||||||
|
#include "hw/naomi/naomi.h"
|
||||||
|
|
||||||
settings_t settings;
|
settings_t settings;
|
||||||
|
|
||||||
|
@ -90,9 +91,8 @@ s32 plugins_Init()
|
||||||
|
|
||||||
if (s32 rv = libGDR_Init())
|
if (s32 rv = libGDR_Init())
|
||||||
return rv;
|
return rv;
|
||||||
|
#if DC_PLATFORM == DC_PLATFORM_NAOMI
|
||||||
#ifdef BUILD_NAOMI
|
if (!NaomiSelectFile(libPvr_GetRenderTarget()))
|
||||||
if (!NaomiSelectFile(GetRenderTargetHandle()))
|
|
||||||
return rv_serror;
|
return rv_serror;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ struct vram_block
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if (DC_PLATFORM==DC_PLATFORM_NORMAL)
|
#if (DC_PLATFORM==DC_PLATFORM_DREAMCAST)
|
||||||
|
|
||||||
#define BUILD_DREAMCAST 1
|
#define BUILD_DREAMCAST 1
|
||||||
|
|
||||||
|
@ -232,9 +232,6 @@ struct vram_block
|
||||||
#define NVR_OPTIONAL 0
|
#define NVR_OPTIONAL 0
|
||||||
|
|
||||||
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI)
|
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI)
|
||||||
|
|
||||||
#define BUILD_NAOMI 1
|
|
||||||
#define BUILD_NAOMI1 1
|
|
||||||
|
|
||||||
//Naomi : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
//Naomi : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
||||||
#define RAM_SIZE (32*1024*1024)
|
#define RAM_SIZE (32*1024*1024)
|
||||||
|
@ -248,9 +245,6 @@ struct vram_block
|
||||||
#define NVR_OPTIONAL 1
|
#define NVR_OPTIONAL 1
|
||||||
|
|
||||||
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI2)
|
#elif (DC_PLATFORM==DC_PLATFORM_NAOMI2)
|
||||||
|
|
||||||
#define BUILD_NAOMI 1
|
|
||||||
#define BUILD_NAOMI2 1
|
|
||||||
|
|
||||||
//Naomi2 : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
//Naomi2 : 32 mb ram, 16 mb vram, 8 mb aram, 2 mb bios, ? flash
|
||||||
#define RAM_SIZE (32*1024*1024)
|
#define RAM_SIZE (32*1024*1024)
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
<ClCompile Include="..\core\hw\maple\maple_helper.cpp" />
|
<ClCompile Include="..\core\hw\maple\maple_helper.cpp" />
|
||||||
<ClCompile Include="..\core\hw\maple\maple_if.cpp" />
|
<ClCompile Include="..\core\hw\maple\maple_if.cpp" />
|
||||||
<ClCompile Include="..\core\hw\mem\_vmem.cpp" />
|
<ClCompile Include="..\core\hw\mem\_vmem.cpp" />
|
||||||
|
<ClCompile Include="..\core\hw\naomi\naomi.cpp" />
|
||||||
<ClCompile Include="..\core\hw\pvr\drkPvr.cpp" />
|
<ClCompile Include="..\core\hw\pvr\drkPvr.cpp" />
|
||||||
<ClCompile Include="..\core\hw\pvr\pvr_mem.cpp" />
|
<ClCompile Include="..\core\hw\pvr\pvr_mem.cpp" />
|
||||||
<ClCompile Include="..\core\hw\pvr\pvr_regs.cpp" />
|
<ClCompile Include="..\core\hw\pvr\pvr_regs.cpp" />
|
||||||
|
@ -258,6 +259,8 @@
|
||||||
<ClInclude Include="..\core\hw\maple\maple_helper.h" />
|
<ClInclude Include="..\core\hw\maple\maple_helper.h" />
|
||||||
<ClInclude Include="..\core\hw\maple\maple_if.h" />
|
<ClInclude Include="..\core\hw\maple\maple_if.h" />
|
||||||
<ClInclude Include="..\core\hw\mem\_vmem.h" />
|
<ClInclude Include="..\core\hw\mem\_vmem.h" />
|
||||||
|
<ClInclude Include="..\core\hw\naomi\naomi.h" />
|
||||||
|
<ClInclude Include="..\core\hw\naomi\naomi_regs.h" />
|
||||||
<ClInclude Include="..\core\hw\pvr\config.h" />
|
<ClInclude Include="..\core\hw\pvr\config.h" />
|
||||||
<ClInclude Include="..\core\hw\pvr\drkPvr.h" />
|
<ClInclude Include="..\core\hw\pvr\drkPvr.h" />
|
||||||
<ClInclude Include="..\core\hw\pvr\helper_classes.h" />
|
<ClInclude Include="..\core\hw\pvr\helper_classes.h" />
|
||||||
|
|
|
@ -420,6 +420,9 @@
|
||||||
<ClCompile Include="..\core\rend\soft\softrend.cpp">
|
<ClCompile Include="..\core\rend\soft\softrend.cpp">
|
||||||
<Filter>rend\soft</Filter>
|
<Filter>rend\soft</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\core\hw\naomi\naomi.cpp">
|
||||||
|
<Filter>hw\naomi</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="hw">
|
<Filter Include="hw">
|
||||||
|
@ -554,6 +557,9 @@
|
||||||
<Filter Include="rend\soft">
|
<Filter Include="rend\soft">
|
||||||
<UniqueIdentifier>{6c4b2d69-54c0-4660-9969-a98fd0339a15}</UniqueIdentifier>
|
<UniqueIdentifier>{6c4b2d69-54c0-4660-9969-a98fd0339a15}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="hw\naomi">
|
||||||
|
<UniqueIdentifier>{1752487d-0739-47bf-8c6b-1d38e6f389f7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\core\hw\aica\aica.h">
|
<ClInclude Include="..\core\hw\aica\aica.h">
|
||||||
|
@ -922,6 +928,12 @@
|
||||||
<ClInclude Include="..\core\rec-x86\rec_x86_ngen.h">
|
<ClInclude Include="..\core\rec-x86\rec_x86_ngen.h">
|
||||||
<Filter>rec-x86</Filter>
|
<Filter>rec-x86</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\core\hw\naomi\naomi.h">
|
||||||
|
<Filter>hw\naomi</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\core\hw\naomi\naomi_regs.h">
|
||||||
|
<Filter>hw\naomi</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\core\deps\zlib\Makefile">
|
<None Include="..\core\deps\zlib\Makefile">
|
||||||
|
|
Loading…
Reference in New Issue