mirror of
https://github.com/libretro/smsplus-gx.git
synced 2024-11-23 09:09:51 +00:00
Bringing back the proprietary Z80 interpreter. Eighty one is still available but it can't run some games like Dizzy and some SG-1000 games
This commit is contained in:
parent
aac90ffd91
commit
7a2b7ba3d9
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,3 +12,4 @@ include/
|
||||
source/nonfree/
|
||||
sms_sdl
|
||||
*.out
|
||||
log.txt
|
||||
|
6
Makefile
6
Makefile
@ -9,14 +9,14 @@ LD = gcc
|
||||
|
||||
# add SDL dependencies
|
||||
|
||||
CFLAGS = -O2 -std=gnu99 -DINLINE=inline -DLSB_FIRST
|
||||
CFLAGS += -I/usr/include/SDL -Isource -Isource/eighty -Isource/generic -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/crabemu_sn76489
|
||||
CFLAGS = -O2 -pg -std=gnu99 -DINLINE=inline -DLSB_FIRST
|
||||
CFLAGS += -I/usr/include/SDL -Isource -Isource/z80 -Isource/generic -I./source/sound -Isource/unzip -Isource/sdl -Isource/sound/crabemu_sn76489
|
||||
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS = -lSDL -lm -flto -lz -lportaudio
|
||||
|
||||
# Files to be r
|
||||
SRCDIR = ./source ./source/unzip ./source/eighty ./source/sound ./source/generic ./source/amini ./source/sound/crabemu_sn76489
|
||||
SRCDIR = ./source ./source/unzip ./source/z80 ./source/sound ./source/generic ./source/k3s ./source/sound/crabemu_sn76489
|
||||
VPATH = $(SRCDIR)
|
||||
SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c))
|
||||
SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp))
|
||||
|
@ -12,7 +12,7 @@ LD = /opt/rs97-toolchain/bin/mipsel-linux-gcc
|
||||
|
||||
CFLAGS = -fno-pic -fno-pie -Ofast -msym32 -mlong-calls -mno-abicalls -fdata-sections -ffunction-sections -mips32 -mno-shared -mno-mips16
|
||||
CFLAGS += -std=gnu99 -DLSB_FIRST -DMAXIM_PSG
|
||||
CFLAGS += -Isource -Isource/eighty -Isource/generic -I./source/sound -Isource/unzip -Isource/rs97 -Isource/sound/maxim_sn76489 -Iinclude
|
||||
CFLAGS += -Isource -Isource/z80 -Isource/generic -I./source/sound -Isource/unzip -Isource/rs97 -Isource/sound/maxim_sn76489 -Iinclude
|
||||
CFLAGS += -funsafe-math-optimizations -fassociative-math -ffinite-math-only -fsingle-precision-constant -fsection-anchors -falign-functions=2 -mno-check-zero-division
|
||||
#CFLAGS += -fprofile-generate -fprofile-dir=/mnt/int_sd/profile
|
||||
CFLAGS += -fprofile-use
|
||||
@ -21,7 +21,7 @@ CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS = -lSDL -lm -flto -lz -Wl,--as-needed -Wl,--gc-sections -flto -s ./libportaudio.a
|
||||
|
||||
# Files to be r
|
||||
SRCDIR = ./source ./source/unzip ./source/eighty ./source/sound ./source/generic ./source/amini ./source/sound/maxim_sn76489
|
||||
SRCDIR = ./source ./source/unzip ./source/z80 ./source/sound ./source/generic ./source/amini ./source/sound/maxim_sn76489
|
||||
VPATH = $(SRCDIR)
|
||||
SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c))
|
||||
SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp))
|
||||
|
42
Makefile.papk3s
Normal file
42
Makefile.papk3s
Normal file
@ -0,0 +1,42 @@
|
||||
PRGNAME = sms_sdl
|
||||
|
||||
# define regarding OS, which compiler to use
|
||||
EXESUFFIX =
|
||||
TOOLCHAIN =
|
||||
CC = /opt/rs97-toolchain/bin/mipsel-linux-gcc
|
||||
CCP = /opt/rs97-toolchain/bin/mipsel-linux-g++
|
||||
LD = /opt/rs97-toolchain/bin/mipsel-linux-gcc
|
||||
|
||||
# add SDL dependencies
|
||||
|
||||
#-msym32 -mlong-calls
|
||||
CFLAGS = -Ofast -fno-pic -fno-pie -mno-abicalls -fdata-sections -ffunction-sections -mips32 -mno-shared -mno-mips16
|
||||
CFLAGS += -std=gnu99 -DLSB_FIRST -DMAXIM_PSG
|
||||
CFLAGS += -Isource -Isource/z80 -Isource/generic -I./source/sound -Isource/unzip -Isource/rs97 -Isource/sound/maxim_sn76489 -Iinclude
|
||||
CFLAGS += -fprofile-generate -fprofile-dir=/mnt/int_sd/profile -funsafe-math-optimizations -fassociative-math -ffinite-math-only -fsingle-precision-constant -fsection-anchors -falign-functions=2 -mno-check-zero-division
|
||||
#CFLAGS += -fprofile-use -msym32 -mlong-calls -fno-math-errno -funsafe-math-optimizations -fassociative-math -ffinite-math-only -fsingle-precision-constant -fsection-anchors -falign-functions=2 -mno-check-zero-division
|
||||
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS = -lSDL -lm -flto -lz -Wl,--as-needed -Wl,--gc-sections -flto -s ./libportaudio.a
|
||||
|
||||
# Files to be r
|
||||
SRCDIR = ./source ./source/unzip ./source/z80 ./source/sound ./source/generic ./source/k3s ./source/sound/maxim_sn76489
|
||||
VPATH = $(SRCDIR)
|
||||
SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c))
|
||||
SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp))
|
||||
OBJ_C = $(notdir $(patsubst %.c, %.o, $(SRC_C)))
|
||||
OBJ_CP = $(notdir $(patsubst %.cpp, %.o, $(SRC_CP)))
|
||||
OBJS = $(OBJ_C) $(OBJ_CP)
|
||||
|
||||
# Rules to make executable
|
||||
$(PRGNAME)$(EXESUFFIX): $(OBJS)
|
||||
$(LD) $(CFLAGS) -o $(PRGNAME)$(EXESUFFIX) $^ $(LDFLAGS)
|
||||
|
||||
$(OBJ_C) : %.o : %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(OBJ_CP) : %.o : %.cpp
|
||||
$(CCP) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(PRGNAME)$(EXESUFFIX) *.o
|
@ -12,7 +12,7 @@ LD = /opt/rs97-toolchain/bin/mipsel-linux-gcc
|
||||
#-msym32 -mlong-calls
|
||||
CFLAGS = -Ofast -fno-pic -fno-pie -mno-abicalls -fdata-sections -ffunction-sections -mips32 -mno-shared -mno-mips16
|
||||
CFLAGS += -std=gnu99 -DLSB_FIRST -DMAXIM_PSG
|
||||
CFLAGS += -Isource -Isource/eighty -Isource/generic -I./source/sound -Isource/unzip -Isource/rs97 -Isource/sound/maxim_sn76489 -Iinclude
|
||||
CFLAGS += -Isource -Isource/z80 -Isource/generic -I./source/sound -Isource/unzip -Isource/rs97 -Isource/sound/maxim_sn76489 -Iinclude
|
||||
#CFLAGS += -fprofile-generate -fprofile-dir=/mnt/int_sd/profile -funsafe-math-optimizations -fassociative-math -ffinite-math-only -fsingle-precision-constant -fsection-anchors -falign-functions=2 -mno-check-zero-division
|
||||
CFLAGS += -fprofile-use -msym32 -mlong-calls -fno-math-errno -funsafe-math-optimizations -fassociative-math -ffinite-math-only -fsingle-precision-constant -fsection-anchors -falign-functions=2 -mno-check-zero-division
|
||||
|
||||
@ -20,7 +20,7 @@ CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS = -lSDL -lm -flto -lz -Wl,--as-needed -Wl,--gc-sections -flto -s ./libportaudio.a
|
||||
|
||||
# Files to be r
|
||||
SRCDIR = ./source ./source/unzip ./source/eighty ./source/sound ./source/generic ./source/rs97 ./source/sound/maxim_sn76489
|
||||
SRCDIR = ./source ./source/unzip ./source/z80 ./source/sound ./source/generic ./source/rs97 ./source/sound/maxim_sn76489
|
||||
VPATH = $(SRCDIR)
|
||||
SRC_C = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.c))
|
||||
SRC_CP = $(foreach dir, $(SRCDIR), $(wildcard $(dir)/*.cpp))
|
||||
|
BIN
background_papk3s.bmp
Normal file
BIN
background_papk3s.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
@ -245,6 +245,51 @@ void upscale_SMS_to_320x240(uint32_t *dst, uint32_t *src, uint32_t height_scale)
|
||||
}
|
||||
}
|
||||
|
||||
void upscale_SMS_to_800x480(uint32_t *dst, uint32_t *src, uint32_t height_scale)
|
||||
{
|
||||
int midh = 480 >> 1;
|
||||
int Eh = 0;
|
||||
int source = 0, target = 0;
|
||||
int dh = 0;
|
||||
int i, j;
|
||||
uint32_t a, b;
|
||||
|
||||
for (i = 0; i < 480; i++)
|
||||
{
|
||||
//Ew = 0;
|
||||
source = dh * height_scale;
|
||||
|
||||
for (j = 0; j < 800/2; j++)
|
||||
{
|
||||
|
||||
__builtin_prefetch(dst + 4, 1);
|
||||
__builtin_prefetch(src + source + 4, 0);
|
||||
|
||||
a = src[source] & 0xF7DEF7DE;
|
||||
|
||||
#define AVERAGE(z, x) ((((z) & 0xF7DEF7DE) >> 1) + (((x) & 0xF7DEF7DE) >> 1))
|
||||
if(Eh >= midh) { // average + 320
|
||||
a = AVERAGE(a, src[source+160]);
|
||||
}
|
||||
#undef AVERAGE
|
||||
|
||||
b = a & 0xFFFF0000;
|
||||
b |= (b >> 16);
|
||||
|
||||
a &= 0xFFFF;
|
||||
a |= (a << 16);
|
||||
|
||||
*dst++ = a;
|
||||
*dst++ = b;
|
||||
|
||||
source += 4;
|
||||
|
||||
}
|
||||
Eh += height_scale; if(Eh >= 480) { Eh -= 480; dh++; } // 160 - real gba y size
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Retro Arcade Mini scalers. Boo, ugly */
|
||||
|
||||
@ -297,6 +342,55 @@ void upscale_160x144_to_320x272_for_480x272(uint32_t *dst, uint32_t *src)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void upscale_160x144_to_320x272_for_800x480(uint32_t *dst, uint32_t *src)
|
||||
{
|
||||
int midh = 480 / 2;
|
||||
int Eh = 0;
|
||||
int source = 0;
|
||||
int dh = 0;
|
||||
int i, j;
|
||||
|
||||
dst += (800-320)/4; // center correction for 800x480 mode
|
||||
|
||||
for (i = 0; i < 480; i++)
|
||||
{
|
||||
source = dh * 256 / 2;
|
||||
|
||||
for (j = 0; j < 800/8; j++)
|
||||
{
|
||||
uint32_t a, b, c, d, ab, cd;
|
||||
|
||||
__builtin_prefetch(dst + 4, 1);
|
||||
__builtin_prefetch(src + source + 4, 0);
|
||||
|
||||
ab = src[source] & 0xF7DEF7DE;
|
||||
cd = src[source + 1] & 0xF7DEF7DE;
|
||||
|
||||
/*if(Eh >= midh) {
|
||||
ab = AVERAGE(ab, src[source+256/2]);
|
||||
cd = AVERAGE(cd, src[source+256/2+1]);
|
||||
}*/
|
||||
|
||||
a = (ab & 0xFFFF) | (ab << 16);
|
||||
b = (ab & 0xFFFF0000) | (ab >> 16);
|
||||
c = (cd & 0xFFFF) | (cd << 16);
|
||||
d = (cd & 0xFFFF0000) | (cd >> 16);
|
||||
|
||||
*dst++ = a;
|
||||
*dst++ = b;
|
||||
*dst++ = c;
|
||||
*dst++ = d;
|
||||
|
||||
source += 2;
|
||||
|
||||
}
|
||||
dst += (800-320)/2; // pitch correction for 800x480 mode
|
||||
Eh += 144; if(Eh >= 480) { Eh -= 480; dh++; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void upscale_160x144_to_480x272(uint32_t *dst, uint32_t *src)
|
||||
{
|
||||
int midh = 272 / 2;
|
||||
@ -345,6 +439,55 @@ void upscale_160x144_to_480x272(uint32_t *dst, uint32_t *src)
|
||||
}
|
||||
}
|
||||
|
||||
void upscale_160x144_to_800x480(uint32_t *dst, uint32_t *src)
|
||||
{
|
||||
int midh = 480 / 2;
|
||||
int Eh = 0;
|
||||
int source = 0;
|
||||
int dh = 0;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 480; i++)
|
||||
{
|
||||
source = dh * 256 / 2;
|
||||
|
||||
for (j = 0; j < 800/12; j++)
|
||||
{
|
||||
uint32_t a, b, c, d, e, f, ab, cd;
|
||||
|
||||
__builtin_prefetch(dst + 4, 1);
|
||||
__builtin_prefetch(src + source + 4, 0);
|
||||
|
||||
ab = src[source] & 0xF7DEF7DE;
|
||||
cd = src[source + 1] & 0xF7DEF7DE;
|
||||
|
||||
/*if(Eh >= midh) {
|
||||
ab = AVERAGE(ab, src[source+256/2]);
|
||||
cd = AVERAGE(cd, src[source+256/2+1]);
|
||||
}*/
|
||||
|
||||
a = (ab & 0xFFFF) | (ab << 16);
|
||||
b = ab;
|
||||
c = (ab & 0xFFFF0000) | (ab >> 16);
|
||||
d = (cd & 0xFFFF) | (cd << 16);
|
||||
e = cd;
|
||||
f = (cd & 0xFFFF0000) | (cd >> 16);
|
||||
|
||||
*dst++ = a;
|
||||
*dst++ = b;
|
||||
*dst++ = c;
|
||||
*dst++ = d;
|
||||
*dst++ = e;
|
||||
*dst++ = f;
|
||||
|
||||
source += 2;
|
||||
|
||||
}
|
||||
Eh += 144; if(Eh >= 272) { Eh -= 272; dh++; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void upscale_256x192_to_384x272_for_480x272(uint32_t *dst, uint32_t *src)
|
||||
{
|
||||
int midh = 272 / 2;
|
||||
@ -386,6 +529,48 @@ void upscale_256x192_to_384x272_for_480x272(uint32_t *dst, uint32_t *src)
|
||||
}
|
||||
}
|
||||
|
||||
void upscale_256x192_to_384x272_for_800x480(uint32_t *dst, uint32_t *src)
|
||||
{
|
||||
int midh = 480 / 2;
|
||||
int Eh = 0;
|
||||
int source = 0;
|
||||
int dh = 0;
|
||||
int y, x;
|
||||
|
||||
dst += (800 - 384) / 4;
|
||||
|
||||
for (y = 0; y < 480; y++)
|
||||
{
|
||||
source = dh * 256 / 2;
|
||||
|
||||
for (x = 0; x < 384/6; x++)
|
||||
{
|
||||
register uint32_t ab, cd;
|
||||
|
||||
__builtin_prefetch(dst + 4, 1);
|
||||
__builtin_prefetch(src + source + 4, 0);
|
||||
|
||||
ab = src[source] & 0xF7DEF7DE;
|
||||
cd = src[source + 1] & 0xF7DEF7DE;
|
||||
|
||||
/*if(Eh >= midh) {
|
||||
ab = AVERAGE(ab, src[source + 256/2]) & 0xF7DEF7DE; // to prevent overflow
|
||||
cd = AVERAGE(cd, src[source + 256/2 + 1]) & 0xF7DEF7DE; // to prevent overflow
|
||||
}*/
|
||||
|
||||
*dst++ = (ab & 0xFFFF) + AVERAGEHI(ab);
|
||||
*dst++ = (ab >> 16) + ((cd & 0xFFFF) << 16);
|
||||
*dst++ = (cd & 0xFFFF0000) + AVERAGELO(cd);
|
||||
|
||||
source += 2;
|
||||
|
||||
}
|
||||
dst += (800 - 384) / 2;
|
||||
Eh += 192; if(Eh >= 480) { Eh -= 480; dh++; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void upscale_256x192_to_480x272(uint32_t *dst, uint32_t *src)
|
||||
{
|
||||
int midh = 272 / 2;
|
||||
@ -446,3 +631,49 @@ void upscale_256x192_to_480x272(uint32_t *dst, uint32_t *src)
|
||||
Eh += 192; if(Eh >= 272) { Eh -= 272; dh++; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void upscale_256x192_to_800x480(uint32_t *dst, uint32_t *src, uint32_t height_scale)
|
||||
{
|
||||
int midh = 480 / 2;
|
||||
int Eh = 0;
|
||||
int source = 0;
|
||||
int dh = 0;
|
||||
int y, x;
|
||||
|
||||
for (y = 0; y < 480; y++)
|
||||
{
|
||||
source = dh * 256 / 2;
|
||||
|
||||
for (x = 0; x < 800/12; x++)
|
||||
{
|
||||
register uint32_t ab, cd, ef, gh;
|
||||
|
||||
__builtin_prefetch(dst + 4, 1);
|
||||
__builtin_prefetch(src + source + 4, 0);
|
||||
|
||||
ab = src[source] & 0xF7DEF7DE;
|
||||
cd = src[source + 1] & 0xF7DEF7DE;
|
||||
ef = src[source + 2] & 0xF7DEF7DE;
|
||||
gh = src[source + 3] & 0xF7DEF7DE;
|
||||
|
||||
if(Eh >= midh) {
|
||||
ab = AVERAGE(ab, src[source + 256/2]) & 0xF7DEF7DE; // to prevent overflow
|
||||
cd = AVERAGE(cd, src[source + 256/2 + 1]) & 0xF7DEF7DE; // to prevent overflow
|
||||
ef = AVERAGE(ef, src[source + 256/2 + 2]) & 0xF7DEF7DE; // to prevent overflow
|
||||
gh = AVERAGE(gh, src[source + 256/2 + 3]) & 0xF7DEF7DE; // to prevent overflow
|
||||
}
|
||||
|
||||
*dst++ = ab;
|
||||
*dst++ = ((ab >> 17) + ((cd & 0xFFFF) >> 1)) + (cd << 16);
|
||||
*dst++ = (cd >> 16) + (ef << 16);
|
||||
*dst++ = (ef >> 16) + (((ef & 0xFFFF0000) >> 1) + ((gh & 0xFFFF) << 15));
|
||||
*dst++ = gh;
|
||||
|
||||
source += 4;
|
||||
|
||||
}
|
||||
Eh += height_scale; if(Eh >= 480) { Eh -= 480; dh++; }
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -9,8 +9,15 @@ void upscale_160x144_to_320x480(uint32_t *dst, uint32_t *src);
|
||||
|
||||
void upscale_SMS_to_320x240(uint32_t *dst, uint32_t *src, uint32_t height_scale);
|
||||
void upscale_SMS_to_320x480(uint32_t *dst, uint32_t *src, uint32_t height_scale);
|
||||
void upscale_SMS_to_800x480(uint32_t *dst, uint32_t *src, uint32_t height_scale);
|
||||
|
||||
void upscale_160x144_to_800x480(uint32_t *dst, uint32_t *src);
|
||||
//void upscale_256x192_to_800x480(uint32_t *dst, uint32_t *src, uint32_t height_scale);
|
||||
|
||||
void upscale_160x144_to_320x272_for_800x480(uint32_t *dst, uint32_t *src);
|
||||
|
||||
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 *src, uint16_t *dst);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
872
source/k3s/smsplus.c
Normal file
872
source/k3s/smsplus.c
Normal file
@ -0,0 +1,872 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include "shared.h"
|
||||
#include "scaler.h"
|
||||
#include "smsplus.h"
|
||||
#include "text_gui.h"
|
||||
#include "bigfontwhite.h"
|
||||
#include "bigfontred.h"
|
||||
#include "font.h"
|
||||
#include <portaudio.h>
|
||||
|
||||
static t_sdl_sound sdl_sound;
|
||||
static t_sdl_sync sdl_sync;
|
||||
uint32_t frames_rendered = 0;
|
||||
gamedata_t gdata;
|
||||
|
||||
t_config option;
|
||||
|
||||
SDL_Surface* sdl_screen, *sms_bitmap;
|
||||
static SDL_Surface* img_background;
|
||||
uint32_t countedFrames = 0;
|
||||
uint32_t start;
|
||||
|
||||
static SDL_Joystick* joystick[2];
|
||||
|
||||
extern SDL_Surface *font;
|
||||
extern SDL_Surface *bigfontred;
|
||||
extern SDL_Surface *bigfontwhite;
|
||||
|
||||
int8_t fullscreen = 1;
|
||||
uint8_t selectpressed = 0;
|
||||
uint8_t save_slot = 0;
|
||||
uint8_t showfps = 0;
|
||||
uint8_t quit = 0;
|
||||
|
||||
#define SOUND_FREQUENCY 48000
|
||||
#define SOUND_SAMPLES_SIZE 2048
|
||||
static int16_t buffer_snd[SOUND_FREQUENCY * 2];
|
||||
|
||||
/* Sound */
|
||||
|
||||
PaStream *apu_stream;
|
||||
|
||||
static uint32_t Sound_Init()
|
||||
{
|
||||
int32_t err;
|
||||
err = Pa_Initialize();
|
||||
|
||||
PaStreamParameters outputParameters;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
outputParameters.channelCount = 2;
|
||||
outputParameters.sampleFormat = paInt16;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream( &apu_stream, NULL, &outputParameters, SOUND_FREQUENCY, SOUND_SAMPLES_SIZE, paNoFlag, NULL, NULL);
|
||||
err = Pa_StartStream( apu_stream );
|
||||
|
||||
option.sndrate = SOUND_FREQUENCY;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void Sound_Update()
|
||||
{
|
||||
uint32_t i;
|
||||
const float volumeMultiplier = 6.0f;
|
||||
for (i = 0; i < (4 * (SOUND_FREQUENCY / snd.fps)); i++)
|
||||
{
|
||||
buffer_snd[i * 2] = snd.output[1][i] * volumeMultiplier;
|
||||
buffer_snd[i * 2 + 1] = snd.output[0][i] * volumeMultiplier;
|
||||
}
|
||||
Pa_WriteStream( apu_stream, buffer_snd, SOUND_FREQUENCY / snd.fps );
|
||||
}
|
||||
|
||||
static void Sound_Close()
|
||||
{
|
||||
int32_t err;
|
||||
err = Pa_CloseStream( apu_stream );
|
||||
err = Pa_Terminate();
|
||||
}
|
||||
|
||||
static void video_update()
|
||||
{
|
||||
SDL_Rect dst, dstT;
|
||||
|
||||
SDL_LockSurface(sdl_screen);
|
||||
switch(fullscreen)
|
||||
{
|
||||
case 3: // FullScreen (No cropping)
|
||||
if (sms.console == CONSOLE_GG)
|
||||
{
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
dst.w = sdl_screen->w;
|
||||
dst.h = sdl_screen->h;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = 160;
|
||||
dstT.h = 144;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
dst.w = sdl_screen->w;
|
||||
dst.h = sdl_screen->h;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = VIDEO_WIDTH_SMS-dstT.x;
|
||||
dstT.h = vdp.height;
|
||||
}
|
||||
break;
|
||||
case 2: // Fullscreen (cropped)
|
||||
if (sms.console == CONSOLE_GG)
|
||||
{
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
dst.w = sdl_screen->w;
|
||||
dst.h = sdl_screen->h;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = 160;
|
||||
dstT.h = 144;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
dst.w = sdl_screen->w;
|
||||
dst.h = sdl_screen->h;
|
||||
if ((bitmap.data[0] == bitmap.data[4]))
|
||||
{
|
||||
dstT.x = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstT.x = 0;
|
||||
}
|
||||
dstT.y = 0;
|
||||
dstT.w = VIDEO_WIDTH_SMS-dstT.x;
|
||||
dstT.h = vdp.height;
|
||||
}
|
||||
break;
|
||||
case 1: // Stretch (keep aspect ratio)
|
||||
if (sms.console == CONSOLE_GG)
|
||||
{
|
||||
dst.x = 80;
|
||||
dst.y = 0;
|
||||
dst.w = 320;
|
||||
dst.h = 144*2;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = 160;
|
||||
dstT.h = 144;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.x = 80;
|
||||
dst.y = 0;
|
||||
dst.w = 640;
|
||||
dst.h = sdl_screen->h;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = VIDEO_WIDTH_SMS;
|
||||
dstT.h = vdp.height;
|
||||
}
|
||||
break;
|
||||
case 0: // native res
|
||||
if (sms.console == CONSOLE_GG)
|
||||
{
|
||||
dst.x = 0;
|
||||
dst.y = 0;
|
||||
dst.w = 160*3;
|
||||
dst.h = 144*3;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = 160;
|
||||
dstT.h = 144;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.x = 148;
|
||||
dst.y = (480-(vdp.height*2))/2;
|
||||
dst.w = 512;
|
||||
dst.h = vdp.height*2;
|
||||
dstT.x = 0;
|
||||
dstT.y = 0;
|
||||
dstT.w = VIDEO_WIDTH_SMS;
|
||||
dstT.h = vdp.height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
SDL_SoftStretch(sms_bitmap, &dstT, sdl_screen, &dst);
|
||||
SDL_UnlockSurface(sdl_screen);
|
||||
}
|
||||
|
||||
void smsp_state(uint8_t slot, uint8_t mode)
|
||||
{
|
||||
// Save and Load States
|
||||
int8_t stpath[PATH_MAX];
|
||||
snprintf(stpath, sizeof(stpath), "%s%s.st%d", gdata.stdir, gdata.gamename, slot);
|
||||
printf("Path state %s\n", stpath);
|
||||
FILE *fd;
|
||||
|
||||
switch(mode) {
|
||||
case 0:
|
||||
fd = fopen(stpath, "wb");
|
||||
if (fd) {
|
||||
system_save_state(fd);
|
||||
fclose(fd);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fd = fopen(stpath, "rb");
|
||||
if (fd) {
|
||||
system_load_state(fd);
|
||||
fclose(fd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void system_manage_sram(uint8_t *sram, uint8_t slot, uint8_t mode)
|
||||
{
|
||||
// Set up save file name
|
||||
FILE *fd;
|
||||
switch(mode)
|
||||
{
|
||||
case SRAM_SAVE:
|
||||
if(sms.save)
|
||||
{
|
||||
fd = fopen(gdata.sramfile, "wb");
|
||||
if (fd)
|
||||
{
|
||||
fwrite(sram, 0x8000, 1, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SRAM_LOAD:
|
||||
fd = fopen(gdata.sramfile, "rb");
|
||||
if (fd)
|
||||
{
|
||||
sms.save = 1;
|
||||
fread(sram, 0x8000, 1, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
else
|
||||
memset(sram, 0x00, 0x8000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int sdl_controls_update_input(SDLKey k, int32_t p)
|
||||
{
|
||||
if (sms.console == CONSOLE_COLECO)
|
||||
{
|
||||
input.system = 0;
|
||||
coleco.keypad[0] = 0xff;
|
||||
coleco.keypad[1] = 0xff;
|
||||
}
|
||||
|
||||
switch(k)
|
||||
{
|
||||
case SDLK_ESCAPE:
|
||||
if(p)
|
||||
selectpressed = 1;
|
||||
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
if(p)
|
||||
input.system |= (sms.console == CONSOLE_GG) ? INPUT_START : INPUT_PAUSE;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
if(p)
|
||||
input.pad[0] |= INPUT_UP;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
if(p)
|
||||
input.pad[0] |= INPUT_DOWN;
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
if(p)
|
||||
input.pad[0] |= INPUT_LEFT;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
if(p)
|
||||
input.pad[0] |= INPUT_RIGHT;
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
if(p)
|
||||
input.pad[0] |= INPUT_BUTTON1;
|
||||
break;
|
||||
case SDLK_LALT:
|
||||
if(p)
|
||||
input.pad[0] |= INPUT_BUTTON2;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void bios_init()
|
||||
{
|
||||
FILE *fd;
|
||||
int8_t bios_path[256];
|
||||
|
||||
bios.rom = malloc(0x100000);
|
||||
bios.enabled = 0;
|
||||
|
||||
snprintf(bios_path, sizeof(bios_path), "%s%s", gdata.biosdir, "BIOS.sms");
|
||||
|
||||
fd = fopen("bios.sms", "rb");
|
||||
if(fd)
|
||||
{
|
||||
/* Seek to end of file, and get size */
|
||||
fseek(fd, 0, SEEK_END);
|
||||
uint32_t size = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
if (size < 0x4000) size = 0x4000;
|
||||
fread(bios.rom, size, 1, fd);
|
||||
bios.enabled = 2;
|
||||
bios.pages = size / 0x4000;
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
snprintf(bios_path, sizeof(bios_path), "%s%s", gdata.biosdir, "BIOS.col");
|
||||
|
||||
fd = fopen("bios.col", "rb");
|
||||
if(fd)
|
||||
{
|
||||
/* Seek to end of file, and get size */
|
||||
fread(coleco.rom, 0x2000, 1, fd);
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void smsp_gamedata_set(int8_t *filename)
|
||||
{
|
||||
// Set paths, create directories
|
||||
int8_t home_path[256];
|
||||
snprintf(home_path, sizeof(home_path), "%s/.smsplus/", getenv("HOME"));
|
||||
|
||||
if (mkdir(home_path, 0755) && errno != EEXIST) {
|
||||
fprintf(stderr, "Failed to create %s: %d\n", home_path, errno);
|
||||
}
|
||||
|
||||
// Set the game name
|
||||
snprintf(gdata.gamename, sizeof(gdata.gamename), "%s", basename(filename));
|
||||
|
||||
// Strip the file extension off
|
||||
for (int i = strlen(gdata.gamename) - 1; i > 0; i--) {
|
||||
if (gdata.gamename[i] == '.') {
|
||||
gdata.gamename[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the sram directory
|
||||
snprintf(gdata.sramdir, sizeof(gdata.sramdir), "%ssram/", home_path);
|
||||
if (mkdir(gdata.sramdir, 0755) && errno != EEXIST) {
|
||||
fprintf(stderr, "Failed to create %s: %d\n", gdata.sramdir, errno);
|
||||
}
|
||||
|
||||
// Set up the sram file
|
||||
snprintf(gdata.sramfile, sizeof(gdata.sramfile), "%s%s%s.sav", home_path, gdata.sramdir, gdata.gamename);
|
||||
|
||||
// Set up the state directory
|
||||
snprintf(gdata.stdir, sizeof(gdata.stdir), "%sstate/", home_path);
|
||||
if (mkdir(gdata.stdir, 0755) && errno != EEXIST) {
|
||||
fprintf(stderr, "Failed to create %s: %d\n", gdata.stdir, errno);
|
||||
}
|
||||
|
||||
// Set up the screenshot directory
|
||||
snprintf(gdata.scrdir, sizeof(gdata.scrdir), "%sscreenshots/", home_path);
|
||||
if (mkdir(gdata.scrdir, 0755) && errno != EEXIST) {
|
||||
fprintf(stderr, "Failed to create %s: %d\n", gdata.scrdir, errno);
|
||||
}
|
||||
|
||||
// Set up the sram directory
|
||||
snprintf(gdata.biosdir, sizeof(gdata.biosdir), "%sbios/", home_path);
|
||||
if (mkdir(gdata.biosdir, 0755) && errno != EEXIST) {
|
||||
fprintf(stderr, "Failed to create %s: %d\n", gdata.sramdir, errno);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Menu()
|
||||
{
|
||||
int16_t pressed = 0;
|
||||
int16_t currentselection = 1;
|
||||
uint16_t miniscreenwidth = 140;
|
||||
uint16_t miniscreenheight = 135;
|
||||
SDL_Rect dstRect;
|
||||
int8_t *cmd = NULL;
|
||||
SDL_Event Event;
|
||||
/* Seriously, we need that mess due to crappy framebuffer drivers on the RS-07... */
|
||||
SDL_Surface* miniscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, miniscreenwidth, miniscreenheight, 16, sdl_screen->format->Rmask, sdl_screen->format->Gmask, sdl_screen->format->Bmask, sdl_screen->format->Amask);
|
||||
SDL_Surface* black_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, sdl_screen->w, sdl_screen->h, 16, sdl_screen->format->Rmask, sdl_screen->format->Gmask, sdl_screen->format->Bmask, sdl_screen->format->Amask);
|
||||
SDL_Surface* final_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, sdl_screen->w, sdl_screen->h, 16, sdl_screen->format->Rmask, sdl_screen->format->Gmask, sdl_screen->format->Bmask, sdl_screen->format->Amask);
|
||||
SDL_FillRect( black_screen, NULL, 0 );
|
||||
|
||||
SDL_LockSurface(miniscreen);
|
||||
if(IS_GG)
|
||||
bitmap_scale(48,0,160,144,miniscreenwidth,miniscreenheight,256,0,(uint16_t*)sms_bitmap->pixels,(uint16_t*)miniscreen->pixels);
|
||||
else
|
||||
bitmap_scale(0,0,256,192,miniscreenwidth,miniscreenheight,256,0,(uint16_t*)sms_bitmap->pixels,(uint16_t*)miniscreen->pixels);
|
||||
|
||||
SDL_UnlockSurface(miniscreen);
|
||||
char text[50];
|
||||
|
||||
SDL_PollEvent(&Event);
|
||||
while (((currentselection != 1) && (currentselection != 5)) || (!pressed))
|
||||
{
|
||||
pressed = 0;
|
||||
|
||||
dstRect.x = sdl_screen->w-5-miniscreenwidth;
|
||||
dstRect.y = 30;
|
||||
if (!img_background) SDL_BlitSurface(black_screen,NULL,final_screen,NULL);
|
||||
else SDL_BlitSurface(img_background,NULL,final_screen,NULL);
|
||||
SDL_BlitSurface(miniscreen,NULL,final_screen,&dstRect);
|
||||
|
||||
gfx_font_print_center(final_screen,22,bigfontwhite,"SMSPlus-GX");
|
||||
|
||||
if (currentselection == 1)
|
||||
gfx_font_print(final_screen,5,25,bigfontred,"Continue");
|
||||
else
|
||||
gfx_font_print(final_screen,5,25,bigfontwhite,"Continue");
|
||||
|
||||
sprintf(text,"Save State %d",save_slot);
|
||||
|
||||
if (currentselection == 2)
|
||||
gfx_font_print(final_screen,5,65,bigfontred,text);
|
||||
else
|
||||
gfx_font_print(final_screen,5,65,bigfontwhite,text);
|
||||
|
||||
sprintf(text,"Load State %d",save_slot);
|
||||
|
||||
if (currentselection == 3)
|
||||
gfx_font_print(final_screen,5,85,bigfontred,text);
|
||||
else
|
||||
gfx_font_print(final_screen,5,85,bigfontwhite,text);
|
||||
|
||||
if (currentselection == 4)
|
||||
{
|
||||
switch (fullscreen)
|
||||
{
|
||||
case 0:
|
||||
gfx_font_print(final_screen,5,105,bigfontred,"Native resolution");
|
||||
break;
|
||||
case 1:
|
||||
gfx_font_print(final_screen,5,105,bigfontred,"Keep Aspect Ratio");
|
||||
break;
|
||||
case 2:
|
||||
gfx_font_print(final_screen,5,105,bigfontred,"Fullscreen (Auto-Crop)");
|
||||
break;
|
||||
case 3:
|
||||
gfx_font_print(final_screen,5,105,bigfontred,"Fullscreen (No Crop)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (fullscreen)
|
||||
{
|
||||
case 0:
|
||||
gfx_font_print(final_screen,5,105,bigfontwhite,"Native resolution");
|
||||
break;
|
||||
case 1:
|
||||
gfx_font_print(final_screen,5,105,bigfontwhite,"Keep Aspect Ratio");
|
||||
break;
|
||||
case 2:
|
||||
gfx_font_print(final_screen,5,105,bigfontwhite,"Fullscreen (Auto-Crop)");
|
||||
break;
|
||||
case 3:
|
||||
gfx_font_print(final_screen,5,105,bigfontwhite,"Fullscreen (No Crop)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentselection == 5)
|
||||
gfx_font_print(final_screen,5,125,bigfontred,"Quit");
|
||||
else
|
||||
gfx_font_print(final_screen,5,125,bigfontwhite,"Quit");
|
||||
|
||||
gfx_font_print_center(final_screen,sdl_screen->h-80-gfx_font_height(font),font,"SMS_SDL for the RS-97");
|
||||
gfx_font_print_center(final_screen,sdl_screen->h-70-gfx_font_height(font),font,"RS-97 port by gameblabla");
|
||||
gfx_font_print_center(final_screen,sdl_screen->h-60-gfx_font_height(font),font,"See full credits on github:");
|
||||
gfx_font_print_center(final_screen,sdl_screen->h-50-gfx_font_height(font),font,"https://github.com/gameblabla/sms_sdl");
|
||||
|
||||
|
||||
|
||||
for(uint8_t i = 0; i < 2; i++)
|
||||
{
|
||||
if (joystick[i] == NULL) joystick[i] = SDL_JoystickOpen(i);
|
||||
}
|
||||
|
||||
while (SDL_PollEvent(&Event))
|
||||
{
|
||||
switch(Event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
switch(Event.key.keysym.sym)
|
||||
{
|
||||
case SDLK_UP:
|
||||
currentselection--;
|
||||
if (currentselection == 0)
|
||||
currentselection = 5;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
currentselection++;
|
||||
if (currentselection == 6)
|
||||
currentselection = 1;
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
case SDLK_LALT:
|
||||
case SDLK_RETURN:
|
||||
pressed = 1;
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
switch(currentselection)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
if (save_slot > 0) save_slot--;
|
||||
break;
|
||||
case 4:
|
||||
fullscreen--;
|
||||
if (fullscreen < 0)
|
||||
fullscreen = 3;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
switch(currentselection)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
save_slot++;
|
||||
if (save_slot == 10)
|
||||
save_slot = 9;
|
||||
break;
|
||||
case 4:
|
||||
fullscreen++;
|
||||
if (fullscreen > 3)
|
||||
fullscreen = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_JOYAXISMOTION:
|
||||
if (Event.jaxis.axis == 0)
|
||||
{
|
||||
if (Event.jaxis.value < -500)
|
||||
{
|
||||
switch(currentselection)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
if (save_slot > 0) save_slot--;
|
||||
break;
|
||||
case 4:
|
||||
fullscreen--;
|
||||
if (fullscreen < 0)
|
||||
fullscreen = 3;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else if (Event.jaxis.value > 500)
|
||||
{
|
||||
switch(currentselection)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
save_slot++;
|
||||
if (save_slot == 10)
|
||||
save_slot = 9;
|
||||
break;
|
||||
case 4:
|
||||
fullscreen++;
|
||||
if (fullscreen > 3)
|
||||
fullscreen = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Event.jaxis.axis == 1)
|
||||
{
|
||||
if (Event.jaxis.value < -500)
|
||||
{
|
||||
currentselection--;
|
||||
if (currentselection == 0)
|
||||
currentselection = 5;
|
||||
}
|
||||
else if (Event.jaxis.value > 500)
|
||||
{
|
||||
currentselection++;
|
||||
if (currentselection == 6)
|
||||
currentselection = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
switch(Event.jbutton.button)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
pressed = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
switch(currentselection)
|
||||
{
|
||||
case 4 :
|
||||
fullscreen++;
|
||||
if (fullscreen > 3)
|
||||
fullscreen = 0;
|
||||
break;
|
||||
case 2 :
|
||||
smsp_state(save_slot, 0);
|
||||
currentselection = 1;
|
||||
break;
|
||||
case 3 :
|
||||
smsp_state(save_slot, 1);
|
||||
currentselection = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_BlitSurface(final_screen, NULL, sdl_screen, NULL);
|
||||
SDL_Flip(sdl_screen);
|
||||
//++sdl_video.frames_rendered;
|
||||
}
|
||||
|
||||
if (currentselection == 5)
|
||||
quit = 1;
|
||||
if (quit)
|
||||
{
|
||||
SDL_FreeSurface(miniscreen);
|
||||
SDL_FreeSurface(black_screen);
|
||||
SDL_FreeSurface(final_screen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int16_t x_move = 0, y_move = 0;
|
||||
Uint8 *keystate;
|
||||
SDL_Event event;
|
||||
// Print Header
|
||||
fprintf(stdout, "%s %s\n", APP_NAME, APP_VERSION);
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: ./smsplus [FILE]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&option, 0, sizeof(option));
|
||||
|
||||
option.fm = 1;
|
||||
option.spritelimit = 0;
|
||||
option.filter = -1;
|
||||
option.country = 0;
|
||||
option.overscan = 0;
|
||||
option.tms_pal = 2;
|
||||
option.console = 0;
|
||||
option.nosound = 0;
|
||||
|
||||
strcpy(option.game_name, argv[1]);
|
||||
|
||||
smsp_gamedata_set(argv[1]);
|
||||
|
||||
// Check the type of ROM
|
||||
sms.console = strcmp(strrchr(argv[1], '.'), ".gg") ? CONSOLE_SMS : CONSOLE_GG;
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
sdl_screen = SDL_SetVideoMode(800, 480, 16, SDL_HWSURFACE);
|
||||
SDL_SetCursor(0);
|
||||
|
||||
// Needed in order to clear the cursor
|
||||
SDL_FillRect( sdl_screen, NULL, 0 );
|
||||
SDL_Flip(sdl_screen);
|
||||
|
||||
sms_bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, VIDEO_WIDTH_SMS, 240, 16, 0, 0, 0, 0);
|
||||
|
||||
img_background = SDL_LoadBMP("background.bmp");
|
||||
|
||||
font = gfx_tex_load_tga_from_array(fontarray);
|
||||
bigfontwhite = gfx_tex_load_tga_from_array(bigfontwhitearray);
|
||||
bigfontred = gfx_tex_load_tga_from_array(bigfontredarray);
|
||||
|
||||
// Load ROM
|
||||
if(!load_rom(argv[1])) {
|
||||
fprintf(stderr, "Error: Failed to load %s.\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "CRC : %08X\n", cart.crc);
|
||||
|
||||
// Set parameters for internal bitmap
|
||||
bitmap.width = VIDEO_WIDTH_SMS;
|
||||
bitmap.height = VIDEO_HEIGHT_SMS;
|
||||
bitmap.depth = 16;
|
||||
bitmap.granularity = 2;
|
||||
bitmap.data = (uint8_t *)sms_bitmap->pixels;
|
||||
bitmap.pitch = sms_bitmap->pitch;
|
||||
bitmap.viewport.w = VIDEO_WIDTH_SMS;
|
||||
bitmap.viewport.h = VIDEO_HEIGHT_SMS;
|
||||
bitmap.viewport.x = 0x00;
|
||||
bitmap.viewport.y = 0x00;
|
||||
|
||||
//sms.territory = settings.misc_region;
|
||||
if (sms.console == CONSOLE_SMS || sms.console == CONSOLE_SMS2)
|
||||
{
|
||||
sms.use_fm = 1;
|
||||
}
|
||||
|
||||
bios_init();
|
||||
|
||||
Sound_Init();
|
||||
|
||||
// Initialize all systems and power on
|
||||
system_poweron();
|
||||
|
||||
frames_rendered = 0;
|
||||
|
||||
// Loop until the user closes the window
|
||||
while (!quit)
|
||||
{
|
||||
// Refresh video data
|
||||
video_update();
|
||||
|
||||
// Output audio
|
||||
Sound_Update();
|
||||
|
||||
// Execute frame(s)
|
||||
system_frame(0);
|
||||
|
||||
++frames_rendered;
|
||||
|
||||
if (sms.console == CONSOLE_COLECO)
|
||||
{
|
||||
input.system = 0;
|
||||
coleco.keypad[0] = 0xff;
|
||||
coleco.keypad[1] = 0xff;
|
||||
}
|
||||
|
||||
if (selectpressed == 1)
|
||||
{
|
||||
Menu();
|
||||
SDL_FillRect(sdl_screen, NULL, 0);
|
||||
input.system &= (IS_GG) ? ~INPUT_START : ~INPUT_PAUSE;
|
||||
selectpressed = 0;
|
||||
}
|
||||
|
||||
keystate = SDL_GetKeyState(NULL);
|
||||
|
||||
for(uint8_t i=0;i<2;i++)
|
||||
{
|
||||
if (joystick[i] == NULL) joystick[i] = SDL_JoystickOpen(i);
|
||||
|
||||
x_move = SDL_JoystickGetAxis(joystick[i], 0);
|
||||
y_move = SDL_JoystickGetAxis(joystick[i], 1);
|
||||
|
||||
if (x_move > 500 || (i == 0 && keystate[SDLK_RIGHT]))
|
||||
input.pad[i] |= INPUT_RIGHT;
|
||||
else
|
||||
input.pad[i] &= ~INPUT_RIGHT;
|
||||
|
||||
if (x_move < -500 || (i == 0 && keystate[SDLK_LEFT]))
|
||||
input.pad[i] |= INPUT_LEFT;
|
||||
else
|
||||
input.pad[i] &= ~INPUT_LEFT;
|
||||
|
||||
if (y_move > 500 || (i == 0 && keystate[SDLK_DOWN]))
|
||||
input.pad[i] |= INPUT_DOWN;
|
||||
else
|
||||
input.pad[i] &= ~INPUT_DOWN;
|
||||
|
||||
if(y_move < -500 || (i == 0 && keystate[SDLK_UP]))
|
||||
input.pad[i] |= INPUT_UP;
|
||||
else
|
||||
input.pad[i] &= ~INPUT_UP;
|
||||
|
||||
if(SDL_JoystickGetButton(joystick[i], 2) == SDL_PRESSED || (i == 0 && keystate[SDLK_LCTRL]))
|
||||
input.pad[i] |= INPUT_BUTTON1;
|
||||
else
|
||||
input.pad[i] &= ~INPUT_BUTTON1;
|
||||
|
||||
if(SDL_JoystickGetButton(joystick[i], 1) == SDL_PRESSED || (i == 0 && keystate[SDLK_LALT]))
|
||||
input.pad[i] |= INPUT_BUTTON2;
|
||||
else
|
||||
input.pad[i] &= ~INPUT_BUTTON2;
|
||||
|
||||
if(i == 0 && SDL_JoystickGetButton(joystick[i], 9) == SDL_PRESSED || keystate[SDLK_RETURN])
|
||||
input.system |= (sms.console == CONSOLE_GG) ? INPUT_START : INPUT_PAUSE;
|
||||
else
|
||||
input.system &= ~(sms.console == CONSOLE_GG) ? INPUT_START : INPUT_PAUSE;
|
||||
|
||||
if(SDL_JoystickGetButton(joystick[i], 8) == SDL_PRESSED || keystate[SDLK_ESCAPE])
|
||||
selectpressed = 1;
|
||||
}
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
if(SDL_PollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
quit = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Flip(sdl_screen);
|
||||
}
|
||||
|
||||
if (sdl_screen) SDL_FreeSurface(sdl_screen);
|
||||
if (sms_bitmap) SDL_FreeSurface(sms_bitmap);
|
||||
if (font) SDL_FreeSurface(font);
|
||||
if (bigfontwhite) SDL_FreeSurface(bigfontwhite);
|
||||
if (bigfontred) SDL_FreeSurface(bigfontred);
|
||||
|
||||
for(uint8_t i=0;i<2;i++)
|
||||
{
|
||||
if (joystick[i]) SDL_JoystickClose(joystick[i]);
|
||||
}
|
||||
|
||||
// Deinitialize audio and video output
|
||||
Sound_Close();
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
// Shut down
|
||||
system_poweroff();
|
||||
system_shutdown();
|
||||
return 0;
|
||||
}
|
31
source/k3s/smsplus.h
Normal file
31
source/k3s/smsplus.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _SMSPLUS_H
|
||||
#define _SMSPLUS_H
|
||||
|
||||
#define VIDEO_WIDTH_SMS 256
|
||||
#define VIDEO_HEIGHT_SMS 192
|
||||
#define VIDEO_WIDTH_GG 160
|
||||
#define VIDEO_HEIGHT_GG 144
|
||||
|
||||
typedef struct {
|
||||
int8_t gamename[256];
|
||||
int8_t sramdir[256];
|
||||
int8_t sramfile[516];
|
||||
int8_t stdir[256];
|
||||
int8_t scrdir[256];
|
||||
int8_t biosdir[256];
|
||||
} gamedata_t;
|
||||
|
||||
typedef struct {
|
||||
int8_t* current_pos;
|
||||
int8_t* buffer;
|
||||
uint32_t current_emulated_samples;
|
||||
} t_sdl_sound;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ticks_starting;
|
||||
SDL_sem* sem_sync;
|
||||
} t_sdl_sync;
|
||||
|
||||
void smsp_state(uint8_t slot, uint8_t mode);
|
||||
|
||||
#endif
|
@ -427,6 +427,8 @@ void render_line(int32_t line)
|
||||
parse_line(line);
|
||||
|
||||
/* LightGun mark */
|
||||
#ifdef LIGHTGUN_ENABLED
|
||||
/* Putting this in an ifdef because the condition loop is executed every render_line */
|
||||
if (sms.device[0] == DEVICE_LIGHTGUN)
|
||||
{
|
||||
int dy = vdp.line - input.analog[0][1];
|
||||
@ -443,6 +445,7 @@ void render_line(int32_t line)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Only draw lines within the video output range ! */
|
||||
if (view)
|
||||
|
70
source/z80/cpuintrf.h
Normal file
70
source/z80/cpuintrf.h
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#ifndef CPUINTRF_H
|
||||
#define CPUINTRF_H
|
||||
|
||||
#include "osd_cpu.h"
|
||||
|
||||
#define CPU_16BIT_PORT 0x4000
|
||||
#define CPU_FLAGS_MASK 0xff00
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_REGS = 128, /* maximum number of register of any CPU */
|
||||
|
||||
/* This value is passed to activecpu_get_reg to retrieve the previous
|
||||
* program counter value, ie. before a CPU emulation started
|
||||
* to fetch opcodes and arguments for the current instrution. */
|
||||
REG_PREVIOUSPC = -1,
|
||||
|
||||
/* This value is passed to activecpu_get_reg to retrieve the current
|
||||
* program counter value. */
|
||||
REG_PC = -2,
|
||||
|
||||
/* This value is passed to activecpu_get_reg to retrieve the current
|
||||
* stack pointer value. */
|
||||
REG_SP = -3,
|
||||
|
||||
/* This value is passed to activecpu_get_reg/activecpu_set_reg, instead of one of
|
||||
* the names from the enum a CPU core defines for it's registers,
|
||||
* to get or set the contents of the memory pointed to by a stack pointer.
|
||||
* You can specify the n'th element on the stack by (REG_SP_CONTENTS-n),
|
||||
* ie. lower negative values. The actual element size (UINT16 or UINT32)
|
||||
* depends on the CPU core. */
|
||||
REG_SP_CONTENTS = -4
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* line states */
|
||||
CLEAR_LINE = 0, /* clear (a fired, held or pulsed) line */
|
||||
ASSERT_LINE, /* assert an interrupt immediately */
|
||||
HOLD_LINE, /* hold interrupt line until acknowledged */
|
||||
PULSE_LINE, /* pulse interrupt line for one instruction */
|
||||
|
||||
/* internal flags (not for use by drivers!) */
|
||||
INTERNAL_CLEAR_LINE = 100 + CLEAR_LINE,
|
||||
INTERNAL_ASSERT_LINE = 100 + ASSERT_LINE,
|
||||
|
||||
/* interrupt parameters */
|
||||
MAX_IRQ_LINES = 16, /* maximum number of IRQ lines per CPU */
|
||||
IRQ_LINE_NMI = 127 /* IRQ line for NMIs */
|
||||
};
|
||||
|
||||
|
||||
/* daisy-chain link */
|
||||
typedef struct {
|
||||
void (*reset)(int); /* reset callback */
|
||||
int (*interrupt_entry)(int); /* entry callback */
|
||||
void (*interrupt_reti)(int); /* reti callback */
|
||||
int irq_param; /* callback paramater */
|
||||
} Z80_DaisyChain;
|
||||
|
||||
#define Z80_MAXDAISY 4 /* maximum of daisy chan device */
|
||||
|
||||
#define Z80_INT_REQ 0x01 /* interrupt request mask */
|
||||
#define Z80_INT_IEO 0x02 /* interrupt disable mask(IEO) */
|
||||
|
||||
#define Z80_VECTOR(device,state) (((device)<<8)|(state))
|
||||
|
||||
|
||||
#endif /* CPUINTRF_H */
|
69
source/z80/osd_cpu.h
Normal file
69
source/z80/osd_cpu.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Define size independent data types and operations. *
|
||||
* *
|
||||
* The following types must be supported by all platforms: *
|
||||
* *
|
||||
* UINT8 - Unsigned 8-bit Integer INT8 - Signed 8-bit integer *
|
||||
* UINT16 - Unsigned 16-bit Integer INT16 - Signed 16-bit integer *
|
||||
* UINT32 - Unsigned 32-bit Integer INT32 - Signed 32-bit integer *
|
||||
* UINT64 - Unsigned 64-bit Integer INT64 - Signed 64-bit integer *
|
||||
* *
|
||||
* *
|
||||
* The macro names for the artithmatic operations are composed as follows: *
|
||||
* *
|
||||
* XXX_R_A_B, where XXX - 3 letter operation code (ADD, SUB, etc.) *
|
||||
* R - The type of the result *
|
||||
* A - The type of operand 1 *
|
||||
* B - The type of operand 2 (if binary operation) *
|
||||
* *
|
||||
* Each type is one of: U8,8,U16,16,U32,32,U64,64 *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#ifndef OSD_CPU_H
|
||||
#define OSD_CPU_H
|
||||
#include <stdint.h>
|
||||
|
||||
/* Combine two 32-bit integers into a 64-bit integer */
|
||||
#define COMBINE_64_32_32(A,B) ((((uint64_t)(A))<<32) | (uint32_t)(B))
|
||||
#define COMBINE_U64_U32_U32(A,B) COMBINE_64_32_32(A,B)
|
||||
|
||||
/* Return upper 32 bits of a 64-bit integer */
|
||||
#define HI32_32_64(A) (((uint64_t)(A)) >> 32)
|
||||
#define HI32_U32_U64(A) HI32_32_64(A)
|
||||
|
||||
/* Return lower 32 bits of a 64-bit integer */
|
||||
#define LO32_32_64(A) ((A) & 0xffffffff)
|
||||
#define LO32_U32_U64(A) LO32_32_64(A)
|
||||
|
||||
#define DIV_64_64_32(A,B) ((A)/(B))
|
||||
#define DIV_U64_U64_U32(A,B) ((A)/(uint32_t)(B))
|
||||
|
||||
#define MOD_32_64_32(A,B) ((A)%(B))
|
||||
#define MOD_U32_U64_U32(A,B) ((A)%(uint32_t)(B))
|
||||
|
||||
#define MUL_64_32_32(A,B) ((A)*(INT64)(B))
|
||||
#define MUL_U64_U32_U32(A,B) ((A)*(uint64_t)(uint32_t)(B))
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Union of UINT8, UINT16 and UINT32 in native endianess of the target
|
||||
* This is used to access bytes and words in a machine independent manner.
|
||||
* The upper bytes h2 and h3 normally contain zero (16 bit CPU cores)
|
||||
* thus PAIR.d can be used to pass arguments to the memory system
|
||||
* which expects 'int' really.
|
||||
******************************************************************************/
|
||||
typedef union {
|
||||
#ifdef LSB_FIRST
|
||||
struct { uint8_t l,h,h2,h3; } b;
|
||||
struct { uint16_t l,h; } w;
|
||||
#else
|
||||
struct { uint8_t h3,h2,h,l; } b;
|
||||
struct { uint16_t h,l; } w;
|
||||
#endif
|
||||
uint32_t d;
|
||||
} PAIR;
|
||||
|
||||
#endif /* defined OSD_CPU_H */
|
121
source/z80/state.c
Normal file
121
source/z80/state.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
state.c --
|
||||
Save state management.
|
||||
*/
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
void system_save_state(void *fd)
|
||||
{
|
||||
char *id = STATE_HEADER;
|
||||
uint16_t version = STATE_VERSION;
|
||||
|
||||
/* Write header */
|
||||
fwrite(id, sizeof(id), 1, fd);
|
||||
fwrite(&version, sizeof(version), 1, fd);
|
||||
|
||||
/* Save VDP context */
|
||||
fwrite(&vdp, sizeof(vdp_t), 1, fd);
|
||||
|
||||
/* Save SMS context */
|
||||
fwrite(&sms, sizeof(sms_t), 1, fd);
|
||||
|
||||
fputc(cart.fcr[0], fd);
|
||||
fputc(cart.fcr[1], fd);
|
||||
fputc(cart.fcr[2], fd);
|
||||
fputc(cart.fcr[3], fd);
|
||||
fwrite(cart.sram, 0x8000, 1, fd);
|
||||
|
||||
/* Save Z80 context */
|
||||
fwrite(Z80_Context, sizeof(Z80_Regs), 1, fd);
|
||||
fwrite(&after_EI, sizeof(int), 1, fd);
|
||||
|
||||
/* Save YM2413 context */
|
||||
fwrite(FM_GetContextPtr(), FM_GetContextSize(), 1, fd);
|
||||
|
||||
/* Save SN76489 context */
|
||||
fwrite(SN76489_GetContextPtr(0), SN76489_GetContextSize(), 1, fd);
|
||||
}
|
||||
|
||||
|
||||
void system_load_state(void *fd)
|
||||
{
|
||||
int i;
|
||||
uint8_t *buf;
|
||||
char id[4];
|
||||
uint16_t version;
|
||||
|
||||
/* Initialize everything */
|
||||
z80_reset(0);
|
||||
z80_set_irq_callback(sms_irq_callback);
|
||||
system_reset();
|
||||
if(snd.enabled)
|
||||
sound_reset();
|
||||
|
||||
/* Read header */
|
||||
fread(id, 4, 1, fd);
|
||||
fread(&version, 2, 1, fd);
|
||||
|
||||
/* Load VDP context */
|
||||
fread(&vdp, sizeof(vdp_t), 1, fd);
|
||||
|
||||
/* Load SMS context */
|
||||
fread(&sms, sizeof(sms_t), 1, fd);
|
||||
|
||||
cart.fcr[0] = fgetc(fd);
|
||||
cart.fcr[1] = fgetc(fd);
|
||||
cart.fcr[2] = fgetc(fd);
|
||||
cart.fcr[3] = fgetc(fd);
|
||||
fread(cart.sram, 0x8000, 1, fd);
|
||||
|
||||
/* Load Z80 context */
|
||||
fread(Z80_Context, sizeof(Z80_Regs), 1, fd);
|
||||
fread(&after_EI, sizeof(int), 1, fd);
|
||||
|
||||
/* Load YM2413 context */
|
||||
buf = malloc(FM_GetContextSize());
|
||||
fread(buf, FM_GetContextSize(), 1, fd);
|
||||
FM_SetContext(buf);
|
||||
free(buf);
|
||||
|
||||
/* Load SN76489 context */
|
||||
buf = malloc(SN76489_GetContextSize());
|
||||
fread(buf, SN76489_GetContextSize(), 1, fd);
|
||||
SN76489_SetContext(0, buf);
|
||||
free(buf);
|
||||
|
||||
/* Restore callbacks */
|
||||
z80_set_irq_callback(sms_irq_callback);
|
||||
|
||||
for(i = 0x00; i <= 0x2F; i++)
|
||||
{
|
||||
cpu_readmap[i] = &cart.rom[(i & 0x1F) << 10];
|
||||
cpu_writemap[i] = dummy_write;
|
||||
}
|
||||
|
||||
for(i = 0x30; i <= 0x3F; i++)
|
||||
{
|
||||
cpu_readmap[i] = &sms.wram[(i & 0x07) << 10];
|
||||
cpu_writemap[i] = &sms.wram[(i & 0x07) << 10];
|
||||
}
|
||||
|
||||
sms_mapper_w(3, cart.fcr[3]);
|
||||
sms_mapper_w(2, cart.fcr[2]);
|
||||
sms_mapper_w(1, cart.fcr[1]);
|
||||
sms_mapper_w(0, cart.fcr[0]);
|
||||
|
||||
/* Force full pattern cache update */
|
||||
bg_list_index = 0x200;
|
||||
for(i = 0; i < 0x200; i++)
|
||||
{
|
||||
bg_name_list[i] = i;
|
||||
bg_name_dirty[i] = -1;
|
||||
}
|
||||
|
||||
/* Restore palette */
|
||||
for(i = 0; i < PALETTE_SIZE; i++)
|
||||
palette_sync(i, 1);
|
||||
|
||||
viewport_check();
|
||||
}
|
||||
|
14
source/z80/state.h
Normal file
14
source/z80/state.h
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
#ifndef _STATE_H_
|
||||
#define _STATE_H_
|
||||
|
||||
|
||||
|
||||
#define STATE_VERSION 0x0101 /* Version 1.1 (BCD) */
|
||||
#define STATE_HEADER "SST\0" /* State file header */
|
||||
|
||||
/* Function prototypes */
|
||||
void system_save_state(void *fd);
|
||||
void system_load_state(void *fd);
|
||||
|
||||
#endif /* _STATE_H_ */
|
3965
source/z80/z80.c
Normal file
3965
source/z80/z80.c
Normal file
File diff suppressed because it is too large
Load Diff
76
source/z80/z80.h
Normal file
76
source/z80/z80.h
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef Z80_H
|
||||
#define Z80_H
|
||||
|
||||
#include "cpuintrf.h"
|
||||
#include "osd_cpu.h"
|
||||
|
||||
/* Hack in order to make the save states work - gameblabla */
|
||||
#define z80_t Z80_Regs
|
||||
|
||||
enum {
|
||||
Z80_PC=1, Z80_SP, Z80_AF, Z80_BC, Z80_DE, Z80_HL,
|
||||
Z80_IX, Z80_IY, Z80_AF2, Z80_BC2, Z80_DE2, Z80_HL2,
|
||||
Z80_R, Z80_I, Z80_IM, Z80_IFF1, Z80_IFF2, Z80_HALT,
|
||||
Z80_NMI_STATE, Z80_IRQ_STATE, Z80_DC0, Z80_DC1, Z80_DC2, Z80_DC3
|
||||
};
|
||||
|
||||
enum {
|
||||
Z80_TABLE_op,
|
||||
Z80_TABLE_cb,
|
||||
Z80_TABLE_ed,
|
||||
Z80_TABLE_xy,
|
||||
Z80_TABLE_xycb,
|
||||
Z80_TABLE_ex /* cycles counts for taken jr/jp/call and interrupt latency (rst opcodes) */
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */
|
||||
/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */
|
||||
/****************************************************************************/
|
||||
typedef struct {
|
||||
/* 00 */ PAIR PREPC,PC,SP,AF,BC,DE,HL,IX,IY;
|
||||
/* 24 */ PAIR AF2,BC2,DE2,HL2;
|
||||
/* 34 */ uint8_t R,R2,IFF1,IFF2,HALT,IM,I;
|
||||
/* 3B */ uint8_t irq_max; /* number of daisy chain devices */
|
||||
/* 3C */ int8_t request_irq; /* daisy chain next request device */
|
||||
/* 3D */ int8_t service_irq; /* daisy chain next reti handling device */
|
||||
/* 3E */ uint8_t nmi_state; /* nmi line state */
|
||||
/* 3F */ uint8_t irq_state; /* irq line state */
|
||||
/* 40 */ uint8_t int_state[Z80_MAXDAISY];
|
||||
/* 44 */ Z80_DaisyChain irq[Z80_MAXDAISY];
|
||||
/* 84 */ int (*irq_callback)(int irqline);
|
||||
/* 88 */ int extra_cycles; /* extra cycles for interrupts */
|
||||
} Z80_Regs;
|
||||
|
||||
|
||||
extern int z80_ICount; /* T-state count */
|
||||
|
||||
extern void z80_init(void);
|
||||
extern void z80_reset (void *param);
|
||||
extern void z80_exit (void);
|
||||
extern int z80_execute(int cycles);
|
||||
extern void z80_burn(int cycles);
|
||||
extern unsigned z80_get_context (void *dst);
|
||||
extern void z80_set_context (void *src);
|
||||
extern const void *z80_get_cycle_table (int which);
|
||||
extern void z80_set_cycle_table (int which, void *new_tbl);
|
||||
extern unsigned z80_get_reg (int regnum);
|
||||
extern void z80_set_reg (int regnum, unsigned val);
|
||||
extern void z80_set_irq_line(int irqline, int state);
|
||||
extern void z80_set_irq_callback(int (*irq_callback)(int));
|
||||
extern unsigned z80_dasm(char *buffer, unsigned pc);
|
||||
|
||||
extern Z80_Regs *Z80_Context;
|
||||
extern int after_EI;
|
||||
extern uint8_t *cpu_readmap[64];
|
||||
extern uint8_t *cpu_writemap[64];
|
||||
|
||||
extern void (*cpu_writemem16)(uint16_t address, uint8_t data);
|
||||
extern void (*cpu_writeport16)(uint16_t port, uint8_t data);
|
||||
extern uint8_t (*cpu_readport16)(uint16_t port);
|
||||
|
||||
void z80_reset_cycle_count(void);
|
||||
int z80_get_elapsed_cycles(void);
|
||||
|
||||
#endif
|
||||
|
31
source/z80/z80_wrap.c
Normal file
31
source/z80/z80_wrap.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stdint.h>
|
||||
#include "z80.h"
|
||||
#include "shared.h"
|
||||
|
||||
int32_t z80_ICount = 0;
|
||||
int32_t z80_nmipending = 0;
|
||||
int32_t z80_nmi_state = 0;
|
||||
int32_t extra_cycles = 0;
|
||||
|
||||
void (*cpu_writemem16)(uint16_t address, uint8_t data);
|
||||
void (*cpu_writeport16)(uint16_t port, uint8_t data);
|
||||
uint8_t (*cpu_readport16)(uint16_t port);
|
||||
|
||||
extern int32_t z80_get_elapsed_cycles();
|
||||
|
||||
void CPUZ80_Init()
|
||||
{
|
||||
z80_init();
|
||||
}
|
||||
|
||||
void CPUZ80_Reset()
|
||||
{
|
||||
z80_reset(NULL);
|
||||
z80_set_irq_callback(sms_irq_callback);
|
||||
}
|
||||
|
||||
void CPUIRQ_Pause()
|
||||
{
|
||||
z80_set_irq_line(IRQ_LINE_NMI, ASSERT_LINE);
|
||||
z80_set_irq_line(IRQ_LINE_NMI, CLEAR_LINE);
|
||||
}
|
25
source/z80/z80_wrap.h
Normal file
25
source/z80/z80_wrap.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef WRAP_H
|
||||
#define WRAP_H
|
||||
|
||||
#define ASSERT_LINE 1
|
||||
#define CLEAR_LINE 0
|
||||
#define IRQ_LINE_NMI 127
|
||||
#define INPUT_LINE_NMI 32
|
||||
#define INPUT_LINE_IRQ0 0
|
||||
|
||||
extern void CPUZ80_Init();
|
||||
extern void CPUZ80_Reset();
|
||||
extern void CPUIRQ_Pause();
|
||||
|
||||
extern int32_t z80_ICount;
|
||||
extern int32_t extra_cycles;
|
||||
extern int32_t z80_nmipending;
|
||||
extern int32_t z80_nmi_state;
|
||||
|
||||
extern void z80_set_irq_line(int irqline, int state);
|
||||
extern int32_t z80_get_elapsed_cycles();
|
||||
|
||||
extern uint8_t *cpu_readmap[64];
|
||||
extern uint8_t *cpu_writemap[64];
|
||||
|
||||
#endif
|
2052
source/z80/z80daa.h
Normal file
2052
source/z80/z80daa.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user