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:
Stefanos Kornilios Mitsis Poiitidis 2015-08-09 06:34:02 +02:00
parent 9bc0a8ff0f
commit 7d0d2ba572
14 changed files with 1530 additions and 42 deletions

View File

@ -118,16 +118,13 @@
#define NO_MMU
#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_NAOMI 2 /* Works, for the most part */
#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_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 DC_PLATFORM_NORMAL
//HOST_OS
@ -206,6 +203,11 @@
#error Invalid Target: TARGET_* not defined
#endif
#if defined(TARGET_NAOMI)
#define DC_PLATFORM DC_PLATFORM_NAOMI
#undef TARGET_NAOMI
#endif
#if defined(TARGET_NO_REC)
#define FEAT_SHREC DYNAREC_NONE
#define FEAT_AREC DYNAREC_NONE
@ -234,6 +236,11 @@
#endif
//defaults
#ifndef DC_PLATFORM
#define DC_PLATFORM DC_PLATFORM_DREAMCAST
#endif
#ifndef FEAT_SHREC
#define FEAT_SHREC DYNAREC_JIT
#endif

View File

@ -172,7 +172,7 @@ struct DCFlashChip : MemChip // I think its Micronix :p
{
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)
return '0' + settings.dreamcast.region;
else if ((addr==0x1A004 || addr==0x1A0A4) && settings.dreamcast.broadcast<=3)

View File

@ -11,9 +11,7 @@
#include "hw/maple/maple_if.h"
#include "hw/aica/aica_if.h"
#if defined(BUILD_NAOMI) || defined(BUILD_ATOMISWAVE)
#include "../../naomi/naomi.h"
#endif
#include "hw/naomi/naomi.h"
Array<RegisterStruct> sb_regs(0x540);

View File

@ -12,7 +12,7 @@
#include "hw/pvr/pvr_mem.h"
#include "hw/gdrom/gdrom_if.h"
#include "hw/aica/aica_if.h"
//#include "naomi/naomi.h"
#include "hw/naomi/naomi.h"
#include "hw/flashrom/flashrom.h"
#include "reios/reios.h"
@ -63,7 +63,7 @@ bool LoadHle(const string& root) {
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); }
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
{
//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);
#else
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
{
//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);
#else
WriteMem_gdrom(addr,data,sz);

View File

@ -66,25 +66,17 @@ void mcfg_Create(MapleDeviceType type,u32 bus,u32 port)
MapleDevices[bus][port]=dev;
}
#ifndef _ANDROID
void mcfg_CreateDevices()
{
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
mcfg_Create(MDT_SegaController,0,5);
#ifdef HAS_VMU
mcfg_Create(MDT_SegaVMU,0,0);
mcfg_Create(MDT_SegaVMU,0,1);
#endif
}
#else
void mcfg_CreateDevices()
{
mcfg_Create(MDT_SegaController,0,5);
mcfg_Create(MDT_SegaVMU,0,0);
mcfg_Create(MDT_SegaVMU,0,1);
}
mcfg_Create(MDT_NaomiJamma, 0, 5);
#endif
}
void mcfg_DestroyDevices()
{

View File

@ -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.";
#define HAS_VMU
enum MapleFunctionID
{
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
This is pretty much done (?)
*/
#ifdef HAS_VMU
u8 vmu_default[] = {
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
{
@ -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* rv=0;
@ -854,14 +1287,19 @@ maple_device* maple_Create(MapleDeviceType type)
case MDT_SegaController:
rv=new maple_sega_controller();
break;
case MDT_Microphone:
rv=new maple_microphone();
break;
#ifdef HAS_VMU
case MDT_SegaVMU:
rv = new maple_sega_vmu();
break;
#endif
case MDT_NaomiJamma:
rv = new maple_naomi_jamma();
break;
default:
return 0;

View File

@ -7,6 +7,8 @@ enum MapleDeviceType
MDT_SegaVMU,
MDT_Microphone,
MDT_NaomiJamma,
MDT_Count
};

995
core/hw/naomi/naomi.cpp Normal file
View File

@ -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
}

40
core/hw/naomi/naomi.h Normal file
View File

@ -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);

View File

@ -3,13 +3,15 @@
#include "types.h"
#include "hw/sh4/sh4_mmr.h"
#include "hw/naomi/naomi.h"
BSC_PDTRA_type BSC_PDTRA;
void write_BSC_PCTRA(u32 addr, u32 data)
{
BSC_PCTRA.full=(u16)data;
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
#if DC_PLATFORM == DC_PLATFORM_NAOMI
NaomiBoardIDWriteControl((u16)data);
#else
//printf("C:BSC_PCTRA = %08X\n",data);
@ -21,14 +23,14 @@ void write_BSC_PDTRA(u32 addr, u32 data)
BSC_PDTRA.full=(u16)data;
//printf("D:BSC_PDTRA = %08X\n",data);
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
#if DC_PLATFORM == DC_PLATFORM_NAOMI
NaomiBoardIDWrite((u16)data);
#endif
}
u32 read_BSC_PDTRA(u32 addr)
{
#if defined(BUILD_NAOMI ) || defined(BUILD_ATOMISWAVE)
#if DC_PLATFORM == DC_PLATFORM_NAOMI
return NaomiBoardIDRead();
@ -111,6 +113,11 @@ void bsc_init()
sh4_rio_reg(BSC,BSC_GPIOIC_addr,RIO_DATA,16);
//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
}

View File

@ -14,6 +14,7 @@
#include "hw/sh4/sh4_mem.h"
#include "webui/server.h"
#include "hw/naomi/naomi.h"
settings_t settings;
@ -90,9 +91,8 @@ s32 plugins_Init()
if (s32 rv = libGDR_Init())
return rv;
#ifdef BUILD_NAOMI
if (!NaomiSelectFile(GetRenderTargetHandle()))
#if DC_PLATFORM == DC_PLATFORM_NAOMI
if (!NaomiSelectFile(libPvr_GetRenderTarget()))
return rv_serror;
#endif

View File

@ -201,7 +201,7 @@ struct vram_block
};
#if (DC_PLATFORM==DC_PLATFORM_NORMAL)
#if (DC_PLATFORM==DC_PLATFORM_DREAMCAST)
#define BUILD_DREAMCAST 1
@ -232,9 +232,6 @@ struct vram_block
#define NVR_OPTIONAL 0
#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
#define RAM_SIZE (32*1024*1024)
@ -248,9 +245,6 @@ struct vram_block
#define NVR_OPTIONAL 1
#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
#define RAM_SIZE (32*1024*1024)

View File

@ -95,6 +95,7 @@
<ClCompile Include="..\core\hw\maple\maple_helper.cpp" />
<ClCompile Include="..\core\hw\maple\maple_if.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\pvr_mem.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_if.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\drkPvr.h" />
<ClInclude Include="..\core\hw\pvr\helper_classes.h" />

View File

@ -420,6 +420,9 @@
<ClCompile Include="..\core\rend\soft\softrend.cpp">
<Filter>rend\soft</Filter>
</ClCompile>
<ClCompile Include="..\core\hw\naomi\naomi.cpp">
<Filter>hw\naomi</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="hw">
@ -554,6 +557,9 @@
<Filter Include="rend\soft">
<UniqueIdentifier>{6c4b2d69-54c0-4660-9969-a98fd0339a15}</UniqueIdentifier>
</Filter>
<Filter Include="hw\naomi">
<UniqueIdentifier>{1752487d-0739-47bf-8c6b-1d38e6f389f7}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\core\hw\aica\aica.h">
@ -922,6 +928,12 @@
<ClInclude Include="..\core\rec-x86\rec_x86_ngen.h">
<Filter>rec-x86</Filter>
</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>
<None Include="..\core\deps\zlib\Makefile">