mirror of
https://github.com/libretro/opera-libretro.git
synced 2026-11-07 04:25:58 -10:00
Add libretro port of 4DO/libfreedo 1.3.2.3
This commit is contained in:
1 parent
f3e396ea72
commit
e8613b5036
37 files changed
+13479
No files matched your search
@@ -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
|
||||
@@ -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?
|
||||
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
@@ -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
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
@@ -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~
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
// , ¶m->resultingWidth
|
||||
// , ¶m->resultingHeight);
|
||||
// break;
|
||||
};
|
||||
|
||||
return NULL;
|
||||
}
|
||||
+1896
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
//}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user