├── .github └── workflows │ └── ccpp.yml ├── .gitignore ├── .gitlab-ci.yml ├── .travis.yml ├── Makefile ├── Makefile.350h ├── Makefile.amini ├── Makefile.bittboy ├── Makefile.common ├── Makefile.funkey ├── Makefile.gameta ├── Makefile.gcw0 ├── Makefile.libretro ├── Makefile.papk3s ├── Makefile.retrostone ├── Makefile.rg99 ├── Makefile.ritmix ├── Makefile.rs2 ├── Makefile.rs90 ├── Makefile.rs97 ├── Makefile.rs97_fbdev ├── Makefile.zipit ├── README.md ├── background.bmp ├── background_papk3s.bmp ├── docs ├── BROKEN_GAMES_LIST.txt ├── MIT_license.txt ├── Megadrive_SMS.txt ├── PROBLEM_GAMES.txt ├── SordM5.txt ├── TODO.txt ├── WISHLIST.md ├── changelog ├── compatability.txt ├── contributors.txt ├── history.txt ├── in_vgm source readme.txt ├── license ├── porting.txt ├── readme.htm ├── readme.txt └── source.txt ├── jni ├── Android.mk └── Application.mk ├── link.T ├── package ├── sms_sdl.png └── source ├── PORTING ├── basetsd.h ├── config.h ├── cpu_cores └── z80 │ ├── cpuintrf.h │ ├── osd_cpu.h │ ├── z80.c │ ├── z80.h │ └── z80_wrap.h ├── hvc.h ├── loadrom.c ├── loadrom.h ├── memz80.c ├── memz80.h ├── ntsc ├── changes.txt ├── license.txt ├── readme.txt ├── sms_ntsc.c ├── sms_ntsc.h ├── sms_ntsc.txt ├── sms_ntsc_config.h └── sms_ntsc_impl.h ├── pio.c ├── pio.h ├── ports ├── 350h │ ├── smsplus.c │ └── smsplus.h ├── amini │ ├── smsplus.c │ └── smsplus.h ├── bittboy │ ├── smsplus.c │ └── smsplus.h ├── fbdev │ ├── smsplus.c │ └── smsplus.h ├── funkey │ ├── smsplus.c │ └── smsplus.h ├── gameta │ ├── smsplus.c │ └── smsplus.h ├── gcw0 │ ├── smsplus.c │ └── smsplus.h ├── k3s │ ├── smsplus.c │ └── smsplus.h ├── libretro │ ├── libretro-common │ │ ├── include │ │ │ ├── libretro.h │ │ │ ├── retro_common_api.h │ │ │ ├── retro_inline.h │ │ │ └── streams │ │ │ │ └── memory_stream.h │ │ └── streams │ │ │ └── memory_stream.c │ ├── libretro_core_options.h │ ├── libretro_core_options_intl.h │ ├── smsplus.h │ └── smsplus_libretro.c ├── retrostone │ ├── smsplus.c │ └── smsplus.h ├── retrostone2 │ ├── smsplus.c │ └── smsplus.h ├── rs90 │ ├── smsplus.c │ └── smsplus.h ├── sdl │ ├── smsplus.c │ └── smsplus.h └── zipit │ ├── smsplus.c │ └── smsplus.h ├── render.c ├── render.h ├── scale2x ├── scale2x.c └── scale2x.h ├── scalers ├── scaler.c └── scaler.h ├── shared.h ├── sms.c ├── sms.h ├── sound ├── crabemu_sn76489 │ ├── sn76489.c │ └── sn76489.h ├── fmintf.c ├── fmintf.h ├── mame_sn76489 │ ├── sn76489.c │ └── sn76489.h ├── maxim_sn76489 │ ├── sn76489.c │ └── sn76489.h ├── sound.c ├── sound.h ├── ym2413.c └── ym2413.h ├── sound_output ├── alsa │ └── sound_output_alsa.c ├── libao │ └── sound_libao.c ├── oss │ └── sound_output_oss.c ├── portaudio │ └── sound_portaudio.c ├── pulse │ └── sound_output_pulse.c ├── sdl12 │ └── sound_output_sdl.c └── sound_output.h ├── state.c ├── state.h ├── system.c ├── system.h ├── text ├── fb │ ├── font_drawing.c │ ├── font_drawing.h │ └── font_menudata.h └── sdl │ ├── bigfontred.h │ ├── bigfontwhite.h │ ├── font.h │ ├── text_gui.c │ └── text_gui.h ├── tms.c ├── tms.h ├── unzip ├── fileio.c ├── fileio.h ├── ioapi.c ├── ioapi.h ├── miniz.c ├── miniz.h ├── minizconf.h ├── unzip.c └── unzip.h ├── vdp.c └── vdp.h /.github/workflows/ccpp.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: make 13 | run: | 14 | make -f Makefile.libretro clean 15 | make -f Makefile.libretro 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | *.a 3 | *.sms 4 | *.gg 5 | *.sg 6 | *.o 7 | *.gcda 8 | *.zip 9 | *.bin 10 | *.opk 11 | core 12 | source/nonfree/ 13 | sms_sdl 14 | *.out 15 | log.txt 16 | ./sms_sdl 17 | *.ipk 18 | *.so 19 | .vscode 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | os: linux 3 | dist: trusty 4 | sudo: required 5 | addons: 6 | apt: 7 | packages: 8 | - g++-7 9 | sources: 10 | - ubuntu-toolchain-r-test 11 | env: 12 | global: 13 | - CORE=smsplus 14 | - COMPILER_NAME=gcc CXX=g++-7 CC=gcc-7 15 | matrix: 16 | - PLATFORM=3ds 17 | - PLATFORM=linux_x64 18 | before_script: 19 | - pwd 20 | - mkdir -p ~/bin 21 | - ln -s /usr/bin/gcc-7 ~/bin/gcc 22 | - ln -s /usr/bin/g++-7 ~/bin/g++ 23 | - ln -s /usr/bin/cpp-7 ~/bin/cpp 24 | - export PATH=~/bin:$PATH 25 | - ls -l ~/bin 26 | - echo $PATH 27 | - g++-7 --version 28 | - g++ --version 29 | script: 30 | - cd ~/ 31 | - git clone --depth=50 https://github.com/libretro/libretro-super 32 | - cd libretro-super/travis 33 | - ./build.sh 34 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PRGNAME = sms.elf 2 | CC = gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = sdl 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = pulse 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate but proprietary), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -O0 -g3 -Wall -Wextra 26 | CFLAGS += -DLSB_FIRST -std=gnu99 -DALIGN_DWORD -DNOYUV 27 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 28 | 29 | SRCDIR += ./source/text/fb 30 | CFLAGS += -Isource/text/fb 31 | 32 | ifeq ($(PROFILE), YES) 33 | CFLAGS += -fprofile-generate=./ 34 | else ifeq ($(PROFILE), APPLY) 35 | CFLAGS += -fprofile-use -fbranch-probabilities 36 | endif 37 | 38 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 39 | CFLAGS += -DMAXIM_PSG 40 | endif 41 | 42 | ifeq ($(ZIP_SUPPORT), 0) 43 | CFLAGS += -DNOZIP_SUPPORT 44 | endif 45 | 46 | ifeq ($(SCALE2X_UPSCALER), 1) 47 | CFLAGS += -DSCALE2X_UPSCALER 48 | CFLAGS += -Isource/scale2x 49 | SRCDIR += ./source/scale2x 50 | endif 51 | 52 | LDFLAGS = -nodefaultlibs -lc -lgcc -lm -lSDL -Wl,--as-needed -Wl,--gc-sections -flto 53 | 54 | ifeq ($(SOUND_OUTPUT), portaudio) 55 | LDFLAGS += -lportaudio 56 | endif 57 | ifeq ($(SOUND_OUTPUT), libao) 58 | LDFLAGS += -lao 59 | endif 60 | ifeq ($(SOUND_OUTPUT), alsa) 61 | LDFLAGS += -lasound 62 | endif 63 | ifeq ($(SOUND_OUTPUT), pulse) 64 | LDFLAGS += -lpulse -lpulse-simple 65 | endif 66 | 67 | # Rules to make executable 68 | $(PRGNAME): $(OBJS) 69 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 70 | 71 | $(OBJ_C) : %.o : %.c 72 | $(CC) $(CFLAGS) -c -o $@ $< 73 | 74 | clean: 75 | rm -f $(PRGNAME) *.o 76 | -------------------------------------------------------------------------------- /Makefile.350h: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/gcw0-toolchain-static/usr/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = 350h 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = alsa 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mframe-header-opt -mno-fp-exceptions -mno-check-zero-division -fsingle-precision-constant -fno-common -march=mips32r2 -mtune=mips32r2 -mno-abicalls -fno-PIC -flto 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -fipa-pta -fsection-anchors -fdelete-dead-exceptions 29 | CFLAGS += -DALIGN_DWORD -DNOBLANKING_LEFTCOLUM 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | SRCDIR += ./source/text/fb 34 | CFLAGS += -Isource/text/fb 35 | 36 | ifeq ($(PROFILE), YES) 37 | CFLAGS += -fprofile-generate=/usr/local/home/.smsplus 38 | else ifeq ($(PROFILE), APPLY) 39 | CFLAGS += -fprofile-use -fbranch-probabilities 40 | endif 41 | 42 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 43 | CFLAGS += -DMAXIM_PSG 44 | endif 45 | 46 | ifeq ($(ZIP_SUPPORT), 0) 47 | CFLAGS += -DNOZIP_SUPPORT 48 | endif 49 | 50 | ifeq ($(SCALE2X_UPSCALER), 1) 51 | CFLAGS += -DSCALE2X_UPSCALER 52 | CFLAGS += -Isource/scale2x 53 | SRCDIR += ./source/scale2x 54 | endif 55 | 56 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -lasound -lm -Wl,--as-needed -Wl,--gc-sections -flto -s 57 | 58 | ifeq ($(SOUND_OUTPUT), portaudio) 59 | LDFLAGS += -lportaudio 60 | endif 61 | ifeq ($(SOUND_OUTPUT), libao) 62 | LDFLAGS += -lao 63 | endif 64 | ifeq ($(SOUND_OUTPUT), alsa) 65 | LDFLAGS += -lasound 66 | endif 67 | 68 | # Rules to make executable 69 | $(PRGNAME): $(OBJS) 70 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 71 | 72 | $(OBJ_C) : %.o : %.c 73 | $(CC) $(CFLAGS) -c -o $@ $< 74 | 75 | clean: 76 | rm -f $(PRGNAME) *.o 77 | -------------------------------------------------------------------------------- /Makefile.amini: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs97-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = amini 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = oss 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 0 13 | PROFILE = APPLY 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fsingle-precision-constant -fno-common -mips32 -fno-PIC -mno-abicalls -flto 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -fipa-pta -fsection-anchors -fdelete-dead-exceptions 29 | CFLAGS += -DALIGN_DWORD 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | ifeq ($(PORT), fbdev) 34 | SRCDIR += ./source/text/fb 35 | CFLAGS += -Isource/text/fb 36 | else 37 | SRCDIR += ./source/text/sdl 38 | CFLAGS += -Isource/text/sdl 39 | endif 40 | 41 | ifeq ($(PROFILE), YES) 42 | CFLAGS += -fprofile-generate=/mnt/int_sd/profile 43 | else ifeq ($(PROFILE), APPLY) 44 | CFLAGS += -fprofile-use -fbranch-probabilities 45 | endif 46 | 47 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 48 | CFLAGS += -DMAXIM_PSG 49 | endif 50 | 51 | ifeq ($(ZIP_SUPPORT), 0) 52 | CFLAGS += -DNOZIP_SUPPORT 53 | endif 54 | 55 | ifeq ($(SCALE2X_UPSCALER), 1) 56 | CFLAGS += -DSCALE2X_UPSCALER 57 | CFLAGS += -Isource/scale2x 58 | SRCDIR += ./source/scale2x 59 | endif 60 | 61 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 62 | 63 | ifeq ($(SOUND_OUTPUT), portaudio) 64 | LDFLAGS += -lportaudio 65 | endif 66 | ifeq ($(SOUND_OUTPUT), libao) 67 | LDFLAGS += -lao 68 | endif 69 | ifeq ($(SOUND_OUTPUT), alsa) 70 | LDFLAGS += -lasound 71 | endif 72 | ifeq ($(SOUND_OUTPUT), pulse) 73 | LDFLAGS += -lpulse -lpulse-simple 74 | endif 75 | 76 | # Rules to make executable 77 | $(PRGNAME): $(OBJS) 78 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 79 | 80 | $(OBJ_C) : %.o : %.c 81 | $(CC) $(CFLAGS) -c -o $@ $< 82 | 83 | clean: 84 | rm -f $(PRGNAME) *.o 85 | -------------------------------------------------------------------------------- /Makefile.bittboy: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/bittboy-toolchain/bin/arm-buildroot-linux-musleabi-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = bittboy 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = alsa 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate but proprietary), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = APPLY 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -fsingle-precision-constant -fno-PIC -flto -march=armv5te -mtune=arm926ej-s 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -DALIGN_DWORD 29 | CFLAGS += -DLSB_FIRST -std=gnu99 30 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 31 | 32 | SRCDIR += ./source/text/fb 33 | CFLAGS += -Isource/text/fb 34 | 35 | ifeq ($(PROFILE), YES) 36 | CFLAGS += -fprofile-generate=/mnt/profile 37 | else ifeq ($(PROFILE), APPLY) 38 | CFLAGS += -fprofile-use -fbranch-probabilities 39 | endif 40 | 41 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 42 | CFLAGS += -DMAXIM_PSG 43 | endif 44 | 45 | ifeq ($(ZIP_SUPPORT), 0) 46 | CFLAGS += -DNOZIP_SUPPORT 47 | endif 48 | 49 | ifeq ($(SCALE2X_UPSCALER), 1) 50 | CFLAGS += -DSCALE2X_UPSCALER 51 | CFLAGS += -Isource/scale2x 52 | SRCDIR += ./source/scale2x 53 | endif 54 | 55 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 56 | 57 | ifeq ($(SOUND_OUTPUT), portaudio) 58 | LDFLAGS += -lportaudio 59 | endif 60 | ifeq ($(SOUND_OUTPUT), libao) 61 | LDFLAGS += -lao 62 | endif 63 | ifeq ($(SOUND_OUTPUT), alsa) 64 | LDFLAGS += -lasound 65 | endif 66 | ifeq ($(SOUND_OUTPUT), pulse) 67 | LDFLAGS += -lpulse -lpulse-simple 68 | endif 69 | 70 | # Rules to make executable 71 | $(PRGNAME): $(OBJS) 72 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 73 | 74 | $(OBJ_C) : %.o : %.c 75 | $(CC) $(CFLAGS) -c -o $@ $< 76 | 77 | clean: 78 | rm -f $(PRGNAME) *.o 79 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | SOURCE_DIR := $(CORE_DIR)/source 2 | LIBRETRO_COMMON := $(SOURCE_DIR)/ports/libretro/libretro-common 3 | 4 | SOURCES_CXX := 5 | SOURCES_C := 6 | 7 | INCFLAGS += -I$(SOURCE_DIR)/ports/libretro -I$(LIBRETRO_COMMON)/include 8 | INCFLAGS += -I$(SOURCE_DIR) 9 | INCFLAGS += -I$(SOURCE_DIR)/sound -I$(SOURCE_DIR)/sound/$(SOUND_ENGINE) -I$(SOURCE_DIR)/sound_output 10 | 11 | ifeq ($(SOUND_ENGINE), crabemu_sn76489) 12 | SOURCES_C += $(SOURCE_DIR)/sound/crabemu_sn76489/sn76489.c 13 | else 14 | CFLAGS += -DMAXIM_PSG 15 | SOURCES_C += $(SOURCE_DIR)/sound/maxim_sn76489/sn76489.c 16 | endif 17 | 18 | ifeq ($(ZIP_SUPPORT), 0) 19 | CFLAGS += -DNOZIP_SUPPORT 20 | else 21 | INCFLAGS += -I$(SOURCE_DIR)/unzip 22 | SOURCES_C += \ 23 | $(SOURCE_DIR)/unzip/fileio.c \ 24 | $(SOURCE_DIR)/unzip/ioapi.c \ 25 | $(SOURCE_DIR)/unzip/miniz.c \ 26 | $(SOURCE_DIR)/unzip/unzip.c 27 | endif 28 | 29 | # Main 30 | SOURCES_C += \ 31 | $(SOURCE_DIR)/loadrom.c \ 32 | $(SOURCE_DIR)/memz80.c \ 33 | $(SOURCE_DIR)/pio.c \ 34 | $(SOURCE_DIR)/render.c \ 35 | $(SOURCE_DIR)/sms.c \ 36 | $(SOURCE_DIR)/system.c \ 37 | $(SOURCE_DIR)/tms.c \ 38 | $(SOURCE_DIR)/vdp.c 39 | 40 | # CPU Cores 41 | INCFLAGS += -I$(SOURCE_DIR)/cpu_cores/z80 42 | CFLAGS += -DUSE_Z80 43 | SOURCES_C += $(SOURCE_DIR)/cpu_cores/z80/z80.c 44 | 45 | # Sounds 46 | SOURCES_C += \ 47 | $(SOURCE_DIR)/sound/fmintf.c \ 48 | $(SOURCE_DIR)/sound/sound.c \ 49 | $(SOURCE_DIR)/sound/ym2413.c 50 | 51 | # SMS NTSC 52 | ifeq ($(HAVE_NTSC), 1) 53 | CFLAGS += -DHAVE_NTSC 54 | INCFLAGS += -I$(SOURCE_DIR)/ntsc 55 | SOURCES_C += $(SOURCE_DIR)/ntsc/sms_ntsc.c 56 | endif 57 | 58 | # Libretro 59 | ifeq ($(STATIC_LINKING),1) 60 | else 61 | SOURCES_C += $(LIBRETRO_COMMON)/streams/memory_stream.c 62 | endif 63 | 64 | SOURCES_C += $(SOURCE_DIR)/ports/libretro/smsplus_libretro.c 65 | -------------------------------------------------------------------------------- /Makefile.funkey: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/funkey-toolchain/bin/arm-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = funkey 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = alsa 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Wall -Wextra -Ofast -fsingle-precision-constant -fno-PIC -flto -fno-common 26 | CFLAGS += -std=gnu99 27 | 28 | CFLAGS += -DNOBLANKING_LEFTCOLUM 29 | CFLAGS += -DLSB_FIRST -std=gnu99 30 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 31 | 32 | SRCDIR += ./source/text/fb 33 | CFLAGS += -Isource/text/fb 34 | 35 | ifeq ($(PROFILE), YES) 36 | CFLAGS += -fprofile-generate=/mnt/smsplusgx_profile 37 | endif 38 | ifeq ($(PROFILE), APPLY) 39 | CFLAGS += -fprofile-use 40 | endif 41 | 42 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 43 | CFLAGS += -DMAXIM_PSG 44 | endif 45 | 46 | ifeq ($(ZIP_SUPPORT), 0) 47 | CFLAGS += -DNOZIP_SUPPORT 48 | endif 49 | 50 | ifeq ($(SCALE2X_UPSCALER), 1) 51 | CFLAGS += -DSCALE2X_UPSCALER 52 | CFLAGS += -Isource/scale2x 53 | SRCDIR += ./source/scale2x 54 | endif 55 | 56 | CFLAGS += -march=armv7-a+neon-vfpv4 -mtune=cortex-a7 -mfpu=neon-vfpv4 57 | CFLAGS += -fdata-sections -ffunction-sections -fsingle-precision-constant -freorder-functions -fno-math-errno -fgcse-las -fgcse-sm -fmerge-all-constants 58 | CXXFLAGS = $(CFLAGS) -ftree-vectorize -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-enforce-eh-specs -fstrict-enums -std=gnu++11 59 | LDFLAGS = -nodefaultlibs -lc -lgcc -lm -lSDL -lasound -lz -pthread -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none -Wl,-O1,--sort-common,--as-needed,--gc-sections -flto -no-pie -s 60 | 61 | ifeq ($(SOUND_OUTPUT), portaudio) 62 | LDFLAGS += -lportaudio 63 | endif 64 | ifeq ($(SOUND_OUTPUT), libao) 65 | LDFLAGS += -lao 66 | endif 67 | ifeq ($(SOUND_OUTPUT), alsa) 68 | LDFLAGS += -lasound 69 | endif 70 | ifeq ($(SOUND_OUTPUT), pulse) 71 | LDFLAGS += -lpulse -lpulse-simple 72 | endif 73 | 74 | # Rules to make executable 75 | $(PRGNAME): $(OBJS) 76 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 77 | 78 | $(OBJ_C) : %.o : %.c 79 | $(CC) $(CFLAGS) -c -o $@ $< 80 | 81 | clean: 82 | rm -f $(PRGNAME) *.o 83 | -------------------------------------------------------------------------------- /Makefile.gameta: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs97-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = gameta 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = oss 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fsingle-precision-constant -fno-common -mips32 -fno-PIC -mno-abicalls -flto 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -fipa-pta -fsection-anchors -fdelete-dead-exceptions 29 | CFLAGS += -DALIGN_DWORD 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | SRCDIR += ./source/text/fb 34 | CFLAGS += -Isource/text/fb 35 | 36 | ifeq ($(PROFILE), YES) 37 | CFLAGS += -fprofile-generate=/mnt/int_sd/profile 38 | else ifeq ($(PROFILE), APPLY) 39 | CFLAGS += -fprofile-use -fbranch-probabilities 40 | endif 41 | 42 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 43 | CFLAGS += -DMAXIM_PSG 44 | endif 45 | 46 | ifeq ($(ZIP_SUPPORT), 0) 47 | CFLAGS += -DNOZIP_SUPPORT 48 | endif 49 | 50 | ifeq ($(SCALE2X_UPSCALER), 1) 51 | CFLAGS += -DSCALE2X_UPSCALER 52 | CFLAGS += -Isource/scale2x 53 | SRCDIR += ./source/scale2x 54 | endif 55 | 56 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 57 | 58 | ifeq ($(SOUND_OUTPUT), portaudio) 59 | LDFLAGS += -lportaudio 60 | endif 61 | ifeq ($(SOUND_OUTPUT), libao) 62 | LDFLAGS += -lao 63 | endif 64 | ifeq ($(SOUND_OUTPUT), alsa) 65 | LDFLAGS += -lasound 66 | endif 67 | ifeq ($(SOUND_OUTPUT), pulse) 68 | LDFLAGS += -lpulse -lpulse-simple 69 | endif 70 | 71 | # Rules to make executable 72 | $(PRGNAME): $(OBJS) 73 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 74 | 75 | $(OBJ_C) : %.o : %.c 76 | $(CC) $(CFLAGS) -c -o $@ $< 77 | 78 | clean: 79 | rm -f $(PRGNAME) *.o 80 | -------------------------------------------------------------------------------- /Makefile.gcw0: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = gcw0 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = sdl12 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = APPLY 14 | ZIP_SUPPORT = 1 15 | HUGE_PAGES = 1 16 | 17 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 18 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 19 | VPATH = $(SRCDIR) 20 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 21 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 22 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 23 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 24 | OBJS = $(OBJ_C) $(OBJ_CP) 25 | 26 | CFLAGS = -Wall -Wextra -Ofast -fdata-sections -ffunction-sections -mframe-header-opt -mno-fp-exceptions -mno-check-zero-division -fsingle-precision-constant -fno-common -march=mips32r2 -mtune=mips32r2 -flto 27 | CFLAGS += -mno-xgot -fsection-anchors -fno-builtin -mplt -fno-PIC -mno-shared -mno-memcpy 28 | CFLAGS += -fno-math-errno -freorder-functions -std=gnu99 29 | 30 | CFLAGS += -DNOBLANKING_LEFTCOLUM -DOPENDINGUX_GCD_16PIXELS_ISSUE 31 | CFLAGS += -DLSB_FIRST -std=gnu99 32 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 33 | 34 | SRCDIR += ./source/text/fb 35 | CFLAGS += -Isource/text/fb 36 | 37 | ifeq ($(PROFILE), YES) 38 | CFLAGS += -fprofile-generate=/usr/local/home 39 | else ifeq ($(PROFILE), APPLY) 40 | CFLAGS += -fprofile-use -fbranch-probabilities 41 | endif 42 | 43 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 44 | CFLAGS += -DMAXIM_PSG 45 | endif 46 | 47 | ifeq ($(ZIP_SUPPORT), 0) 48 | CFLAGS += -DNOZIP_SUPPORT 49 | endif 50 | 51 | ifeq ($(SCALE2X_UPSCALER), 1) 52 | CFLAGS += -DSCALE2X_UPSCALER 53 | CFLAGS += -Isource/scale2x 54 | SRCDIR += ./source/scale2x 55 | endif 56 | 57 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -lasound -lm -flto -Wl,--as-needed -Wl,--gc-sections -no-pie -s 58 | ifeq ($(HUGE_PAGES), 1) 59 | LDFLAGS += -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152 -lhugetlbfs 60 | endif 61 | 62 | ifeq ($(SOUND_OUTPUT), portaudio) 63 | LDFLAGS += -lportaudio 64 | endif 65 | ifeq ($(SOUND_OUTPUT), libao) 66 | LDFLAGS += -lao 67 | endif 68 | ifeq ($(SOUND_OUTPUT), alsa) 69 | LDFLAGS += -lasound 70 | endif 71 | ifeq ($(SOUND_OUTPUT), pulse) 72 | LDFLAGS += -lpulse -lpulse-simple 73 | endif 74 | 75 | # Rules to make executable 76 | $(PRGNAME): $(OBJS) 77 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 78 | ifeq ($(HUGE_PAGES), 1) 79 | hugeedit --text --data $(PRGNAME) 80 | endif 81 | 82 | $(OBJ_C) : %.o : %.c 83 | $(CC) $(CFLAGS) -c -o $@ $< 84 | 85 | clean: 86 | rm -f $(PRGNAME) *.o 87 | -------------------------------------------------------------------------------- /Makefile.papk3s: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs97-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = k3s 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = oss 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = APPLY 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -funroll-loops -fdata-sections -ffunction-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fsingle-precision-constant -fno-common -mips32 -fno-PIC -mno-abicalls -flto 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -fipa-pta -fsection-anchors -fdelete-dead-exceptions 29 | CFLAGS += -DALIGN_DWORD -DNOBLANKING_LEFTCOLUM 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | ifeq ($(PORT), fbdev) 34 | SRCDIR += ./source/text/fb 35 | CFLAGS += -Isource/text/fb 36 | else 37 | SRCDIR += ./source/text/sdl 38 | CFLAGS += -Isource/text/sdl 39 | endif 40 | 41 | ifeq ($(PROFILE), YES) 42 | CFLAGS += -fprofile-generate=/mnt/int_sd/profile 43 | else ifeq ($(PROFILE), APPLY) 44 | CFLAGS += -fprofile-use -fbranch-probabilities 45 | endif 46 | 47 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 48 | CFLAGS += -DMAXIM_PSG 49 | endif 50 | 51 | ifeq ($(ZIP_SUPPORT), 0) 52 | CFLAGS += -DNOZIP_SUPPORT 53 | endif 54 | 55 | ifeq ($(SCALE2X_UPSCALER), 1) 56 | CFLAGS += -DSCALE2X_UPSCALER 57 | CFLAGS += -Isource/scale2x 58 | SRCDIR += ./source/scale2x 59 | endif 60 | 61 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 62 | 63 | ifeq ($(SOUND_OUTPUT), portaudio) 64 | LDFLAGS += -lportaudio 65 | endif 66 | ifeq ($(SOUND_OUTPUT), libao) 67 | LDFLAGS += -lao 68 | endif 69 | ifeq ($(SOUND_OUTPUT), alsa) 70 | LDFLAGS += -lasound 71 | endif 72 | ifeq ($(SOUND_OUTPUT), pulse) 73 | LDFLAGS += -lpulse -lpulse-simple 74 | endif 75 | 76 | # Rules to make executable 77 | $(PRGNAME): $(OBJS) 78 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 79 | 80 | $(OBJ_C) : %.o : %.c 81 | $(CC) $(CFLAGS) -c -o $@ $< 82 | 83 | clean: 84 | rm -f $(PRGNAME) *.o 85 | -------------------------------------------------------------------------------- /Makefile.retrostone: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/retrostone-toolchain/bin/arm-buildroot-linux-musleabihf-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = retrostone 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = alsa 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate but proprietary), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = APPLY 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fsingle-precision-constant -fno-PIC -flto 26 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 27 | CFLAGS += -DLSB_FIRST -std=gnu99 -DALIGN_DWORD -DRETROSTONE -DNOBLANKING_LEFTCOLUM 28 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 29 | 30 | SRCDIR += ./source/text/fb 31 | CFLAGS += -Isource/text/fb 32 | 33 | ifeq ($(PROFILE), YES) 34 | CFLAGS += -fprofile-generate=/home/useless/profile 35 | else ifeq ($(PROFILE), APPLY) 36 | CFLAGS += -fprofile-use -fbranch-probabilities 37 | endif 38 | 39 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 40 | CFLAGS += -DMAXIM_PSG 41 | endif 42 | 43 | ifeq ($(ZIP_SUPPORT), 0) 44 | CFLAGS += -DNOZIP_SUPPORT 45 | endif 46 | 47 | ifeq ($(SCALE2X_UPSCALER), 1) 48 | CFLAGS += -DSCALE2X_UPSCALER 49 | CFLAGS += -Isource/scale2x 50 | SRCDIR += ./source/scale2x 51 | endif 52 | 53 | LDFLAGS = -lc -lgcc -lm -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 54 | 55 | ifeq ($(SOUND_OUTPUT), portaudio) 56 | LDFLAGS += -lasound -lportaudio 57 | endif 58 | ifeq ($(SOUND_OUTPUT), libao) 59 | LDFLAGS += -lao 60 | endif 61 | ifeq ($(SOUND_OUTPUT), alsa) 62 | LDFLAGS += -lasound 63 | endif 64 | ifeq ($(SOUND_OUTPUT), pulse) 65 | LDFLAGS += -lpulse -lpulse-simple 66 | endif 67 | 68 | # Rules to make executable 69 | $(PRGNAME): $(OBJS) 70 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 71 | 72 | $(OBJ_C) : %.o : %.c 73 | $(CC) $(CFLAGS) -c -o $@ $< 74 | 75 | clean: 76 | rm -f $(PRGNAME) *.o 77 | -------------------------------------------------------------------------------- /Makefile.rg99: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs90-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = rg99 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = sdl12 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate but proprietary), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | PROFILE = 0 13 | ZIP_SUPPORT = 1 14 | 15 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip ./source/scalers 16 | SRCDIR += ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 17 | VPATH = $(SRCDIR) 18 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 19 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 20 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 21 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 22 | OBJS = $(OBJ_C) $(OBJ_CP) 23 | 24 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mplt -mno-shared -mframe-header-opt -fno-common -march=mips32 -mtune=mips32 -flto=auto 25 | CFLAGS += -falign-functions=4 -falign-jumps=4 -falign-loops=4 -falign-labels=4 -fsingle-precision-constant 26 | CFLAGS += -mno-fp-exceptions -mno-check-zero-division -fno-common 27 | CFLAGS += -DALIGN_DWORD -DNONBLOCKING_AUDIO -D_8BPP_COLOR 28 | CFLAGS += -DLSB_FIRST 29 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 30 | 31 | SRCDIR += ./source/text/fb 32 | CFLAGS += -Isource/text/fb 33 | 34 | ifeq ($(PROFILE), YES) 35 | CFLAGS += -fprofile-generate="/media/mmcblk0p1/sms_gcda" 36 | LDFLAGS = -lgcov 37 | else ifeq ($(PROFILE), APPLY) 38 | CFLAGS += -fprofile-use="./" 39 | LDFLAGS = -nodefaultlibs 40 | else 41 | LDFLAGS = -nodefaultlibs 42 | endif 43 | 44 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 45 | CFLAGS += -DMAXIM_PSG 46 | endif 47 | 48 | ifeq ($(ZIP_SUPPORT), 0) 49 | CFLAGS += -DNOZIP_SUPPORT 50 | endif 51 | 52 | ifeq ($(SCALE2X_UPSCALER), 1) 53 | CFLAGS += -DSCALE2X_UPSCALER 54 | CFLAGS += -Isource/scale2x 55 | SRCDIR += ./source/scale2x 56 | endif 57 | 58 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -Wl,--as-needed -Wl,--gc-sections -flto=auto -s 59 | 60 | ifeq ($(SOUND_OUTPUT), portaudio) 61 | LDFLAGS += -lportaudio 62 | endif 63 | ifeq ($(SOUND_OUTPUT), libao) 64 | LDFLAGS += -lao 65 | endif 66 | ifeq ($(SOUND_OUTPUT), alsa) 67 | LDFLAGS += -lasound 68 | endif 69 | ifeq ($(SOUND_OUTPUT), pulse) 70 | LDFLAGS += -lpulse -lpulse-simple 71 | endif 72 | 73 | # Rules to make executable 74 | $(PRGNAME): $(OBJS) 75 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 76 | 77 | $(OBJ_C) : %.o : %.c 78 | $(CC) $(CFLAGS) -std=gnu99 -c -o $@ $< 79 | 80 | clean: 81 | rm -f $(PRGNAME) *.o 82 | -------------------------------------------------------------------------------- /Makefile.ritmix: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/ritmix-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = amini 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = oss 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 1 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fsingle-precision-constant -fno-common -mips32 -fno-PIC -mno-abicalls -flto 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -fipa-pta -fsection-anchors -fdelete-dead-exceptions 29 | CFLAGS += -DALIGN_DWORD 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | ifeq ($(PORT), fbdev) 34 | SRCDIR += ./source/text/fb 35 | CFLAGS += -Isource/text/fb 36 | else 37 | SRCDIR += ./source/text/sdl 38 | CFLAGS += -Isource/text/sdl 39 | endif 40 | 41 | ifeq ($(PROFILE), YES) 42 | CFLAGS += -fprofile-generate=/mnt/int_sd/profile 43 | else ifeq ($(PROFILE), APPLY) 44 | CFLAGS += -fprofile-use -fbranch-probabilities 45 | endif 46 | 47 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 48 | CFLAGS += -DMAXIM_PSG 49 | endif 50 | 51 | ifeq ($(ZIP_SUPPORT), 0) 52 | CFLAGS += -DNOZIP_SUPPORT 53 | endif 54 | 55 | ifeq ($(SCALE2X_UPSCALER), 1) 56 | CFLAGS += -DSCALE2X_UPSCALER 57 | CFLAGS += -Isource/scale2x 58 | SRCDIR += ./source/scale2x 59 | endif 60 | 61 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 62 | 63 | ifeq ($(SOUND_OUTPUT), portaudio) 64 | LDFLAGS += -lportaudio 65 | endif 66 | ifeq ($(SOUND_OUTPUT), libao) 67 | LDFLAGS += -lao 68 | endif 69 | ifeq ($(SOUND_OUTPUT), alsa) 70 | LDFLAGS += -lasound 71 | endif 72 | ifeq ($(SOUND_OUTPUT), pulse) 73 | LDFLAGS += -lpulse -lpulse-simple 74 | endif 75 | 76 | # Rules to make executable 77 | $(PRGNAME): $(OBJS) 78 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 79 | 80 | $(OBJ_C) : %.o : %.c 81 | $(CC) $(CFLAGS) -c -o $@ $< 82 | 83 | clean: 84 | rm -f $(PRGNAME) *.o 85 | -------------------------------------------------------------------------------- /Makefile.rs2: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/retrostone2-toolchain/usr/bin/arm-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = retrostone2 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = sdl12 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 0 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Wall -Wextra -Ofast -fdata-sections -ffunction-sections -fsingle-precision-constant -fno-common -flto 26 | CFLAGS += -fsection-anchors -fno-builtin 27 | CFLAGS += -fno-math-errno -freorder-functions -std=gnu99 28 | 29 | CFLAGS += -DNOBLANKING_LEFTCOLUM -D_8BPP_COLOR 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | SRCDIR += ./source/text/fb 34 | CFLAGS += -Isource/text/fb 35 | 36 | ifeq ($(PROFILE), YES) 37 | CFLAGS += -fprofile-generate=/usr/local/home 38 | else ifeq ($(PROFILE), APPLY) 39 | CFLAGS += -fprofile-use -fbranch-probabilities 40 | endif 41 | 42 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 43 | CFLAGS += -DMAXIM_PSG 44 | endif 45 | 46 | ifeq ($(ZIP_SUPPORT), 0) 47 | CFLAGS += -DNOZIP_SUPPORT 48 | endif 49 | 50 | ifeq ($(SCALE2X_UPSCALER), 1) 51 | CFLAGS += -DSCALE2X_UPSCALER 52 | CFLAGS += -Isource/scale2x 53 | SRCDIR += ./source/scale2x 54 | endif 55 | 56 | LDFLAGS = -nodefaultlibs -lc -lgcc -lSDL -lasound -lm -flto -Wl,--as-needed -Wl,--gc-sections -no-pie -s 57 | 58 | ifeq ($(SOUND_OUTPUT), portaudio) 59 | LDFLAGS += -lportaudio 60 | endif 61 | ifeq ($(SOUND_OUTPUT), libao) 62 | LDFLAGS += -lao 63 | endif 64 | ifeq ($(SOUND_OUTPUT), alsa) 65 | LDFLAGS += -lasound 66 | endif 67 | ifeq ($(SOUND_OUTPUT), pulse) 68 | LDFLAGS += -lpulse -lpulse-simple 69 | endif 70 | 71 | # Rules to make executable 72 | $(PRGNAME): $(OBJS) 73 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 74 | 75 | $(OBJ_C) : %.o : %.c 76 | $(CC) $(CFLAGS) -c -o $@ $< 77 | 78 | clean: 79 | rm -f $(PRGNAME) *.o 80 | -------------------------------------------------------------------------------- /Makefile.rs90: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs90-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = rs90 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = sdl12 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate but proprietary), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | PROFILE = 0 13 | ZIP_SUPPORT = 1 14 | 15 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 16 | SRCDIR += ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 17 | VPATH = $(SRCDIR) 18 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 19 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 20 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 21 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 22 | OBJS = $(OBJ_C) $(OBJ_CP) 23 | 24 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mplt -mno-shared -mframe-header-opt -fno-common -march=mips32 -mtune=mips32 -flto=auto 25 | CFLAGS += -falign-functions=4 -falign-jumps=4 -falign-loops=4 -falign-labels=4 -fsingle-precision-constant 26 | CFLAGS += -mno-fp-exceptions -mno-check-zero-division -fno-common -fno-short-enums -ffinite-math-only -funsafe-math-optimizations -fsection-anchors -fgcse-las -fgcse-sm 27 | CFLAGS += -DALIGN_DWORD -D_8BPP_COLOR -DNOBLANKING_LEFTCOLUM -DNONBLOCKING_AUDIO 28 | CFLAGS += -DLSB_FIRST 29 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 30 | 31 | SRCDIR += ./source/text/fb 32 | CFLAGS += -Isource/text/fb 33 | 34 | ifeq ($(PROFILE), YES) 35 | CFLAGS += -fprofile-generate="/usr/local/home" 36 | LDFLAGS = -lgcov 37 | else ifeq ($(PROFILE), APPLY) 38 | CFLAGS += -fprofile-use 39 | LDFLAGS = -nodefaultlibs 40 | else 41 | LDFLAGS = -nodefaultlibs 42 | endif 43 | 44 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 45 | CFLAGS += -DMAXIM_PSG 46 | endif 47 | 48 | ifeq ($(ZIP_SUPPORT), 0) 49 | CFLAGS += -DNOZIP_SUPPORT 50 | endif 51 | 52 | ifeq ($(SCALE2X_UPSCALER), 1) 53 | CFLAGS += -DSCALE2X_UPSCALER 54 | CFLAGS += -Isource/scale2x 55 | SRCDIR += ./source/scale2x 56 | endif 57 | 58 | LDFLAGS += -lc -lgcc -lSDL -Wl,--as-needed -Wl,--gc-sections -flto=auto -s 59 | 60 | ifeq ($(SOUND_OUTPUT), portaudio) 61 | LDFLAGS += -lportaudio 62 | endif 63 | ifeq ($(SOUND_OUTPUT), libao) 64 | LDFLAGS += -lao 65 | endif 66 | ifeq ($(SOUND_OUTPUT), alsa) 67 | LDFLAGS += -lasound 68 | endif 69 | ifeq ($(SOUND_OUTPUT), pulse) 70 | LDFLAGS += -lpulse -lpulse-simple 71 | endif 72 | 73 | # Rules to make executable 74 | $(PRGNAME): $(OBJS) 75 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 76 | 77 | $(OBJ_C) : %.o : %.c 78 | $(CC) $(CFLAGS) -std=gnu99 -c -o $@ $< 79 | 80 | clean: 81 | rm -f $(PRGNAME) *.o 82 | -------------------------------------------------------------------------------- /Makefile.rs97: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs97-toolchain/bin/mipsel-linux-gcc 3 | STRIP = /opt/rs97-toolchain/bin/mipsel-linux-strip 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = gcw0 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = oss 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate but proprietary), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fsingle-precision-constant -fno-common -mxgot -mips32 -mno-mips16 -fno-PIC -mno-abicalls -flto 26 | CFLAGS += -DALIGN_DWORD -DRS97 -Wall -Wextra -DNONBLOCKING_AUDIO 27 | CFLAGS += -DLSB_FIRST -std=gnu99 28 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 29 | 30 | SRCDIR += ./source/text/fb 31 | CFLAGS += -Isource/text/fb 32 | 33 | ifeq ($(PROFILE), YES) 34 | CFLAGS += -fprofile-generate=/home/retrofw/profile_sms 35 | else ifeq ($(PROFILE), APPLY) 36 | CFLAGS += -fprofile-use 37 | endif 38 | 39 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 40 | CFLAGS += -DMAXIM_PSG 41 | endif 42 | 43 | ifeq ($(ZIP_SUPPORT), 0) 44 | CFLAGS += -DNOZIP_SUPPORT 45 | endif 46 | 47 | ifeq ($(SCALE2X_UPSCALER), 1) 48 | CFLAGS += -DSCALE2X_UPSCALER 49 | CFLAGS += -Isource/scale2x 50 | SRCDIR += ./source/scale2x 51 | endif 52 | 53 | LDFLAGS = -nodefaultlibs -lc -lgcc -lm -lSDL -no-pie -Wl,--as-needed -Wl,--gc-sections -flto -s 54 | 55 | ifeq ($(PROFILE), YES) 56 | LDFLAGS += -lgcov 57 | endif 58 | 59 | ifeq ($(SOUND_OUTPUT), portaudio) 60 | LDFLAGS += -lportaudio 61 | endif 62 | ifeq ($(SOUND_OUTPUT), libao) 63 | LDFLAGS += -lao 64 | endif 65 | ifeq ($(SOUND_OUTPUT), alsa) 66 | LDFLAGS += -lasound 67 | endif 68 | ifeq ($(SOUND_OUTPUT), pulse) 69 | LDFLAGS += -lpulse -lpulse-simple 70 | endif 71 | 72 | # Rules to make executable 73 | $(PRGNAME): $(OBJS) 74 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 75 | $(STRIP) $(PRGNAME) -s -R .comment -R .gnu.version --remove-section=.note --remove-section=.comment --strip-unneeded --strip-all 76 | 77 | $(OBJ_C) : %.o : %.c 78 | $(CC) $(CFLAGS) -c -o $@ $< 79 | 80 | clean: 81 | rm -f $(PRGNAME) *.o 82 | -------------------------------------------------------------------------------- /Makefile.rs97_fbdev: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/rs97-toolchain/bin/mipsel-linux-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = fbdev 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = oss 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fdata-sections -ffunction-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fsingle-precision-constant -fno-common -mips32 -fno-PIC -mno-abicalls -flto 26 | # SMS Plus GX suffers from alignment issues so setting these to 1 helps. 27 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 28 | CFLAGS += -fipa-pta -fsection-anchors -fdelete-dead-exceptions 29 | CFLAGS += -DALIGN_DWORD 30 | CFLAGS += -DLSB_FIRST -std=gnu99 31 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 32 | 33 | ifeq ($(PORT), fbdev) 34 | SRCDIR += ./source/text/fb 35 | CFLAGS += -Isource/text/fb 36 | else 37 | SRCDIR += ./source/text/sdl 38 | CFLAGS += -Isource/text/sdl 39 | endif 40 | 41 | ifeq ($(PROFILE), YES) 42 | CFLAGS += -fprofile-generate=/home/retrofw/profile 43 | else ifeq ($(PROFILE), APPLY) 44 | CFLAGS += -fprofile-use -fbranch-probabilities 45 | endif 46 | 47 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 48 | CFLAGS += -DMAXIM_PSG 49 | endif 50 | 51 | ifeq ($(ZIP_SUPPORT), 0) 52 | CFLAGS += -DNOZIP_SUPPORT 53 | endif 54 | 55 | ifeq ($(SCALE2X_UPSCALER), 1) 56 | CFLAGS += -DSCALE2X_UPSCALER 57 | CFLAGS += -Isource/scale2x 58 | SRCDIR += ./source/scale2x 59 | endif 60 | 61 | LDFLAGS = -nodefaultlibs -lc -lgcc -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 62 | 63 | ifeq ($(SOUND_OUTPUT), portaudio) 64 | LDFLAGS += -lportaudio 65 | endif 66 | ifeq ($(SOUND_OUTPUT), libao) 67 | LDFLAGS += -lao 68 | endif 69 | ifeq ($(SOUND_OUTPUT), alsa) 70 | LDFLAGS += -lasound 71 | endif 72 | ifeq ($(SOUND_OUTPUT), pulse) 73 | LDFLAGS += -lpulse -lpulse-simple 74 | endif 75 | 76 | # Rules to make executable 77 | $(PRGNAME): $(OBJS) 78 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 79 | 80 | $(OBJ_C) : %.o : %.c 81 | $(CC) $(CFLAGS) -c -o $@ $< 82 | 83 | clean: 84 | rm -f $(PRGNAME) *.o 85 | -------------------------------------------------------------------------------- /Makefile.zipit: -------------------------------------------------------------------------------- 1 | PRGNAME = sms_sdl 2 | CC = /opt/zipit-toolchain/bin/arm-buildroot-linux-musleabi-gcc 3 | 4 | # Possible choices : rs97, k3s (PAP K3S), sdl, amini, fbdev 5 | PORT = zipit 6 | # Possible choices : alsa, pulse (pulseaudio), oss, sdl12 (SDL 1.2 sound output), portaudio, libao 7 | SOUND_OUTPUT = alsa 8 | # Possible choices : crabemu_sn76489 (less accurate, GPLv2), maxim_sn76489 (somewhat problematic license but good accuracy) 9 | SOUND_ENGINE = maxim_sn76489 10 | # Possible choices : z80 (accurate), eighty (EightyZ80's core, GPLv2) 11 | Z80_CORE = z80 12 | SCALE2X_UPSCALER = 1 13 | PROFILE = 0 14 | ZIP_SUPPORT = 1 15 | 16 | SRCDIR = ./source ./source/cpu_cores/$(Z80_CORE) ./source/sound ./source/unzip 17 | SRCDIR += ./source/scalers ./source/ports/$(PORT) ./source/sound/$(SOUND_ENGINE) ./source/sound_output/$(SOUND_OUTPUT) 18 | VPATH = $(SRCDIR) 19 | SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c)) 20 | SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp)) 21 | OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C))) 22 | OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP))) 23 | OBJS = $(OBJ_C) $(OBJ_CP) 24 | 25 | CFLAGS = -Ofast -fsingle-precision-constant -fno-PIC -flto 26 | CFLAGS += -falign-functions=1 -falign-jumps=1 -falign-loops=1 -falign-labels=1 27 | CFLAGS += -DLSB_FIRST -std=gnu99 -DALIGN_DWORD -DZIPIT_PORT 28 | CFLAGS += -Isource -Isource/cpu_cores/$(Z80_CORE) -Isource/scalers -Isource/ports/$(PORT) -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/$(SOUND_ENGINE) -Isource/sound_output 29 | 30 | SRCDIR += ./source/text/fb 31 | CFLAGS += -Isource/text/fb 32 | 33 | ifeq ($(PROFILE), YES) 34 | CFLAGS += -fprofile-generate=/home/useless/profile 35 | else ifeq ($(PROFILE), APPLY) 36 | CFLAGS += -fprofile-use -fbranch-probabilities 37 | endif 38 | 39 | ifeq ($(SOUND_ENGINE), maxim_sn76489) 40 | CFLAGS += -DMAXIM_PSG 41 | endif 42 | 43 | ifeq ($(ZIP_SUPPORT), 0) 44 | CFLAGS += -DNOZIP_SUPPORT 45 | endif 46 | 47 | ifeq ($(SCALE2X_UPSCALER), 1) 48 | CFLAGS += -DSCALE2X_UPSCALER 49 | CFLAGS += -Isource/scale2x 50 | SRCDIR += ./source/scale2x 51 | endif 52 | 53 | LDFLAGS = -lc -lgcc -lm -lSDL -lasound -no-pie -Wl,--as-needed -Wl,--gc-sections -s -flto 54 | 55 | ifeq ($(SOUND_OUTPUT), portaudio) 56 | LDFLAGS += -lportaudio 57 | endif 58 | ifeq ($(SOUND_OUTPUT), libao) 59 | LDFLAGS += -lao 60 | endif 61 | ifeq ($(SOUND_OUTPUT), alsa) 62 | LDFLAGS += -lasound 63 | endif 64 | ifeq ($(SOUND_OUTPUT), tinyalsa) 65 | LDFLAGS += -ltinyalsa 66 | endif 67 | ifeq ($(SOUND_OUTPUT), pulse) 68 | LDFLAGS += -lpulse -lpulse-simple 69 | endif 70 | 71 | # Rules to make executable 72 | $(PRGNAME): $(OBJS) 73 | $(CC) $(CFLAGS) -o $(PRGNAME) $^ $(LDFLAGS) 74 | 75 | $(OBJ_C) : %.o : %.c 76 | $(CC) $(CFLAGS) -c -o $@ $< 77 | 78 | clean: 79 | rm -f $(PRGNAME) *.o 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SMSPlus-GX RS97 2 | ================== 3 | 4 | It used to be based on SMS Plus 1.3 but then i realised SMS Plus GX had a lot of additions and was much better, while still being free software. 5 | It is now based on SMS Plus GX, with some other changes too such as : 6 | - Updated MAME FM & Z80 core based on upstream (YM core from CrabEmu, GPLv2 licensed. Z80's core is BSD licensed) 7 | - PSG emulation based on CrabEmu's own PSG sound core. (also Maxim's psg as an option, set MAXIM_PSG) 8 | - Multiple audio output supports (ALSA, OSS, Pulseaudio, Portaudio, libao) 9 | - Numerous fixes so it can build & work properly on 64-bits. (as well as 32-bits of course) 10 | 11 | And more... 12 | 13 | This emulator is free software under the GPLv2 or later. See docs/license for more details. 14 | Also, see docs/contributors to see who contributed (indirectly or directly) to SMS Plus (GX). 15 | -------------------------------------------------------------------------------- /background.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/smsplus-gx/c642bbd0680b5959180a420036108893d0aec961/background.bmp -------------------------------------------------------------------------------- /background_papk3s.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/smsplus-gx/c642bbd0680b5959180a420036108893d0aec961/background_papk3s.bmp -------------------------------------------------------------------------------- /docs/BROKEN_GAMES_LIST.txt: -------------------------------------------------------------------------------- 1 | Known issues 2 | ============= 3 | 4 | - Madou Monogatari I (Game Gear) 5 | 6 | Has rendering issues due to video timing being different between SMS and GG. 7 | See : 8 | https://github.com/drhelius/Gearsystem/commit/71b7252831e8a50d94a11b491431b52f6c3af8d4 9 | 10 | Partially fixed as of f0192681f2daa9d1f225f891119e26dbc4969a54, but 11 | it is still not correct when the sprite moves into the background. 12 | 13 | - 93c46 EEPROM Support 14 | 15 | Used by a few Game Game games. 16 | 17 | Majors Pro Baseball 18 | Nomo's World Series Baseball (J) 19 | Pro Yakyuu GG League (J) 20 | World Series Baseball [A] 21 | World Series Baseball [B] 22 | World Series Baseball 95 23 | 24 | Implementations : 25 | https://github.com/OpenEmu/CrabEmu-Core/blob/master/consoles/sms/mapper-93c46.c 26 | 27 | World Series Baseball '95 and World Series Baseball will hang up without at least a stub in place. 28 | 29 | - LCD Persistence issues 30 | 31 | Some games take advantage of the Game Gear's poor LCD screen. 32 | If this behaviour is not replicated then it results in some heavy flickering. 33 | 34 | Here's a list of affected games : 35 | 36 | - The Adventures of Batman & Robin (Disappearing HUD) 37 | - Super Monaco GP 2 (Titlescreen) 38 | - Space Harrier 39 | - Ninja Gaiden (affects 3rd & 2nd act) 40 | - Halley Wars 41 | - MLBPA Baseball 42 | - Power Drive (unreleased prototype) 43 | - James Pond 3 (Overworld level text) 44 | 45 | MAME has an implementation of LCD persistence here (first appeared in MESS 0.135) : 46 | 47 | https://github.com/mamedev/mame/blob/08cd6110268f9363e6c2cb9f0b6d92c00dadfbd6/src/mame/machine/sms.cpp#L1557 48 | 49 | - Graphics Board 50 | 51 | http://www.smspower.org/forums/15032-SegaGraphicBoardV20ReverseEngineering 52 | No support for it given how recent it is. MEKA supports this so i should take a look at it. 53 | 54 | - Space Gun 55 | 56 | http://www.smspower.org/Development/SpaceGun-SMS 57 | 58 | I need to add back Lightgun emulation. 59 | The code is left turned off for now because most games also support the controllers but this game requires the light gun. 60 | 61 | There's also an issue with memory mapping. I believe we don't suffer from that bug ? 62 | 63 | - Sports Pad 64 | 65 | Not currently implemented. 66 | In addition to that, a bug has been discovered where the game would sometimes read the input from player 1 for player 2. 67 | Do we really want to implement this bug though ??? 68 | 69 | https://github.com/mamedev/mame/commit/33c5196a429d0afa801caac3ad24a76bf0ac273d#diff-cafb9b1c2517c95f421c776c3ec74e56 70 | -------------------------------------------------------------------------------- /docs/MIT_license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Gameblabla 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /docs/Megadrive_SMS.txt: -------------------------------------------------------------------------------- 1 | VDP Test 2 | 3 | Intro screen is glitchy. 4 | When entering a test, text is pink with grey outlines and some kind of blueish background, incorrect. 5 | Goes back to normal colors when exiting tests. 6 | Megadrive VDP test is correct. 7 | 8 | **SMS VDP data test** 9 | 10 | The following get errors 11 | Write after code2 wr 12 | VRAM wr set VDPbuffer 13 | CRAM wr set VDPbuffer 14 | 1 byte wr sets rd adr 15 | 1 byte wr sets wr adr 16 | 17 | The rest is OK. 18 | 19 | **VDP misc test** 20 | VCounter values : Error 21 | Hcounter correct : Error 22 | VCounter eng time 23 | VDP Realster mirrors 24 | Vcounter mirrors 25 | Frame IRQ HCount 26 | Line IRQ Hcount 27 | VINT flag Hcount 28 | 29 | **VDP Sprite test** 30 | Offscreen Y, col 31 | Spr col correct HC 32 | No disp spr egr 33 | 34 | Spr eyr correct HC 35 | 36 | 37 | **Testing X-Scroll latchtime** 38 | 39 | Column is not straight (sprite is visible, except if set to Megadrive VDP) 40 | 41 | Z80 SP : 0xDFF0 42 | Z80 IR : 0x0009 43 | Z80 AF : 0xAB00 44 | VDP VC : 0x0015 45 | VDP HC : 0x00F3 46 | -------------------------------------------------------------------------------- /docs/PROBLEM_GAMES.txt: -------------------------------------------------------------------------------- 1 | BreakThru! (Game Gear) 2 | ====================== 3 | 4 | Unpatched version does not actually work on real hardware it seems. (tested on Megadrive with GG2SMS and reverted patch) 5 | The patch just NOPs out the DI/EI calls to 0x00. 6 | 7 | It is apparently supposed not to work on real hardware without the patch, see : 8 | https://github.com/ekeeke/Genesis-Plus-GX/issues/399 9 | 10 | One might wonder if this was intentional or only happens under very specific circumstances. 11 | (Leftover register values ?) 12 | 13 | Madou Monogatari I (Game Gear) 14 | =============================== 15 | 16 | Intro with character waking up from nightmare has rendering issues with the sprite. 17 | This part is sensitive to the timing of the rendering scanline. 18 | 19 | Currently, this is partially fixed except during the short time when the sprites scroll into the background. 20 | 21 | Sonic's Edusoft (Master System) 22 | =============================== 23 | 24 | Relies on VDP register 1 being set by the BIOS. 25 | I looked at what the BIOS outputs to that register and it's 0xE except for one BIOS setting it to 0xC. 26 | The latter of which would still make it work on Sonic's Edusoft but seemingly break other games also. 27 | 28 | Because of this flaw, the Megadrive cannot run this game unpatched and it appears that 29 | the Game Gear and Mark 3 should not be able to run this either. 30 | 31 | Fantastic Dizzy (Master System) 32 | =============================== 33 | 34 | Uses the higher resolution modes found on PAL models. Very sensitive to timings. 35 | The game also needs proper emulation of HALT and a fairly accurate Z80 interpreter overall. 36 | If you don't get the timing rights for the VDP, you will get some rendering issues. 37 | The most common one being the flickering bar at the top. 38 | 39 | There are also other issues as well, such as the fact that this game won't work properly in NTSC mode 40 | so this should be done accordingly. 41 | 42 | Sonic 1 FM (Master system, homebrew patch) 43 | ========================================== 44 | 45 | The game can switch on the fly to FM or PSG. 46 | One must make sure that the FM code is not being emulated when disabled as otherwise this can lead 47 | to higher CPU usage for nothing. 48 | 49 | Some earlier versions of it were also suffering from timing issues on Japanese Mark 3 models. 50 | (I believe this is partly the reason why games just use one chip at a time, except for the Japanese SMS bios) 51 | These have since been fixed but i wonder if we should emulate this someday ? 52 | 53 | Dallyeora Pigu Wang (Master System) 54 | =================================== 55 | 56 | Uses the Z80's R register for selecting the CPU team. (it is used as some sort of a randomizer, a few other games do this also) 57 | If we ever add another CPU dynarec to it, this is a good test case. 58 | ROM file size is also not a power of 2. 59 | 60 | Alibaba and 40 Thieves, Block Hole (Master system) 61 | ================================================== 62 | 63 | These games will only work on consoles with RAM not being cleared. 64 | A quick fix is simply to clear the memory with 0xF0. 65 | 66 | This means that only the Japanese Master system can run these games. 67 | The overseas version clear the memory (0x00) but this also means that they can't run these games at all. 68 | 69 | Shadow Dancer, Ace of Aces (SMS) 70 | ================================= 71 | 72 | Both rely on the BIOS setting the Z80's SP register to 0xDFF0. 73 | If this is not being done, Shadow Dancer will be stuck on a black screen. 74 | 75 | Rainbow Islands (Master System, PAL) 76 | ==================================== 77 | 78 | Relies on memory area $df90 - $dffb being 0. 79 | On Consoles without a BIOS (Megadrive, Game Gear, Mark 3), area will most likely be random thus the game will lock up 80 | before you can reach the final level. 81 | 82 | https://www.smspower.org/forums/6843-WhatsUpWithRainbowIslands 83 | 84 | This is fixed in the Brazilian release. 85 | 86 | PGA TOUR Golf (Game Gear) 87 | ========================= 88 | 89 | Expects the low 5 bits of the VDP status register to not be zero. 90 | https://www.smspower.org/Development/PGATourGolf-SMS 91 | 92 | Great Baseball (1985), Pit Pot and Teddy Boy Blues (Japan) 93 | ========================================================== 94 | 95 | These have control issues when a FM sound unit is plugged in. 96 | 97 | Wanted (SMS) 98 | ============ 99 | 100 | Incompatible FM game. (Won't boot, red screen of death) 101 | 102 | Zool (GG, SMS) 103 | ============== 104 | 105 | From https://www.smspower.org/Development/Zool-SMS : 106 | 107 | Zool (SMS and GG versions) expects the VBlank bit (VDP status register bit 7) to be set several cycles 108 | before the VBlank IRQ actually occurs because of the following polling routine which can execute with interrupts enabled: 109 | 110 | wait_for_vblank: 111 | in a,(bf) 112 | and a,a 113 | jp p,wait_for_blank 114 | ret 115 | -------------------------------------------------------------------------------- /docs/SordM5.txt: -------------------------------------------------------------------------------- 1 | Sord M5 shares a lot in common with the SC-3000/SG-1000. 2 | 3 | It uses the same VDP chip (16KB of VRAM) and also the same RAM amount. 4 | There seems to be some conflict over the RAM memory : z88dk says it has 4K but someone else said it had 2k ?? 5 | 6 | Sord M5 also uses a stock PSG soundchip, which is the same as the SG-1000/SC-3000. 7 | 8 | Some people reported that the PSG soundchip in the Sord M5 has subtle differences. 9 | 10 | http://www.smspower.org/forums/14468-SordM5Programming 11 | https://github.com/z88dk/z88dk/wiki/Platform---Sord-M5 12 | -------------------------------------------------------------------------------- /docs/TODO.txt: -------------------------------------------------------------------------------- 1 | TODO LIST 2 | ========= 3 | 4 | - Switch render.c internally to 16-bits instead of using remap_8_to_16. 5 | Right now, SMS Plus assumes that we use an 8-bits display instead. 6 | For better performance on devices we target (RGB565 mainly), this will need to be switched to 16-bits internally. 7 | 8 | remap_8_to_16 is COMPLETE AND UTTER CRAP and takes away most of our CPU cycles simply because of it. 9 | I've seen some other ports trying to simplify said code. 10 | The Odroid-Go port of SMS Plus GX does such a thing, see here : 11 | https://github.com/OtherCrashOverride/go-play/blob/71636ed569ea6ecbb128fbd30bc4c5eedb59eab1/smsplusgx-go/components/smsplus/render.c 12 | 13 | But if you look at it, it still uses an 8-bits buffer. 14 | Looks like they still use an 8-bits display on the Odroid-Go. 15 | 16 | We really want to do it the proper way but perhaps getting rid of caching can help us do so. 17 | -------------------------------------------------------------------------------- /docs/WISHLIST.md: -------------------------------------------------------------------------------- 1 | - Sega System E 2 | 3 | A somewhat similar arcade board based on the Master system. 4 | It uses 2 VDP, both identical to the Master system. 5 | It is also equipped with 2 PSG (still mono), again same as Master System's tweaked PSG. 6 | It has 16kb of RAM. It does not come with a CPU, games are expected to be packaged with their own. 7 | Z80 CPUs are clocked slightly higher : 5.38 Mhz. 8 | 9 | Exclusive games for it : 10 | - Tetris 11 | - Pythagoras no Nazo 12 | - Slap Shooter 13 | 14 | Apparently Tetris only makes use of 1 VDP. 15 | 16 | FBA supports this board but we cannot borrow code from it due to the non-commercial clause. 17 | 18 | - Sord M5 19 | 20 | Shares a lot of similarities with the SG-1000/SC-3000 : 21 | Most of the differences bows down to the I/O ports and the BASIC ROM that comes with it. 22 | This thing supports cartridges as well as tape games. 23 | It would be nice to support at least cart games. 24 | 25 | - Memotech MTX 26 | 27 | Same as Sord M5, a lot of similarities to the SC-3000. 28 | -------------------------------------------------------------------------------- /docs/changelog: -------------------------------------------------------------------------------- 1 | 2 | Change log 3 | 4 | [1.3] 5 | 6 | - Fixed last entry in CRC lookup table. 7 | - Added TMS9918 display mode support for SMS2 and GG video chips. 8 | - Added very preliminary Windows port using Allegro. 9 | 10 | [1.2] 11 | 12 | - Fixed smptab allocation error. 13 | - Various source code cleanups. 14 | - Minor tweaks to sync with Mac source changes. 15 | - New sound update code from Richard Bannister. 16 | - Added more support for PAL hardware. 17 | - Added partial support for Codemasters games. 18 | - Fixed some aspects of ROM loading. 19 | - Fixed SRAM restore bug in save states. 20 | - Fixed viewport size check when going from extended to normal mode, which 21 | fixes Fantastic Dizzy opening screen and V counter test program. 22 | - Split up VDP emulation into SMS/GG/MD specific parts. 23 | - Added support for different port I/O port memory maps. 24 | - Fixed mapper restore bug in save states. 25 | - Fixed UI key management in dos/main.c 26 | - Improved HV counter emulation. 27 | - Added dump VRAM keyboard shortcut. (Alt+V) 28 | - Split up DOS code into different modules. 29 | - Fixed EXT connector and related I/O port 2 behavior. 30 | - Added GG I/O register emulation. 31 | - Changed SRAM management. 32 | - Modified use of reset/poweron/poweroff functions. 33 | - Added configuration via CRC for some Codemasters games. 34 | - Fixed implementation of GG input port. 35 | - Added cycle counter feature to Z80 emulator. 36 | - Added shutdown functions to other modules. 37 | - Mapped 2nd player inputs to keyboard numeric pad in dos/main.c 38 | - Fixed reset button handling in dos/main.c 39 | - Moved Z80 port handlers to memz80.c 40 | - Fixed console type assign in loadrom.c (removed TYPE_* defines) 41 | - Added support for I/O chip disable control. 42 | - Rewrote I/O chip emulation. 43 | - Fixed pixel LUT to handle sprite collision behind high priority BG tiles. 44 | - Added emulation of sprite overflow status flag. 45 | - Added 'granularity' member to bitmap struct and fixed DOS blur code. 46 | - Fixed FM sound restore on state load / FM emulator change. 47 | - Corrected screen blanking width. 48 | - Removed sprite limit disable feature. 49 | - Added support for extended display modes. 50 | - Added partial support for PAL display timing. 51 | - Removed BMP_* macros, replaced with bitmap.viewport.* variables. 52 | - Removed Y's (J) rendering hack that was problematic in other games. 53 | - Added error logging routines. 54 | - Removed Game Gear specific rendering speedups. 55 | - Replaced cart.type with sms.console, replaced access with IS_GG macro. 56 | - Renamed INPUT_SOFT_RESET to INPUT_RESET. Use for SMS games only. 57 | - Removed INPUT_HARD_RESET, use system_reset() instead. 58 | - Modified vdp_ctrl_w() to update address register LSB during leading write. 59 | - Changed path length in wram/state/snap routines to PATH_MAX in DOS code. 60 | - Added define to specify message length in DOS code. 61 | - Added r/w handlers for FM detection latch access, renamed fm* -> fmunit* 62 | - Added territory/console members to struct sms (removed sms.country). 63 | Removed TYPE_* and replaced with TERRITORY_* enums. 64 | - Fixed FM register restore during state load when sound is disabled. 65 | - Updated memory system to support 1K pages. 66 | - Updated zlib to 1.2.1 and unzip.c to 1.0 67 | - Moved sound management out of system.c into sound/sound.c,fmintf.c 68 | - Moved state management out of system.c into state.c 69 | - Rearranged header file include order in system.h 70 | - Added support for MAME YM2413 emulator 71 | - Abstracted FM sound chip interface to support both YM2413 emulators 72 | - Updated timeline in dos/main.c and system.c 73 | - Removed SSL logging 74 | - Fixed path length in loadrom.c to MAX_PATH from limits.h 75 | - Added library version display option to dos/main.c 76 | - Moved file I/O code to fileio.c 77 | - Fixed loadrom.c to support 16K ROM images 78 | - Updated documentation and porting instructions 79 | - Modified EMU2413 to have update function for 2-channel output 80 | - Modified dos\config.c to ensure parameters are left during option parsing 81 | - Modified YM2413 emulator to check for NULL pointer during shutdown 82 | - Cleaned up variable names in snd struct 83 | - Added default mixer callback 84 | - Made sound_shutdown() free memory 85 | - Modified sound_init() to allow re-initialization 86 | - Cleaned up system.h, sms.h, vdp.h 87 | - Optimized color expansion for paletteized 8-bit format in render.c 88 | - Added Maxim's SN76489 emulator, removed the old one 89 | - Added YM2413 context management 90 | - Fixed PSG/FM state save/load behavior 91 | 92 | [0.9.4b] 93 | 94 | - Removed calls to text_mode() and changed textprintf() to textprintf_ex(). 95 | for compatability with Allegro v4.1.11 (WIP). 96 | - Removed VERSION from shared.h and add APP_NAME, APP_VERSION to system.h. 97 | - Changed TYPE_OVERSEAS to TYPE_EXPORT in sms.h. 98 | - Renamed dos.c/dos.h to main.c/main.h. 99 | - Fixed FPS meter state display. 100 | - Moved 1P buttons from ALT/LCTRL keys to S/A keys. 101 | - Added work RAM dump feature (Alt+W). 102 | - Added mostly complete HV counter tables to hvc.h. 103 | - Rewrote VDP frame and line interrupt handling. 104 | - Added ID and version number to state files. 105 | - Removed vdp_run(), renamed sms_run() to system_run() in system.c. 106 | - Merged cpu_reset() with sms_reset(). 107 | - Consolidated parts of the ROM file loading routines. 108 | - Increased resolution of GG palette (Mean Bean Machine intro). 109 | - Fixed GG palette write handling (RoboCop 3 intro). 110 | - Rewrote and optimized tile caching routines. 111 | - Made SMS/GG palette brighter. 112 | - Fixed leftmost column drawing in SMS mode. 113 | - Upgraded Z80 CPU emulator from V2.7 to V3.3. 114 | 115 | -------------------------------------------------------------------------------- /docs/compatability.txt: -------------------------------------------------------------------------------- 1 | 2 | Cool Spot 3 | 4 | Menu area has gap after the screen blanking part. 5 | Caused by new interrupt handling code. 6 | 7 | F16 Fighting Falcon, Rozetta no Shouzou 8 | 9 | Uses TMS9918 display modes which are not supported yet. 10 | 11 | UPDATE: Fixed for v1.3! 12 | 13 | Y's (J) 14 | 15 | Uses specific features of SMS 1 VDP. 16 | 17 | (Fixed by Exophase in SMS Plus GX) 18 | -------------------------------------------------------------------------------- /docs/in_vgm source readme.txt: -------------------------------------------------------------------------------- 1 | in_vgm source files 2 | =================== 3 | 4 | Made with VC6. Please let me know if I've missed out any files. 5 | Uses ZLib (not included), EMU2413 (included), a modified version 6 | of some MAME FM cores (included) and Gens' YM2612 core (included). 7 | 8 | Many thanks to BlackAura for getting the MAME stuff working. 9 | 10 | Please note that I am not vastly experienced in C, so there may well be 11 | some stupid stuff in this source. 12 | 13 | You are allowed to do what you like with it just so long as: 14 | 15 | 1. You let me know if you distribute it (any included files or 16 | anything derived from them), and 17 | 2. You don't pass it off as your own. 18 | 19 | Maxim 20 | maxim@mwos.cjb.net 21 | -------------------------------------------------------------------------------- /docs/source.txt: -------------------------------------------------------------------------------- 1 | 2 | To compile: 3 | 4 | DOS: You'll need Allegro, SEAL and zlib. The fileutils package is needed 5 | for the 'clean' target in the makefile. 6 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | SOUND_ENGINE := maxim_sn76489 4 | Z80_CORE := z80 5 | ZIP_SUPPORT := 0 6 | DEBUG := 0 7 | FLAGS := 8 | 9 | CORE_DIR := $(LOCAL_PATH)/.. 10 | 11 | include $(CORE_DIR)/Makefile.common 12 | 13 | COREFLAGS := $(INCFLAGS) $(CFLAGS) 14 | COREFLAGS += -D__LIBRETRO__ -DALIGN_DWORD -DLSB_FIRST 15 | 16 | GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)" 17 | ifneq ($(GIT_VERSION)," unknown") 18 | COREFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" 19 | endif 20 | 21 | include $(CLEAR_VARS) 22 | LOCAL_MODULE := retro 23 | LOCAL_SRC_FILES := $(SOURCES_CXX) $(SOURCES_C) 24 | LOCAL_CFLAGS := $(COREFLAGS) 25 | LOCAL_CXXFLAGS := $(COREFLAGS) 26 | LOCAL_LDFLAGS := -Wl,-version-script=$(CORE_DIR)/link.T 27 | include $(BUILD_SHARED_LIBRARY) 28 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all 2 | -------------------------------------------------------------------------------- /link.T: -------------------------------------------------------------------------------- 1 | { 2 | global: retro_*; 3 | local: *; 4 | }; 5 | 6 | -------------------------------------------------------------------------------- /package: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir -p opk 4 | cp ./sms_sdl opk/sms_sdl 5 | cp ./sms_sdl.png opk/sms.png 6 | cp ./docs/license opk/COPYING 7 | 8 | # https://unix.stackexchange.com/questions/219268/how-to-add-new-lines-when-using-echo 9 | print() 10 | case ${IFS- } in 11 | (\ *) printf %b\\n "$*";; 12 | (*) IFS=\ $IFS 13 | printf %b\\n "$*" 14 | IFS=${IFS#?} 15 | esac 16 | 17 | # Create GmenuNx entry file plus other things 18 | 19 | print '[Desktop Entry] 20 | Type=Application 21 | Name=SMS Plus GX 22 | Comment=SMS/GG/SG emulator 23 | Exec=sms_sdl %f 24 | Icon=sms 25 | Terminal=false 26 | Type=Application 27 | Categories=emulators; 28 | X-OD-NeedsDownscaling=true 29 | selectorbrowser=true 30 | SelectorFilter=sms,SMS,gg,GG,sg,SG,zip,ZIP,col,COL,ms,MS,bin,BIN 31 | ' > opk/default."$1".desktop 32 | 33 | mksquashfs ./opk smsplus_"$1".opk -all-root -noappend -no-exports -no-xattrs 34 | 35 | rm -r opk 36 | -------------------------------------------------------------------------------- /sms_sdl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/smsplus-gx/c642bbd0680b5959180a420036108893d0aec961/sms_sdl.png -------------------------------------------------------------------------------- /source/basetsd.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/libretro/smsplus-gx/c642bbd0680b5959180a420036108893d0aec961/source/basetsd.h -------------------------------------------------------------------------------- /source/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H__ 2 | #define CONFIG_H__ 3 | 4 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 5 | 6 | typedef struct { 7 | int32_t fullscreen; 8 | int32_t fullspeed; 9 | int32_t nosound; 10 | int32_t joystick; 11 | /* Don't use below (sndrate), deprecated */ 12 | int32_t sndrate; 13 | int32_t country; 14 | int32_t console; 15 | int32_t fm; 16 | int32_t ntsc; 17 | int32_t spritelimit; 18 | int32_t extra_gg; 19 | int32_t tms_pal; 20 | char game_name[0x100]; 21 | uint8_t use_bios; 22 | uint8_t soundlevel; 23 | /* For input remapping */ 24 | uint32_t config_buttons[18]; 25 | } t_config; 26 | extern t_config option; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /source/cpu_cores/z80/cpuintrf.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef CPUINTRF_H 3 | #define CPUINTRF_H 4 | 5 | #include "osd_cpu.h" 6 | 7 | /* Interrupt line constants */ 8 | enum 9 | { 10 | /* line states */ 11 | CLEAR_LINE = 0, /* clear (a fired, held or pulsed) line */ 12 | ASSERT_LINE, /* assert an interrupt immediately */ 13 | HOLD_LINE, /* hold interrupt line until acknowledged */ 14 | PULSE_LINE, /* pulse interrupt line for one instruction */ 15 | 16 | /* internal flags (not for use by drivers!) */ 17 | INTERNAL_CLEAR_LINE = 100 + CLEAR_LINE, 18 | INTERNAL_ASSERT_LINE = 100 + ASSERT_LINE, 19 | 20 | /* input lines */ 21 | MAX_INPUT_LINES = 32+3, 22 | INPUT_LINE_IRQ0 = 0, 23 | INPUT_LINE_IRQ1 = 1, 24 | INPUT_LINE_IRQ2 = 2, 25 | INPUT_LINE_IRQ3 = 3, 26 | INPUT_LINE_IRQ4 = 4, 27 | INPUT_LINE_IRQ5 = 5, 28 | INPUT_LINE_IRQ6 = 6, 29 | INPUT_LINE_IRQ7 = 7, 30 | INPUT_LINE_IRQ8 = 8, 31 | INPUT_LINE_IRQ9 = 9, 32 | INPUT_LINE_NMI = MAX_INPUT_LINES - 3, 33 | 34 | /* special input lines that are implemented in the core */ 35 | INPUT_LINE_RESET = MAX_INPUT_LINES - 2, 36 | INPUT_LINE_HALT = MAX_INPUT_LINES - 1, 37 | 38 | /* output lines */ 39 | MAX_OUTPUT_LINES = 32 40 | }; 41 | 42 | 43 | /* daisy-chain link */ 44 | typedef struct { 45 | void (*reset)(int32_t); /* reset callback */ 46 | int32_t (*interrupt_entry)(int32_t); /* entry callback */ 47 | void (*interrupt_reti)(int32_t); /* reti callback */ 48 | int32_t irq_param; /* callback paramater */ 49 | } Z80_DaisyChain; 50 | 51 | #define Z80_MAXDAISY 4 /* maximum of daisy chan device */ 52 | 53 | #define Z80_INT_REQ 0x01 /* interrupt request mask */ 54 | #define Z80_INT_IEO 0x02 /* interrupt disable mask(IEO) */ 55 | 56 | #define Z80_VECTOR(device,state) (((device)<<8)|(state)) 57 | 58 | 59 | #endif /* CPUINTRF_H */ 60 | -------------------------------------------------------------------------------- /source/cpu_cores/z80/osd_cpu.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * * 3 | * Define size independent data types and operations. * 4 | * * 5 | * The following types must be supported by all platforms: * 6 | * * 7 | * UINT8 - Unsigned 8-bit Integer INT8 - Signed 8-bit integer * 8 | * UINT16 - Unsigned 16-bit Integer INT16 - Signed 16-bit integer * 9 | * UINT32 - Unsigned 32-bit Integer INT32 - Signed 32-bit integer * 10 | * UINT64 - Unsigned 64-bit Integer INT64 - Signed 64-bit integer * 11 | * * 12 | * * 13 | * The macro names for the artithmatic operations are composed as follows: * 14 | * * 15 | * XXX_R_A_B, where XXX - 3 letter operation code (ADD, SUB, etc.) * 16 | * R - The type of the result * 17 | * A - The type of operand 1 * 18 | * B - The type of operand 2 (if binary operation) * 19 | * * 20 | * Each type is one of: U8,8,U16,16,U32,32,U64,64 * 21 | * * 22 | *******************************************************************************/ 23 | 24 | 25 | #ifndef OSD_CPU_H 26 | #define OSD_CPU_H 27 | 28 | #include 29 | 30 | /****************************************************************************** 31 | * Union of uint8_t, uint16_t and uint32_t in native endianess of the target 32 | * This is used to access bytes and words in a machine independent manner. 33 | * The upper bytes h2 and h3 normally contain zero (16 bit CPU cores) 34 | * thus PAIR.d can be used to pass arguments to the memory system 35 | * which expects 'int' really. 36 | ******************************************************************************/ 37 | typedef union { 38 | #ifdef LSB_FIRST 39 | struct { uint8_t l,h,h2,h3; } b; 40 | struct { uint16_t l,h; } w; 41 | #else 42 | struct { uint8_t h3,h2,h,l; } b; 43 | struct { uint16_t h,l; } w; 44 | #endif 45 | uint32_t d; 46 | } PAIR; 47 | 48 | #endif /* defined OSD_CPU_H */ 49 | -------------------------------------------------------------------------------- /source/cpu_cores/z80/z80.h: -------------------------------------------------------------------------------- 1 | #ifndef Z80_H_ 2 | #define Z80_H_ 3 | 4 | #include "cpuintrf.h" 5 | 6 | #define Z80_Regs z80_t 7 | #define Z80_Context &Z80 8 | 9 | #define true 1 10 | #define false 0 11 | 12 | #define Z80_INPUT_LINE_WAIT 4 13 | #define Z80_INPUT_LINE_BUSRQ 5 14 | 15 | enum 16 | { 17 | Z80_PC, Z80_SP, 18 | Z80_A, Z80_B, Z80_C, Z80_D, Z80_E, Z80_H, Z80_L, 19 | Z80_AF, Z80_BC, Z80_DE, Z80_HL, 20 | Z80_IX, Z80_IY, Z80_AF2, Z80_BC2, Z80_DE2, Z80_HL2, 21 | Z80_R, Z80_I, Z80_IM, Z80_IFF1, Z80_IFF2, Z80_HALT, 22 | Z80_DC0, Z80_DC1, Z80_DC2, Z80_DC3, Z80_WZ 23 | }; 24 | 25 | enum { 26 | Z80_TABLE_op, 27 | Z80_TABLE_cb, 28 | Z80_TABLE_ed, 29 | Z80_TABLE_xy, 30 | Z80_TABLE_xycb, 31 | Z80_TABLE_ex /* cycles counts for taken jr/jp/call and interrupt latency (rst opcodes) */ 32 | }; 33 | 34 | /****************************************************************************/ 35 | /* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */ 36 | /* register is calculated as follows: refresh=(Z80.r&127)|(Z80.r2&128) */ 37 | /****************************************************************************/ 38 | typedef struct 39 | { 40 | PAIR pc,sp,af,bc,de,hl,ix,iy,wz; 41 | PAIR af2,bc2,de2,hl2; 42 | PAIR prvpc; 43 | uint8_t r,r2,iff1,iff2,halt,im,i; 44 | uint8_t after_ei; /* are we in the EI shadow? */ 45 | uint8_t after_ldair; /* same, but for LD A,I or LD A,R */ 46 | 47 | uint8_t *cc_op; 48 | uint8_t *cc_cb; 49 | uint8_t *cc_ed; 50 | uint8_t *cc_xy; 51 | uint8_t *cc_xycb; 52 | uint8_t *cc_ex; 53 | 54 | uint16_t ea; 55 | 56 | int32_t nmi_state; /* nmi line state */ 57 | int32_t nmi_pending; /* nmi pending */ 58 | int32_t irq_state; /* irq line state */ 59 | int32_t (*irq_callback)(int32_t); 60 | int32_t icount; 61 | int32_t wait_state; /* wait line state */ 62 | int32_t busrq_state; /* bus request line state */ 63 | } Z80_Regs; 64 | 65 | 66 | extern int32_t z80_cycle_count; 67 | extern Z80_Regs Z80; 68 | 69 | void z80_init(int32_t (*irqcallback)(int32_t)); 70 | void z80_reset (void); 71 | void z80_exit (void); 72 | int32_t z80_execute(int32_t cycles); 73 | void z80_set_irq_line(int32_t inputnum, int32_t state); 74 | void z80_reset_cycle_count(void); 75 | int32_t z80_get_elapsed_cycles(void); 76 | 77 | extern void (*cpu_writemem16)(uint16_t address, uint8_t data); 78 | extern void (*cpu_writeport16)(uint16_t port, uint8_t data); 79 | extern uint8_t (*cpu_readport16)(uint16_t port); 80 | 81 | #define zPC Z80.pc.w.l; 82 | 83 | #endif 84 | 85 | -------------------------------------------------------------------------------- /source/cpu_cores/z80/z80_wrap.h: -------------------------------------------------------------------------------- 1 | #ifndef WRAP_H 2 | #define WRAP_H 3 | 4 | #define ASSERT_LINE 1 5 | #define CLEAR_LINE 0 6 | #define IRQ_LINE_NMI 127 7 | #define INPUT_LINE_NMI 32 8 | #define INPUT_LINE_IRQ0 0 9 | 10 | #define CPUZ80_Init() \ 11 | z80_init(sms_irq_callback); 12 | 13 | #define CPUZ80_Reset() \ 14 | z80_reset(); \ 15 | z80_reset_cycle_count(); \ 16 | z80_set_irq_line (0, CLEAR_LINE); 17 | 18 | #define CPUIRQ_Pause() \ 19 | z80_set_irq_line(INPUT_LINE_NMI, ASSERT_LINE); \ 20 | z80_set_irq_line(INPUT_LINE_NMI, CLEAR_LINE); 21 | 22 | extern uint8_t *cpu_readmap[64]; 23 | extern uint8_t *cpu_writemap[64]; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /source/loadrom.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * ROM File loading support 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef LOADROM_H_ 26 | #define LOADROM_H_ 27 | 28 | /* Function prototypes */ 29 | uint32_t load_rom(char *filename); 30 | void free_rom(void); 31 | 32 | #ifndef NGC 33 | uint8_t *loadzip(char *archive, char *filename, int32_t *filesize); 34 | extern char game_name[PATH_MAX]; 35 | #endif 36 | 37 | #endif /* _LOADROM_H_ */ 38 | 39 | -------------------------------------------------------------------------------- /source/memz80.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Z80 Memory handlers 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef MEMZ80_H_ 26 | #define MEMZ80_H_ 27 | 28 | /* Global data */ 29 | extern uint8_t data_bus_pullup; 30 | extern uint8_t data_bus_pulldown; 31 | 32 | /* Function prototypes */ 33 | extern uint8_t z80_read_unmapped(void); 34 | extern void gg_port_w(uint16_t port, uint8_t data); 35 | extern uint8_t gg_port_r(uint16_t port); 36 | extern void ggms_port_w(uint16_t port, uint8_t data); 37 | extern uint8_t ggms_port_r(uint16_t port); 38 | extern void sms_port_w(uint16_t port, uint8_t data); 39 | extern uint8_t sms_port_r(uint16_t port); 40 | extern void smsj_port_w(uint16_t port, uint8_t data); 41 | extern uint8_t smsj_port_r(uint16_t port); 42 | extern void md_port_w(uint16_t port, uint8_t data); 43 | extern uint8_t md_port_r(uint16_t port); 44 | extern void tms_port_w(uint16_t port, uint8_t data); 45 | extern uint8_t tms_port_r(uint16_t port); 46 | extern void coleco_port_w(uint16_t port, uint8_t data); 47 | extern uint8_t coleco_port_r(uint16_t port); 48 | 49 | #ifdef SORDM5_EMU 50 | extern void sordm5_port_w(uint16_t port, uint8_t data); 51 | extern uint8_t sordm5_port_r(uint16_t port); 52 | #endif 53 | 54 | #endif /* _MEMZ80_H_ */ 55 | -------------------------------------------------------------------------------- /source/ntsc/changes.txt: -------------------------------------------------------------------------------- 1 | sms_ntsc Change Log 2 | ------------------- 3 | 4 | sms_ntsc 0.2.3 5 | -------------- 6 | - Moved configuration options to sms_ntsc_config.h, making it easier to 7 | manage 8 | 9 | - Greatly clarified and improved demo to read any uncompressed BMP image 10 | and write filtered image when done 11 | 12 | - Improved gamma to be properly applied to each RGB channel, and changed 13 | default to compensate for difference between PC monitor and TV gamma 14 | 15 | - Improved contrast to be properly applied to each RGB channel rather 16 | than just luma 17 | 18 | - Improved floating point calculations in library to be more stable and 19 | not need double precision, which was causing problems with the sharpness 20 | control on Windows when the DirectX libraries changed the FPU to single 21 | precision mode 22 | 23 | - Added extern "C" to header, allowing use in C++ without having to 24 | rename the source file 25 | 26 | - Made internal changes to factor out code common from all my NTSC 27 | filter libraries, greatly simplifying things for me 28 | 29 | 30 | sms_ntsc 0.2.2 31 | -------------- 32 | - Changed sms_ntsc_blit() again, this time to always take a pixel count 33 | for input pitch (since the type is known) and a byte count for the 34 | output pitch (since it can output at multiple depths now). I think I've 35 | got the right interface this time. :) 36 | 37 | - Improved default blitter to have selectable input and output pixel 38 | formats 39 | 40 | - Added parameters for resolution, color bleed, and artifacts 41 | 42 | - Added presets for composite video, S-video, RGB, and monochrome 43 | 44 | - Added SMS_NTSC_OUT_WIDTH() and SMS_NTSC_IN_WIDTH() for calculating 45 | input/output widths 46 | 47 | - Improved demo with more controls and interpolation and darkening of 48 | scanlines rather than duplicating them 49 | 50 | - Improved documentation 51 | 52 | - Interface changes: sms_ntsc_blit() takes output pitch in bytes again. 53 | Sorry for the multiple changes; I think I got it right this time. :) 54 | 55 | - Removed: SMS_NTSC_CALC_WIDTH (use SMS_NTSC_OUT_WIDTH) 56 | 57 | 58 | sms_ntsc 0.2.1 59 | -------------- 60 | - Added parameters for color fringing and edge artifacts 61 | 62 | 63 | sms_ntsc 0.2.0 64 | -------------- 65 | - Changed sms_ntsc_blit() to take pixel counts instead of byte counts 66 | for in_pitch and out_pitch, making it simpler to use. This requires that 67 | current code be updated. 68 | 69 | - Significantly improved NTSC signal processing to give clearer image 70 | and better sharpness control 71 | 72 | - Reduced scrolling shimmer and color artifacts to be closer to what 73 | console generates 74 | 75 | - Added gamma curve parameter to allow better matching of darker colors 76 | on a TV 77 | 78 | - Added ability to generate matching RGB palette for use in a normal 79 | blitter 80 | 81 | 82 | sms_ntsc 0.1.1 83 | -------------- 84 | - Changed sms_ntsc_blit() to accept 12-bit BGR pixels instead of palette 85 | indicies and a separate palette. 86 | 87 | - Improved sms_ntsc_blit() to accept any input width, allowing all the 88 | different screen widths to be handled without complication. Use 89 | SMS_NTSC_CALC_WIDTH() to find the output width for a given input width. 90 | 91 | - Added toggling of left 8 column display to demo 92 | 93 | 94 | sms_ntsc 0.1.0 95 | -------------- 96 | - First version 97 | -------------------------------------------------------------------------------- /source/ntsc/readme.txt: -------------------------------------------------------------------------------- 1 | sms_ntsc 0.2.3: Sega Master System NTSC Video Filter 2 | ---------------------------------------------------- 3 | This library filters a Sega Master System image to match what a TV would 4 | show, allowing an authentic image in an emulator. It uses a highly 5 | optimized algorithm to perform the same signal processing as an NTSC 6 | decoder in a TV, giving very similar pixel artifacts and color bleeding. 7 | The usual picture controls can be adjusted: hue, saturation, contrast, 8 | brightness, and sharpness. Additionally, the amount of NTSC chroma and 9 | luma artifacts can be reduced, allowing an image that corresponds to 10 | composite video (artifacts), S-video (color bleeding only), RGB (clean 11 | pixels), or anywhere inbetween. 12 | 13 | The output is scaled to the proper horizontal width, leaving it up the 14 | emulator to simply double the height. Specialized blitters can be easily 15 | written using a special interface, allowing customization of input and 16 | output pixel formats, optimization for the host platform, and efficient 17 | scanline doubling. 18 | 19 | Blitting a 248x192 source image to a 581x384 pixel 16-bit RGB memory 20 | buffer at 60 frames per second uses 7% CPU on a 2.0 GHz Athlon 3500+ and 21 | 33% CPU on a 10-year-old 400 MHz G3 PowerMac. 22 | 23 | Author : Shay Green 24 | Website : http://www.slack.net/~ant/ 25 | Forum : http://groups.google.com/group/blargg-sound-libs 26 | License : GNU Lesser General Public License (LGPL) 27 | Language: C or C++ 28 | 29 | 30 | Getting Started 31 | --------------- 32 | Build a program from demo.c, sms_ntsc.c, and the SDL multimedia library 33 | (see http://libsdl.org/). Run it with "test.bmp" in the same directory 34 | and it should show the filtered image. See demo.c for more. 35 | 36 | See sms_ntsc.txt for documentation and sms_ntsc.h for reference. Post to 37 | the discussion forum for assistance. 38 | 39 | 40 | Files 41 | ----- 42 | readme.txt Essential information 43 | sms_ntsc.txt Library documentation 44 | changes.txt Changes made since previous releases 45 | license.txt GNU Lesser General Public License 46 | 47 | benchmark.c Measures frame rate and processor usage of library 48 | demo.c Displays and saves NTSC filtered image 49 | demo_impl.h Internal routines used by demo 50 | test.bmp Test image for demo 51 | 52 | sms_ntsc_config.h Library configuration (modify as needed) 53 | sms_ntsc.h Library header and source 54 | sms_ntsc.c 55 | sms_ntsc_impl.h 56 | 57 | -- 58 | Shay Green 59 | -------------------------------------------------------------------------------- /source/ntsc/sms_ntsc.c: -------------------------------------------------------------------------------- 1 | /* sms_ntsc 0.2.3. http://www.slack.net/~ant/ */ 2 | 3 | #include "sms_ntsc.h" 4 | 5 | /* Copyright (C) 2006-2007 Shay Green. This module is free software; you 6 | can redistribute it and/or modify it under the terms of the GNU Lesser 7 | General Public License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. This 9 | module is distributed in the hope that it will be useful, but WITHOUT ANY 10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | details. You should have received a copy of the GNU Lesser General Public 13 | License along with this module; if not, write to the Free Software Foundation, 14 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 15 | 16 | sms_ntsc_setup_t const sms_ntsc_monochrome = { 0,-1, 0, 0,.2, 0, .2,-.2,-.2,-1, 0, 0 }; 17 | sms_ntsc_setup_t const sms_ntsc_composite = { 0, 0, 0, 0, 0, 0,.25, 0, 0, 0, 0, 0 }; 18 | sms_ntsc_setup_t const sms_ntsc_svideo = { 0, 0, 0, 0, 0, 0,.25, -1, -1, 0, 0, 0 }; 19 | sms_ntsc_setup_t const sms_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.70, -1, -1,-1, 0, 0 }; 20 | 21 | #define alignment_count 3 22 | #define burst_count 1 23 | #define rescale_in 8 24 | #define rescale_out 7 25 | 26 | #define artifacts_mid 0.4f 27 | #define artifacts_max 1.2f 28 | #define fringing_mid 0.8f 29 | #define std_decoder_hue 0 30 | 31 | #define gamma_size 16 32 | 33 | #include "sms_ntsc_impl.h" 34 | 35 | /* 3 input pixels -> 8 composite samples */ 36 | pixel_info_t const sms_ntsc_pixels [alignment_count] = { 37 | { PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } }, 38 | { PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } }, 39 | { PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } }, 40 | }; 41 | 42 | static void correct_errors( sms_ntsc_rgb_t color, sms_ntsc_rgb_t* out ) 43 | { 44 | unsigned i; 45 | for ( i = 0; i < rgb_kernel_size / 2; i++ ) 46 | { 47 | sms_ntsc_rgb_t error = color - 48 | out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] - 49 | out [i + 7] - out [i + 5 +14] - out [i + 3 +28]; 50 | CORRECT_ERROR( i + 3 + 28 ); 51 | } 52 | } 53 | 54 | void sms_ntsc_init( sms_ntsc_t* ntsc, sms_ntsc_setup_t const* setup ) 55 | { 56 | int entry; 57 | init_t impl; 58 | if ( !setup ) 59 | setup = &sms_ntsc_composite; 60 | init( &impl, setup ); 61 | 62 | for ( entry = 0; entry < sms_ntsc_palette_size; entry++ ) 63 | { 64 | float bb = impl.to_float [entry >> 8 & 0x0F]; 65 | float gg = impl.to_float [entry >> 4 & 0x0F]; 66 | float rr = impl.to_float [entry & 0x0F]; 67 | 68 | float y, i, q = RGB_TO_YIQ( rr, gg, bb, y, i ); 69 | 70 | int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g ); 71 | sms_ntsc_rgb_t rgb = PACK_RGB( r, g, b ); 72 | 73 | if ( setup->palette_out ) 74 | RGB_PALETTE_OUT( rgb, &setup->palette_out [entry * 3] ); 75 | 76 | if ( ntsc ) 77 | { 78 | gen_kernel( &impl, y, i, q, ntsc->table [entry] ); 79 | correct_errors( rgb, ntsc->table [entry] ); 80 | } 81 | } 82 | } 83 | 84 | #ifndef SMS_NTSC_NO_BLITTERS 85 | 86 | void sms_ntsc_blit( sms_ntsc_t const* ntsc, SMS_NTSC_IN_T const* input, long in_row_width, 87 | int in_width, int in_height, void* rgb_out, long out_pitch ) 88 | { 89 | int const chunk_count = in_width / sms_ntsc_in_chunk; 90 | 91 | /* handle extra 0, 1, or 2 pixels by placing them at beginning of row */ 92 | int const in_extra = in_width - chunk_count * sms_ntsc_in_chunk; 93 | unsigned const extra2 = (unsigned) -(in_extra >> 1 & 1); /* (unsigned) -1 = ~0 */ 94 | unsigned const extra1 = (unsigned) -(in_extra & 1) | extra2; 95 | 96 | for ( ; in_height; --in_height ) 97 | { 98 | SMS_NTSC_IN_T const* line_in = input; 99 | SMS_NTSC_BEGIN_ROW( ntsc, sms_ntsc_black, 100 | (SMS_NTSC_ADJ_IN( line_in [0] )) & extra2, 101 | (SMS_NTSC_ADJ_IN( line_in [extra2 & 1] )) & extra1 ); 102 | sms_ntsc_out_t* restrict line_out = (sms_ntsc_out_t*) rgb_out; 103 | int n; 104 | line_in += in_extra; 105 | 106 | for ( n = chunk_count; n; --n ) 107 | { 108 | /* order of input and output pixels must not be altered */ 109 | SMS_NTSC_COLOR_IN( 0, ntsc, SMS_NTSC_ADJ_IN( line_in [0] ) ); 110 | SMS_NTSC_RGB_OUT( 0, line_out [0], SMS_NTSC_OUT_DEPTH ); 111 | SMS_NTSC_RGB_OUT( 1, line_out [1], SMS_NTSC_OUT_DEPTH ); 112 | 113 | SMS_NTSC_COLOR_IN( 1, ntsc, SMS_NTSC_ADJ_IN( line_in [1] ) ); 114 | SMS_NTSC_RGB_OUT( 2, line_out [2], SMS_NTSC_OUT_DEPTH ); 115 | SMS_NTSC_RGB_OUT( 3, line_out [3], SMS_NTSC_OUT_DEPTH ); 116 | 117 | SMS_NTSC_COLOR_IN( 2, ntsc, SMS_NTSC_ADJ_IN( line_in [2] ) ); 118 | SMS_NTSC_RGB_OUT( 4, line_out [4], SMS_NTSC_OUT_DEPTH ); 119 | SMS_NTSC_RGB_OUT( 5, line_out [5], SMS_NTSC_OUT_DEPTH ); 120 | SMS_NTSC_RGB_OUT( 6, line_out [6], SMS_NTSC_OUT_DEPTH ); 121 | 122 | line_in += 3; 123 | line_out += 7; 124 | } 125 | 126 | /* finish final pixels */ 127 | SMS_NTSC_COLOR_IN( 0, ntsc, sms_ntsc_black ); 128 | SMS_NTSC_RGB_OUT( 0, line_out [0], SMS_NTSC_OUT_DEPTH ); 129 | SMS_NTSC_RGB_OUT( 1, line_out [1], SMS_NTSC_OUT_DEPTH ); 130 | 131 | SMS_NTSC_COLOR_IN( 1, ntsc, sms_ntsc_black ); 132 | SMS_NTSC_RGB_OUT( 2, line_out [2], SMS_NTSC_OUT_DEPTH ); 133 | SMS_NTSC_RGB_OUT( 3, line_out [3], SMS_NTSC_OUT_DEPTH ); 134 | 135 | SMS_NTSC_COLOR_IN( 2, ntsc, sms_ntsc_black ); 136 | SMS_NTSC_RGB_OUT( 4, line_out [4], SMS_NTSC_OUT_DEPTH ); 137 | SMS_NTSC_RGB_OUT( 5, line_out [5], SMS_NTSC_OUT_DEPTH ); 138 | SMS_NTSC_RGB_OUT( 6, line_out [6], SMS_NTSC_OUT_DEPTH ); 139 | 140 | input += in_row_width; 141 | rgb_out = (char*) rgb_out + out_pitch; 142 | } 143 | } 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /source/ntsc/sms_ntsc.txt: -------------------------------------------------------------------------------- 1 | sms_ntsc 0.2.3: Sega Master System NTSC Video Filter 2 | ---------------------------------------------------- 3 | Author : Shay Green 4 | Website : http://www.slack.net/~ant/ 5 | Forum : http://groups.google.com/group/blargg-sound-libs 6 | License : GNU Lesser General Public License (LGPL) 7 | Language: C or C++ 8 | 9 | 10 | Overview 11 | -------- 12 | To perform NTSC filtering, first allocate memory for a sms_ntsc_t object 13 | and call sms_ntsc_init(), then call sms_ntsc_blit() to perform 14 | filtering. You can call sms_ntsc_init() at any time to change image 15 | parameters. 16 | 17 | By default, sms_ntsc_blit() reads and writes pixels in 16-bit RGB. Edit 18 | sms_ntsc_config.h to change this. 19 | 20 | 21 | RGB Palette Generation 22 | ---------------------- 23 | A 4096-color RGB palette can be generated for use in a normal blitter. 24 | In your sms_ntsc_setup_t structure, point palette_out to a 12288-byte 25 | buffer (4096 * 3) to hold the palette, then call sms_ntsc_init(). If you 26 | only need the palette and aren't going to be using the NTSC blitter, 27 | pass 0 for the first parameter. 28 | 29 | 30 | Image Parameters 31 | ---------------- 32 | Many image parameters can be adjusted and presets are provided for 33 | composite video, S-video, RGB, and monochrome. Most are floating-point 34 | values with a general range of -1.0 to 1.0, where 0 is normal. The 35 | ranges are adjusted so that one parameter at an extreme (-1 or +1) and 36 | the rest at zero shouldn't result in any internal overflow (garbage 37 | pixels). Setting multiple parameters to their extreme can produce 38 | garbage. Put another way, the state space defined by all parameters 39 | within the range -1 to +1 is not fully usable, but some extreme corners 40 | are very useful so I don't want to reduce the parameter ranges. 41 | 42 | The sharpness and resolution parameters have similar effects. Resolution 43 | affects how crisp pixels are. Sharpness merely enhances the edges by 44 | increasing contrast, which makes things brighter at the edges. Artifacts 45 | sets how much "junk" is around the edges where colors and brightness 46 | change in the image, where -1 completely eliminates them. (Color) bleed 47 | affects how much colors blend together and the artifact colors at the 48 | edges of pixels surrounded by black. (Color) fringing affects how much 49 | color fringing occurs around the edges of bright objects, especially 50 | white text on a black background. 51 | 52 | When using custom settings, initialize your sms_ntsc_setup_t using one 53 | of the standard setups before customizing it. This will ensure that all 54 | fields are properly initialized, including any added in future releases 55 | of the library that your current code can't even know about. 56 | 57 | sms_ntsc_setup_t setup; 58 | setup = sms_ntsc_composite; /* do this first */ 59 | setup.sharpness = custom_sharpness; 60 | sms_ntsc_init( ntsc, &setup ); 61 | 62 | 63 | Image Size 64 | ---------- 65 | For proper aspect ratio, the image generated by the library must be 66 | doubled vertically. 67 | 68 | Use the SMS_NTSC_OUT_WIDTH() and SMS_NTSC_IN_WIDTH() macros to convert 69 | between input and output widths that the blitter uses. For example, if 70 | you are blitting an image 256 pixels wide, use SMS_NTSC_OUT_WIDTH( 256 ) 71 | to find out how many output pixels are written per row. Another example, 72 | use SMS_NTSC_IN_WIDTH( 640 ) to find how many input pixels will fit 73 | within 640 output pixels. 74 | 75 | 76 | Custom Blitter 77 | -------------- 78 | You can write your own blitter, allowing customization of how input 79 | pixels are obtained, the format of output pixels (15, 16, or 32-bit 80 | RGB), optimizations for your platform, and additional effects like 81 | efficient scanline doubling during blitting. 82 | 83 | Macros are included in sms_ntsc.h for writing your blitter so that your 84 | code can be carried over without changes to improved versions of the 85 | library. The default blitter at the end of sms_ntsc.c shows how to use 86 | the macros. Contact me for further assistance. 87 | 88 | The SMS_NTSC_BEGIN_ROW macro allows starting up to three pixels. The 89 | first pixel is cut off; its use is in specifying a background color 90 | other than black for the sliver on the left edge. The next two pixels 91 | can be used to handle the extra one or two pixels not handled by the 92 | main chunks of three pixels. For example if you want to blit 257 input 93 | pixels on a row (for whatever odd reason), you would start the first two 94 | with SMS_NTSC_BEGIN_ROW( ... sms_ntsc_black, line_in [0], line_in [1] ), 95 | then do the remaining 255 in chunks of three (255 is divisible by 3). 96 | 97 | 98 | Limitations 99 | ----------- 100 | The library's horizontal rescaling is too wide by about 3% in order to 101 | allow a much more optimal implementation. This means that a 248 pixel 102 | wide input image should appear as 563 output pixels, but with this 103 | library appears as 581 output pixels. TV aspect ratios probably vary by 104 | this much anyway. If you really need unscaled output, contact me and 105 | I'll see about adding it. 106 | 107 | 108 | Thanks 109 | ------ 110 | Thanks to NewRisingSun for his original code and explanations of NTSC, 111 | which was a starting point for me learning about NTSC video and 112 | decoding. Thanks to the Nesdev forum for feedback and encouragement. 113 | Thanks to Martin Freij (Nestopia author) and Charles MacDonald (SMS Plus 114 | author) for significant ongoing testing and feedback as the library has 115 | improved. Thanks to byuu (bsnes author) and pagefault (ZSNES team) for 116 | feedback about the SNES version. 117 | 118 | -- 119 | Shay Green 120 | -------------------------------------------------------------------------------- /source/ntsc/sms_ntsc_config.h: -------------------------------------------------------------------------------- 1 | /* Configure library by modifying this file */ 2 | 3 | #include 4 | 5 | #ifndef SMS_NTSC_CONFIG_H 6 | #define SMS_NTSC_CONFIG_H 7 | 8 | /* Format of source pixels */ 9 | #define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB16 10 | /* #define SMS_NTSC_IN_FORMAT SMS_NTSC_RGB15 */ 11 | /* #define SMS_NTSC_IN_FORMAT SMS_NTSC_BGR12 */ 12 | 13 | /* The following affect the built-in blitter only; a custom blitter can 14 | handle things however it wants. */ 15 | 16 | /* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */ 17 | #define SMS_NTSC_OUT_DEPTH 16 18 | 19 | /* Type of input pixel values */ 20 | #define SMS_NTSC_IN_T uint16_t 21 | 22 | /* Each raw pixel input value is passed through this. You might want to mask 23 | the pixel index if you use the high bits as flags, etc. */ 24 | #define SMS_NTSC_ADJ_IN( in ) in 25 | 26 | /* For each pixel, this is the basic operation: 27 | output_color = SMS_NTSC_ADJ_IN( SMS_NTSC_IN_T ) */ 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /source/pio.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * I/O chip and peripheral emulation 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef PIO_H_ 26 | #define PIO_H_ 27 | 28 | #define SIO_TXFL (1 << 0) /* 1= Transmit buffer full */ 29 | #define SIO_RXRD (1 << 1) /* 1= Receive buffer full */ 30 | #define SIO_FRER (1 << 2) /* 1= Framing error occured */ 31 | 32 | #define MAX_DEVICE 2 33 | #define DEVICE_D0 (1 << 0) 34 | #define DEVICE_D1 (1 << 1) 35 | #define DEVICE_D2 (1 << 2) 36 | #define DEVICE_D3 (1 << 3) 37 | #define DEVICE_TL (1 << 4) 38 | #define DEVICE_TR (1 << 5) 39 | #define DEVICE_TH (1 << 6) 40 | #define DEVICE_ALL (DEVICE_D0 | DEVICE_D1 | DEVICE_D2 | DEVICE_D3 | DEVICE_TL | DEVICE_TR | DEVICE_TH) 41 | 42 | #define PIN_LVL_LO 0 /* Pin outputs 0V */ 43 | #define PIN_LVL_HI 1 /* Pin outputs +5V */ 44 | #define PIN_DIR_OUT 0 /* Pin is is an active driving output */ 45 | #define PIN_DIR_IN 1 /* Pin is in active-low input mode */ 46 | 47 | enum { 48 | PORT_A = 0, /* I/O port A */ 49 | PORT_B = 1 /* I/O port B */ 50 | }; 51 | 52 | enum { 53 | DEVICE_NONE = 0, /* No peripheral */ 54 | DEVICE_PAD2B = 1, /* Standard 2-button digital joystick/gamepad */ 55 | DEVICE_PADDLE = 2, /* Paddle controller; rotary dial with fire button */ 56 | DEVICE_LIGHTGUN = 3, /* Sega Light Phaser; Light Gun with trigger button */ 57 | DEVICE_SPORTSPAD = 4, /* Sports Pad controller; analog stick with 2 buttons */ 58 | }; 59 | 60 | /* Function prototypes */ 61 | extern void pio_init(void); 62 | extern void pio_reset(void); 63 | extern void pio_shutdown(void); 64 | extern void pio_ctrl_w(uint8_t data); 65 | extern uint8_t pio_port_r(int32_t offset); 66 | extern void sio_w(int32_t offset, uint8_t data); 67 | extern uint8_t sio_r(int32_t offset); 68 | extern uint8_t coleco_pio_r(int32_t port); 69 | 70 | #endif /* _PIO_H_ */ 71 | -------------------------------------------------------------------------------- /source/ports/350h/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 320 7 | #define HOST_HEIGHT_RESOLUTION 240 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | /* Input defines for custom remapping */ 15 | #define CONFIG_BUTTON_UP 0 16 | #define CONFIG_BUTTON_DOWN 1 17 | #define CONFIG_BUTTON_LEFT 2 18 | #define CONFIG_BUTTON_RIGHT 3 19 | #define CONFIG_BUTTON_BUTTON1 4 20 | #define CONFIG_BUTTON_BUTTON2 5 21 | #define CONFIG_BUTTON_START 6 22 | 23 | /* Colecovision specific */ 24 | #define CONFIG_BUTTON_DOLLARS 7 25 | #define CONFIG_BUTTON_ASTERISK 8 26 | #define CONFIG_BUTTON_ONE 9 27 | #define CONFIG_BUTTON_TWO 10 28 | #define CONFIG_BUTTON_THREE 11 29 | #define CONFIG_BUTTON_FOUR 12 30 | #define CONFIG_BUTTON_FIVE 13 31 | #define CONFIG_BUTTON_SIX 14 32 | #define CONFIG_BUTTON_SEVEN 15 33 | #define CONFIG_BUTTON_EIGHT 16 34 | #define CONFIG_BUTTON_NINE 17 35 | 36 | /* End of Defines for input remapping */ 37 | 38 | extern SDL_Surface* sms_bitmap; 39 | 40 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 41 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 42 | 43 | 44 | typedef struct { 45 | char gamename[256]; 46 | char sramdir[256]; 47 | char sramfile[256]; 48 | char stdir[256]; 49 | char scrdir[256]; 50 | char biosdir[256]; 51 | } gamedata_t; 52 | 53 | void smsp_state(uint8_t slot_number, uint8_t mode); 54 | 55 | #define SOUND_FREQUENCY 44100 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /source/ports/amini/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define VIDEO_WIDTH_SMS 256 7 | #define VIDEO_HEIGHT_SMS 192 8 | #define VIDEO_WIDTH_GG 160 9 | #define VIDEO_HEIGHT_GG 144 10 | 11 | extern SDL_Surface* sms_bitmap; 12 | 13 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 14 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 15 | 16 | typedef struct { 17 | char gamename[256]; 18 | char sramdir[256]; 19 | char sramfile[256]; 20 | char stdir[256]; 21 | char scrdir[256]; 22 | char biosdir[256]; 23 | } gamedata_t; 24 | 25 | void smsp_state(uint8_t slot_number, uint8_t mode); 26 | 27 | #define SOUND_FREQUENCY 44100 28 | #endif 29 | -------------------------------------------------------------------------------- /source/ports/bittboy/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HAS_FAST_FORWARD 1 7 | 8 | #define HOST_WIDTH_RESOLUTION 320 9 | #define HOST_HEIGHT_RESOLUTION 240 10 | 11 | #define VIDEO_WIDTH_SMS 256 12 | #define VIDEO_HEIGHT_SMS 192 13 | #define VIDEO_WIDTH_GG 160 14 | #define VIDEO_HEIGHT_GG 144 15 | 16 | /* Input defines for custom remapping */ 17 | #define CONFIG_BUTTON_UP 0 18 | #define CONFIG_BUTTON_DOWN 1 19 | #define CONFIG_BUTTON_LEFT 2 20 | #define CONFIG_BUTTON_RIGHT 3 21 | #define CONFIG_BUTTON_BUTTON1 4 22 | #define CONFIG_BUTTON_BUTTON2 5 23 | #define CONFIG_BUTTON_START 6 24 | 25 | #define CONFIG_BUTTON_FF 7 26 | 27 | /* Colecovision specific */ 28 | #define CONFIG_BUTTON_DOLLARS 8 29 | #define CONFIG_BUTTON_ASTERISK 9 30 | #define CONFIG_BUTTON_ONE 10 31 | #define CONFIG_BUTTON_TWO 11 32 | #define CONFIG_BUTTON_THREE 12 33 | #define CONFIG_BUTTON_FOUR 13 34 | #define CONFIG_BUTTON_FIVE 14 35 | #define CONFIG_BUTTON_SIX 15 36 | #define CONFIG_BUTTON_SEVEN 16 37 | #define CONFIG_BUTTON_EIGHT 17 38 | #define CONFIG_BUTTON_NINE 18 39 | 40 | /* End of Defines for input remapping */ 41 | 42 | extern SDL_Surface* sms_bitmap; 43 | 44 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 45 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 46 | 47 | 48 | typedef struct { 49 | char gamename[256]; 50 | char sramdir[256]; 51 | char sramfile[256]; 52 | char stdir[256]; 53 | char scrdir[256]; 54 | char biosdir[256]; 55 | } gamedata_t; 56 | 57 | void smsp_state(uint8_t slot_number, uint8_t mode); 58 | 59 | #define SOUND_FREQUENCY 44100 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /source/ports/fbdev/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #define HOST_WIDTH_RESOLUTION 320 5 | #define HOST_HEIGHT_RESOLUTION 240 6 | 7 | #define VIDEO_WIDTH_SMS 256 8 | #define VIDEO_HEIGHT_SMS 192 9 | #define VIDEO_WIDTH_GG 160 10 | #define VIDEO_HEIGHT_GG 144 11 | 12 | //#define NONBLOCKING_AUDIO 1 13 | 14 | #define LOCK_VIDEO 15 | #define UNLOCK_VIDEO 16 | 17 | typedef struct { 18 | char gamename[256]; 19 | char sramdir[256]; 20 | char sramfile[256]; 21 | char stdir[256]; 22 | char scrdir[256]; 23 | char biosdir[256]; 24 | } gamedata_t; 25 | 26 | void smsp_state(uint8_t slot_number, uint8_t mode); 27 | 28 | #define SOUND_FREQUENCY 44100 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /source/ports/funkey/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 240 7 | #define HOST_HEIGHT_RESOLUTION 240 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | /* Input defines for custom remapping */ 15 | #define CONFIG_BUTTON_UP 0 16 | #define CONFIG_BUTTON_DOWN 1 17 | #define CONFIG_BUTTON_LEFT 2 18 | #define CONFIG_BUTTON_RIGHT 3 19 | #define CONFIG_BUTTON_BUTTON1 4 20 | #define CONFIG_BUTTON_BUTTON2 5 21 | #define CONFIG_BUTTON_START 6 22 | 23 | /* Colecovision specific */ 24 | #define CONFIG_BUTTON_DOLLARS 7 25 | #define CONFIG_BUTTON_ASTERISK 8 26 | #define CONFIG_BUTTON_ONE 9 27 | #define CONFIG_BUTTON_TWO 10 28 | #define CONFIG_BUTTON_THREE 11 29 | #define CONFIG_BUTTON_FOUR 12 30 | #define CONFIG_BUTTON_FIVE 13 31 | #define CONFIG_BUTTON_SIX 14 32 | #define CONFIG_BUTTON_SEVEN 15 33 | #define CONFIG_BUTTON_EIGHT 16 34 | #define CONFIG_BUTTON_NINE 17 35 | 36 | /* End of Defines for input remapping */ 37 | 38 | extern SDL_Surface* sms_bitmap; 39 | 40 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 41 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 42 | 43 | 44 | typedef struct { 45 | char gamename[256]; 46 | char sramdir[256]; 47 | char sramfile[256]; 48 | char stdir[256]; 49 | char scrdir[256]; 50 | char biosdir[256]; 51 | } gamedata_t; 52 | 53 | void smsp_state(uint8_t slot_number, uint8_t mode); 54 | 55 | #define SOUND_FREQUENCY 44100 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /source/ports/gameta/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 480 7 | #define HOST_HEIGHT_RESOLUTION 320 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | extern SDL_Surface* sms_bitmap; 15 | 16 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 17 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 18 | 19 | typedef struct { 20 | char gamename[256]; 21 | char sramdir[256]; 22 | char sramfile[256]; 23 | char stdir[256]; 24 | char scrdir[256]; 25 | char biosdir[256]; 26 | } gamedata_t; 27 | 28 | void smsp_state(uint8_t slot_number, uint8_t mode); 29 | 30 | #define SOUND_FREQUENCY 44100 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /source/ports/gcw0/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 320 7 | #define HOST_HEIGHT_RESOLUTION 240 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | /* Input defines for custom remapping */ 15 | #define CONFIG_BUTTON_UP 0 16 | #define CONFIG_BUTTON_DOWN 1 17 | #define CONFIG_BUTTON_LEFT 2 18 | #define CONFIG_BUTTON_RIGHT 3 19 | #define CONFIG_BUTTON_BUTTON1 4 20 | #define CONFIG_BUTTON_BUTTON2 5 21 | #define CONFIG_BUTTON_START 6 22 | 23 | /* Colecovision specific */ 24 | #define CONFIG_BUTTON_DOLLARS 7 25 | #define CONFIG_BUTTON_ASTERISK 8 26 | #define CONFIG_BUTTON_ONE 9 27 | #define CONFIG_BUTTON_TWO 10 28 | #define CONFIG_BUTTON_THREE 11 29 | #define CONFIG_BUTTON_FOUR 12 30 | #define CONFIG_BUTTON_FIVE 13 31 | #define CONFIG_BUTTON_SIX 14 32 | #define CONFIG_BUTTON_SEVEN 15 33 | #define CONFIG_BUTTON_EIGHT 16 34 | #define CONFIG_BUTTON_NINE 17 35 | 36 | extern SDL_Surface* sms_bitmap; 37 | 38 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 39 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 40 | 41 | /* End of Defines for input remapping */ 42 | 43 | typedef struct { 44 | char gamename[128]; 45 | char sramdir[256]; 46 | char sramfile[256]; 47 | char stdir[256]; 48 | char scrdir[256]; 49 | char biosdir[256]; 50 | } gamedata_t; 51 | 52 | void smsp_state(uint8_t slot_number, uint8_t mode); 53 | 54 | #define SOUND_FREQUENCY 48000 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /source/ports/k3s/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define VIDEO_WIDTH_SMS 256 7 | #define VIDEO_HEIGHT_SMS 192 8 | #define VIDEO_WIDTH_GG 160 9 | #define VIDEO_HEIGHT_GG 144 10 | 11 | extern SDL_Surface* sms_bitmap; 12 | 13 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 14 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 15 | 16 | typedef struct { 17 | char gamename[256]; 18 | char sramdir[256]; 19 | char sramfile[256]; 20 | char stdir[256]; 21 | char scrdir[256]; 22 | char biosdir[256]; 23 | } gamedata_t; 24 | 25 | void smsp_state(uint8_t slot_number, uint8_t mode); 26 | 27 | #define SOUND_FREQUENCY 22050 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /source/ports/libretro/libretro-common/include/retro_common_api.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_common_api.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _LIBRETRO_COMMON_RETRO_COMMON_API_H 24 | #define _LIBRETRO_COMMON_RETRO_COMMON_API_H 25 | 26 | /* 27 | This file is designed to normalize the libretro-common compiling environment 28 | for public API headers. This should be leaner than a normal compiling environment, 29 | since it gets #included into other project's sources. 30 | */ 31 | 32 | /* ------------------------------------ */ 33 | 34 | /* 35 | Ordinarily we want to put #ifdef __cplusplus extern "C" in C library 36 | headers to enable them to get used by c++ sources. 37 | However, we want to support building this library as C++ as well, so a 38 | special technique is called for. 39 | */ 40 | 41 | #define RETRO_BEGIN_DECLS 42 | #define RETRO_END_DECLS 43 | 44 | #ifdef __cplusplus 45 | 46 | #ifdef CXX_BUILD 47 | /* build wants everything to be built as c++, so no extern "C" */ 48 | #else 49 | #undef RETRO_BEGIN_DECLS 50 | #undef RETRO_END_DECLS 51 | #define RETRO_BEGIN_DECLS extern "C" { 52 | #define RETRO_END_DECLS } 53 | #endif 54 | 55 | #else 56 | 57 | /* header is included by a C source file, so no extern "C" */ 58 | 59 | #endif 60 | 61 | /* 62 | IMO, this non-standard ssize_t should not be used. 63 | However, it's a good example of how to handle something like this. 64 | */ 65 | #ifdef _MSC_VER 66 | #ifndef HAVE_SSIZE_T 67 | #define HAVE_SSIZE_T 68 | #if defined(_WIN64) 69 | typedef __int64 ssize_t; 70 | #elif defined(_WIN32) 71 | typedef int ssize_t; 72 | #endif 73 | #endif 74 | #elif defined(__MACH__) 75 | #include 76 | #endif 77 | 78 | #ifdef _MSC_VER 79 | #if _MSC_VER >= 1800 80 | #include 81 | #else 82 | #ifndef PRId64 83 | #define PRId64 "I64d" 84 | #define PRIu64 "I64u" 85 | #define PRIuPTR "Iu" 86 | #endif 87 | #endif 88 | #else 89 | /* C++11 says this one isn't needed, but apparently (some versions of) mingw require it anyways */ 90 | /* https://stackoverflow.com/questions/8132399/how-to-printf-uint64-t-fails-with-spurious-trailing-in-format */ 91 | /* https://github.com/libretro/RetroArch/issues/6009 */ 92 | #ifndef __STDC_FORMAT_MACROS 93 | #define __STDC_FORMAT_MACROS 1 94 | #endif 95 | #include 96 | #endif 97 | #ifndef PRId64 98 | #error "inttypes.h is being screwy" 99 | #endif 100 | #define STRING_REP_INT64 "%" PRId64 101 | #define STRING_REP_UINT64 "%" PRIu64 102 | #define STRING_REP_USIZE "%" PRIuPTR 103 | 104 | /* 105 | I would like to see retro_inline.h moved in here; possibly boolean too. 106 | 107 | rationale: these are used in public APIs, and it is easier to find problems 108 | and write code that works the first time portably when theyre included uniformly 109 | than to do the analysis from scratch each time you think you need it, for each feature. 110 | 111 | Moreover it helps force you to make hard decisions: if you EVER bring in boolean.h, 112 | then you should pay the price everywhere, so you can see how much grief it will cause. 113 | 114 | Of course, another school of thought is that you should do as little damage as possible 115 | in as few places as possible... 116 | */ 117 | 118 | /* _LIBRETRO_COMMON_RETRO_COMMON_API_H */ 119 | #endif 120 | -------------------------------------------------------------------------------- /source/ports/libretro/libretro-common/include/retro_inline.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (retro_inline.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef __LIBRETRO_SDK_INLINE_H 24 | #define __LIBRETRO_SDK_INLINE_H 25 | 26 | #ifndef INLINE 27 | 28 | #if defined(_WIN32) || defined(__INTEL_COMPILER) 29 | #define INLINE __inline 30 | #elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L 31 | #define INLINE inline 32 | #elif defined(__GNUC__) 33 | #define INLINE __inline__ 34 | #else 35 | #define INLINE 36 | #endif 37 | 38 | #endif 39 | #endif 40 | -------------------------------------------------------------------------------- /source/ports/libretro/libretro-common/include/streams/memory_stream.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (memory_stream.h). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef _LIBRETRO_SDK_FILE_MEMORY_STREAM_H 24 | #define _LIBRETRO_SDK_FILE_MEMORY_STREAM_H 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | RETRO_BEGIN_DECLS 32 | 33 | typedef struct memstream memstream_t; 34 | 35 | memstream_t *memstream_open(unsigned writing); 36 | 37 | void memstream_close(memstream_t *stream); 38 | 39 | uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes); 40 | 41 | uint64_t memstream_write(memstream_t *stream, const void *data, uint64_t bytes); 42 | 43 | int memstream_getc(memstream_t *stream); 44 | 45 | void memstream_putc(memstream_t *stream, int c); 46 | 47 | char *memstream_gets(memstream_t *stream, char *buffer, size_t len); 48 | 49 | uint64_t memstream_pos(memstream_t *stream); 50 | 51 | void memstream_rewind(memstream_t *stream); 52 | 53 | int64_t memstream_seek(memstream_t *stream, int64_t offset, int whence); 54 | 55 | void memstream_set_buffer(uint8_t *buffer, uint64_t size); 56 | 57 | uint64_t memstream_get_last_size(void); 58 | 59 | uint64_t memstream_get_ptr(memstream_t *stream); 60 | 61 | RETRO_END_DECLS 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /source/ports/libretro/libretro-common/streams/memory_stream.c: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2010-2020 The RetroArch team 2 | * 3 | * --------------------------------------------------------------------------------------- 4 | * The following license statement only applies to this file (memory_stream.c). 5 | * --------------------------------------------------------------------------------------- 6 | * 7 | * Permission is hereby granted, free of charge, 8 | * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | /* TODO/FIXME - static globals */ 30 | static uint8_t* g_buffer = NULL; 31 | static uint64_t g_size = 0; 32 | static uint64_t last_file_size = 0; 33 | 34 | struct memstream 35 | { 36 | uint64_t size; 37 | uint64_t ptr; 38 | uint64_t max_ptr; 39 | uint8_t *buf; 40 | unsigned writing; 41 | }; 42 | 43 | void memstream_set_buffer(uint8_t *buffer, uint64_t size) 44 | { 45 | g_buffer = buffer; 46 | g_size = size; 47 | } 48 | 49 | uint64_t memstream_get_last_size(void) 50 | { 51 | return last_file_size; 52 | } 53 | 54 | memstream_t *memstream_open(unsigned writing) 55 | { 56 | memstream_t *stream; 57 | if (!g_buffer || !g_size) 58 | return NULL; 59 | 60 | stream = (memstream_t*)malloc(sizeof(*stream)); 61 | 62 | if (!stream) 63 | return NULL; 64 | 65 | stream->buf = g_buffer; 66 | stream->size = g_size; 67 | stream->ptr = 0; 68 | stream->max_ptr = 0; 69 | stream->writing = writing; 70 | 71 | g_buffer = NULL; 72 | g_size = 0; 73 | 74 | return stream; 75 | } 76 | 77 | void memstream_close(memstream_t *stream) 78 | { 79 | if (!stream) 80 | return; 81 | 82 | last_file_size = stream->writing ? stream->max_ptr : stream->size; 83 | free(stream); 84 | } 85 | 86 | uint64_t memstream_get_ptr(memstream_t *stream) 87 | { 88 | return stream->ptr; 89 | } 90 | 91 | uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes) 92 | { 93 | uint64_t avail = 0; 94 | 95 | if (!stream) 96 | return 0; 97 | 98 | avail = stream->size - stream->ptr; 99 | if (bytes > avail) 100 | bytes = avail; 101 | 102 | memcpy(data, stream->buf + stream->ptr, (size_t)bytes); 103 | stream->ptr += bytes; 104 | if (stream->ptr > stream->max_ptr) 105 | stream->max_ptr = stream->ptr; 106 | return bytes; 107 | } 108 | 109 | uint64_t memstream_write(memstream_t *stream, 110 | const void *data, uint64_t bytes) 111 | { 112 | uint64_t avail = 0; 113 | 114 | if (!stream) 115 | return 0; 116 | 117 | avail = stream->size - stream->ptr; 118 | if (bytes > avail) 119 | bytes = avail; 120 | 121 | memcpy(stream->buf + stream->ptr, data, (size_t)bytes); 122 | stream->ptr += bytes; 123 | if (stream->ptr > stream->max_ptr) 124 | stream->max_ptr = stream->ptr; 125 | return bytes; 126 | } 127 | 128 | int64_t memstream_seek(memstream_t *stream, int64_t offset, int whence) 129 | { 130 | uint64_t ptr; 131 | 132 | switch (whence) 133 | { 134 | case SEEK_SET: 135 | ptr = offset; 136 | break; 137 | case SEEK_CUR: 138 | ptr = stream->ptr + offset; 139 | break; 140 | case SEEK_END: 141 | ptr = (stream->writing ? stream->max_ptr : stream->size) + offset; 142 | break; 143 | default: 144 | return -1; 145 | } 146 | 147 | if (ptr <= stream->size) 148 | { 149 | stream->ptr = ptr; 150 | return 0; 151 | } 152 | 153 | return -1; 154 | } 155 | 156 | void memstream_rewind(memstream_t *stream) 157 | { 158 | memstream_seek(stream, 0L, SEEK_SET); 159 | } 160 | 161 | uint64_t memstream_pos(memstream_t *stream) 162 | { 163 | return stream->ptr; 164 | } 165 | 166 | char *memstream_gets(memstream_t *stream, char *buffer, size_t len) 167 | { 168 | return NULL; 169 | } 170 | 171 | int memstream_getc(memstream_t *stream) 172 | { 173 | int ret = 0; 174 | if (stream->ptr >= stream->size) 175 | return EOF; 176 | ret = stream->buf[stream->ptr++]; 177 | 178 | if (stream->ptr > stream->max_ptr) 179 | stream->max_ptr = stream->ptr; 180 | 181 | return ret; 182 | } 183 | 184 | void memstream_putc(memstream_t *stream, int c) 185 | { 186 | if (stream->ptr < stream->size) 187 | stream->buf[stream->ptr++] = c; 188 | 189 | if (stream->ptr > stream->max_ptr) 190 | stream->max_ptr = stream->ptr; 191 | } 192 | -------------------------------------------------------------------------------- /source/ports/libretro/libretro_core_options_intl.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBRETRO_CORE_OPTIONS_INTL_H__ 2 | #define LIBRETRO_CORE_OPTIONS_INTL_H__ 3 | 4 | #if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900) 5 | /* https://support.microsoft.com/en-us/kb/980263 */ 6 | #pragma execution_character_set("utf-8") 7 | #pragma warning(disable:4566) 8 | #endif 9 | 10 | #include 11 | 12 | /* 13 | ******************************** 14 | * VERSION: 1.3 15 | ******************************** 16 | * 17 | * - 1.3: Move translations to libretro_core_options_intl.h 18 | * - libretro_core_options_intl.h includes BOM and utf-8 19 | * fix for MSVC 2010-2013 20 | * - Added HAVE_NO_LANGEXTRA flag to disable translations 21 | * on platforms/compilers without BOM support 22 | * - 1.2: Use core options v1 interface when 23 | * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 24 | * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) 25 | * - 1.1: Support generation of core options v0 retro_core_option_value 26 | * arrays containing options with a single value 27 | * - 1.0: First commit 28 | */ 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* 35 | ******************************** 36 | * Core Option Definitions 37 | ******************************** 38 | */ 39 | 40 | /* RETRO_LANGUAGE_JAPANESE */ 41 | 42 | /* RETRO_LANGUAGE_FRENCH */ 43 | 44 | /* RETRO_LANGUAGE_SPANISH */ 45 | 46 | /* RETRO_LANGUAGE_GERMAN */ 47 | 48 | /* RETRO_LANGUAGE_ITALIAN */ 49 | 50 | /* RETRO_LANGUAGE_DUTCH */ 51 | 52 | /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */ 53 | 54 | /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */ 55 | 56 | /* RETRO_LANGUAGE_RUSSIAN */ 57 | 58 | /* RETRO_LANGUAGE_KOREAN */ 59 | 60 | /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */ 61 | 62 | /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */ 63 | 64 | /* RETRO_LANGUAGE_ESPERANTO */ 65 | 66 | /* RETRO_LANGUAGE_POLISH */ 67 | 68 | /* RETRO_LANGUAGE_VIETNAMESE */ 69 | 70 | /* RETRO_LANGUAGE_ARABIC */ 71 | 72 | /* RETRO_LANGUAGE_GREEK */ 73 | 74 | /* RETRO_LANGUAGE_TURKISH */ 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /source/ports/libretro/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #define SOUND_FREQUENCY 44100 5 | 6 | #define VIDEO_WIDTH_SMS 256 7 | #define VIDEO_HEIGHT_SMS 192 8 | #define VIDEO_WIDTH_GG 160 9 | #define VIDEO_HEIGHT_GG 144 10 | 11 | #define LOCK_VIDEO 12 | #define UNLOCK_VIDEO 13 | 14 | typedef struct { 15 | char gamename[256]; 16 | char biosdir[512]; 17 | } gamedata_t; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /source/ports/retrostone/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | extern SDL_Surface* sdl_screen; 7 | extern SDL_Surface* sms_bitmap; 8 | 9 | #define HOST_WIDTH_RESOLUTION 320 10 | #define HOST_HEIGHT_RESOLUTION 240 11 | 12 | #define REAL_WIDTH_RESOLUTION sdl_screen->w 13 | #define REAL_HEIGHT_RESOLUTION sdl_screen->h 14 | 15 | #define VIDEO_WIDTH_SMS 256 16 | #define VIDEO_HEIGHT_SMS 192 17 | #define VIDEO_WIDTH_GG 160 18 | #define VIDEO_HEIGHT_GG 144 19 | 20 | /* Input defines for custom remapping */ 21 | #define CONFIG_BUTTON_UP 0 22 | #define CONFIG_BUTTON_DOWN 1 23 | #define CONFIG_BUTTON_LEFT 2 24 | #define CONFIG_BUTTON_RIGHT 3 25 | #define CONFIG_BUTTON_BUTTON1 4 26 | #define CONFIG_BUTTON_BUTTON2 5 27 | #define CONFIG_BUTTON_START 6 28 | 29 | /* Colecovision specific */ 30 | #define CONFIG_BUTTON_DOLLARS 7 31 | #define CONFIG_BUTTON_ASTERISK 8 32 | #define CONFIG_BUTTON_ONE 9 33 | #define CONFIG_BUTTON_TWO 10 34 | #define CONFIG_BUTTON_THREE 11 35 | #define CONFIG_BUTTON_FOUR 12 36 | #define CONFIG_BUTTON_FIVE 13 37 | #define CONFIG_BUTTON_SIX 14 38 | #define CONFIG_BUTTON_SEVEN 15 39 | #define CONFIG_BUTTON_EIGHT 16 40 | #define CONFIG_BUTTON_NINE 17 41 | 42 | //#define VSYNC_SUPPORTED 1 43 | 44 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 45 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 46 | 47 | typedef struct { 48 | char gamename[256]; 49 | char sramdir[256]; 50 | char sramfile[256]; 51 | char stdir[256]; 52 | char scrdir[256]; 53 | char biosdir[256]; 54 | } gamedata_t; 55 | 56 | void smsp_state(uint8_t slot_number, uint8_t mode); 57 | 58 | #define SOUND_FREQUENCY 48000 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /source/ports/retrostone2/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 320 7 | #define HOST_HEIGHT_RESOLUTION 240 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | /* Input defines for custom remapping */ 15 | #define CONFIG_BUTTON_UP 0 16 | #define CONFIG_BUTTON_DOWN 1 17 | #define CONFIG_BUTTON_LEFT 2 18 | #define CONFIG_BUTTON_RIGHT 3 19 | #define CONFIG_BUTTON_BUTTON1 4 20 | #define CONFIG_BUTTON_BUTTON2 5 21 | #define CONFIG_BUTTON_START 6 22 | 23 | /* Colecovision specific */ 24 | #define CONFIG_BUTTON_DOLLARS 7 25 | #define CONFIG_BUTTON_ASTERISK 8 26 | #define CONFIG_BUTTON_ONE 9 27 | #define CONFIG_BUTTON_TWO 10 28 | #define CONFIG_BUTTON_THREE 11 29 | #define CONFIG_BUTTON_FOUR 12 30 | #define CONFIG_BUTTON_FIVE 13 31 | #define CONFIG_BUTTON_SIX 14 32 | #define CONFIG_BUTTON_SEVEN 15 33 | #define CONFIG_BUTTON_EIGHT 16 34 | #define CONFIG_BUTTON_NINE 17 35 | 36 | extern SDL_Surface* sms_bitmap; 37 | 38 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 39 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 40 | 41 | /* End of Defines for input remapping */ 42 | 43 | typedef struct { 44 | char gamename[128]; 45 | char sramdir[256]; 46 | char sramfile[256]; 47 | char stdir[256]; 48 | char scrdir[256]; 49 | char biosdir[256]; 50 | } gamedata_t; 51 | 52 | void smsp_state(uint8_t slot_number, uint8_t mode); 53 | 54 | #define SOUND_FREQUENCY 48000 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /source/ports/rs90/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 240 7 | #define HOST_HEIGHT_RESOLUTION 160 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | //#define VSYNC_SUPPORTED 1 15 | 16 | /* Input defines for custom remapping */ 17 | #define CONFIG_BUTTON_UP 0 18 | #define CONFIG_BUTTON_DOWN 1 19 | #define CONFIG_BUTTON_LEFT 2 20 | #define CONFIG_BUTTON_RIGHT 3 21 | #define CONFIG_BUTTON_BUTTON1 4 22 | #define CONFIG_BUTTON_BUTTON2 5 23 | #define CONFIG_BUTTON_START 6 24 | 25 | /* Colecovision specific */ 26 | #define CONFIG_BUTTON_DOLLARS 7 27 | #define CONFIG_BUTTON_ASTERISK 8 28 | #define CONFIG_BUTTON_ONE 9 29 | #define CONFIG_BUTTON_TWO 10 30 | #define CONFIG_BUTTON_THREE 11 31 | #define CONFIG_BUTTON_FOUR 12 32 | #define CONFIG_BUTTON_FIVE 13 33 | #define CONFIG_BUTTON_SIX 14 34 | #define CONFIG_BUTTON_SEVEN 15 35 | #define CONFIG_BUTTON_EIGHT 16 36 | #define CONFIG_BUTTON_NINE 17 37 | 38 | extern SDL_Surface* sms_bitmap; 39 | 40 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 41 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 42 | 43 | typedef struct { 44 | char gamename[256]; 45 | char sramdir[256]; 46 | char sramfile[256]; 47 | char stdir[256]; 48 | char scrdir[256]; 49 | char biosdir[256]; 50 | } gamedata_t; 51 | 52 | void smsp_state(uint8_t slot_number, uint8_t mode); 53 | 54 | #define SOUND_FREQUENCY 22050 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /source/ports/sdl/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 640 7 | #define HOST_HEIGHT_RESOLUTION 480 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | //#define VSYNC_SUPPORTED 1 15 | 16 | extern SDL_Surface* sms_bitmap; 17 | 18 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 19 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 20 | 21 | typedef struct { 22 | char gamename[256]; 23 | char sramdir[256]; 24 | char sramfile[256]; 25 | char stdir[256]; 26 | char scrdir[256]; 27 | char biosdir[256]; 28 | } gamedata_t; 29 | 30 | void smsp_state(uint8_t slot_number, uint8_t mode); 31 | 32 | #define SOUND_FREQUENCY 44100 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /source/ports/zipit/smsplus.h: -------------------------------------------------------------------------------- 1 | #ifndef SMSPLUS_H 2 | #define SMSPLUS_H 3 | 4 | #include 5 | 6 | #define HOST_WIDTH_RESOLUTION 320 7 | #define HOST_HEIGHT_RESOLUTION 240 8 | 9 | #define VIDEO_WIDTH_SMS 256 10 | #define VIDEO_HEIGHT_SMS 192 11 | #define VIDEO_WIDTH_GG 160 12 | #define VIDEO_HEIGHT_GG 144 13 | 14 | extern SDL_Surface* sms_bitmap; 15 | 16 | #define LOCK_VIDEO SDL_LockSurface(sms_bitmap); 17 | #define UNLOCK_VIDEO SDL_UnlockSurface(sms_bitmap); 18 | 19 | typedef struct { 20 | char gamename[256]; 21 | char sramdir[256]; 22 | char sramfile[256]; 23 | char stdir[256]; 24 | char scrdir[256]; 25 | char biosdir[256]; 26 | } gamedata_t; 27 | 28 | void smsp_state(uint8_t slot_number, uint8_t mode); 29 | 30 | #define SOUND_FREQUENCY 22050 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /source/render.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * VDP rendering core 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef RENDER_H_ 26 | #define RENDER_H_ 27 | 28 | #if defined(ABGR1555) 29 | /* Pack RGB data into a 16-bit RGB 5:5:5 format */ 30 | #define MAKE_PIXEL(r,g,b) (((b << 7) & 0x7c00) | ((g << 2) & 0x03E0) | ((r >> 3) & 0x001F)) 31 | #else 32 | /* Pack RGB data into a 16-bit RGB 5:6:5 format */ 33 | #define MAKE_PIXEL(r,g,b) (((r << 8) & 0xF800) | ((g << 3) & 0x07E0) | ((b >> 3) & 0x001F)) 34 | #endif 35 | 36 | 37 | /* Used for blanking a line in whole or in part */ 38 | #define BACKDROP_COLOR (0x10 | (vdp.reg[7] & 0x0F)) 39 | 40 | extern void (*render_bg)(int32_t line); 41 | extern void (*render_obj)(int32_t line); 42 | extern uint8_t *linebuf; 43 | extern uint8_t sms_cram_expand_table[4]; 44 | extern uint8_t gg_cram_expand_table[16]; 45 | extern uint8_t bg_name_dirty[0x200]; 46 | extern uint16_t bg_name_list[0x200]; 47 | extern uint16_t bg_list_index; 48 | 49 | extern void render_shutdown(void); 50 | extern void render_init(void); 51 | extern void render_reset(void); 52 | extern void render_line(int32_t line); 53 | extern void render_bg_sms(int32_t line); 54 | extern void render_obj_sms(int32_t line); 55 | extern void palette_sync(int32_t index); 56 | 57 | #endif /* _RENDER_H_ */ 58 | -------------------------------------------------------------------------------- /source/scale2x/scale2x.c: -------------------------------------------------------------------------------- 1 | /* scaler.c: code for selecting (etc) scalers 2 | * Copyright (C) 2003 Fredrick Meunier, Philip Kendall 3 | * Copyright (c) 2015 Sergio Baldoví 4 | * 5 | * $Id: scaler.c 5432 2016-05-01 04:16:09Z fredm $ 6 | * 7 | * Originally taken from ScummVM - Scumm Interpreter 8 | * Copyright (C) 2001 Ludvig Strigeus 9 | * Copyright (C) 2001/2002 The ScummVM project 10 | * 11 | * HQ2x and HQ3x scalers taken from HiEnd3D Demos (http://www.hiend3d.com) 12 | * Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) 13 | * 14 | * This program is free software; you can redistribute it and/or 15 | * modify it under the terms of the GNU General Public License 16 | * as published by the Free Software Foundation; either version 2 17 | * of the License, or (at your option) any later version. 18 | 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | 24 | * You should have received a copy of the GNU General Public License along 25 | * with this program; if not, write to the Free Software Foundation, Inc., 26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 27 | * 28 | */ 29 | #include "scale2x.h" 30 | 31 | /* No license ? Scale2x was licensed under the GPLv2 and this code was found among in GPLv2 licensed code. 32 | * I had to make some minor modifications to it and the code is fairly small but i think we should be good. */ 33 | 34 | void scale2x(uint16_t* restrict srcpixels, uint16_t* restrict dstpixels, const uint32_t srcpitch, const uint32_t dstpitch, const uint32_t width, uint32_t height) 35 | { 36 | uint32_t nextlineSrc = srcpitch / sizeof(uint16_t); 37 | uint16_t* restrict p = (uint16_t* restrict)srcpixels; 38 | 39 | uint32_t nextlineDst = dstpitch / sizeof(uint16_t); 40 | uint16_t* restrict q = (uint16_t* restrict)dstpixels; 41 | 42 | uint32_t i, j; 43 | uint16_t B, D, E, F, H; 44 | 45 | while(height--) 46 | { 47 | j = 0; 48 | for(i = 0; i < width; ++i, j += 2) { 49 | B = *(p + i - nextlineSrc); 50 | D = *(p + i - 1); 51 | E = *(p + i); 52 | F = *(p + i + 1); 53 | H = *(p + i + nextlineSrc); 54 | 55 | *(q + j) = (uint16_t)(D == B && B != F && D != H ? D : E); 56 | *(q + j + 1) = (uint16_t)(B == F && B != D && F != H ? F : E); 57 | *(q + j + nextlineDst) = (uint16_t)(D == H && D != B && H != F ? D : E); 58 | *(q + j + nextlineDst + 1) = (uint16_t)(H == F && D != H && B != F ? F : E); 59 | } 60 | p += nextlineSrc; 61 | q += nextlineDst << 1; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /source/scale2x/scale2x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Advance project. 3 | * 4 | * Copyright (C) 2003, 2004, 2008 Andrea Mazzoleni 5 | * 6 | * This program 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 | * This program 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 this program; if not, write to the Free Software 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * 20 | * In addition, as a special exception, Andrea Mazzoleni 21 | * gives permission to link the code of this program with 22 | * the MAME library (or with modified versions of MAME that use the 23 | * same license as MAME), and distribute linked combinations including 24 | * the two. You must obey the GNU General Public License in all 25 | * respects for all of the code used other than MAME. If you modify 26 | * this file, you may extend this exception to your version of the 27 | * file, but you are not obligated to do so. If you do not wish to 28 | * do so, delete this exception statement from your version. 29 | */ 30 | 31 | #ifndef SCALE2X_H 32 | #define SCALE2X_H 33 | #include 34 | void scale2x(uint16_t* restrict srcpixels, uint16_t* restrict dstpixels, const uint32_t srcpitch, const uint32_t dstpitch, const uint32_t width, uint32_t height); 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /source/scalers/scaler.h: -------------------------------------------------------------------------------- 1 | #ifndef SCALER_H 2 | #define SCALER_H 3 | 4 | #include 5 | 6 | /* Generic */ 7 | extern void bitmap_scale(uint32_t startx, uint32_t starty, uint32_t viswidth, uint32_t visheight, uint32_t newwidth, uint32_t newheight,uint32_t pitchsrc,uint32_t pitchdest, uint16_t* restrict src, uint16_t* restrict dst); 8 | 9 | /* OpenDingux-like devices (320x240) */ 10 | extern void upscale_160x144_to_320x240(uint32_t* restrict dst, uint32_t* restrict src); 11 | extern void upscale_SMS_to_320x240(uint32_t* restrict dst, uint32_t* restrict src, uint32_t height_scale); 12 | 13 | /* Arcade Mini/PAP K3 Plus/PSP-Like scalers */ 14 | extern void upscale_160x144_to_320x272_for_480x272(uint32_t* restrict dst, uint32_t* restrict src); 15 | extern void upscale_160x144_to_480x272(uint32_t* restrict dst, uint32_t* restrict src); 16 | extern void upscale_256xXXX_to_384x272_for_480x272(uint32_t* restrict dst, uint32_t* restrict src, uint32_t height); 17 | extern void upscale_256xXXX_to_480x272(uint32_t* restrict dst, uint32_t* restrict src, uint32_t height); 18 | 19 | /* PAP Gameta II scalers */ 20 | void upscale_160x144_to_320x320_for_480x320(uint32_t* restrict dst, uint32_t* restrict src); 21 | void upscale_160x144_to_480x320(uint32_t* restrict dst, uint32_t* restrict src); 22 | void upscale_256xXXX_to_384x320_for_480x320(uint32_t* restrict dst, uint32_t* restrict src, uint32_t height); 23 | void upscale_256xXXX_to_480x320(uint32_t* restrict dst, uint32_t* restrict src, uint32_t height); 24 | 25 | // RS-90 Scaler 26 | //for GG 27 | void upscale_160x144_to_212x160(uint16_t* restrict src, uint16_t* restrict dst); 28 | void upscale_160x144_to_212x144(uint16_t* restrict src, uint16_t* restrict dst); 29 | void upscale_160x144_to_240x160(uint16_t* restrict src, uint16_t* restrict dst); 30 | //for SMS 31 | void downscale_240x192to240x160(uint32_t* restrict src, uint32_t* restrict dst); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /source/shared.h: -------------------------------------------------------------------------------- 1 | #ifndef SHARED_H_ 2 | #define SHARED_H_ 3 | 4 | /* Convenience stuff... */ 5 | #undef INLINE 6 | #if __STDC_VERSION__ >= 199901L 7 | # define INLINE static inline 8 | #elif defined(__GNUC__) || defined(__GNUG__) 9 | # define INLINE static __inline__ 10 | #else 11 | # define INLINE static 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #ifndef NGC 24 | #ifndef PATH_MAX 25 | #ifdef MAX_PATH 26 | #define PATH_MAX MAX_PATH 27 | #else 28 | #define PATH_MAX 1024 29 | #endif 30 | #endif 31 | #endif 32 | 33 | #include "z80.h" 34 | #include "sms.h" 35 | #include "pio.h" 36 | #include "memz80.h" 37 | #include "vdp.h" 38 | #include "render.h" 39 | #include "tms.h" 40 | #include "sn76489.h" 41 | #include "ym2413.h" 42 | #include "fmintf.h" 43 | #include "sound.h" 44 | #include "system.h" 45 | #include "loadrom.h" 46 | #include "config.h" 47 | #include "state.h" 48 | #include "z80_wrap.h" 49 | #include "sound_output.h" 50 | 51 | /* For lock and unlocking screen surface */ 52 | #include "smsplus.h" 53 | 54 | #ifndef NOZIP_SUPPORT 55 | #include "miniz.h" 56 | #include "fileio.h" 57 | #include "unzip.h" 58 | #endif 59 | 60 | #ifdef SCALE2X_UPSCALER 61 | #include "scale2x.h" 62 | #endif 63 | 64 | #endif /* _SHARED_H_ */ 65 | -------------------------------------------------------------------------------- /source/sms.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Sega Master System console emulation 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef SMS_H_ 26 | #define SMS_H_ 27 | 28 | #define CYCLES_PER_LINE 228 29 | 30 | enum { 31 | SLOT_BIOS = 0, 32 | SLOT_CARD = 1, 33 | SLOT_CART = 2, 34 | SLOT_EXP = 3 35 | }; 36 | 37 | enum { 38 | MAPPER_NONE = 0, 39 | MAPPER_SEGA = 1, 40 | MAPPER_CODIES = 2, 41 | MAPPER_KOREA = 3, 42 | MAPPER_KOREA_MSX = 4, 43 | MAPPER_4PAK = 5 44 | }; 45 | 46 | enum { 47 | DISPLAY_NTSC = 0, 48 | DISPLAY_PAL = 1 49 | }; 50 | 51 | enum { 52 | FPS_NTSC = 60, 53 | FPS_PAL = 50 54 | }; 55 | 56 | enum { 57 | CLOCK_NTSC = 3579545, 58 | CLOCK_PAL = 3546895, 59 | CLOCK_NTSC_SMS1 = 3579527 60 | }; 61 | 62 | enum { 63 | CONSOLE_COLECO = 0x10, 64 | CONSOLE_SG1000 = 0x11, 65 | CONSOLE_SC3000 = 0x12, 66 | CONSOLE_SF7000 = 0x13, 67 | 68 | CONSOLE_SORDM5 = 0x14, 69 | 70 | CONSOLE_SMS = 0x20, 71 | CONSOLE_SMS2 = 0x21, 72 | 73 | CONSOLE_GG = 0x40, 74 | CONSOLE_GGMS = 0x41, 75 | 76 | CONSOLE_MD = 0x80, 77 | CONSOLE_MDPBC = 0x81, 78 | CONSOLE_GEN = 0x82, 79 | CONSOLE_GENPBC = 0x83 80 | }; 81 | 82 | enum { 83 | FM_NOT_COMPATIBLE = 0, 84 | FM_COMPATIBLE = 1 85 | }; 86 | 87 | #define HWTYPE_TMS CONSOLE_COLECO 88 | #define HWTYPE_SMS CONSOLE_SMS 89 | #define HWTYPE_GG CONSOLE_GG 90 | #define HWTYPE_MD CONSOLE_MD 91 | 92 | #define IS_TMS (sms.console & HWTYPE_TMS) 93 | #define IS_SMS (sms.console & HWTYPE_SMS) 94 | #define IS_GG (sms.console & HWTYPE_GG) 95 | #define IS_MD (sms.console & HWTYPE_MD) 96 | 97 | enum { 98 | TERRITORY_DOMESTIC = 0, 99 | TERRITORY_EXPORT = 1 100 | }; 101 | 102 | /* SMS context */ 103 | typedef struct 104 | { 105 | struct 106 | { 107 | uint8_t pdr; /* Parallel data register */ 108 | uint8_t ddr; /* Data direction register */ 109 | uint8_t txdata; /* Transmit data buffer */ 110 | uint8_t rxdata; /* Receive data buffer */ 111 | uint8_t sctrl; /* Serial mode control and status */ 112 | } sio; 113 | uint8_t wram[0x2000]; 114 | uint8_t paused; 115 | uint8_t save; 116 | uint8_t territory; 117 | uint8_t console; 118 | uint8_t display; 119 | uint8_t glasses_3d; 120 | uint8_t hlatch; 121 | uint8_t memctrl; 122 | uint8_t ioctrl; 123 | uint8_t irq; 124 | uint8_t gun_offset; 125 | uint32_t fm_detect; 126 | int32_t use_fm; 127 | uint8_t device[2]; 128 | } sms_t; 129 | 130 | /* BIOS ROM */ 131 | typedef struct 132 | { 133 | uint8_t *rom; 134 | uint8_t enabled; 135 | /* We need to use an unsigned short for pages, as Bad Apple SMS requires it !*/ 136 | uint16_t pages; 137 | uint8_t fcr[4]; 138 | } bios_t; 139 | 140 | typedef struct 141 | { 142 | uint8_t *rom; 143 | /* We need to use an unsigned short for pages, as Bad Apple SMS requires it !*/ 144 | uint16_t pages; 145 | uint8_t *fcr; 146 | uint8_t mapper; 147 | } slot_t; 148 | 149 | typedef struct 150 | { 151 | uint8_t rom[0x2000]; /* BIOS ROM */ 152 | uint8_t pio_mode; /* PIO mode */ 153 | uint8_t keypad[2]; /* Keypad inputs */ 154 | } t_coleco; 155 | 156 | /* Global data */ 157 | extern sms_t sms; 158 | extern bios_t bios; 159 | extern slot_t slot; 160 | extern t_coleco coleco; 161 | extern uint8_t dummy_write[0x400]; 162 | extern uint8_t dummy_read[0x400]; 163 | 164 | /* Function prototypes */ 165 | extern void sms_init(void); 166 | extern void sms_reset(void); 167 | extern void sms_shutdown(void); 168 | extern void mapper_reset(void); 169 | extern void mapper_8k_w(uint16_t address, uint8_t data); 170 | extern void mapper_16k_w(uint16_t address, uint8_t data); 171 | extern int32_t sms_irq_callback(int32_t param); 172 | 173 | extern uint8_t *MMapPtrs[64]; 174 | 175 | #endif /* _SMS_H_ */ 176 | -------------------------------------------------------------------------------- /source/sound/crabemu_sn76489/sn76489.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CrabEmu. 3 | 4 | Copyright (C) 2005, 2006, 2007, 2008, 2012 Lawrence Sebald 5 | 6 | CrabEmu is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License version 2 8 | as published by the Free Software Foundation. 9 | 10 | CrabEmu 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 CrabEmu; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef SN76489_H 21 | #define SN76489_H 22 | 23 | #include 24 | 25 | typedef struct sn76489_struct { 26 | uint8_t volume[4]; 27 | uint16_t tone[3]; 28 | uint8_t noise; 29 | 30 | uint16_t noise_shift; 31 | uint16_t noise_bits; 32 | uint16_t noise_tapped; 33 | 34 | int8_t tone_state[4]; 35 | 36 | uint8_t latched_reg; 37 | 38 | float counter[4]; 39 | 40 | uint8_t enabled_channels; 41 | 42 | uint8_t output_channels; 43 | uint32_t channel_masks[2][4]; 44 | 45 | float clocks_per_sample; 46 | } sn76489_t; 47 | 48 | #define LATCH_TONE0 0x00 49 | #define LATCH_TONE1 0x20 50 | #define LATCH_TONE2 0x40 51 | #define LATCH_NOISE 0x60 52 | 53 | #define LATCH_VOL0 0x10 54 | #define LATCH_VOL1 0x30 55 | #define LATCH_VOL2 0x50 56 | #define LATCH_VOL3 0x70 57 | 58 | #define ENABLE_TONE0 0x01 59 | #define ENABLE_TONE1 0x02 60 | #define ENABLE_TONE2 0x04 61 | #define ENABLE_NOISE 0x08 62 | 63 | /* Channel outputs */ 64 | #define TONE0_RIGHT 0x01 65 | #define TONE1_RIGHT 0x02 66 | #define TONE2_RIGHT 0x04 67 | #define NOISE_RIGHT 0x08 68 | #define TONE0_LEFT 0x10 69 | #define TONE1_LEFT 0x20 70 | #define TONE2_LEFT 0x40 71 | #define NOISE_LEFT 0x80 72 | 73 | /* Default settings */ 74 | #define SN76489_NOISE_TAPPED_NORMAL 0x0006 75 | #define SN76489_NOISE_BITS_NORMAL 15 76 | 77 | #define SN76489_NOISE_TAPPED_SMS 0x0009 78 | #define SN76489_NOISE_BITS_SMS 16 79 | 80 | #define SN76489_NOISE_TAPPED_SG1000 SN76489_NOISE_TAPPED_NORMAL 81 | #define SN76489_NOISE_BITS_SG1000 SN76489_NOISE_BITS_NORMAL 82 | 83 | uint32_t sn76489_init(sn76489_t *psg, float clock, float sample_rate, uint16_t noise_bits, uint16_t tapped); 84 | uint32_t sn76489_reset(sn76489_t *psg, float clock, float sample_rate, uint16_t noise_bits, uint16_t tapped); 85 | void sn76489_write(sn76489_t *psg, uint8_t byte); 86 | 87 | void sn76489_execute_samples(sn76489_t *psg, int16_t *bufl, int16_t *bufr, uint32_t samples) ; 88 | void sn76489_set_output_channels(sn76489_t *psg, uint8_t data); 89 | int32_t SN76489_GetContextSize(void); 90 | void SN76489_SetContext(uint8_t* data); 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /source/sound/fmintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | fmintf.c -- 3 | Interface to YM2413 emulators emulators. 4 | */ 5 | #include "shared.h" 6 | 7 | static FM_Context fm_context; 8 | static YM2413 *fmm; 9 | 10 | /* Only the 1st Master System supports FM sound. Because it is still processed even though it's not used, 11 | * don't process FM sound if it can't be used in any way. 12 | */ 13 | static uint32_t isfm_used = 0; 14 | 15 | void FM_Init(void) 16 | { 17 | isfm_used = 0; 18 | fmm = ym2413_init(snd.fm_clock, snd.sample_rate); 19 | ym2413_reset(fmm); 20 | } 21 | 22 | 23 | void FM_Shutdown(void) 24 | { 25 | isfm_used = 0; 26 | ym2413_shutdown(fmm); 27 | } 28 | 29 | 30 | void FM_Reset(void) 31 | { 32 | isfm_used = 0; 33 | ym2413_reset(fmm); 34 | } 35 | 36 | 37 | void FM_Update(int16_t **buffer, int32_t length) 38 | { 39 | if (isfm_used) ym2413_update(fmm, buffer, length); 40 | } 41 | 42 | void FM_WriteReg(uint8_t reg, uint8_t data) 43 | { 44 | FM_Write(0, reg); 45 | FM_Write(1, data); 46 | } 47 | 48 | void FM_Write(uint32_t offset, uint8_t data) 49 | { 50 | if(offset & 1) 51 | { 52 | fm_context.reg[ fm_context.latch ] = data; 53 | } 54 | else 55 | { 56 | fm_context.latch = data; 57 | } 58 | 59 | ym2413_write(fmm, offset & 1, data); 60 | isfm_used = 1; 61 | } 62 | 63 | void FM_GetContext(uint8_t *data) 64 | { 65 | memcpy(data, &fm_context, sizeof(FM_Context)); 66 | } 67 | 68 | void FM_SetContext(uint8_t *data) 69 | { 70 | uint8_t i; 71 | uint8_t *reg = fm_context.reg; 72 | 73 | memcpy(&fm_context, data, sizeof(FM_Context)); 74 | 75 | /* If we are loading a save state, we want to update the ym2413_ context 76 | but not actually write to the current ym2413_ emulator. */ 77 | if(!snd.enabled || !sms.use_fm) 78 | return; 79 | 80 | FM_Write(0, 0x0E); 81 | FM_Write(1, reg[0x0E]); 82 | 83 | for(i = 0x00; i <= 0x07; i++) 84 | { 85 | FM_Write(0, i); 86 | FM_Write(1, reg[i]); 87 | } 88 | 89 | for(i = 0x10; i <= 0x18; i++) 90 | { 91 | FM_Write(0, i); 92 | FM_Write(1, reg[i]); 93 | } 94 | 95 | for(i = 0x20; i <= 0x28; i++) 96 | { 97 | FM_Write(0, i); 98 | FM_Write(1, reg[i]); 99 | } 100 | 101 | for(i = 0x30; i <= 0x38; i++) 102 | { 103 | FM_Write(0, i); 104 | FM_Write(1, reg[i]); 105 | } 106 | 107 | FM_Write(0, fm_context.latch); 108 | } 109 | 110 | uint32_t FM_GetContextSize(void) 111 | { 112 | return sizeof(FM_Context); 113 | } 114 | 115 | uint8_t *FM_GetContextPtr(void) 116 | { 117 | return (uint8_t *)&fm_context; 118 | } 119 | 120 | uint32_t YM2413_GetContextSize(void) 121 | { 122 | return sizeof(YM2413); 123 | } 124 | 125 | uint8_t *YM2413_GetContextPtr(void) 126 | { 127 | return (uint8_t *)fmm; 128 | } 129 | -------------------------------------------------------------------------------- /source/sound/fmintf.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FMINTF_H_ 3 | #define FMINTF_H_ 4 | 5 | enum 6 | { 7 | SND_NULL, 8 | SND_EMU2413, /* Mitsutaka Okazaki's YM2413 emulator, removed until i can switch to upstream due to unclear license */ 9 | SND_YM2413 /* Jarek Burczynski's YM2413 emulator */ 10 | }; 11 | 12 | typedef struct 13 | { 14 | uint8_t latch; 15 | uint8_t reg[0x40]; 16 | } FM_Context; 17 | 18 | /* Function prototypes */ 19 | void FM_Init(void); 20 | void FM_Shutdown(void); 21 | void FM_Reset(void); 22 | void FM_Update(int16_t **buffer, int32_t length); 23 | void FM_Write(uint32_t offset, uint8_t data); 24 | void FM_GetContext(uint8_t *data); 25 | void FM_SetContext(uint8_t *data); 26 | uint32_t FM_GetContextSize(void); 27 | uint8_t *FM_GetContextPtr(void); 28 | uint32_t YM2413_GetContextSize(void); 29 | uint8_t *YM2413_GetContextPtr(void); 30 | void FM_WriteReg(uint8_t reg, uint8_t data); 31 | 32 | #endif /* FMINTF_H_ */ 33 | -------------------------------------------------------------------------------- /source/sound/mame_sn76489/sn76489.h: -------------------------------------------------------------------------------- 1 | #ifndef SN76489_DEFINE 2 | #define SN76489_DEFINE 3 | 4 | #include 5 | 6 | typedef struct sn76489_struct 7 | { 8 | uint32_t m_feedback_mask; 9 | uint8_t m_noisetap1; 10 | uint8_t m_noisetap2; 11 | uint8_t m_negate; 12 | uint8_t m_stereo; 13 | uint8_t m_clockdivider; 14 | uint8_t m_sega_style_psg; 15 | 16 | uint16_t m_clock_divider; 17 | uint16_t m_whitenoise_tap1; 18 | uint16_t m_whitenoise_tap2; 19 | 20 | uint8_t m_last_register; 21 | 22 | uint8_t m_ready_state; 23 | 24 | int m_cycles_to_ready; 25 | int m_stereo_mask; 26 | int m_current_clock ; 27 | 28 | int32_t m_output[4]; 29 | int32_t m_period[4]; 30 | int32_t m_count[4]; 31 | int32_t m_register[8]; 32 | int32_t m_volume[4]; 33 | int32_t m_vol_table[16]; 34 | 35 | int32_t m_RNG; 36 | 37 | int32_t m_clocks_per_sample; 38 | } sn76489_t; 39 | 40 | extern sn76489_t PSG; 41 | 42 | extern void SN76489_Init(uint32_t machine, uint32_t clock, uint32_t sample_rate); 43 | extern void SN76489_GGStereoWrite(uint8_t st); 44 | extern void SN76489_write(uint8_t data); 45 | 46 | 47 | extern void SN76489_Update(int16_t** outputs, int samples); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /source/sound/maxim_sn76489/sn76489.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SN76489_H_ 3 | #define SN76489_H_ 4 | 5 | #define MAX_SN76489 1 6 | 7 | /* 8 | More testing is needed to find and confirm feedback patterns for 9 | SN76489 variants and compatible chips. 10 | */ 11 | enum feedback_patterns { 12 | FB_BBCMICRO = 0x8005, /* Texas Instruments TMS SN76489N (original) from BBC Micro computer */ 13 | FB_SC3000 = 0x0006, /* Texas Instruments TMS SN76489AN (rev. A) from SC-3000H computer */ 14 | FB_SEGAVDP = 0x0009, /* SN76489 clone in Sega's VDP chips (315-5124, 315-5246, 315-5313, Game Gear) */ 15 | }; 16 | 17 | enum volume_modes { 18 | VOL_TRUNC = 0, /* Volume levels 13-15 are identical */ 19 | VOL_FULL = 1, /* Volume levels 13-15 are unique */ 20 | }; 21 | 22 | enum boost_modes { 23 | BOOST_OFF = 0, /* Regular noise channel volume */ 24 | BOOST_ON = 1, /* Doubled noise channel volume */ 25 | }; 26 | 27 | enum mute_values { 28 | MUTE_ALLOFF = 0, /* All channels muted */ 29 | MUTE_TONE1 = 1, /* Tone 1 mute control */ 30 | MUTE_TONE2 = 2, /* Tone 2 mute control */ 31 | MUTE_TONE3 = 4, /* Tone 3 mute control */ 32 | MUTE_NOISE = 8, /* Noise mute control */ 33 | MUTE_ALLON = 15, /* All channels enabled */ 34 | }; 35 | 36 | typedef struct 37 | { 38 | /* expose this for inspection/modification for channel muting */ 39 | int32_t Mute; 40 | int32_t BoostNoise; 41 | int32_t VolumeArray; 42 | 43 | /* Variables */ 44 | float Clock; 45 | float dClock; 46 | int32_t PSGStereo; 47 | int32_t NumClocksForSample; 48 | int32_t WhiteNoiseFeedback; 49 | 50 | /* PSG registers: */ 51 | int32_t Registers[8]; /* Tone, vol x4 */ 52 | int32_t LatchedRegister; 53 | int32_t NoiseShiftRegister; 54 | int32_t NoiseFreq; /* Noise channel signal generator frequency */ 55 | 56 | /* Output calculation variables */ 57 | int32_t ToneFreqVals[4]; /* Frequency register values (counters) */ 58 | int8_t ToneFreqPos[4]; /* Frequency channel flip-flops */ 59 | int32_t Channels[4]; /* Value of each channel, before stereo is applied */ 60 | /* It was using LONG_MIN in sn76489.c before but that requires a 64-bits variable so i changed it to INT_MIN instead. So far, i haven't noticed any regressions yet. - Gameblabla */ 61 | int32_t IntermediatePos[4]; /* intermediate values used at boundaries between + and - */ 62 | 63 | } SN76489_Context; 64 | 65 | /* Function prototypes */ 66 | void SN76489_Init(int32_t which, int32_t PSGClockValue, int32_t SamplingRate); 67 | void SN76489_Reset(int32_t which); 68 | void SN76489_Shutdown(void); 69 | void SN76489_Config(int32_t which, int32_t mute, int32_t boost, int32_t volume, int32_t feedback); 70 | void SN76489_SetContext(int32_t which, uint8_t *data); 71 | void SN76489_GetContext(int32_t which, uint8_t *data); 72 | uint8_t *SN76489_GetContextPtr(int32_t which); 73 | uint32_t SN76489_GetContextSize(void); 74 | void SN76489_Write(int32_t which, int32_t data); 75 | void SN76489_GGStereoWrite(int32_t which, int32_t data); 76 | void SN76489_Update(int32_t which, int16_t **buffer, int32_t length); 77 | 78 | #endif /* SN76489_H_ */ 79 | 80 | -------------------------------------------------------------------------------- /source/sound/sound.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Sound emulation. 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef SOUND_H_ 26 | #define SOUND_H_ 27 | 28 | enum { 29 | STREAM_PSG_L, /* PSG left channel */ 30 | STREAM_PSG_R, /* PSG right channel */ 31 | STREAM_FM_MO, /* YM2413 melody channel */ 32 | STREAM_FM_RO, /* YM2413 rhythm channel */ 33 | STREAM_MAX /* Total # of sound streams */ 34 | }; 35 | 36 | /* Sound emulation structure */ 37 | typedef struct 38 | { 39 | void (*mixer_callback)(int16_t *output, int32_t length); 40 | int16_t *output; 41 | int16_t *stream[STREAM_MAX]; 42 | int32_t fm_which; 43 | int32_t enabled; 44 | int32_t fps; 45 | uint32_t buffer_size; 46 | int32_t sample_count; 47 | int32_t sample_rate; 48 | int32_t done_so_far; 49 | int32_t fm_clock; 50 | int32_t psg_clock; 51 | } snd_t; 52 | 53 | 54 | /* Global data */ 55 | extern snd_t snd; 56 | 57 | /* Function prototypes */ 58 | void psg_write(int32_t data); 59 | void psg_stereo_w(int32_t data); 60 | uint32_t fmunit_detect_r(void); 61 | void fmunit_detect_w(uint32_t data); 62 | void fmunit_write(uint32_t offset, uint8_t data); 63 | uint32_t SMSPLUS_sound_init(void); 64 | void SMSPLUS_sound_shutdown(void); 65 | void SMSPLUS_sound_reset(void); 66 | void SMSPLUS_sound_update(int32_t line); 67 | void SMSPLUS_sound_mixer_callback(int16_t *output, int32_t length); 68 | 69 | #endif /* SOUND_H_ */ 70 | -------------------------------------------------------------------------------- /source/sound_output/alsa/sound_output_alsa.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Alsa output sound code. 3 | * License : MIT 4 | * See docs/MIT_license.txt for more information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include "smsplus.h" 11 | #include "sound_output.h" 12 | #include "shared.h" 13 | 14 | static snd_pcm_t *handle; 15 | 16 | void Sound_Init(void) 17 | { 18 | snd_pcm_hw_params_t *params; 19 | uint32_t val; 20 | int32_t dir = -1; 21 | snd_pcm_uframes_t frames; 22 | 23 | /* Open PCM device for playback. */ 24 | int32_t rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); 25 | 26 | #ifdef ZIPIT_PORT 27 | if (rc < 0) 28 | rc = snd_pcm_open(&handle, "plughw:Z2,0,0", SND_PCM_STREAM_PLAYBACK, 0); 29 | #endif 30 | 31 | if (rc < 0) 32 | rc = snd_pcm_open(&handle, "plughw:0,0,0", SND_PCM_STREAM_PLAYBACK, 0); 33 | 34 | if (rc < 0) 35 | rc = snd_pcm_open(&handle, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0); 36 | 37 | if (rc < 0) 38 | rc = snd_pcm_open(&handle, "plughw:1,0,0", SND_PCM_STREAM_PLAYBACK, 0); 39 | 40 | if (rc < 0) 41 | rc = snd_pcm_open(&handle, "plughw:1,0", SND_PCM_STREAM_PLAYBACK, 0); 42 | 43 | if (rc < 0) 44 | { 45 | fprintf(stderr, "unable to open PCM device: %s\n", snd_strerror(rc)); 46 | return; 47 | } 48 | 49 | #ifdef NONBLOCKING_AUDIO 50 | snd_pcm_nonblock(handle, 1); 51 | #else 52 | snd_pcm_nonblock(handle, 0); 53 | #endif 54 | 55 | /* Allocate a hardware parameters object. */ 56 | snd_pcm_hw_params_alloca(¶ms); 57 | 58 | /* Fill it in with default values. */ 59 | rc = snd_pcm_hw_params_any(handle, params); 60 | if (rc < 0) 61 | { 62 | fprintf(stderr, "Error:snd_pcm_hw_params_any %s\n", snd_strerror(rc)); 63 | return; 64 | } 65 | 66 | /* Set the desired hardware parameters. */ 67 | 68 | /* Interleaved mode */ 69 | rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); 70 | if (rc < 0) 71 | { 72 | fprintf(stderr, "Error:snd_pcm_hw_params_set_access %s\n", snd_strerror(rc)); 73 | return; 74 | } 75 | 76 | /* Signed 16-bit little-endian format */ 77 | rc = snd_pcm_hw_params_set_format(handle, params, 78 | #ifdef LSB_FIRST 79 | SND_PCM_FORMAT_S16_LE 80 | #else 81 | SND_PCM_FORMAT_S16_BE 82 | #endif 83 | ); 84 | if (rc < 0) 85 | { 86 | fprintf(stderr, "Error:snd_pcm_hw_params_set_format %s\n", snd_strerror(rc)); 87 | return; 88 | } 89 | 90 | /* Two channels (stereo) */ 91 | rc = snd_pcm_hw_params_set_channels(handle, params, 2); 92 | if (rc < 0) 93 | { 94 | fprintf(stderr, "Error:snd_pcm_hw_params_set_channels %s\n", snd_strerror(rc)); 95 | return; 96 | } 97 | 98 | val = snd.sample_rate; 99 | rc=snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); 100 | if (rc < 0) 101 | { 102 | fprintf(stderr, "Error:snd_pcm_hw_params_set_rate_near %s\n", snd_strerror(rc)); 103 | return; 104 | } 105 | 106 | /* Set period size to settings.aica.BufferSize frames. */ 107 | frames = snd.buffer_size; 108 | rc = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); 109 | if (rc < 0) 110 | { 111 | fprintf(stderr, "Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); 112 | return; 113 | } 114 | frames *= 4; 115 | rc = snd_pcm_hw_params_set_buffer_size_near(handle, params, &frames); 116 | if (rc < 0) 117 | { 118 | fprintf(stderr, "Error:snd_pcm_hw_params_set_buffer_size_near %s\n", snd_strerror(rc)); 119 | return; 120 | } 121 | 122 | /* Write the parameters to the driver */ 123 | rc = snd_pcm_hw_params(handle, params); 124 | if (rc < 0) 125 | { 126 | fprintf(stderr, "Unable to set hw parameters: %s\n", snd_strerror(rc)); 127 | return; 128 | } 129 | 130 | return; 131 | } 132 | 133 | void Sound_Update(int16_t* sound_buffer, unsigned long len) 134 | { 135 | long ret; 136 | ret = snd_pcm_writei(handle, sound_buffer, len); 137 | while(ret != len) 138 | { 139 | if (ret < 0) snd_pcm_prepare( handle ); 140 | else len -= ret; 141 | ret = snd_pcm_writei(handle, sound_buffer, len); 142 | } 143 | } 144 | 145 | void Sound_Close(void) 146 | { 147 | if (handle) 148 | { 149 | snd_pcm_drop(handle); 150 | snd_pcm_close(handle); 151 | snd_config_update_free_global(); 152 | } 153 | } 154 | 155 | void Sound_Pause() 156 | { 157 | Sound_Close(); 158 | } 159 | 160 | void Sound_Unpause() 161 | { 162 | Sound_Init(); 163 | } 164 | -------------------------------------------------------------------------------- /source/sound_output/libao/sound_libao.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libao output sound code. 3 | * License : MIT 4 | * See docs/MIT_license.txt for more information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "smsplus.h" 12 | #include "sound_output.h" 13 | #include "shared.h" 14 | 15 | static ao_device *aodevice; 16 | static ao_sample_format aoformat; 17 | 18 | void Sound_Init() 19 | { 20 | ao_initialize(); 21 | memset(&aoformat, 0, sizeof(aoformat)); 22 | 23 | aoformat.bits = 16; 24 | aoformat.channels = 2; 25 | aoformat.rate = SOUND_FREQUENCY; 26 | aoformat.byte_format = AO_FMT_LITTLE; 27 | 28 | aodevice = ao_open_live(ao_default_driver_id(), &aoformat, NULL); // Live output 29 | if (!aodevice) 30 | aodevice = ao_open_live(ao_driver_id("null"), &aoformat, NULL); 31 | } 32 | 33 | void Sound_Update(int16_t* sound_buffer, unsigned long len) 34 | { 35 | ao_play(aodevice, (char*)sound_buffer, len); 36 | } 37 | 38 | void Sound_Close() 39 | { 40 | if (aodevice) 41 | { 42 | ao_close(aodevice); 43 | ao_shutdown(); 44 | } 45 | } 46 | 47 | void Sound_Pause() 48 | { 49 | Sound_Close(); 50 | } 51 | 52 | void Sound_Unpause() 53 | { 54 | Sound_Init(); 55 | } 56 | -------------------------------------------------------------------------------- /source/sound_output/oss/sound_output_oss.c: -------------------------------------------------------------------------------- 1 | /* 2 | * OSSv3/OSSv4 output sound code. 3 | * License : MIT 4 | * See docs/MIT_license.txt for more information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "smsplus.h" 14 | #include "sound_output.h" 15 | #include "shared.h" 16 | 17 | static int32_t oss_audio_fd = -1; 18 | 19 | void Sound_Init() 20 | { 21 | uint32_t channels = 2; 22 | #ifdef LSB_FIRST 23 | uint32_t format = AFMT_S16_LE; 24 | #else 25 | uint32_t format = AFMT_S16_BE; 26 | #endif 27 | int32_t err_ret; 28 | int32_t tmp; 29 | 30 | tmp = SOUND_FREQUENCY; 31 | 32 | oss_audio_fd = open("/dev/dsp", O_WRONLY 33 | #ifdef NONBLOCKING_AUDIO 34 | | O_NONBLOCK 35 | #endif 36 | ); 37 | if (oss_audio_fd < 0) 38 | { 39 | printf("Couldn't open /dev/dsp.\n"); 40 | return; 41 | } 42 | 43 | err_ret = ioctl(oss_audio_fd, SNDCTL_DSP_SPEED,&tmp); 44 | if (err_ret == -1) 45 | { 46 | printf("Could not set sound frequency\n"); 47 | return; 48 | } 49 | err_ret = ioctl(oss_audio_fd, SNDCTL_DSP_CHANNELS, &channels); 50 | if (err_ret == -1) 51 | { 52 | printf("Could not set channels\n"); 53 | return; 54 | } 55 | err_ret = ioctl(oss_audio_fd, SNDCTL_DSP_SETFMT, &format); 56 | if (err_ret == -1) 57 | { 58 | printf("Could not set sound format\n"); 59 | return; 60 | } 61 | 62 | return; 63 | } 64 | 65 | void Sound_Update(int16_t* sound_buffer, unsigned long len) 66 | { 67 | if (!oss_audio_fd) return; 68 | write(oss_audio_fd, sound_buffer, len * 4); 69 | } 70 | 71 | void Sound_Close() 72 | { 73 | if (oss_audio_fd >= 0) 74 | { 75 | close(oss_audio_fd); 76 | oss_audio_fd = -1; 77 | } 78 | } 79 | 80 | 81 | void Sound_Pause() 82 | { 83 | } 84 | 85 | void Sound_Unpause() 86 | { 87 | } 88 | -------------------------------------------------------------------------------- /source/sound_output/portaudio/sound_portaudio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Portaudio output sound code. 3 | * License : MIT 4 | * See docs/MIT_license.txt for more information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "smsplus.h" 12 | #include "sound_output.h" 13 | #include "shared.h" 14 | 15 | PaStream *apu_stream; 16 | 17 | #ifdef NONBLOCKING_AUDIO 18 | static int patestCallback( const void *inputBuffer, void *outputBuffer, 19 | unsigned long framesPerBuffer, 20 | const PaStreamCallbackTimeInfo* timeInfo, 21 | PaStreamCallbackFlags statusFlags, 22 | void *userData ) 23 | { 24 | /* Cast data passed through stream to our structure. */ 25 | snd.output = (int16_t*)outputBuffer; 26 | int32_t i; 27 | (void) inputBuffer; /* Prevent unused variable warning. */ 28 | 29 | return 0; 30 | } 31 | #endif 32 | 33 | void Sound_Init() 34 | { 35 | int32_t err; 36 | err = Pa_Initialize(); 37 | 38 | PaStreamParameters outputParameters; 39 | 40 | outputParameters.device = Pa_GetDefaultOutputDevice(); 41 | 42 | if (outputParameters.device == paNoDevice) 43 | { 44 | printf("No sound output\n"); 45 | return; 46 | } 47 | 48 | outputParameters.channelCount = 2; 49 | outputParameters.sampleFormat = paInt16; 50 | //outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; 51 | outputParameters.hostApiSpecificStreamInfo = NULL; 52 | 53 | err = Pa_OpenStream( &apu_stream, NULL, &outputParameters, SOUND_FREQUENCY, snd.buffer_size, paNoFlag, 54 | #ifdef NONBLOCKING_AUDIO 55 | patestCallback, NULL); 56 | #else 57 | NULL, NULL); 58 | #endif 59 | err = Pa_StartStream( apu_stream ); 60 | } 61 | 62 | void Sound_Update(int16_t* sound_buffer, unsigned long len) 63 | { 64 | #ifndef NONBLOCKING_AUDIO 65 | Pa_WriteStream( apu_stream, sound_buffer, len); 66 | #endif 67 | } 68 | 69 | void Sound_Close() 70 | { 71 | int32_t err; 72 | err = Pa_CloseStream( apu_stream ); 73 | err = Pa_Terminate(); 74 | } 75 | 76 | void Sound_Pause() 77 | { 78 | } 79 | 80 | void Sound_Unpause() 81 | { 82 | } 83 | -------------------------------------------------------------------------------- /source/sound_output/pulse/sound_output_pulse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Pulseaudio output sound code. 3 | * License : MIT 4 | * See docs/MIT_license.txt for more information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "smsplus.h" 14 | #include "sound_output.h" 15 | #include "shared.h" 16 | 17 | static pa_simple *pulse_stream; 18 | 19 | void Sound_Init() 20 | { 21 | pa_sample_spec ss; 22 | pa_buffer_attr paattr; 23 | 24 | ss.format = PA_SAMPLE_S16LE; 25 | ss.channels = 2; 26 | ss.rate = SOUND_FREQUENCY; 27 | 28 | paattr.tlength = snd.buffer_size * 4; 29 | paattr.prebuf = -1; 30 | paattr.maxlength = -1; 31 | paattr.minreq = snd.buffer_size; 32 | 33 | /* Create a new playback stream */ 34 | pulse_stream = pa_simple_new(NULL, "SMS Plus GX", PA_STREAM_PLAYBACK, NULL, "SMS Plus GX", &ss, NULL, &paattr, NULL); 35 | if (!pulse_stream) 36 | { 37 | fprintf(stderr, "PulseAudio: pa_simple_new() failed!\n"); 38 | } 39 | return; 40 | } 41 | 42 | void Sound_Update(int16_t* sound_buffer, unsigned long len) 43 | { 44 | if (pa_simple_write(pulse_stream, sound_buffer, len * 4, NULL) < 0) 45 | { 46 | fprintf(stderr, "PulseAudio: pa_simple_write() failed!\n"); 47 | } 48 | } 49 | 50 | void Sound_Close() 51 | { 52 | if(pulse_stream != NULL) 53 | { 54 | if (pa_simple_drain(pulse_stream, NULL) < 0) 55 | { 56 | fprintf(stderr, "PulseAudio: pa_simple_drain() failed!\n"); 57 | } 58 | pa_simple_free(pulse_stream); 59 | } 60 | } 61 | 62 | void Sound_Pause() 63 | { 64 | } 65 | 66 | void Sound_Unpause() 67 | { 68 | } 69 | 70 | -------------------------------------------------------------------------------- /source/sound_output/sdl12/sound_output_sdl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "smsplus.h" 5 | #include "sound_output.h" 6 | #include "shared.h" 7 | 8 | /* Most of the sound code was taken from FBA-SDL by DmitrySmagin so many thanks to him ! */ 9 | 10 | static SDL_mutex *sound_mutex; 11 | static SDL_cond *sound_cv; 12 | 13 | /* Using Mutexes by default but allowing disabling them on compilation */ 14 | //#define SDLAUDIO_MUTEX 15 | 16 | static int32_t BUFFSIZE; 17 | static uint8_t *buffer; 18 | static int32_t buf_read_pos = 0; 19 | static uint32_t buf_write_pos = 0; 20 | static int32_t buffered_bytes = 0; 21 | 22 | /* 23 | static int32_t sdl_write_buffer_m(uint8_t* data, unsigned long len) 24 | { 25 | SDL_LockMutex(sound_mutex); 26 | for(uint8_t i = 0; i < len; i += 4) 27 | { 28 | while(buffered_bytes == BUFFSIZE) SDL_CondWait(sound_cv, sound_mutex); 29 | 30 | *(int32_t*)((char*)(buffer + buf_write_pos)) = *(int32_t*)((char*)(data + i)); 31 | //memcpy(buffer + buf_write_pos, data + i, 4); 32 | buf_write_pos = (buf_write_pos + 4) % BUFFSIZE; 33 | buffered_bytes += 4; 34 | } 35 | SDL_CondSignal(sound_cv); 36 | SDL_UnlockMutex(sound_mutex); 37 | return len; 38 | } 39 | */ 40 | static void sdl_write_buffer(uint8_t* data, int32_t len) 41 | { 42 | for(int32_t i = 0; i < len; i += 4) 43 | { 44 | if(buffered_bytes == BUFFSIZE) return; // just drop samples 45 | *(int32_t*)((char*)(buffer + buf_write_pos)) = *(int32_t*)((char*)(data + i)); 46 | //memcpy(buffer + buf_write_pos, data + i, 4); 47 | buf_write_pos = (buf_write_pos + 4) % BUFFSIZE; 48 | buffered_bytes += 4; 49 | } 50 | } 51 | 52 | 53 | static int32_t sdl_read_buffer(uint8_t* data, int32_t len) 54 | { 55 | if (buffered_bytes >= len) 56 | { 57 | if(buf_read_pos + len <= BUFFSIZE ) 58 | { 59 | memcpy(data, buffer + buf_read_pos, len); 60 | } 61 | else 62 | { 63 | int32_t tail = BUFFSIZE - buf_read_pos; 64 | memcpy(data, buffer + buf_read_pos, tail); 65 | memcpy(data + tail, buffer, len - tail); 66 | } 67 | buf_read_pos = (buf_read_pos + len) % BUFFSIZE; 68 | buffered_bytes -= len; 69 | } 70 | 71 | return len; 72 | } 73 | 74 | void sdl_callback_m(void *unused, uint8_t *stream, int32_t len) 75 | { 76 | SDL_LockMutex(sound_mutex); 77 | 78 | sdl_read_buffer((uint8_t *)stream, len); 79 | 80 | SDL_CondSignal(sound_cv); 81 | SDL_UnlockMutex(sound_mutex); 82 | } 83 | 84 | void sdl_callback(void *unused, uint8_t *stream, int32_t len) 85 | { 86 | sdl_read_buffer((uint8_t *)stream, len); 87 | } 88 | 89 | void Sound_Init() 90 | { 91 | SDL_AudioSpec aspec, obtained; 92 | 93 | BUFFSIZE = snd.buffer_size * 2 * 2 * 8; 94 | buffer = (uint8_t *) malloc(BUFFSIZE); 95 | 96 | /* Add some silence to the buffer */ 97 | buffered_bytes = 0; 98 | buf_read_pos = 0; 99 | buf_write_pos = 0; 100 | 101 | aspec.format = AUDIO_S16SYS; 102 | aspec.freq = SOUND_FREQUENCY; 103 | aspec.channels = 2; 104 | aspec.samples = snd.buffer_size; 105 | #ifdef SDLAUDIO_MUTEX 106 | aspec.callback = sdl_callback_m; 107 | #else 108 | aspec.callback = sdl_callback; 109 | #endif 110 | aspec.userdata = NULL; 111 | 112 | /* initialize the SDL Audio system */ 113 | if (SDL_InitSubSystem (SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE)) 114 | { 115 | printf("SDL: Initializing of SDL Audio failed: %s.\n", SDL_GetError()); 116 | return; 117 | } 118 | 119 | /* Open the audio device and start playing sound! */ 120 | if(SDL_OpenAudio(&aspec, &obtained) < 0) 121 | { 122 | printf("SDL: Unable to open audio: %s\n", SDL_GetError()); 123 | return; 124 | } 125 | 126 | #ifdef SDLAUDIO_MUTEX 127 | { 128 | sound_mutex = SDL_CreateMutex(); 129 | sound_cv = SDL_CreateCond(); 130 | } 131 | #endif 132 | 133 | SDL_PauseAudio(0); 134 | 135 | return; 136 | } 137 | 138 | void Sound_Pause() 139 | { 140 | SDL_PauseAudio(1); 141 | } 142 | 143 | void Sound_Unpause() 144 | { 145 | SDL_PauseAudio(0); 146 | } 147 | 148 | void Sound_Update(int16_t* sound_buffer, unsigned long len) 149 | { 150 | SDL_LockAudio(); 151 | sdl_write_buffer((uint8_t*)sound_buffer, len * 4); 152 | SDL_UnlockAudio(); 153 | } 154 | 155 | void Sound_Close() 156 | { 157 | SDL_PauseAudio(1); 158 | #ifdef SDLAUDIO_MUTEX 159 | { 160 | SDL_LockMutex(sound_mutex); 161 | buffered_bytes = BUFFSIZE; 162 | SDL_CondSignal(sound_cv); 163 | SDL_UnlockMutex(sound_mutex); 164 | SDL_Delay(25); 165 | SDL_DestroyCond(sound_cv); 166 | SDL_DestroyMutex(sound_mutex); 167 | } 168 | #endif 169 | SDL_CloseAudio(); 170 | SDL_QuitSubSystem(SDL_INIT_AUDIO); 171 | 172 | if (buffer != NULL) 173 | { 174 | free(buffer); 175 | buffer = NULL; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /source/sound_output/sound_output.h: -------------------------------------------------------------------------------- 1 | #ifndef SOUND_OUTPUT_H 2 | #define SOUND_OUTPUT_H 3 | 4 | #include 5 | 6 | extern void Sound_Init(void); 7 | /* extern void Sound_Update(void); */ 8 | extern void Sound_Update(int16_t* sound_buffer, unsigned long len); 9 | extern void Sound_Close(void); 10 | extern void Sound_Pause(void); 11 | extern void Sound_Unpause(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /source/state.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | ******************************************************************************/ 22 | /* 23 | * See git commit history for more information. 24 | * - Gameblabla 25 | * March 15th 2019 : Minor changes. 26 | * March 14th 2019 : Use fwrite instead of fputc. Also fix an issue with fread which could cause issues. 27 | * March 13th 2019 : Bring it back again due to regressions. Also i parsed some random shit by accident so i fixed it again. 28 | * March 9th 2019 : Decomment CrabZ80 related code and removing extra externs. 29 | * March 7th 2019 : Comment out CrabZ80 related code. 30 | * Feb 2nd 2019 : Sound function names were changed, fix accordingly. 31 | */ 32 | 33 | #include "shared.h" 34 | 35 | #if !defined(MAXIM_PSG) && !defined(MAME_PSG) 36 | extern sn76489_t psg_sn; 37 | #endif 38 | 39 | uint32_t system_save_state(FILE* fd) 40 | { 41 | /* Save VDP context */ 42 | fwrite(&vdp, sizeof(vdp_t), sizeof(int8_t), fd); 43 | 44 | /* Save SMS context */ 45 | fwrite(&sms, sizeof(sms_t), sizeof(int8_t), fd); 46 | 47 | fwrite(cart.fcr, 4, sizeof(int8_t), fd); 48 | 49 | fwrite(cart.sram, 0x8000, sizeof(int8_t), fd); 50 | 51 | /* Save Z80 context */ 52 | fwrite(Z80_Context, sizeof(z80_t), sizeof(int8_t), fd); 53 | 54 | /* Save YM2413 context */ 55 | fwrite(FM_GetContextPtr(), FM_GetContextSize(), sizeof(int8_t), fd); 56 | 57 | /* Save SN76489 context */ 58 | #ifdef MAXIM_PSG 59 | fwrite(SN76489_GetContextPtr(0), SN76489_GetContextSize(), sizeof(int8_t), fd); 60 | #elif defined(MAME_PSG) 61 | fwrite(&PSG, sizeof(sn76489_t), sizeof(int8_t), fd); 62 | #else 63 | fwrite(&psg_sn, sizeof(sn76489_t), sizeof(int8_t), fd); 64 | #endif 65 | 66 | return 0; 67 | } 68 | 69 | void system_load_state(FILE* fd) 70 | { 71 | uint8_t *buf; 72 | uint32_t i; 73 | 74 | /* Initialize everything */ 75 | system_reset(); 76 | 77 | /* Load VDP context */ 78 | fread(&vdp, sizeof(vdp_t), sizeof(int8_t), fd); 79 | 80 | /* Load SMS context */ 81 | fread(&sms, sizeof(sms_t), sizeof(int8_t), fd); 82 | 83 | /** restore video & audio settings (needed if timing changed) ***/ 84 | vdp_init(); 85 | SMSPLUS_sound_init(); 86 | 87 | fread(cart.fcr, 4, sizeof(int8_t), fd); 88 | 89 | fread(cart.sram, 0x8000, sizeof(int8_t), fd); 90 | 91 | /* Load Z80 context */ 92 | fread(Z80_Context, sizeof(z80_t), sizeof(int8_t), fd); 93 | Z80.irq_callback = sms_irq_callback; 94 | 95 | /* Load YM2413 context */ 96 | buf = malloc(FM_GetContextSize()); 97 | fread(buf, FM_GetContextSize(), sizeof(int8_t), fd); 98 | FM_SetContext(buf); 99 | free(buf); 100 | 101 | /* Load SN76489 context */ 102 | #ifdef MAXIM_PSG 103 | buf = malloc(SN76489_GetContextSize()); 104 | fread(buf, SN76489_GetContextSize(), sizeof(int8_t), fd); 105 | SN76489_SetContext(0, buf); 106 | free(buf); 107 | #elif defined(MAME_PSG) 108 | buf = malloc(sizeof(sn76489_t)); 109 | fread(buf, sizeof(sn76489_t), sizeof(int8_t), fd); 110 | memcpy(&PSG, buf, sizeof(sn76489_t)); 111 | free(buf); 112 | #else 113 | buf = malloc(sizeof(sn76489_t)); 114 | fread(buf, sizeof(sn76489_t), sizeof(int8_t), fd); 115 | memcpy(&psg_sn, buf, sizeof(sn76489_t)); 116 | free(buf); 117 | #endif 118 | 119 | if ((sms.console != CONSOLE_COLECO) && (sms.console != CONSOLE_SG1000) && (sms.console != CONSOLE_SORDM5)) 120 | { 121 | /* Cartridge by default */ 122 | slot.rom = cart.rom; 123 | slot.pages = cart.pages; 124 | slot.mapper = cart.mapper; 125 | slot.fcr = &cart.fcr[0]; 126 | 127 | /* Restore mapping */ 128 | mapper_reset(); 129 | cpu_readmap[0] = &slot.rom[0]; 130 | if (slot.mapper != MAPPER_KOREA_MSX) 131 | { 132 | mapper_16k_w(0,slot.fcr[0]); 133 | mapper_16k_w(1,slot.fcr[1]); 134 | mapper_16k_w(2,slot.fcr[2]); 135 | mapper_16k_w(3,slot.fcr[3]); 136 | } 137 | else 138 | { 139 | mapper_8k_w(0,slot.fcr[0]); 140 | mapper_8k_w(1,slot.fcr[1]); 141 | mapper_8k_w(2,slot.fcr[2]); 142 | mapper_8k_w(3,slot.fcr[3]); 143 | } 144 | } 145 | 146 | /* Force full pattern cache update */ 147 | bg_list_index = 0x200; 148 | for(i = 0; i < 0x200; i++) 149 | { 150 | bg_name_list[i] = i; 151 | bg_name_dirty[i] = 255; 152 | } 153 | 154 | /* Restore palette */ 155 | for(i = 0; i < PALETTE_SIZE; i++) 156 | palette_sync(i); 157 | } 158 | -------------------------------------------------------------------------------- /source/state.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Freeze State support 22 | * 23 | ******************************************************************************/ 24 | 25 | #ifndef STATE_H_ 26 | #define STATE_H_ 27 | 28 | #define STATE_VERSION 0x0104 /* Version 1.4 (BCD) */ 29 | #define STATE_HEADER "SST\0" /* State file header */ 30 | 31 | /* Function prototypes */ 32 | extern uint32_t system_save_state(FILE *fd); 33 | extern void system_load_state(FILE *fd); 34 | 35 | #endif /* _STATE_H_ */ 36 | -------------------------------------------------------------------------------- /source/system.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Sega Master System manager 22 | * 23 | ******************************************************************************/ 24 | /* 25 | * See git commit history for more information. 26 | * - Gameblabla 27 | * March 13th 2019 : Minor fixes as part of the CrabZ80's revert. (mostly whitepacing but the TMS code was also broken to some extent) 28 | * March 7th 2019 : Some whitepacing and changing variables to c99 datatypes. 29 | * Feb 19th 2019 : Minor whitepacing fix. 30 | * August 12th 2018 : Minor fixes. (mostly changing variables to c99 datatypes and whitepacing) 31 | */ 32 | 33 | #include "shared.h" 34 | 35 | bitmap_t bitmap; 36 | cart_t cart; 37 | input_t input; 38 | 39 | extern int32_t z80_cycle_count; 40 | 41 | /* Run the virtual console emulation for one frame */ 42 | void system_frame(uint32_t skip_render) 43 | { 44 | int32_t iline = 0, line_z80 = 0; 45 | 46 | /* Debounce pause key */ 47 | if(input.system & INPUT_PAUSE) 48 | { 49 | if(!sms.paused) 50 | { 51 | sms.paused = 1; 52 | CPUIRQ_Pause(); 53 | } 54 | } 55 | else 56 | { 57 | sms.paused = 0; 58 | } 59 | 60 | /* Reset TMS Text offset counter */ 61 | text_counter = 0; 62 | 63 | /* 3D glasses faking */ 64 | if (sms.glasses_3d) skip_render = sms.wram[0x1ffb]; 65 | 66 | /* VDP register 9 is latched during VBLANK */ 67 | vdp.vscroll = vdp.reg[9]; 68 | 69 | /* Reload Horizontal Interrupt counter */ 70 | vdp.left = vdp.reg[0x0A]; 71 | 72 | /* Reset collision flag infos */ 73 | vdp.spr_col = 0xff00; 74 | 75 | /* Line processing */ 76 | for(vdp.line = 0; vdp.line < vdp.lpf; vdp.line++) 77 | { 78 | iline = vdp.height; 79 | 80 | /* VDP line rendering */ 81 | if(!skip_render) render_line(vdp.line); 82 | 83 | /* Horizontal Interrupt */ 84 | if (sms.console >= CONSOLE_SMS) 85 | { 86 | if(vdp.line <= iline) 87 | { 88 | if(--vdp.left < 0) 89 | { 90 | vdp.left = vdp.reg[0x0A]; 91 | vdp.hint_pending = 1; 92 | if(vdp.reg[0x00] & 0x10) 93 | { 94 | /* IRQ line is latched between instructions, on instruction last cycle */ 95 | /* This means that if Z80 cycle count is exactly a multiple of CYCLES_PER_LINE, */ 96 | /* interrupt should be triggered AFTER the next instruction. */ 97 | if (!(z80_get_elapsed_cycles()%CYCLES_PER_LINE)) 98 | z80_execute(1); 99 | z80_set_irq_line(0, ASSERT_LINE); 100 | } 101 | } 102 | } 103 | } 104 | 105 | /* Run Z80 CPU */ 106 | line_z80 += CYCLES_PER_LINE; 107 | z80_execute((line_z80 - z80_cycle_count)); 108 | 109 | /* Vertical Interrupt */ 110 | if(vdp.line == iline) 111 | { 112 | vdp.status |= 0x80; 113 | vdp.vint_pending = 1; 114 | if(vdp.reg[0x01] & 0x20) 115 | { 116 | z80_set_irq_line(vdp.irq, ASSERT_LINE); 117 | } 118 | } 119 | 120 | /* Run sound chips */ 121 | SMSPLUS_sound_update(vdp.line); 122 | } 123 | 124 | /* Adjust Z80 cycle count for next frame */ 125 | z80_cycle_count -= line_z80; 126 | } 127 | 128 | void system_init(void) 129 | { 130 | sms_init(); 131 | pio_init(); 132 | vdp_init(); 133 | render_init(); 134 | SMSPLUS_sound_init(); 135 | } 136 | 137 | void system_shutdown(void) 138 | { 139 | sms_shutdown(); 140 | pio_shutdown(); 141 | vdp_shutdown(); 142 | render_shutdown(); 143 | SMSPLUS_sound_shutdown(); 144 | free_rom(); 145 | } 146 | 147 | void system_reset(void) 148 | { 149 | sms_reset(); 150 | pio_reset(); 151 | vdp_reset(); 152 | render_reset(); 153 | SMSPLUS_sound_reset(); 154 | system_manage_sram(cart.sram, SLOT_CART, SRAM_LOAD); 155 | } 156 | 157 | 158 | void system_poweron(void) 159 | { 160 | system_init(); 161 | system_reset(); 162 | } 163 | 164 | void system_poweroff(void) 165 | { 166 | system_manage_sram(cart.sram, SLOT_CART, SRAM_SAVE); 167 | } 168 | -------------------------------------------------------------------------------- /source/system.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Sega Master System manager 22 | * 23 | ******************************************************************************/ 24 | #ifndef SYSTEM_H_ 25 | #define SYSTEM_H_ 26 | 27 | #define APP_NAME "SMS Plus GX" 28 | #define APP_VERSION "1.8" 29 | 30 | #define PALETTE_SIZE 0x20 31 | 32 | /* Mask for removing unused pixel data */ 33 | #define PIXEL_MASK 0x1F 34 | 35 | /* These can be used for 'input.pad[]' */ 36 | #define INPUT_UP 0x00000001 37 | #define INPUT_DOWN 0x00000002 38 | #define INPUT_LEFT 0x00000004 39 | #define INPUT_RIGHT 0x00000008 40 | #define INPUT_BUTTON1 0x00000010 41 | #define INPUT_BUTTON2 0x00000020 42 | 43 | /* These can be used for 'input.system' */ 44 | #define INPUT_START 0x00000001 /* Game Gear only */ 45 | #define INPUT_PAUSE 0x00000002 /* Master System only */ 46 | #define INPUT_RESET 0x00000004 /* Master System only */ 47 | 48 | enum 49 | { 50 | SRAM_SAVE = 0, 51 | SRAM_LOAD = 1 52 | }; 53 | 54 | /* User input structure */ 55 | typedef struct 56 | { 57 | int32_t analog[2][2]; 58 | uint8_t pad[2]; 59 | uint8_t system; 60 | } input_t; 61 | 62 | /* Game image structure */ 63 | typedef struct 64 | { 65 | uint8_t *rom; 66 | uint8_t loaded; 67 | uint32_t size; 68 | /* We need to use an unsigned short for pages, as Bad Apple SMS requires it !*/ 69 | uint16_t pages; 70 | uint32_t crc; 71 | uint32_t sram_crc; 72 | uint8_t mapper; 73 | uint8_t sram[0x8000]; 74 | uint8_t fcr[4]; 75 | } cart_t; 76 | 77 | /* Bitmap structure */ 78 | typedef struct 79 | { 80 | uint8_t *data; 81 | uint32_t width; 82 | uint32_t height; 83 | uint32_t pitch; 84 | uint32_t depth; 85 | struct 86 | { 87 | int32_t x, y, w, h; 88 | int32_t ox, oy, ow, oh; 89 | int32_t changed; 90 | } viewport; 91 | struct 92 | { 93 | uint8_t color[PALETTE_SIZE][3]; 94 | uint8_t dirty[PALETTE_SIZE]; 95 | uint8_t update; 96 | } pal; 97 | } bitmap_t; 98 | 99 | /* Global variables */ 100 | extern bitmap_t bitmap; /* Display bitmap */ 101 | extern cart_t cart; /* Game cartridge data */ 102 | extern input_t input; /* Controller input */ 103 | 104 | /* Function prototypes */ 105 | extern void system_frame(uint32_t skip_render); 106 | extern void system_init(void); 107 | extern void system_shutdown(void); 108 | extern void system_reset(void); 109 | extern void system_manage_sram(uint8_t *sram, uint8_t slot_number, uint8_t mode); 110 | extern void system_poweron(void); 111 | extern void system_poweroff(void); 112 | 113 | #endif /* _SYSTEM_H_ */ 114 | 115 | 116 | -------------------------------------------------------------------------------- /source/text/fb/font_drawing.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "smsplus.h" 5 | #include "font_drawing.h" 6 | #include "font_menudata.h" 7 | 8 | #define setPixel(buffer, x,y,c) *((uint16_t* restrict)buffer + ((x) + (y) * HOST_WIDTH_RESOLUTION)) = c; 9 | 10 | static int32_t isOutlinePixel(uint8_t* charfont, int32_t x, int32_t y) 11 | { 12 | int32_t xis0 = !x, xis7 = x == 7, yis0 = !y, yis7 = y == 7; 13 | 14 | if(xis0) 15 | { 16 | if(yis0) 17 | { 18 | return !(*charfont & 0x80) && ((*charfont & 0x40) || (charfont[1] & 0x80) || (charfont[1] & 0x40)); 19 | } 20 | else if(yis7) 21 | { 22 | return !(charfont[7] & 0x80) && ((charfont[7] & 0x40) || (charfont[6] & 0x80) || (charfont[6] & 0x40)); 23 | } 24 | else 25 | { 26 | return !(charfont[y] & 0x80) && ( 27 | (charfont[y - 1] & 0x80) || (charfont[y - 1] & 0x40) || 28 | (charfont[y] & 0x40) || 29 | (charfont[y + 1] & 0x80) || (charfont[y + 1] & 0x40)); 30 | } 31 | } 32 | else if(xis7) 33 | { 34 | if(yis0) 35 | { 36 | return !(*charfont & 0x01) && ((*charfont & 0x02) || (charfont[1] & 0x01) || (charfont[1] & 0x02)); 37 | } 38 | else if(yis7) 39 | { 40 | return !(charfont[7] & 0x01) && ((charfont[7] & 0x02) || (charfont[6] & 0x01) || (charfont[6] & 0x02)); 41 | } 42 | else 43 | { 44 | return !(charfont[y] & 0x01) && ( 45 | (charfont[y - 1] & 0x01) || (charfont[y - 1] & 0x02) || 46 | (charfont[y] & 0x02) || 47 | (charfont[y + 1] & 0x01) || (charfont[y + 1] & 0x02)); 48 | } 49 | } 50 | else 51 | { 52 | int32_t b = 1 << (7 - x); 53 | if(yis0) 54 | { 55 | return !(*charfont & b) && ( 56 | (*charfont & (b << 1)) || (*charfont & (b >> 1)) || 57 | (charfont[1] & (b << 1)) || (charfont[1] & b) || (charfont[1] & (b >> 1))); 58 | } 59 | else if(yis7) 60 | { 61 | return !(charfont[7] & b) && ( 62 | (charfont[7] & (b << 1)) || (charfont[7] & (b >> 1)) || 63 | (charfont[6] & (b << 1)) || (charfont[6] & b) || (charfont[6] & (b >> 1))); 64 | } 65 | else 66 | { 67 | return !(charfont[y] & b) && ( 68 | (charfont[y] & (b << 1)) || (charfont[y] & (b >> 1)) || 69 | (charfont[y - 1] & (b << 1)) || (charfont[y - 1] & b) || (charfont[y - 1] & (b >> 1)) || 70 | (charfont[y + 1] & (b << 1)) || (charfont[y + 1] & b) || (charfont[y + 1] & (b >> 1))); 71 | } 72 | } 73 | } 74 | 75 | static void drawChar(uint16_t* restrict buffer, int32_t *x, int32_t *y, int32_t margin, char ch, uint16_t fc, uint16_t olc) 76 | { 77 | int32_t i, j; 78 | uint8_t *charSprite; 79 | if (ch == '\n') 80 | { 81 | *x = margin; 82 | *y += 8; 83 | } 84 | else if(*y < HOST_HEIGHT_RESOLUTION-1) 85 | { 86 | charSprite = ch * 8 + n2DLib_font; 87 | // Draw charSprite as monochrome 8*8 image using given color 88 | for(i = 0; i < 8; i++) 89 | { 90 | for(j = 7; j >= 0; j--) 91 | { 92 | if((charSprite[i] >> j) & 1) 93 | { 94 | setPixel(buffer, *x + (7 - j), *y + i, fc) 95 | } 96 | else if(isOutlinePixel(charSprite, 7 - j, i)) 97 | { 98 | setPixel(buffer, *x + (7 - j), *y + i, olc) 99 | } 100 | } 101 | } 102 | *x += 8; 103 | } 104 | } 105 | 106 | static void drawString(uint16_t* restrict buffer, int32_t *x, int32_t *y, int32_t _x, const char *str, uint16_t fc, uint16_t olc) 107 | { 108 | unsigned long i, max = strlen(str) + 1; 109 | for(i = 0; i < max; i++) 110 | drawChar(buffer, x, y, _x, str[i], fc, olc); 111 | } 112 | 113 | void print_string(const char *s,const uint16_t fg_color, const uint16_t bg_color, int32_t x, int32_t y, uint16_t* restrict buffer) 114 | { 115 | drawString(buffer, &x, &y, 0, s, fg_color, bg_color); 116 | } 117 | -------------------------------------------------------------------------------- /source/text/fb/font_drawing.h: -------------------------------------------------------------------------------- 1 | #ifndef FONT_DRAWING_H 2 | #define FONT_DRAWING_H 3 | 4 | #include 5 | #include 6 | 7 | #define TextWhite 65535 8 | #define TextRed ((255>>3)<<11) + ((0>>2)<<5) + (0>>3) 9 | #define TextBlue ((0>>3)<<11) + ((0>>2)<<5) + (255>>3) 10 | 11 | void print_string(const char *s,const uint16_t fg_color, const uint16_t bg_color, int32_t x, int32_t y, uint16_t* restrict buffer); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /source/text/sdl/text_gui.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "shared.h" 5 | #include "smsplus.h" 6 | #include "text_gui.h" 7 | 8 | SDL_Surface *font = NULL; 9 | SDL_Surface *bigfontred = NULL; 10 | SDL_Surface *bigfontwhite = NULL; 11 | 12 | extern SDL_Surface* sdl_screen; 13 | 14 | int32_t gfx_font_width(SDL_Surface* inFont, char* inString) { 15 | if((inFont == NULL) || (inString == NULL)) 16 | return 0; 17 | int32_t i, tempCur, tempMax; 18 | for(i = 0, tempCur = 0, tempMax = 0; inString[i] != '\0'; i++) { 19 | if(inString[i] == '\t') 20 | tempCur += 4; 21 | else if((inString[i] == '\r') || (inString[i] == '\n')) 22 | tempCur = 0; 23 | else 24 | tempCur++; 25 | if(tempCur > tempMax) tempMax = tempCur; 26 | } 27 | tempMax *= (inFont->w >> 4); 28 | return tempMax; 29 | } 30 | 31 | int32_t gfx_font_height(SDL_Surface* inFont) { 32 | if(inFont == NULL) 33 | return 0; 34 | return (inFont->h >> 4); 35 | } 36 | 37 | void gfx_font_print(SDL_Surface* dest, int32_t inX, int32_t inY, SDL_Surface* inFont, char* inString) 38 | { 39 | if((inFont == NULL) || (inString == NULL)) 40 | return; 41 | 42 | uint16_t* tempBuffer = dest->pixels; 43 | uint16_t* tempFont = inFont->pixels; 44 | uint8_t* tempChar; 45 | int32_t tempX = inX; 46 | int32_t tempY = inY; 47 | int32_t i, j, x, y; 48 | 49 | SDL_LockSurface(dest); 50 | SDL_LockSurface(inFont); 51 | 52 | for(tempChar = (uint8_t*)inString; *tempChar != '\0'; tempChar++) 53 | { 54 | switch(*tempChar) 55 | { 56 | case ' ': 57 | tempX += (inFont->w >> 4); 58 | break; 59 | case '\t': 60 | tempX += ((inFont->w >> 4) << 2); 61 | break; 62 | case '\r': 63 | tempX = inX; 64 | break; 65 | case '\n': 66 | tempX = inX; 67 | tempY += (inFont->h >> 4); 68 | break; 69 | } 70 | 71 | for(j = ((*tempChar >> 4) * (inFont->h >> 4)), y = tempY; (j < (((*tempChar >> 4) + 1) * (inFont->h >> 4))) && (y < dest->h); j++, y++) 72 | { 73 | for(i = ((*tempChar & 0x0F) * (inFont->w >> 4)), x = tempX; (i < (((*tempChar & 0x0F) + 1) * (inFont->w >> 4))) && (x < dest->w); i++, x++) 74 | { 75 | tempBuffer[(y * dest->w) + x] |= tempFont[(j * inFont->w) + i]; 76 | } 77 | } 78 | tempX += (inFont->w >> 4); 79 | } 80 | SDL_UnlockSurface(dest); 81 | SDL_UnlockSurface(inFont); 82 | } 83 | 84 | void gfx_font_print_center(SDL_Surface* dest,int32_t inY, SDL_Surface* inFont, char* inString) 85 | { 86 | int32_t tempX = (dest->w - gfx_font_width(inFont, inString)) >> 1; 87 | gfx_font_print(dest,tempX, inY, inFont, inString); 88 | } 89 | 90 | void gfx_font_print_fromright(SDL_Surface* dest,int32_t inX, int32_t inY, SDL_Surface* inFont, char* inString) 91 | { 92 | int32_t tempX = inX - gfx_font_width(inFont, inString); 93 | gfx_font_print(dest,tempX, inY, inFont, inString); 94 | } 95 | 96 | SDL_Surface* gfx_tex_load_tga_from_array(uint8_t* buffer) 97 | { 98 | if(buffer == NULL) 99 | return NULL; 100 | 101 | int32_t tga_width; 102 | int32_t tga_height; 103 | uint8_t tga_descriptor; 104 | 105 | tga_width = buffer[12] + (buffer[13] << 8); 106 | tga_height = buffer[14] + (buffer[15] << 8); 107 | tga_descriptor = buffer[17]; 108 | 109 | uint32_t bufIndex = 18; 110 | 111 | SDL_Surface* tempTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, tga_width, tga_height, 16, 0, 0, 0, 0); 112 | if(tempTexture == NULL) 113 | { 114 | return NULL; 115 | } 116 | 117 | uint32_t upsideDown = (tga_descriptor & 0x20) > 0; 118 | 119 | int32_t i; 120 | int32_t iNew; 121 | uint8_t tempColor[3]; 122 | SDL_LockSurface(tempTexture); 123 | uint16_t* tempTexPtr = tempTexture->pixels; 124 | for(i = 0; i < (tga_width * tga_height); i++) 125 | { 126 | tempColor[2] = buffer[bufIndex + 0]; 127 | tempColor[1] = buffer[bufIndex + 1]; 128 | tempColor[0] = buffer[bufIndex + 2]; 129 | bufIndex += 3; 130 | 131 | if (upsideDown) 132 | iNew = i; 133 | else 134 | iNew = (tga_height - 1 - (i / tga_width)) * tga_width + i % tga_width; 135 | 136 | tempTexPtr[iNew] = SDL_MapRGB(sdl_screen->format,tempColor[0], tempColor[1], tempColor[2]); 137 | } 138 | SDL_UnlockSurface(tempTexture); 139 | return tempTexture; 140 | } 141 | -------------------------------------------------------------------------------- /source/text/sdl/text_gui.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTGUI_H_ 2 | #define TEXTGUI_H_ 3 | 4 | extern SDL_Surface *font, *bigfontred, *bigfontwhite; 5 | 6 | SDL_Surface* gfx_tex_load_tga_from_array(uint8_t* buffer); 7 | void gfx_font_print(SDL_Surface* dest, int32_t inX, int32_t inY, SDL_Surface* inFont, char* inString); 8 | void gfx_font_print_center(SDL_Surface* dest,int32_t inY, SDL_Surface* inFont, char* inString); 9 | int32_t gfx_font_height(SDL_Surface* inFont); 10 | int32_t gfx_font_width(SDL_Surface* inFont, char* inString); 11 | void gfx_font_print_fromright(SDL_Surface* dest,int32_t inX, int32_t inY, SDL_Surface* inFont, char* inString); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /source/tms.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * This program 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 | * This program 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 this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * TMS9918 and legacy video mode support. 20 | * 21 | ******************************************************************************/ 22 | #ifndef TMS_H_ 23 | #define TMS_H_ 24 | 25 | /* Global variables */ 26 | extern int32_t text_counter; 27 | 28 | /* Function prototypes */ 29 | extern void make_tms_tables(void); 30 | extern void render_bg_tms(int32_t line); 31 | extern void render_obj_tms(int32_t line); 32 | extern void parse_line(int32_t line); 33 | 34 | #endif /* _TMS_H_ */ 35 | -------------------------------------------------------------------------------- /source/unzip/fileio.c: -------------------------------------------------------------------------------- 1 | /* 2 | fileio.c -- 3 | File management. 4 | */ 5 | #include "shared.h" 6 | #include "unzip.h" 7 | 8 | uint8_t *loadFromZipByName(char *archive, char *filename, uint32_t *filesize) 9 | { 10 | char name[PATH_MAX]; 11 | uint8_t *buffer; 12 | 13 | int32_t zerror = UNZ_OK; 14 | unzFile zhandle; 15 | unz_file_info zinfo; 16 | 17 | zinfo.uncompressed_size = 0; 18 | 19 | zhandle = unzOpen(archive); 20 | if(!zhandle) return (NULL); 21 | 22 | /* Seek to first file in archive */ 23 | zerror = unzGoToFirstFile(zhandle); 24 | if(zerror != UNZ_OK) 25 | { 26 | unzClose(zhandle); 27 | return (NULL); 28 | } 29 | 30 | /* Get information about the file */ 31 | unzGetCurrentFileInfo(zhandle, &zinfo, &name[0], 0xff, NULL, 0, NULL, 0); 32 | 33 | /* Force console if file extension is detected */ 34 | if (strcmp(strrchr(&name[0], '.'), ".col") == 0) option.console = 6; 35 | else if (strcmp(strrchr(&name[0], '.'), ".gg") == 0) option.console = 3; 36 | 37 | *filesize = zinfo.uncompressed_size; 38 | 39 | /* Error: file size is zero */ 40 | if(*filesize == 0) 41 | { 42 | unzClose(zhandle); 43 | return (NULL); 44 | } 45 | 46 | /* Open current file */ 47 | zerror = unzOpenCurrentFile(zhandle); 48 | if(zerror != UNZ_OK) 49 | { 50 | unzClose(zhandle); 51 | return (NULL); 52 | } 53 | 54 | /* Allocate buffer and read in file */ 55 | buffer = malloc(*filesize); 56 | if(!buffer) return (NULL); 57 | zerror = unzReadCurrentFile(zhandle, buffer, *filesize); 58 | 59 | /* Internal error: free buffer and close file */ 60 | if(zerror < 0 || zerror != (int32_t)*filesize) 61 | { 62 | free(buffer); 63 | buffer = NULL; 64 | unzCloseCurrentFile(zhandle); 65 | unzClose(zhandle); 66 | return (NULL); 67 | } 68 | 69 | /* Close current file and archive file */ 70 | unzCloseCurrentFile(zhandle); 71 | unzClose(zhandle); 72 | 73 | memcpy(filename, name, PATH_MAX); 74 | return (buffer); 75 | } 76 | 77 | /* 78 | Verifies if a file is a ZIP archive or not. 79 | Returns: 1= ZIP archive, 0= not a ZIP archive 80 | */ 81 | int32_t check_zip(const char *filename) 82 | { 83 | uint8_t buf[2]; 84 | FILE* fd = NULL; 85 | fd = fopen(filename, "rb"); 86 | if(!fd) return (0); 87 | 88 | fread(buf, 2, 1, fd); 89 | fclose(fd); 90 | if(memcmp(buf, "PK", 2) == 0) return (1); 91 | return (0); 92 | } 93 | -------------------------------------------------------------------------------- /source/unzip/fileio.h: -------------------------------------------------------------------------------- 1 | #ifndef FILEIO_H_ 2 | #define FILEIO_H_ 3 | 4 | #include 5 | 6 | /* Function prototypes */ 7 | uint8_t *loadFromZipByName(char *archive, char *filename, uint32_t *filesize); 8 | int32_t check_zip(const char *filename); 9 | //int gzsize(gzFile *gd); 10 | 11 | #endif /* FILEIO_H_ */ 12 | -------------------------------------------------------------------------------- /source/unzip/minizconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Yamagi Burmeister 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | * SUCH DAMAGE. 25 | * 26 | * -------------------------------------------------------------------- 27 | * 28 | * Some additional definitions required by minizip and not provided 29 | * by the miniz library. 30 | * 31 | * -------------------------------------------------------------------- 32 | */ 33 | 34 | #ifndef COMMON_UNZIP_MINIZCONF_H 35 | #define COMMON_UNZIP_MINIZCONF_H 36 | 37 | #ifndef OF 38 | #define OF(args) args 39 | #endif 40 | 41 | #ifndef ZEXPORT 42 | #define ZEXPORT 43 | #endif 44 | 45 | #ifndef z_off_t 46 | #define z_off_t long 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /source/vdp.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * Sega Master System / GameGear Emulator 3 | * Copyright (C) 1998-2007 Charles MacDonald 4 | * 5 | * additionnal code by Eke-Eke (SMS Plus GX) 6 | * 7 | * This program 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 | * This program 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 this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Video Display Processor (VDP) emulation. 22 | * 23 | ******************************************************************************/ 24 | #ifndef VDP_H_ 25 | #define VDP_H_ 26 | 27 | /* 28 | vdp1 29 | 30 | mode 4 when m4 set and m1 reset 31 | 32 | vdp2 33 | 34 | mode 4 when m4 set and m2,m1 != 1,0 35 | 36 | 37 | */ 38 | 39 | /* VDP context */ 40 | typedef struct 41 | { 42 | uint8_t vram[0x4000]; 43 | uint8_t cram[0x40]; 44 | uint8_t reg[0x10]; 45 | uint8_t vscroll; 46 | uint8_t status; 47 | uint8_t latch; 48 | uint8_t pending; 49 | uint8_t code; 50 | uint8_t buffer; 51 | uint8_t height; 52 | uint8_t extended; 53 | uint8_t irq; 54 | uint8_t vint_pending; 55 | uint8_t hint_pending; 56 | uint8_t spr_ovr; 57 | uint8_t bd; 58 | uint16_t lpf; 59 | uint16_t cram_latch; 60 | uint16_t addr; 61 | int32_t pn, ct, pg, sa, sg; 62 | int32_t ntab; 63 | int32_t satb; 64 | int32_t line; 65 | int32_t left; 66 | int32_t spr_col; 67 | int32_t mode; 68 | } vdp_t; 69 | 70 | /* Global data */ 71 | extern vdp_t vdp; 72 | extern uint8_t hc_256[228]; 73 | 74 | /* Function prototypes */ 75 | extern void vdp_init(void); 76 | extern void vdp_shutdown(void); 77 | extern void vdp_reset(void); 78 | extern void viewport_check(void); 79 | extern uint8_t vdp_counter_r(int32_t offset); 80 | extern uint8_t vdp_read(int32_t offset); 81 | extern void vdp_write(int32_t offset, uint8_t data); 82 | extern void gg_vdp_write(int32_t offset, uint8_t data); 83 | extern void md_vdp_write(int32_t offset, uint8_t data); 84 | extern void tms_write(int32_t offset, uint8_t data); 85 | 86 | #endif /* _VDP_H_ */ 87 | 88 | --------------------------------------------------------------------------------