Add libretro port of 4DO/libfreedo 1.3.2.3

This commit is contained in:
clobber committed 2014-08-23 01:17:53 -05:00
1 parent f3e396ea72
commit e8613b5036
37 files changed
+13479

No files matched your search

+174
View File
@@ -0,0 +1,174 @@
DEBUG = 0
ifeq ($(platform),)
platform = unix
ifeq ($(shell uname -a),)
platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
platform = osx
arch = intel
ifeq ($(shell uname -p),powerpc)
arch = ppc
endif
else ifneq ($(findstring MINGW,$(shell uname -a)),)
platform = win
endif
endif
# system platform
system_platform = unix
ifeq ($(shell uname -a),)
EXE_EXT = .exe
system_platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
system_platform = osx
arch = intel
ifeq ($(shell uname -p),powerpc)
arch = ppc
endif
else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
TARGET_NAME := 4DO
ifeq ($(platform), unix)
TARGET := $(TARGET_NAME)_libretro.so
fpic := -fPIC
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
else ifeq ($(platform), osx)
TARGET := $(TARGET_NAME)_libretro.dylib
fpic := -fPIC
SHARED := -dynamiclib
ifeq ($(arch),ppc)
FLAGS += -DMSB_FIRST
OLD_GCC = 1
endif
OSXVER = `sw_vers -productVersion | cut -c 4`
ifneq ($(OSXVER),9)
fpic += -mmacosx-version-min=10.5
endif
else ifeq ($(platform), ios)
TARGET := $(TARGET_NAME)_libretro_ios.dylib
fpic := -fPIC
SHARED := -dynamiclib
CC = clang -arch armv7 -isysroot $(IOSSDK)
CXX = clang++ -arch armv7 -isysroot $(IOSSDK)
OSXVER = `sw_vers -productVersion | cut -c 4`
ifneq ($(OSXVER),9)
SHARED += -miphoneos-version-min=5.0
CC += -miphoneos-version-min=5.0
CXX += -miphoneos-version-min=5.0
endif
else ifeq ($(platform), qnx)
TARGET := $(TARGET_NAME)_libretro_qnx.so
fpic := -fPIC
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
CC = qcc -Vgcc_ntoarmv7le
CXX = QCC -Vgcc_ntoarmv7le_cpp
else ifeq ($(platform), ps3)
TARGET := $(TARGET_NAME)_libretro_ps3.a
CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe
STATIC_LINKING = 1
FLAGS += -DMSB_FIRST
OLD_GCC = 1
else ifeq ($(platform), sncps3)
TARGET := $(TARGET_NAME)_libretro_ps3.a
CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
STATIC_LINKING = 1
FLAGS += -DMSB_FIRST
NO_GCC = 1
else ifeq ($(platform), psp1)
TARGET := $(TARGET_NAME)_libretro_psp1.a
CC = psp-gcc$(EXE_EXT)
CXX = psp-g++$(EXE_EXT)
AR = psp-ar$(EXE_EXT)
STATIC_LINKING = 1
FLAGS += -G0 -DLSB_FIRST
else
TARGET := $(TARGET_NAME)_libretro.dll
CC = gcc
CXX = g++
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
LDFLAGS += -static-libgcc -static-libstdc++ -lwinmm
endif
4DO_DIR := libfreedo
4DO_SOURCES := $(4DO_DIR)/_3do_sys.cpp \
$(4DO_DIR)/arm.cpp \
$(4DO_DIR)/bitop.cpp \
$(4DO_DIR)/Clio.cpp \
$(4DO_DIR)/DiagPort.cpp \
$(4DO_DIR)/DSP.cpp \
$(4DO_DIR)/frame.cpp \
$(4DO_DIR)/Iso.cpp \
$(4DO_DIR)/Madam.cpp \
$(4DO_DIR)/quarz.cpp \
$(4DO_DIR)/SPORT.cpp \
$(4DO_DIR)/vdlp.cpp \
$(4DO_DIR)/XBUS.cpp
LIBRETRO_SOURCES := libretro.cpp
SOURCES_C :=
SOURCES := $(LIBRETRO_SOURCES) $(4DO_SOURCES)
OBJECTS := $(SOURCES:.cpp=.o) $(SOURCES_C:.c=.o)
all: $(TARGET)
ifeq ($(DEBUG),1)
FLAGS += -O0 -g
else
FLAGS += -O3 -DNDEBUG
endif
LDFLAGS += $(fpic) -lz $(SHARED)
FLAGS += $(fpic)
FLAGS += -I. -Ilibfreedo
ifeq ($(OLD_GCC), 1)
WARNINGS := -Wall
else ifeq ($(NO_GCC), 1)
WARNINGS :=
else
WARNINGS := -Wall \
-Wno-narrowing \
-Wno-sign-compare \
-Wno-unused-variable \
-Wno-unused-function \
-Wno-uninitialized \
-Wno-unused-result \
-Wno-strict-aliasing \
-Wno-overflow \
-fno-strict-overflow
endif
FLAGS += -D__LIBRETRO__ $(WARNINGS)
CXXFLAGS += $(FLAGS)
CFLAGS += $(FLAGS)
$(TARGET): $(OBJECTS)
ifeq ($(STATIC_LINKING), 1)
$(AR) rcs $@ $(OBJECTS)
else
$(CXX) -o $@ $^ $(LDFLAGS)
endif
%.o: %.cpp
$(CXX) -c -o $@ $< $(CXXFLAGS)
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
clean:
rm -f $(TARGET) $(OBJECTS)
.PHONY: clean
+992
View File
@@ -0,0 +1,992 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// Clio.cpp: implementation of the CClio class.
//
//////////////////////////////////////////////////////////////////////
#include "freedoconfig.h"
#include "Clio.h"
#include "Madam.h"
#include "XBUS.h"
#include "arm.h"
#include "DSP.h"
#include "stdafx.h"
#define DECREMENT 0x1
#define RELOAD 0x2
#define CASCADE 0x4
#define FLABLODE 0x8
void __fastcall HandleDMA(unsigned int val);
//#define FIFODBG
#define RELOAD_VAL 0x10
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#pragma pack(push,1)
struct FIFOt{
unsigned int StartAdr;
int StartLen;
unsigned int NextAdr;
int NextLen;
};
struct CLIODatum
{
unsigned int cregs[65536];
int DSPW1;
int DSPW2;
int DSPA;
int PTRI[13];
int PTRO[4];
FIFOt FIFOI[13];
FIFOt FIFOO[4];
};
#pragma pack(pop)
static unsigned int * Mregs;
static CLIODatum clio;
#define cregs clio.cregs
#define DSPW1 clio.DSPW1
#define DSPW2 clio.DSPW2
#define DSPA clio.DSPA
#define PTRI clio.PTRI
#define PTRO clio.PTRO
#define FIFOI clio.FIFOI
#define FIFOO clio.FIFOO
#include <memory.h>
unsigned int _clio_SaveSize()
{
return sizeof(CLIODatum);
}
void _clio_Save(void *buff)
{
memcpy(buff,&clio,sizeof(CLIODatum));
}
void _clio_Load(void *buff)
{
memcpy(&clio,buff,sizeof(CLIODatum));
}
#define CURADR Mregs[base]
#define CURLEN Mregs[base+4]
#define RLDADR Mregs[base+8]
#define RLDLEN Mregs[base+0xc]
extern int fastrand();
int _clio_v0line()
{
return cregs[8]&0x7ff;
}
int _clio_v1line()
{
return cregs[12]&0x7ff;
}
bool __fastcall _clio_NeedFIQ()
{
if( (cregs[0x40]&cregs[0x48]) || (cregs[0x60]&cregs[0x68]) ) return true;
return false;
}
void __fastcall _clio_GenerateFiq(unsigned int reason1, unsigned int reason2)
{
cregs[0x40]|=reason1;
cregs[0x60]|=reason2;
if(cregs[0x60]) cregs[0x40]|=0x80000000; // irq31 if exist irq32 and high
//if( (cregs[0x40]&cregs[0x48]) || (cregs[0x60]&cregs[0x68]) ) _arm_SetFIQ();
/////////////
#ifdef DBGFIQ
sprintf(str,"FIQ accepted 0x%8.8X 0x%8.8X 0x%8.8X 0x%8.8X\n",reason1,reason2,CClio::Peek(0x48),CClio::Peek(0x68));
CDebug::DPrint(str);
if( (cregs[0x40]&cregs[0x48]) || (cregs[0x60]&cregs[0x68]) )
{
sprintf(str,"!!!FIQ decision taken\n");
CDebug::DPrint(str);
}
#endif
/////////////
}
#include "freedocore.h"
extern _ext_Interface io_interface;
//extern AString str;
void __fastcall _clio_SetTimers(uint32 v200, uint32 v208);
void __fastcall _clio_ClearTimers(uint32 v204, uint32 v20c);
int __fastcall _clio_Poke(unsigned int addr, unsigned int val)
{
int base;
int i;
//if(addr==0x200 || addr==0x204 || addr==0x208 || addr==0x20c || (addr>=0x100 && addr<=0x17c) || addr==0x220)io_interface(EXT_DEBUG_PRINT,(void*)str.print("CLIO Write[0x%X] = 0x%8.8X",addr,val).CStr());
//if(addr==0x34 || addr==0x30)io_interface(EXT_DEBUG_PRINT,(void*)str.print("CLIO Write[0x%X] = 0x%8.8X",addr,val).CStr());
if( (addr& ~0x2C) == 0x40 ) // 0x40..0x4C, 0x60..0x6C case
{
if(addr==0x40)
{
cregs[0x40]|=val;
if(cregs[0x60]) cregs[0x40]|=0x80000000;
//if(cregs[0x40]&cregs[0x48]) _arm_SetFIQ();
return 0;
}
else if(addr==0x44)
{
cregs[0x40]&=~val;
if(!cregs[0x60]) cregs[0x40]&=~0x80000000;
return 0;
}
else if(addr==0x48)
{
cregs[0x48]|=val;
//if(cregs[0x40]&cregs[0x48]) _arm_SetFIQ();
return 0;
}
else if(addr==0x4c)
{
cregs[0x48]&=~val;
cregs[0x48]|=0x80000000; // always one for irq31
return 0;
}
/*else if(addr==0x50)
{
cregs[0x50]|=val&0x3fff0000;
return 0;
}
else if(addr==0x54)
{
cregs[0x50]&=~val;
return 0;
} */
else if(addr==0x60)
{
cregs[0x60]|=val;
if(cregs[0x60]) cregs[0x40]|=0x80000000;
//if(cregs[0x60]&cregs[0x68]) _arm_SetFIQ();
return 0;
}
else if(addr==0x64)
{
cregs[0x60]&=~val;
if(!cregs[0x60]) cregs[0x40]&=~0x80000000;
return 0;
}
else if(addr==0x68)
{
cregs[0x68]|=val;
//if(cregs[0x60]&cregs[0x68]) _arm_SetFIQ();
return 0;
}
else if(addr==0x6c)
{
cregs[0x68]&=~val;
return 0;
}
}
else if(addr==0x84)
{
//temp=val&0xf0;
//temp=temp>>4;
//val&=0x0f;
//cregs[0x84]&=~temp;
//cregs[0x84]|=val;
cregs[0x84]=val&0xf;
SelectROM((val&4)? 1:0 );
return 0;
}else if(addr==0x300)
{ //clear down the fifos and stop them
base=0;
cregs[0x304]&=~val;
for(i=0;i<13;i++)
{
if(val&(1<<i))
{
base=0x400+(i<<4);
RLDADR=CURADR=0;
RLDLEN=CURLEN=0;
_clio_SetFIFO(base,0);
_clio_SetFIFO(base+4,0);
_clio_SetFIFO(base+8,0);
_clio_SetFIFO(base+0xc,0);
val&=~(1<<i);
PTRI[i]=0;
}
}
{
for(i=0;i<4;i++)
{
if(val&(1<<(i+16)))
{
base=0x500+(i<<4);
RLDADR=CURADR=0;
RLDLEN=CURLEN=0;
_clio_SetFIFO(base,0);
_clio_SetFIFO(base+4,0);
_clio_SetFIFO(base+8,0);
_clio_SetFIFO(base+0xc,0);
val&=~(1<<(i+16));
PTRO[i]=0;
}
}
}
return 0;
}
else if(addr==0x304) // Dma Starter!!!!! P/A !!!! need to create Handler.
{
//if(val&0x00100000)
//{
HandleDMA(val);
// cregs[0x304]&=~0x00100000;
//}
return 0;
}
else if(addr==0x308) //Dma Stopper!!!!
{
cregs[0x304]&=~val;
return 0;
}
else if(addr==0x400) //XBUS direction
{
if(val&0x800)
return 0;
else
{
cregs[0x400]=val;
return 0;
}
}
else if((addr>=0x500) && (addr<0x540))
{
_xbus_SetSEL(val);
return 0;
}
else if((addr>=0x540) && (addr<0x580))
{
#ifdef DBGXBUS
sprintf(str,"XBPC : 0x%8.8x :",RegRead(15));
CDebug::DPrint(str);
#endif
_xbus_SetPoll(val);
return 0;
}
else if((addr>=0x580) && (addr<0x5c0))
{
_xbus_SetCommandFIFO(val); // on FIFO Filled execute the command
return 0;
}
else if((addr>=0x5c0) && (addr<0x600))
{
_xbus_SetDataFIFO(val); // on FIFO Filled execute the command
return 0;
}
else if(addr==0x28)
{
cregs[addr]=val;
if(val==0x30)
return 1;
else
return 0;
}else if((addr>=0x1800)&&(addr<=0x1fff))//0x0340 1800 … 0x0340 1BFF && 0x0340 1C00 … 0x0340 1FFF
{
addr&=~0x400; //mirrors
DSPW1=val>>16;
DSPW2=val&0xffff;
DSPA=(addr-0x1800)>>1;
//sprintf(str,"0x%8.8X : 2x1NWRITE 0x%3.3X 0x%4.4X\n",GetPC(),DSPA,DSPW1);
//CDebug::DPrint(str);
//sprintf(str,"0x%8.8X : 2x2NWRITE 0x%3.3X 0x%4.4X\n",GetPC(),DSPA+1,DSPW2);
//CDebug::DPrint(str);
_dsp_WriteMemory(DSPA,DSPW1);
_dsp_WriteMemory(DSPA+1,DSPW2);
return 0;
//DSPNRAMWrite 2 DSPW per 1ARMW
}else if((addr>=0x2000)&&(addr<=0x2fff))
{
addr&=~0x800;//mirrors
DSPW1=val&0xffff;
DSPA=(addr-0x2000)>>2;
//sprintf(str,"0x%8.8X : 1xNWRITE 0x%3.3X 0x%4.4X\n",GetPC(),DSPA,DSPW1);
//CDebug::DPrint(str);
_dsp_WriteMemory(DSPA,DSPW1);
return 0;
//DSPNRAMWrite 1 DSPW per 1ARMW
}else if((addr>=0x3000)&&(addr<=0x33ff)) //0x0340 3000 … 0x0340 33FF
{
DSPA=(addr-0x3000)>>1;
DSPA&=0xff;
DSPW1=val>>16;
DSPW2=val&0xffff;
_dsp_WriteIMem(DSPA,DSPW1);
_dsp_WriteIMem(DSPA+1,DSPW2);
/* printf("#ARM 2IWRITE1 0x%3.3X<=0x%4.4X\n",DSPA,DSPW1);
printf("#ARM 2IWRITE2 0x%3.3X<=0x%4.4X\n",DSPA+1,DSPW2);
printf("#ARM word %8.8x\n-----------------------\n",val);*/
return 0;
//DSPEIRam 2 DSPW per 1ARMW
}else if((addr>=0x3400)&&(addr<=0x37ff))//0x0340 3400 … 0x0340 37FF
{
DSPA=(addr-0x3400)>>2;
DSPA&=0xff;
//if(DSPA>0x6f)
//printf("##Strange coeff write -- 0x%3.3X<=0x%4.4X\n",DSPA,DSPW1);
DSPW1=val&0xffff;
_dsp_WriteIMem(DSPA,DSPW1);
/* printf("#ARM IWRITE 0x%3.3X<=0x%4.4X\n",DSPA,DSPW1);
printf("#ARM word %8.8x\n-----------------------\n",val);*/
return 0;
//DSPEIRam 1 DSPW per 1 ARMW
}
else if(addr==0x17E8)//Reset
{
_dsp_Reset();
return 0;
}
else if(addr==0x17D0)//Write DSP/ARM Semaphore
{
_dsp_ARMwrite2sema4(val);
return 0;
}
else if(addr==0x17FC)//start/stop
{
_dsp_SetRunning(val>0);
return 0;
}
else if(addr==0x200)
{
cregs[0x200]|=val;
_clio_SetTimers(val, 0);
return 0;
}
else if(addr==0x204)
{
cregs[0x200]&=~val;
_clio_ClearTimers(val, 0);
return 0;
}
else if(addr==0x208)
{
cregs[0x208]|=val;
_clio_SetTimers(0, val);
return 0;
}
else if(addr==0x20c)
{
cregs[0x208]&=~val;
_clio_ClearTimers(0, val);
return 0;
}
else if(addr==0x220)
{
//if(val<64)val=64;
cregs[addr]=val&0x3ff;
return 0;
}
else if(addr>=0x100 && addr<=0x7c)
{
cregs[addr]=val&0xffff;
return 0;
}
// char jj[90];
// sprintf(jj, "addr=%X, val=0x%8.8X", addr, val,);
//if(jw==0&&addr==0x128){io_interface(EXT_DEBUG_PRINT,(void*)jj); jw=100000;}
if(addr==0x128&&val==0x0)jw=17000000;//val=1;
cregs[addr]=val;
return 0;
}
unsigned int __fastcall _clio_Peek(unsigned int addr)
{
#ifdef DBGCLIO
val=CClio::Peek(index);
if(index!=0x34)
{
sprintf(str,"0x%8.8X : CLIO Read clio[0x%X] = 0x%8.8X\n",RegRead(15),index,val);
CDebug::DPrint(str);
}
return val;
#endif
//if(addr>0x600) // ??????? DSP debug
//{
// printf("#CLIO:PEEK (0x%4.4X)\n",addr);
//}
//if(addr==0x200 || addr==0x204 || addr==0x208 || addr==0x20c || (addr>=0x100 && addr<=0x17c) || addr==0x220)io_interface(EXT_DEBUG_PRINT,(void*)str.print("CLIO Read[0x%X] = 0x%8.8X",addr,cregs[addr]).CStr());
//if(addr==0x34 || addr==0x30)io_interface(EXT_DEBUG_PRINT,(void*)str.print("CLIO Read[0x%X] = 0x%8.8X",addr,cregs[addr]).CStr());
if( (addr& ~0x2C) == 0x40 ) // 0x40..0x4C, 0x60..0x6C case
{
addr&=~4; // By read 40 and 44, 48 and 4c, 60 and 64, 68 and 6c same
if(addr==0x40)
{
return cregs[0x40];
}
else if(addr==0x48)
{
return cregs[0x48]|0x80000000;
}
else if(addr==0x60)
{
return cregs[0x60];
}
else if(addr==0x68)
{
return cregs[0x68];
}
return 0; // for skip warning C4715
}
else if(addr==0x204)
{
return cregs[0x200];
}
else if(addr==0x20c)
{
return cregs[0x208];
}
else if(addr==0x308)
{
return cregs[0x304];
}
else if (addr==0x414)
{
return 0x4000; //TO CHECK!!! requested by CDROMDIPIR
}
else if((addr>=0x500) && (addr<0x540))
{
return _xbus_GetRes();
}
else if((addr>=0x540) && (addr<0x580))
{
#ifdef DBGXBUS
sprintf(str,"XBPC : 0x%8.8x :",RegRead(15));
CDebug::DPrint(str);
#endif
return _xbus_GetPoll();
}
else if((addr>=0x580) && (addr<0x5c0))
{
return _xbus_GetStatusFIFO();
}
else if((addr>=0x5c0) && (addr<0x600))
{
return _xbus_GetDataFIFO();
}
else if(addr==0x0)
{
return 0x02020000;
}
else if((addr>=0x3800)&&(addr<=0x3bff))//0x0340 3800 … 0x0340 3BFF
{
//2DSPW per 1ARMW
DSPA=(addr-0x3800)>>1;
DSPA&=0xff;
DSPA+=0x300;
DSPW1=_dsp_ReadIMem(DSPA);
DSPW2=_dsp_ReadIMem(DSPA+1);
return ((DSPW1<<16)|DSPW2);
}
else if((addr>=0x3c00)&&(addr<=0x3fff))//0x0340 3C00 … 0x0340 3FFF
{
DSPA=(addr-0x3c00)>>2;
DSPA&=0xff;
DSPA+=0x300;
return (_dsp_ReadIMem(DSPA));
}
else if(addr==0x17F0)
{
return fastrand();
}
else if(addr==0x17D0)//Read DSP/ARM Semaphore
{
return _dsp_ARMread2sema4();
}
else if(addr>=0x100 && addr<=0x7c)
{
return cregs[addr]&0xffff;
}
else
return cregs[addr];
}
void __fastcall _clio_UpdateVCNT(int line, int halfframe)
{
// Poke(0x34,Peek(0x34)+1);
cregs[0x34]=(halfframe<<11)+line;
}
void __fastcall _clio_SetTimers(uint32 v200, uint32 v208)
{
(void) v200;
(void) v208;
}
void __fastcall _clio_ClearTimers(uint32 v204, uint32 v20c)
{
(void) v204;
(void) v20c;
}
void __fastcall _clio_DoTimers()
{
unsigned int timer;
unsigned short counter;
unsigned int flag;
bool NeedDecrementNextTimer=true; // Need decrement for next timer
//bool prevdec=false;
for (timer=0;timer<16;timer++)
{
flag=cregs[(timer<8)?0x200:0x208]>>((timer*4)&31);
if( !(flag&CASCADE) ) NeedDecrementNextTimer=true;
if( NeedDecrementNextTimer && (flag&DECREMENT) )
{
counter=cregs[0x100+timer*8];
if((NeedDecrementNextTimer=(counter--==0)))
{
if((timer&1)) // Only odd timers can generate
{ // generate the interrupts because be overflow
_clio_GenerateFiq(1<<(10-timer/2),0);
}
if(flag&RELOAD)
{ // reload timer by reload value
counter=cregs[0x100+timer*8+4];
//return;
}
else
{ // timer stopped -> reset it's flag DECREMENT
cregs[(timer<8)?0x200:0x208] &= ~( DECREMENT<<((timer*4)&31) );
}
}
cregs[0x100+timer*8]=counter;
}
//else if( !prevdec && (flag&CASCADE) ) return;
else NeedDecrementNextTimer=false;
//if( !(flag&CASCADE) ) NeedDecrementNextTimer=true;
//prevdec=(flag&DECREMENT);
}
}
unsigned int _clio_GetTimerDelay()
{
return cregs[0x220];
}
void __fastcall HandleDMA(unsigned int val)
{
unsigned int src;
unsigned int trg;
int len;
unsigned int ptr;
unsigned char b0,b1,b2,b3;
cregs[0x304]|=val;
if(val&0x00100000)
{
cregs[0x304]&=~0x00100000;
src=_madam_Peek(0x540);
//if(src&3)_3do_DPrint("Align Err!!! - see CLIO XBUS DMA");
trg=src;
len=_madam_Peek(0x544);
//if(len&3)_3do_DPrint("Overflow Err!!! - see CLIO XBUS DMA");
cregs[0x400]&=~0x80;
if((cregs[0x404])&0x200)
{
ptr=0;
while(len>=0)
{
b3=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
//ptr++;
b2=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
b1=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
b0=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
_mem_write8(trg,b0);
_mem_write8(trg+1,b1);
_mem_write8(trg+2,b2);
_mem_write8(trg+3,b3);
trg+=4;
len-=4;
ptr+=4;
}
//CCdRom::ClearDataPoll(CMadam::Peek(0x544));
//CCdRom::ClearDataPoll();
cregs[0x400]|=0x80;
}
else
{
ptr=0;
while(len>=0)
{
b3=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
//ptr++;
b2=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
b1=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
b0=_xbus_GetDataFIFO();
//st=CXBUS::GetPoll();
_mem_write8(trg,b0);
_mem_write8(trg+1,b1);
_mem_write8(trg+2,b2);
_mem_write8(trg+3,b3);
trg+=4;
len-=4;
ptr+=4;
}
//CCdRom::ClearDataPoll(CMadam::Peek(0x544));
//CCdRom::ClearDataPoll();
cregs[0x400]|=0x80;
}
len=0xFFFFFFFC;
_madam_Poke(0x544,len);
//event.type = SDL_USEREVENT;
//event.user.code = CREATEFIQ|29;
//SDL_PushEvent(&event);
//CFE::FE_PushEvent(&event);
_clio_GenerateFiq(1<<29,0);
return;
}//XBDMA transfer
#ifdef FIFODBG
else
{
sprintf(str,"_Fifo304 inChan=");
CDebug::DPrint(str);
for(i=0;i<13;i++)
{
if(val&(1<<i))
{
sprintf(str,"%d ",i);
CDebug::DPrint(str);
}
}
sprintf(str,"outChan=");
CDebug::DPrint(str);
for(i=0;i<4;i++)
{
if(val&(1<<(i+16)))
{
sprintf(str,"%d ",i);
CDebug::DPrint(str);
}
}
sprintf(str,"\n");
CDebug::DPrint(str);
}
#endif
}
void _clio_Init(int ResetReson)
{
for(int i=0;i<32768;i++)
cregs[i]=0;
//cregs[8]=240;
cregs[0x0028]=ResetReson;
cregs[0x0400]=0x80;
cregs[0x220]=64;
Mregs=_madam_GetRegs();
}
unsigned short __fastcall _clio_EIFIFO(unsigned short channel)
{
unsigned int val,base,mask;
base=0x400+(channel*16);
mask=1<<channel;
if(FIFOI[channel].StartAdr!=0)//channel enabled
{
if( (FIFOI[channel].StartLen-PTRI[channel])>0 )
{
val=_mem_read16( ((FIFOI[channel].StartAdr+PTRI[channel])^2) );
PTRI[channel]+=2;
}
else
{
PTRI[channel]=0;
_clio_GenerateFiq(1<<(channel+16),0);//generate fiq
if(FIFOI[channel].NextAdr!=0)// reload enabled see patent WO09410641A1, 49.16
{
FIFOI[channel].StartAdr=FIFOI[channel].NextAdr;
FIFOI[channel].StartLen=FIFOI[channel].NextLen;
val=_mem_read16(((FIFOI[channel].StartAdr+PTRI[channel])^2)); //get the value!!!
PTRI[channel]+=2;
}
else
{
FIFOI[channel].StartAdr=0;
val=0;
}
}
}
else
{
val=0;
// JMK SEZ: What is this? It was commented out along with this whole "else"
// block, but I had to bring this else block back from the dead
// in order to initialize val appropriately.
// _clio_GenerateFiq(1<<(channel+16),0);
}
return val;
}
void __fastcall _clio_EOFIFO(unsigned short channel, unsigned short val)
{
unsigned int base;
unsigned int mask;
base=0x500+(channel*16);
mask=1<<(channel+16);
if(FIFOO[channel].StartAdr!=0)//channel enabled
{
if( (FIFOO[channel].StartLen-PTRO[channel])>0 )
{
_mem_write16(((FIFOO[channel].StartAdr+PTRO[channel])^2),val);
PTRO[channel]+=2;
}
else
{
PTRO[channel]=0;
_clio_GenerateFiq(1<<(channel+12),0);//generate fiq
if(FIFOO[channel].NextAdr!=0) //reload enabled?
{
FIFOO[channel].StartAdr=FIFOO[channel].NextAdr;
FIFOO[channel].StartLen=FIFOO[channel].NextLen;
}
else
{
FIFOO[channel].StartAdr=0;
}
}
}
}
unsigned short __fastcall _clio_EIFIFONI(unsigned short channel)
{
unsigned int base;
base=0x400+(channel*16);
return _mem_read16(((FIFOI[channel].StartAdr+PTRI[channel])^2));
}
unsigned short __fastcall _clio_GetEIFIFOStat(unsigned char channel)
{
unsigned int mask;
mask=1<<channel;
//if(cregs[0x304]&mask)//channel enabled
if( FIFOI[channel].StartAdr!=0 )
{
//return 1;
//return (FIFOI[channel].StartLen-PTRI[channel]);
return 2;// 2fixme
}
return 0;
}
unsigned short __fastcall _clio_GetEOFIFOStat(unsigned char channel)
{
unsigned int mask;
mask=1<<(channel+16);
//if(cregs[0x304]&mask)//channel enabled
if( FIFOO[channel].StartAdr!=0 )
return 1;
return 0;
}
void _clio_SetFIFO(unsigned int adr, unsigned int val)
{
if((adr&0x500)==0x400)
{
switch (adr&0xf)
{
case 0: FIFOI[(adr>>4)&0xf].StartAdr=val;
FIFOI[(adr>>4)&0xf].NextAdr=0;//see patent WO09410641A1, 46.25
#ifdef FIFODBG
sprintf(str,"SetInFIFO chan=%x StartAdr=%x\n",(adr>>4)&0xf,val);CDebug::DPrint(str);
#endif
return;
case 4: FIFOI[(adr>>4)&0xf].StartLen=val+4;
if(val==0)
FIFOI[(adr>>4)&0xf].StartLen=0;
FIFOI[(adr>>4)&0xf].NextLen=0;//see patent WO09410641A1, 46.25
#ifdef FIFODBG
sprintf(str,"SetInFIFO chan=%x StartLen=%x\n",(adr>>4)&0xf,val+4);CDebug::DPrint(str);
#endif
return;
case 8: FIFOI[(adr>>4)&0xf].NextAdr=val;
#ifdef FIFODBG
sprintf(str,"SetInFIFO chan=%x NextAdr=%x\n",(adr>>4)&0xf,val);CDebug::DPrint(str);
#endif
return;
case 0xc:
if(val!=0)
FIFOI[(adr>>4)&0xf].NextLen=val+4;
else
FIFOI[(adr>>4)&0xf].NextLen=0;
#ifdef FIFODBG
sprintf(str,"SetInFIFO chan=%x NextLen=%x\n",(adr>>4)&0xf,val+4);CDebug::DPrint(str);
#endif
return;
}
}
else
{
#ifdef FIFODBG
sprintf(str,"SetOutFIFO chan=%x addr=%x var=%x\n",(adr>>4)&0xf,val,adr&0xf);
CDebug::DPrint(str);
#endif
switch (adr&0xf)
{
case 0: FIFOO[(adr>>4)&0xf].StartAdr=val;return;
case 4: FIFOO[(adr>>4)&0xf].StartLen=val+4;return;
case 8: FIFOO[(adr>>4)&0xf].NextAdr=val;return;
case 0xc:FIFOO[(adr>>4)&0xf].NextLen=val+4;return;
}
}
}
void _clio_Reset()
{
int i;
for(i=0;i<65536;i++)
cregs[i]=0;
}
unsigned int _clio_FIFOStruct(unsigned int addr)
{
if((addr&0x500)==0x400)
{
//printf("SetOutFIFO chan=%x addr=%x var=%x\n",(adr>>4)&0xf,val,adr&0xf);
switch (addr&0xf)
{
case 0:
#ifdef FIFODBG
sprintf(str,"_GetInFIFO chan=%x StartAdr=%x\n",(addr>>4)&0xf,FIFOI[(addr>>4)&0xf].StartAdr+PTRI[(addr>>4)&0xf]);CDebug::DPrint(str);
#endif
return FIFOI[(addr>>4)&0xf].StartAdr+PTRI[(addr>>4)&0xf];
case 4:
#ifdef FIFODBG
sprintf(str,"_GetInFIFO chan=%x StartLen=%x\n",(addr>>4)&0xf,FIFOI[(addr>>4)&0xf].StartLen-PTRI[(addr>>4)&0xf]);CDebug::DPrint(str);
#endif
return FIFOI[(addr>>4)&0xf].StartLen-PTRI[(addr>>4)&0xf];
case 8:
#ifdef FIFODBG
sprintf(str,"_GetInFIFO chan=%x NextAdr=%x\n",(addr>>4)&0xf,FIFOI[(addr>>4)&0xf].NextAdr);CDebug::DPrint(str);
#endif
return FIFOI[(addr>>4)&0xf].NextAdr;
case 0xc:
#ifdef FIFODBG
sprintf(str,"_GetInFIFO chan=%x NextLen=%x\n",(addr>>4)&0xf,FIFOI[(addr>>4)&0xf].NextLen);CDebug::DPrint(str);
#endif
return FIFOI[(addr>>4)&0xf].NextLen;
}
}
else
{
//printf("SetInFIFO chan=%x addr=%x var=%x\n",(adr>>4)&0xf,val,adr&0xf);
switch (addr&0xf)
{
case 0: return FIFOO[(addr>>4)&0xf].StartAdr+PTRO[(addr>>4)&0xf];
case 4: return FIFOO[(addr>>4)&0xf].StartLen-PTRO[(addr>>4)&0xf];
case 8: return FIFOO[(addr>>4)&0xf].NextAdr;
case 0xc:return FIFOO[(addr>>4)&0xf].NextLen;
}
}
return 0; // ??? it's possible?
}
+58
View File
@@ -0,0 +1,58 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// Clio.h: interface for the CClio class.
//
//////////////////////////////////////////////////////////////////////
#ifndef CLIO_3DO_HEADER
#define CLIO_3DO_HEADER
int _clio_v0line();
int _clio_v1line();
bool __fastcall _clio_NeedFIQ();
unsigned int _clio_FIFOStruct(unsigned int addr);
void _clio_Reset();
void _clio_SetFIFO(unsigned int adr, unsigned int val);
unsigned short __fastcall _clio_GetEOFIFOStat(unsigned char channel);
unsigned short __fastcall _clio_GetEIFIFOStat(unsigned char channel);
unsigned short __fastcall _clio_EIFIFONI(unsigned short channel);
void __fastcall _clio_EOFIFO(unsigned short channel, unsigned short val);
unsigned short __fastcall _clio_EIFIFO(unsigned short channel);
void _clio_Init(int ResetReson);
void __fastcall _clio_DoTimers();
unsigned int __fastcall _clio_Peek(unsigned int addr);
int __fastcall _clio_Poke(unsigned int addr, unsigned int val);
void __fastcall _clio_UpdateVCNT(int line, int halfframe);
void __fastcall _clio_GenerateFiq(unsigned int reason1, unsigned int reason2);
unsigned int _clio_GetTimerDelay();
unsigned int _clio_SaveSize();
void _clio_Save(void *buff);
void _clio_Load(void *buff);
#endif
+1294
View File
File diff suppressed because it is too large. Load diff
+50
View File
@@ -0,0 +1,50 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// DSP.h: interface for the CDSP class.
//
//////////////////////////////////////////////////////////////////////
#ifndef DSP_3DO_HEADER
#define DSP_3DO_HEADER
unsigned int _dsp_Loop();
unsigned short __fastcall _dsp_ReadIMem(unsigned short addr);
void __fastcall _dsp_WriteIMem(unsigned short addr, unsigned short val);
void __fastcall _dsp_WriteMemory(unsigned short addr,unsigned short val);
void __fastcall _dsp_SetRunning(bool val);
void __fastcall _dsp_ARMwrite2sema4(unsigned int val);
unsigned int _dsp_ARMread2sema4(void);
void _dsp_Init();
void _dsp_Reset();
unsigned int _dsp_SaveSize();
void _dsp_Save(void *buff);
void _dsp_Load(void *buff);
#endif
+110
View File
@@ -0,0 +1,110 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// DiagPort.cpp: implementation of the DiagPort class.
//
//////////////////////////////////////////////////////////////////////
#include "freedoconfig.h"
#include "DiagPort.h"
static unsigned short SNDDebugFIFO0;
static unsigned short SNDDebugFIFO1;
static unsigned short RCVDebugFIFO0;
static unsigned short RCVDebugFIFO1;
static unsigned short GetPTR;
static unsigned short SendPTR;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void __fastcall _diag_Send(unsigned int val)
{
if(GetPTR!=16)
{
GetPTR=16;
SendPTR=16;
SNDDebugFIFO0=0;
SNDDebugFIFO1=0;
}
SNDDebugFIFO0|=(val&1)<<(SendPTR-1);
SNDDebugFIFO1|=((val&1)>>1)<<(SendPTR-1);
SendPTR--;
if(SendPTR==0)
{
SendPTR=16;
}
}
unsigned int __fastcall _diag_Get()
{
unsigned int val;
if(SendPTR!=16)
{
GetPTR=16;
SendPTR=16;
}
val=0;
val=((RCVDebugFIFO0>>(GetPTR-1))&0x1);
val|=((RCVDebugFIFO1>>(GetPTR-1))&0x1)<<0x1;
GetPTR--;
/* if(GetPTR>0)
{
RCVDebugFIFO0=RCVDebugFIFO0>>1;
RCVDebugFIFO1=RCVDebugFIFO1>>1;
GetPTR--;
val=RCVDebugFIFO0&0x1;
val|=(RCVDebugFIFO1&0x1)<<0x1;
}
*/
if(GetPTR==0) GetPTR=16;
return val;
}
void _diag_Init(int testcode)
{
SNDDebugFIFO0=0;
SNDDebugFIFO1=0;
GetPTR=16;
SendPTR=16;
if(testcode>=0)
{
testcode ^= 0xFF;
testcode |= 0xA000;
} else testcode=0;
RCVDebugFIFO0=testcode;
RCVDebugFIFO1=testcode;
}
+37
View File
@@ -0,0 +1,37 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// DiagPort.h: interface for the DiagPort class.
//
//////////////////////////////////////////////////////////////////////
#ifndef _DIAG_PORT_HEADER_DEFINITION_
#define _DIAG_PORT_HEADER_DEFINITION_
void _diag_Init(int testcode);
unsigned int __fastcall _diag_Get();
void __fastcall _diag_Send(unsigned int val);
#endif
+1371
View File
File diff suppressed because it is too large. Load diff
+66
View File
@@ -0,0 +1,66 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#ifndef ISO_3DO_HEADER
#define ISO_3DO_HEADER 0x00000001
#define XBP_INIT 0 //plugin init, returns plugin version
#define XBP_RESET 1 //plugin reset with parameter(image path)
#define XBP_SET_COMMAND 2 //XBUS
#define XBP_FIQ 3 //check interrupt form device
#define XBP_SET_DATA 4 //XBUS
#define XBP_GET_DATA 5 //XBUS
#define XBP_GET_STATUS 6 //XBUS
#define XBP_SET_POLL 7 //XBUS
#define XBP_GET_POLL 8 //XBUS
#define XBP_SELECT 9 //selects device by Opera
#define XBP_RESERV 10 //reserved reading from device
#define XBP_DESTROY 11 //plugin destroy
#define XBP_GET_SAVESIZE 19 //save support from emulator side
#define XBP_GET_SAVEDATA 20
#define XBP_SET_SAVEDATA 21
#ifdef XBUS_EXPORTS
#define XBUS_API __declspec(dllexport)
#else
#define XBUS_API __declspec(dllimport)
#endif
/*extern "C"
{
XBUS_API void* _xbplug_MainDevice(int proc, void* data);
#ifdef XBUS_EXPORTS
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
);
#endif
};
#ifndef XBUS_EXPORTS
#pragma comment(lib, "IsoXBUS.lib")
#endif*/
#endif
+2880
View File
File diff suppressed because it is too large. Load diff
+57
View File
@@ -0,0 +1,57 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// Madam.h: interface for the CMadam class.
//
//////////////////////////////////////////////////////////////////////
#ifndef MADAM_3DO_HEADER
#define MADAM_3DO_HEADER
#define FSM_IDLE 1
#define FSM_INPROCESS 2
#define FSM_SUSPENDED 3
unsigned int Get_madam_FSM();
void Set_madam_FSM(unsigned int val);
void _madam_SetMapping(unsigned int flag);
void _madam_Reset();
unsigned int _madam_GetCELCycles();
unsigned int * _madam_GetRegs();
int _madam_HandleCEL(); //!!!~!
void _madam_Init(unsigned char* memory);
void _madam_KeyPressed(unsigned char* data, unsigned int num);
void __fastcall _madam_Poke(unsigned int addr, unsigned int val);
unsigned int __fastcall _madam_Peek(unsigned int addr);
unsigned int _madam_SaveSize();
void _madam_Save(void *buff);
void _madam_Load(void *buff);
//void _madam_PrepToRendering();
//bool __fastcall _madam_VRAMBusy(unsigned int addr, int size);
#endif
+65
View File
@@ -0,0 +1,65 @@
#www.freedo.org
#The first and only working 3DO multiplayer emulator.
#
#The FreeDO licensed under modified GNU LGPL, with following notes:
#
#* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
#* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
# of the sources, or any other material published by FreeDO have to be accompanied with full credits.
#* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
# or any other material published by FreeDO is strictly forbidden without owners approval.
#
#The above notes are taking precedence over GNU LGPL in conflicting situations.
#
#Project authors:
#
#Alexander Troosh
#Maxim Grishin
#Allen Wright
#John Sammons
#Felix Lazarev
##########################################################################################################################
#source files
SRC = Clio.cpp Madam.cpp bitop.cpp arm.cpp DSP.cpp Iso.cpp quarz.cpp SPORT.cpp vdlp.cpp XBUS.cpp DiagPort.cpp _3do_sys.cpp
OBJ = $(SRC:.cpp=.o)
OUT = libfreedo.a
#include dirs
INCLUDES = -I. -I/usr/local/include
#C++ flags
CCFLAGS = -g
#compiler
CCC = g++
#libraries
LIBS = -L/usr/local/lib
#compile flags
LDFLAGS = -g
.SUFFIXES: .cpp
default: dep $(OUT)
.cpp.o:
$(CCC) $(INCLUDES) $(CCFLAGS) -c $< -o $@
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
depend: dep
dep:
makedepend -- $(CFLAGS) -- $(INCLUDES) $(SRC)
clean:
rm -f $(OBJ) $(OUT) Makefile.bak Makefile~
+153
View File
@@ -0,0 +1,153 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// SPORT.cpp: implementation of the SPORT class.
//
//////////////////////////////////////////////////////////////////////
#include "freedoconfig.h"
#include "SPORT.h"
#include "arm.h"
#include <memory.h>
#include "freedocore.h"
extern _ext_Interface io_interface;
static unsigned int gSPORTCOLOR;
static unsigned int gSPORTSOURCE=0;
static unsigned int gSPORTDESTINATION=0;
static unsigned char* VRAM;
unsigned int _sport_SaveSize()
{
return 12;
}
void _sport_Save(void *buff)
{
((unsigned int*)buff)[0]=gSPORTCOLOR;
((unsigned int*)buff)[1]=gSPORTSOURCE;
((unsigned int*)buff)[2]=gSPORTDESTINATION;
}
void _sport_Load(void *buff)
{
gSPORTCOLOR=((unsigned int*)buff)[0];
gSPORTSOURCE=((unsigned int*)buff)[1];
gSPORTDESTINATION=((unsigned int*)buff)[2];
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//static AString str;
void _sport_Init(unsigned char *vmem)
{
VRAM=vmem;
}
int __fastcall _sport_SetSource(unsigned int index) //take source for SPORT
{
gSPORTSOURCE=(index<<7);
return 0;
}
void __fastcall _sport_WriteAccess(unsigned int index, unsigned int mask)
{
int i;
unsigned int tmp,ctmp;
if((index & ~0x1FFF)==0x4000) //SPORT flash write
{
index&=0x7ff;
index<<=7;
if(mask == 0xFFFFffff)
{
for(i=0;i<512;i++)
{
((unsigned int*)VRAM)[index+i]=gSPORTCOLOR;
}
}
else // mask is not 0xFFFFffff
{
for(i=0;i<512;i++)
{
tmp=((unsigned int*)VRAM)[index+i];
tmp=((tmp^gSPORTCOLOR)&mask)^gSPORTCOLOR;
((unsigned int*)VRAM)[index+i]=tmp;
}
}
if(!RESSCALE)return;
memcpy(&((unsigned int*)VRAM)[index+1024*256], &((unsigned int*)VRAM)[index], 2048);
memcpy(&((unsigned int*)VRAM)[index+2*1024*256], &((unsigned int*)VRAM)[index], 2048);
memcpy(&((unsigned int*)VRAM)[index+3*1024*256], &((unsigned int*)VRAM)[index], 2048);
return;
}
if(!(index & ~0x1FFF)) //SPORT copy page
{
gSPORTDESTINATION=(index &0x7ff)<<7;
if(mask == 0xFFFFffff)
{
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION],&((unsigned int*)VRAM)[gSPORTSOURCE],512*4);
if(!RESSCALE)return;
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION+1024*256], &((unsigned int*)VRAM)[gSPORTSOURCE+1024*256], 2048);
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION+2*1024*256], &((unsigned int*)VRAM)[gSPORTSOURCE+2*1024*256], 2048);
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION+3*1024*256], &((unsigned int*)VRAM)[gSPORTSOURCE+3*1024*256], 2048);
}
else // mask != 0xFFFFffff
{
for(i=0;i<512;i++)
{
tmp=((unsigned int*)VRAM)[gSPORTDESTINATION+i];
ctmp=((unsigned int*)VRAM)[gSPORTSOURCE+i];
tmp=((tmp^ctmp)&mask)^ctmp;
((unsigned int*)VRAM)[gSPORTDESTINATION+i]=tmp;
}
if(!RESSCALE)return;
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION+1024*256], &((unsigned int*)VRAM)[gSPORTDESTINATION], 2048);
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION+2*1024*256], &((unsigned int*)VRAM)[gSPORTDESTINATION], 2048);
memcpy(&((unsigned int*)VRAM)[gSPORTDESTINATION+3*1024*256], &((unsigned int*)VRAM)[gSPORTDESTINATION], 2048);
}
return;
}
if((index & ~0x1FFF)==0x2000) //SPORT set color!!!
{
gSPORTCOLOR=mask;
return;
}
// io_interface(EXT_DEBUG_PRINT,(void*)str.print("::::SPORT:::: Unknown write, Index=0x%8.8X, Mask=0x%8.8X",index, mask).CStr());
}
+43
View File
@@ -0,0 +1,43 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// SPORT.h: interface for the SPORT class.
//
//////////////////////////////////////////////////////////////////////
#ifndef SPORT_3DO_HEADER
#define SPORT_3DO_HEADER
void _sport_Init(unsigned char *vmem);
//take source for SPORT
int __fastcall _sport_SetSource(unsigned int index);
void __fastcall _sport_WriteAccess(unsigned int index, unsigned int mask);
unsigned int _sport_SaveSize();
void _sport_Save(void *buff);
void _sport_Load(void *buff);
#endif
+43
View File
@@ -0,0 +1,43 @@
#include "Worker.h"
#include <windows.h>
#include <process.h>
unsigned int __stdcall ThreadEntry(void* classInstance);
Worker::Worker(void (*workerFunction)(void*), void* workerFunctionArgument)
{
this->startEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
this->threadHandle = (HANDLE)_beginthreadex( NULL, 0, ThreadEntry, this, 0, &this->threadId );
this->internalWorkerFunction = workerFunction;
this->internalWorkerFunctionArgument = workerFunctionArgument;
}
Worker::~Worker()
{
}
void Worker::Run()
{
SetEvent(this->startEvent);
}
void Worker::Wait()
{
WaitForSingleObject(this->threadHandle, INFINITE);
}
////////////////////////////
void Worker::_ThreadFunction()
{
// Wait until we're told to start.
WaitForSingleObject(this->startEvent, INFINITE);
this->internalWorkerFunction(this->internalWorkerFunctionArgument);
}
unsigned int __stdcall ThreadEntry(void* classInstance)
{
((Worker*)classInstance)->_ThreadFunction();
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef __4DO_WORKER_HEADER
#define __4DO_WORKER_HEADER
#include <windows.h>
class Worker
{
public:
Worker(void (*workerFunction)(void*), void* workerFunctionArgument);
~Worker();
void Run();
void Wait();
void _ThreadFunction();
private:
HANDLE threadHandle;
unsigned int threadId;
HANDLE startEvent;
void (*internalWorkerFunction)(void*);
void* internalWorkerFunctionArgument;
};
#endif
+322
View File
@@ -0,0 +1,322 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// XBUS.cpp: implementation of the CXBUS class.
//
//////////////////////////////////////////////////////////////////////
#include "freedoconfig.h"
//#include "astring.h"
#include "XBUS.h"
#include "Clio.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#pragma pack(push,1)
struct XBUSDatum
{
unsigned char XBSEL;
unsigned char XBSELH;
unsigned char POLF;
unsigned char POLDEVF;
unsigned char STDEVF[255]; //status of devices
unsigned char STLENF; //pointer in fifo
unsigned char CmdF[7];
unsigned char CmdPtrF;
};
#pragma pack(pop)
#define XBSEL xbus.XBSEL
#define XBSELH xbus.XBSELH
#define POLF xbus.POLF
#define POLDEVF xbus.POLDEVF
#define STDEVF xbus.STDEVF
#define STLENF xbus.STLENF
#define CmdF xbus.CmdF
#define CmdPtrF xbus.CmdPtrF
static XBUSDatum xbus;
static _xbus_device xdev[16];
#define POLSTMASK 0x01
#define POLDTMASK 0x02
#define POLMAMASK 0x04
#define POLREMASK 0x08
#define POLST 0x10
#define POLDT 0x20
#define POLMA 0x40
#define POLRE 0x80
void ExecuteCommandF();
void _xbus_SetCommandFIFO(unsigned int val)
{
if(xdev[XBSEL])
{
(*xdev[XBSEL])(XBP_SET_COMMAND,(void*)val);
if((*xdev[XBSEL])(XBP_FIQ,NULL)) _clio_GenerateFiq(4,0);
}
else if(XBSEL==0xf)
{
if (CmdPtrF<7)
{
CmdF[CmdPtrF]=(unsigned char)val;
CmdPtrF++;
}
if(CmdPtrF>=7)
{
ExecuteCommandF();
CmdPtrF=0;
}
}
}
unsigned int _xbus_GetDataFIFO()
{
if(xdev[XBSEL])
{
return (uintptr_t)(*xdev[XBSEL])(XBP_GET_DATA,NULL);
}
else
return 0;
}
unsigned int _xbus_GetPoll()
{
unsigned int res;
if(XBSEL==0xf)
res=POLF;
else if(xdev[XBSEL])res=(uintptr_t)(*xdev[XBSEL])(XBP_GET_POLL, NULL);
else res=0x30;
if(XBSELH&0x80)
res&=0xf;
return res;
}
unsigned int _xbus_GetRes()
{
if(xdev[XBSEL])return (uintptr_t)(*xdev[XBSEL])(XBP_RESERV, NULL);
return 0;
}
void ExecuteCommandF()
{
if(CmdF[0]==0x83)
{
STLENF=12;
STDEVF[0]=0x83;
STDEVF[1]=0x01;
STDEVF[2]=0x01;
STDEVF[3]=0x01;
STDEVF[4]=0x01;
STDEVF[5]=0x01;
STDEVF[6]=0x01;
STDEVF[7]=0x01;
STDEVF[8]=0x01;
STDEVF[9]=0x01;
STDEVF[10]=0x01;
STDEVF[11]=0x01;
POLDEVF|=POLST;
}
if(((POLDEVF&POLST) && (POLDEVF&POLSTMASK)) || ((POLDEVF&POLDT) && (POLDEVF&POLDTMASK)))
{
_clio_GenerateFiq(4,0);
}
}
unsigned int _xbus_GetStatusFIFO()
{
unsigned int res=0;
if(xdev[XBSEL])
{
res=(uintptr_t)(*xdev[XBSEL])(XBP_GET_STATUS,NULL);
}
else if(XBSEL==0xf)
{
if(STLENF>0)
{
res=STDEVF[0];
STLENF--;
if(STLENF>0)
{
for(int i=0;i<STLENF;i++)
STDEVF[i]=STDEVF[i+1];
}
else
{
POLDEVF&=~POLST;
}
}
return res;
}
return res;
}
void _xbus_SetDataFIFO(unsigned int val)
{
if(xdev[XBSEL])(*xdev[XBSEL])(XBP_SET_DATA,(void*)val);
}
void _xbus_SetPoll(unsigned int val)
{
if(XBSEL==0xf)
{
POLF&=0xF0;
POLF|=(val&0xf);
}
if(xdev[XBSEL])
{
(*xdev[XBSEL])(XBP_SET_POLL,(void*)val);
if((*xdev[XBSEL])(XBP_FIQ,NULL)) _clio_GenerateFiq(4,0);
}
}
void _xbus_SetSEL(unsigned int val)
{
XBSEL=(unsigned char)val&0xf;
XBSELH=(unsigned char)val&0xf0;
}
void _xbus_Init(_xbus_device zero_dev)
{
int i;
POLF=0xf;
for(i=0;i<15;i++)
{
xdev[i]=NULL;
}
_xbus_Attach(zero_dev);
}
int _xbus_Attach(_xbus_device dev)
{
int i;
for(i=0;i<16;i++)if(!xdev[i])break;
if(i==16)return -1;
xdev[i]=dev;
(*xdev[i])(XBP_INIT,NULL);
return i;
}
void _xbus_DevLoad(int dev, const char * name)
{
(*xdev[dev])(XBP_RESET,(void*)name);
}
void _xbus_DevEject(int dev)
{
(*xdev[dev])(XBP_RESET,NULL);
}
void _xbus_Destroy()
{
for(int i=0;i<16;i++)if(xdev[i]){(*xdev[i])(XBP_DESTROY,NULL);xdev[i]=NULL;}
}
unsigned int _xbus_SaveSize()
{
unsigned int tmp=sizeof(XBUSDatum);
int i;
tmp+=16*4;
for(i=0;i<15;i++)
{
if(!xdev[i])continue;
tmp+=(uintptr_t)(*xdev[i])(XBP_GET_SAVESIZE,NULL);
}
return tmp;
}
#include <memory.h>
void _xbus_Save(void *buff)
{
int i,off,j,tmp;
memcpy(buff,&xbus,sizeof(XBUSDatum));
j=off=sizeof(XBUSDatum);
off+=16*4;
for(i=0;i<15;i++)
{
if(!xdev[i])
{
tmp=0;
memcpy(&((unsigned char*)buff)[j+i*4],&tmp,4);
}
else
{
(*xdev[i])(XBP_GET_SAVEDATA,&((unsigned char*)buff)[off]);
memcpy(&((unsigned char*)buff)[j+i*4],&off,4);
off+=(uintptr_t)(*xdev[i])(XBP_GET_SAVESIZE,NULL);
}
}
}
void _xbus_Load(void *buff)
{
//AString tstr;
int i,offd,j;
j=sizeof(XBUSDatum);
memcpy(&xbus,buff,j);
for(i=0;i<15;i++)
{
memcpy(&offd,&((unsigned char*)buff)[j+i*4],4);
if(xdev[i])
{
if(!offd)
{
(*xdev[i])(XBP_RESET,NULL);
}
else
{
(*xdev[i])(XBP_SET_SAVEDATA,&((unsigned char*)buff)[offd]);
}
}
}
}
+55
View File
@@ -0,0 +1,55 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// XBUS.h: interface for the CXBUS class.
//
//////////////////////////////////////////////////////////////////////
#ifndef XBUS_3DO_HEADER
#define XBUS_3DO_HEADER
#include "IsoXBUS.h"
//interface functions
typedef void* (*_xbus_device)(int, void*);
int _xbus_Attach(_xbus_device dev);
void _xbus_DevLoad(int dev, const char * name); //!!!
void _xbus_DevEject(int dev); //!!!
void _xbus_Init(_xbus_device zero_dev);
void _xbus_Destroy();
void _xbus_SetSEL(unsigned int val);
void _xbus_SetPoll(unsigned int val);
void _xbus_SetCommandFIFO(unsigned int val);
void _xbus_SetDataFIFO(unsigned int val);
unsigned int _xbus_GetStatusFIFO();
unsigned int _xbus_GetRes();
unsigned int _xbus_GetPoll();
unsigned int _xbus_GetDataFIFO();
unsigned int _xbus_SaveSize();
void _xbus_Save(void *buff);
void _xbus_Load(void *buff);
#endif
+333
View File
@@ -0,0 +1,333 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#include "freedoconfig.h"
#include "freedocore.h"
#include "stdafx.h"
#include "arm.h"
#include "vdlp.h"
#include "DSP.h"
#include "Clio.h"
#include "frame.h"
#include "Madam.h"
#include "SPORT.h"
#include "XBUS.h"
#include "DiagPort.h"
#include "quarz.h"
#ifdef _WIN32
#include <windows.h>
#endif
_ext_Interface io_interface;
extern void* Getp_NVRAM();
extern void* Getp_ROMS();
extern void* Getp_RAMS();
extern int ARM_CLOCK;
extern int THE_ARM_CLOCK;
__inline uint32 _bswap(uint32 x)
{
return (x>>24) | ((x>>8)&0x0000FF00L) | ((x&0x0000FF00L)<<8) | (x<<24);
}
extern void* _xbplug_MainDevice(int proc, void* data);
int _3do_Init()
{
unsigned char *Memory;
unsigned char *rom;
Memory=_arm_Init();
io_interface(EXT_READ_ROMS,Getp_ROMS());
rom=(unsigned char*)Getp_ROMS();
for(int i=(1024*1024*2)-4;i>=0;i-=4) *(int *)(rom+i)=_bswap(*(int *)(rom+i));
_vdl_Init(Memory+0x200000); // Visible only VRAM to it
_sport_Init(Memory+0x200000); // Visible only VRAM to it
_madam_Init(Memory);
_xbus_Init(_xbplug_MainDevice);
_clio_Init(0x40); // 0x40 for start from 3D0-CD, 0x01/0x02 from PhotoCD ?? (NO use 0x40/0x02 for BIOS test)
_dsp_Init();
_frame_Init();
_diag_Init(-1); // Select test, use -1 -- if d'nt need tests
/*
00 DIAGNOSTICS TEST (run of test: 1F, 24, 25, 32, 50, 51, 60, 61, 62, 68, 71, 75, 80, 81, 90)
01 AUTO-DIAG TEST (run of test: 1F, 24, 25, 32, 50, 51, 60, 61, 62, 68, 80, 81, 90)
12 DRAM1 DATA TEST
1A DRAM2 DATA TEST
1E EARLY RAM TEST
1F RAM DATA TEST
22 VRAM1 DATA TEST
24 VRAM1 FLASH TEST
25 VRAM1 SPORT TEST
32 SRAM DATA TEST
50 MADAM TEST
51 CLIO TEST
60 CD-ROM POLL TEST
61 CD-ROM PATH TEST
62 CD-ROM READ TEST ???
63 CD-ROM AutoAdjustValue TEST
67 CD-ROM#2 AutoAdjustValue TEST
68 DEV#15 POLL TEST
71 JOYPAD1 PRESS TEST
75 JOYPAD1 AUDIO TEST
80 SIN WAVE TEST
81 MUTING TEST
90 COLORBAR
F0 CHECK TESTTOOL ???
F1 REVISION TEST
FF TEST END (halt)
*/
_xbus_DevLoad(0,NULL);
_qrz_Init();
return 0;
}
VDLFrame *curr_frame;
bool scipframe;
void _3do_InternalFrame(int cicles)
{
int line;
_qrz_PushARMCycles(cicles);
if(_qrz_QueueDSP())
{
io_interface(EXT_PUSH_SAMPLE,(void*)_dsp_Loop());
}
if(_qrz_QueueTimer())_clio_DoTimers();
if(_qrz_QueueVDL())
{
line=_qrz_VDCurrLine();
_clio_UpdateVCNT(line, _qrz_VDHalfFrame());
if(!scipframe)_vdl_DoLineNew(line,curr_frame);
if(line==16 && scipframe) io_interface(EXT_FRAMETRIGGER_MT,NULL);
if(line==_clio_v0line())
{
_clio_GenerateFiq(1<<0,0);
}
if(line==_clio_v1line())
{
_clio_GenerateFiq(1<<1,0);
_madam_KeyPressed((unsigned char*)io_interface(EXT_GETP_PBUSDATA,NULL),(intptr_t)io_interface(EXT_GET_PBUSLEN,NULL));
curr_frame->srcw=320;
curr_frame->srch=240;
if(!scipframe)curr_frame=(VDLFrame*)io_interface(EXT_SWAPFRAME,curr_frame);
}
}
}
void __fastcall _3do_Frame(VDLFrame *frame, bool __scipframe=false)
{
int i,cnt=0;
curr_frame=frame;
scipframe=__scipframe;
for(i=0;i<(12500000/60);)
{
if(Get_madam_FSM()==FSM_INPROCESS)
{
_madam_HandleCEL();
Set_madam_FSM(FSM_IDLE);
continue;
}
cnt+=_arm_Execute();
if(cnt>>4){_3do_InternalFrame(cnt);i+=cnt;cnt=0;}
}
}
void _3do_Destroy()
{
_arm_Destroy();
_xbus_Destroy();
}
unsigned int _3do_SaveSize()
{
unsigned int tmp;
tmp=_arm_SaveSize();
tmp+=_vdl_SaveSize();
tmp+=_dsp_SaveSize();
tmp+=_clio_SaveSize();
tmp+=_qrz_SaveSize();
tmp+=_sport_SaveSize();
tmp+=_madam_SaveSize();
tmp+=_xbus_SaveSize();
tmp+=16*4;
return tmp;
}
void _3do_Save(void *buff)
{
unsigned char *data=(unsigned char*)buff;
int *indexes=(int*)buff;
indexes[0]=0x97970101;
indexes[1]=16*4;
indexes[2]=indexes[1]+_arm_SaveSize();
indexes[3]=indexes[2]+_vdl_SaveSize();
indexes[4]=indexes[3]+_dsp_SaveSize();
indexes[5]=indexes[4]+_clio_SaveSize();
indexes[6]=indexes[5]+_qrz_SaveSize();
indexes[7]=indexes[6]+_sport_SaveSize();
indexes[8]=indexes[7]+_madam_SaveSize();
indexes[9]=indexes[8]+_xbus_SaveSize();
_arm_Save(&data[indexes[1]]);
_vdl_Save(&data[indexes[2]]);
_dsp_Save(&data[indexes[3]]);
_clio_Save(&data[indexes[4]]);
_qrz_Save(&data[indexes[5]]);
_sport_Save(&data[indexes[6]]);
_madam_Save(&data[indexes[7]]);
_xbus_Save(&data[indexes[8]]);
}
bool _3do_Load(void *buff)
{
unsigned char *data=(unsigned char*)buff;
int *indexes=(int*)buff;
if((unsigned int)indexes[0]!=0x97970101)return false;
_arm_Load(&data[indexes[1]]);
_vdl_Load(&data[indexes[2]]);
_dsp_Load(&data[indexes[3]]);
_clio_Load(&data[indexes[4]]);
_qrz_Load(&data[indexes[5]]);
_sport_Load(&data[indexes[6]]);
_madam_Load(&data[indexes[7]]);
_xbus_Load(&data[indexes[8]]);
return true;
}
//------------------------------------------------------------------------------
extern uint32 *profiling;
void _3do_OnSector(unsigned int sector)
{
io_interface(EXT_ON_SECTOR,(void*)sector);
}
void _3do_Read2048(void *buff)
{
io_interface(EXT_READ2048,(void*)buff);
}
unsigned int _3do_DiscSize()
{
return (uintptr_t)io_interface(EXT_GET_DISC_SIZE,NULL);
}
int __tex__scaler = 0;
int HightResMode=0;
int fixmode=0;
int speedfixes=0;
int sf=0;
int sdf=0;
int unknownflag11=0;
int jw=0;
int cnbfix=0;
FREEDOCORE_API void* __stdcall _freedo_Interface(int procedure, void *datum)
{
int line;
switch(procedure)
{
case FDP_INIT:
sf=5000000;
cnbfix=0;
io_interface=(_ext_Interface)datum;
return (void*)_3do_Init();
case FDP_DESTROY:
_3do_Destroy();
break;
case FDP_DO_EXECFRAME:
_3do_Frame((VDLFrame*)datum);
break;
case FDP_DO_EXECFRAME_MT:
_3do_Frame((VDLFrame*)datum, true);
break;
case FDP_DO_FRAME_MT:
line=0;
while(line<256)_vdl_DoLineNew(line++,(VDLFrame*)datum);
break;
case FDP_GET_SAVE_SIZE:
return (void*)_3do_SaveSize();
case FDP_DO_SAVE:
_3do_Save(datum);
break;
case FDP_DO_LOAD:
sf=0;
return (void*)_3do_Load(datum);
case FDP_GETP_NVRAM:
return Getp_NVRAM();
case FDP_GETP_RAMS:
return Getp_RAMS();
case FDP_GETP_ROMS:
return Getp_ROMS();
case FDP_GETP_PROFILE:
return profiling;
case FDP_FREEDOCORE_VERSION:
return (void*)0x20008;
case FDP_SET_ARMCLOCK:
THE_ARM_CLOCK=0;
ARM_CLOCK=(intptr_t)datum;
break;
case FDP_SET_TEXQUALITY:
__tex__scaler=(intptr_t)datum;
break;
// case FDP_SET_FIX_MODE:
// fixmode=(intptr_t)datum;
// break;
// case FDP_GET_FRAME_BITMAP:
// GetFrameBitmapParams* param = (GetFrameBitmapParams*)datum;
// Get_Frame_Bitmap(
// param->sourceFrame
// , param->destinationBitmap
// , param->destinationBitmapWidthPixels
// , param->bitmapCrop
// , param->copyWidthPixels
// , param->copyHeightPixels
// , param->addBlackBorder
// , param->copyPointlessAlphaByte
// , param->allowCrop
// , (ScalingAlgorithm)param->scalingAlgorithm
// , &param->resultingWidth
// , &param->resultingHeight);
// break;
};
return NULL;
}
+1896
View File
File diff suppressed because it is too large. Load diff
+55
View File
@@ -0,0 +1,55 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// CPU.h: interface for the CCPU class.
//
//////////////////////////////////////////////////////////////////////
#ifndef ARM_3DO_HEADER
#define ARM_3DO_HEADER
int __fastcall _arm_Execute();
void _arm_Reset();
void _arm_Destroy();
unsigned char * _arm_Init();
//for mas
void __fastcall _mem_write8(unsigned int addr, unsigned char val);
void __fastcall _mem_write16(unsigned int addr, unsigned short val);
void __fastcall _mem_write32(unsigned int addr, unsigned int val);
unsigned char __fastcall _mem_read8(unsigned int addr);
unsigned short __fastcall _mem_read16(unsigned int addr);
unsigned int __fastcall _mem_read32(unsigned int addr);
void __fastcall WriteIO(unsigned int addr, unsigned int val);
unsigned int __fastcall ReadIO(unsigned int addr);
void __fastcall SelectROM(int n);
unsigned int _arm_SaveSize();
void _arm_Save(void *buff);
void _arm_Load(void *buff);
#endif
+71
View File
@@ -0,0 +1,71 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#include "freedoconfig.h"
#include "bitop.h"
#include "arm.h"
uint32 BitReaderBig::Read()
{
const static uint8 mas[]={0,1,3,7,15,31,63,127,255};
uint32 retval=0;
int32 bitcnt=bitset;
if(!buf)return retval;
if((8-bitpoint)>bitset)
{
retval=_mem_read8(buf+(point^3));
retval>>=8-bitpoint-bitset;
retval&=mas[bitset];
bitpoint+=bitset;
return retval;
}
if(bitpoint)
{
retval=_mem_read8(buf+(point^3))&mas[8-bitpoint];
point++;
bitcnt-=8-bitpoint;
}
while(bitcnt>=8)
{
retval<<=8;
retval|=_mem_read8(buf+(point^3));
point++;
bitcnt-=8;
}
if(bitcnt)
{
retval<<=bitcnt;
retval|=_mem_read8(buf+(point^3))>>(8-bitcnt);
}
bitpoint=bitcnt;
return retval;
}
uint32 BitReaderBig::Read(uint8 bits)
{
SetBitRate(bits);
return Read();
}
+91
View File
@@ -0,0 +1,91 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#ifndef BITOPCLASS_DEFINITION_HEADER
#define BITOPCLASS_DEFINITION_HEADER
#include "types.h"
class BitReaderBig
{
protected:
uint32 buf;
uint32 point;
int32 bitpoint;
int32 bitset;
public:
BitReaderBig()
{
buf=0;
bitset=1;
point=0;
bitpoint=0;
};
BitReaderBig(uint32 buff)
{
buf=buff;
point=0;
bitpoint=0;
bitset=1;
};
void AttachBuffer(uint32 buff)
{
buf=buff;
point=0;
bitpoint=0;
};
void SetBitRate(uint8 bits)
{
bitset=bits;
if(bitset>32)bitset=32;
if(!bitset)bitset=1;
};
void SetPosition(uint32 bytepos, uint8 bitpos)
{
point=bytepos;
bitpoint=bitpos;
};
void SetPos(uint32 bitpos){SetPosition(bitpos>>3,bitpos&7);};
uint32 GetBytePose(){return point;};
uint32 Read();
uint32 Read(uint8 bits);
void Skip(uint32 bits)
{
bits+=bitpoint;
point+=(bits>>3);
bitpoint=bits&7;
};
};
#endif
+180
View File
@@ -0,0 +1,180 @@
#include "freedoconfig.h"
#include "freedocore.h"
#include "frame.h"
//#include "hqx.h"
unsigned char FIXED_CLUTR[32];
unsigned char FIXED_CLUTG[32];
unsigned char FIXED_CLUTB[32];
static void* tempBitmap;
static ScalingAlgorithm currentAlgorithm;
//void setCurrentAlgorithm(ScalingAlgorithm algorithm);
void _frame_Init()
{
tempBitmap = NULL;
//currentAlgorithm = ScalingAlgorithm::None;
for(int j = 0; j < 32; j++)
{
FIXED_CLUTR[j] = (unsigned char)(((j & 0x1f) << 3) | ((j >> 2) & 7));
FIXED_CLUTG[j] = FIXED_CLUTR[j];
FIXED_CLUTB[j] = FIXED_CLUTR[j];
}
}
void Get_Frame_Bitmap(
VDLFrame* sourceFrame,
void* destinationBitmap,
int destinationBitmapWidth,
BitmapCrop* bitmapCrop,
int copyWidth,
int copyHeight,
bool addBlackBorder,
bool copyPointlessAlphaByte,
bool allowCrop,
ScalingAlgorithm scalingAlgorithm,
int* resultingWidth,
int* resultingHeight)
{
//setCurrentAlgorithm(scalingAlgorithm);
float maxCropPercent = allowCrop ? .25f : 0;
int maxCropTall = (int)(copyHeight * maxCropPercent);
int maxCropWide = (int)(copyWidth * maxCropPercent);
bitmapCrop->top = maxCropTall;
bitmapCrop->left = maxCropWide;
bitmapCrop->right = maxCropWide;
bitmapCrop->bottom = maxCropTall;
int pointlessAlphaByte = copyPointlessAlphaByte ? 1 : 0;
// Destination will be directly changed if there is no scaling algorithm.
// Otherwise we extract to a temporary buffer.
unsigned char* destPtr;
//if (currentAlgorithm == ScalingAlgorithm::None)
destPtr = (unsigned char*)destinationBitmap;
//else
// destPtr = (unsigned char*)tempBitmap;
VDLFrame* framePtr = sourceFrame;
for (int line = 0; line < copyHeight; line++)
{
VDLLine* linePtr = &framePtr->lines[line];
short* srcPtr = (short*)linePtr;
bool allowFixedClut = (linePtr->xOUTCONTROLL & 0x2000000) > 0;
for (int pix = 0; pix < copyWidth; pix++)
{
unsigned char bPart = 0;
unsigned char gPart = 0;
unsigned char rPart = 0;
if (*srcPtr == 0)
{
bPart = (unsigned char)(linePtr->xBACKGROUND & 0x1F);
gPart = (unsigned char)((linePtr->xBACKGROUND >> 5) & 0x1F);
rPart = (unsigned char)((linePtr->xBACKGROUND >> 10) & 0x1F);
}
else if (allowFixedClut && (*srcPtr & 0x8000) > 0)
{
bPart = FIXED_CLUTB[(*srcPtr) & 0x1F];
gPart = FIXED_CLUTG[((*srcPtr) >> 5) & 0x1F];
rPart = FIXED_CLUTR[(*srcPtr) >> 10 & 0x1F];
}
else
{
bPart = (unsigned char)(linePtr->xCLUTB[(*srcPtr) & 0x1F]);
gPart = linePtr->xCLUTG[((*srcPtr) >> 5) & 0x1F];
rPart = linePtr->xCLUTR[(*srcPtr) >> 10 & 0x1F];
}
*destPtr++ = bPart;
*destPtr++ = gPart;
*destPtr++ = rPart;
destPtr += pointlessAlphaByte;
srcPtr++;
if (line < bitmapCrop->top)
if (!(rPart < 0xF && gPart < 0xF && bPart < 0xF))
bitmapCrop->top = line;
if (pix < bitmapCrop->left )
if (!(rPart < 0xF && gPart < 0xF && bPart < 0xF))
bitmapCrop->left = pix;
if (pix > copyWidth - bitmapCrop->right - 1)
if (!(rPart < 0xF && gPart < 0xF && bPart < 0xF))
bitmapCrop->right = copyWidth - pix - 1;
if (line > copyHeight - bitmapCrop->bottom - 1)
if (!(rPart < 0xF && gPart < 0xF && bPart < 0xF))
bitmapCrop->bottom = copyHeight - line - 1;
}
}
int cropAdjust = 1;
// switch (currentAlgorithm)
// {
// case ScalingAlgorithm::None:
// // Nothing left to do
// break;
// case ScalingAlgorithm::HQ2X:
// hq2x_32((uint32_t*)tempBitmap, (uint32_t*)destinationBitmap, copyWidth, copyHeight);
// cropAdjust = 2;
// break;
// case ScalingAlgorithm::HQ3X:
// hq3x_32((uint32_t*)tempBitmap, (uint32_t*)destinationBitmap, copyWidth, copyHeight);
// cropAdjust = 3;
// break;
// case ScalingAlgorithm::HQ4X:
// hq4x_32((uint32_t*)tempBitmap, (uint32_t*)destinationBitmap, copyWidth, copyHeight);
// cropAdjust = 4;
// break;
// }
bitmapCrop->top *= cropAdjust;
bitmapCrop->left *= cropAdjust;
bitmapCrop->right *= cropAdjust;
bitmapCrop->bottom *= cropAdjust;
*resultingWidth = copyWidth * cropAdjust;
*resultingHeight = copyHeight * cropAdjust;
}
//void setCurrentAlgorithm(ScalingAlgorithm algorithm)
//{
// //////////////////
// // De-initialize current (if necessary).
// if (
// ((currentAlgorithm == ScalingAlgorithm::HQ2X)
// || (currentAlgorithm == ScalingAlgorithm::HQ3X)
// || (currentAlgorithm == ScalingAlgorithm::HQ4X))
// && algorithm != ScalingAlgorithm::HQ2X
// && algorithm != ScalingAlgorithm::HQ3X
// && algorithm != ScalingAlgorithm::HQ4X )
// {
// delete tempBitmap;
// hqxDestroy();
// }
//
// //////////////////
// // Initialize current (if necessary).
//
// if (
// ((algorithm == ScalingAlgorithm::HQ2X)
// || (algorithm == ScalingAlgorithm::HQ3X)
// || (algorithm == ScalingAlgorithm::HQ4X))
// && currentAlgorithm != ScalingAlgorithm::HQ2X
// && currentAlgorithm != ScalingAlgorithm::HQ3X
// && currentAlgorithm != ScalingAlgorithm::HQ4X )
// {
// //hqxInit();
// tempBitmap = new unsigned char[1280*960*4];
// }
//
// // Accept new current algorithm.
// currentAlgorithm = algorithm;
//}
+22
View File
@@ -0,0 +1,22 @@
// Frame.h - For frame extraction and filtering options.
#ifndef FRAME_3DO_HEADER
#define FRAME_3DO_HEADER
void _frame_Init();
void Get_Frame_Bitmap(
VDLFrame* sourceFrame,
void* destinationBitmap,
int destinationBitmapWidth,
BitmapCrop* bitmapCrop,
int copyWidth,
int copyHeight,
bool addBlackBorder,
bool copyPointlessAlphaByte,
bool allowCrop,
ScalingAlgorithm scalingAlgorithm,
int* resultingWidth,
int* resultingHeight);
#endif
+54
View File
@@ -0,0 +1,54 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#ifndef FREEDOCONFIG_H
#define FREEDOCONFIG_H
#ifdef __MSVC__
//#include <stdafx.h>
#include <windows.h>
#define __temporalfixes 0
#define RESSCALE __tex__scaler
extern int __tex__scaler;
#else
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
extern bool __temporalfixes;
extern int HightResMode;
#define RESSCALE HightResMode
#define DEBUG_CORE
#define _T(a) (a)
#endif
#include "types.h"
#endif // FREEDOCONFIG_H
+154
View File
@@ -0,0 +1,154 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#ifndef __3DO_SYSTEM_HEADER_DEFINITION
#define __3DO_SYSTEM_HEADER_DEFINITION
//------------------------------------------------------------------------------
#pragma pack(push,1)
struct VDLLine
//VDLP Line - one VDLP line per patent
{
unsigned short line[320*4];//,line2[320*2*16];
unsigned char xCLUTB[32];
unsigned char xCLUTG[32];
unsigned char xCLUTR[32];
unsigned int xOUTCONTROLL;
unsigned int xCLUTDMA;
unsigned int xBACKGROUND;
};
struct VDLFrame
{
VDLLine lines[240*4];
unsigned int srcw,srch;
};
struct BitmapCrop
{
int left;
int top;
int bottom;
int right;
};
struct GetFrameBitmapParams
{
VDLFrame* sourceFrame;
void* destinationBitmap;
int destinationBitmapWidthPixels;
BitmapCrop* bitmapCrop;
int copyWidthPixels;
int copyHeightPixels;
bool addBlackBorder;
bool copyPointlessAlphaByte;
bool allowCrop;
int scalingAlgorithm;
int resultingWidth;
int resultingHeight;
};
enum ScalingAlgorithm
{
None = 0,
HQ2X = 1,
HQ3X = 2,
HQ4X = 3
};
#pragma pack(pop)
#define EXT_READ_ROMS 1
#define EXT_READ_NVRAM 2
#define EXT_WRITE_NVRAM 3
#define EXT_SWAPFRAME 5 //frame swap (in mutlithreaded) or frame draw(single treaded)
#define EXT_PUSH_SAMPLE 6 //sends sample to the buffer
#define EXT_GET_PBUSLEN 7
#define EXT_GETP_PBUSDATA 8
#define EXT_KPRINT 9
#define EXT_DEBUG_PRINT 10
#define EXT_FRAMETRIGGER_MT 12 //multitasking
#define EXT_READ2048 14 //for XBUS Plugin
#define EXT_GET_DISC_SIZE 15
#define EXT_ON_SECTOR 16
#define EXT_ARM_SYNC 17
typedef void* (__stdcall *_ext_Interface)(int, void*);
#define FDP_FREEDOCORE_VERSION 0
#define FDP_INIT 1 //set ext_interface
#define FDP_DESTROY 2
#define FDP_DO_EXECFRAME 3 //execute 1/60 of second
#define FDP_DO_FRAME_MT 4 //multitasking
#define FDP_DO_EXECFRAME_MT 5 //multitasking
#define FDP_DO_LOAD 6 //load state from buffer, returns !NULL if everything went smooth
#define FDP_GET_SAVE_SIZE 7 //return size of savestatemachine
#define FDP_DO_SAVE 8 //save state to buffer
#define FDP_GETP_NVRAM 9 //returns ptr to NVRAM 32K
#define FDP_GETP_RAMS 10 //returns ptr to RAM 3M
#define FDP_GETP_ROMS 11 //returns ptr to ROM 2M
#define FDP_GETP_PROFILE 12 //returns profile pointer, sizeof = 3M/4
#define FDP_BUGTEMPORALFIX 13
#define FDP_SET_ARMCLOCK 14
#define FDP_SET_TEXQUALITY 15
#define FDP_GETP_WRCOUNT 16
#define FDP_SET_FIX_MODE 17
#define FDP_GET_FRAME_BITMAP 18
#define FIX_BIT_TIMING_1 (0x00000001)
#define FIX_BIT_TIMING_2 (0x00000002)
#define FIX_BIT_TIMING_3 (0x00000004)
#define FIX_BIT_TIMING_4 (0x00000008)
#define FIX_BIT_TIMING_5 (0x00000010)
#define FIX_BIT_TIMING_6 (0x00000020)
#define FIX_BIT_TIMING_7 (0x00000040)
#define FIX_BIT_GRAPHICS_STEP_Y (0x00080000) // Preserve Y coordinate rather than X between CELs.
#ifdef __MSVC__
#ifdef FREEDOCORE_EXPORTS
#define FREEDOCORE_API __declspec(dllexport)
#else
#define FREEDOCORE_API __declspec(dllimport)
#endif
#else
#define FREEDOCORE_API
#endif
extern "C"
{
FREEDOCORE_API void* __stdcall _freedo_Interface(int procedure, void *datum=0);
};
#ifdef __MSVC__
#ifndef FREEDOCORE_EXPORTS
//#pragma comment(lib, "freedocore.lib")
#endif
#endif
//------------------------------------------------------------------------------
#endif
+13
View File
@@ -0,0 +1,13 @@
#-------------------------------------------------
#
# Project created by QtCreator 2010-11-10T21:13:39
#
#-------------------------------------------------
TARGET = freedo
TEMPLATE = lib
CONFIG += staticlib
SOURCES += arm.cpp bitop.cpp Clio.cpp DiagPort.cpp DSP.cpp Iso.cpp Madam.cpp quarz.cpp SPORT.cpp vdlp.cpp XBUS.cpp _3do_sys.cpp
HEADERS += arm.h bitop.h Clio.h DiagPort.h DSP.h freedoconfig.h freedocore.h IsoXBUS.h Madam.h quarz.h SPORT.h types.h vdlp.h XBUS.h
+179
View File
@@ -0,0 +1,179 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#include "quarz.h"
#include "types.h"
#include "clio.h"
#include "vdlp.h"
#include "XBUS.h"
#include "madam.h"
#include "stdafx.h"
int ARM_CLOCK=12500000;
int THE_ARM_CLOCK=0;
extern _ext_Interface io_interface;
#define SND_CLOCK 44100
//#define NTSC_CLOCK 12270000 //818*500(ñòðîê) //15 ÊÃö
//#define PAL_CLOCK 14750000 //944*625(ñòðîê) //15625 Ãö
#pragma pack(push,1)
struct QDatum
{
uint32 qrz_AccARM;
uint32 qrz_AccDSP;
uint32 qrz_AccVDL;
uint32 qrz_TCount;
uint32 VDL_CLOCK, qrz_vdlline, VDL_HS,VDL_FS;
};
#pragma pack(pop)
static QDatum quarz;
#include <memory.h>
unsigned int _qrz_SaveSize()
{
return sizeof(QDatum);
}
void _qrz_Save(void *buff)
{
memcpy(buff,&quarz,sizeof(QDatum));
}
void _qrz_Load(void *buff)
{
memcpy(&quarz,buff,sizeof(QDatum));
}
#define qrz_AccARM quarz.qrz_AccARM
#define qrz_AccDSP quarz.qrz_AccDSP
#define qrz_AccVDL quarz.qrz_AccVDL
#define qrz_TCount quarz.qrz_TCount
#define VDL_CLOCK quarz.VDL_CLOCK
#define qrz_vdlline quarz.qrz_vdlline
#define VDL_HS quarz.VDL_HS
#define VDL_FS quarz.VDL_FS
void __fastcall _qrz_Init()
{
qrz_AccVDL=qrz_AccDSP=0;
qrz_AccARM=0;
VDL_FS=526;
VDL_CLOCK=VDL_FS*30;
VDL_HS=VDL_FS/2;
qrz_TCount=0;
qrz_vdlline=0;
}
int __fastcall _qrz_VDCurrLine()
{
return qrz_vdlline%(VDL_HS/*+(VDL_HS/2)*/);
}
int __fastcall _qrz_VDHalfFrame()
{
return qrz_vdlline/(VDL_HS);
}
int __fastcall _qrz_VDCurrOverline()
{
return qrz_vdlline;
}
bool __fastcall _qrz_QueueVDL()
{
if(qrz_AccVDL>>24)
{
qrz_AccVDL-=0x1000000;
qrz_vdlline++;
qrz_vdlline%=VDL_FS;
return true;
}
return false;
}
bool __fastcall _qrz_QueueDSP()
{
if(qrz_AccDSP>>24)
{
//if(HightResMode!=0) qrz_AccDSP-=0x1000000/1.3;
//else
qrz_AccDSP-=0x1000000;
return true;
}
return false;
}
bool __fastcall _qrz_QueueTimer()
{
//uint32 cnt=_clio_GetTimerDelay();
if(qrz_TCount>>24)//=cnt)
{
qrz_TCount-=0x1000000;//cnt;
return true;
}
return false;
}
void __fastcall _qrz_PushARMCycles(unsigned int clks)
{
uint32 arm,cnt;
int timers=21000000; //default
int sp=0;
if(sdf>0) sdf--;
if(sf>0) sf--;
if(unknownflag11>0)unknownflag11--;
if(ARM_CLOCK<0x5F5E10)ARM_CLOCK=0x5F5E10;
if(ARM_CLOCK>0x2FAF080)ARM_CLOCK=0x2FAF080;
if(speedfixes>0&&speedfixes<0x186A1) {/*sp=0x2DC6C0;*/ speedfixes--;}
else if(speedfixes>0x186A1&&speedfixes<0x30D41) {/*if(sdf==0)sp=0x4C4B40; */speedfixes--;}
else if(speedfixes<0) {sp=0x3D0900; speedfixes++;}
else if(speedfixes>0x30D41) {/*sp=0x249F00;*/ speedfixes--;}
else if(speedfixes==0x30D41||speedfixes==0x186A1) speedfixes=0;
if((fixmode&FIX_BIT_TIMING_2)&&sf<=2500000) {sp=0; timers=21000000; if(sf==0)sp=-(0x1C9C380-ARM_CLOCK);}
if((fixmode&FIX_BIT_TIMING_1)/*&&jw>0*/&&sf<=1500000){/*jw--;*/timers=1000000;sp=-1000000;}
if((fixmode&FIX_BIT_TIMING_4)/*&&jw>0*/){/*jw--;*/timers=1000000;sp=-1000000;}
if((fixmode&FIX_BIT_TIMING_3)&&(sf>0&&sf<=100000)/*&&jw>0*/){/*jw--;*/timers=900000;}
if((fixmode&FIX_BIT_TIMING_5)&&sf==0/*&&jw>0*/){/*jw--;*/timers=1000000;}
if((fixmode&FIX_BIT_TIMING_6)/*&&jw>0*/){/*jw--;*/timers=1000000; if(sf<=80000)sp=-23000000;}
if(fixmode&FIX_BIT_TIMING_7){sp=-3000000; timers=21000000;}
if((sf>0x186A0&&!(fixmode&FIX_BIT_TIMING_2))||((fixmode&FIX_BIT_TIMING_2)&&sf>2500000))sp=-(12200000-ARM_CLOCK);
if((ARM_CLOCK-sp)<0x2DC6C0)sp=-(0x2DC6C0-ARM_CLOCK);
if((ARM_CLOCK-sp)!=THE_ARM_CLOCK)
{ THE_ARM_CLOCK=(ARM_CLOCK-sp);
io_interface(EXT_ARM_SYNC,(void*)THE_ARM_CLOCK); //fix for working with 4do
}
arm=(clks<<24)/(ARM_CLOCK-sp);
qrz_AccARM+=arm*(ARM_CLOCK-sp);
if( (qrz_AccARM>>24) != clks )
{
arm++;
qrz_AccARM+=ARM_CLOCK;
qrz_AccARM&=0xffffff;
}
qrz_AccDSP+=arm*SND_CLOCK;
qrz_AccVDL+=arm*(VDL_CLOCK);
//if(Get_madam_FSM()!=FSM_INPROCESS)
if(_clio_GetTimerDelay())qrz_TCount+=arm*((timers)/(_clio_GetTimerDelay()));//clks<<1;
}
+44
View File
@@ -0,0 +1,44 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
#ifndef QUARZ_3DO_HEADER_DEFINTION
#define QUARZ_3DO_HEADER_DEFINTION
void __fastcall _qrz_Init();
int __fastcall _qrz_VDCurrLine();
int __fastcall _qrz_VDHalfFrame();
int __fastcall _qrz_VDCurrOverline();
bool __fastcall _qrz_QueueVDL();
bool __fastcall _qrz_QueueDSP();
bool __fastcall _qrz_QueueTimer();
void __fastcall _qrz_PushARMCycles(unsigned int clks);
unsigned int _qrz_SaveSize();
void _qrz_Save(void *buff);
void _qrz_Load(void *buff);
#endif
+26
View File
@@ -0,0 +1,26 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#ifndef AFX_STDAFX_H__MAZAFAKING_HEADER
#define AFX_STDAFX_H__MAZAFAKING_HEADER
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
//#include "astring.h"
#include "types.h"
extern int fixmode;
extern int speedfixes;
extern int sf;
extern int sdf;
extern int unknownflag11;
extern int HightResMode;
extern int jw;
extern int cnbfix;
#define DEBUG_CORE
#endif
+79
View File
@@ -0,0 +1,79 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
/*****************************************************************************
Copyright (C) 2007-2008 Maxim Grishin (http://altmer.arts-union.ru)
*****************************************************************************/
#ifndef TYPES_HEAD_DEFINITION
#define TYPES_HEAD_DEFINITION
typedef unsigned int uint32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long long uint64;
typedef unsigned long long __uint64;
typedef int int32;
typedef char int8;
typedef short int16;
typedef signed long long int64;
#ifndef WIN32
#ifndef __int64
typedef signed long long __int64;
#endif
#endif
typedef float real32;
typedef double real64;
typedef long double real80;
#ifndef NULL
#define NULL 0
#endif
#ifdef __GNUC__
#define __fastcall __attribute__((__fastcall__))
#endif
//------------------Vector types-------------------------------------------
#pragma pack(push,1)
template <class T> struct point2d { T x,y; };
template <class T> struct sprite{ point2d<T> ul,dr; };
#pragma pack(pop)
//---------------------------------------------------------------------------
//--------------------resources------------------------------------------------
#pragma pack(push,1)
struct imgdata
{
#define IMDT_BMP32 0
#define IMDT_BMP24 1
uint32 pref; //0xf - type,....
uint32 w,h,d;
uint32 data[1];
};
#pragma pack(pop)
//----------------------------------------------------------------------------
#endif
+393
View File
@@ -0,0 +1,393 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// VDLP.cpp: implementation of the CVDLP class.
//
//////////////////////////////////////////////////////////////////////
#include "freedoconfig.h"
#include "vdlp.h"
#include "arm.h"
#include <memory.h>
#include "freedocore.h"
extern _ext_Interface io_interface;
/* === VDL Palette data === */
#define VDL_CONTROL 0x80000000
#define VDL_BACKGROUND 0xE0000000
#define VDL_RGBCTL_MASK 0x60000000
#define VDL_PEN_MASK 0x1F000000
#define VDL_R_MASK 0x00FF0000
#define VDL_G_MASK 0x0000FF00
#define VDL_B_MASK 0x000000FF
#define VDL_B_SHIFT 0
#define VDL_G_SHIFT 8
#define VDL_R_SHIFT 16
#define VDL_PEN_SHIFT 24
#define VDL_RGBSEL_SHIFT 29
/* VDL_RGBCTL_MASK definitions */
#define VDL_FULLRGB 0x00000000
#define VDL_REDONLY 0x60000000
#define VDL_GREENONLY 0x40000000
#define VDL_BLUEONLY 0x20000000
#pragma pack(push,1)
struct cdmaw
{
unsigned int lines:9;//0-8
unsigned int numword:6;//9-14
unsigned int prevover:1;//15
unsigned int currover:1;//16
unsigned int prevtick:1;//17
unsigned int abs:1;//18
unsigned int vmode:1;//19
unsigned int pad0:1;//20
unsigned int enadma:1;//21
unsigned int pad1:1;//22
unsigned int modulo:3;//23-25
unsigned int pad2:6;//26-31
};
union CDMW
{
unsigned int raw;
cdmaw dmaw;
};
struct VDLDatum
{
unsigned char CLUTB[32];
unsigned char CLUTG[32];
unsigned char CLUTR[32];
unsigned int BACKGROUND;
unsigned int HEADVDL;
unsigned int MODULO;
unsigned int CURRENTVDL;
unsigned int CURRENTBMP;
unsigned int PREVIOUSBMP;
unsigned int OUTCONTROLL;
CDMW CLUTDMA;
int linedelay;
};
#pragma pack(pop)
static VDLDatum vdl;
static unsigned char * vram;
unsigned int _vdl_SaveSize()
{
return sizeof(VDLDatum);
}
void _vdl_Save(void *buff)
{
memcpy(buff,&vdl,sizeof(VDLDatum));
}
void _vdl_Load(void *buff)
{
memcpy(&vdl,buff,sizeof(VDLDatum));
}
#define CLUTB vdl.CLUTB
#define CLUTG vdl.CLUTG
#define CLUTR vdl.CLUTR
#define BACKGROUND vdl.BACKGROUND
#define HEADVDL vdl.HEADVDL
#define MODULO vdl.MODULO
#define CURRENTVDL vdl.CURRENTVDL
#define CURRENTBMP vdl.CURRENTBMP
#define PREVIOUSBMP vdl.PREVIOUSBMP
#define OUTCONTROLL vdl.OUTCONTROLL
#define CLUTDMA vdl.CLUTDMA
#define linedelay vdl.linedelay
unsigned int vmreadw(unsigned int addr);
//static AString str;
void _vdl_ProcessVDL( unsigned int addr)
{
HEADVDL=addr;
if((addr&0xfff00000)!=0x200000)
{
//io_interface(EXT_DEBUG_PRINT,(void*)str.print("!!!!VDLP!!!! VDLP code out of VRAM boundaries!!! 0x%8.8X",addr).CStr());
}
}
static const unsigned int HOWMAYPIXELEXPECTPERLINE[8] =
{320, 384, 512, 640, 1024, 320, 320, 320};
// ###### Per line implementation ######
bool doloadclut=false;
__inline void VDLExec()
{
unsigned int NEXTVDL,tmp;
unsigned char ifgnorflag=0;
tmp=vmreadw(CURRENTVDL);
if(tmp==0) // End of list
{
linedelay=511;
doloadclut=false;
}
else
{
CLUTDMA.raw=tmp;
if(CLUTDMA.dmaw.currover)
CURRENTBMP=vmreadw(CURRENTVDL+4);
if(CLUTDMA.dmaw.prevover)
PREVIOUSBMP=vmreadw(CURRENTVDL+8);
if(CLUTDMA.dmaw.abs)
{
NEXTVDL=(CURRENTVDL+vmreadw(CURRENTVDL+12)+16);
//CDebug::DPrint("Relative offset??\n");
}
else
NEXTVDL=vmreadw(CURRENTVDL+12);
CURRENTVDL+=16;
int nmcmd=CLUTDMA.dmaw.numword; //nmcmd-=4;?
for(int i=0; i<nmcmd; i++)
{
int cmd=vmreadw(CURRENTVDL);
CURRENTVDL+=4;
if(!(cmd&VDL_CONTROL))
{ //color value
unsigned int coloridx=(cmd&VDL_PEN_MASK)>>VDL_PEN_SHIFT;
if((cmd&VDL_RGBCTL_MASK)==VDL_FULLRGB)
{
CLUTR[coloridx]=(cmd&VDL_R_MASK)>>VDL_R_SHIFT;
CLUTG[coloridx]=(cmd&VDL_G_MASK)>>VDL_G_SHIFT;
CLUTB[coloridx]=(cmd&VDL_B_MASK)>>VDL_B_SHIFT;
}
else if((cmd&VDL_RGBCTL_MASK)==VDL_REDONLY)
CLUTR[coloridx]=(cmd&VDL_R_MASK)>>VDL_R_SHIFT;
else if((cmd&VDL_RGBCTL_MASK)==VDL_GREENONLY)
CLUTG[coloridx]=(cmd&VDL_G_MASK)>>VDL_G_SHIFT;
else if((cmd&VDL_RGBCTL_MASK)==VDL_BLUEONLY)
CLUTB[coloridx]=(cmd&VDL_B_MASK)>>VDL_B_SHIFT;
}
else if((cmd&0xff000000)==VDL_BACKGROUND)
{
if(ifgnorflag)continue;
BACKGROUND=(( cmd&0xFF )<<16)|
(( cmd&0xFF00 )) |
(((cmd>>16)&0xFF) );
}
else if((cmd&0xE0000000)==0xc0000000)
{
if(ifgnorflag)continue;
OUTCONTROLL=cmd;
//io_interface(EXT_DEBUG_PRINT,(void*)str.print("????VDLP???? Strange... DPComm=0x%8.8X",cmd).CStr());
/*if((OUTCONTROLL>>22)&7)
{
_3do_DPrint(str.print("????VDLP???? Strange... DPComm=0x%8.8X",cmd).CStr());
} */
ifgnorflag=OUTCONTROLL&2;
//if(!ifgnorflag)break;
}
else if((unsigned int)cmd==0xffffffff)
{
if(ifgnorflag)continue;
for(unsigned int j=0;j<32;j++)
{
CLUTB[j]=CLUTG[j]=CLUTR[j]=((j&0x1f)<<3)|((j>>2)&7);
}
}
else if((cmd&0xff000000)!=0xE1000000 && (cmd&0xC0000000)!=VDL_CONTROL)
{
// io_interface(EXT_DEBUG_PRINT,(void*)str.print("::::VDLP:::: Unknown opcode... Comm=0x%8.8X",cmd).CStr());
}
}//for(i<nmcmd)
CURRENTVDL=NEXTVDL;
MODULO=HOWMAYPIXELEXPECTPERLINE[CLUTDMA.dmaw.modulo];
if(MODULO!=320)
{
// io_interface(EXT_DEBUG_PRINT,(void*)str.print("::::VDLP:::: Nonstandard modulo... W=%d, DMAWORD=0x%8.8X",MODULO, CLUTDMA.raw).CStr());
}
doloadclut=((linedelay=CLUTDMA.dmaw.lines)!=0);
}
}
__inline uint32 VRAMOffEval(uint32 addr, uint32 line)
{
return ((((~addr)&2)<<(18+RESSCALE))+((addr>>2)<<1)+1024*512*line)<<RESSCALE;
}
void _vdl_DoLineNew(int line2x, VDLFrame *frame)
{
int y,i;
int line=line2x&0x7ff;
if(line==0)
{
doloadclut=true;
linedelay=0;
CURRENTVDL=HEADVDL;
VDLExec();
}
y=(line-(16));
if(linedelay==0 /*&& doloadclut*/)
{
VDLExec();
}
if((y>=0) && (y<240)) // 256???
{
if(CLUTDMA.dmaw.enadma)
{
if(RESSCALE)
{
unsigned short *dst1,*dst2;
unsigned int *src1,*src2,*src3,*src4;
dst1=frame->lines[(y<<1)].line;
dst2=frame->lines[(y<<1)+1].line;
src1=(unsigned int*)(vram+((PREVIOUSBMP^2) & 0x0FFFFF));
src2=(unsigned int*)(vram+((PREVIOUSBMP^2) & 0x0FFFFF)+1024*1024);
src3=(unsigned int*)(vram+((CURRENTBMP^2) & 0x0FFFFF)+2*1024*1024);
src4=(unsigned int*)(vram+((CURRENTBMP^2) & 0x0FFFFF)+3*1024*1024);
i=320;
while(i--)
{
*dst1++=*(unsigned short*)(src1++);
*dst1++=*(unsigned short*)(src2++);
*dst2++=*(unsigned short*)(src3++);
*dst2++=*(unsigned short*)(src4++);
}
}
else
{
unsigned short *dst;
unsigned int *src;
dst=frame->lines[y].line;
src=(unsigned int*)(vram+((PREVIOUSBMP^2) & 0x0FFFFF));
i=320;
while(i--)*dst++=*(unsigned short*)(src++);
}
memcpy(frame->lines[(y<<RESSCALE)].xCLUTB,CLUTB,32);
memcpy(frame->lines[(y<<RESSCALE)].xCLUTG,CLUTG,32);
memcpy(frame->lines[(y<<RESSCALE)].xCLUTR,CLUTR,32);
if(RESSCALE)
{
memcpy(frame->lines[(y<<RESSCALE)+1].xCLUTB,frame->lines[(y<<RESSCALE)].xCLUTB,32*3);
}
}
frame->lines[(y<<RESSCALE)].xOUTCONTROLL=OUTCONTROLL;
frame->lines[(y<<RESSCALE)].xCLUTDMA=CLUTDMA.raw;
frame->lines[(y<<RESSCALE)].xBACKGROUND=BACKGROUND;
if(RESSCALE)
{
frame->lines[(y<<RESSCALE)+1].xOUTCONTROLL=OUTCONTROLL;
frame->lines[(y<<RESSCALE)+1].xCLUTDMA=CLUTDMA.raw;
frame->lines[(y<<RESSCALE)+1].xBACKGROUND=BACKGROUND;
}
} // //if((y>=0) && (y<240))
if(CURRENTBMP & 2)
CURRENTBMP+=MODULO*4 - 2;
else
CURRENTBMP+=2;
if(!CLUTDMA.dmaw.prevtick)
{
PREVIOUSBMP=CURRENTBMP;
}
else
{
if(PREVIOUSBMP & 2)
PREVIOUSBMP+=MODULO*4 - 2;
else
PREVIOUSBMP+=2;
}
linedelay--;
OUTCONTROLL&=~1; //Vioff1ln
}
void _vdl_Init(unsigned char *vramstart)
{
vram=vramstart;
static const unsigned int StartupVDL[]=
{ // Startup VDL at addres 0x2B0000
0x00004410, 0x002C0000, 0x002C0000, 0x002B0098,
0x00000000, 0x01080808, 0x02101010, 0x03191919,
0x04212121, 0x05292929, 0x06313131, 0x073A3A3A,
0x08424242, 0x094A4A4A, 0x0A525252, 0x0B5A5A5A,
0x0C636363, 0x0D6B6B6B, 0x0E737373, 0x0F7B7B7B,
0x10848484, 0x118C8C8C, 0x12949494, 0x139C9C9C,
0x14A5A5A5, 0x15ADADAD, 0x16B5B5B5, 0x17BDBDBD,
0x18C5C5C5, 0x19CECECE, 0x1AD6D6D6, 0x1BDEDEDE,
0x1CE6E6E6, 0x1DEFEFEF, 0x1EF8F8F8, 0x1FFFFFFF,
0xE0010101, 0xC001002C, 0x002180EF, 0x002C0000,
0x002C0000, 0x002B00A8, 0x00000000, 0x002C0000,
0x002C0000, 0x002B0000
};
HEADVDL=0xB0000;
for(unsigned int i=0;i<(sizeof(StartupVDL)/4);i++)
_mem_write32(HEADVDL+i*4+1024*1024*2,StartupVDL[i]);
//memcpy(vram+HEADVDL, StartupVDL, sizeof(StartupVDL));
for(unsigned int i=0;i<32;i++)
{
CLUTB[i]=CLUTG[i]=CLUTR[i]=((i&0x1f)<<3)|((i>>2)&7);
}
}
unsigned int vmreadw(unsigned int addr)
{
//unsigned int val;
//val=*(unsigned int*)(vram+(addr&0xfffff));
//return val;
return _mem_read32((addr&0xfffff)+1024*1024*2);
}
+42
View File
@@ -0,0 +1,42 @@
/*
www.freedo.org
The first and only working 3DO multiplayer emulator.
The FreeDO licensed under modified GNU LGPL, with following notes:
* The owners and original authors of the FreeDO have full right to develop closed source derivative work.
* Any non-commercial uses of the FreeDO sources or any knowledge obtained by studying or reverse engineering
of the sources, or any other material published by FreeDO have to be accompanied with full credits.
* Any commercial uses of FreeDO sources or any knowledge obtained by studying or reverse engineering of the sources,
or any other material published by FreeDO is strictly forbidden without owners approval.
The above notes are taking precedence over GNU LGPL in conflicting situations.
Project authors:
Alexander Troosh
Maxim Grishin
Allen Wright
John Sammons
Felix Lazarev
*/
// VDLP.h: interface for the CVDLP class.
//
//////////////////////////////////////////////////////////////////////
#ifndef VDLP_3DO_HEADER
#define VDLP_3DO_HEADER
#include "freedocore.h"
void _vdl_Init(unsigned char *vramstart);
void _vdl_ProcessVDL( unsigned int addr);
void _vdl_DoLineNew(int line, VDLFrame *frame);
unsigned int _vdl_SaveSize();
void _vdl_Save(void *buff);
void _vdl_Load(void *buff);
#endif
+571
View File
@@ -0,0 +1,571 @@
#ifndef _MSC_VER
#include <stdbool.h>
#include <sched.h>
#endif
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fstream>
#include <sstream>
#include <string.h>
#ifdef _MSC_VER
#define snprintf _snprintf
#pragma pack(1)
#endif
#include "libretro.h"
#include "freedocore.h"
#include "frame.h"
#define TEMP_BUFFER_SIZE 512
#define ROM1_SIZE 1 * 1024 * 1024
#define ROM2_SIZE 933636 //was 1 * 1024 * 1024,
#define NVRAM_SIZE 32 * 1024
#define INPUTBUTTONL (1<<4)
#define INPUTBUTTONR (1<<5)
#define INPUTBUTTONX (1<<6)
#define INPUTBUTTONP (1<<7)
#define INPUTBUTTONC (1<<8)
#define INPUTBUTTONB (1<<9)
#define INPUTBUTTONA (1<<10)
#define INPUTBUTTONLEFT (1<<11)
#define INPUTBUTTONRIGHT (1<<12)
#define INPUTBUTTONUP (1<<13)
#define INPUTBUTTONDOWN (1<<14)
typedef struct{
int buttons; // buttons bitfield
}inputState;
inputState internal_input_state[6];
const char *biosPath;
static void *nvramCopy;
static VDLFrame *frame;
FILE *fcdrom;
static int currentSector;
static bool isSwapFrameSignaled;
static int fver1,fver2;
static uint32_t *videoBuffer;
static int videoWidth, videoHeight;
//uintptr_t sampleBuffer[TEMP_BUFFER_SIZE];
static int32_t sampleBuffer[TEMP_BUFFER_SIZE];
static unsigned int sampleCurrent;
static retro_log_printf_t log_cb;
static retro_video_refresh_t video_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;
static retro_environment_t environ_cb;
static retro_audio_sample_t audio_cb;
static retro_audio_sample_batch_t audio_batch_cb;
void retro_set_environment(retro_environment_t cb) { environ_cb = cb; }
void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }
void retro_set_audio_sample(retro_audio_sample_t cb) { audio_cb = cb; }
void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; }
void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; }
void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; }
// File/ISO helper functions
unsigned char nvramhead[]=
{
0x01,0x5a,0x5a,0x5a,0x5a,0x5a,0x02,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0x6e,0x76,0x72,0x61,0x6d,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0xff,0xff,0xff,0xff,0,0,0,1,
0,0,0x80,0,0xff,0xff,0xff,0xfe,0,0,0,0,0,0,0,1,
0,0,0,0,0,0,0,0x84,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0x85,0x5a,2,0xb6,0,0,0,0x98,0,0,0,0x98,
0,0,0,0x14,0,0,0,0x14,0x7A,0xa5,0x65,0xbd,0,0,0,0x84,
0,0,0,0x84,0,0,0x76,0x68,0,0,0,0x14
};
void fsReadBios(const char *biosFile, void *prom)
{
FILE *bios1;
long fsize;
int readcount;
bios1 = fopen(biosFile, "rb");
fseek(bios1, 0, SEEK_END);
fsize = ftell(bios1);
rewind(bios1);
readcount = fread(prom, 1, fsize, bios1);
fclose(bios1);
}
static int fsOpenIso(const char *path)
{
fcdrom = fopen(path, "rb");
if(!fcdrom)
return 0;
return 1;
}
static int fsCloseIso()
{
fclose(fcdrom);
return 1;
}
static int fsReadBlock(void *buffer, int sector)
{
fseek(fcdrom, 2048 * sector, SEEK_SET);
fread(buffer, 1, 2048, fcdrom);
rewind(fcdrom);
return 1;
}
static char *fsReadSize()
{
char *buffer = (char *)malloc(sizeof(char) * 4);
rewind(fcdrom);
fseek(fcdrom, 80, SEEK_SET);
fread(buffer, 1, 4, fcdrom);
rewind(fcdrom);
return buffer;
}
static unsigned int fsReadDiscSize()
{
unsigned int size;
char sectorZero[2048];
unsigned int temp;
char *ssize;
ssize = fsReadSize();
memcpy(&temp, ssize, 4);
size = (temp & 0x000000FFU) << 24 | (temp & 0x0000FF00U) << 8 |
(temp & 0x00FF0000U) >> 8 | (temp & 0xFF000000U) >> 24;
//printf("disc size: %d sectors\n", size);
return size;
}
void initVideo()
{
if(videoBuffer)
free(videoBuffer);
//TODO core option or always enable if CPU hit isn't too high?
/*
extern int HightResMode;
HightResMode = 1;
videoWidth = 640;
videoHeight = 480;
*/
videoWidth = 320;
videoHeight = 240;
videoBuffer = (uint32_t*)malloc(videoWidth * videoHeight * 4);
frame = new VDLFrame;
fver2=fver1=0;
}
void initNVRAM()
{
nvramCopy = malloc(65536/2);
memset(nvramCopy, 0, 65536/2);
memcpy(nvramCopy, nvramhead, sizeof(nvramhead));
frame = (VDLFrame*)malloc(sizeof(VDLFrame));
memset(frame, 0, sizeof(VDLFrame));
}
// Input helper functions
static int CheckDownButton(int deviceNumber,int button)
{
if(internal_input_state[deviceNumber].buttons&button)
return 1;
else
return 0;
}
static char CalculateDeviceLowByte(int deviceNumber)
{
char returnValue = 0;
returnValue |= 0x01 & 0; // unknown
returnValue |= 0x02 & 0; // unknown
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONL) ? (char)0x04 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONR) ? (char)0x08 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONX) ? (char)0x10 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONP) ? (char)0x20 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONC) ? (char)0x40 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONB) ? (char)0x80 : (char)0;
return returnValue;
}
static char CalculateDeviceHighByte(int deviceNumber)
{
char returnValue = 0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONA) ? (char)0x01 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONLEFT) ? (char)0x02 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONRIGHT) ? (char)0x04 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONUP) ? (char)0x08 : (char)0;
returnValue |= CheckDownButton(deviceNumber, INPUTBUTTONDOWN) ? (char)0x10 : (char)0;
returnValue |= 0x20 & 0; // unknown
returnValue |= 0x40 & 0; // unknown
returnValue |= 0x80; // This last bit seems to indicate power and/or connectivity.
return returnValue;
}
// libfreedo callback
static void *fdcCallback(int procedure, void *data)
{
switch(procedure)
{
case EXT_READ_ROMS:
{
fsReadBios(biosPath, data);
break;
}
case EXT_READ_NVRAM:
memcpy(data, nvramCopy, NVRAM_SIZE);
break;
case EXT_WRITE_NVRAM:
// ?
break;
case EXT_SWAPFRAME:
{
isSwapFrameSignaled = true;
return frame;
}
case EXT_PUSH_SAMPLE:
{
//TODO: fix all this, not right
sampleBuffer[sampleCurrent] = (uintptr_t)data;
sampleCurrent++;
if(sampleCurrent > TEMP_BUFFER_SIZE)
{
sampleCurrent = 0;
audio_batch_cb((int16_t *)sampleBuffer, TEMP_BUFFER_SIZE);
//memset(sampleBuffer, 0, sizeof(int32_t) * TEMP_BUFFER_SIZE);
}
break;
}
case EXT_GET_PBUSLEN:
return (void*)16;
case EXT_GETP_PBUSDATA:
{
// Set up raw data to return
unsigned char *pbusData;
pbusData = (unsigned char *)malloc(sizeof(unsigned char) * 16);
pbusData[0x0] = 0x00;
pbusData[0x1] = 0x48;
pbusData[0x2] = CalculateDeviceLowByte(0);
pbusData[0x3] = CalculateDeviceHighByte(0);
pbusData[0x4] = CalculateDeviceLowByte(2);
pbusData[0x5] = CalculateDeviceHighByte(2);
pbusData[0x6] = CalculateDeviceLowByte(1);
pbusData[0x7] = CalculateDeviceHighByte(1);
pbusData[0x8] = CalculateDeviceLowByte(4);
pbusData[0x9] = CalculateDeviceHighByte(4);
pbusData[0xA] = CalculateDeviceLowByte(3);
pbusData[0xB] = CalculateDeviceHighByte(3);
pbusData[0xC] = 0x00;
pbusData[0xD] = 0x80;
pbusData[0xE] = CalculateDeviceLowByte(5);
pbusData[0xF] = CalculateDeviceHighByte(5);
return pbusData;
}
case EXT_KPRINT:
break;
case EXT_FRAMETRIGGER_MT:
{
isSwapFrameSignaled = true;
_freedo_Interface(FDP_DO_FRAME_MT, frame);
break;
}
case EXT_READ2048:
fsReadBlock(data, currentSector);
break;
case EXT_GET_DISC_SIZE:
return (void *)(intptr_t)fsReadDiscSize();
case EXT_ON_SECTOR:
currentSector = (intptr_t)data;
break;
case EXT_ARM_SYNC:
//printf("fdcCallback EXT_ARM_SYNC\n");
break;
default:
break;
}
return (void*)0;
}
static void update_input()
{
if (!input_poll_cb)
return;
input_poll_cb();
// Can possibly support up to 6 players but is currently set for 2
for (unsigned i = 0; i < 2; i++)
{
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP))
internal_input_state[i].buttons|=INPUTBUTTONUP;
else
internal_input_state[i].buttons&=~INPUTBUTTONUP;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN))
internal_input_state[i].buttons|=INPUTBUTTONDOWN;
else
internal_input_state[i].buttons&=~INPUTBUTTONDOWN;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT))
internal_input_state[i].buttons|=INPUTBUTTONLEFT;
else
internal_input_state[i].buttons&=~INPUTBUTTONLEFT;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT))
internal_input_state[i].buttons|=INPUTBUTTONRIGHT;
else
internal_input_state[i].buttons&=~INPUTBUTTONRIGHT;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y))
internal_input_state[i].buttons|=INPUTBUTTONA;
else
internal_input_state[i].buttons&=~INPUTBUTTONA;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B))
internal_input_state[i].buttons|=INPUTBUTTONB;
else
internal_input_state[i].buttons&=~INPUTBUTTONB;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A))
internal_input_state[i].buttons|=INPUTBUTTONC;
else
internal_input_state[i].buttons&=~INPUTBUTTONC;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L))
internal_input_state[i].buttons|=INPUTBUTTONL;
else
internal_input_state[i].buttons&=~INPUTBUTTONL;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R))
internal_input_state[i].buttons|=INPUTBUTTONR;
else
internal_input_state[i].buttons&=~INPUTBUTTONR;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START))
internal_input_state[i].buttons|=INPUTBUTTONP;
else
internal_input_state[i].buttons&=~INPUTBUTTONP;
if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT))
internal_input_state[i].buttons|=INPUTBUTTONX;
else
internal_input_state[i].buttons&=~INPUTBUTTONX;
}
}
/************************************
* libretro implementation
************************************/
static struct retro_system_av_info g_av_info;
void retro_get_system_info(struct retro_system_info *info)
{
memset(info, 0, sizeof(*info));
info->library_name = "4DO";
info->library_version = "1.3.2.3";
info->need_fullpath = false;
info->valid_extensions = "iso";
}
void retro_get_system_av_info(struct retro_system_av_info *info)
{
memset(info, 0, sizeof(*info));
info->timing.fps = 60;
info->timing.sample_rate = 44100;
info->geometry.base_width = videoWidth;
info->geometry.base_height = videoHeight;
info->geometry.max_width = videoWidth;
info->geometry.max_height = videoHeight;
info->geometry.aspect_ratio = 4.0 / 3.0;
}
void retro_set_controller_port_device(unsigned port, unsigned device)
{
(void)port;
(void)device;
}
size_t retro_serialize_size(void)
{
//TODO
//return STATE_SIZE;
return 0;
}
bool retro_serialize(void *data, size_t size)
{
//TODO
return false;
}
bool retro_unserialize(const void *data, size_t size)
{
//TODO
return false;
}
void retro_cheat_reset(void)
{}
void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
(void)index;
(void)enabled;
(void)code;
}
bool retro_load_game(const struct retro_game_info *info)
{
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
if (log_cb)
log_cb(RETRO_LOG_INFO, "[4DO]: XRGB8888 is not supported.\n");
return false;
}
currentSector = 0;
sampleCurrent = 0;
memset(sampleBuffer, 0, sizeof(int32_t) * TEMP_BUFFER_SIZE);
const char *full_path;
full_path = info->path;
const char *system_directory_c = NULL;
if (fsOpenIso(full_path))
{
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_directory_c);
if (!system_directory_c)
{
if (log_cb)
log_cb(RETRO_LOG_WARN, "[4DO]: no system directory defined, unable to look for panafz10.bin\n");
}
else
{
std::string system_directory(system_directory_c);
std::string bios_file_path = system_directory + "/panafz10.bin";
std::ifstream bios_file(bios_file_path.c_str());
if (!bios_file.is_open())
{
if (log_cb)
log_cb(RETRO_LOG_WARN, "[4DO]: panafz10.bin not found, cannot load BIOS\n");
}
else
biosPath = bios_file_path.c_str();
}
// Initialize libfreedo
initNVRAM();
initVideo();
_freedo_Interface(FDP_INIT, (void*)*fdcCallback);
return true;
}
return false;
}
bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info)
{
(void)game_type;
(void)info;
(void)num_info;
return false;
}
void retro_unload_game(void)
{
_freedo_Interface(FDP_DESTROY, (void*)0);
fsCloseIso();
}
unsigned retro_get_region(void)
{
return RETRO_REGION_NTSC;
}
unsigned retro_api_version(void)
{
return RETRO_API_VERSION;
}
void *retro_get_memory_data(unsigned id)
{
return NULL;
}
size_t retro_get_memory_size(unsigned id)
{
return 0;
}
void retro_init(void)
{
struct retro_log_callback log;
unsigned level = 5;
if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
log_cb = log.log;
else
log_cb = NULL;
environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
}
void retro_deinit(void)
{
}
void retro_reset(void)
{
}
void retro_run(void)
{
update_input();
_freedo_Interface(FDP_DO_EXECFRAME, frame); // FDP_DO_EXECFRAME_MT ?
if(isSwapFrameSignaled)
{
if(fver2==fver1)
{
isSwapFrameSignaled = false;
struct BitmapCrop bmpcrop;
ScalingAlgorithm sca;
int rw, rh;
Get_Frame_Bitmap((VDLFrame *)frame, videoBuffer, 0, &bmpcrop, videoWidth, videoHeight, false, true, false, sca, &rw, &rh);
fver1++;
}
}
fver2=fver1;
video_cb(videoBuffer, videoWidth, videoHeight, videoWidth << 2);
}
Executable
+1476
View File
File diff suppressed because it is too large. Load diff
+5
View File
@@ -0,0 +1,5 @@
{
global: retro_*;
local: *;
};