├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── deps └── wii-install-deps-linux.sh └── src ├── #cs2.c# ├── bios.c ├── bios.h ├── cart.c ├── cart.h ├── cdbase.c ├── cdbase.h ├── core.h ├── cs2.c ├── cs2.h ├── debug.c ├── debug.h ├── error.c ├── error.h ├── m68kcore.c ├── m68kcore.h ├── memory.c ├── memory.h ├── musashi ├── m68k.h ├── m68kconf.h ├── m68kcpu.c ├── m68kcpu.h ├── m68kopac.c ├── m68kopdm.c ├── m68kopnz.c ├── m68kops.c ├── m68kops.h └── readme.txt ├── osd ├── gui.c ├── gui.h ├── menu_tex.c ├── menu_tex.png ├── osd.c └── osd.h ├── peripheral.c ├── peripheral.h ├── profile.c ├── profile.h ├── scsp.c ├── scsp.h ├── scsp2.c ├── scspdummy.c ├── scu.c ├── scu.h ├── sgx ├── indtex.c ├── sgx.c ├── sgx.h ├── sgx_vdp1.c ├── sgx_vdp2.c ├── svi.c └── svi.h ├── sh2 ├── drc │ ├── compiler.c │ ├── compiler.h │ └── emit_ppc.inc ├── sh2.c ├── sh2.h ├── sh2_int.c └── sh2_int.h ├── sh2core.c ├── sh2core.h ├── sh2idle.c ├── sh2idle.h ├── sh2int.c ├── sh2int.h ├── smpc.c ├── smpc.h ├── snd.c ├── snd.h ├── vdp1.c ├── vdp1.h ├── vdp2.c ├── vdp2.h ├── vidshared.c ├── vidshared.h ├── yabause.c ├── yabause.h ├── yui.c └── yui.h /.gitignore: -------------------------------------------------------------------------------- 1 | /SetaGX 2 | /saves 3 | /vgames 4 | /build 5 | /*.dol 6 | /*.elf 7 | /src/*.old 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | # Clear the implicit built in rules 3 | #--------------------------------------------------------------------------------- 4 | .SUFFIXES: 5 | #--------------------------------------------------------------------------------- 6 | # prevent deletion of implicit targets 7 | #--------------------------------------------------------------------------------- 8 | .SECONDARY: 9 | #--------------------------------------------------------------------------------- 10 | 11 | ifeq ($(strip $(DEVKITPPC)),) 12 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") 13 | endif 14 | 15 | include $(DEVKITPRO)/libogc2/wii_rules 16 | 17 | #--------------------------------------------------------------------------------- 18 | # TARGET is the name of the output 19 | # BUILD is the directory where object files & intermediate files will be placed 20 | # SOURCES is a list of directories containing source code 21 | # INCLUDES is a list of directories containing extra header files 22 | #--------------------------------------------------------------------------------- 23 | TARGET := seta-gx 24 | BUILD := build 25 | SOURCES := src \ 26 | src/osd \ 27 | src/sgx 28 | # src/sh2/mame 29 | 30 | DATA := #res 31 | INCLUDES := 32 | 33 | #--------------------------------------------------------------------------------- 34 | # options for code generation 35 | #--------------------------------------------------------------------------------- 36 | DDEFINES= -DUSE_WIIGX -DWIICONVERTASM 37 | #DDEFINES+= -Dmain=SDL_main 38 | DDEFINES+= -DHW_RVL 39 | DDEFINES+= -DDRC_SH2 40 | DDEFINES+= -DEXEC_FROM_CACHE 41 | DDEFINES+= -DOPTIMIZED_DMA 42 | DDEFINES+= -DHAVE_Q68 43 | DDEFINES+= -DQ68_DISABLE_ADDRESS_ERROR 44 | DDEFINES+= -DUSE_SCSP2 45 | DDEFINES+= -DSCSP_PLUGIN 46 | DDEFINES+= -DWORDS_BIGENDIAN 47 | DDEFINES+= -DAUTOLOADPLUGIN 48 | DDEFINES+= -DHAVE_STRCASECMP 49 | 50 | VDEFINES=-DPACKAGE=\"saturn-gx\" -DVERSION=\"r2926\" -DWIIVERSION=\"ver.\ 1.0\" -DREENTRANT_SYSCALLS_PROVIDED 51 | 52 | MACHDEP = -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float -fsigned-char -ffast-math -funroll-loops -fauto-inc-dec -finline-functions #-fomit-frame-pointer 53 | 54 | #This is only for profiling with gperf 55 | MACHDEP += #-fomit-frame-pointer 56 | CFLAGS = -g -O2 -Wall -static -falign-functions=2 $(MACHDEP) $(DDEFINES) $(VDEFINES) $(INCLUDE) 57 | #CFLAGS = $(DDEFINES) -g -Ofast -mrvl -Wall $(MACHDEP) -$(INDLUDE) 58 | CXXFLAGS = $(CFLAGS) 59 | 60 | LDFLAGS = -g $(MACHDEP) -mrvl -Wl,-Map,$(notdir $@).map -static 61 | 62 | 63 | #--------------------------------------------------------------------------------- 64 | # any extra libraries we wish to link with the project 65 | #--------------------------------------------------------------------------------- 66 | LIBS := -laesnd -lfat -lwiiuse -lbte -logc -lchdr -llzma -lzstd -lm -lz 67 | 68 | #--------------------------------------------------------------------------------- 69 | # list of directories containing libraries, this must be the top level containing 70 | # include and lib 71 | #--------------------------------------------------------------------------------- 72 | LIBDIRS := $(PORTLIBS) 73 | 74 | #--------------------------------------------------------------------------------- 75 | # no real need to edit anything past this point unless you need to add additional 76 | # rules for different file extensions 77 | #--------------------------------------------------------------------------------- 78 | ifneq ($(BUILD),$(notdir $(CURDIR))) 79 | #--------------------------------------------------------------------------------- 80 | 81 | export OUTPUT := $(CURDIR)/$(TARGET) 82 | 83 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 84 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ 85 | $(foreach dir,$(TEXTURES),$(CURDIR)/$(dir)) 86 | 87 | export DEPSDIR := $(CURDIR)/$(BUILD) 88 | 89 | #--------------------------------------------------------------------------------- 90 | # automatically build a list of object files for our project 91 | #--------------------------------------------------------------------------------- 92 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 93 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 94 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 95 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) 96 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 97 | SCFFILES := $(foreach dir,$(TEXTURES),$(notdir $(wildcard $(dir)/*.scf))) 98 | TPLFILES := $(SCFFILES:.scf=.tpl) 99 | 100 | #--------------------------------------------------------------------------------- 101 | # use CXX for linking C++ projects, CC for standard C 102 | #--------------------------------------------------------------------------------- 103 | ifeq ($(strip $(CPPFILES)),) 104 | export LD := $(CC) 105 | else 106 | export LD := $(CXX) 107 | endif 108 | 109 | export OFILES_BIN := $(addsuffix .o,$(BINFILES)) $(addsuffix .o,$(TPLFILES)) 110 | export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) 111 | export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) m68kops.o m68kcpu.o m68kopdm.o m68kopac.o m68kopdm.o m68kopnz.o 112 | 113 | export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(addsuffix .h,$(subst .,_,$(TPLFILES))) 114 | 115 | #--------------------------------------------------------------------------------- 116 | # build a list of include paths 117 | #--------------------------------------------------------------------------------- 118 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 119 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 120 | -I$(CURDIR)/$(BUILD) \ 121 | -I$(LIBOGC_INC) 122 | 123 | #--------------------------------------------------------------------------------- 124 | # build a list of library paths 125 | #--------------------------------------------------------------------------------- 126 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ 127 | -L$(LIBOGC_LIB) 128 | 129 | export OUTPUT := $(CURDIR)/$(TARGET) 130 | .PHONY: $(BUILD) clean 131 | 132 | #--------------------------------------------------------------------------------- 133 | $(BUILD): 134 | @echo $(INCLUDE) $(LIBPATHS) 135 | @[ -d $@ ] || mkdir -p $@ 136 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 137 | cp $(OUTPUT).dol SetaGX/boot.dol 138 | size -A -d $(OUTPUT).elf | grep -w --color .text 139 | 140 | 141 | #--------------------------------------------------------------------------------- 142 | clean: 143 | @echo clean ... 144 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol 145 | 146 | #--------------------------------------------------------------------------------- 147 | run: 148 | wiiload $(TARGET).dol 149 | 150 | 151 | #--------------------------------------------------------------------------------- 152 | else 153 | 154 | DEPENDS := $(OFILES:.o=.d) 155 | 156 | #--------------------------------------------------------------------------------- 157 | # main targets 158 | #--------------------------------------------------------------------------------- 159 | $(OUTPUT).dol: $(OUTPUT).elf 160 | $(OUTPUT).elf: $(OFILES) 161 | 162 | $(OFILES_SOURCES) : $(HFILES) 163 | 164 | #--------------------------------------------------------------------------------- 165 | # This rule links in binary data with the .bin extension 166 | #--------------------------------------------------------------------------------- 167 | %.bin.o : %.bin 168 | #--------------------------------------------------------------------------------- 169 | @echo $(notdir $<) 170 | $(bin2o) 171 | 172 | c68k/c68kexec.o: 173 | $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c c68k/c68kexec.c -o $@ 174 | 175 | 176 | m68kops.o: 177 | $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c $(CURDIR)/../src/musashi/m68kops.c -o $@ 178 | 179 | m68kcpu.o: 180 | $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c $(CURDIR)/../src/musashi/m68kcpu.c -o $@ 181 | 182 | m68kopac.o: 183 | $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c $(CURDIR)/../src/musashi/m68kopac.c -o $@ 184 | 185 | m68kopdm.o: 186 | $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c $(CURDIR)/../src/musashi/m68kopdm.c -o $@ 187 | 188 | m68kopnz.o: 189 | $(CC) $(VDEFINES) $(DDEFINES) -mrvl -Wall $(MACHDEP) -I$(LIBOGC_INC) -c $(CURDIR)/../src/musashi/m68kopnz.c -o $@ 190 | 191 | 192 | 193 | -include $(DEPSDIR)/*.d 194 | 195 | #--------------------------------------------------------------------------------- 196 | endif 197 | #--------------------------------------------------------------------------------- 198 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Seta GX 2 | 3 | **_Seta GX_** is an experimental Sega Saturn emulator for the Wii. The original Yabause Wii port was heavily modified and simplified. A couple of improvements (namely CHD support and SCU emulation) come from devmiyax's [Yaba Sanshiro](https://github.com/devmiyax/yabause). The main speed improvement comes from hardware accelerated rendering by using some tricks of the Hollywood GPU. 4 | 5 | This software is licensed under the GNU General Public License v2, available at: http://www.gnu.org/licenses/gpl-2.0.txt This requires any released modifications to be licensed similarly, and to have the source available. 6 | 7 | **DISCLAIMER:** This project is experimental and in no way close to good in terms of code quality and stability (this is to be expected), so you may find a lot of bugs/crashes/softlocks. 8 | 9 | ## Features 10 | 11 | - CUE or CHD file support. 12 | - WiiMote, Classic and GameCube controller support. 13 | - SD and/or USB storage (FAT32). 14 | - Can save games. 15 | 16 | ## Installation 17 | 18 | Download and extract the latest release. Copy the `apps/SetaGX` folder into the `apps` folder located on the root of your USB/SD card. From the root of your USB/SD card, games must be stored in a `vgames/Saturn` directory, saves will be located in a `saves/Saturn` directory, be sure to create these beforehand (Note: the paths are case sensitive). 19 | 20 | > **BIOS NOT INCLUDED:** In order to start the emulator, you need to provide your own BIOS. Place a Saturn BIOS file inside the `apps/SetaGX/` folder with the name `bios.bin`. 21 | 22 | ## Controller Mapping 23 | 24 | Remapping is planned, but the following is the standard mapping: 25 | 26 | | Sega Saturn | GameCube | WiiMote | Classic | 27 | |-------------|-----------|---------|---------| 28 | | D-pad | D-pad | D-pad | D-pad | 29 | | A | B | A | Y | 30 | | B | A | 1 | B | 31 | | C | X | 2 | A | 32 | | X | Cstick-UP | - | X | 33 | | Y | Y | B | ZL | 34 | | Z | Z | | ZR | 35 | | R | R | | R | 36 | | L | L | | L | 37 | | Start | Start | + | + | 38 | 39 | To return to the menu press **Start + Z** on GameCube Controller and **Home** on Wii controllers, this will close the game so save before doing this. In the menu you can select a game and press A/2 to start it (if you start a game while holding R a FPS counter will show), pressing B/1 will return to the Homebrew Channel. 40 | 41 | ## Credits/Special Thanks 42 | 43 | - Yabause Team: Original soure code 44 | - Devmiyax: Updates to Yabause trough Yaba Sanshiro 45 | - Extrems: Help on GX issues 46 | - emu_kidid & Pcercuei: Their continued work on WiiSX helped inspire this endeavor 47 | - tueidj: Virtual memory code 48 | -------------------------------------------------------------------------------- /deps/wii-install-deps-linux.sh: -------------------------------------------------------------------------------- 1 | 2 | git clone https://github.com/rtissera/libchdr.git 3 | 4 | cd libchdr/ 5 | /opt/devkitpro/devkitPPC/bin/powerpc-eabi-cmake 6 | make chdr-static 7 | #move all generated files 8 | sudo rsync -av include/libchdr /opt/devkitpro/portlibs/ppc/include 9 | sudo rsync -av include/dr_libs /opt/devkitpro/portlibs/ppc/include 10 | sudo cp libchdr-static.a /opt/devkitpro/portlibs/ppc/lib/libchdr.a 11 | 12 | sudo rsync -av deps/lzma*/include /opt/devkitpro/portlibs/ppc/include 13 | sudo cp deps/lzma*/liblzma.a /opt/devkitpro/portlibs/ppc/lib/liblzma.a 14 | sudo cp deps/zstd*/build/cmake/lib/libzstd.a /opt/devkitpro/portlibs/ppc/lib/libzstd.a 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/bios.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2006 Theo Berkau 2 | 3 | This file is part of Yabause. 4 | 5 | Yabause is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Yabause is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Yabause; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef BIOS_H 21 | #define BIOS_H 22 | 23 | #include "sh2core.h" 24 | 25 | typedef struct 26 | { 27 | char filename[12]; 28 | char comment[11]; 29 | u8 language; 30 | u8 year; 31 | u8 month; 32 | u8 day; 33 | u8 hour; 34 | u8 minute; 35 | u8 week; 36 | u32 datasize; 37 | u16 blocksize; 38 | } saveinfo_struct; 39 | 40 | typedef struct 41 | { 42 | u8 id; 43 | char name[32]; 44 | } deviceinfo_struct; 45 | 46 | void BiosInit(void); 47 | int FASTCALL BiosHandleFunc(SH2_struct * sh); 48 | 49 | deviceinfo_struct *BupGetDeviceList(int *numdevices); 50 | int BupGetStats(u32 device, u32 *freespace, u32 *maxspace); 51 | saveinfo_struct *BupGetSaveList(u32 device, int *numsaves); 52 | int BupDeleteSave(u32 device, const char *savename); 53 | void BupFormat(u32 device); 54 | int BupCopySave(u32 srcdevice, u32 dstdevice, const char *savename); 55 | int BupImportSave(u32 device, const char *filename); 56 | int BupExportSave(u32 device, const char *savename, const char *filename); 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /src/cart.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "cart.h" 5 | 6 | WriteFunc8 cs0_write8; 7 | WriteFunc16 cs0_write16; 8 | WriteFunc32 cs0_write32; 9 | ReadFunc8 cs0_read8; 10 | ReadFunc16 cs0_read16; 11 | ReadFunc32 cs0_read32; 12 | 13 | Cartridge cart; 14 | 15 | 16 | /*No cart RW functions*/ 17 | static u8 cs0_NoneRead8(u32 addr) { return 0xFF;} 18 | static u16 cs0_NoneRead16(u32 addr) { return 0xFFFF;} 19 | static u32 cs0_NoneRead32(u32 addr) { return 0xFFFFFFFF;} 20 | 21 | static void cs0_NoneWrite8(u32 addr, u8 val) {} 22 | static void cs0_NoneWrite16(u32 addr, u16 val) {} 23 | static void cs0_NoneWrite32(u32 addr, u32 val) {} 24 | 25 | 26 | /*1MB RAM RW functions*/ 27 | static u8 cs0_1MBRamRead8(u32 addr) 28 | { 29 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0x50; 30 | addr = (addr & 0x7FFFF) | (addr & 0x200000) >> 2; 31 | if (mask) { 32 | return cart.data[addr]; 33 | } 34 | return 0xFF; 35 | } 36 | 37 | static u16 cs0_1MBRamRead16(u32 addr) 38 | { 39 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0x50; 40 | addr = (addr & 0x7FFFF) | (addr & 0x200000) >> 2; 41 | if (mask) { 42 | return *((u16*)(cart.data + addr)); 43 | } 44 | return 0xFFFF; 45 | } 46 | 47 | static u32 cs0_1MBRamRead32(u32 addr) 48 | { 49 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0x50; 50 | addr = (addr & 0x7FFFF) | (addr & 0x200000) >> 2; 51 | if (mask) { 52 | return *((u32*)(cart.data + addr)); 53 | } 54 | return 0xFFFFFFFF; 55 | } 56 | 57 | static void cs0_1MBRamWrite8(u32 addr, u8 val) 58 | { 59 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0x50; 60 | addr = (addr & 0x7FFFF) | (addr & 0x200000) >> 2; 61 | if (mask) { 62 | cart.data[addr] = val; 63 | } 64 | } 65 | 66 | static void cs0_1MBRamWrite16(u32 addr, u16 val) 67 | { 68 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0x50; 69 | addr = (addr & 0x7FFFF) | (addr & 0x200000) >> 2; 70 | if (mask) { 71 | *((u16*)(cart.data + addr)) = val; 72 | } 73 | } 74 | 75 | static void cs0_1MBRamWrite32(u32 addr, u32 val) 76 | { 77 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0x50; 78 | addr = (addr & 0x7FFFF) | (addr & 0x200000) >> 2; 79 | if (mask) { 80 | *((u32*)(cart.data + addr)) = val; 81 | } 82 | } 83 | 84 | 85 | /*4MB RAM RW functions*/ 86 | static u8 cs0_4MBRamRead8(u32 addr) 87 | { 88 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0xF0; 89 | if (mask) { 90 | return cart.data[addr]; 91 | } 92 | return 0xFF; 93 | } 94 | 95 | static u16 cs0_4MBRamRead16(u32 addr) 96 | { 97 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0xF0; 98 | if (mask) { 99 | return *((u16*)(cart.data + addr)); 100 | } 101 | return 0xFFFF; 102 | } 103 | 104 | static u32 cs0_4MBRamRead32(u32 addr) 105 | { 106 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0xF0; 107 | if (mask) { 108 | return *((u32*)(cart.data + addr)); 109 | } 110 | return 0xFFFFFFFF; 111 | } 112 | 113 | static void cs0_4MBRamWrite8(u32 addr, u8 val) 114 | { 115 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0xF0; 116 | if (mask) { 117 | cart.data[addr] = val; 118 | } 119 | } 120 | 121 | static void cs0_4MBRamWrite16(u32 addr, u16 val) 122 | { 123 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0xF0; 124 | if (mask) { 125 | *((u16*)(cart.data + addr)) = val; 126 | } 127 | } 128 | 129 | static void cs0_4MBRamWrite32(u32 addr, u32 val) 130 | { 131 | u32 mask = (1 << ((addr >> 20) & 0x1F)) & 0xF0; 132 | if (mask) { 133 | *((u32*)(cart.data + addr)) = val; 134 | } 135 | } 136 | 137 | 138 | /*2MB ROM RW functions*/ 139 | static u8 cs0_RomRead8(u32 addr) 140 | { 141 | return cart.data[addr & 0x1FFFFF]; 142 | } 143 | 144 | static u16 cs0_RomRead16(u32 addr) 145 | { 146 | return *((u16*)(cart.data + (addr & 0x1FFFFF))); 147 | } 148 | 149 | static u32 cs0_RomRead32(u32 addr) 150 | { 151 | return *((u32*)(cart.data + (addr & 0x1FFFFF))); 152 | } 153 | 154 | static void cs0_RomWrite8(u32 addr, u8 val) 155 | { 156 | cart.data[addr & 0x1FFFFF] = val; 157 | } 158 | 159 | static void cs0_RomWrite16(u32 addr, u16 val) 160 | { 161 | *((u16*)(cart.data + (addr & 0x1FFFFF))) = val; 162 | } 163 | 164 | static void cs0_RomWrite32(u32 addr, u32 val) 165 | { 166 | *((u32*)(cart.data + (addr & 0x1FFFFF))) = val; 167 | } 168 | 169 | 170 | /*CS1 area RW functions (This is used for determining CS0 cart type)*/ 171 | u8 cs1_Read8(u32 addr) 172 | { 173 | return cart.id | (-(addr != 0xFFFFFF)); 174 | } 175 | 176 | u16 cs1_Read16(u32 addr) 177 | { 178 | return cart.id | (-(addr != 0xFFFFFE)); 179 | } 180 | 181 | u32 cs1_Read32(u32 addr) 182 | { 183 | return cart.id | (-(addr != 0xFFFFFC)); 184 | } 185 | 186 | void cs1_Write8(u32 addr, u8 val) {/*Does nothing*/} 187 | void cs1_Write16(u32 addr, u16 val) {/*Does nothing*/} 188 | void cs1_Write32(u32 addr, u32 val) {/*Does nothing*/} 189 | 190 | 191 | //================================= 192 | // Cartridge area functions 193 | //================================= 194 | 195 | u32 cart_Init(u32 type, const char * filename) 196 | { 197 | cart.type = type; 198 | cart.id = 0xFFFFFFFF; 199 | 200 | cs0_write8 = cs0_NoneWrite8; 201 | cs0_write16 = cs0_NoneWrite16; 202 | cs0_write32 = cs0_NoneWrite32; 203 | cs0_read8 = cs0_NoneRead8; 204 | cs0_read16 = cs0_NoneRead16; 205 | cs0_read32 = cs0_NoneRead32; 206 | 207 | switch(type) { 208 | /*1MB RAM Cartridge*/ 209 | case CART_TYPE_RAM1MB: { 210 | if (!(cart.data = (u8*) memalign(32, 0x100000))) { 211 | return -1; 212 | } 213 | 214 | cart.id = 0xFF5AFF5A; 215 | cs0_write8 = cs0_1MBRamWrite8; 216 | cs0_write16 = cs0_1MBRamWrite16; 217 | cs0_write32 = cs0_1MBRamWrite32; 218 | cs0_read8 = cs0_1MBRamRead8; 219 | cs0_read16 = cs0_1MBRamRead16; 220 | cs0_read32 = cs0_1MBRamRead32; 221 | } break; 222 | /*4MB RAM Cartridge*/ 223 | case CART_TYPE_RAM4MB: { 224 | if (!(cart.data = (u8*) memalign(32, 0x400000))) { 225 | return -1; 226 | } 227 | 228 | cart.id = 0xFF5CFF5C; 229 | cs0_write8 = cs0_4MBRamWrite8; 230 | cs0_write16 = cs0_4MBRamWrite16; 231 | cs0_write32 = cs0_4MBRamWrite32; 232 | cs0_read8 = cs0_4MBRamRead8; 233 | cs0_read16 = cs0_4MBRamRead16; 234 | cs0_read32 = cs0_4MBRamRead32; 235 | } break; 236 | /*2MB ROM Cartridge*/ 237 | case CART_TYPE_ROM2MB: { 238 | if (!(cart.data = (u8*) memalign(32, 0x200000))) { 239 | return -1; 240 | } 241 | 242 | // TODO: Load the ROM 243 | 244 | cart.id = 0xFFFFFFFF; 245 | cs0_write8 = cs0_RomWrite8; 246 | cs0_write16 = cs0_RomWrite16; 247 | cs0_write32 = cs0_RomWrite32; 248 | cs0_read8 = cs0_RomRead8; 249 | cs0_read16 = cs0_RomRead16; 250 | cs0_read32 = cs0_RomRead32; 251 | } break; 252 | } 253 | 254 | return 0; 255 | } 256 | 257 | ////////////////////////////////////////////////////////////////////////////// 258 | 259 | void cart_Deinit(void) 260 | { 261 | if (cart.data) { 262 | free(cart.data); 263 | cart.data = NULL; 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /src/cart.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __CART_H__ 3 | #define __CART_H__ 4 | 5 | #include "memory.h" 6 | 7 | /* 8 | * Cart types: 9 | * Only useful cart types are included. Back-up ram 10 | * is not used since we save to file. 11 | */ 12 | #define CART_TYPE_NONE 0 13 | #define CART_TYPE_RAM1MB 1 14 | #define CART_TYPE_RAM4MB 2 15 | #define CART_TYPE_ROM2MB 3 16 | #define CART_TYPE_NETLINK 4 /*Unused*/ 17 | #define CART_TYPE_JAPMODEM 5 /*Unused*/ 18 | 19 | typedef struct Cartridge_t { 20 | u32 type; 21 | u32 id; 22 | u8 *data; 23 | } Cartridge; 24 | 25 | extern Cartridge cart; 26 | 27 | extern WriteFunc8 cs0_write8; 28 | extern WriteFunc16 cs0_write16; 29 | extern WriteFunc32 cs0_write32; 30 | extern ReadFunc8 cs0_read8; 31 | extern ReadFunc16 cs0_read16; 32 | extern ReadFunc32 cs0_read32; 33 | 34 | u8 cs1_Read8(u32 addr); 35 | u16 cs1_Read16(u32 addr); 36 | u32 cs1_Read32(u32 addr); 37 | void cs1_Write8(u32 addr, u8 val); 38 | void cs1_Write16(u32 addr, u16 val); 39 | void cs1_Write32(u32 addr, u32 val); 40 | 41 | u32 cart_Init(u32 type, const char *filename); 42 | void cart_Deinit(void); 43 | 44 | #endif /*__CART_H__*/ 45 | -------------------------------------------------------------------------------- /src/cdbase.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2004-2005 Theo Berkau 2 | Copyright 2005 Joost Peters 3 | Copyright 2006 Guillaume Duhamel 4 | 5 | This file is part of Yabause. 6 | 7 | Yabause is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | Yabause is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Yabause; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | /* 22 | Copyright 2019 devMiyax(smiyaxdev@gmail.com) 23 | 24 | This file is part of YabaSanshiro. 25 | 26 | YabaSanshiro is free software; you can redistribute it and/or modify 27 | it under the terms of the GNU General Public License as published by 28 | the Free Software Foundation; either version 2 of the License, or 29 | (at your option) any later version. 30 | 31 | YabaSanshiro is distributed in the hope that it will be useful, 32 | but WITHOUT ANY WARRANTY; without even the implied warranty of 33 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 | GNU General Public License for more details. 35 | 36 | You should have received a copy of the GNU General Public License 37 | along with YabaSanshiro; if not, write to the Free Software 38 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 39 | */ 40 | 41 | /*! \file cdbase.c 42 | \brief Header for Dummy and ISO, BIN/CUE, MDS CD Interfaces 43 | */ 44 | 45 | #ifndef CDBASE_H 46 | #define CDBASE_H 47 | 48 | #include 49 | #include "core.h" 50 | 51 | #if defined (__cplusplus) 52 | extern "C" { 53 | #endif 54 | 55 | #define CDCORE_DEFAULT -1 56 | #define CDCORE_DUMMY 0 57 | #define CDCORE_ISO 1 58 | #define CDCORE_CHD 2 59 | //#define CDCORE_ARCH 2 60 | //#define CDCORE_WEBAPI 4 61 | 62 | #define CDCORE_NORMAL 0 63 | #define CDCORE_NODISC 2 64 | #define CDCORE_OPEN 3 65 | 66 | typedef struct 67 | { 68 | int id; 69 | const char *Name; 70 | int (*Init)(const char *); 71 | void (*DeInit)(void); 72 | int (*GetStatus)(void); 73 | s32 (*ReadTOC)(u32 *TOC); 74 | int (*ReadSectorFAD)(u32 FAD, void *buffer); 75 | void (*ReadAheadFAD)(u32 FAD); 76 | void(*SetStatus)(int status); 77 | } CDInterface; 78 | 79 | extern CDInterface DummyCD; 80 | 81 | extern CDInterface ISOCD; 82 | 83 | extern CDInterface ArchCD; 84 | 85 | 86 | 87 | #if defined (__cplusplus) 88 | } 89 | #endif 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /src/core.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2005 Guillaume Duhamel 2 | Copyright 2005-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef CORE_H 22 | #define CORE_H 23 | 24 | #include 25 | #include 26 | 27 | #ifndef ALIGNED 28 | #ifdef _MSC_VER 29 | #define ALIGNED(x) __declspec(align(x)) 30 | #else 31 | #define ALIGNED(x) __attribute__((aligned(x))) 32 | #endif 33 | #endif 34 | 35 | #ifndef STDCALL 36 | #ifdef _MSC_VER 37 | #define STDCALL __stdcall 38 | #else 39 | #define STDCALL 40 | #endif 41 | #endif 42 | 43 | #ifndef FASTCALL 44 | #ifdef __MINGW32__ 45 | #define FASTCALL __attribute__((fastcall)) 46 | #elif defined (__i386__) 47 | #define FASTCALL __attribute__((regparm(3))) 48 | #else 49 | #define FASTCALL 50 | #endif 51 | #endif 52 | 53 | 54 | #ifndef INLINE 55 | #ifdef _MSC_VER 56 | #define INLINE _inline 57 | #else 58 | #define INLINE inline 59 | #endif 60 | #endif 61 | 62 | /* Wii has both stdint.h and "yabause" definitions of fixed 63 | size types */ 64 | #include 65 | typedef unsigned long pointer; 66 | 67 | 68 | typedef struct { 69 | unsigned int size; 70 | unsigned int done; 71 | } IOCheck_struct; 72 | 73 | static INLINE void ywrite(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) { 74 | check->done += (unsigned int)fwrite(ptr, size, nmemb, stream); 75 | check->size += (unsigned int)nmemb; 76 | } 77 | 78 | static INLINE void yread(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) { 79 | check->done += (unsigned int)fread(ptr, size, nmemb, stream); 80 | check->size += (unsigned int)nmemb; 81 | } 82 | 83 | static INLINE int StateWriteHeader(FILE *fp, const char *name, int version) { 84 | IOCheck_struct check; 85 | fprintf(fp, "%s", name); 86 | check.done = 0; 87 | check.size = 0; 88 | ywrite(&check, (void *)&version, sizeof(version), 1, fp); 89 | ywrite(&check, (void *)&version, sizeof(version), 1, fp); // place holder for size 90 | return (check.done == check.size) ? ftell(fp) : -1; 91 | } 92 | 93 | static INLINE int StateFinishHeader(FILE *fp, int offset) { 94 | IOCheck_struct check; 95 | int size = 0; 96 | size = ftell(fp) - offset; 97 | fseek(fp, offset - 4, SEEK_SET); 98 | check.done = 0; 99 | check.size = 0; 100 | ywrite(&check, (void *)&size, sizeof(size), 1, fp); // write true size 101 | fseek(fp, 0, SEEK_END); 102 | return (check.done == check.size) ? (size + 12) : -1; 103 | } 104 | 105 | static INLINE int StateCheckRetrieveHeader(FILE *fp, const char *name, int *version, int *size) { 106 | char id[4]; 107 | size_t ret; 108 | 109 | if ((ret = fread((void *)id, 1, 4, fp)) != 4) 110 | return -1; 111 | 112 | if (strncmp(name, id, 4) != 0) 113 | return -2; 114 | 115 | if ((ret = fread((void *)version, 4, 1, fp)) != 1) 116 | return -1; 117 | 118 | if (fread((void *)size, 4, 1, fp) != 1) 119 | return -1; 120 | 121 | return 0; 122 | } 123 | 124 | ////////////////////////////////////////////////////////////////////////////// 125 | 126 | // Terrible, but I'm not sure how to do the equivalent in inline 127 | #ifdef HAVE_C99_VARIADIC_MACROS 128 | #define AddString(s, ...) \ 129 | { \ 130 | sprintf(s, __VA_ARGS__); \ 131 | s += strlen(s); \ 132 | } 133 | #else 134 | #define AddString(s, r...) \ 135 | { \ 136 | sprintf(s, ## r); \ 137 | s += strlen(s); \ 138 | } 139 | #endif 140 | 141 | ////////////////////////////////////////////////////////////////////////////// 142 | 143 | 144 | ////////////////////////////////////////////////////////////////////////////// 145 | 146 | /* Minimum/maximum values */ 147 | 148 | #undef MIN 149 | #undef MAX 150 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) 151 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) 152 | 153 | ////////////////////////////////////////////////////////////////////////////// 154 | 155 | /* 156 | * BSWAP16(x) swaps two bytes in a 16-bit value (AABB -> BBAA) or adjacent 157 | * bytes in a 32-bit value (AABBCCDD -> BBAADDCC). 158 | * 159 | * BSWAP32(x) reverses four bytes in a 32-bit value (AABBCCDD -> DDCCBBAA). 160 | * 161 | * WSWAP32(x) swaps two 16-bit words in a 32-bit value (AABBCCDD -> CCDDAABB). 162 | * 163 | * Any of these can be left undefined if there is no platform-specific 164 | * optimization for them; the defaults below will then be used instead. 165 | */ 166 | 167 | #ifdef PSP 168 | # define BSWAP16(x) ((typeof(x)) __builtin_allegrex_wsbh((x))) 169 | # define BSWAP32(x) ((typeof(x)) __builtin_allegrex_wsbw((x))) 170 | # define WSWAP32(x) ((typeof(x)) __builtin_allegrex_rotr((x), 16)) 171 | #endif 172 | 173 | /* Defaults: */ 174 | 175 | #ifndef BSWAP16 176 | # define BSWAP16(x) (((u32)(x)>>8 & 0x00FF00FF) | ((u32)(x) & 0x00FF00FF) << 8) 177 | #endif 178 | #ifndef BSWAP32 179 | # define BSWAP32(x) ((u32)(x)>>24 | ((u32)(x)>>8 & 0xFF00) | ((u32)(x) & 0xFF00)<<8 | (u32)(x)<<24) 180 | #endif 181 | #ifndef WSWAP32 182 | # define WSWAP32(x) ((u32)(x)>>16 | (u32)(x)<<16) 183 | #endif 184 | 185 | ////////////////////////////////////////////////////////////////////////////// 186 | 187 | #ifdef __GNUC__ 188 | 189 | #define UNUSED __attribute ((unused)) 190 | 191 | #ifdef DEBUG 192 | #define USED_IF_DEBUG 193 | #else 194 | #define USED_IF_DEBUG __attribute ((unused)) 195 | #endif 196 | 197 | #ifdef SMPC_DEBUG 198 | #define USED_IF_SMPC_DEBUG 199 | #else 200 | #define USED_IF_SMPC_DEBUG __attribute ((unused)) 201 | #endif 202 | 203 | /* LIKELY(x) indicates that x is likely to be true (nonzero); 204 | * UNLIKELY(x) indicates that x is likely to be false (zero). 205 | * Use like: "if (UNLIKELY(a < b)) {...}" */ 206 | #define LIKELY(x) (__builtin_expect(!!(x), 1)) 207 | #define UNLIKELY(x) (__builtin_expect(!!(x), 0)) 208 | 209 | #else 210 | 211 | #define UNUSED 212 | #define USED_IF_DEBUG 213 | #define USED_IF_SMPC_DEBUG 214 | #define LIKELY(x) (x) 215 | #define UNLIKELY(x) (x) 216 | 217 | #endif 218 | 219 | #endif 220 | -------------------------------------------------------------------------------- /src/debug.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2005 Guillaume Duhamel 2 | Copyright 2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "debug.h" 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | ////////////////////////////////////////////////////////////////////////////// 28 | 29 | Debug * DebugInit(const char * n, DebugOutType t, char * s) { 30 | Debug * d; 31 | 32 | if ((d = (Debug *) malloc(sizeof(Debug))) == NULL) 33 | return NULL; 34 | 35 | d->output_type = t; 36 | 37 | if ((d->name = strdup(n)) == NULL) 38 | { 39 | free(d); 40 | return NULL; 41 | } 42 | 43 | switch(t) { 44 | case DEBUG_STREAM: 45 | d->output.stream = fopen(s, "w"); 46 | break; 47 | case DEBUG_STRING: 48 | d->output.string = s; 49 | break; 50 | case DEBUG_STDOUT: 51 | d->output.stream = stdout; 52 | break; 53 | case DEBUG_STDERR: 54 | d->output.stream = stderr; 55 | break; 56 | case DEBUG_CALLBACK: 57 | d->output.callback = (void (*) (char*))s; 58 | break; 59 | } 60 | 61 | return d; 62 | } 63 | 64 | ////////////////////////////////////////////////////////////////////////////// 65 | 66 | void DebugDeInit(Debug * d) { 67 | if (d == NULL) 68 | return; 69 | 70 | switch(d->output_type) { 71 | case DEBUG_STREAM: 72 | if (d->output.stream) 73 | fclose(d->output.stream); 74 | break; 75 | case DEBUG_STRING: 76 | case DEBUG_STDOUT: 77 | case DEBUG_STDERR: 78 | case DEBUG_CALLBACK: 79 | break; 80 | } 81 | if (d->name) 82 | free(d->name); 83 | free(d); 84 | } 85 | 86 | ////////////////////////////////////////////////////////////////////////////// 87 | 88 | void DebugChangeOutput(Debug * d, DebugOutType t, char * s) { 89 | if (t != d->output_type) { 90 | if (d->output_type == DEBUG_STREAM) 91 | { 92 | if (d->output.stream) 93 | fclose(d->output.stream); 94 | } 95 | d->output_type = t; 96 | } 97 | switch(t) { 98 | case DEBUG_STREAM: 99 | d->output.stream = fopen(s, "w"); 100 | break; 101 | case DEBUG_STRING: 102 | d->output.string = s; 103 | break; 104 | case DEBUG_CALLBACK: 105 | d->output.callback = (void (*) (char*))s; 106 | break; 107 | case DEBUG_STDOUT: 108 | d->output.stream = stdout; 109 | break; 110 | case DEBUG_STDERR: 111 | d->output.stream = stderr; 112 | break; 113 | } 114 | } 115 | 116 | ////////////////////////////////////////////////////////////////////////////// 117 | 118 | void DebugPrintf(Debug * d, const char * file, u32 line, const char * format, ...) { 119 | va_list l; 120 | static char strtmp[512]; 121 | static int strhash; 122 | 123 | if (d == NULL) 124 | return; 125 | 126 | va_start(l, format); 127 | 128 | switch(d->output_type) { 129 | case DEBUG_STDOUT: 130 | case DEBUG_STDERR: 131 | case DEBUG_STREAM: 132 | if (d->output.stream == NULL) 133 | break; 134 | fprintf(d->output.stream, "%s (%s:%ld): ", d->name, file, (long)line); 135 | vfprintf(d->output.stream, format, l); 136 | break; 137 | case DEBUG_STRING: 138 | { 139 | int i; 140 | if (d->output.string == NULL) 141 | break; 142 | 143 | i = sprintf(d->output.string, "%s (%s:%ld): ", d->name, file, (long)line); 144 | vsprintf(d->output.string + i, format, l); 145 | } 146 | break; 147 | case DEBUG_CALLBACK: 148 | { 149 | int i; 150 | int strnewhash = 0; 151 | i = sprintf(strtmp, "%s (%s:%ld): ", d->name, file, (long)line); 152 | i += vsprintf(strtmp + i, format, l); 153 | for ( ; i>0 ; i-- ) strnewhash += (int)(strtmp[i]); 154 | if ( strnewhash != strhash ) d->output.callback( strtmp ); 155 | strhash = strnewhash; 156 | } 157 | break; 158 | } 159 | 160 | va_end(l); 161 | } 162 | 163 | ////////////////////////////////////////////////////////////////////////////// 164 | 165 | Debug * MainLog; 166 | 167 | ////////////////////////////////////////////////////////////////////////////// 168 | 169 | void LogStart(void) { 170 | MainLog = DebugInit("main", DEBUG_STDOUT, NULL); 171 | // MainLog = DebugInit("main", DEBUG_STREAM, "stdout.txt"); 172 | } 173 | 174 | ////////////////////////////////////////////////////////////////////////////// 175 | 176 | void LogStop(void) { 177 | DebugDeInit(MainLog); 178 | MainLog = NULL; 179 | } 180 | 181 | ////////////////////////////////////////////////////////////////////////////// 182 | 183 | void LogChangeOutput(DebugOutType t, char * s) { 184 | 185 | DebugChangeOutput( MainLog, t, s ); 186 | } 187 | -------------------------------------------------------------------------------- /src/debug.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2005-2006 Guillaume Duhamel 2 | Copyright 2005 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef DEBUG_H 22 | #define DEBUG_H 23 | 24 | #include "core.h" 25 | #include 26 | 27 | typedef enum { DEBUG_STRING, DEBUG_STREAM , DEBUG_STDOUT, DEBUG_STDERR, DEBUG_CALLBACK } DebugOutType; 28 | 29 | typedef struct { 30 | DebugOutType output_type; 31 | union { 32 | FILE * stream; 33 | char * string; 34 | void (*callback) (char*); 35 | } output; 36 | char * name; 37 | } Debug; 38 | 39 | Debug * DebugInit(const char *, DebugOutType, char *); 40 | void DebugDeInit(Debug *); 41 | 42 | void DebugChangeOutput(Debug *, DebugOutType, char *); 43 | 44 | void DebugPrintf(Debug *, const char *, u32, const char *, ...); 45 | 46 | extern Debug * MainLog; 47 | 48 | void LogStart(void); 49 | void LogStop(void); 50 | void LogChangeOutput(DebugOutType t, char * s); 51 | 52 | #ifdef DEBUG 53 | #define LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) 54 | #else 55 | #define LOG(...) 56 | #endif 57 | 58 | #ifdef CDDEBUG 59 | #define CDLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) 60 | #else 61 | #define CDLOG(...) 62 | #endif 63 | 64 | #ifdef SCSP_DEBUG 65 | #define SCSPLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) 66 | #else 67 | #define SCSPLOG(...) 68 | #endif 69 | 70 | #ifdef VDP1_DEBUG 71 | #define VDP1LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) 72 | #else 73 | #define VDP1LOG(...) 74 | #endif 75 | 76 | #ifdef VDP2_DEBUG 77 | #define VDP2LOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) 78 | #else 79 | #define VDP2LOG(...) 80 | #endif 81 | 82 | #ifdef SMPC_DEBUG 83 | #define SMPCLOG(...) DebugPrintf(MainLog, __FILE__, __LINE__, __VA_ARGS__) 84 | #else 85 | #define SMPCLOG(...) 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /src/error.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2005-2006 Theo Berkau 2 | 3 | This file is part of Yabause. 4 | 5 | Yabause is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Yabause is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Yabause; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "error.h" 25 | #include "yui.h" 26 | 27 | ////////////////////////////////////////////////////////////////////////////// 28 | 29 | static void AllocAmendPrintString(const char *string1, const char *string2) 30 | { 31 | char *string; 32 | 33 | if ((string = (char *)malloc(strlen(string1) + strlen(string2) + 2)) == NULL) 34 | return; 35 | 36 | sprintf(string, "%s%s\n", string1, string2); 37 | YuiErrorMsg(string); 38 | 39 | free(string); 40 | } 41 | 42 | ////////////////////////////////////////////////////////////////////////////// 43 | 44 | void YabSetError(int type, const void *extra) 45 | { 46 | char tempstr[512]; 47 | SH2_struct *sh; 48 | 49 | switch (type) 50 | { 51 | case YAB_ERR_FILENOTFOUND: 52 | AllocAmendPrintString("File not found: ", extra); 53 | break; 54 | case YAB_ERR_MEMORYALLOC: 55 | YuiErrorMsg("Error allocating memory\n"); 56 | break; 57 | case YAB_ERR_FILEREAD: 58 | AllocAmendPrintString("Error reading file: ", extra); 59 | break; 60 | case YAB_ERR_FILEWRITE: 61 | AllocAmendPrintString("Error writing file: ", extra); 62 | break; 63 | case YAB_ERR_CANNOTINIT: 64 | AllocAmendPrintString("Cannot initialize ", extra); 65 | break; 66 | case YAB_ERR_SH2INVALIDOPCODE: 67 | sh = (SH2_struct *)extra; 68 | SH2GetRegisters(sh, &sh->regs); 69 | sprintf(tempstr, "%s SH2 invalid opcode\n\n" 70 | "R0 = %08lX\tR12 = %08lX\n" 71 | "R1 = %08lX\tR13 = %08lX\n" 72 | "R2 = %08lX\tR14 = %08lX\n" 73 | "R3 = %08lX\tR15 = %08lX\n" 74 | "R4 = %08lX\tSR = %08lX\n" 75 | "R5 = %08lX\tGBR = %08lX\n" 76 | "R6 = %08lX\tVBR = %08lX\n" 77 | "R7 = %08lX\tMACH = %08lX\n" 78 | "R8 = %08lX\tMACL = %08lX\n" 79 | "R9 = %08lX\tPR = %08lX\n" 80 | "R10 = %08lX\tPC = %08lX\n" 81 | "R11 = %08lX\n", sh->isslave ? "Slave" : "Master", 82 | (long)sh->regs.R[0], (long)sh->regs.R[12], 83 | (long)sh->regs.R[1], (long)sh->regs.R[13], 84 | (long)sh->regs.R[2], (long)sh->regs.R[14], 85 | (long)sh->regs.R[3], (long)sh->regs.R[15], 86 | (long)sh->regs.R[4], (long)sh->regs.SR.all, 87 | (long)sh->regs.R[5], (long)sh->regs.GBR, 88 | (long)sh->regs.R[6], (long)sh->regs.VBR, 89 | (long)sh->regs.R[7], (long)sh->regs.MACH, 90 | (long)sh->regs.R[8], (long)sh->regs.MACL, 91 | (long)sh->regs.R[9], (long)sh->regs.PR, 92 | (long)sh->regs.R[10], (long)sh->regs.PC, 93 | (long)sh->regs.R[11]); 94 | YuiErrorMsg(tempstr); 95 | break; 96 | case YAB_ERR_SH2READ: 97 | YuiErrorMsg("SH2 read error\n"); // fix me 98 | break; 99 | case YAB_ERR_SH2WRITE: 100 | YuiErrorMsg("SH2 write error\n"); // fix me 101 | break; 102 | case YAB_ERR_SDL: 103 | AllocAmendPrintString("SDL Error: ", extra); 104 | break; 105 | case YAB_ERR_OTHER: 106 | YuiErrorMsg((char *)extra); 107 | break; 108 | case YAB_ERR_UNKNOWN: 109 | default: 110 | YuiErrorMsg("Unknown error occurred\n"); 111 | break; 112 | } 113 | } 114 | 115 | ////////////////////////////////////////////////////////////////////////////// 116 | 117 | void YabErrorMsg(const char * format, ...) { 118 | va_list l; 119 | int n; 120 | char * buffer; 121 | 122 | va_start(l, format); 123 | n = vsnprintf(NULL, 0, format, l); 124 | va_end(l); 125 | 126 | buffer = malloc(n + 1); 127 | 128 | va_start(l, format); 129 | vsprintf(buffer, format, l); 130 | va_end(l); 131 | 132 | YuiErrorMsg(buffer); 133 | free(buffer); 134 | } 135 | 136 | ////////////////////////////////////////////////////////////////////////////// 137 | 138 | -------------------------------------------------------------------------------- /src/error.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2005-2006 Theo Berkau 2 | 3 | This file is part of Yabause. 4 | 5 | Yabause is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Yabause is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Yabause; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef ERROR_H 21 | #define ERROR_H 22 | 23 | #define YAB_ERR_UNKNOWN 0 24 | #define YAB_ERR_FILENOTFOUND 1 25 | #define YAB_ERR_MEMORYALLOC 2 26 | #define YAB_ERR_FILEREAD 3 27 | #define YAB_ERR_FILEWRITE 4 28 | #define YAB_ERR_CANNOTINIT 5 29 | 30 | #define YAB_ERR_SH2INVALIDOPCODE 6 31 | #define YAB_ERR_SH2READ 7 32 | #define YAB_ERR_SH2WRITE 8 33 | 34 | #define YAB_ERR_SDL 9 35 | 36 | #define YAB_ERR_OTHER 10 37 | 38 | void YabSetError(int type, const void *extra); 39 | #endif 40 | -------------------------------------------------------------------------------- /src/m68kcore.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2007 Guillaume Duhamel 2 | 3 | This file is part of Yabause. 4 | 5 | Yabause is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Yabause is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Yabause; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include "m68kcore.h" 21 | #include "memory.h" 22 | #include "musashi/m68k.h" 23 | #include "musashi/m68kcpu.h" 24 | 25 | extern u8 * SoundRam; 26 | 27 | //TODO: this should not be done this way.. implement directly 28 | M68K_READ *mus_read8; 29 | M68K_READ *mus_read16; 30 | M68K_WRITE *mus_write8; 31 | M68K_WRITE *mus_write16; 32 | 33 | 34 | int musashi_Init(void) 35 | { 36 | m68k_init(); 37 | m68k_set_reset_instr_callback(m68k_pulse_reset); 38 | m68k_set_cpu_type(M68K_CPU_TYPE_68000); 39 | return 0; 40 | } 41 | 42 | void musashi_DeInit(void) 43 | { 44 | //Does nothing 45 | } 46 | 47 | void musashi_Reset(void) 48 | { 49 | m68k_pulse_reset(); 50 | } 51 | 52 | s32 musashi_Exec(s32 cycles) 53 | { 54 | return m68k_execute(cycles); 55 | } 56 | 57 | void musashi_Sync(void) 58 | { 59 | //Does nothing 60 | } 61 | 62 | 63 | u32 musashi_GetDReg(u32 n) 64 | { 65 | return m68k_get_reg(NULL, M68K_REG_D0 + n); 66 | } 67 | 68 | u32 musashi_GetAReg(u32 n) 69 | { 70 | return m68k_get_reg(NULL, M68K_REG_A0 + n); 71 | } 72 | 73 | u32 musashi_GetPC(void) 74 | { 75 | return m68k_get_reg(NULL, M68K_REG_PC); 76 | } 77 | 78 | u32 musashi_GetSR(void) 79 | { 80 | return m68k_get_reg(NULL, M68K_REG_SR); 81 | } 82 | 83 | u32 musashi_GetUSP(void) 84 | { 85 | return m68k_get_reg(NULL, M68K_REG_USP); 86 | } 87 | 88 | u32 musashi_GetMSP(void) 89 | { 90 | return m68k_get_reg(NULL, M68K_REG_MSP); 91 | } 92 | 93 | void musashi_SetDReg(u32 n, u32 val) 94 | { 95 | m68k_set_reg(M68K_REG_D0 + n, val); 96 | } 97 | 98 | void musashi_SetAReg(u32 n, u32 val) 99 | { 100 | m68k_set_reg(M68K_REG_A0 + n, val); 101 | } 102 | 103 | void musashi_SetPC(u32 val) 104 | { 105 | m68k_set_reg(M68K_REG_PC, val); 106 | } 107 | 108 | void musashi_SetSR(u32 val) 109 | { 110 | m68k_set_reg(M68K_REG_SR, val); 111 | } 112 | 113 | void musashi_SetUSP(u32 val) 114 | { 115 | m68k_set_reg(M68K_REG_USP, val); 116 | } 117 | 118 | void musashi_SetMSP(u32 val) 119 | { 120 | m68k_set_reg(M68K_REG_MSP, val); 121 | } 122 | 123 | void musashi_SetFetch(u32 low_adr, u32 high_adr, pointer fetch_addr) 124 | { 125 | //Does nothing 126 | } 127 | 128 | void FASTCALL musashi_SetIRQ(s32 level) 129 | { 130 | if (level) { 131 | m68k_set_irq(level); 132 | } 133 | } 134 | 135 | void FASTCALL musashi_WriteNotify(u32 address, u32 size) 136 | { 137 | //Does nothing 138 | } 139 | 140 | void musashi_SetReadB(M68K_READ *func) 141 | { 142 | mus_read8 = func; 143 | } 144 | 145 | void musashi_SetReadW(M68K_READ *func) 146 | { 147 | mus_read16 = func; 148 | } 149 | 150 | void musashi_SetWriteB(M68K_WRITE *func) 151 | { 152 | mus_write8 = func; 153 | } 154 | 155 | void musashi_SetWriteW(M68K_WRITE *func) 156 | { 157 | mus_write16 = func; 158 | } 159 | 160 | //Implementation for musashi read/write functions 161 | u32 m68k_read_memory_8(u32 address) 162 | { 163 | return mus_read8(address); 164 | } 165 | 166 | u32 m68k_read_memory_16(u32 address) 167 | { 168 | return mus_read16(address); 169 | } 170 | 171 | u32 m68k_read_memory_32(u32 address) 172 | { 173 | return ((((u32)mus_read16(address)) << 16) | mus_read16(address + 2)); 174 | } 175 | 176 | void m68k_write_memory_8(u32 address, u32 value) 177 | { 178 | mus_write8(address, value); 179 | } 180 | 181 | void m68k_write_memory_16(u32 address, u32 value) 182 | { 183 | mus_write16(address, value); 184 | } 185 | 186 | void m68k_write_memory_32(u32 address, u32 value) 187 | { 188 | mus_write16(address, value >> 16); 189 | mus_write16(address + 2, value & 0xFFFFu); 190 | } 191 | -------------------------------------------------------------------------------- /src/m68kcore.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2007 Guillaume Duhamel 2 | 3 | This file is part of Yabause. 4 | 5 | Yabause is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Yabause is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Yabause; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef M68KCORE_H 21 | #define M68KCORE_H 22 | 23 | #include "core.h" 24 | 25 | #define M68KCORE_DEFAULT -1 26 | #define M68KCORE_DUMMY 0 27 | #define M68KCORE_C68K 1 28 | #define M68KCORE_Q68 2 29 | 30 | typedef u32 FASTCALL M68K_READ(const u32 adr); 31 | typedef void FASTCALL M68K_WRITE(const u32 adr, u32 data); 32 | 33 | int musashi_Init(void); 34 | void musashi_DeInit(void); 35 | void musashi_Reset(void); 36 | s32 musashi_Exec(s32 cycles); 37 | void musashi_Sync(void); 38 | u32 musashi_GetDReg(u32 n); 39 | u32 musashi_GetAReg(u32 n); 40 | u32 musashi_GetPC(void); 41 | u32 musashi_GetSR(void); 42 | u32 musashi_GetUSP(void); 43 | u32 musashi_GetMSP(void); 44 | void musashi_SetDReg(u32 n, u32 val); 45 | void musashi_SetAReg(u32 n, u32 val); 46 | void musashi_SetPC(u32 val); 47 | void musashi_SetSR(u32 val); 48 | void musashi_SetUSP(u32 val); 49 | void musashi_SetMSP(u32 val); 50 | void musashi_SetFetch(u32 low_adr, u32 high_adr, pointer fetch_addr); 51 | void FASTCALL musashi_SetIRQ(s32 level); 52 | void FASTCALL musashi_WriteNotify(u32 address, u32 size); 53 | void musashi_SetReadB(M68K_READ *func); 54 | void musashi_SetReadW(M68K_READ *func); 55 | void musashi_SetWriteB(M68K_WRITE *func); 56 | void musashi_SetWriteW(M68K_WRITE *func); 57 | //Implementation for musashi read/write functions 58 | u32 m68k_read_memory_8(u32 address); 59 | u32 m68k_read_memory_16(u32 address); 60 | u32 m68k_read_memory_32(u32 address); 61 | void m68k_write_memory_8(u32 address, u32 value); 62 | void m68k_write_memory_16(u32 address, u32 value); 63 | void m68k_write_memory_32(u32 address, u32 value); 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2005-2006 Guillaume Duhamel 2 | Copyright 2005 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef MEMORY_H 22 | #define MEMORY_H 23 | 24 | #include 25 | #include "core.h" 26 | //#include "sh2core.h" 27 | 28 | /* Type 1 Memory, faster for byte (8 bits) accesses */ 29 | 30 | u8 * T1MemoryInit(u32); 31 | void T1MemoryDeInit(u8 *); 32 | 33 | static INLINE u8 T1ReadByte(u8 * mem, u32 addr) 34 | { 35 | return mem[addr]; 36 | } 37 | 38 | static INLINE u16 T1ReadWord(u8 * mem, u32 addr) 39 | { 40 | return *((u16 *) (mem + addr)); 41 | } 42 | 43 | static INLINE u32 T1ReadLong(u8 * mem, u32 addr) 44 | { 45 | return *((u32 *) (mem + addr)); 46 | } 47 | 48 | static INLINE void T1WriteByte(u8 * mem, u32 addr, u8 val) 49 | { 50 | mem[addr] = val; 51 | } 52 | 53 | static INLINE void T1WriteWord(u8 * mem, u32 addr, u16 val) 54 | { 55 | *((u16 *) (mem + addr)) = val; 56 | } 57 | 58 | static INLINE void T1WriteLong(u8 * mem, u32 addr, u32 val) 59 | { 60 | *((u32 *) (mem + addr)) = val; 61 | } 62 | 63 | /* Type 2 Memory, faster for word (16 bits) accesses */ 64 | 65 | #define T2MemoryInit(x) (T1MemoryInit(x)) 66 | #define T2MemoryDeInit(x) (T1MemoryDeInit(x)) 67 | 68 | static INLINE u8 T2ReadByte(u8 * mem, u32 addr) 69 | { 70 | return mem[addr]; 71 | } 72 | 73 | static INLINE u16 T2ReadWord(u8 * mem, u32 addr) 74 | { 75 | return *((u16 *) (mem + addr)); 76 | } 77 | 78 | static INLINE u32 T2ReadLong(u8 * mem, u32 addr) 79 | { 80 | return *((u32 *) (mem + addr)); 81 | } 82 | 83 | static INLINE void T2WriteByte(u8 * mem, u32 addr, u8 val) 84 | { 85 | mem[addr] = val; 86 | } 87 | 88 | static INLINE void T2WriteWord(u8 * mem, u32 addr, u16 val) 89 | { 90 | *((u16 *) (mem + addr)) = val; 91 | } 92 | 93 | static INLINE void T2WriteLong(u8 * mem, u32 addr, u32 val) 94 | { 95 | *((u32 *) (mem + addr)) = val; 96 | } 97 | 98 | /* Type 3 Memory, faster for long (32 bits) accesses */ 99 | 100 | typedef struct 101 | { 102 | u8 * base_mem; 103 | u8 * mem; 104 | } T3Memory; 105 | 106 | T3Memory * T3MemoryInit(u32); 107 | void T3MemoryDeInit(T3Memory *); 108 | 109 | static INLINE u8 T3ReadByte(T3Memory * mem, u32 addr) 110 | { 111 | return mem->mem[addr]; 112 | } 113 | 114 | static INLINE u16 T3ReadWord(T3Memory * mem, u32 addr) 115 | { 116 | return *((u16 *) (mem->mem + addr)); 117 | } 118 | 119 | static INLINE u32 T3ReadLong(T3Memory * mem, u32 addr) 120 | { 121 | return *((u32 *) (mem->mem + addr)); 122 | } 123 | 124 | static INLINE void T3WriteByte(T3Memory * mem, u32 addr, u8 val) 125 | { 126 | mem->mem[addr] = val; 127 | } 128 | 129 | static INLINE void T3WriteWord(T3Memory * mem, u32 addr, u16 val) 130 | { 131 | *((u16 *) (mem->mem + addr)) = val; 132 | } 133 | 134 | static INLINE void T3WriteLong(T3Memory * mem, u32 addr, u32 val) 135 | { 136 | *((u32 *) (mem->mem + addr)) = val; 137 | } 138 | 139 | static INLINE int T123Load(void * mem, u32 size, int type, const char *filename) 140 | { 141 | FILE *fp; 142 | u32 filesize, filesizecheck; 143 | u8 *buffer; 144 | u32 i; 145 | 146 | if (!filename) 147 | return -1; 148 | 149 | if ((fp = fopen(filename, "rb")) == NULL) 150 | return -1; 151 | 152 | // Calculate file size 153 | fseek(fp, 0, SEEK_END); 154 | filesize = ftell(fp); 155 | fseek(fp, 0, SEEK_SET); 156 | 157 | if (filesize > size) 158 | return -1; 159 | 160 | if ((buffer = (u8 *)malloc(filesize)) == NULL) 161 | { 162 | fclose(fp); 163 | return -1; 164 | } 165 | 166 | filesizecheck = (u32)fread((void *)buffer, 1, filesize, fp); 167 | fclose(fp); 168 | 169 | if (filesizecheck != filesize) return -1; 170 | 171 | switch (type) 172 | { 173 | case 1: 174 | { 175 | for (i = 0; i < filesize; i++) 176 | T1WriteByte((u8 *) mem, i, buffer[i]); 177 | break; 178 | } 179 | case 2: 180 | { 181 | for (i = 0; i < filesize; i++) 182 | T2WriteByte((u8 *) mem, i, buffer[i]); 183 | break; 184 | } 185 | case 3: 186 | { 187 | for (i = 0; i < filesize; i++) 188 | T3WriteByte((T3Memory *) mem, i, buffer[i]); 189 | break; 190 | } 191 | default: 192 | { 193 | free(buffer); 194 | return -1; 195 | } 196 | } 197 | 198 | free(buffer); 199 | 200 | return 0; 201 | } 202 | 203 | static INLINE int T123Save(void * mem, u32 size, int type, const char *filename) 204 | { 205 | FILE *fp; 206 | u8 *buffer; 207 | u32 i; 208 | u32 sizecheck; 209 | 210 | if (filename == NULL) 211 | return 0; 212 | 213 | if (filename[0] == 0x00) 214 | return 0; 215 | 216 | if ((buffer = (u8 *)malloc(size)) == NULL) 217 | return -1; 218 | 219 | switch (type) 220 | { 221 | case 1: 222 | { 223 | for (i = 0; i < size; i++) 224 | buffer[i] = T1ReadByte((u8 *) mem, i); 225 | break; 226 | } 227 | case 2: 228 | { 229 | for (i = 0; i < size; i++) 230 | buffer[i] = T2ReadByte((u8 *) mem, i); 231 | break; 232 | } 233 | case 3: 234 | { 235 | for (i = 0; i < size; i++) 236 | buffer[i] = T3ReadByte((T3Memory *) mem, i); 237 | break; 238 | } 239 | default: 240 | { 241 | free(buffer); 242 | return -1; 243 | } 244 | } 245 | 246 | if ((fp = fopen(filename, "wb")) == NULL) 247 | { 248 | free(buffer); 249 | return -1; 250 | } 251 | 252 | sizecheck = (u32)fwrite((void *)buffer, 1, size, fp); 253 | fclose(fp); 254 | free(buffer); 255 | 256 | if (sizecheck != size) return -1; 257 | 258 | return 0; 259 | } 260 | 261 | 262 | 263 | void MappedMemoryInit(void); 264 | /* 265 | u8 FASTCALL mem_Read8(u32 addr); 266 | u16 FASTCALL mem_Read16(u32 addr); 267 | u32 FASTCALL mem_Read32(u32 addr); 268 | void FASTCALL mem_Write8(u32 addr, u8 val); 269 | void FASTCALL mem_Write16(u32 addr, u16 val); 270 | void FASTCALL mem_Write32(u32 addr, u32 val); 271 | */ 272 | 273 | 274 | u8 FASTCALL mem_Read8(u32 addr); 275 | u16 FASTCALL mem_Read16(u32 addr); 276 | u32 FASTCALL mem_Read32(u32 addr); 277 | void FASTCALL mem_Write8(u32 addr, u8 val); 278 | void FASTCALL mem_Write16(u32 addr, u16 val); 279 | void FASTCALL mem_Write32(u32 addr, u32 val); 280 | 281 | u8 FASTCALL mem_ReadNoCache8(u32 addr); 282 | u16 FASTCALL mem_ReadNoCache16(u32 addr); 283 | u32 FASTCALL mem_ReadNoCache32(u32 addr); 284 | void FASTCALL mem_WriteNoCache8(u32 addr, u8 val); 285 | void FASTCALL mem_WriteNoCache16(u32 addr, u16 val); 286 | void FASTCALL mem_WriteNoCache32(u32 addr, u32 val); 287 | 288 | #define HIGH_WRAM_SIZE 0x100000 289 | #define LOW_WRAM_SIZE 0x100000 290 | #define WRAM_SIZE 0x200000 291 | #define BIOS_SIZE 0x80000 292 | #define BACKUP_RAM_SIZE 0x10000 293 | #define PAGE_SIZE 4096 294 | extern u8 bup_ram_written; 295 | 296 | typedef void (FASTCALL *WriteFunc8)(u32, u8); 297 | typedef void (FASTCALL *WriteFunc16)(u32, u16); 298 | typedef void (FASTCALL *WriteFunc32)(u32, u32); 299 | 300 | typedef u8 (FASTCALL *ReadFunc8)(u32); 301 | typedef u16 (FASTCALL *ReadFunc16)(u32); 302 | typedef u32 (FASTCALL *ReadFunc32)(u32); 303 | 304 | extern WriteFunc8 mem_write8_arr[0x100]; 305 | extern WriteFunc16 mem_write16_arr[0x100]; 306 | extern WriteFunc32 mem_write32_arr[0x100]; 307 | 308 | extern ReadFunc8 mem_read8_arr[0x100]; 309 | extern ReadFunc16 mem_read16_arr[0x100]; 310 | extern ReadFunc32 mem_read32_arr[0x100]; 311 | 312 | #define MEM_GET_FUNC_ADDR(addr) (((addr) >> 19) & 0xFF) 313 | 314 | typedef struct { 315 | u32 addr; 316 | u32 val; 317 | } result_struct; 318 | 319 | #define SEARCHBYTE 0 320 | #define SEARCHWORD 1 321 | #define SEARCHLONG 2 322 | 323 | #define SEARCHEXACT (0 << 2) 324 | #define SEARCHLESSTHAN (1 << 2) 325 | #define SEARCHGREATERTHAN (2 << 2) 326 | 327 | #define SEARCHUNSIGNED (0 << 4) 328 | #define SEARCHSIGNED (1 << 4) 329 | #define SEARCHHEX (2 << 4) 330 | #define SEARCHSTRING (3 << 4) 331 | #define SEARCHREL8BIT (6 << 4) 332 | #define SEARCHREL16BIT (7 << 4) 333 | 334 | 335 | void mem_Init(void); 336 | void mem_allocate(void); 337 | void mem_Deinit(void); 338 | 339 | extern u8 *wram; 340 | extern u8 *bup_ram; 341 | extern u8 *bios_rom; 342 | extern u8 *wii_vram; 343 | extern u8 *Vdp1Ram; 344 | extern u8 *Vdp1FrameBuffer; 345 | extern u8 *SoundRam; 346 | 347 | int LoadBios(const char *filename); 348 | int LoadBackupRam(const char *filename); 349 | void FormatBackupRam(void *mem, u32 size); 350 | u32 getMemClock(u32 addr); 351 | 352 | u16 FASTCALL bios_Read16(u32 addr); 353 | 354 | #endif 355 | -------------------------------------------------------------------------------- /src/musashi/m68kconf.h: -------------------------------------------------------------------------------- 1 | /* ======================================================================== */ 2 | /* ========================= LICENSING & COPYRIGHT ======================== */ 3 | /* ======================================================================== */ 4 | /* 5 | * MUSASHI 6 | * Version 3.4 7 | * 8 | * A portable Motorola M680x0 processor emulation engine. 9 | * Copyright 1998-2001 Karl Stenerud. All rights reserved. 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | */ 29 | 30 | 31 | 32 | #ifndef M68KCONF__HEADER 33 | #define M68KCONF__HEADER 34 | 35 | /* Configuration switches. 36 | * Use OPT_SPECIFY_HANDLER for configuration options that allow callbacks. 37 | * OPT_SPECIFY_HANDLER causes the core to link directly to the function 38 | * or macro you specify, rather than using callback functions whose pointer 39 | * must be passed in using m68k_set_xxx_callback(). 40 | */ 41 | #define OPT_OFF 0 42 | #define OPT_ON 1 43 | #define OPT_SPECIFY_HANDLER 2 44 | 45 | 46 | /* ======================================================================== */ 47 | /* ============================== MAME STUFF ============================== */ 48 | /* ======================================================================== */ 49 | 50 | /* If you're compiling this for MAME, only change M68K_COMPILE_FOR_MAME 51 | * to OPT_ON and use m68kmame.h to configure the 68k core. 52 | */ 53 | #ifndef M68K_COMPILE_FOR_MAME 54 | #define M68K_COMPILE_FOR_MAME OPT_OFF 55 | #endif /* M68K_COMPILE_FOR_MAME */ 56 | 57 | 58 | #if M68K_COMPILE_FOR_MAME == OPT_OFF 59 | 60 | 61 | /* ======================================================================== */ 62 | /* ============================= CONFIGURATION ============================ */ 63 | /* ======================================================================== */ 64 | 65 | /* Turn ON if you want to use the following M68K variants */ 66 | #define M68K_EMULATE_010 OPT_OFF 67 | #define M68K_EMULATE_EC020 OPT_OFF 68 | #define M68K_EMULATE_020 OPT_OFF 69 | 70 | 71 | /* If ON, the CPU will call m68k_read_immediate_xx() for immediate addressing 72 | * and m68k_read_pcrelative_xx() for PC-relative addressing. 73 | * If off, all read requests from the CPU will be redirected to m68k_read_xx() 74 | */ 75 | #define M68K_SEPARATE_READS OPT_OFF 76 | 77 | /* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a 78 | * predecrement destination EA mode instead of m68k_write_32(). 79 | * To simulate real 68k behavior, m68k_write_32_pd() must first write the high 80 | * word to [address+2], and then write the low word to [address]. 81 | */ 82 | #define M68K_SIMULATE_PD_WRITES OPT_OFF 83 | 84 | /* If ON, CPU will call the interrupt acknowledge callback when it services an 85 | * interrupt. 86 | * If off, all interrupts will be autovectored and all interrupt requests will 87 | * auto-clear when the interrupt is serviced. 88 | */ 89 | #define M68K_EMULATE_INT_ACK OPT_OFF 90 | #define M68K_INT_ACK_CALLBACK(A) your_int_ack_handler_function(A) 91 | 92 | 93 | /* If ON, CPU will call the breakpoint acknowledge callback when it encounters 94 | * a breakpoint instruction and it is running a 68010+. 95 | */ 96 | #define M68K_EMULATE_BKPT_ACK OPT_OFF 97 | #define M68K_BKPT_ACK_CALLBACK() your_bkpt_ack_handler_function() 98 | 99 | 100 | /* If ON, the CPU will monitor the trace flags and take trace exceptions 101 | */ 102 | #define M68K_EMULATE_TRACE OPT_OFF 103 | 104 | 105 | /* If ON, CPU will call the output reset callback when it encounters a reset 106 | * instruction. 107 | */ 108 | #define M68K_EMULATE_RESET OPT_ON 109 | #define M68K_RESET_CALLBACK() your_reset_handler_function() 110 | 111 | 112 | /* If ON, CPU will call the set fc callback on every memory access to 113 | * differentiate between user/supervisor, program/data access like a real 114 | * 68000 would. This should be enabled and the callback should be set if you 115 | * want to properly emulate the m68010 or higher. (moves uses function codes 116 | * to read/write data from different address spaces) 117 | */ 118 | #define M68K_EMULATE_FC OPT_OFF 119 | #define M68K_SET_FC_CALLBACK(A) your_set_fc_handler_function(A) 120 | 121 | 122 | /* If ON, CPU will call the pc changed callback when it changes the PC by a 123 | * large value. This allows host programs to be nicer when it comes to 124 | * fetching immediate data and instructions on a banked memory system. 125 | */ 126 | #define M68K_MONITOR_PC OPT_OFF 127 | #define M68K_SET_PC_CALLBACK(A) your_pc_changed_handler_function(A) 128 | 129 | 130 | /* If ON, CPU will call the instruction hook callback before every 131 | * instruction. 132 | */ 133 | #define M68K_INSTRUCTION_HOOK OPT_OFF 134 | #define M68K_INSTRUCTION_CALLBACK() your_instruction_hook_function() 135 | 136 | 137 | /* If ON, the CPU will emulate the 4-byte prefetch queue of a real 68000 */ 138 | #define M68K_EMULATE_PREFETCH OPT_OFF 139 | 140 | 141 | /* If ON, the CPU will generate address error exceptions if it tries to 142 | * access a word or longword at an odd address. 143 | * NOTE: This is only emulated properly for 68000 mode. 144 | */ 145 | #define M68K_EMULATE_ADDRESS_ERROR OPT_OFF 146 | 147 | 148 | /* Turn ON to enable logging of illegal instruction calls. 149 | * M68K_LOG_FILEHANDLE must be #defined to a stdio file stream. 150 | * Turn on M68K_LOG_1010_1111 to log all 1010 and 1111 calls. 151 | */ 152 | #define M68K_LOG_ENABLE OPT_OFF 153 | #define M68K_LOG_1010_1111 OPT_OFF 154 | #define M68K_LOG_FILEHANDLE some_file_handle 155 | 156 | 157 | /* ----------------------------- COMPATIBILITY ---------------------------- */ 158 | 159 | /* The following options set optimizations that violate the current ANSI 160 | * standard, but will be compliant under the forthcoming C9X standard. 161 | */ 162 | 163 | 164 | /* If ON, the enulation core will use 64-bit integers to speed up some 165 | * operations. 166 | */ 167 | #define M68K_USE_64_BIT OPT_OFF 168 | 169 | 170 | /* Set to your compiler's static inline keyword to enable it, or 171 | * set it to blank to disable it. 172 | * If you define INLINE in the makefile, it will override this value. 173 | * NOTE: not enabling inline functions will SEVERELY slow down emulation. 174 | */ 175 | #ifndef INLINE 176 | #ifdef _MSC_VER 177 | #define INLINE _inline 178 | #else 179 | #define INLINE static inline 180 | #endif 181 | #endif /* INLINE */ 182 | 183 | #endif /* M68K_COMPILE_FOR_MAME */ 184 | 185 | 186 | /* ======================================================================== */ 187 | /* ============================== END OF FILE ============================= */ 188 | /* ======================================================================== */ 189 | 190 | #endif /* M68KCONF__HEADER */ 191 | -------------------------------------------------------------------------------- /src/osd/gui.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef __GUI_H__ 4 | #define __GUI_H__ 5 | 6 | 7 | /* 8 | * gui.h 9 | *-------------------- 10 | * Simple graphical user interface for the wii 11 | */ 12 | 13 | #include 14 | 15 | 16 | #define MAX_MESSAGES 64 17 | #define OSD_MSG_BG 0x01 18 | 19 | #define GUI_ELEM_BOX 0x01 20 | #define GUI_ELEM_LABEL 0x02 21 | #define GUI_ELEM_IMAGE 0x03 22 | 23 | #define GUI_BOX_BORDER 0x10 24 | 25 | #define GUI_LABEL_BG 0x10 26 | #define GUI_LABEL_MONO 0x20 27 | 28 | #define GUI_XY(x, y) ((x & 0xFFFF) << 16 | (y & 0xFFFF)) 29 | 30 | extern GXTexObj gui_tobj; 31 | extern GXTexRegion gui_treg; 32 | 33 | typedef struct String_t { 34 | u32 len; 35 | char *data; 36 | } String; 37 | 38 | typedef struct GuiElem_t { 39 | u32 type; 40 | u32 color; 41 | u16 x; 42 | u16 y; 43 | u32 len; 44 | void *data; //NECESARY? 45 | } GuiElem; 46 | 47 | typedef struct GuiLabel_t { 48 | u32 color; 49 | u16 x; 50 | u16 y; 51 | u32 len; 52 | void *data; //NECESARY? 53 | } GuiLabel; 54 | 55 | typedef struct GuiItems_t { 56 | u32 cursor; //position of cursor 57 | u32 count; //number of entries 58 | u32 disp_offset; //offset of list displayed 59 | u32 disp_count; //number of entries displayed 60 | //Position on screen 61 | u16 x; 62 | u16 y; 63 | //Array of strings 64 | String *item; 65 | } GuiItems; 66 | 67 | typedef struct GuiAnim { 68 | u32 type; 69 | u32 color_fg; 70 | u32 value; 71 | u32 time; 72 | } GuiAnim; 73 | 74 | void gui_Init(void); 75 | void gui_Draw(GuiItems *items); 76 | void gui_SetMessage(String msg, u32 color); 77 | 78 | u32 gui_AnimSet(GuiAnim *anim, GuiElem *elems); 79 | 80 | 81 | 82 | 83 | #endif /*__GUI_H__*/ 84 | -------------------------------------------------------------------------------- /src/osd/menu_tex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fadedled/seta-gx/c23d7cdc1800bc7af5022d2d9139b997397c5895/src/osd/menu_tex.png -------------------------------------------------------------------------------- /src/osd/osd.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #include "osd.h" 5 | #include "gui.h" 6 | #include "../yabause.h" 7 | #include "../sgx/sgx.h" 8 | #include 9 | #include 10 | 11 | 12 | 13 | struct MsgQueue { 14 | u32 count; 15 | struct Msg { 16 | u32 msg; 17 | u32 m_len; 18 | u16 x; 19 | u16 y; 20 | u32 color; 21 | } queue[MAX_MESSAGES]; 22 | } osd = {0}; 23 | 24 | 25 | GXTexObj osd_tobj; 26 | 27 | #define OSD_TEX_W 256 28 | #define OSD_TEX_H 64 29 | 30 | 31 | u8 msg_buffer[0x800]; 32 | u32 msg_index = 0; 33 | u64 cycle_data[8]; 34 | 35 | extern yabsys_struct yabsys; 36 | 37 | 38 | 39 | void osd_CyclesSet(u32 indx, u64 cycles) 40 | { 41 | cycle_data[indx] = (cycles * 100) / yabsys.OneFrameTime; 42 | } 43 | 44 | 45 | void osd_MsgAdd(u32 x, u32 y, u32 color, char *msg) 46 | { 47 | u32 len = 0; 48 | 49 | if (!msg || osd.count >= MAX_MESSAGES) { 50 | return; 51 | } 52 | 53 | osd.queue[osd.count].x = x; 54 | osd.queue[osd.count].y = y; 55 | osd.queue[osd.count].color = color; 56 | osd.queue[osd.count].msg = msg_index; 57 | 58 | //Copy the string to the message buffer: 59 | while ((msg_buffer[msg_index] = (*msg))) { 60 | msg_index = (msg_index + 1) & 0x7FF; 61 | ++len; 62 | ++msg; 63 | } 64 | msg_index = (msg_index + 1) & 0x7FF; 65 | 66 | osd.queue[osd.count].m_len = len; 67 | ++osd.count; 68 | } 69 | 70 | 71 | void osd_MsgShow(void) 72 | { 73 | /*Show messages*/ 74 | if (!osd.count) { 75 | return; 76 | } 77 | 78 | 79 | //GX_SetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); 80 | 81 | GX_ClearVtxDesc(); 82 | GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); 83 | GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); 84 | 85 | /*Reserve GX_VTXFMT7 for OSD*/ 86 | GX_SetVtxAttrFmt(GX_VTXFMT7, GX_VA_POS, GX_POS_XY, GX_U16, 0); 87 | GX_SetVtxAttrFmt(GX_VTXFMT7, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); 88 | 89 | GX_SetNumChans(0); 90 | GX_SetNumTexGens(1); 91 | GX_SetNumTevStages(1); 92 | 93 | GX_LoadTexObjPreloaded(&gui_tobj, &gui_treg, GX_TEXMAP0); 94 | 95 | GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); 96 | GX_SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); 97 | GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_KONST, GX_CC_TEXC, GX_CC_ZERO); 98 | GX_SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); 99 | GX_SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); 100 | 101 | GX_SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); 102 | 103 | GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); 104 | GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); 105 | 106 | for (u32 i = 0; i < osd.count; ++i) { 107 | u32 c = osd.queue[i].msg; 108 | u32 x = osd.queue[i].x; 109 | u32 y = osd.queue[i].y; 110 | 111 | GX_SetTevKColor(GX_KCOLOR0, *((GXColor*) &osd.queue[i].color)); 112 | 113 | GX_Begin(GX_QUADS, GX_VTXFMT7, 4 * osd.queue[i].m_len); 114 | /*not while m_ptr, must use index for this because of circular buffering*/ 115 | for (u32 j = 0; j < osd.queue[i].m_len; ++j) { 116 | //XXX: Use a texCoordGen for this. 117 | f32 chr_x = (f32) ((msg_buffer[c]) & 0x1F) * 0.03125; 118 | f32 chr_y = (f32) (((msg_buffer[c]) >> 5) & 0x3) * 0.125; 119 | GX_Position2u16(x , y); // Top Left 120 | GX_TexCoord2f32(chr_x, chr_y); 121 | GX_Position2u16(x + 8, y); // Top Right 122 | GX_TexCoord2f32(chr_x + 0.03125, chr_y); 123 | GX_Position2u16(x + 8, y + 8); // Bottom Right 124 | GX_TexCoord2f32(chr_x + 0.03125, chr_y + 0.125); 125 | GX_Position2u16(x, y + 8); // Bottom Left 126 | GX_TexCoord2f32(chr_x, chr_y + 0.125); 127 | x += 8; 128 | c = (c + 1) & 0x7FF; 129 | } 130 | GX_End(); 131 | } 132 | 133 | GX_SetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); 134 | osd.count = 0; 135 | } 136 | #define MAX_PROF_COUNTERS 16 137 | 138 | u32 system_cycles; 139 | struct ProfCounter { 140 | char *name; 141 | u32 is_active; 142 | u32 value; 143 | } prof_counters[MAX_PROF_COUNTERS]; 144 | 145 | void osd_ProfInit(u32 sys_cycles) 146 | { 147 | system_cycles = sys_cycles; 148 | } 149 | 150 | 151 | void osd_ProfAddCounter(u32 indx, char *name) 152 | { 153 | prof_counters[indx].name = name; 154 | prof_counters[indx].is_active = 1; 155 | } 156 | 157 | 158 | void osd_ProfAddTime(u32 indx, u32 ticks) 159 | { 160 | if (prof_counters[indx].is_active) { 161 | prof_counters[indx].value += ticks; 162 | } 163 | } 164 | extern u32 preloadtex_addr; 165 | 166 | static void __osd_SetTev(void) 167 | { 168 | GX_ClearVtxDesc(); 169 | GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); 170 | GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); 171 | GX_SetCurrentMtx(MTX_IDENTITY); 172 | GX_SetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 8, 8); 173 | 174 | GX_SetScissor(0, 0, 640, 480); 175 | GX_SetNumChans(0); 176 | GX_SetNumTexGens(1); 177 | GX_SetNumTevStages(1); 178 | 179 | GX_LoadTexObjPreloaded(&gui_tobj, &gui_treg, GX_TEXMAP0); 180 | GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); 181 | GX_SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); 182 | GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_KONST, GX_CC_TEXC, GX_CC_ZERO); 183 | GX_SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); 184 | GX_SetTevAlphaIn(GX_TEVSTAGE0, GX_CC_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); 185 | 186 | GX_SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_1); 187 | GX_SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); 188 | GX_SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_1_2); 189 | 190 | GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); 191 | GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); 192 | } 193 | 194 | static void __osd_DrawText(u32 x, u32 y, char *text, u32 numc) 195 | { 196 | GX_Begin(GX_QUADS, GX_VTXFMT1, 4 * numc); 197 | for (u32 j = 0; j < numc; ++j) { 198 | u32 chr_x = ((text[j]) & 0x1F); 199 | u32 chr_y = (((text[j]) >> 5) & 0x3); 200 | GX_Position2s16(x , y); // Top Left 201 | GX_TexCoord2u16(chr_x, chr_y); 202 | GX_Position2s16(x + 8, y); // Top Right 203 | GX_TexCoord2u16(chr_x + 1, chr_y); 204 | GX_Position2s16(x + 8, y + 8); // Bottom Right 205 | GX_TexCoord2u16(chr_x + 1, chr_y + 1); 206 | GX_Position2s16(x, y + 8); // Bottom Left 207 | GX_TexCoord2u16(chr_x, chr_y + 1); 208 | x += 8; 209 | } 210 | GX_End(); 211 | } 212 | 213 | void osd_FPSDraw(u32 fps) 214 | { 215 | char tstr[64]; 216 | __osd_SetTev(); 217 | GX_SetCurrentMtx(MTX_IDENTITY_2X); 218 | 219 | u32 numc = sprintf(tstr, "FPS:%2d", fps); 220 | GX_SetTevKColor(GX_KCOLOR0, (GXColor) {0xBB, 0xFF, 0xCC, 0xFF}); 221 | __osd_DrawText(0, 0, tstr, numc); 222 | 223 | GX_SetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 8, 1); 224 | GX_SetDispCopySrc(0, 0, 6*16, 16); 225 | SVI_CopyXFB(32, 24); 226 | } 227 | 228 | 229 | void osd_ProfDraw(void) 230 | { 231 | char tstr[64]; 232 | u32 y = 4, x = 4; 233 | u32 total = 0; 234 | __osd_SetTev(); 235 | 236 | GX_SetTevKColor(GX_KCOLOR0, (GXColor){0xFF, 0xFF, 0xFF, 0xFF}); 237 | for (u32 i = 0; i < MAX_PROF_COUNTERS; ++i) { 238 | if (prof_counters[i].is_active) { 239 | x = 8; 240 | u32 us = (u32) ticks_to_microsecs(prof_counters[i].value); 241 | total += us; 242 | u32 numc = sprintf(tstr, "%5s:%6d", prof_counters[i].name, us); 243 | prof_counters[i].value = 0; 244 | __osd_DrawText(x, y, tstr, numc); 245 | y += 8; 246 | } 247 | } 248 | 249 | x = 8; 250 | u32 numc = sprintf(tstr, "%5s:%6d", "TOTAL", total); 251 | __osd_DrawText(x, y, tstr, numc); 252 | 253 | GX_SetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 8, 1); 254 | GX_SetDispCopySrc(0, 0, (14*8), y+12); 255 | SVI_CopyXFB(32, 320); 256 | } 257 | -------------------------------------------------------------------------------- /src/osd/osd.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef __OSD_H__ 4 | #define __OSD_H__ 5 | 6 | 7 | /* 8 | * osd.h 9 | *-------------------- 10 | * OSD for printing data 11 | */ 12 | 13 | #include 14 | 15 | 16 | #define MAX_MESSAGES 64 17 | #define OSD_MSG_BG 0x01 18 | #define OSD_MSG_MONO 0x02 19 | 20 | 21 | void osd_MsgAdd(u32 x, u32 y, u32 color, char *str); 22 | void osd_MsgShow(void); 23 | 24 | void osd_CyclesSet(u32 indx, u64 cycles); 25 | 26 | enum { 27 | PROF_SH2M, 28 | PROF_SH2S, 29 | PROF_M68K, 30 | PROF_SCSP, 31 | PROF_SCU, 32 | PROF_SMPC, 33 | PROF_VDP1, 34 | PROF_VDP2, 35 | PROF_CDB 36 | }; 37 | 38 | void osd_ProfInit(u32 sys_cycles); 39 | void osd_ProfAddCounter(u32 indx, char *name); 40 | void osd_ProfAddTime(u32 indx, u32 ticks); 41 | void osd_ProfDraw(void); //All counters reset to 0 42 | void osd_FPSDraw(u32 fps); 43 | 44 | 45 | #endif /*__OSD_H__*/ 46 | -------------------------------------------------------------------------------- /src/peripheral.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2005 Guillaume Duhamel 2 | Copyright 2005-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "debug.h" 22 | #include "peripheral.h" 23 | #include 24 | #include 25 | 26 | PerPad perpad[PER_PADMAX]; 27 | 28 | PerData per_data; 29 | 30 | //XXX: this is for gamepad configuration 31 | //static u8 gcpad_bitoffsets[16] = { 0, 0, 0, 0, 0, 0, 0, GC_BIT_A, GC_BIT_B, GC_BIT_Z2, GC_BIT_Y, GC_BIT_X, GC_BIT_Z }; 32 | //static u8 wcpad_bitoffsets[16]; 33 | //static u8 wpad_bitoffsets[16]; 34 | 35 | 36 | void per_Init(void) 37 | { 38 | PAD_Init(); 39 | WPAD_Init(); 40 | per_data.ids[0] = PER_ID_DIGITAL; 41 | } 42 | 43 | static void per_GCToSat(u32 indx, u32 *exit_code) 44 | { 45 | s8 axis_x = perpad[indx].x; 46 | s8 axis_y = perpad[indx].y; 47 | //TODO: only do this when using the ANALOGUE controller 48 | u32 btns = perpad[indx].btn | GC_AXIS_TO_DIGITAL(axis_x, axis_y); 49 | //Use C-stick as another button 50 | btns |= (u32) ((perpad[indx].sy > 32) | (perpad[indx].sy < -32)) << GC_BIT_Z2; 51 | *exit_code |= (btns & (PAD_BUTTON_START | PAD_TRIGGER_Z)) == (PAD_BUTTON_START | PAD_TRIGGER_Z); 52 | 53 | //TODO: get the user defined bits for the buttons 54 | u32 sat_btns = 55 | (((btns >> GC_BIT_A) & 1) << PAD_DI_BIT_B) | 56 | (((btns >> GC_BIT_B) & 1) << PAD_DI_BIT_A) | 57 | (((btns >> GC_BIT_X) & 1) << PAD_DI_BIT_C) | 58 | (((btns >> GC_BIT_STR) & 1) << PAD_DI_BIT_STR) | 59 | (((btns >> GC_BIT_UP) & 1) << PAD_DI_BIT_UP) | 60 | (((btns >> GC_BIT_DOWN) & 1) << PAD_DI_BIT_DOWN) | 61 | (((btns >> GC_BIT_LEFT) & 1) << PAD_DI_BIT_LEFT) | 62 | (((btns >> GC_BIT_RIGHT) & 1) << PAD_DI_BIT_RIGHT) | 63 | (((btns >> GC_BIT_L) & 1) << PAD_DI_BIT_L) | 64 | (((btns >> GC_BIT_Z2) & 1) << PAD_DI_BIT_X) | 65 | (((btns >> GC_BIT_Y) & 1) << PAD_DI_BIT_Y) | 66 | (((btns >> GC_BIT_Z) & 1) << PAD_DI_BIT_Z) | 67 | (((btns >> GC_BIT_R) & 1) << PAD_DI_BIT_R) | 68 | 0x300; //First 2 bits must be 0 69 | perpad[indx].btn = sat_btns; 70 | } 71 | 72 | static void per_WiiToSat(u32 indx, u32 *exit_code) 73 | { 74 | s8 axis_x = 0; 75 | s8 axis_y = 0; 76 | //TODO: only do this when using the ANALOGUE controller 77 | u32 btns = perpad[indx].btn | CLASSIC_AXIS_TO_DIGITAL(axis_x, axis_y); 78 | *exit_code |= (btns & WPAD_BUTTON_HOME); 79 | 80 | //TODO: get the user defined bits for the buttons 81 | u32 sat_btns = 82 | (((btns >> WII_BIT_A) & 1) << PAD_DI_BIT_A) | 83 | (((btns >> WII_BIT_1) & 1) << PAD_DI_BIT_B) | 84 | (((btns >> WII_BIT_2) & 1) << PAD_DI_BIT_C) | 85 | (((btns >> WII_BIT_PLUS) & 1) << PAD_DI_BIT_STR) | 86 | (((btns >> WII_BIT_RIGHT) & 1) << PAD_DI_BIT_UP) | 87 | (((btns >> WII_BIT_LEFT) & 1) << PAD_DI_BIT_DOWN) | 88 | (((btns >> WII_BIT_UP) & 1) << PAD_DI_BIT_LEFT) | 89 | (((btns >> WII_BIT_DOWN) & 1) << PAD_DI_BIT_RIGHT) | 90 | //(((btns >> WII_BIT_L) & 1) << PAD_DI_BIT_L) | 91 | (((btns >> WII_BIT_MINUS) & 1) << PAD_DI_BIT_X) | 92 | (((btns >> WII_BIT_B) & 1) << PAD_DI_BIT_Y) | 93 | //(((btns >> WII_BIT_ZR) & 1) << PAD_DI_BIT_Z) | 94 | //(((btns >> WII_BIT_R) & 1) << PAD_DI_BIT_R) | 95 | 0x300; //First 2 bits must be 0 96 | perpad[indx].btn = sat_btns; 97 | } 98 | 99 | static void per_ClassicToSat(u32 indx, u32 *exit_code) 100 | { 101 | s8 axis_x = perpad[indx].x; 102 | s8 axis_y = perpad[indx].y; 103 | //TODO: only do this when using the ANALOGUE controller 104 | u32 btns = perpad[indx].btn | CLASSIC_AXIS_TO_DIGITAL(axis_x, axis_y); 105 | *exit_code |= (btns & WPAD_CLASSIC_BUTTON_HOME); 106 | 107 | //TODO: get the user defined bits for the buttons 108 | u32 sat_btns = 109 | (((btns >> WCL_BIT_Y) & 1) << PAD_DI_BIT_A) | 110 | (((btns >> WCL_BIT_B) & 1) << PAD_DI_BIT_B) | 111 | (((btns >> WCL_BIT_A) & 1) << PAD_DI_BIT_C) | 112 | (((btns >> WCL_BIT_PLUS) & 1) << PAD_DI_BIT_STR) | 113 | (((btns >> WCL_BIT_UP) & 1) << PAD_DI_BIT_UP) | 114 | (((btns >> WCL_BIT_DOWN) & 1) << PAD_DI_BIT_DOWN) | 115 | (((btns >> WCL_BIT_LEFT) & 1) << PAD_DI_BIT_LEFT) | 116 | (((btns >> WCL_BIT_RIGHT) & 1) << PAD_DI_BIT_RIGHT) | 117 | (((btns >> WCL_BIT_L) & 1) << PAD_DI_BIT_L) | 118 | (((btns >> WCL_BIT_X) & 1) << PAD_DI_BIT_X) | 119 | (((btns >> WCL_BIT_ZL) & 1) << PAD_DI_BIT_Y) | 120 | (((btns >> WCL_BIT_ZR) & 1) << PAD_DI_BIT_Z) | 121 | (((btns >> WCL_BIT_R) & 1) << PAD_DI_BIT_R) | 122 | 0x300; //First 2 bits must be 0 123 | perpad[indx].btn = sat_btns; 124 | } 125 | 126 | 127 | u32 per_updatePads() 128 | { 129 | PADStatus padstatus[PAD_CHANMAX]; 130 | u32 port_stat[2] = {PER_STAT_NONE, PER_STAT_NONE}; 131 | u32 per_num = 0; 132 | 133 | //Reset ports 134 | u32 exit_code = 0; 135 | per_data.data_sent = 0; 136 | per_data.data_size = 2; 137 | per_data.data[0] = PER_STAT_NONE; //Port 1 138 | per_data.data[1] = PER_STAT_NONE; //Port 2 139 | per_data.port2_offset = 1; 140 | 141 | //Fill with gc controllers 142 | u32 connected = PAD_ScanPads(); 143 | for (u32 i = 0; i < PAD_CHANMAX; ++i) { 144 | if ((connected >> i) & 1) { 145 | perpad[per_num].type = PAD_TYPE_GCPAD; 146 | perpad[per_num].x = PAD_StickX(i); 147 | perpad[per_num].y = PAD_StickY(i); 148 | perpad[per_num].sx = PAD_SubStickX(i); 149 | perpad[per_num].sy = PAD_SubStickY(i); 150 | perpad[per_num].prev_btn = perpad[per_num].btn; 151 | perpad[per_num].btn = PAD_ButtonsHeld(i); 152 | per_GCToSat(per_num, &exit_code); 153 | ++per_num; 154 | } 155 | } 156 | 157 | //Fill with wiimote 158 | for (u32 i = 0; i < PAD_CHANMAX; ++i) { 159 | WPADData *wpad = WPAD_Data(i); 160 | u32 exp_type; 161 | u32 err = WPAD_Probe(i, &exp_type); 162 | WPAD_ReadPending(i, NULL); 163 | if (err == WPAD_ERR_NONE) { 164 | if (exp_type == WPAD_EXP_NONE) { //Wiimote used 165 | perpad[per_num].type = PAD_TYPE_WIIMOTE; 166 | perpad[per_num].x = 0; 167 | perpad[per_num].y = 0; 168 | perpad[per_num].prev_btn = perpad[per_num].btn; 169 | perpad[per_num].btn = wpad->btns_h; 170 | per_WiiToSat(per_num, &exit_code); 171 | ++per_num; 172 | } else if (exp_type == WPAD_EXP_CLASSIC) { //Classic controller used 173 | perpad[per_num].type = PAD_TYPE_CLASSIC; 174 | perpad[per_num].x = (s16) (wpad->exp.classic.ljs.pos.x); 175 | perpad[per_num].y = (s16) (wpad->exp.classic.ljs.pos.y); 176 | perpad[per_num].prev_btn = perpad[per_num].btn; 177 | perpad[per_num].btn = wpad->btns_h; 178 | per_ClassicToSat(per_num, &exit_code); 179 | ++per_num; 180 | } 181 | } 182 | } 183 | 184 | //Set the port stats 185 | port_stat[0] = (per_num ? (per_num == 8 ? PER_STAT_MULTITAP : PER_STAT_DIRECT) : PER_STAT_NONE); 186 | port_stat[1] = (per_num > 1 ? (per_num > 2 ? PER_STAT_MULTITAP : PER_STAT_DIRECT) : PER_STAT_NONE); 187 | u32 size = 0; 188 | u32 port_count = 0; 189 | u32 port_ofs = 0b00000011 + (per_num == 8 ? 2 : 0); 190 | 191 | //Generate Peripheral data for SMPC 192 | for (u32 i = 0; i < per_num; ++i) { 193 | if ((port_ofs >> i) & 1) { //See if port stat must be set 194 | per_data.data[size++] = port_stat[port_count++]; 195 | } 196 | if (perpad[i].type != PAD_TYPE_NONE) { 197 | per_data.data[size++] = PER_ID_DIGITAL; 198 | per_data.data[size++] = ~(perpad[i].btn & 0xFF); 199 | per_data.data[size++] = ~((perpad[i].btn >> 0x8) & 0xFF); 200 | } 201 | } 202 | //Fill rest of data with no input 203 | if (2 < per_num && per_num < 8){ //Fill the rest of multitap 204 | for (u32 i = per_num; i < 7; ++i) { 205 | per_data.data[size++] = PER_ID_NONE; 206 | } 207 | } else if (per_num == 1) { //Only have one controller 208 | per_data.data[size++] = PER_STAT_NONE; 209 | } 210 | 211 | //Fill the rest of the pads 212 | while (per_num < PER_PADMAX) { 213 | perpad[per_num].type = PAD_TYPE_NONE; 214 | perpad[per_num].x = 0; 215 | perpad[per_num].y = 0; 216 | perpad[per_num].sx = 0; 217 | perpad[per_num].sy = 0; 218 | perpad[per_num].btn = 0; 219 | ++per_num; 220 | } 221 | 222 | per_data.data_size = size; 223 | return exit_code; 224 | } 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /src/peripheral.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2005 Guillaume Duhamel 2 | Copyright 2005-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef PERIPHERAL_H 22 | #define PERIPHERAL_H 23 | 24 | #include "core.h" 25 | #include "smpc.h" 26 | #include "yabause.h" 27 | 28 | /** @defgroup peripheral Peripheral 29 | * 30 | * @brief This module provides two kind of functions 31 | * - peripheral core management functions 32 | * - controller ports management functions 33 | * 34 | * @{ 35 | */ 36 | 37 | #define PERPAD 0x02 38 | #define PERMOUSE 0xE3 39 | 40 | #define PERCORE_DEFAULT -1 41 | #define PERCORE_DUMMY 0 42 | 43 | extern PortData_struct PORTDATA1; 44 | extern PortData_struct PORTDATA2; 45 | 46 | typedef struct 47 | { 48 | int id; 49 | const char * Name; 50 | int (*Init)(void); 51 | void (*DeInit)(void); 52 | int (*HandleEvents)(void); 53 | void (*PerSetButtonMapping)(void); 54 | u32 (*Scan)(void); 55 | int canScan; 56 | void (*Flush)(void); 57 | #ifdef PERKEYNAME 58 | void (*KeyName)(u32 key, char * name, int size); 59 | #endif 60 | } PerInterface_struct; 61 | 62 | /** @brief Pointer to the current peripheral core. 63 | * 64 | * You should not set this manually but use 65 | * PerInit() and PerDeInit() instead. */ 66 | extern PerInterface_struct * PERCore; 67 | 68 | extern PerInterface_struct PERDummy; 69 | 70 | /** 71 | * @brief Init a peripheral core 72 | * 73 | * Searches through the PERCoreList array for the given coreid. 74 | * If found, PERCore is set to the address of that core and 75 | * the core's Init function is called. 76 | * 77 | * @param coreid the peripheral core to be used 78 | * @return 0 if core has been inited, -1 otherwise 79 | */ 80 | int PerInit(int coreid); 81 | /** 82 | * @brief De-init a peripheral core 83 | * 84 | * Calls the core's DeInit callback and set PERCore to NULL. 85 | */ 86 | void PerDeInit(void); 87 | 88 | /** @brief Adds a peripheral 89 | * 90 | * You shouldn't directly use this function but 91 | * PerPadAdd() or PerMouseAdd() instead. 92 | */ 93 | void * PerAddPeripheral(PortData_struct *port, int perid); 94 | int PerGetId(void * peripheral); 95 | void PerRemovePeripheral(PortData_struct *port, int removeoffset); 96 | void PerPortReset(void); 97 | /** 98 | * Iterate the list of peripherals connected to a port 99 | * and flush them if necesseray. This is needed for mouses. 100 | */ 101 | void PerFlush(PortData_struct * port); 102 | 103 | void PerKeyDown(u32 key); 104 | void PerKeyUp(u32 key); 105 | void PerSetKey(u32 key, u8 name, void * controller); 106 | 107 | /** @defgroup pad Pad 108 | * 109 | * @{ 110 | */ 111 | #define PERPAD_UP 0 112 | #define PERPAD_RIGHT 1 113 | #define PERPAD_DOWN 2 114 | #define PERPAD_LEFT 3 115 | #define PERPAD_RIGHT_TRIGGER 4 116 | #define PERPAD_LEFT_TRIGGER 5 117 | #define PERPAD_START 6 118 | #define PERPAD_A 7 119 | #define PERPAD_B 8 120 | #define PERPAD_C 9 121 | #define PERPAD_X 10 122 | #define PERPAD_Y 11 123 | #define PERPAD_Z 12 124 | 125 | 126 | extern const char * PerPadNames[14]; 127 | 128 | typedef struct 129 | { 130 | u8 perid; 131 | u8 padbits[2]; 132 | } PerPad_struct; 133 | 134 | /** @brief Adds a pad to one of the controller ports. 135 | * 136 | * @param port can be either &PORTDATA1 or &PORTDATA2 137 | * @return pointer to a PerPad_struct or NULL if it fails 138 | * */ 139 | PerPad_struct * PerPadAdd(PortData_struct * port); 140 | 141 | void PerPadUpPressed(PerPad_struct * pad); 142 | void PerPadUpReleased(PerPad_struct * pad); 143 | 144 | void PerPadDownPressed(PerPad_struct * pad); 145 | void PerPadDownReleased(PerPad_struct * pad); 146 | 147 | void PerPadRightPressed(PerPad_struct * pad); 148 | void PerPadRightReleased(PerPad_struct * pad); 149 | 150 | void PerPadLeftPressed(PerPad_struct * pad); 151 | void PerPadLeftReleased(PerPad_struct * pad); 152 | 153 | void PerPadStartPressed(PerPad_struct * pad); 154 | void PerPadStartReleased(PerPad_struct * pad); 155 | 156 | void PerPadAPressed(PerPad_struct * pad); 157 | void PerPadAReleased(PerPad_struct * pad); 158 | 159 | void PerPadBPressed(PerPad_struct * pad); 160 | void PerPadBReleased(PerPad_struct * pad); 161 | 162 | void PerPadCPressed(PerPad_struct * pad); 163 | void PerPadCReleased(PerPad_struct * pad); 164 | 165 | void PerPadXPressed(PerPad_struct * pad); 166 | void PerPadXReleased(PerPad_struct * pad); 167 | 168 | void PerPadYPressed(PerPad_struct * pad); 169 | void PerPadYReleased(PerPad_struct * pad); 170 | 171 | void PerPadZPressed(PerPad_struct * pad); 172 | void PerPadZReleased(PerPad_struct * pad); 173 | 174 | void PerPadRTriggerPressed(PerPad_struct * pad); 175 | void PerPadRTriggerReleased(PerPad_struct * pad); 176 | 177 | void PerPadLTriggerPressed(PerPad_struct * pad); 178 | void PerPadLTriggerReleased(PerPad_struct * pad); 179 | /** @} */ 180 | 181 | /** @defgroup mouse Mouse 182 | * 183 | * @{ 184 | * */ 185 | #define PERMOUSE_LEFT 13 186 | #define PERMOUSE_MIDDLE 14 187 | #define PERMOUSE_RIGHT 15 188 | #define PERMOUSE_START 16 189 | 190 | extern const char * PerMouseNames[5]; 191 | 192 | typedef struct 193 | { 194 | u8 perid; 195 | u8 mousebits[3]; 196 | } PerMouse_struct; 197 | 198 | /** @brief Adds a mouse to one of the controller ports. 199 | * 200 | * @param port can be either &PORTDATA1 or &PORTDATA2 201 | * @return pointer to a PerMouse_struct or NULL if it fails 202 | * */ 203 | PerMouse_struct * PerMouseAdd(PortData_struct * port); 204 | 205 | void PerMouseLeftPressed(PerMouse_struct * mouse); 206 | void PerMouseLeftReleased(PerMouse_struct * mouse); 207 | 208 | void PerMouseMiddlePressed(PerMouse_struct * mouse); 209 | void PerMouseMiddleReleased(PerMouse_struct * mouse); 210 | 211 | void PerMouseRightPressed(PerMouse_struct * mouse); 212 | void PerMouseRightReleased(PerMouse_struct * mouse); 213 | 214 | void PerMouseStartPressed(PerMouse_struct * mouse); 215 | void PerMouseStartReleased(PerMouse_struct * mouse); 216 | 217 | void PerMouseMove(PerMouse_struct * mouse, s32 dispx, s32 dispy); 218 | /** @} */ 219 | 220 | 221 | 222 | 223 | 224 | //NEW 225 | 226 | #define PER_PADMAX 8 227 | #define PER_DATASIZE 64 228 | 229 | typedef struct PerData_t { 230 | u32 port2_offset; 231 | u32 data_size; 232 | u32 data_sent; 233 | u8 ids[PER_PADMAX]; 234 | u8 data[PER_DATASIZE]; 235 | } PerData; 236 | 237 | extern PerData per_data; 238 | 239 | 240 | #define PAD_TYPE_NONE 0 241 | #define PAD_TYPE_GCPAD 1 242 | #define PAD_TYPE_WIIMOTE 2 243 | #define PAD_TYPE_CLASSIC 3 244 | 245 | typedef struct PerPad_t { 246 | u32 type; 247 | u32 port; 248 | u32 prev_btn; 249 | u32 btn; 250 | s16 x; 251 | s16 y; 252 | s16 sx; 253 | s16 sy; 254 | } PerPad; 255 | 256 | extern PerPad perpad[PER_PADMAX]; 257 | 258 | #define PER_BUTTONS_HELD(i) (perpad[i].btn) 259 | #define PER_BUTTONS_DOWN(i) (~perpad[i].prev_btn & perpad[i].btn) 260 | 261 | /* Port Status: 262 | 0x04 - Sega-tap is connected 263 | 0x16 - Multi-tap is connected 264 | 0x21-0x2F - Clock serial peripheral is connected 265 | 0xF0 - Not Connected or Unknown Device 266 | 0xF1 - Peripheral is directly connected */ 267 | #define PER_STAT_NONE 0xF0 268 | #define PER_STAT_DIRECT 0xF1 269 | #define PER_STAT_MULTITAP 0x16 270 | 271 | // PeripheralID: 272 | #define PER_ID_DIGITAL 0x02 273 | #define PER_ID_ANALOGUE 0x15 274 | #define PER_ID_GUN 0x23 275 | #define PER_ID_MOUSE 0xE3 276 | #define PER_ID_NONE 0xFF 277 | 278 | //Standard Sega Saturn Controller 279 | #define PAD_DI_B 0x0001 280 | #define PAD_DI_C 0x0002 281 | #define PAD_DI_A 0x0004 282 | #define PAD_DI_STR 0x0008 283 | #define PAD_DI_UP 0x0010 284 | #define PAD_DI_DOWN 0x0020 285 | #define PAD_DI_LEFT 0x0040 286 | #define PAD_DI_RIGHT 0x0080 287 | #define PAD_DI_L 0x0800 288 | #define PAD_DI_Z 0x1000 289 | #define PAD_DI_X 0x2000 290 | #define PAD_DI_Y 0x4000 291 | #define PAD_DI_R 0x8000 292 | 293 | 294 | #define PAD_DI_BIT_B 0 295 | #define PAD_DI_BIT_C 1 296 | #define PAD_DI_BIT_A 2 297 | #define PAD_DI_BIT_STR 3 298 | #define PAD_DI_BIT_UP 4 299 | #define PAD_DI_BIT_DOWN 5 300 | #define PAD_DI_BIT_LEFT 6 301 | #define PAD_DI_BIT_RIGHT 7 302 | #define PAD_DI_BIT_L (3+8) 303 | #define PAD_DI_BIT_Z (4+8) 304 | #define PAD_DI_BIT_X (5+8) 305 | #define PAD_DI_BIT_Y (6+8) 306 | #define PAD_DI_BIT_R (7+8) 307 | 308 | //Gamecube controller bit shifts 309 | #define GC_BIT_LEFT 0 310 | #define GC_BIT_RIGHT 1 311 | #define GC_BIT_DOWN 2 312 | #define GC_BIT_UP 3 313 | #define GC_BIT_Z 4 314 | #define GC_BIT_R 5 315 | #define GC_BIT_L 6 316 | #define GC_BIT_Z2 7 317 | #define GC_BIT_A 8 318 | #define GC_BIT_B 9 319 | #define GC_BIT_X 10 320 | #define GC_BIT_Y 11 321 | #define GC_BIT_STR 12 322 | 323 | //Wiimote bit shifts 324 | #define WII_BIT_LEFT 0 325 | #define WII_BIT_RIGHT 1 326 | #define WII_BIT_DOWN 2 327 | #define WII_BIT_UP 3 328 | #define WII_BIT_PLUS 4 329 | #define WII_BIT_2 8 330 | #define WII_BIT_1 9 331 | #define WII_BIT_B 10 332 | #define WII_BIT_A 11 333 | #define WII_BIT_MINUS 12 334 | #define WII_BIT_HOME 15 335 | 336 | //Classic controller bit shifts 337 | #define WCL_BIT_UP (8+16) 338 | #define WCL_BIT_LEFT (9+16) 339 | #define WCL_BIT_ZR (10+16) 340 | #define WCL_BIT_X (11+16) 341 | #define WCL_BIT_A (12+16) 342 | #define WCL_BIT_Y (13+16) 343 | #define WCL_BIT_B (14+16) 344 | #define WCL_BIT_ZL (15+16) 345 | #define WCL_BIT_R (1+16) 346 | #define WCL_BIT_PLUS (2+16) 347 | #define WCL_BIT_HOME (3+16) 348 | #define WCL_BIT_MINUS (4+16) 349 | #define WCL_BIT_L (5+16) 350 | #define WCL_BIT_DOWN (6+16) 351 | #define WCL_BIT_RIGHT (7+16) 352 | 353 | //TODO: Make generic wrapper for controller 354 | 355 | void per_Init(void); 356 | u32 per_updatePads(void); 357 | void per_closePad(u32 indx); 358 | 359 | #define GC_AXIS_TO_DIGITAL(x, y) (((x < -46) << GC_BIT_LEFT) | ((x > 46) << GC_BIT_RIGHT) | (((y < -54) << GC_BIT_DOWN) | ((y > 54) << GC_BIT_UP))) 360 | #define CLASSIC_AXIS_TO_DIGITAL(x, y) (((x < -46) << WCL_BIT_LEFT) | ((x > 46) << WCL_BIT_RIGHT) | (((y < -54) << WCL_BIT_DOWN) | ((y > 54) << WCL_BIT_UP))) 361 | 362 | 363 | /** @} */ 364 | 365 | #endif 366 | -------------------------------------------------------------------------------- /src/profile.c: -------------------------------------------------------------------------------- 1 | /* copyright Patrick Kooman, 2002 2 | 3 | Lightweight C & C++ profiler. Works both in 4 | debug- and release mode. For more info, read: 5 | 6 | http://www.2dgame-tutorial.com/sdl/profile.htm 7 | 8 | You are free to use / modify / re-distribute this code. 9 | 10 | */ 11 | #if !defined(SYS_PROFILE_H) && !defined(DONT_PROFILE) 12 | 13 | #include "profile.h" 14 | 15 | /* The time when the profiler initializes */ 16 | clock_t g_init_time ; 17 | /* Entries */ 18 | entry_t g_tag [NUM_TAGS] ; 19 | /* "high-water-mark" */ 20 | int g_i_hwm = 0 ; 21 | /* Is ProfileInit called? */ 22 | int g_init = 0 ; 23 | 24 | /* Looks up given tag and returns the name, 25 | of 0 if not found. */ 26 | static entry_t* LookupTag (char* str_tag) { 27 | int i ; 28 | for (i = 0; i < g_i_hwm; ++i) { 29 | if (strcmp (g_tag [i].str_name, str_tag) == 0) { 30 | return &g_tag [i] ; 31 | } 32 | } 33 | return 0 ; 34 | } 35 | 36 | /* Checks whether the given tag is already started (nesting). 37 | This is true when an entry with the given name is found, 38 | for which the start_time_t is not 0. */ 39 | static int Nested (char* str_tag) { 40 | int i ; 41 | for (i = 0; i < g_i_hwm; ++i) { 42 | if (strcmp (g_tag [i].str_name, str_tag) == 0 && g_tag [i].start_time > -1) { 43 | /* Already 'running': nested*/ 44 | return 1 ; 45 | } 46 | } 47 | /* Not running: not nested */ 48 | return 0 ; 49 | } 50 | 51 | /* Adds the given tag and return the entry it is stored into */ 52 | static entry_t* AddTag (char* str_tag) { 53 | if (g_i_hwm + 1 == NUM_TAGS) { 54 | /* Full */ 55 | return 0 ; 56 | } 57 | /* Copy the name */ 58 | strcpy (g_tag [g_i_hwm].str_name, str_tag) ; 59 | g_tag [g_i_hwm].start_time = -1 ; 60 | /* Increase the high-water-mark but return the current index */ 61 | return &g_tag [g_i_hwm++] ; 62 | } 63 | 64 | /* Compare function for 'qsort' */ 65 | static int CompareEntries (const void* p_1, const void* p_2) { 66 | entry_t* p_entry1, *p_entry2 ; 67 | /* Cast elements to entry_t type */ 68 | p_entry1 = (entry_t*) p_1 ; 69 | p_entry2 = (entry_t*) p_2 ; 70 | /* Compare */ 71 | return p_entry2->l_total_ms - p_entry1->l_total_ms ; 72 | } 73 | 74 | /* Called on the first start-call. It receives the start-time */ 75 | static void Init (void) { 76 | memset (g_tag, 0, sizeof (g_tag)) ; 77 | /* Retreive the time */ 78 | g_init_time = clock () ; 79 | /* Flag that this function has been called */ 80 | g_init = 1 ; 81 | g_i_hwm = 0 ; 82 | } 83 | 84 | /* Prints profiling statistice to stdout, 85 | sorted by percentage (descending) */ 86 | void ProfilePrint (void) { 87 | int i ; 88 | long l_prof_time ; 89 | if (g_i_hwm == 0) { 90 | fprintf (stdout, "ProfilePrint: nothing to print.\n") ; 91 | return ; 92 | } 93 | /* Retreive the time */ 94 | l_prof_time = clock () - g_init_time ; 95 | if (l_prof_time == 0) { 96 | /* Avoid division by 0 */ 97 | fprintf (stdout, "Warning: nothing to show because timer ran for less than 1 clock-tick.") ; 98 | } 99 | /* Print warnings for tags which are not stopped. */ 100 | for (i = 0; i < g_i_hwm; ++i) { 101 | if (g_tag [i].i_stopped == 0) { 102 | g_tag [i].l_total_ms += clock () - g_tag [i].start_time ; 103 | fprintf (stdout, "Warning: \"%s\" started but not stopped. (Done now, but result may be over-expensive!)\n", g_tag [i].str_name) ; 104 | } 105 | } 106 | /* Sort the array desending */ 107 | qsort (&g_tag, g_i_hwm, sizeof (entry_t), CompareEntries) ; 108 | fprintf (stdout, "Profiler results (descending by percentage):\n\n") ; 109 | for (i = 0; i < g_i_hwm; ++i) { 110 | /* Print statistics */ 111 | fprintf (stdout, "< calls: %2d, total ms: %3d, percentage: %3.1f%% > - \"%s\"\n", 112 | g_tag [i].i_calls, 113 | (int) ((double) g_tag [i].l_total_ms / CLOCKS_PER_SEC * 1000), 114 | (double) g_tag [i].l_total_ms / l_prof_time * 100, 115 | g_tag [i].str_name) ; 116 | } 117 | } 118 | 119 | /* Starts timer for given tag. If it does not exist yet, 120 | it is added. 121 | 122 | Note: 1. The tag may not be nested with the same name 123 | 2. The tag may not equal "" */ 124 | void ProfileStart (char* str_tag) { 125 | entry_t* p_entry ; 126 | /* One the first call, we must initialize the profiler. */ 127 | if (!g_init) { 128 | Init () ; 129 | } 130 | /* Test for "" */ 131 | if (*str_tag == '\0') { 132 | fprintf (stdout, "ERROR in ProfileStart: a tag may not be \"\". Call is denied.") ; 133 | return ; 134 | } 135 | /* Search the entry with the given name */ 136 | p_entry = LookupTag (str_tag) ; 137 | if (!p_entry) { 138 | /* New tag, add it*/ 139 | p_entry = AddTag (str_tag) ; 140 | if (!p_entry) { 141 | fprintf (stdout, "WARNING in ProfileStart: no more space to store the tag (\"%s\"). Increase NUM_TAGS in \"profile.h\". Call is denied.\n", str_tag) ; 142 | return ; 143 | } 144 | } 145 | /* Check for nesting of equal tag.*/ 146 | if (Nested (str_tag)) { 147 | fprintf (stdout, "ERROR in ProfileStart: nesting of equal tags not allowed (\"%s\"). Call is denied.\n", str_tag) ; 148 | return ; 149 | } 150 | /* Increase the number of hits */ 151 | ++p_entry->i_calls ; 152 | /* Set the start time */ 153 | p_entry->start_time = clock () ; 154 | p_entry->i_stopped = 0 ; 155 | } 156 | 157 | /* Stops timer for given tag. Checks for existence. 158 | Adds the time between now and the Start call to the 159 | total time.*/ 160 | void ProfileStop (char* str_tag) { 161 | clock_t end_time ; 162 | entry_t* p_entry ; 163 | /* Test for "" */ 164 | if (*str_tag == '\0') { 165 | fprintf (stdout, "ERROR in ProfileStop: a tag may not be \"\". Call is denied.") ; 166 | return ; 167 | } 168 | /* Check for a existing name */ 169 | p_entry = LookupTag (str_tag) ; 170 | if (!p_entry) { 171 | fprintf (stdout, "WARNING in ProfileStop: tag \"%s\" was never started. Call is denied.\n", str_tag) ; 172 | return ; 173 | } 174 | /* Get the time */ 175 | end_time = clock () ; 176 | p_entry->l_total_ms += end_time - p_entry->start_time ; 177 | /* Reset */ 178 | p_entry->start_time = -1 ; 179 | p_entry->i_stopped = 1 ; 180 | } 181 | 182 | /* Resets the profiler. */ 183 | void ProfileReset (void) { 184 | Init () ; 185 | } 186 | 187 | #endif /* !SYS_PROFILE_H && !DONT_PROFILE */ 188 | 189 | -------------------------------------------------------------------------------- /src/profile.h: -------------------------------------------------------------------------------- 1 | /* copyright Patrick Kooman, 2002 2 | 3 | Lightweight C & C++ profiler. Works both in 4 | debug- and release mode. For more info, read: 5 | 6 | http://www.2dgame-tutorial.com/sdl/profile.htm 7 | 8 | You are free to use / modify / re-distribute this code. 9 | 10 | */ 11 | #ifndef _PROFILE_H_ 12 | #define _PROFILE_H_ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #ifdef DONT_PROFILE 21 | /* Profiling disabled: compiler won't generate machine instructions now. */ 22 | #define PROFILE_START(t) 23 | #define PROFILE_STOP(t) 24 | #define PROFILE_PRINT() 25 | #define PROFILE_RESET() 26 | #else 27 | /* Profiling enabled */ 28 | #define MAX_TAG_LEN 100 29 | #define NUM_TAGS 100 30 | 31 | typedef struct { 32 | char str_name [MAX_TAG_LEN] ; 33 | int i_calls ; 34 | clock_t start_time ; 35 | int i_stopped ; 36 | long l_total_ms ; 37 | } entry_t ; 38 | 39 | /* Compiler calls functions now. */ 40 | #define PROFILE_START(t) ProfileStart (t) 41 | #define PROFILE_STOP(t) ProfileStop (t) 42 | #define PROFILE_PRINT() ProfilePrint () 43 | #define PROFILE_RESET() ProfileReset () 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif /* __cplusplus */ 48 | 49 | /* Start timer for given tag */ 50 | void ProfileStart (char* str_tag) ; 51 | /* Stops timer for given tag and add time to total time for this tag */ 52 | void ProfileStop (char* str_tag) ; 53 | /* Prints result to stdout */ 54 | void ProfilePrint (void) ; 55 | /* Resets the profiler. */ 56 | void ProfileReset (void) ; 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif /* __cplusplus */ 61 | 62 | #endif /* NO_PROFILE */ 63 | 64 | #endif /* _PROFILE_H_ */ 65 | 66 | -------------------------------------------------------------------------------- /src/scsp.h: -------------------------------------------------------------------------------- 1 | /* src/scsp2.h: Header for new SCSP implementation 2 | * Copyright 2010 Andrew Church 3 | * 4 | * This file is part of Yabause. 5 | * 6 | * Yabause is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Yabause is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Yabause; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SCSP_H // Not SCSP2_H (we substitute for the original scsp.h) 22 | #define SCSP_H 23 | 24 | #include "core.h" // For sized integer types 25 | #include "snd.h" 26 | /////////////////////////////////////////////////////////////////////////// 27 | // Breakpoint data structure (currently just an address) 28 | typedef struct { 29 | u32 addr; 30 | } M68KBreakpointInfo; 31 | 32 | #ifdef SCSP_PLUGIN 33 | #define SCSCORE_DEFAULT -1 34 | #define SCSCORE_DUMMY 0 35 | #define SCSCORE_SCSP1 1 36 | #define SCSCORE_SCSP2 2 37 | 38 | typedef struct 39 | { 40 | int id; 41 | const char *Name; 42 | int (*Init)(int coreid, void (*interrupt_handler)(void)); 43 | void (*DeInit)(void); 44 | void (*Reset)(void); 45 | int (*ChangeVideoFormat)(int type); 46 | void (*Exec)(int decilines); 47 | void (*MuteAudio)(int flags); 48 | void (*UnMuteAudio)(int flags); 49 | void (*SetVolume)(int volume); 50 | void (*M68KStart)(void); 51 | void (*M68KStop)(void); 52 | u8 FASTCALL (*SoundRamReadByte)(u32 addr); 53 | void FASTCALL (*SoundRamWriteByte)(u32 addr, u8 val); 54 | u16 FASTCALL (*SoundRamReadWord)(u32 addr); 55 | void FASTCALL (*SoundRamWriteWord)(u32 addr, u16 val); 56 | u32 FASTCALL (*SoundRamReadLong)(u32 addr); 57 | void FASTCALL (*SoundRamWriteLong)(u32 addr, u32 val); 58 | void (*ReceiveCDDA)(const u8 *sector); 59 | int (*SoundSaveState)(FILE *fp); 60 | int (*SoundLoadState)(FILE *fp, int version, int size); 61 | u32 FASTCALL (*M68KReadWord)(const u32 adr); 62 | u8 FASTCALL (*ReadByte)(u32 address); 63 | u16 FASTCALL (*ReadWord)(u32 address); 64 | u32 FASTCALL (*ReadLong)(u32 address); 65 | void FASTCALL (*WriteByte)(u32 address, u8 data); 66 | void FASTCALL (*WriteWord)(u32 address, u16 data); 67 | void FASTCALL (*WriteLong)(u32 address, u32 data); 68 | M68KBreakpointInfo *(*M68KGetBreakpointList)(void); 69 | } SCSPInterface_struct; 70 | 71 | extern SCSPInterface_struct *SCSCore; 72 | extern SCSPInterface_struct SCSDummy; 73 | extern SCSPInterface_struct SCSScsp1; 74 | extern SCSPInterface_struct SCSScsp2; 75 | extern SCSPInterface_struct *SCSCoreList[]; // Defined by each port 76 | #endif 77 | 78 | /////////////////////////////////////////////////////////////////////////// 79 | 80 | // Module interface declaration 81 | 82 | #define SNDCORE_DEFAULT -1 83 | #define SNDCORE_DUMMY 0 84 | #define SNDCORE_WAV 10 // Should be 1, but left as is for backward compat 85 | 86 | #define SCSP_MUTE_SYSTEM 1 87 | #define SCSP_MUTE_USER 2 88 | 89 | 90 | /////////////////////////////////////////////////////////////////////////// 91 | 92 | // Parameter block for M68K{Get,Set}Registers() 93 | typedef struct { 94 | u32 D[8]; 95 | u32 A[8]; 96 | u32 SR; 97 | u32 PC; 98 | } M68KRegs; 99 | 100 | // Maximum number of M68K breakpoints that can be set simultaneously 101 | #define M68K_MAX_BREAKPOINTS 10 102 | 103 | /////////////////////////////////////////////////////////////////////////// 104 | 105 | // Data/function declarations 106 | 107 | extern u8 *SoundRam; 108 | 109 | extern int ScspInit(int coreid, void (*interrupt_handler)(void)); 110 | extern void ScspReset(void); 111 | #ifdef SCSP_PLUGIN 112 | extern int ScspChangeCore(int coreid); 113 | #endif 114 | extern int ScspChangeSoundCore(int coreid); 115 | extern int ScspChangeVideoFormat(int type); 116 | extern void ScspSetFrameAccurate(int on); 117 | extern void ScspMuteAudio(int flags); 118 | extern void ScspUnMuteAudio(int flags); 119 | extern void ScspSetVolume(int volume); 120 | extern void ScspDeInit(void); 121 | 122 | extern void ScspExec(int decilines); 123 | 124 | extern u8 FASTCALL SoundRamReadByte(u32 address); 125 | extern u16 FASTCALL SoundRamReadWord(u32 address); 126 | extern u32 FASTCALL SoundRamReadLong(u32 address); 127 | extern void FASTCALL SoundRamWriteByte(u32 address, u8 data); 128 | extern void FASTCALL SoundRamWriteWord(u32 address, u16 data); 129 | extern void FASTCALL SoundRamWriteLong(u32 address, u32 data); 130 | extern u8 FASTCALL ScspReadByte(u32 address); 131 | extern u16 FASTCALL ScspReadWord(u32 address); 132 | extern u32 FASTCALL ScspReadLong(u32 address); 133 | extern void FASTCALL ScspWriteByte(u32 address, u8 data); 134 | extern void FASTCALL ScspWriteWord(u32 address, u16 data); 135 | extern void FASTCALL ScspWriteLong(u32 address, u32 data); 136 | extern void ScspReceiveCDDA(const u8 *sector); 137 | 138 | extern int SoundSaveState(FILE *fp); 139 | extern int SoundLoadState(FILE *fp, int version, int size); 140 | extern void ScspSlotDebugStats(u8 slotnum, char *outstring); 141 | extern void ScspCommonControlRegisterDebugStats(char *outstring); 142 | extern int ScspSlotDebugSaveRegisters(u8 slotnum, const char *filename); 143 | extern int ScspSlotDebugAudioSaveWav(u8 slotnum, const char *filename); 144 | #ifndef SCSP_PLUGIN 145 | extern void ScspConvert32uto16s(s32 *srcL, s32 *srcR, s16 *dest, u32 len); 146 | #else 147 | extern void Scsp2Convert32uto16s(s32 *srcL, s32 *srcR, s16 *dest, u32 len); 148 | #endif 149 | 150 | extern void M68KStart(void); 151 | extern void M68KStop(void); 152 | extern void M68KStep(void); 153 | extern void M68KWriteNotify(u32 address, u32 size); 154 | extern void M68KGetRegisters(M68KRegs *regs); 155 | extern void M68KSetRegisters(const M68KRegs *regs); 156 | extern void M68KSetBreakpointCallBack(void (*func)(u32 address)); 157 | extern int M68KAddCodeBreakpoint(u32 address); 158 | extern int M68KDelCodeBreakpoint(u32 address); 159 | #ifndef SCSP_PLUGIN 160 | extern const M68KBreakpointInfo *M68KGetBreakpointList(void); 161 | #else 162 | extern M68KBreakpointInfo *M68KGetBreakpointList(void); 163 | #endif 164 | extern void M68KClearCodeBreakpoints(void); 165 | extern u32 FASTCALL M68KReadByte(u32 address); 166 | extern u32 FASTCALL M68KReadWord(u32 address); 167 | extern void FASTCALL M68KWriteByte(u32 address, u32 data); 168 | extern void FASTCALL M68KWriteWord(u32 address, u32 data); 169 | 170 | /////////////////////////////////////////////////////////////////////////// 171 | 172 | // Compatibility macros to match scsp.h interface 173 | 174 | #define m68kregs_struct M68KRegs 175 | #define m68kcodebreakpoint_struct M68KBreakpointInfo 176 | 177 | #include "scu.h" 178 | #ifndef SCSP_PLUGIN 179 | #define ScspInit(coreid) ScspInit((coreid), ScuSendSoundRequest) 180 | #else 181 | //#define SCSScsp1Init(coreid) SCSScsp1Init((coreid), ScuSendSoundRequest) 182 | #endif 183 | 184 | #ifndef SCSP_PLUGIN 185 | #define scsp_r_b ScspReadByte 186 | #define scsp_r_w ScspReadWord 187 | #define scsp_r_d ScspReadLong 188 | #define scsp_w_b ScspWriteByte 189 | #define scsp_w_w ScspWriteWord 190 | #define scsp_w_d ScspWriteLong 191 | 192 | #define c68k_word_read M68KReadWord 193 | #else 194 | #define scsp_r_b SCSCore->ReadByte 195 | #define scsp_r_w SCSCore->ReadWord 196 | #define scsp_r_d SCSCore->ReadLong 197 | #define scsp_w_b SCSCore->WriteByte 198 | #define scsp_w_w SCSCore->WriteWord 199 | #define scsp_w_d SCSCore->WriteLong 200 | #define ScspReadByte SCSCore->ReadByte 201 | #define ScspReadWord SCSCore->ReadWord 202 | #define ScspReadLong SCSCore->ReadLong 203 | #define ScspWriteByte SCSCore->WriteByte 204 | #define ScspWriteWord SCSCore->WriteWord 205 | #define ScspWriteLong SCSCore->WriteLong 206 | 207 | #define c68k_word_read M68KReadWord 208 | #define M68KReadWord SCSCore->M68KReadWord 209 | #define SoundSaveState SCSCore->SoundSaveState 210 | #define ScspMuteAudio SCSCore->MuteAudio 211 | #define ScspUnMuteAudio SCSCore->UnMuteAudio 212 | #define SoundLoadState SCSCore->SoundLoadState 213 | //#define ScspInit SCSCore->Init 214 | #define ScspDeInit SCSCore->DeInit 215 | #define ScspReset SCSCore->Reset 216 | #define ScspChangeVideoFormat SCSCore->ChangeVideoFormat 217 | #define ScspReceiveCDDA SCSCore->ReceiveCDDA 218 | #define M68KStart SCSCore->M68KStart 219 | #define M68KStop SCSCore->M68KStop 220 | #endif 221 | 222 | /////////////////////////////////////////////////////////////////////////// 223 | 224 | typedef struct 225 | { 226 | u32 scsptiming1; 227 | u32 scsptiming2; // 16.16 fixed point 228 | 229 | m68kcodebreakpoint_struct codebreakpoint[MAX_BREAKPOINTS]; 230 | int numcodebreakpoints; 231 | void (*BreakpointCallBack)(u32); 232 | int inbreakpoint; 233 | } ScspInternal; 234 | 235 | #ifndef SCSP_PLUGIN 236 | void FASTCALL scsp_w_b(u32, u8); 237 | void FASTCALL scsp_w_w(u32, u16); 238 | void FASTCALL scsp_w_d(u32, u32); 239 | u8 FASTCALL scsp_r_b(u32); 240 | u16 FASTCALL scsp_r_w(u32); 241 | u32 FASTCALL scsp_r_d(u32); 242 | #endif 243 | 244 | void scsp_init(u8 *scsp_ram, void (*sint_hand)(u32), void (*mint_hand)(void)); 245 | void scsp_shutdown(void); 246 | void scsp_reset(void); 247 | 248 | void scsp_midi_in_send(u8 data); 249 | void scsp_midi_out_send(u8 data); 250 | u8 scsp_midi_in_read(void); 251 | u8 scsp_midi_out_read(void); 252 | void scsp_update(s32 *bufL, s32 *bufR, u32 len); 253 | void scsp_update_monitor(void); 254 | void scsp_update_timer(u32 len); 255 | 256 | void M68KExec(s32 cycles); 257 | void M68KSync(void); 258 | void M68KSortCodeBreakpoints(void); 259 | 260 | #ifndef SCSP_PLUGIN 261 | u32 FASTCALL c68k_word_read(const u32 adr); 262 | #endif 263 | 264 | #endif // SCSP_H 265 | -------------------------------------------------------------------------------- /src/scspdummy.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2004 Stephane Dallongeville 2 | Copyright 2004-2007 Theo Berkau 3 | Copyright 2006 Guillaume Duhamel 4 | 5 | This file is part of Yabause. 6 | 7 | Yabause is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | Yabause is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Yabause; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "scsp.h" 23 | 24 | ////////////////////////////////////////////////////////////////////////////// 25 | // Dummy SCSP Interface 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | static int SCSDummyInit(int coreid, void (*interrupt_handler)(void)); 29 | static void SCSDummyDeInit(void); 30 | static void SCSDummyReset(void); 31 | static int SCSDummyChangeVideoFormat(int type); 32 | static void SCSDummyExec(int decilines); 33 | static void SCSDummyMuteAudio(int flags); 34 | static void SCSDummyUnMuteAudio(int flags); 35 | static void SCSDummySetVolume(int volume); 36 | static void SCSDummyM68KStart(void); 37 | static void SCSDummyM68KStop(void); 38 | static u8 FASTCALL SCSDummySoundRamReadByte(u32 addr); 39 | static void FASTCALL SCSDummySoundRamWriteByte(u32 addr, u8 val); 40 | static u16 FASTCALL SCSDummySoundRamReadWord(u32 addr); 41 | static void FASTCALL SCSDummySoundRamWriteWord(u32 addr, u16 val); 42 | static u32 FASTCALL SCSDummySoundRamReadLong(u32 addr); 43 | static void FASTCALL SCSDummySoundRamWriteLong(u32 addr, u32 val); 44 | static void SCSDummyScspReceiveCDDA(const u8 *sector); 45 | static int SCSDummySoundSaveState(FILE *fp); 46 | static int SCSDummySoundLoadState(FILE *fp, int version, int size); 47 | static u32 FASTCALL SCSDummyM68KReadWord(const u32 adr); 48 | static u8 FASTCALL SCSDummyReadByte(u32 address); 49 | static u16 FASTCALL SCSDummyReadWord(u32 address); 50 | static u32 FASTCALL SCSDummyReadLong(u32 address); 51 | static void FASTCALL SCSDummyWriteByte(u32 address, u8 data); 52 | static void FASTCALL SCSDummyWriteWord(u32 address, u16 data); 53 | static void FASTCALL SCSDummyWriteLong(u32 address, u32 data); 54 | static M68KBreakpointInfo *SCSDummyM68KGetBreakpointList(void); 55 | 56 | SCSPInterface_struct SCSDummy = { 57 | SCSCORE_DUMMY, 58 | "Dummy SCSP Interface", 59 | SCSDummyInit, 60 | SCSDummyDeInit, 61 | SCSDummyReset, 62 | SCSDummyChangeVideoFormat, 63 | SCSDummyExec, 64 | SCSDummyMuteAudio, 65 | SCSDummyUnMuteAudio, 66 | SCSDummySetVolume, 67 | SCSDummyM68KStart, 68 | SCSDummyM68KStop, 69 | SCSDummySoundRamReadByte, 70 | SCSDummySoundRamWriteByte, 71 | SCSDummySoundRamReadWord, 72 | SCSDummySoundRamWriteWord, 73 | SCSDummySoundRamReadLong, 74 | SCSDummySoundRamWriteLong, 75 | SCSDummyScspReceiveCDDA, 76 | SCSDummySoundSaveState, 77 | SCSDummySoundLoadState, 78 | SCSDummyM68KReadWord, 79 | SCSDummyReadByte, 80 | SCSDummyReadWord, 81 | SCSDummyReadLong, 82 | SCSDummyWriteByte, 83 | SCSDummyWriteWord, 84 | SCSDummyWriteLong, 85 | SCSDummyM68KGetBreakpointList 86 | }; 87 | 88 | ////////////////////////////////////////////////////////////////////////////// 89 | 90 | static int SCSDummyInit(int coreid, void (*interrupt_handler)(void)) 91 | { 92 | return 0; 93 | } 94 | 95 | ////////////////////////////////////////////////////////////////////////////// 96 | 97 | static void SCSDummyDeInit(void) 98 | { 99 | } 100 | 101 | ////////////////////////////////////////////////////////////////////////////// 102 | 103 | static void SCSDummyReset(void) 104 | { 105 | } 106 | 107 | ////////////////////////////////////////////////////////////////////////////// 108 | 109 | static int SCSDummyChangeVideoFormat(int type) 110 | { 111 | return 0; 112 | } 113 | 114 | ////////////////////////////////////////////////////////////////////////////// 115 | 116 | static void SCSDummyExec(int decilines) 117 | { 118 | } 119 | 120 | ////////////////////////////////////////////////////////////////////////////// 121 | 122 | static void SCSDummyMuteAudio(int flags) 123 | { 124 | } 125 | 126 | ////////////////////////////////////////////////////////////////////////////// 127 | 128 | static void SCSDummyUnMuteAudio(int flags) 129 | { 130 | } 131 | 132 | ////////////////////////////////////////////////////////////////////////////// 133 | 134 | static void SCSDummySetVolume(UNUSED int volume) 135 | { 136 | } 137 | 138 | ////////////////////////////////////////////////////////////////////////////// 139 | 140 | static void SCSDummyM68KStart(void) 141 | { 142 | } 143 | 144 | ////////////////////////////////////////////////////////////////////////////// 145 | 146 | static void SCSDummyM68KStop(void) 147 | { 148 | } 149 | 150 | ////////////////////////////////////////////////////////////////////////////// 151 | 152 | static u8 FASTCALL SCSDummySoundRamReadByte(u32 addr) 153 | { 154 | return 0; 155 | } 156 | 157 | ////////////////////////////////////////////////////////////////////////////// 158 | 159 | static void FASTCALL SCSDummySoundRamWriteByte(u32 addr, u8 val) 160 | { 161 | } 162 | 163 | ////////////////////////////////////////////////////////////////////////////// 164 | 165 | static u16 FASTCALL SCSDummySoundRamReadWord(u32 addr) 166 | { 167 | return 0; 168 | } 169 | 170 | ////////////////////////////////////////////////////////////////////////////// 171 | 172 | static void FASTCALL SCSDummySoundRamWriteWord(u32 addr, u16 val) 173 | { 174 | } 175 | 176 | ////////////////////////////////////////////////////////////////////////////// 177 | 178 | static u32 FASTCALL SCSDummySoundRamReadLong(u32 addr) 179 | { 180 | return 0; 181 | } 182 | 183 | ////////////////////////////////////////////////////////////////////////////// 184 | 185 | static void FASTCALL SCSDummySoundRamWriteLong(u32 addr, u32 val) 186 | { 187 | } 188 | 189 | ////////////////////////////////////////////////////////////////////////////// 190 | 191 | static void SCSDummyScspReceiveCDDA(const u8 *sector) 192 | { 193 | } 194 | 195 | ////////////////////////////////////////////////////////////////////////////// 196 | 197 | static int SCSDummySoundSaveState(FILE *fp) 198 | { 199 | return 0; 200 | } 201 | 202 | ////////////////////////////////////////////////////////////////////////////// 203 | 204 | static int SCSDummySoundLoadState(FILE *fp, int version, int size) 205 | { 206 | return 0; 207 | } 208 | 209 | ////////////////////////////////////////////////////////////////////////////// 210 | 211 | static u32 FASTCALL SCSDummyM68KReadWord(const u32 adr) 212 | { 213 | return 0; 214 | } 215 | 216 | ////////////////////////////////////////////////////////////////////////////// 217 | 218 | static u8 FASTCALL SCSDummyReadByte(u32 address) 219 | { 220 | return 0; 221 | } 222 | 223 | ////////////////////////////////////////////////////////////////////////////// 224 | 225 | static u16 FASTCALL SCSDummyReadWord(u32 address) 226 | { 227 | return 0; 228 | } 229 | 230 | ////////////////////////////////////////////////////////////////////////////// 231 | 232 | static u32 FASTCALL SCSDummyReadLong(u32 address) 233 | { 234 | return 0; 235 | } 236 | 237 | ////////////////////////////////////////////////////////////////////////////// 238 | 239 | static void FASTCALL SCSDummyWriteByte(u32 address, u8 data) 240 | { 241 | } 242 | 243 | ////////////////////////////////////////////////////////////////////////////// 244 | 245 | static void FASTCALL SCSDummyWriteWord(u32 address, u16 data) 246 | { 247 | } 248 | 249 | ////////////////////////////////////////////////////////////////////////////// 250 | 251 | static void FASTCALL SCSDummyWriteLong(u32 address, u32 data) 252 | { 253 | } 254 | 255 | ////////////////////////////////////////////////////////////////////////////// 256 | 257 | static M68KBreakpointInfo *SCSDummyM68KGetBreakpointList(void) 258 | { 259 | return NULL; 260 | } 261 | 262 | ////////////////////////////////////////////////////////////////////////////// 263 | -------------------------------------------------------------------------------- /src/scu.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2005-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SCU_H 22 | #define SCU_H 23 | 24 | #include "core.h" 25 | 26 | typedef struct 27 | { 28 | u32 addr; 29 | } scucodebreakpoint_struct; 30 | 31 | #define MAX_BREAKPOINTS 10 32 | 33 | typedef struct 34 | { 35 | u8 vector; 36 | u8 level; 37 | u16 mask; 38 | u32 statusbit; 39 | } scuinterrupt_struct; 40 | 41 | typedef struct 42 | { 43 | int mode; 44 | u32 ReadAddress; 45 | u32 WriteAddress; 46 | s32 TransferNumber; 47 | u32 AddValue; 48 | u32 ModeAddressUpdate; 49 | u32 ReadAdd; 50 | u32 WriteAdd; 51 | u32 InDirectAdress; 52 | } scudmainfo_struct; 53 | 54 | typedef struct 55 | { 56 | /* DMA registers */ 57 | u32 D0R; 58 | u32 D0W; 59 | u32 D0C; 60 | u32 D0AD; 61 | u32 D0EN; 62 | u32 D0MD; 63 | 64 | u32 D1R; 65 | u32 D1W; 66 | u32 D1C; 67 | u32 D1AD; 68 | u32 D1EN; 69 | u32 D1MD; 70 | 71 | u32 D2R; 72 | u32 D2W; 73 | u32 D2C; 74 | u32 D2AD; 75 | u32 D2EN; 76 | u32 D2MD; 77 | 78 | u32 DSTP; 79 | u32 DSTA; 80 | 81 | /* DSP registers */ 82 | u32 PPAF; 83 | u32 PPD; 84 | u32 PDA; 85 | u32 PDD; 86 | 87 | /* Timer registers */ 88 | u32 T0C; 89 | u32 T1S; 90 | u32 T1MD; 91 | 92 | /* Interrupt registers */ 93 | u32 IMS; 94 | u32 IST; 95 | 96 | /* A-bus registers */ 97 | u32 AIACK; 98 | u32 ASR0; 99 | u32 ASR1; 100 | u32 AREF; 101 | 102 | /* SCU registers */ 103 | u32 RSEL; 104 | u32 VER; 105 | 106 | /* internal variables */ 107 | u32 timer0; 108 | u32 timer1; 109 | scuinterrupt_struct interrupts[30]; 110 | u32 NumberOfInterrupts; 111 | s32 timer1_counter; 112 | u32 timer0_set; 113 | u32 timer1_set; 114 | s32 timer1_preset; 115 | 116 | scudmainfo_struct dma0; 117 | scudmainfo_struct dma1; 118 | scudmainfo_struct dma2; 119 | 120 | } Scu; 121 | 122 | extern Scu * ScuRegs; 123 | 124 | typedef struct 125 | { 126 | scucodebreakpoint_struct codebreakpoint[MAX_BREAKPOINTS]; 127 | int numcodebreakpoints; 128 | void(*BreakpointCallBack)(u32); 129 | u8 inbreakpoint; 130 | } scubp_struct; 131 | 132 | typedef struct { 133 | u32 ProgramRam[256]; 134 | u32 MD[4][64]; 135 | union { 136 | struct { 137 | u32 unused1 : 5; 138 | u32 PR : 1; // Pause cancel flag 139 | u32 EP : 1; // Temporary stop execution flag 140 | u32 unused2 : 1; 141 | u32 T0 : 1; // D0 bus use DMA execute flag 142 | u32 S : 1; // Sine flag 143 | u32 Z : 1; // Zero flag 144 | u32 C : 1; // Carry flag 145 | u32 V : 1; // Overflow flag 146 | u32 E : 1; // Program end interrupt flag 147 | u32 ES : 1; // Program step execute control bit 148 | u32 EX : 1; // Program execute control bit 149 | u32 LE : 1; // Program counter load enable bit 150 | u32 unused3 : 7; 151 | u32 P : 8; // Program Ram Address 152 | } part; 153 | u32 all; 154 | } ProgControlPort; 155 | u8 PC; 156 | u8 TOP; 157 | u16 LOP; 158 | s32 jmpaddr; 159 | int delayed; 160 | u8 DataRamPage; 161 | u8 DataRamReadAddress; 162 | u8 CT[4]; 163 | s32 RX; 164 | s32 RY; 165 | u32 RA0; 166 | u32 WA0; 167 | 168 | union { 169 | struct { 170 | s64 unused : 16; 171 | s64 H : 16; 172 | s64 L : 32; 173 | } part; 174 | s64 all; 175 | } AC; 176 | 177 | union { 178 | struct { 179 | s64 unused : 16; 180 | s64 H : 16; 181 | s64 L : 32; 182 | } part; 183 | s64 all; 184 | } P; 185 | 186 | union { 187 | struct { 188 | s64 unused : 16; 189 | s64 H : 16; 190 | s64 L : 32; 191 | } part; 192 | s64 all; 193 | } ALU; 194 | 195 | union { 196 | struct { 197 | s64 unused : 16; 198 | s64 H : 16; 199 | s64 L : 32; 200 | } part; 201 | s64 all; 202 | } MUL; 203 | 204 | u32 dsp_dma_instruction; 205 | s32 dsp_dma_wait; 206 | u32 dsp_dma_size; 207 | u32 WA0M; 208 | u32 RA0M; 209 | u32 dmy; 210 | } scudspregs_struct; 211 | 212 | 213 | int ScuInit(void); 214 | void ScuDeInit(void); 215 | void ScuReset(void); 216 | void ScuExec(u32 timing); 217 | 218 | u8 FASTCALL ScuReadByte(u32); 219 | u16 FASTCALL ScuReadWord(u32); 220 | u32 FASTCALL ScuReadLong(u32); 221 | void FASTCALL ScuWriteByte(u32, u8); 222 | void FASTCALL ScuWriteWord(u32, u16); 223 | void FASTCALL ScuWriteLong(u32, u32); 224 | 225 | void ScuSendVBlankIN(void); 226 | void ScuSendVBlankOUT(void); 227 | void ScuSendHBlankIN(void); 228 | void ScuRemoveHBlankIN(); 229 | void ScuSendTimer0(void); 230 | void ScuSendTimer1(void); 231 | void ScuSendDSPEnd(void); 232 | void ScuSendSoundRequest(void); 233 | void ScuSendSystemManager(void); 234 | void ScuSendPadInterrupt(void); 235 | void ScuSendDMAEnd(u32 mode); 236 | void ScuSendDMAIllegal(void); 237 | void ScuSendDrawEnd(void); 238 | 239 | void ScuDspStep(void); 240 | void ScuDspGetRegisters(scudspregs_struct *regs); 241 | void ScuDspSetRegisters(scudspregs_struct *regs); 242 | void ScuDspSetBreakpointCallBack(void(*func)(u32)); 243 | int ScuDspAddCodeBreakpoint(u32 addr); 244 | int ScuDspDelCodeBreakpoint(u32 addr); 245 | scucodebreakpoint_struct *ScuDspGetBreakpointList(void); 246 | void ScuDspClearCodeBreakpoints(void); 247 | void ScuSendExternalInterrupt00(void); 248 | #endif 249 | -------------------------------------------------------------------------------- /src/sgx/indtex.c: -------------------------------------------------------------------------------- 1 | #include "sgx.h" 2 | 3 | 4 | #define INDTEX_SIZE 0x8000 5 | 6 | static u8 indtex_data[INDTEX_SIZE] ATTRIBUTE_ALIGN(32); 7 | static u32 ind_addr = 0; 8 | static SGXTexPre indtex_arr[3*4*64]; 9 | u32 preloadtex_addr = 0x60000 >> 5; //Begin address of preloaded textures 10 | 11 | // 4bpp indirect 12 | // n is the width divided by 8 13 | static u32 __indtex4bppGen(u16 *data, u32 n, u32 align) 14 | { 15 | u32 tile_cnt = (((n-1)>>2)+1) << 1; 16 | align <<= 1; 17 | u32 n0 = align; 18 | 19 | //We must fill 8 rows 20 | u16 *i0 = data + (0); 21 | u16 *i1 = data + (4); 22 | u16 *i2 = data + (8); 23 | u16 *i3 = data + (12); 24 | u16 *i4 = data + (0 + (tile_cnt << 3)); 25 | u16 *i5 = data + (4 + (tile_cnt << 3)); 26 | u16 *i6 = data + (8 + (tile_cnt << 3)); 27 | u16 *i7 = data + (12 + (tile_cnt << 3)); 28 | 29 | u32 last_v = 12 + (tile_cnt << 3); 30 | //u32 y_ofs = 2; 31 | u32 last = 12 + (tile_cnt << 3); 32 | u32 xc = 128; 33 | for (u32 col = 0; col < n;) { 34 | for (u32 s = 0; (s < 4) && (col < n); ++s, ++col) { 35 | u32 yc = 128; 36 | u32 nn = n0; 37 | //Calculate the offsets 38 | *i0++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 39 | *i1++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 40 | *i2++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 41 | *i3++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 42 | *i4++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 43 | *i5++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 44 | *i6++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 45 | *i7++ = ((xc + (nn >> 3)) << 8) | ((yc--) + (nn & 0x7)); nn += n; 46 | 47 | ++n0; 48 | --xc; 49 | last = s+last_v; 50 | } 51 | i0 += 12; i1 += 12; i2 += 12; i3 += 12; 52 | i4 += 12; i5 += 12; i6 += 12; i7 += 12; 53 | last_v += 16; 54 | } 55 | 56 | // Correct the last 2, 4 or 6 entries... 57 | for (u32 i = 0; i < align; ++i) { 58 | u8 *it = (u8*) &data[last]; 59 | it[0] -= (n); 60 | it[1] += (8); 61 | 62 | if (last & 0x3) { 63 | --last; 64 | } else { 65 | if (n <= 4) { 66 | last = last + (n - 5); 67 | } else { 68 | last -= 13; 69 | } 70 | } 71 | } 72 | 73 | return tile_cnt; //Return the number of 32-byte tiles stored 74 | } 75 | 76 | 77 | // 8bpp indirect 78 | // n is the width divided by 8 79 | static u32 __indtex8bppGen(u16 *data, u32 n, u32 align) 80 | { 81 | // We only must fill 4 rows 82 | u32 tile_cnt = (((n-1)>>2)+1); 83 | u32 n0 = align; 84 | 85 | //We must fill 8 rows 86 | u16 *i0 = data + (0); 87 | u16 *i1 = data + (4); 88 | u16 *i2 = data + (8); 89 | u16 *i3 = data + (12); 90 | 91 | u32 last_v = 12; 92 | u32 last = 0; 93 | u32 xc = 128; 94 | for (u32 col = 0; col < n;) { 95 | for (u32 s = 0; (s < 4) && (col < n); ++s, ++col) { 96 | u32 yc = 128; 97 | u32 nn = n0; 98 | //Calculate the offsets 99 | *i0++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 100 | *i1++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 101 | *i2++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 102 | *i3++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 103 | 104 | ++n0; 105 | --xc; 106 | last = s+last_v; 107 | } 108 | i0 += 12; i1 += 12; i2 += 12; i3 += 12; 109 | last_v += 16; 110 | } 111 | 112 | // Correct the last 1, 2 or 3 entries... 113 | for (u32 i = 0; i < align; ++i) { 114 | u8 *it = (u8*) &data[last]; 115 | it[0] -= (n); 116 | it[1] += (4); 117 | 118 | if (last & 0x3) { 119 | --last; 120 | } else { 121 | if (n <= 2) { 122 | last = last + (n - 3); 123 | } else { 124 | last -= 13; 125 | } 126 | } 127 | } 128 | 129 | return tile_cnt; //Return the number of bytes stored 130 | } 131 | 132 | 133 | 134 | // 16bpp indirect 135 | // n is the width divided by 8 136 | static u32 __indtex16bppGen(u16 *data, u32 n, u32 align) 137 | { 138 | n *= 2; // Almost the same as if we made a 8bpp indirect of double the width 139 | u32 tile_cnt = (((n-1)>>2)+1); 140 | u32 n0 = align; 141 | 142 | //We must fill 8 rows 143 | u16 *i0 = data + (0); 144 | u16 *i1 = data + (4); 145 | u16 *i2 = data + (8); 146 | u16 *i3 = data + (12); 147 | 148 | u32 last_v = 12; 149 | u32 last = 0; 150 | u32 xc = 128; 151 | for (u32 col = 0; col < n;) { 152 | for (u32 s = 0; (s < 4) && (col < n); ++s, ++col) { 153 | u32 yc = 128; 154 | u32 nn = n0; 155 | //Calculate the offsets 156 | *i0++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 157 | *i1++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 158 | *i2++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 159 | *i3++ = ((xc + (nn >> 2)) << 8) | ((yc--) + (nn & 0x3)); nn += n; 160 | 161 | ++n0; 162 | --xc; 163 | last = s+last_v; 164 | } 165 | i0 += 12; i1 += 12; i2 += 12; i3 += 12; 166 | last_v += 16; 167 | } 168 | 169 | 170 | // Correct the last 1, 2 or 3 entries... 171 | for (u32 i = 0; i < align; ++i) { 172 | u8 *it = (u8*) &data[last]; 173 | it[0] -= (n); //XXX: could be wrong 174 | it[1] += (4); 175 | 176 | 177 | if (last & 0x3) { 178 | --last; 179 | } else { 180 | if (n <= 2) { 181 | last = last + (n - 3); 182 | } else { 183 | last -= 13; 184 | } 185 | } 186 | } 187 | 188 | return tile_cnt; //Return the number of bytes stored 189 | } 190 | 191 | void SGX_InitSpriteConv(void) 192 | { 193 | ind_addr = 0; 194 | 195 | } 196 | 197 | //Uses the sprite size (from 0 to 62) to make use of indirect textrue conversion 198 | void SGX_SpriteConverterSet(u32 width, u32 bpp_id, u32 align) 199 | { 200 | //If width is greater than 8 pixels or is using 16bpp 201 | u32 use_indirect = (width + align + (bpp_id & SPRITE_16BPP)) > 1; 202 | GX_SetNumIndStages(use_indirect); 203 | if (use_indirect) { 204 | //Check if indirect texture is preloaded (if not then generate and load) 205 | u32 t = (bpp_id << 8) + (align << 6) + width; 206 | SGXTexPre *tex = indtex_arr + t; 207 | if (!tex->addr) { 208 | u32 tile_cnt; 209 | tex->addr = preloadtex_addr | (0x200000 | 0xD8000); 210 | tex->attr = TEX_ATTR(GX_CLAMP, GX_REPEAT); 211 | //Check bpp to generate texture 212 | if (bpp_id == SPRITE_4BPP) { 213 | tile_cnt = __indtex4bppGen((u16*)(indtex_data + ind_addr), width, align); 214 | tex->fmt = TEX_FMT(GX_TF_IA8, width, 8); 215 | } else { 216 | // 8bpp is the same as 16bpp if the width is doubled 217 | width <<= bpp_id == SPRITE_16BPP; 218 | tile_cnt = __indtex8bppGen((u16*)(indtex_data + ind_addr), width, align); 219 | tex->fmt = TEX_FMT(GX_TF_IA8, width, 4); 220 | } 221 | DCStoreRange(indtex_data + ind_addr, tile_cnt * 32); 222 | //TODO: Directly load usign BP Registers 223 | SGX_PreloadTex(indtex_data + ind_addr, tex->addr, TEXPRE_TYPE_16BPP | tile_cnt); 224 | ind_addr += tile_cnt * 32; 225 | ind_addr = (ind_addr > 0x7C00 ? 0 : ind_addr); 226 | preloadtex_addr += tile_cnt; 227 | } 228 | SGX_SetTexPreloaded(GX_TEXMAP7, tex); 229 | GX_SetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_ST, GX_ITM_0 + (bpp_id >> 1), GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); 230 | GX_SetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP7); 231 | GX_SetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_8 - (bpp_id >> 1), GX_ITS_1); 232 | } else { 233 | GX_SetTevDirect(GX_TEVSTAGE0); 234 | } 235 | } 236 | 237 | 238 | static const u16 indtex_8x2cell[] ATTRIBUTE_ALIGN(32) = { 239 | 0x8080, 0x7F81, 0x0000, 0x0000, 240 | 0x817F, 0x8080, 0x0000, 0x0000, 241 | 0x0000, 0x0000, 0x0000, 0x0000, 242 | 0x0000, 0x0000, 0x0000, 0x0000 243 | }; 244 | 245 | static const u16 indtex_16x1cell[] ATTRIBUTE_ALIGN(32) = { 246 | 0x8080, 0x7f81, 0x0000, 0x0000, 247 | 0x8081, 0x7f82, 0x0000, 0x0000, 248 | 0x817e, 0x807f, 0x0000, 0x0000, 249 | 0x817f, 0x8080, 0x0000, 0x0000 250 | }; 251 | 252 | static const u16 indtex_16x2cell[] ATTRIBUTE_ALIGN(32) = { 253 | 0x8080, 0x7f81, 0x7e84, 0x7d85, 254 | 0x8081, 0x7f82, 0x7e85, 0x7d86, 255 | 0x817e, 0x807f, 0x7f82, 0x7e83, 256 | 0x817f, 0x8080, 0x7f83, 0x7e84, 257 | 258 | 0x827c, 0x817d, 0x8080, 0x7f81, 259 | 0x827d, 0x817e, 0x8081, 0x7f82, 260 | 0x837a, 0x827b, 0x817e, 0x807f, 261 | 0x837b, 0x827c, 0x817f, 0x8080 262 | }; 263 | 264 | enum IndCell { 265 | INDTEX_CELL_8x2, 266 | INDTEX_CELL_16x1, 267 | INDTEX_CELL_16x2 268 | }; 269 | 270 | SGXTexPre indtex_cell[8] = { 271 | {.addr = (0x7FF00 >> 5) | (0x200000 | 0xD8000), .fmt = TEX_FMT(GX_TF_IA8, 2, 2), .attr = TEX_ATTR(GX_CLAMP, GX_REPEAT)}, 272 | {.addr = (0x7FF20 >> 5) | (0x200000 | 0xD8000), .fmt = TEX_FMT(GX_TF_IA8, 2, 4), .attr = TEX_ATTR(GX_CLAMP, GX_REPEAT)}, 273 | {.addr = (0x7FF40 >> 5) | (0x200000 | 0xD8000), .fmt = TEX_FMT(GX_TF_IA8, 4, 8), .attr = TEX_ATTR(GX_CLAMP, GX_REPEAT)}, 274 | }; 275 | 276 | void SGX_CellConverterInit(void) 277 | { 278 | SGX_PreloadTex(indtex_8x2cell , indtex_cell[INDTEX_CELL_8x2].addr, TEXPRE_TYPE_16BPP | 1); 279 | SGX_PreloadTex(indtex_16x1cell, indtex_cell[INDTEX_CELL_16x1].addr, TEXPRE_TYPE_16BPP | 1); 280 | SGX_PreloadTex(indtex_16x2cell, indtex_cell[INDTEX_CELL_16x2].addr, TEXPRE_TYPE_16BPP | 2); 281 | } 282 | 283 | void SGX_CellConverterSet(u32 cellsize, u32 bpp_id) 284 | { 285 | if (cellsize && (bpp_id == SPRITE_8BPP)) { 286 | GX_SetNumIndStages(1); 287 | SGX_SetTexPreloaded(GX_TEXMAP7, &indtex_cell[INDTEX_CELL_8x2]); 288 | GX_SetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP7); 289 | GX_SetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_ST, GX_ITM_2, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); 290 | GX_SetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_8, GX_ITS_4); 291 | } else if (bpp_id == SPRITE_16BPP) { 292 | GX_SetNumIndStages(1); 293 | SGX_SetTexPreloaded(GX_TEXMAP7, &indtex_cell[INDTEX_CELL_16x1 + cellsize]); 294 | GX_SetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_ST, GX_ITM_1, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF); 295 | GX_SetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP7); 296 | GX_SetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_4, GX_ITS_1); 297 | } 298 | //TODO: Handle Cell 16BPP (1x1 and 2x2) 299 | } 300 | -------------------------------------------------------------------------------- /src/sgx/sgx.h: -------------------------------------------------------------------------------- 1 | #ifndef __VID_GX_H__ 2 | #define __VID_GX_H__ 3 | 4 | #include 5 | #include "../memory.h" 6 | #include "svi.h" 7 | 8 | #define VTXFMT_FLAT_TEX GX_VTXFMT2 9 | #define VTXFMT_GOUR_TEX GX_VTXFMT3 10 | #define VTXFMT_COLOR GX_VTXFMT5 11 | 12 | #define TLUT_INDX(type, pos) ((GX_TLUT_2K << 10) | (((pos) + (type) + 0x200) & 0x3ff)) 13 | 14 | 15 | #define TLUT_SIZE_16 (GX_TLUT_16 << 10) 16 | #define TLUT_SIZE_256 (GX_TLUT_256 << 10) 17 | #define TLUT_SIZE_2K (GX_TLUT_2K << 10) 18 | 19 | #define TLUT_FMT_IA8 (GX_TL_IA8 << 10) 20 | #define TLUT_FMT_RGB5A3 (GX_TL_RGB5A3 << 10) 21 | #define TLUT_FMT_RGB565 (GX_TL_RGB565 << 10) 22 | 23 | #define TLUT_INDX_CRAM (0x200) 24 | #define TLUT_INDX_PPCC (0x210) //Priority and colorcalculation (256 colors) 25 | #define TLUT_INDX_WIN (0x22E) //Vdp2 Window values (16 colors) 26 | #define TLUT_INDX_CLROFS (0x22F) //Vdp2 Color Offset (16 colors) 27 | #define TLUT_INDX_CLRBANK (0x2F0) //Vdp1 color bank parts (256 colors) 28 | #define TLUT_INDX_CRAM0 (0x300) 29 | #define TLUT_INDX_CRAM1 (0x380) //Color Ram 30 | #define TLUT_INDX_IMM4 (0x310) //Vdp1 CLUT parts 31 | #define TLUT_INDX_IMM ((GX_TLUT_16 << 10) | (0x380 & 0x3ff)) 32 | #define TLUT_INDX_IMM8 (((GX_TLUT_256) << 10) | (0x3E0 & 0x3ff)) 33 | 34 | //========================= 35 | //Matrices 36 | //========================= 37 | //We use the matrix memory to generate textures and positions 38 | //Without having to make costly calculations, i.e. we use the 39 | //GPU to our advantage 40 | //Position matrices: 41 | #define MTX_IDENTITY 0 // Identity matrix (Constant) 42 | #define MTX_MOVED_640 3 // Identity matrix that has been moved 640 pixels (Constant) 43 | #define MTX_VDP1_POS_2D 6 // For positions of 2d sprites 44 | #define MTX_VDP1_POS_3D 9 // For positions of 3d polygons 45 | #define MTX_VDP2_POS_BG 12 // For positions of backgrounds 46 | #define MTX_IDENTITY_2X 15 // Identity matrix (Constant) 47 | 48 | 49 | //Texture matrices: 50 | #define MTX_TEX_IDENTITY 28 // Textures set identity (Constant) 51 | #define MTX_TEX_FLIP_N 30 // Textures set identity (Constant) 52 | #define MTX_TEX_FLIP_X 32 // Textures get flipped in X axis (Constant) 53 | #define MTX_TEX_FLIP_Y 34 // Textures get flipped in Y axis (Constant) 54 | #define MTX_TEX_FLIP_XY 36 // Textures get flipped in X and Y axis (Constant) 55 | #define MTX_TEX_VDP1_GOUR 38 // For Gouraud shaded VDP1 parts (Constant) 56 | #define MTX_TEX_SCALED_N 40 // For scaled axis aligned textures (Vdp1 fb or display scaling) 57 | #define MTX_TEX_SCALED_X 42 // For scaled axis aligned textures (Vdp1 fb or display scaling) 58 | #define MTX_TEX_SCALED_Y 44 // For scaled axis aligned textures (Vdp1 fb or display scaling) 59 | #define MTX_TEX_SCALED_XY 46 // For scaled axis aligned textures (Vdp1 fb or display scaling) 60 | 61 | //========================= 62 | 63 | #define TLUT_TYPE_FULL 0x0 64 | #define TLUT_TYPE_4BPP 0x80 65 | #define TLUT_TYPE_8BPP 0x100 66 | 67 | #define TEX_FMT(fmt, w, h) ((fmt << 20) | (((h-1) & 0x3FFu) << 10) | ((w-1) & 0x3FFu)) 68 | #define TEX_ATTR(wrap_s, wrap_t) ((((wrap_t) & 0x3u) << 2) | ((wrap_s) & 0x3u)) 69 | #define TEXREG(addr, size) ((addr >> 5) | size) 70 | #define TEXREG_SIZE_NONE 0x0 71 | #define TEXREG_SIZE_128K 0x120000 72 | #define TEXREG_SIZE_32K 0xD8000 73 | 74 | #define SPRITE_NONE 0 75 | #define SPRITE_4BPP 0 76 | #define SPRITE_8BPP 1 77 | #define SPRITE_16BPP 2 78 | 79 | 80 | #define TEXPRE_TYPE_4BPP (1<<15) 81 | #define TEXPRE_TYPE_8BPP (2<<15) 82 | #define TEXPRE_TYPE_16BPP (2<<15) 83 | #define TEXPRE_TYPE_32BPP (3<<15) 84 | 85 | 86 | #define PRI_SPR 0x07 87 | #define PRI_RGB0 0x06 88 | #define PRI_NGB0 0x05 89 | #define PRI_NGB1 0x04 90 | #define PRI_NGB2 0x03 91 | #define PRI_NGB3 0x02 92 | #define PRI_LINECOLOR 0x01 93 | #define PRI_BACKCOLOR 0x10 //This Z value should be the lowest possible 94 | 95 | #define USE_NEW_VDP1 1 96 | 97 | //======================================== 98 | // Macros for writing to gpu regs 99 | //======================================== 100 | #define GX_LOAD_BP_REG(x) \ 101 | do { \ 102 | wgPipe->U8 = 0x61; \ 103 | asm volatile ("" ::: "memory" ); \ 104 | wgPipe->U32 = (u32)(x); \ 105 | asm volatile ("" ::: "memory" ); \ 106 | } while(0) 107 | 108 | //Masks bits when writing once to BP regs (afterwards it is reset) 109 | #define SGX_MASK_BP(mask) GX_LOAD_BP_REG((0xFE000000 | (mask & 0xFFFFFF))) 110 | #define __SGX_FLUSH_TEX_STATE GX_LOAD_BP_REG((0x0F << 24)) 111 | 112 | #define GX_LOAD_CP_REG(x, y) \ 113 | do { \ 114 | wgPipe->U8 = 0x08; \ 115 | asm volatile ("" ::: "memory" ); \ 116 | wgPipe->U8 = (u8)(x); \ 117 | asm volatile ("" ::: "memory" ); \ 118 | wgPipe->U32 = (u32)(y); \ 119 | asm volatile ("" ::: "memory" ); \ 120 | } while(0) 121 | 122 | #define GX_LOAD_XF_REG(x, y) \ 123 | do { \ 124 | wgPipe->U8 = 0x10; \ 125 | asm volatile ("" ::: "memory" ); \ 126 | wgPipe->U32 = (u32)((x)&0xffff); \ 127 | asm volatile ("" ::: "memory" ); \ 128 | wgPipe->U32 = (u32)(y); \ 129 | asm volatile ("" ::: "memory" ); \ 130 | } while(0) 131 | 132 | #define GX_LOAD_XF_REGS(x, n) \ 133 | do { \ 134 | wgPipe->U8 = 0x10; \ 135 | asm volatile ("" ::: "memory" ); \ 136 | wgPipe->U32 = (u32)(((((n)&0xffff)-1)<<16)|((x)&0xffff)); \ 137 | asm volatile ("" ::: "memory" ); \ 138 | } while(0) 139 | 140 | 141 | typedef struct SGXTexPre_t { 142 | u32 addr; //Address region in TMEM 143 | u32 fmt; //Format for loading texture to TEXMAP 144 | u32 attr; 145 | } SGXTexPre; 146 | 147 | static inline void GX_Color1u24(u32 clr) 148 | { 149 | wgPipe->U8 = clr >> 16; 150 | wgPipe->U16 = clr; 151 | } 152 | 153 | 154 | void SGX_Init(void); 155 | void SGX_BeginVdp1(void); 156 | void SGX_InitTex(u32 mapid, u32 even, u32 odd); 157 | void SGX_SetTex(void *img_addr, u32 fmt, u32 w, u32 h, u32 tlut); 158 | void SGX_PreloadTex(const void *tex_addr, u32 tmem_addr, u32 tile_cnt_fmt); 159 | void SGX_SetTexPreloaded(u32 mapid, SGXTexPre *tex); 160 | void SGX_SetOtherTex(u32 mapid, void *img_addr, u32 fmt, u32 w, u32 h, u32 tlut); 161 | void SGX_SpriteConverterSet(u32 width, u32 bpp_id, u32 align); 162 | void SGX_EndVdp1(void); 163 | void SGX_BeginVdp2Scroll(u32 fmt, u32 sz); 164 | void SGX_SetVdp2Texture(void *img_addr, u32 tlut); 165 | void SGX_LoadTlut(void *data_addr, u32 tlut); 166 | void SGX_SetZOffset(u32 offset); 167 | 168 | void SGX_CellConverterInit(void); 169 | void SGX_CellConverterSet(u32 cellsize, u32 bpp_id); 170 | void SGX_SetVtxOffset(f32 x, f32 y); 171 | 172 | void SGX_DrawScroll(void); 173 | void SGX_DrawBitmap(void); 174 | 175 | void SGX_Vdp2GenCRAM(void); 176 | 177 | void SGX_Vdp2ColorRamLoad(void); 178 | void SGX_InvalidateVRAM(void); 179 | void SGX_TlutLoadCRAMImm(u32 pos, u32 trn_code, u32 size); 180 | void SGX_ColorRamDirty(u32 pos); 181 | 182 | //Functions for Vdp1 Drawing 183 | void SGX_Vdp1Init(void); 184 | void SGX_Vdp1Deinit(void); 185 | void SGX_Vdp1Begin(void); 186 | void SGX_Vdp1End(void); 187 | void SGX_Vdp1DrawFramebuffer(void); 188 | void SGX_Vdp1SwapFramebuffer(void); 189 | void SGX_Vdp1ProcessFramebuffer(void); 190 | void SGX_Vdp1DrawNormalSpr(void); 191 | void SGX_Vdp1DrawScaledSpr(void); 192 | void SGX_Vdp1DrawDistortedSpr(void); 193 | void SGX_Vdp1DrawPolygon(void); 194 | void SGX_Vdp1DrawPolyline(void); 195 | void SGX_Vdp1DrawLine(void); 196 | void SGX_Vdp1UserClip(void); 197 | void SGX_Vdp1SysClip(void); 198 | void SGX_Vdp1LocalCoord(void); 199 | 200 | void SGX_Vdp2Init(void); 201 | void SGX_Vdp2Draw(void); 202 | void SGX_Vdp2Postprocess(void); 203 | 204 | /* 205 | * Here we have a serious attempt at replacing all GX functions that use shadow regs 206 | */ 207 | void SGX_Begin(u8 primitive, u8 vtxfmt, u16 vtxcnt); 208 | void SGX_End(); 209 | 210 | //==================== 211 | // TEV STAGES 212 | //==================== 213 | void SGX_SetTevGens(u8 num_tevs, u8 num_texgens, u8 num_chans); 214 | void SGX_SetTevGensExt(u8 num_tevs, u8 num_texgens, u8 num_chans, u8 num_indtevs); 215 | void SGX_SetNumIndStages(u8 num_indtevs); 216 | void SGX_SetCullMode(u8 mode); 217 | 218 | 219 | 220 | //==================== 221 | // MATRIX 222 | //==================== 223 | void SGX_SetCurrentMtxLo(u32 posn, u32 t0, u32 t1, u32 t2, u32 t3); 224 | void SGX_SetCurrentMtxHi(u32 t4, u32 t5, u32 t6, u32 t7); 225 | 226 | //TODO: More functions are needed to replace GX 227 | // -SetVtxAttrFmt 228 | // -SetTexCoordScale (use manual) 229 | // -Update BP mask if using GC (indtev) 230 | // -SetPxlFmt must change ms_en in gen_rode reg 231 | // Set Vertex description (also XF is modified) 232 | // If chan color changes update corresponding XF regs (SetChanCntrl/SetChanColor) 233 | // If tex coordgen updates the update the mask (SetTexCoordGen) 234 | 235 | 236 | #endif //__VID_GX_H__ 237 | -------------------------------------------------------------------------------- /src/sgx/svi.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "svi.h" 4 | #include "sgx.h" 5 | 6 | #define COLOR_BLACK (0x10801080) 7 | 8 | #define DEFAULT_FIFO_SIZE (256*1024) 9 | 10 | enum TVModeType { 11 | TVMODE_A_ST = 0, //320 12 | TVMODE_B_ST = 1, //352 13 | TVMODE_A_HI = 2, //640 14 | TVMODE_B_HI = 3 //704 15 | }; 16 | 17 | extern void __VIClearFramebuffer(void* fb, u32 bytes, u32 color); 18 | extern u32 vdp2_disp_w; 19 | extern u32 vdp2_disp_h; 20 | extern u32 vdp1_fb_w; 21 | extern u32 vdp1_fb_h; 22 | extern u32 vdp1_fb_mtx; 23 | 24 | u32 vert_offset = 0; 25 | u32 scale_mtx = MTX_TEX_SCALED_N; 26 | u16 *xfb[2] = { NULL, NULL }; 27 | u32 fbsel = 0; 28 | GXRModeObj *rmode; 29 | u32 tvmode; 30 | void *gp_fifo; 31 | u8 *fb_scale_tex ATTRIBUTE_ALIGN(32); /*Texture for scaling x axis fb*/ 32 | 33 | 34 | void SVI_Init(void) 35 | { 36 | VIDEO_Init(); 37 | rmode = VIDEO_GetPreferredMode(NULL); 38 | 39 | Mtx GXmodelView2D; 40 | Mtx44 perspective; 41 | u16 w = VIDEO_PadFramebufferWidth(704); 42 | u16 h = 512; 43 | u32 xfb_size = w * h * VI_DISPLAY_PIX_SZ; 44 | //Allocate framebuffers 45 | xfb[0] = MEM_K0_TO_K1(memalign(32, xfb_size)); 46 | xfb[1] = MEM_K0_TO_K1(memalign(32, xfb_size)); 47 | fb_scale_tex = (u8*) memalign(32, 704*512*2); 48 | 49 | __VIClearFramebuffer(xfb[0], xfb_size, COLOR_BLACK); 50 | __VIClearFramebuffer(xfb[1], xfb_size, COLOR_BLACK); 51 | 52 | rmode->viWidth = rmode->fbWidth = 704; 53 | rmode->viXOrigin = (VI_MAX_WIDTH_NTSC - 704)/2; 54 | VIDEO_SetBlack(1); 55 | VIDEO_Configure(rmode); 56 | VIDEO_Flush(); 57 | VIDEO_WaitVSync(); 58 | 59 | // Initialize GX 60 | gp_fifo = memalign(32, DEFAULT_FIFO_SIZE); 61 | GX_Init(gp_fifo, DEFAULT_FIFO_SIZE); 62 | 63 | GX_SetCopyClear((GXColor){0, 0, 0, 0}, 0); 64 | GX_SetDispCopyGamma(GX_GM_1_0); 65 | 66 | GX_SetCopyFilter(GX_FALSE, rmode->sample_pattern, GX_FALSE, rmode->vfilter); 67 | GX_SetFieldMode(GX_DISABLE, ((rmode->viHeight == 2*rmode->xfbHeight)? GX_ENABLE : GX_DISABLE)); 68 | GX_SetDither(GX_DISABLE); 69 | GX_SetCopyClamp(GX_CLAMP_NONE); 70 | 71 | GX_InvVtxCache(); 72 | GX_InvalidateTexAll(); 73 | GX_ClearVtxDesc(); 74 | 75 | GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0); 76 | GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); 77 | GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); 78 | 79 | GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XY, GX_S16, 0); 80 | GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_U16, 0); 81 | GX_SetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); 82 | 83 | //VDP1 vertex format for 16bpp 84 | GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_POS, GX_POS_XY, GX_S16, 0); 85 | GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); 86 | GX_SetVtxAttrFmt(GX_VTXFMT2, GX_VA_CLR0, GX_CLR_RGB, GX_RGB565, 0); 87 | //VDP1 vertex format for 8bpp 88 | GX_SetVtxAttrFmt(GX_VTXFMT3, GX_VA_POS, GX_POS_XY, GX_S16, 1); 89 | GX_SetVtxAttrFmt(GX_VTXFMT3, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); 90 | GX_SetVtxAttrFmt(GX_VTXFMT3, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA6, 0); 91 | 92 | GX_SetVtxAttrFmt(GX_VTXFMT6, GX_VA_POS, GX_POS_XYZ, GX_F32, 1); 93 | 94 | //VDP2 vertex format 95 | GX_SetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XY, GX_U8, 0); 96 | GX_SetVtxAttrFmt(GX_VTXFMT5, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); 97 | 98 | //GUI vertex format 99 | GX_SetVtxAttrFmt(GX_VTXFMT4, GX_VA_POS, GX_POS_XY, GX_S16, 0); 100 | GX_SetVtxAttrFmt(GX_VTXFMT4, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); 101 | GX_SetVtxAttrFmt(GX_VTXFMT4, GX_VA_CLR0, GX_CLR_RGB, GX_RGB565, 0); 102 | 103 | GX_SetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); 104 | GX_SetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_BLUE, GX_CH_GREEN, GX_CH_RED, GX_CH_ALPHA); 105 | GX_SetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_ALPHA, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE); 106 | GX_SetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); 107 | 108 | GX_SetZCompLoc(GX_FALSE); 109 | GX_SetZMode(GX_ENABLE, GX_ALWAYS, GX_TRUE); 110 | 111 | GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHTNULL, GX_DF_NONE, GX_AF_NONE); 112 | GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, MTX_IDENTITY); 113 | GX_SetCurrentMtx(MTX_IDENTITY); 114 | 115 | guOrtho(perspective, 0, 480.0, 0, 640.0, 0, 1.0); 116 | GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC); 117 | 118 | GX_SetViewport(0, 0, 640, 480, 0.0f, 1.0f); 119 | GX_SetAlphaCompare(GX_GREATER, 0, GX_AOP_AND, GX_ALWAYS, 0); 120 | 121 | //Reset various parameters 122 | GX_SetCoPlanar(GX_DISABLE); 123 | GX_SetClipMode(GX_CLIP_ENABLE); 124 | GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); 125 | GX_SetColorUpdate(GX_ENABLE); 126 | GX_SetAlphaUpdate(GX_DISABLE); 127 | GX_SetCullMode(GX_CULL_NONE); 128 | GX_SetDispCopyGamma(GX_GM_1_0); 129 | GX_SetCopyClamp(GX_CLAMP_NONE); 130 | 131 | SGX_Init(); 132 | 133 | SVI_SetResolution(0x80D2); 134 | VIDEO_SetNextFramebuffer(xfb[0]); 135 | VIDEO_SetBlack(0); 136 | VIDEO_Flush(); 137 | VIDEO_WaitVSync(); 138 | } 139 | 140 | u32 prev_tvmd = 0; 141 | 142 | void SVI_SetResolution(u32 tvmd) 143 | { 144 | if (prev_tvmd == tvmd) { 145 | return; 146 | } 147 | prev_tvmd = tvmd; 148 | // Set vertical and horizontal Resolution 149 | u32 width = SS_DISP_WIDTH + ((tvmd & 1) << 5); 150 | u32 height = SS_DISP_HEIGHT + (((tvmd & 0x30) > 0) << 5); 151 | u32 vdp2_x_hires = ((tvmd >> 1) & 1); 152 | u32 vdp2_interlace = ((tvmd & 0xC0) == 0xC0); 153 | vdp2_disp_w = width << vdp2_x_hires; 154 | vdp2_disp_h = height << vdp2_interlace; 155 | vdp1_fb_w = width; 156 | vdp1_fb_h = height; 157 | scale_mtx = MTX_TEX_SCALED_N + ((1-vdp2_x_hires) << 1); 158 | vert_offset = ((((tvmd & 0x30) == 0) << 3)); 159 | tvmode = (tvmd & 3); 160 | 161 | //TODO: DONT CHANGE THIS, ONLY CLEAR TO BLACK 162 | u32 xfb_size = 704 * 512 * VI_DISPLAY_PIX_SZ; 163 | __VIClearFramebuffer(xfb[0], xfb_size, COLOR_BLACK); 164 | __VIClearFramebuffer(xfb[1], xfb_size, COLOR_BLACK); 165 | 166 | GX_SetDispCopyYScale((f32)(2 - vdp2_interlace)); //scale the XFB copy if not interlaced 167 | GX_Flush(); 168 | } 169 | 170 | void SVI_CopyXFB(u32 x, u32 y) 171 | { 172 | GX_SetDispCopyYScale(1.0); //scale the XFB copy if not interlaced 173 | GX_CopyDisp(xfb[fbsel] + (y * 704) + x, GX_TRUE); 174 | GX_DrawDone(); 175 | GX_SetDispCopyYScale((f32)(2 - (vdp2_disp_h > 352))); //scale the XFB copy if not interlaced 176 | } 177 | 178 | 179 | void SVI_CopyFrame(void) 180 | { 181 | GX_SetCopyClear((GXColor) {0x00, 0x00, 0x00, 0x00}, 0); 182 | GX_SetScissor(0, 0, 640, 480); 183 | GX_ClearVtxDesc(); 184 | GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); 185 | //Set up general TEV 186 | GX_SetNumTevStages(1); 187 | GX_SetNumTexGens(1); 188 | GX_SetNumChans(0); 189 | GX_SetNumIndStages(0); 190 | GX_SetTevDirect(GX_TEVSTAGE0); 191 | //TEXMAP6 is for VDP2 scaling 192 | SGX_SetOtherTex(GX_TEXMAP6, fb_scale_tex, GX_TF_RGB565, vdp2_disp_w, vdp2_disp_h, 0); 193 | GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_POS, scale_mtx); 194 | GX_SetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 1, 1); 195 | GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP6, GX_COLORNULL); 196 | 197 | GX_SetZMode(GX_DISABLE, GX_GREATER, GX_TRUE); 198 | GX_SetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); 199 | 200 | GX_SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); 201 | GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); 202 | GX_SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ADDHALF, GX_CS_SCALE_2, GX_TRUE, GX_TEVPREV); 203 | GX_SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); 204 | GX_SetCurrentMtx(MTX_IDENTITY); 205 | GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); 206 | 207 | switch (tvmode) { 208 | case TVMODE_A_ST: { 209 | GX_SetTexCopySrc(0, 0, vdp2_disp_w, vdp2_disp_h); 210 | GX_SetTexCopyDst(vdp2_disp_w, vdp2_disp_h, GX_TF_RGB565, GX_FALSE); 211 | GX_CopyTex(fb_scale_tex, GX_TRUE); 212 | GX_PixModeSync(); //Not necesary? 213 | 214 | u32 w = 640; 215 | u32 h = vdp2_disp_h; 216 | 217 | GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT4, 4); 218 | GX_Position2s16(0, 0); 219 | GX_Position2s16(w, 0); 220 | GX_Position2s16(0, h); 221 | GX_Position2s16(w, h); 222 | GX_End(); 223 | 224 | GX_SetDispCopySrc(0, 0, w, h); 225 | GX_SetDispCopyDst(704, h); 226 | GX_CopyDisp(xfb[fbsel] + (vert_offset * 704) + 32, GX_TRUE); 227 | } break; 228 | case TVMODE_B_ST: { 229 | GX_SetTexCopySrc(0, 0, vdp2_disp_w, vdp2_disp_h); 230 | GX_SetTexCopyDst(vdp2_disp_w, vdp2_disp_h, GX_TF_RGB565, GX_FALSE); 231 | GX_CopyTex(fb_scale_tex, GX_TRUE); 232 | GX_PixModeSync(); //Not necesary? 233 | 234 | u32 w = 640; 235 | u32 h = vdp2_disp_h; 236 | 237 | GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT4, 4); 238 | GX_Position2s16(0, 0); 239 | GX_Position2s16(w, 0); 240 | GX_Position2s16(0, h); 241 | GX_Position2s16(w, h); 242 | GX_End(); 243 | 244 | GX_SetDispCopySrc(0, 0, w, h); 245 | GX_SetDispCopyDst(704, h); 246 | GX_CopyDisp(xfb[fbsel] + (vert_offset * 704), GX_TRUE); 247 | 248 | GX_SetCurrentMtx(MTX_MOVED_640); 249 | GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT4, 4); 250 | GX_Position2s16(w, 0); 251 | GX_Position2s16(w+64, 0); 252 | GX_Position2s16(w, h); 253 | GX_Position2s16(w+64, h); 254 | GX_End(); 255 | GX_SetDispCopySrc(0, 0, 64, h); 256 | GX_CopyDisp(xfb[fbsel] + (vert_offset * 704) + w, GX_TRUE); 257 | } break; 258 | case TVMODE_A_HI: { 259 | GX_SetDispCopySrc(0, 0, 640, vdp2_disp_h); 260 | GX_SetDispCopyDst(704, vdp2_disp_h); 261 | GX_CopyDisp(xfb[fbsel] + (vert_offset * 704) + 32, GX_TRUE); 262 | } break; 263 | case TVMODE_B_HI: { 264 | GX_SetDispCopySrc(0, 0, 640, vdp2_disp_h); 265 | GX_SetDispCopyDst(704, vdp2_disp_h); 266 | GX_CopyDisp(xfb[fbsel] + (vert_offset * 704), GX_TRUE); 267 | } break; 268 | } 269 | GX_DrawDone(); 270 | } 271 | 272 | 273 | void SVI_ClearFrame(void) 274 | { 275 | //Copy black 276 | GX_SetCopyClear((GXColor){0, 0, 0, 0}, 0); 277 | GX_SetDispCopySrc(0, 0, 640, vdp2_disp_h); 278 | GX_SetDispCopyDst(704, vdp2_disp_h); 279 | GX_CopyDisp(xfb[fbsel], GX_TRUE); 280 | GX_SetDispCopySrc(0, 0, 64, vdp2_disp_h); 281 | GX_CopyDisp(xfb[fbsel]+640, GX_TRUE); 282 | GX_DrawDone(); 283 | 284 | } 285 | 286 | void SVI_SwapBuffers(u32 wait_vsync) 287 | { 288 | VIDEO_SetNextFramebuffer(xfb[fbsel]); 289 | VIDEO_Flush(); 290 | if (wait_vsync) { 291 | VIDEO_WaitVSync(); 292 | } 293 | fbsel ^= 1; 294 | } 295 | -------------------------------------------------------------------------------- /src/sgx/svi.h: -------------------------------------------------------------------------------- 1 | #ifndef __SVI_H__ 2 | #define __SVI_H__ 3 | 4 | #include 5 | 6 | #define SS_DISP_WIDTH 320 7 | #define SS_DISP_HEIGHT 224 8 | 9 | void SVI_Init(void); 10 | void SVI_CopyXFB(u32 x, u32 y); 11 | void SVI_SwapBuffers(u32 wait_vsync); 12 | void SVI_SetResolution(u32 tvmd); 13 | void SVI_CopyFrame(void); 14 | void SVI_ClearFrame(void); 15 | 16 | #endif //__SVI_H__ 17 | -------------------------------------------------------------------------------- /src/sh2/drc/compiler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fadedled/seta-gx/c23d7cdc1800bc7af5022d2d9139b997397c5895/src/sh2/drc/compiler.h -------------------------------------------------------------------------------- /src/sh2/drc/emit_ppc.inc: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 4 | * 5 | * 6 | */ 7 | 8 | /* 9 | * emit 32-bit PPC from SH2 instructions 10 | * 11 | * SH2 has 142 instructions 12 | * 13 | * Since the PPC has more regs than the SH2 we 14 | * can store them in all the GPRs as so: 15 | * 16 | * SH2 reg PPC reg 17 | * ========================= 18 | * PC | GPR6 19 | * SR | GPR7 20 | * GBR | GPR8 21 | * VBR | GPR9 22 | * PR | GPR10 23 | * MACH | GPR11 24 | * MACL | GPR12 25 | * R0 to R15 | GPR16 to GPR31 26 | * 27 | * Also, CR2-CR4 must be preserved during function calls 28 | * and CR0 is not 29 | * XER register is also important 30 | * T can be checked as needed, for all opcodes the T bit 31 | * will be what it is used for afterward 32 | */ 33 | 34 | #define GP_R0 (16) 35 | #define GP_R(x) (x + GP_R0) 36 | 37 | #define GP_TMP (5) //temp variable for mutli-instruction 38 | #define GP_PC (7) 39 | #define GP_PR (8) 40 | #define GP_GBR (9) 41 | #define GP_VBR (10) 42 | #define GP_SR (13) 43 | #define GP_MACH (14) 44 | #define GP_MACL (15) 45 | 46 | 47 | #define EMIT(x) \ 48 | do { \ 49 | *icache_ptr = (x); \ 50 | icache_ptr++; \ 51 | } while (0) 52 | 53 | /*Power PC opcodes*/ 54 | #define PPCC_ADD(rD, rA, rB) EMIT(0x7C000214 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 55 | #define PPCC_ADDO(rD, rA, rB) EMIT(0x7C000614 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 56 | #define PPCC_ADDI(rD, rA, imm) EMIT(0x38000000 | ((rD) << 21) | ((rA) << 16) | (imm & 0xFFFF)) 57 | #define PPCC_ADDEO(rD, rA, rB) EMIT(0x7C000514 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 58 | #define PPCC_SUBF(rD, rA, rB) EMIT(0x7C000050 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 59 | #define PPCC_MULLW(rD, rA, rB) EMIT(0x7C0001D6 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 60 | #define PPCC_MULHW(rD, rA, rB) EMIT(0x7C000096 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 61 | #define PPCC_MULHWU(rD, rA, rB) EMIT(0x7C000016 | ((rD) << 21) | ((rA) << 16) | ((rB) << 11)) 62 | #define PPCC_AND(rD, rA, rB) EMIT(0x7C000038 | ((rA) << 21) | ((rD) << 16) | ((rB) << 11)) 63 | #define PPCC_ANDp(rD, rA, rB) EMIT(0x7C000039 | ((rA) << 21) | ((rD) << 16) | ((rB) << 11)) 64 | #define PPCC_ANDI(rD, rA, imm) EMIT(0x70000000 | ((rA) << 21) | ((rD) << 16) | (imm & 0xFFFF)) 65 | #define PPCC_OR(rD, rA, rB) EMIT(0x7C000378 | ((rA) << 21) | ((rD) << 16) | ((rB) << 11)) 66 | #define PPCC_ORI(rD, rA, imm) EMIT(0x60000000 | ((rA) << 21) | ((rD) << 16) | (imm & 0xFFFF)) 67 | #define PPCC_XOR(rD, rA, rB) EMIT(0x7C000278 | ((rA) << 21) | ((rD) << 16) | ((rB) << 11)) 68 | #define PPCC_XORI(rD, rA, imm) EMIT(0x68000000 | ((rA) << 21) | ((rD) << 16) | (imm & 0xFFFF)) 69 | #define PPCC_NOR(rD, rA, rB) EMIT(0x7C0000F8 | ((rA) << 21) | ((rD) << 16) | ((rB) << 11)) 70 | #define PPCC_NEG(rD, rA) EMIT(0x7C0000D0 | ((rD) << 21) | ((rA) << 16)) 71 | #define PPCC_EXTSB(rD, rA) EMIT(0x7C000774 | ((rA) << 21) | ((rD) << 16)) 72 | #define PPCC_EXTSH(rD, rA) EMIT(0x7C000734 | ((rA) << 21) | ((rD) << 16)) 73 | #define PPCC_RLWINM(rD, rA, shf, mb, me) EMIT(0x54000000 | ((rA) << 21) | ((rD) << 16) | ((shf) << 11) | ((mb) << 6) | ((me) << 1)) 74 | #define PPCC_RLWIMI(rD, rA, shf, mb, me) EMIT(0x50000000 | ((rA) << 21) | ((rD) << 16) | ((shf) << 11) | ((mb) << 6) | ((me) << 1)) 75 | #define PPCC_SRAWI(rD, rA, shf) EMIT(0x7C000670 | ((rA) << 21) | ((rD) << 16) | ((shf) << 11)) 76 | #define PPCC_CMP(cD, rA, rB) EMIT(0x7C000000 | ((cD) << 23) | ((rA) << 16) | ((rB) << 11)) 77 | #define PPCC_CMPL(cD, rA, rB) EMIT(0x7C000040 | ((cD) << 23) | ((rA) << 16) | ((rB) << 11)) 78 | #define PPCC_CMPI(cD, rA, imm) EMIT(0x2C000000 | ((cD) << 23) | ((rA) << 16) | (imm & 0xFFFF)) 79 | 80 | #define PPCC_MTXER(rS) EMIT(0x7C0003A6 | ((rS) << 21) | ((0x20) << 11)) 81 | #define PPCC_MFXER(rD) EMIT(0x7C0002A6 | ((rD) << 21) | ((0x20) << 11)) 82 | #define PPCC_MFCR(rD) EMIT(0x7C000026 | ((rD) << 21)) 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /src/sh2/sh2.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | typedef struct SH2_tag 7 | { 8 | u32 regs[16]; 9 | u32 pc; 10 | u32 pr; 11 | u32 gbr; 12 | u32 vbr; 13 | u32 sr; 14 | u32 mach; 15 | u32 macl; 16 | 17 | u32 delay_slot; 18 | u32 cycles; 19 | u32 flags; 20 | 21 | //XXX: Interrupt stuff 22 | //Interrupt iqr_arr[MAX_INTERRUPTS]; 23 | 24 | u32 address_arr[0x100]; /*Address Array*/ 25 | u8 on_chip[0x200]; /*On-chip peripheral modules*/ 26 | u8 cache[0x1000]; /*Data Cache Array*/ 27 | } SH2; 28 | 29 | SH2 msh2; 30 | SH2 ssh2; 31 | 32 | #define write8(ptr, x) (*((u8*)(ptr)) = (x)) 33 | #define write16(ptr, x) (*((u16*)(ptr)) = (x)) 34 | #define write32(ptr, x) (*((u32*)(ptr)) = (x)) 35 | 36 | 37 | void sh2_Init(SH2 *sh, u32 is_slave_flag) 38 | { 39 | //Initialize the main sh2 40 | msh2.flags |= is_slave_flag; 41 | sh2_PowerOn(sh); 42 | } 43 | 44 | 45 | void sh2_PowerOn(SH2 *sh) 46 | { 47 | sh->pc = mem_Read32(0x0); //Get from vector address table 48 | sh->regs[15] = mem_Read32(0x4); //Get from vector address table 49 | sh->vbr = 0x0; 50 | sh->sr |= 0xF0; 51 | } 52 | 53 | 54 | void sh2_Reset(SH2 *sh) 55 | { 56 | sh->pc = mem_Read32(0x8); //Get from vector address table 57 | sh->regs[15] = mem_Read32(0xC); //Get from vector address table 58 | sh->vbr = 0x0; 59 | sh->sr |= 0xF0; 60 | } 61 | 62 | 63 | void sh2_HandleInterrupts(SH2 *sh) 64 | { 65 | 66 | } 67 | 68 | 69 | void sh2_HandleBreakpoints(SH2 *sh) 70 | { 71 | 72 | } 73 | 74 | 75 | void sh2_OnchipReset(SH2 *sh) 76 | { 77 | u8 *oc = sh->on_chip; 78 | write8(oc + OC_SMR, 0x00); 79 | write8(oc + OC_BRR, 0xFF); 80 | write8(oc + OC_SCR, 0x00); 81 | write8(oc + OC_TDR, 0xFF); 82 | write8(oc + OC_SSR, 0x84); 83 | write8(oc + OC_RDR, 0x00); 84 | write8(oc + OC_TIER, 0x01); 85 | write8(oc + OC_FTCSR, 0x00); 86 | write16(oc + OC_FRC, 0x0000); 87 | write16(oc + OC_OCRA, 0xFFFF); 88 | write16(oc + OC_OCRB + 0x10, 0xFFFF); //Add 0x10 89 | write8(oc + OC_TRC, 0x00); 90 | write8(oc + OC_TOCR, 0xE0); 91 | write16(oc + OC_ICR, 0x0000); 92 | write16(oc + OC_IPRB, 0x0000); 93 | write16(oc + OC_VCRA, 0x0000); 94 | write16(oc + OC_VCRB, 0x0000); 95 | write16(oc + OC_VCRC, 0x0000); 96 | write16(oc + OC_VCRD, 0x0000); 97 | write8(oc + OC_DRCR0, 0x00); 98 | write8(oc + OC_DRCR1, 0x00); 99 | write16(oc + OC_WTCSR, 0x0018); 100 | write16(oc + OC_WTCNT, 0x0000); 101 | write16(oc + OC_RSTCSR, 0x001F); 102 | write8(oc + OC_SBYCR, 0x60); 103 | write16(oc + OC_ICR, 0x0000); 104 | write16(oc + OC_IPRA, 0x0000); 105 | write16(oc + OC_VCRWDT, 0x0000); 106 | write32(oc + OC_DVCR, 0x0000); 107 | write16(oc + OC_BARAH, 0x0000); 108 | write16(oc + OC_BARAL, 0x0000); 109 | write16(oc + OC_BAMRAH, 0x0000); 110 | write16(oc + OC_BAMRAL, 0x0000); 111 | write16(oc + OC_BBRA, 0x0000); 112 | write16(oc + OC_BARBH, 0x0000); 113 | write16(oc + OC_BARBL, 0x0000); 114 | write16(oc + OC_BAMRBH, 0x0000); 115 | write16(oc + OC_BAMRBL, 0x0000); 116 | write16(oc + OC_BBRB, 0x0000); 117 | write16(oc + OC_BDRBH, 0x0000); 118 | write16(oc + OC_BDRBL, 0x0000); 119 | write16(oc + OC_BDMRBH, 0x0000); 120 | write16(oc + OC_BDMRBL, 0x0000); 121 | write16(oc + OC_BRCR, 0x0000); 122 | write32(oc + OC_CHCR0, 0x0000); 123 | write32(oc + OC_CHCR1, 0x0000); 124 | write32(oc + OC_DMAOR, 0x0000); 125 | write32(oc + OC_BCR1, 0x03F0); 126 | write32(oc + OC_BCR2, 0x00FC); 127 | write32(oc + OC_WCR, 0xAAFF); 128 | write32(oc + OC_MCR, 0x0000); 129 | write32(oc + OC_RTCSR, 0x0000); 130 | write32(oc + OC_RTCNT, 0x0000); 131 | write32(oc + OC_RTCOR, 0x0000); 132 | } 133 | 134 | 135 | void sh2_Exec(SH2 *sh, u32 cycles) 136 | { 137 | sh2_HandleInterrupts(sh); 138 | sh2_HandleBreakpoints(sh); 139 | u32* iblock; 140 | while(sh->cycles < cycles) { 141 | iblock = jit_LookupITable[sh->pc]; 142 | if (!iblock) { 143 | iblock = jit_Recompile(); 144 | jit_LookupITable[sh->pc] = iblock; 145 | } 146 | //XXX: Load the used values 147 | __asm call iblock; 148 | //XXX: Load the previous values´ 149 | } 150 | } 151 | 152 | 153 | -------------------------------------------------------------------------------- /src/sh2/sh2.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | //=================================== 5 | // SH2 Flags 6 | //=================================== 7 | #define SH2_FLAG_SLAVE 0x01 8 | #define SH2_FLAG_IDLE 0x02 9 | #define SH2_FLAG_SLEEPING 0x04 10 | 11 | //=================================== 12 | // On-Chip peripheral modules (Addresses 0xFFFFFE00 - 0xFFFFFFFF) 13 | //=================================== 14 | #define OC_SMR 0x000 15 | #define OC_BRR 0x001 16 | #define OC_SCR 0x002 17 | #define OC_TDR 0x003 18 | #define OC_SSR 0x004 19 | #define OC_RDR 0x005 20 | #define OC_TIER 0x010 21 | #define OC_FTCSR 0x011 22 | #define OC_FRC 0x012 23 | #define OC_OCRA 0x014 24 | #define OC_OCRB 0x014 //WTF.. Add 0x10 25 | #define OC_TRC 0x016 26 | #define OC_TOCR 0x017 27 | #define OC_FICR 0x018 28 | #define OC_IPRB 0x060 29 | #define OC_VCRA 0x062 30 | #define OC_VCRB 0x064 31 | #define OC_VCRC 0x066 32 | #define OC_VCRD 0x068 33 | #define OC_DRCR0 0x071 34 | #define OC_DRCR1 0x072 35 | #define OC_WTCSR 0x080 36 | #define OC_WTCNT 0x081 37 | #define OC_RSTCSR 0x082 38 | #define OC_SBYCR 0x091 39 | #define OC_ICR 0x0E0 40 | #define OC_IPRA 0x0E2 41 | #define OC_VCRWDT 0x0E4 42 | #define OC_DVSR 0x100 43 | #define OC_DVDNT 0x104 44 | #define OC_DVCR 0x108 45 | #define OC_VCRDIV 0x10C 46 | #define OC_DVDNTH 0x110 47 | #define OC_DVDNTL 0x114 48 | #define OC_BARAH 0x140 49 | #define OC_BARAL 0x142 50 | #define OC_BAMRAH 0x144 51 | #define OC_BAMRAL 0x146 52 | #define OC_BBRA 0x148 53 | #define OC_BARBH 0x160 54 | #define OC_BARBL 0x162 55 | #define OC_BAMRBH 0x164 56 | #define OC_BAMRBL 0x166 57 | #define OC_BBRB 0x168 58 | #define OC_BDRBH 0x170 59 | #define OC_BDRBL 0x172 60 | #define OC_BDMRBH 0x174 61 | #define OC_BDMRBL 0x176 62 | #define OC_BRCR 0x178 63 | #define OC_SAR0 0x180 64 | #define OC_DAR0 0x184 65 | #define OC_TCR0 0x188 66 | #define OC_CHCR0 0x18C 67 | #define OC_SAR1 0x190 68 | #define OC_DAR1 0x194 69 | #define OC_TCR1 0x198 70 | #define OC_CHCR1 0x19C 71 | #define OC_VCRDMA0 0x1A0 72 | #define OC_VCRDMA1 0x1A8 73 | #define OC_DMAOR 0x1B0 74 | #define OC_BCR1 0x1E0 75 | #define OC_BCR2 0x1E4 76 | #define OC_WCR 0x1E8 77 | #define OC_MCR 0x1EC 78 | #define OC_RTCSR 0x1F0 79 | #define OC_RTCNT 0x1F4 80 | #define OC_RTCOR 0x1F8 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/sh2/sh2_int.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | typedef struct SH2_tag 7 | { 8 | u32 regs[16]; 9 | u32 pc; 10 | u32 pr; 11 | u32 gbr; 12 | u32 vbr; 13 | u32 sr; 14 | u32 mach; 15 | u32 macl; 16 | 17 | 18 | 19 | u32 is_slave; 20 | } SH2; 21 | 22 | SH2 msh2; 23 | SH2 ssh2; 24 | 25 | 26 | void sh2_Init(void) 27 | { 28 | //Initialize the main sh2 29 | msh2.is_slave = 0; 30 | 31 | 32 | //Initialize the main sh2 33 | msh2.is_slave = 1; 34 | } 35 | 36 | void sh2_Reset(SH2 *sh) 37 | { 38 | 39 | 40 | } 41 | 42 | void sh2_HandleInterrupts(SH2 *sh) 43 | { 44 | 45 | } 46 | 47 | void sh2_HandleBreakpoints(SH2 *sh) 48 | { 49 | 50 | } 51 | 52 | void sh2_Exec(SH2 *sh, u32 cycles) 53 | { 54 | sh2_HandleInterrupts(sh); 55 | sh2_HandleBreakpoints(sh); 56 | u32* iblock; 57 | while(sh->cycles < cycles) { 58 | iblock = jit_LookupITable[sh->pc]; 59 | if (!iblock) { 60 | iblock = jit_Recompile(); 61 | jit_LookupITable[sh->pc] = iblock; 62 | } 63 | //XXX: Load the used values 64 | __asm call iblock; 65 | //XXX: Load the previous values´ 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/sh2/sh2_int.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fadedled/seta-gx/c23d7cdc1800bc7af5022d2d9139b997397c5895/src/sh2/sh2_int.h -------------------------------------------------------------------------------- /src/sh2core.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2004-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SH2CORE_H 22 | #define SH2CORE_H 23 | 24 | #include "core.h" 25 | #include "memory.h" 26 | 27 | #define SH2CORE_DEFAULT -1 28 | #define MAX_INTERRUPTS 50 29 | 30 | #ifdef MACH 31 | #undef MACH 32 | #endif 33 | 34 | // UBC Flags 35 | #define BBR_CPA_NONE (0 << 6) 36 | #define BBR_CPA_CPU (1 << 6) 37 | #define BBR_CPA_PER (2 << 6) 38 | 39 | #define BBR_IDA_NONE (0 << 4) 40 | #define BBR_IDA_INST (1 << 4) 41 | #define BBR_IDA_DATA (2 << 4) 42 | 43 | #define BBR_RWA_NONE (0 << 2) 44 | #define BBR_RWA_READ (1 << 2) 45 | #define BBR_RWA_WRITE (2 << 2) 46 | 47 | #define BBR_SZA_NONE (0 << 0) 48 | #define BBR_SZA_BYTE (1 << 0) 49 | #define BBR_SZA_WORD (2 << 0) 50 | #define BBR_SZA_LONGWORD (3 << 0) 51 | 52 | #define BRCR_CMFCA (1 << 15) 53 | #define BRCR_CMFPA (1 << 14) 54 | #define BRCR_EBBA (1 << 13) 55 | #define BRCR_UMD (1 << 12) 56 | #define BRCR_PCBA (1 << 10) 57 | 58 | #define BRCR_CMFCB (1 << 7) 59 | #define BRCR_CMFPB (1 << 6) 60 | #define BRCR_SEQ (1 << 4) 61 | #define BRCR_DBEB (1 << 3) 62 | #define BRCR_PCBB (1 << 2) 63 | 64 | typedef struct 65 | { 66 | u32 R[16]; 67 | 68 | union { 69 | struct { 70 | u32 reserved1:22; 71 | u32 M:1; 72 | u32 Q:1; 73 | u32 I:4; 74 | u32 reserved0:2; 75 | u32 S:1; 76 | u32 T:1; 77 | } part; 78 | u32 all; 79 | } SR; 80 | 81 | u32 GBR; 82 | u32 VBR; 83 | u32 MACH; 84 | u32 MACL; 85 | u32 PR; 86 | u32 PC; 87 | } sh2regs_struct; 88 | 89 | typedef struct 90 | { 91 | u8 SMR; // 0xFFFFFE00 92 | u8 BRR; // 0xFFFFFE01 93 | u8 SCR; // 0xFFFFFE02 94 | u8 TDR; // 0xFFFFFE03 95 | u8 SSR; // 0xFFFFFE04 96 | u8 RDR; // 0xFFFFFE05 97 | u8 TIER; // 0xFFFFFE10 98 | u8 FTCSR; // 0xFFFFFE11 99 | 100 | union { 101 | struct { 102 | u16 H:8; // 0xFFFFFE12 103 | u16 L:8; // 0xFFFFFE13 104 | } part; 105 | u16 all; 106 | } FRC; 107 | 108 | u16 OCRA; // 0xFFFFFE14/0xFFFFFE15 109 | u16 OCRB; // 0xFFFFFE14/0xFFFFFE15 110 | u8 TCR; // 0xFFFFFE16 111 | u8 TOCR; // 0xFFFFFE17 112 | u16 FICR; // 0xFFFFFE18 113 | // 0xFFFFFE19 114 | u16 IPRB; // 0xFFFFFE60 115 | u16 VCRA; // 0xFFFFFE62 116 | u16 VCRB; // 0xFFFFFE64 117 | u16 VCRC; // 0xFFFFFE66 118 | u16 VCRD; // 0xFFFFFE68 119 | u8 DRCR0; // 0xFFFFFE71 120 | u8 DRCR1; // 0xFFFFFE72 121 | u8 WTCSR; // 0xFFFFFE80 122 | u8 WTCNT; // 0xFFFFFE81 123 | u8 RSTCSR; // 0xFFFFFE83 124 | u8 SBYCR; // 0xFFFFFE91 125 | u8 CCR; // 0xFFFFFE92 126 | u16 ICR; // 0xFFFFFEE0 127 | u16 IPRA; // 0xFFFFFEE2 128 | u16 VCRWDT; // 0xFFFFFEE4 129 | u32 DVSR; // 0xFFFFFF00 130 | u32 DVDNT; // 0xFFFFFF04 131 | u32 DVCR; // 0xFFFFFF08 132 | u32 VCRDIV; // 0xFFFFFF0C 133 | u32 DVDNTH; // 0xFFFFFF10 134 | u32 DVDNTL; // 0xFFFFFF14 135 | u32 DVDNTUH; // 0xFFFFFF18 136 | u32 DVDNTUL; // 0xFFFFFF1C 137 | 138 | union { 139 | struct { 140 | u32 H:16; // 0xFFFFFF40 141 | u32 L:16; // 0xFFFFFF42 142 | } part; 143 | u16 all; 144 | } BARA; 145 | 146 | union { 147 | struct { 148 | u32 H:16; // 0xFFFFFF44 149 | u32 L:16; // 0xFFFFFF46 150 | } part; 151 | u16 all; 152 | } BAMRA; 153 | 154 | u32 BBRA; // 0xFFFFFF48 155 | 156 | union { 157 | struct { 158 | u32 H:16; // 0xFFFFFF60 159 | u32 L:16; // 0xFFFFFF62 160 | } part; 161 | u16 all; 162 | } BARB; 163 | 164 | union { 165 | struct { 166 | u32 H:16; // 0xFFFFFF64 167 | u32 L:16; // 0xFFFFFF66 168 | } part; 169 | u16 all; 170 | } BAMRB; 171 | 172 | u32 BBRB; // 0xFFFFFF68 173 | 174 | union { 175 | struct { 176 | u32 H:16; // 0xFFFFFF70 177 | u32 L:16; // 0xFFFFFF72 178 | } part; 179 | u16 all; 180 | } BDRB; 181 | 182 | union { 183 | struct { 184 | u32 H:16; // 0xFFFFFF74 185 | u32 L:16; // 0xFFFFFF76 186 | } part; 187 | u16 all; 188 | } BDMRB; 189 | 190 | u32 BRCR; // 0xFFFFFF78 191 | u32 SAR0; // 0xFFFFFF80 192 | u32 DAR0; // 0xFFFFFF84 193 | u32 TCR0; // 0xFFFFFF88 194 | u32 CHCR0; // 0xFFFFFF8C 195 | u32 SAR1; // 0xFFFFFF90 196 | u32 DAR1; // 0xFFFFFF94 197 | u32 TCR1; // 0xFFFFFF98 198 | u32 CHCR1; // 0xFFFFFF9C 199 | u32 VCRDMA0;// 0xFFFFFFA0 200 | u32 VCRDMA1;// 0xFFFFFFA8 201 | u32 DMAOR; // 0xFFFFFFB0 202 | u16 BCR1; // 0xFFFFFFE0 203 | u16 BCR2; // 0xFFFFFFE4 204 | u16 WCR; // 0xFFFFFFE8 205 | u16 MCR; // 0xFFFFFFEC 206 | u16 RTCSR; // 0xFFFFFFF0 207 | u16 RTCNT; // 0xFFFFFFF4 208 | u16 RTCOR; // 0xFFFFFFF8 209 | } Onchip_struct; 210 | 211 | typedef struct 212 | { 213 | u8 vector; 214 | u8 level; 215 | } interrupt_struct; 216 | 217 | typedef struct 218 | { 219 | u32 addr; 220 | } codebreakpoint_struct; 221 | 222 | typedef struct 223 | { 224 | u32 addr; 225 | u32 flags; 226 | ReadFunc8 oldreadbyte; 227 | ReadFunc16 oldreadword; 228 | ReadFunc32 oldreadlong; 229 | WriteFunc8 oldwritebyte; 230 | WriteFunc16 oldwriteword; 231 | WriteFunc32 oldwritelong; 232 | } memorybreakpoint_struct; 233 | 234 | #define MAX_BREAKPOINTS 10 235 | 236 | typedef struct 237 | { 238 | codebreakpoint_struct codebreakpoint[MAX_BREAKPOINTS]; 239 | int numcodebreakpoints; 240 | memorybreakpoint_struct memorybreakpoint[MAX_BREAKPOINTS]; 241 | int nummemorybreakpoints; 242 | void (*BreakpointCallBack)(void *, u32); 243 | int inbreakpoint; 244 | } breakpoint_struct; 245 | 246 | #define BREAK_BYTEREAD 0x1 247 | #define BREAK_WORDREAD 0x2 248 | #define BREAK_LONGREAD 0x4 249 | #define BREAK_BYTEWRITE 0x8 250 | #define BREAK_WORDWRITE 0x10 251 | #define BREAK_LONGWRITE 0x20 252 | 253 | typedef struct 254 | { 255 | sh2regs_struct regs; 256 | Onchip_struct onchip; 257 | 258 | struct 259 | { 260 | u32 leftover; 261 | u32 shift; 262 | } frc; 263 | 264 | struct 265 | { 266 | int isenable; 267 | int isinterval; 268 | u32 leftover; 269 | u32 shift; 270 | } wdt; 271 | 272 | interrupt_struct interrupts[MAX_INTERRUPTS]; 273 | u32 NumberOfInterrupts; 274 | u32 AddressArray[0x100]; 275 | u8 DataArray[0x1000]; 276 | u32 delay; 277 | u32 cycles; 278 | u8 isslave; 279 | u8 isIdle; 280 | u8 isSleeping; 281 | u16 instruction; 282 | u8 breakpointEnabled; 283 | breakpoint_struct bp; 284 | 285 | } SH2_struct; 286 | 287 | typedef struct 288 | { 289 | int id; 290 | const char *Name; 291 | 292 | int (*Init)(void); 293 | void (*DeInit)(void); 294 | void (*Reset)(SH2_struct *context); 295 | void FASTCALL (*Exec)(SH2_struct *context, u32 cycles); 296 | 297 | void (*GetRegisters)(SH2_struct *context, sh2regs_struct *regs); 298 | u32 (*GetGPR)(SH2_struct *context, int num); 299 | u32 (*GetSR)(SH2_struct *context); 300 | u32 (*GetGBR)(SH2_struct *context); 301 | u32 (*GetVBR)(SH2_struct *context); 302 | u32 (*GetMACH)(SH2_struct *context); 303 | u32 (*GetMACL)(SH2_struct *context); 304 | u32 (*GetPR)(SH2_struct *context); 305 | u32 (*GetPC)(SH2_struct *context); 306 | 307 | void (*SetRegisters)(SH2_struct *context, const sh2regs_struct *regs); 308 | void (*SetGPR)(SH2_struct *context, int num, u32 value); 309 | void (*SetSR)(SH2_struct *context, u32 value); 310 | void (*SetGBR)(SH2_struct *context, u32 value); 311 | void (*SetVBR)(SH2_struct *context, u32 value); 312 | void (*SetMACH)(SH2_struct *context, u32 value); 313 | void (*SetMACL)(SH2_struct *context, u32 value); 314 | void (*SetPR)(SH2_struct *context, u32 value); 315 | void (*SetPC)(SH2_struct *context, u32 value); 316 | 317 | void (*SendInterrupt)(SH2_struct *context, u8 vector, u8 level); 318 | int (*GetInterrupts)(SH2_struct *context, 319 | interrupt_struct interrupts[MAX_INTERRUPTS]); 320 | void (*SetInterrupts)(SH2_struct *context, int num_interrupts, 321 | const interrupt_struct interrupts[MAX_INTERRUPTS]); 322 | 323 | void (*WriteNotify)(u32 start, u32 length); 324 | } SH2Interface_struct; 325 | 326 | extern SH2_struct *MSH2; 327 | extern SH2_struct *SSH2; 328 | extern SH2Interface_struct *SH2Core; 329 | 330 | int SH2Init(int coreid); 331 | void SH2DeInit(void); 332 | void SH2Reset(SH2_struct *context); 333 | void SH2PowerOn(SH2_struct *context); 334 | void FASTCALL SH2Exec(SH2_struct *context, u32 cycles); 335 | void SH2SendInterrupt(SH2_struct *context, u8 vector, u8 level); 336 | void SH2NMI(SH2_struct *context); 337 | void SH2Step(SH2_struct *context); 338 | void SH2GetRegisters(SH2_struct *context, sh2regs_struct * r); 339 | void SH2SetRegisters(SH2_struct *context, sh2regs_struct * r); 340 | void SH2WriteNotify(u32 start, u32 length); 341 | 342 | void DMAExec(void); 343 | void DMATransfer(u32 *CHCR, u32 *SAR, u32 *DAR, u32 *TCR, u32 *VCRDMA); 344 | 345 | u8 FASTCALL OnchipReadByte(u32 addr); 346 | u16 FASTCALL OnchipReadWord(u32 addr); 347 | u32 FASTCALL OnchipReadLong(u32 addr); 348 | void FASTCALL OnchipWriteByte(u32 addr, u8 val); 349 | void FASTCALL OnchipWriteWord(u32 addr, u16 val); 350 | void FASTCALL OnchipWriteLong(u32 addr, u32 val); 351 | 352 | u32 FASTCALL AddressArrayReadLong(u32 addr); 353 | void FASTCALL AddressArrayWriteLong(u32 addr, u32 val); 354 | 355 | u8 FASTCALL DataArrayReadByte(u32 addr); 356 | u16 FASTCALL DataArrayReadWord(u32 addr); 357 | u32 FASTCALL DataArrayReadLong(u32 addr); 358 | void FASTCALL DataArrayWriteByte(u32 addr, u8 val); 359 | void FASTCALL DataArrayWriteWord(u32 addr, u16 val); 360 | void FASTCALL DataArrayWriteLong(u32 addr, u32 val); 361 | 362 | void FASTCALL MSH2InputCaptureWriteWord(u32 addr, u16 data); 363 | void FASTCALL SSH2InputCaptureWriteWord(u32 addr, u16 data); 364 | 365 | #endif 366 | -------------------------------------------------------------------------------- /src/sh2idle.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2005 Theo Berkau 2 | 3 | This file is part of Yabause. 4 | 5 | Yabause is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Yabause is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Yabause; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef SH2IDLE_H 21 | #define SH2IDLE_H 22 | 23 | void FASTCALL SH2idleCheck(SH2_struct *context, u32 cycles); 24 | void FASTCALL SH2idleParse(SH2_struct *context, u32 cycles); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/sh2int.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2004-2005 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef SH2INT_H 22 | #define SH2INT_H 23 | 24 | #define SH2CORE_INTERPRETER 0 25 | #define SH2CORE_DEBUGINTERPRETER 1 26 | 27 | #define INSTRUCTION_A(x) ((x & 0xF000) >> 12) 28 | #define INSTRUCTION_B(x) ((x & 0x0F00) >> 8) 29 | #define INSTRUCTION_C(x) ((x & 0x00F0) >> 4) 30 | #define INSTRUCTION_D(x) (x & 0x000F) 31 | #define INSTRUCTION_CD(x) (x & 0x00FF) 32 | #define INSTRUCTION_BCD(x) (x & 0x0FFF) 33 | 34 | int SH2InterpreterInit(void); 35 | int SH2DebugInterpreterInit(void); 36 | void SH2InterpreterDeInit(void); 37 | void SH2InterpreterReset(SH2_struct *context); 38 | void FASTCALL SH2InterpreterExec(SH2_struct *context, u32 cycles); 39 | void FASTCALL SH2DebugInterpreterExec(SH2_struct *context, u32 cycles); 40 | void SH2InterpreterGetRegisters(SH2_struct *context, sh2regs_struct *regs); 41 | u32 SH2InterpreterGetGPR(SH2_struct *context, int num); 42 | u32 SH2InterpreterGetSR(SH2_struct *context); 43 | u32 SH2InterpreterGetGBR(SH2_struct *context); 44 | u32 SH2InterpreterGetVBR(SH2_struct *context); 45 | u32 SH2InterpreterGetMACH(SH2_struct *context); 46 | u32 SH2InterpreterGetMACL(SH2_struct *context); 47 | u32 SH2InterpreterGetPR(SH2_struct *context); 48 | u32 SH2InterpreterGetPC(SH2_struct *context); 49 | void SH2InterpreterSetRegisters(SH2_struct *context, const sh2regs_struct *regs); 50 | void SH2InterpreterSetGPR(SH2_struct *context, int num, u32 value); 51 | void SH2InterpreterSetSR(SH2_struct *context, u32 value); 52 | void SH2InterpreterSetGBR(SH2_struct *context, u32 value); 53 | void SH2InterpreterSetVBR(SH2_struct *context, u32 value); 54 | void SH2InterpreterSetMACH(SH2_struct *context, u32 value); 55 | void SH2InterpreterSetMACL(SH2_struct *context, u32 value); 56 | void SH2InterpreterSetPR(SH2_struct *context, u32 value); 57 | void SH2InterpreterSetPC(SH2_struct *context, u32 value); 58 | void SH2InterpreterSendInterrupt(SH2_struct *context, u8 level, u8 vector); 59 | int SH2InterpreterGetInterrupts(SH2_struct *context, 60 | interrupt_struct interrupts[MAX_INTERRUPTS]); 61 | void SH2InterpreterSetInterrupts(SH2_struct *context, int num_interrupts, 62 | const interrupt_struct interrupts[MAX_INTERRUPTS]); 63 | 64 | extern SH2Interface_struct SH2Interpreter; 65 | extern SH2Interface_struct SH2DebugInterpreter; 66 | 67 | typedef u32 (FASTCALL *fetchfunc)(u32); 68 | extern fetchfunc fetchlist[0x100]; 69 | 70 | typedef void (FASTCALL *opcodefunc)(SH2_struct *); 71 | extern opcodefunc opcode_arr[16]; 72 | opcodefunc FASTCALL decode(u16 instruction); 73 | 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/smpc.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2004-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef __SMPC_H__ 22 | #define __SMPC_H__ 23 | 24 | #include "memory.h" 25 | 26 | #define REGION_AUTODETECT 0 27 | #define REGION_JAPAN 1 28 | #define REGION_ASIANTSC 2 29 | #define REGION_NORTHAMERICA 4 30 | #define REGION_CENTRALSOUTHAMERICANTSC 5 31 | #define REGION_KOREA 6 32 | #define REGION_ASIAPAL 10 33 | #define REGION_EUROPE 12 34 | #define REGION_CENTRALSOUTHAMERICAPAL 13 35 | 36 | extern u8 smpc_regs[0x80]; 37 | 38 | #define SMPC_REG_IREG(x) (*(smpc_regs + 0x01 + ((x) << 1))) 39 | #define SMPC_REG_COMREG (*(smpc_regs + 0x1F)) 40 | #define SMPC_REG_OREG(x) (*(smpc_regs + 0x21 + ((x) << 1))) 41 | #define SMPC_REG_SR (*(smpc_regs + 0x61)) 42 | #define SMPC_REG_SF (*(smpc_regs + 0x63)) 43 | #define SMPC_REG_PDR1 (*(smpc_regs + 0x75)) 44 | #define SMPC_REG_PDR2 (*(smpc_regs + 0x77)) 45 | #define SMPC_REG_DDR1 (*(smpc_regs + 0x79)) 46 | #define SMPC_REG_DDR2 (*(smpc_regs + 0x7B)) 47 | #define SMPC_REG_IOSEL (*(smpc_regs + 0x7D)) 48 | #define SMPC_REG_EXLE (*(smpc_regs + 0x7F)) 49 | 50 | 51 | typedef struct 52 | { 53 | int offset; 54 | int size; 55 | u8 data[256]; 56 | } PortData_struct; 57 | 58 | typedef struct { 59 | u8 dotsel; // 0 -> 320 | 1 -> 352 60 | u8 mshnmi; 61 | u8 sndres; 62 | u8 cdres; 63 | u8 sysres; 64 | u8 resb; 65 | u8 ste; 66 | u8 resd; 67 | u8 intback; 68 | u8 intbackIreg0; 69 | u8 firstPeri; 70 | u8 regionid; 71 | u8 regionsetting; 72 | u8 SMEM[4]; 73 | s32 timing; 74 | //PortData_struct port1; 75 | //PortData_struct port2; 76 | u8 clocksync; 77 | u32 basetime; // Safe until early 2106. After that you're on your own (: 78 | } SmpcInternal; 79 | 80 | extern SmpcInternal * SmpcInternalVars; 81 | 82 | int SmpcInit(u8 regionid, int clocksync, u32 basetime); 83 | void SmpcDeInit(void); 84 | void SmpcRecheckRegion(void); 85 | void SmpcReset(void); 86 | void SmpcResetButton(void); 87 | void SmpcExec(s32 t); 88 | void SmpcINTBACKEnd(void); 89 | void SmpcCKCHG(u32 clk_type); 90 | 91 | u8 FASTCALL SmpcReadByte(u32); 92 | u16 FASTCALL SmpcReadWord(u32); 93 | u32 FASTCALL SmpcReadLong(u32); 94 | void FASTCALL SmpcWriteByte(u32, u8); 95 | void FASTCALL SmpcWriteWord(u32, u16); 96 | void FASTCALL SmpcWriteLong(u32, u32); 97 | 98 | int SmpcSetClockSync(int clocksync, u32 basetime); 99 | 100 | #endif /*__SMPC_H__*/ 101 | -------------------------------------------------------------------------------- /src/snd.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2004 Stephane Dallongeville 2 | Copyright 2004-2007 Theo Berkau 3 | Copyright 2006 Guillaume Duhamel 4 | 5 | This file is part of Yabause. 6 | 7 | Yabause is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | Yabause is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Yabause; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "scsp.h" 23 | #include "snd.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | static AESNDPB* voice = NULL; 34 | 35 | #define NUM_BUFFERS 4 36 | #define BUFFER_SIZE (8*DSP_STREAMBUFFER_SIZE) 37 | 38 | char buffers[NUM_BUFFERS][BUFFER_SIZE]; 39 | s16 stereodata16[(44100 / 60) * 16]; //11760 40 | int playBuffer = 0; 41 | int fillBufferOffset[NUM_BUFFERS]; 42 | int bytesBuffered = 0; 43 | u32 fillBuffer = 0; 44 | 45 | 46 | static void aesnd_callback(AESNDPB* voice, u32 state){ 47 | if(state == VOICE_STATE_STREAM) { 48 | if(playBuffer != fillBuffer) { 49 | if(fillBufferOffset[playBuffer] == BUFFER_SIZE) { 50 | AESND_SetVoiceBuffer(voice, 51 | buffers[playBuffer], BUFFER_SIZE); 52 | playBuffer = (playBuffer + 1) % NUM_BUFFERS; 53 | bytesBuffered -= BUFFER_SIZE; 54 | } 55 | } 56 | } 57 | } 58 | 59 | void snd_SetVolume(int volume) 60 | { 61 | u16 aesnd_vol = (u16)(((float)(256.0f / 1024.0f)) * 255); 62 | if (voice) AESND_SetVoiceVolume(voice, aesnd_vol, aesnd_vol); 63 | //soundvolume = ( (double)SDL_MIX_MAXVOLUME /(double)100 ) *volume; 64 | } 65 | 66 | void snd_Init(void) 67 | { 68 | AESND_Init(); 69 | voice = AESND_AllocateVoice(aesnd_callback); 70 | AESND_SetVoiceFormat(voice, VOICE_STEREO16); 71 | AESND_SetVoiceFrequency(voice, 44100); 72 | snd_SetVolume(0); 73 | AESND_SetVoiceStream(voice, true); 74 | AESND_Pause(1); 75 | } 76 | 77 | 78 | ////////////////////////////////////////////////////////////////////////////// 79 | 80 | void snd_DeInit(void) 81 | { 82 | AESND_Pause(1); 83 | } 84 | 85 | ////////////////////////////////////////////////////////////////////////////// 86 | 87 | int snd_Reset(void) 88 | { 89 | return 0; 90 | } 91 | 92 | ////////////////////////////////////////////////////////////////////////////// 93 | 94 | int snd_ChangeVideoFormat(int vertfreq) 95 | { 96 | //return (44100 / 60) * 8; 97 | return 0; 98 | } 99 | 100 | 101 | ////////////////////////////////////////////////////////////////////////////// 102 | 103 | 104 | static void snd32uto16s(s32 *src, s16 *dst, u32 len) { 105 | u32 i; 106 | for (i = 0; i < len; ++i) { 107 | // Are these useless? 108 | if (*src > 0x7FFF) *dst = 0x7FFF; 109 | else if (*src < -0x8000) *dst = -0x8000; 110 | else *dst = *src; 111 | ++src; 112 | ++dst; 113 | } 114 | } 115 | 116 | 117 | void snd_UpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples) 118 | { 119 | char *soundData = (char *) stereodata16; 120 | snd32uto16s((s32*) leftchanbuffer, stereodata16, num_samples << 1); 121 | s32 bytesRemaining = (num_samples << 1) * sizeof(s16); 122 | 123 | while (bytesRemaining > 0) { 124 | // Compute how many bytes to copy into the fillBuffer 125 | int bytesToCopy = BUFFER_SIZE - fillBufferOffset[fillBuffer]; 126 | if (bytesToCopy > bytesRemaining) { 127 | bytesToCopy = bytesRemaining; 128 | } 129 | 130 | // Copy the sound data into the fillBuffer 131 | memcpy(&buffers[fillBuffer][fillBufferOffset[fillBuffer]], soundData, bytesToCopy); 132 | soundData += bytesToCopy; 133 | bytesRemaining -= bytesToCopy; 134 | fillBufferOffset[fillBuffer] += bytesToCopy; 135 | bytesBuffered += bytesToCopy; 136 | 137 | // If the fillBuffer is full, advance to the next fillBuffer 138 | if (fillBufferOffset[fillBuffer] == BUFFER_SIZE) { 139 | fillBuffer = (fillBuffer + 1) % NUM_BUFFERS; 140 | fillBufferOffset[fillBuffer] = 0; 141 | } 142 | } 143 | 144 | AESND_SetVoiceStop(voice, false); 145 | } 146 | 147 | ////////////////////////////////////////////////////////////////////////////// 148 | 149 | u32 snd_GetAudioSpace(void) 150 | { 151 | return BUFFER_SIZE - fillBufferOffset[fillBuffer]; 152 | } 153 | 154 | ////////////////////////////////////////////////////////////////////////////// 155 | 156 | void snd_MuteAudio() 157 | { 158 | AESND_Pause(1); 159 | } 160 | 161 | ////////////////////////////////////////////////////////////////////////////// 162 | 163 | void snd_UnMuteAudio() 164 | { 165 | AESND_Pause(0); 166 | } 167 | 168 | -------------------------------------------------------------------------------- /src/snd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * snd.h - Sound output 3 | */ 4 | 5 | #ifndef __SOUND_H__ 6 | #define __SOUND_H__ 7 | 8 | void snd_Init(void); 9 | void snd_SetVolume(int volume); 10 | void snd_DeInit(void); 11 | int snd_Reset(void); 12 | int snd_ChangeVideoFormat(int vertfreq); 13 | void snd_UpdateAudio(u32 *leftchanbuffer, u32 *rightchanbuffer, u32 num_samples); 14 | u32 snd_GetAudioSpace(void); 15 | void snd_MuteAudio(); 16 | void snd_UnMuteAudio(); 17 | 18 | 19 | #endif /* __SOUND_H__ */ 20 | -------------------------------------------------------------------------------- /src/vdp1.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2004-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef VDP1_H 22 | #define VDP1_H 23 | 24 | #include "memory.h" 25 | 26 | //#define VDP1R_TVMR 27 | 28 | 29 | typedef struct { 30 | u16 TVMR; 31 | u16 FBCR; 32 | u16 PTMR; 33 | u16 EWDR; 34 | u16 EWLR; 35 | u16 EWRR; 36 | u16 ENDR; 37 | u16 EDSR; 38 | u16 LOPR; 39 | u16 COPR; 40 | u16 MODR; 41 | 42 | u32 addr; 43 | int disptoggle_dont_use_me; // not used anymore, see Vdp1External_struct 44 | 45 | s16 localX; 46 | s16 localY; 47 | 48 | u16 systemclipX1; 49 | u16 systemclipY1; 50 | u16 systemclipX2; 51 | u16 systemclipY2; 52 | 53 | u16 userclipX1; 54 | u16 userclipY1; 55 | u16 userclipX2; 56 | u16 userclipY2; 57 | } Vdp1; 58 | 59 | 60 | u8 FASTCALL Vdp1RamReadByte(u32); 61 | u16 FASTCALL Vdp1RamReadWord(u32); 62 | u32 FASTCALL Vdp1RamReadLong(u32); 63 | void FASTCALL Vdp1RamWriteByte(u32, u8); 64 | void FASTCALL Vdp1RamWriteWord(u32, u16); 65 | void FASTCALL Vdp1RamWriteLong(u32, u32); 66 | u8 FASTCALL Vdp1FrameBufferReadByte(u32); 67 | u16 FASTCALL Vdp1FrameBufferReadWord(u32); 68 | u32 FASTCALL Vdp1FrameBufferReadLong(u32); 69 | void FASTCALL Vdp1FrameBufferWriteByte(u32, u8); 70 | void FASTCALL Vdp1FrameBufferWriteWord(u32, u16); 71 | void FASTCALL Vdp1FrameBufferWriteLong(u32, u32); 72 | 73 | void Vdp1DrawCommands(u8 * ram, Vdp1 * regs, u8* back_framebuffer); 74 | void Vdp1FakeDrawCommands(u8 * ram, Vdp1 * regs); 75 | 76 | #define VDP1_RAM_SIZE 0x80000 77 | #define VDP1_FB_SIZE 0x80000 78 | #define VDP1_REGS_SIZE 0x1000 //Most bytes go unused, must be min pagesize 79 | 80 | 81 | extern u8 *Vdp1Ram; 82 | extern u8 *vdp1_ram_al[4]; 83 | extern u8 *Vdp1FrameBuffer; 84 | extern Vdp1 * Vdp1Regs; 85 | 86 | enum VDP1STATUS { 87 | VDP1_STATUS_IDLE = 0, 88 | VDP1_STATUS_RUNNING 89 | }; 90 | 91 | // struct for Vdp1 part that shouldn't be saved 92 | typedef struct { 93 | int disptoggle; 94 | int manualerase; 95 | int manualchange; 96 | int vbalnk_erase; 97 | int frame_change_plot; 98 | int swap_frame_buffer; 99 | int current_frame; 100 | int status; 101 | } Vdp1External_struct; 102 | 103 | extern Vdp1External_struct Vdp1External; 104 | 105 | typedef struct 106 | { 107 | u16 CMDCTRL; 108 | u16 CMDLINK; 109 | u16 CMDPMOD; 110 | u16 CMDCOLR; 111 | u16 CMDSRCA; 112 | u16 CMDSIZE; 113 | s16 CMDXA; 114 | s16 CMDYA; 115 | s16 CMDXB; 116 | s16 CMDYB; 117 | s16 CMDXC; 118 | s16 CMDYC; 119 | s16 CMDXD; 120 | s16 CMDYD; 121 | u16 CMDGRDA; 122 | } vdp1cmd_struct; 123 | 124 | 125 | //New Command struct 126 | typedef struct Vdp1Cmd_t { 127 | u16 CTRL; 128 | u16 LINK; 129 | u16 PMOD; 130 | u16 COLR; 131 | u16 SRCA; 132 | u16 SIZE; 133 | s16 XA; 134 | s16 YA; 135 | s16 XB; 136 | s16 YB; 137 | s16 XC; 138 | s16 YC; 139 | s16 XD; 140 | s16 YD; 141 | u16 GRDA; 142 | u16 _padding; 143 | } Vdp1Cmd; 144 | 145 | //Poinet to current command 146 | extern Vdp1Cmd *vdp1cmd; 147 | 148 | 149 | int Vdp1Init(void); 150 | void Vdp1DeInit(void); 151 | int VideoInit(int coreid); 152 | void VideoDeInit(void); 153 | void Vdp1Reset(void); 154 | 155 | u8 FASTCALL Vdp1ReadByte(u32); 156 | u16 FASTCALL Vdp1ReadWord(u32); 157 | u32 FASTCALL Vdp1ReadLong(u32); 158 | void FASTCALL Vdp1WriteByte(u32, u8); 159 | void FASTCALL Vdp1WriteWord(u32, u16); 160 | void FASTCALL Vdp1WriteLong(u32, u32); 161 | 162 | void Vdp1Draw(void); 163 | void Vdp1NoDraw(void); 164 | void FASTCALL Vdp1ReadCommand(vdp1cmd_struct *cmd, u32 addr); 165 | void ToggleVDP1(void); 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /src/vdp2.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2004-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef VDP2_H 22 | #define VDP2_H 23 | 24 | #include "memory.h" 25 | /* This include is not *needed*, it's here to avoid breaking ports */ 26 | 27 | extern u8 * Vdp2Ram; 28 | extern u8 * Vdp2ColorRam; 29 | 30 | u8 FASTCALL Vdp2RamReadByte(u32); 31 | u16 FASTCALL Vdp2RamReadWord(u32); 32 | u32 FASTCALL Vdp2RamReadLong(u32); 33 | void FASTCALL Vdp2RamWriteByte(u32, u8); 34 | void FASTCALL Vdp2RamWriteWord(u32, u16); 35 | void FASTCALL Vdp2RamWriteLong(u32, u32); 36 | 37 | u8 FASTCALL Vdp2ColorRamReadByte(u32); 38 | u16 FASTCALL Vdp2ColorRamReadWord(u32); 39 | u32 FASTCALL Vdp2ColorRamReadLong(u32); 40 | void FASTCALL Vdp2ColorRamWriteByte(u32, u8); 41 | void FASTCALL Vdp2ColorRamWriteWord(u32, u16); 42 | void FASTCALL Vdp2ColorRamWriteLong(u32, u32); 43 | 44 | typedef struct { 45 | u16 TVMD; // 0x25F80000 46 | u16 EXTEN; // 0x25F80002 47 | u16 TVSTAT; // 0x25F80004 48 | u16 VRSIZE; // 0x25F80006 49 | u16 HCNT; // 0x25F80008 50 | u16 VCNT; // 0x25F8000A 51 | u16 RAMCTL; // 0x25F8000E 52 | u16 CYCA0L; // 0x25F80010 53 | u16 CYCA0U; // 0x25F80012 54 | u16 CYCA1L; // 0x25F80014 55 | u16 CYCA1U; // 0x25F80016 56 | u16 CYCB0L; // 0x25F80018 57 | u16 CYCB0U; // 0x25F8001A 58 | u16 CYCB1L; // 0x25F8001C 59 | u16 CYCB1U; // 0x25F8001E 60 | u16 BGON; // 0x25F80020 61 | u16 MZCTL; // 0x25F80022 62 | u16 SFSEL; // 0x25F80024 63 | u16 SFCODE; // 0x25F80026 64 | u16 CHCTLA; // 0x25F80028 65 | u16 CHCTLB; // 0x25F8002A 66 | u16 BMPNA; // 0x25F8002C 67 | u16 BMPNB; // 0x25F8002E 68 | u16 PNCN0; // 0x25F80030 69 | u16 PNCN1; // 0x25F80032 70 | u16 PNCN2; // 0x25F80034 71 | u16 PNCN3; // 0x25F80036 72 | u16 PNCR; // 0x25F80038 73 | u16 PLSZ; // 0x25F8003A 74 | u16 MPOFN; // 0x25F8003C 75 | u16 MPOFR; // 0x25F8003E 76 | u16 MPABN0; // 0x25F80040 77 | u16 MPCDN0; // 0x25F80042 78 | u16 MPABN1; // 0x25F80044 79 | u16 MPCDN1; // 0x25F80046 80 | u16 MPABN2; // 0x25F80048 81 | u16 MPCDN2; // 0x25F8004A 82 | u16 MPABN3; // 0x25F8004C 83 | u16 MPCDN3; // 0x25F8004E 84 | u16 MPABRA; // 0x25F80050 85 | u16 MPCDRA; // 0x25F80052 86 | u16 MPEFRA; // 0x25F80054 87 | u16 MPGHRA; // 0x25F80056 88 | u16 MPIJRA; // 0x25F80058 89 | u16 MPKLRA; // 0x25F8005A 90 | u16 MPMNRA; // 0x25F8005C 91 | u16 MPOPRA; // 0x25F8005E 92 | u16 MPABRB; // 0x25F80060 93 | u16 MPCDRB; // 0x25F80062 94 | u16 MPEFRB; // 0x25F80064 95 | u16 MPGHRB; // 0x25F80066 96 | u16 MPIJRB; // 0x25F80068 97 | u16 MPKLRB; // 0x25F8006A 98 | u16 MPMNRB; // 0x25F8006C 99 | u16 MPOPRB; // 0x25F8006E 100 | u16 SCXIN0; // 0x25F80070 101 | u16 SCXDN0; // 0x25F80072 102 | u16 SCYIN0; // 0x25F80074 103 | u16 SCYDN0; // 0x25F80076 104 | 105 | union { 106 | struct { 107 | u32 I:16; // 0x25F80078 108 | u32 D:16; // 0x25F8007A 109 | } part; 110 | u32 all; 111 | } ZMXN0; 112 | 113 | union { 114 | struct { 115 | u32 I:16; // 0x25F8007C 116 | u32 D:16; // 0x25F8007E 117 | } part; 118 | u32 all; 119 | } ZMYN0; 120 | 121 | 122 | u16 SCXIN1; // 0x25F80080 123 | u16 SCXDN1; // 0x25F80082 124 | u16 SCYIN1; // 0x25F80084 125 | u16 SCYDN1; // 0x25F80086 126 | 127 | union { 128 | struct { 129 | u32 I:16; // 0x25F80088 130 | u32 D:16; // 0x25F8008A 131 | } part; 132 | u32 all; 133 | } ZMXN1; 134 | 135 | union { 136 | struct { 137 | u32 I:16; // 0x25F8008C 138 | u32 D:16; // 0x25F8008E 139 | } part; 140 | u32 all; 141 | } ZMYN1; 142 | 143 | u16 SCXN2; // 0x25F80090 144 | u16 SCYN2; // 0x25F80092 145 | u16 SCXN3; // 0x25F80094 146 | u16 SCYN3; // 0x25F80096 147 | u16 ZMCTL; // 0x25F80098 148 | u16 SCRCTL; // 0x25F8009A 149 | 150 | union { 151 | struct { 152 | u32 U:16; // 0x25F8009C 153 | u32 L:16; // 0x25F8009E 154 | } part; 155 | u32 all; 156 | } VCSTA; 157 | 158 | union { 159 | struct { 160 | u32 U:16; // 0x25F800A0 161 | u32 L:16; // 0x25F800A2 162 | } part; 163 | u32 all; 164 | } LSTA0; 165 | 166 | union { 167 | struct { 168 | u32 U:16; // 0x25F800A4 169 | u32 L:16; // 0x25F800A6 170 | } part; 171 | u32 all; 172 | } LSTA1; 173 | 174 | union { 175 | struct { 176 | u32 U:16; // 0x25F800A8 177 | u32 L:16; // 0x25F800AA 178 | } part; 179 | u32 all; 180 | } LCTA; 181 | 182 | 183 | u16 BKTAU; // 0x25F800AC 184 | u16 BKTAL; // 0x25F800AE 185 | u16 RPMD; // 0x25F800B0 186 | u16 RPRCTL; // 0x25F800B2 187 | u16 KTCTL; // 0x25F800B4 188 | u16 KTAOF; // 0x25F800B6 189 | u16 OVPNRA; // 0x25F800B8 190 | u16 OVPNRB; // 0x25F800BA 191 | 192 | union { 193 | struct { 194 | u32 U:16; // 0x25F800BC 195 | u32 L:16; // 0x25F800BE 196 | } part; 197 | u32 all; 198 | } RPTA; 199 | 200 | u16 WPSX0; // 0x25F800C0 201 | u16 WPSY0; // 0x25F800C2 202 | u16 WPEX0; // 0x25F800C4 203 | u16 WPEY0; // 0x25F800C6 204 | u16 WPSX1; // 0x25F800C8 205 | u16 WPSY1; // 0x25F800CA 206 | u16 WPEX1; // 0x25F800CC 207 | u16 WPEY1; // 0x25F800CE 208 | u16 WCTLA; // 0x25F800D0 209 | u16 WCTLB; // 0x25F800D2 210 | u16 WCTLC; // 0x25F800D4 211 | u16 WCTLD; // 0x25F800D6 212 | 213 | union { 214 | struct { 215 | u32 U:16; // 0x25F800D8 216 | u32 L:16; // 0x25F800DA 217 | } part; 218 | u32 all; 219 | } LWTA0; 220 | 221 | union { 222 | struct { 223 | u32 U:16; // 0x25F800DC 224 | u32 L:16; // 0x25F800DE 225 | } part; 226 | u32 all; 227 | } LWTA1; 228 | 229 | u16 SPCTL; // 0x25F800E0 230 | u16 SDCTL; // 0x25F800E2 231 | u16 CRAOFA; // 0x25F800E4 232 | u16 CRAOFB; // 0x25F800E6 233 | u16 LNCLEN; // 0x25F800E8 234 | u16 SFPRMD; // 0x25F800EA 235 | u16 CCCTL; // 0x25F800EC 236 | u16 SFCCMD; // 0x25F800EE 237 | u16 PRISA; // 0x25F800F0 238 | u16 PRISB; // 0x25F800F2 239 | u16 PRISC; // 0x25F800F4 240 | u16 PRISD; // 0x25F800F6 241 | u16 PRINA; // 0x25F800F8 242 | u16 PRINB; // 0x25F800FA 243 | u16 PRIR; // 0x25F800FC 244 | u16 CCRSA; // 0x25F80100 245 | u16 CCRSB; // 0x25F80102 246 | u16 CCRSC; // 0x25F80104 247 | u16 CCRSD; // 0x25F80106 248 | u16 CCRNA; // 0x25F80108 249 | u16 CCRNB; // 0x25F8010A 250 | u16 CCRR; // 0x25F8010C 251 | u16 CCRLB; // 0x25F8010E 252 | u16 CLOFEN; // 0x25F80110 253 | u16 CLOFSL; // 0x25F80112 254 | u16 COAR; // 0x25F80114 255 | u16 COAG; // 0x25F80116 256 | u16 COAB; // 0x25F80118 257 | u16 COBR; // 0x25F8011A 258 | u16 COBG; // 0x25F8011C 259 | u16 COBB; // 0x25F8011E 260 | } Vdp2; 261 | 262 | typedef struct { 263 | int ColorMode; 264 | } Vdp2Internal_struct; 265 | 266 | typedef struct Vdp2Lines_tag{ 267 | u16 SFPRMD; 268 | u16 BGON; 269 | } Vdp2Lines; 270 | 271 | extern Vdp2 * Vdp2Regs; 272 | extern Vdp2Lines vdp2_lines[270]; 273 | extern Vdp2Internal_struct Vdp2Internal; 274 | extern u64 lastticks; 275 | 276 | // struct for Vdp2 part that shouldn't be saved 277 | typedef struct { 278 | int disptoggle; 279 | } Vdp2External_struct; 280 | 281 | extern Vdp2External_struct Vdp2External; 282 | 283 | int Vdp2Init(void); 284 | void Vdp2DeInit(void); 285 | void Vdp2Reset(void); 286 | void Vdp2VBlankIN(void); 287 | void Vdp2HBlankIN(void); 288 | void Vdp2HBlankOUT(void); 289 | void Vdp2VBlankOUT(void); 290 | 291 | u8 FASTCALL Vdp2ReadByte(u32); 292 | u16 FASTCALL Vdp2ReadWord(u32); 293 | u32 FASTCALL Vdp2ReadLong(u32); 294 | void FASTCALL Vdp2WriteByte(u32, u8); 295 | void FASTCALL Vdp2WriteWord(u32, u16); 296 | void FASTCALL Vdp2WriteLong(u32, u32); 297 | 298 | 299 | void ToggleNBG0(void); 300 | void ToggleNBG1(void); 301 | void ToggleNBG2(void); 302 | void ToggleNBG3(void); 303 | void ToggleRBG0(void); 304 | 305 | 306 | #endif 307 | -------------------------------------------------------------------------------- /src/yabause.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2003-2005 Guillaume Duhamel 2 | Copyright 2004-2006 Theo Berkau 3 | Copyright 2006 Anders Montonen 4 | 5 | This file is part of Yabause. 6 | 7 | Yabause is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | Yabause is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with Yabause; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef YABAUSE_H 23 | #define YABAUSE_H 24 | 25 | #include "core.h" 26 | 27 | typedef struct 28 | { 29 | int percoretype; 30 | int sh2coretype; 31 | int vidcoretype; 32 | #ifdef SCSP_PLUGIN 33 | int scspcoretype; 34 | #endif 35 | int sndcoretype; 36 | int m68kcoretype; 37 | int cdcoretype; 38 | int carttype; 39 | u8 regionid; 40 | const char *biospath; 41 | const char *cdpath; 42 | const char *buppath; 43 | const char *mpegpath; 44 | const char *cartpath; 45 | const char *netlinksetting; 46 | int videoformattype; 47 | int frameskip; 48 | int clocksync; // 1 = sync internal clock to emulation, 0 = realtime clock 49 | u32 basetime; // Initial time in clocksync mode (0 = start w/ system time) 50 | int usethreads; 51 | } yabauseinit_struct; 52 | 53 | #define CLKTYPE_26MHZ 0 54 | #define CLKTYPE_28MHZ 1 55 | 56 | #define VIDEOFORMATTYPE_NTSC 0 57 | #define VIDEOFORMATTYPE_PAL 1 58 | 59 | #ifndef NO_CLI 60 | void print_usage(const char *program_name); 61 | #endif 62 | 63 | void YabauseChangeTiming(int freqtype); 64 | int YabauseInit(yabauseinit_struct *init); 65 | void YabauseDeInit(void); 66 | void YabauseSetDecilineMode(int on); 67 | void YabauseResetNoLoad(void); 68 | void YabauseReset(void); 69 | void YabauseResetButton(void); 70 | int YabauseExec(void); 71 | void YabauseStartSlave(void); 72 | void YabauseStopSlave(void); 73 | u64 YabauseGetTicks(void); 74 | void YabauseSetVideoFormat(int type); 75 | void YabauseSpeedySetup(void); 76 | int YabauseQuickLoadGame(void); 77 | 78 | #define YABSYS_TIMING_BITS 20 79 | #define YABSYS_TIMING_MASK ((1 << YABSYS_TIMING_BITS) - 1) 80 | 81 | #define SYS_FLAGS_SHOW_FPS 0x2 /* Shows FPS on screen */ 82 | #define SYS_FLAGS_SHOW_DEBUG 0x2 /* Shows debug info on screen */ 83 | 84 | typedef struct { 85 | int DecilineMode; 86 | int DecilineCount; 87 | int LineCount; 88 | int VBlankLineCount; 89 | int MaxLineCount; 90 | u32 DecilineStop; // Fixed point 91 | u32 SH2CycleFrac; // Fixed point 92 | u32 DecilineUsec; // Fixed point 93 | u32 UsecFrac; // Fixed point 94 | u32 flags; /* System flags */ 95 | int CurSH2FreqType; 96 | int IsPal; 97 | u8 UseThreads; 98 | u8 IsSSH2Running; 99 | u64 OneFrameTime; 100 | u64 tickfreq; 101 | int emulatebios; 102 | int usequickload; 103 | } yabsys_struct; 104 | 105 | extern yabsys_struct yabsys; 106 | extern int lagframecounter; 107 | extern int LagFrameFlag; 108 | extern int framelength; 109 | extern int framecounter; 110 | 111 | int YabauseEmulate(void); 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /src/yui.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2004-2005 Guillaume Duhamel 2 | Copyright 2004-2006 Theo Berkau 3 | 4 | This file is part of Yabause. 5 | 6 | Yabause is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | Yabause is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with Yabause; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef YUI_H 22 | #define YUI_H 23 | 24 | #include "cdbase.h" 25 | #include "sh2core.h" 26 | #include "sh2int.h" 27 | #include "scsp.h" 28 | #include "smpc.h" 29 | #include "vdp1.h" 30 | #include "yabause.h" 31 | #include "sgx/svi.h" 32 | 33 | #define RED_SIZE 1 34 | #define GREEN_SIZE 2 35 | #define BLUE_SIZE 3 36 | #define DEPTH_SIZE 4 37 | #define DOUBLEBUFFER 5 38 | 39 | /* If Yabause encounters any fatal errors, it sends the error text to this function */ 40 | void YuiErrorMsg(const char *string); 41 | 42 | /* Sets attribute for the Video display. The values passed to this function 43 | depends on what Video core is being used at the time. This may end up 44 | being moved to the Video Core. */ 45 | void YuiSetVideoAttribute(int type, int val); 46 | 47 | /* Tells the yui it wants to setup the display to display the specified video 48 | format. It's up to the yui to setup the actual display. This may end 49 | up being moved to the Video Core. */ 50 | int YuiSetVideoMode(int width, int height, int bpp, int fullscreen); 51 | 52 | /* Tells the yui to exchange front and back video buffers. This may end 53 | up being moved to the Video Core. */ 54 | void YuiSwapBuffers(u32 wait_vsync); 55 | 56 | ////////////////////////////////////////////////////////////////////////////// 57 | // Helper functions(you can use these in your own port) 58 | ////////////////////////////////////////////////////////////////////////////// 59 | 60 | /* int MappedMemoryLoad(const char *filename, u32 addr); 61 | 62 | Loads the specified file(filename) to specified address(addr). Returns zero 63 | on success, less than zero if an error has occured. 64 | Note: Some areas in memory are read-only and won't acknowledge any writes. 65 | */ 66 | 67 | /* int MappedMemorySave(const char *filename, u32 addr, u32 size); 68 | 69 | Saves data from specified address(addr) by specified amount of bytes(size) 70 | to specified file(filename). Returns zero on success, less than zero if 71 | an error has occured. 72 | Note: Some areas in memory are write-only and will only return zero on 73 | reads. 74 | */ 75 | 76 | /* void MappedMemoryLoadExec(const char *filename, u32 pc); 77 | 78 | Loads the specified file(filename) to specified address(pc) and sets 79 | Master SH2 to execute from there. 80 | Note: Some areas in memory are read-only and won't acknowledge any writes. 81 | */ 82 | 83 | /* void FormatBackupRam(void *mem, u32 size); 84 | 85 | Formats the specified Backup Ram memory area(mem) of specified size(size). 86 | */ 87 | 88 | /* void SH2Disasm(u32 v_addr, u16 op, int mode, char *string); 89 | 90 | Generates a disassembled instruction into specified string(string) based 91 | on specified address(v_addr) and specified opcode(op). mode should always 92 | be 0. 93 | */ 94 | 95 | /* void SH2Step(SH2_struct *context); 96 | 97 | For the specified SH2 context(context), it executes 1 instruction. context 98 | should be either MSH2 or SSH2. 99 | */ 100 | 101 | /* void SH2GetRegisters(SH2_struct *context, sh2regs_struct * r); 102 | 103 | For the specified SH2 context(context), copies the current registers into 104 | the specified structure(r). context should be either MSH2 or SSH2. 105 | */ 106 | 107 | /* void SH2SetRegisters(SH2_struct *context, sh2regs_struct * r); 108 | 109 | For the specified SH2 context(context), copies the specified structure(r) 110 | to the current registers. context should be either MSH2 or SSH2. 111 | */ 112 | 113 | /* void SH2SetBreakpointCallBack(SH2_struct *context, void (*func)(void *, u32)); 114 | 115 | For the specified SH2 context(context), it sets the breakpoint handler 116 | function(func). context should be either MSH2 or SSH2. 117 | */ 118 | 119 | /* int SH2AddCodeBreakpoint(SH2_struct *context, u32 addr); 120 | 121 | For the specified SH2 context(context), it adds a code breakpoint for 122 | specified address(addr). context should be either MSH2 or SSH2. Returns 123 | zero on success, or less than zero if an error has occured(such as the 124 | breakpoint list being full) 125 | */ 126 | 127 | /* int SH2DelCodeBreakpoint(SH2_struct *context, u32 addr); 128 | 129 | For the specified SH2 context(context), it deletes a code breakpoint for 130 | specified address(addr). context should be either MSH2 or SSH2. Returns 131 | zero on success, or less than zero if an error has occured. 132 | */ 133 | 134 | /* codebreakpoint_struct *SH2GetBreakpointList(SH2_struct *context); 135 | 136 | For the specified SH2 context(context), it returns a pointer to the 137 | code breakpoint list for the processor. context should be either MSH2 or 138 | SSH2. 139 | */ 140 | 141 | /* void SH2ClearCodeBreakpoints(SH2_struct *context); 142 | 143 | For the specified SH2 context(context), it deletes every code breakpoint 144 | entry. context should be either MSH2 or SSH2. 145 | */ 146 | 147 | /* u32 M68KDisasm(u32 addr, char *outstring); 148 | 149 | Generates a disassembled instruction into specified string(string) based on 150 | instruction stored at specified address(addr). Returns address of next 151 | instruction. 152 | */ 153 | 154 | /* void M68KStep(); 155 | 156 | Executes 1 68k instruction. 157 | */ 158 | 159 | /* void M68KGetRegisters(m68kregs_struct *regs); 160 | 161 | Copies the current 68k registers into the specified structure(regs). 162 | */ 163 | 164 | /* void M68KSetRegisters(m68kregs_struct *regs); 165 | 166 | Copies the specified structure(regs) to the current 68k registers. 167 | */ 168 | 169 | /* void M68KSetBreakpointCallBack(void (*func)(u32)); 170 | 171 | It sets the breakpoint handler function(func) for the 68k. 172 | */ 173 | 174 | /* int M68KAddCodeBreakpoint(u32 addr); 175 | 176 | It adds a 68K code breakpoint for specified address(addr). Returns zero on 177 | success, or less than zero if an error has occured(such as the breakpoint 178 | list being full) 179 | */ 180 | 181 | /* int M68KDelCodeBreakpoint(u32 addr); 182 | 183 | It deletes a 68k code breakpoint for specified address(addr). Returns zero 184 | on success, or less than zero if an error has occured. 185 | */ 186 | 187 | /* m68kcodebreakpoint_struct *M68KGetBreakpointList(); 188 | 189 | It returns a pointer to the code breakpoint list for the 68k. 190 | */ 191 | 192 | /* void M68KClearCodeBreakpoints(); 193 | 194 | It deletes every code breakpoint entry for the 68k. 195 | */ 196 | 197 | /* void ScuDspDisasm(u8 addr, char *outstring); 198 | 199 | Generates a disassembled instruction into specified string(string) based on 200 | instruction stored at specified address(addr). 201 | */ 202 | 203 | /* void ScuDspStep(void); 204 | 205 | Executes 1 SCU DSP step 206 | */ 207 | 208 | /* void ScuDspGetRegisters(scudspregs_struct *regs); 209 | 210 | Copies the current SCU DSP registers into the specified structure(regs). 211 | */ 212 | 213 | /* void ScuDspSetRegisters(scudspregs_struct *regs); 214 | 215 | Copies the specified structure(regs) to the current SCU DSP registers. 216 | */ 217 | 218 | /* void ScuDspSetBreakpointCallBack(void (*func)(u32)); 219 | 220 | It sets the breakpoint handler function(func) for the SCU DSP. 221 | */ 222 | 223 | /* int ScuDspAddCodeBreakpoint(u32 addr); 224 | 225 | It adds a SCU DSP code breakpoint for specified address(addr). Returns zero 226 | on success, or less than zero if an error has occured(such as the 227 | breakpoint list being full) 228 | */ 229 | 230 | /* int ScuDspDelCodeBreakpoint(u32 addr); 231 | 232 | It deletes a SCU DSP code breakpoint for specified address(addr). Returns 233 | zero on success, or less than zero if an error has occured. 234 | */ 235 | 236 | /* scucodebreakpoint_struct *ScuDspGetBreakpointList(); 237 | 238 | It returns a pointer to the code breakpoint list for the SCU DSP. 239 | */ 240 | 241 | /* void ScuDspClearCodeBreakpoints(); 242 | 243 | It deletes every code breakpoint entry for the SCU DSP. 244 | */ 245 | 246 | /* void Vdp2DebugStatsRBG0(char *outstring, int *isenabled); 247 | void Vdp2DebugStatsNBG0(char *outstring, int *isenabled); 248 | void Vdp2DebugStatsNBG1(char *outstring, int *isenabled); 249 | void Vdp2DebugStatsNBG2(char *outstring, int *isenabled); 250 | void Vdp2DebugStatsNBG3(char *outstring, int *isenabled); 251 | 252 | Fills a specified string pointer(outstring) with debug information for the 253 | specified screen. It also fills a variable(isenabled) with the screen's 254 | current status 255 | */ 256 | 257 | #endif 258 | --------------------------------------------------------------------------------