i'd stash all of this but it's less effort to commit
This commit is contained in:
parent
f7ac0d0b02
commit
17cc595ba6
|
@ -1,18 +1,42 @@
|
|||
CFLAGS=-O3
|
||||
ifeq ($(OS),Windows_NT)
|
||||
LIBS=-lrt `sdl2-config --libs`
|
||||
CFLAGS+=-w
|
||||
else
|
||||
LIBS=-lrt -lSDL2 -pthread
|
||||
endif
|
||||
CC = x86_64-nt64-midipix-gcc
|
||||
|
||||
all: libpizza.a
|
||||
gcc $(CFLAGS) pizza.c -I lib lib/libpizza.a -o emu-pizza $(LIBS)
|
||||
CCFLAGS:=-Ilib \
|
||||
-I../emulibc \
|
||||
-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \
|
||||
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
|
||||
-DLSB_FIRST -DUSE_32BPP_RENDERING -DINLINE=static\ __inline__ \
|
||||
-O0 -flto
|
||||
|
||||
libpizza.a:
|
||||
make -C lib
|
||||
TARGET = pizza.wbx
|
||||
|
||||
LDFLAGS = -Wl,--dynamicbase,--export-all-symbols
|
||||
|
||||
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c')
|
||||
OBJ_DIR:=$(ROOT_DIR)/obj
|
||||
|
||||
_OBJS:=$(SRCS:.c=.o)
|
||||
OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS))
|
||||
|
||||
$(OBJ_DIR)/%.o: %.c
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) -c -o $@ $< $(CCFLAGS)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
$(TARGET).in: $(OBJS)
|
||||
@$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) ../emulibc/libemuhost.so
|
||||
|
||||
$(TARGET): $(TARGET).in
|
||||
# strip $< -o $@ -R /4 -R /14 -R /29 -R /41 -R /55 -R /67 -R /78 -R /89 -R /104
|
||||
cp $< $@
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
make -C cpu clean
|
||||
make -C system clean
|
||||
rm -rf $(OBJ_DIR)
|
||||
rm -f $(TARGET).in
|
||||
rm -f $(TARGET)
|
||||
|
||||
#install:
|
||||
# $(CP) $(TARGET) $(DEST_$(ARCH))
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
SRCS=$(wildcard *.c)
|
||||
CFLAGS=-I.. -c -pthread -O3 -Wall
|
||||
|
||||
all:
|
||||
gcc $(CFLAGS) $(SRCS)
|
||||
ar rcs libpizza.a *.o
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
|
@ -35,35 +35,19 @@ uint8_t rom[2 << 24];
|
|||
char file_sav[1024];
|
||||
char file_rtc[1024];
|
||||
|
||||
/* internal use prototype */
|
||||
int __mkdirp (char *path, mode_t omode);
|
||||
|
||||
|
||||
/* guess what */
|
||||
/* return values */
|
||||
/* 0: OK */
|
||||
/* 1: Can't open/read file */
|
||||
/* 2: Unknown cartridge */
|
||||
|
||||
char cartridge_load(char *file_gb)
|
||||
char cartridge_load(const void* data, size_t sz)
|
||||
{
|
||||
FILE *fp;
|
||||
int i,z = 0;
|
||||
|
||||
/* open ROM file */
|
||||
if ((fp = fopen(file_gb, "r")) == NULL)
|
||||
if (sz < 1 || sz > 2 << 24)
|
||||
return 1;
|
||||
|
||||
/* read all the content into rom buffer */
|
||||
size_t sz = fread(rom, 1, (2 << 24), fp);
|
||||
|
||||
/* check for errors */
|
||||
if (sz < 1)
|
||||
return 1;
|
||||
|
||||
/* close */
|
||||
fclose(fp);
|
||||
|
||||
/* gameboy color? */
|
||||
if (rom[0x143] == 0xC0 || rom[0x143] == 0x80)
|
||||
{
|
||||
|
@ -169,9 +153,6 @@ char cartridge_load(char *file_gb)
|
|||
case 0x05: mmu_init_ram(1 << 16); utils_log("64 kB\n"); break;
|
||||
}
|
||||
|
||||
/* save base name of the rom */
|
||||
strncpy(global_rom_name, basename(file_gb), 256);
|
||||
|
||||
/* restore saved RAM if it's the case */
|
||||
mmu_restore_ram(file_sav);
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
@ -32,12 +30,6 @@
|
|||
#include "interrupt.h"
|
||||
#include "utils.h"
|
||||
|
||||
/* timer stuff */
|
||||
struct itimerspec cycles_timer;
|
||||
timer_t cycles_timer_id = 0;
|
||||
struct sigevent cycles_te;
|
||||
struct sigaction cycles_sa;
|
||||
|
||||
interrupts_flags_t *cycles_if;
|
||||
|
||||
/* instance of the main struct */
|
||||
|
@ -45,9 +37,6 @@ cycles_t cycles = { 0, 0, 0, 0 };
|
|||
|
||||
#define CYCLES_PAUSES 256
|
||||
|
||||
/* sync timing */
|
||||
struct timespec deadline;
|
||||
|
||||
/* hard sync stuff (for remote connection) */
|
||||
uint8_t cycles_hs_mode = 0;
|
||||
|
||||
|
@ -96,6 +85,13 @@ void cycles_set_speed(char dbl)
|
|||
cycles_change_emulation_speed();
|
||||
}
|
||||
|
||||
/* set emulation speed */
|
||||
void cycles_change_emulation_speed()
|
||||
{
|
||||
cycles.step = ((4194304 / CYCLES_PAUSES)
|
||||
<< global_cpu_double_speed);
|
||||
}
|
||||
|
||||
void cycles_closest_next()
|
||||
{
|
||||
int_fast32_t diff = cycles.cnt - cycles.next;
|
||||
|
@ -163,16 +159,6 @@ void cycles_step()
|
|||
/* 65536 == cpu clock / CYCLES_PAUSES pauses every second */
|
||||
if (cycles.cnt == cycles.next)
|
||||
{
|
||||
deadline.tv_nsec += 1000000000 / CYCLES_PAUSES;
|
||||
|
||||
if (deadline.tv_nsec > 1000000000)
|
||||
{
|
||||
deadline.tv_sec += 1;
|
||||
deadline.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL);
|
||||
|
||||
cycles.next += cycles.step;
|
||||
|
||||
/* update current running seconds */
|
||||
|
@ -328,9 +314,6 @@ void cycles_hdma()
|
|||
|
||||
char cycles_init()
|
||||
{
|
||||
/* CLOCK */
|
||||
clock_gettime(CLOCK_MONOTONIC, &deadline);
|
||||
|
||||
cycles.inited = 1;
|
||||
|
||||
/* interrupt registers */
|
||||
|
@ -347,21 +330,3 @@ char cycles_init()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char cycles_start_timer()
|
||||
{
|
||||
/* just pick new time reference */
|
||||
clock_gettime(CLOCK_MONOTONIC, &deadline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cycles_stop_timer()
|
||||
{
|
||||
if (cycles.inited == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
void cycles_term()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -65,10 +65,8 @@ void cycles_hdma();
|
|||
char cycles_init();
|
||||
void cycles_set_speed(char dbl);
|
||||
void cycles_start_hs();
|
||||
char cycles_start_timer();
|
||||
void cycles_step();
|
||||
void cycles_stop_hs();
|
||||
void cycles_stop_timer();
|
||||
void cycles_term();
|
||||
void cycles_vblank();
|
||||
|
||||
|
|
|
@ -121,8 +121,10 @@ void gameboy_init()
|
|||
state.sp = 0xFFFE;
|
||||
*state.f = 0xB0;
|
||||
|
||||
/* init semaphore for pauses */
|
||||
sem_init(&gameboy_sem, 0, 0);
|
||||
/* reset counter */
|
||||
cycles.cnt = 0;
|
||||
/* start at normal speed */
|
||||
global_cpu_double_speed = 0;
|
||||
|
||||
/* mark as inited */
|
||||
gameboy_inited = 1;
|
||||
|
@ -130,41 +132,10 @@ void gameboy_init()
|
|||
return;
|
||||
}
|
||||
|
||||
void gameboy_set_pause(char pause)
|
||||
{
|
||||
if (!gameboy_inited)
|
||||
return;
|
||||
|
||||
if (pause == global_pause)
|
||||
return;
|
||||
|
||||
global_pause = pause;
|
||||
|
||||
if (pause)
|
||||
{
|
||||
/* wait a bit - i need the main cycle fall into global_pause check */
|
||||
usleep(100000);
|
||||
|
||||
/* stop timer */
|
||||
cycles_stop_timer();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* restart timer */
|
||||
cycles_start_timer();
|
||||
|
||||
/* wake up */
|
||||
sem_post(&gameboy_sem);
|
||||
}
|
||||
}
|
||||
|
||||
void gameboy_run()
|
||||
{
|
||||
uint8_t op;
|
||||
|
||||
/* reset counter */
|
||||
cycles.cnt = 0;
|
||||
|
||||
/* get interrupt flags and interrupt enables */
|
||||
uint8_t *int_e;
|
||||
uint8_t *int_f;
|
||||
|
@ -173,9 +144,6 @@ void gameboy_run()
|
|||
int_e = mmu_addr(0xFFFF);
|
||||
int_f = mmu_addr(0xFF0F);
|
||||
|
||||
/* start at normal speed */
|
||||
global_cpu_double_speed = 0;
|
||||
|
||||
/* run stuff! */
|
||||
/* mechanism is simple. */
|
||||
/* 1) execute instruction 2) update cycles counter 3) check interrupts */
|
||||
|
@ -188,10 +156,6 @@ void gameboy_run()
|
|||
global_slow_down = 0;
|
||||
}*/
|
||||
|
||||
/* pause? */
|
||||
while (global_pause)
|
||||
sem_wait(&gameboy_sem);
|
||||
|
||||
/* get op */
|
||||
op = mmu_read(state.pc);
|
||||
|
||||
|
@ -290,28 +254,5 @@ void gameboy_run()
|
|||
}
|
||||
}
|
||||
|
||||
/* terminate all the stuff */
|
||||
cartridge_term();
|
||||
sound_term();
|
||||
mmu_term();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void gameboy_stop()
|
||||
{
|
||||
global_quit = 1;
|
||||
|
||||
/* wake up */
|
||||
if (global_pause)
|
||||
{
|
||||
global_pause = 0;
|
||||
sem_post(&gameboy_sem);
|
||||
}
|
||||
|
||||
/* unlock threads stuck during reading */
|
||||
sound_term();
|
||||
|
||||
/* shutdown semaphore limitator */
|
||||
cycles_term();
|
||||
}
|
||||
|
|
|
@ -27,26 +27,18 @@ char global_cgb;
|
|||
char global_cpu_double_speed;
|
||||
char global_debug;
|
||||
char global_next_frame;
|
||||
char global_pause;
|
||||
char global_quit;
|
||||
char global_record_audio;
|
||||
char global_rom_name[256];
|
||||
char global_rumble;
|
||||
char global_slow_down;
|
||||
char global_window;
|
||||
|
||||
void global_init()
|
||||
{
|
||||
global_quit = 0;
|
||||
global_pause = 0;
|
||||
global_window = 1;
|
||||
global_debug = 0;
|
||||
global_cgb = 0;
|
||||
global_cpu_double_speed = 0;
|
||||
global_slow_down = 0;
|
||||
global_record_audio = 0;
|
||||
global_next_frame = 0;
|
||||
global_rumble = 0;
|
||||
bzero(global_rom_name, 256);
|
||||
sprintf(global_cart_name, "NOCARTIRDGE");
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#ifndef __GLOBAL__
|
||||
#define __GLOBAL__
|
||||
|
||||
extern char global_quit;
|
||||
extern char global_pause;
|
||||
extern char global_window;
|
||||
extern char global_debug;
|
||||
extern char global_cgb;
|
||||
|
@ -29,9 +27,7 @@ extern char global_next_frame;
|
|||
// extern char global_started;
|
||||
extern char global_cpu_double_speed;
|
||||
extern char global_slow_down;
|
||||
extern char global_record_audio;
|
||||
extern char global_rumble;
|
||||
extern char global_rom_name[256];
|
||||
extern char global_cart_name[256];
|
||||
|
||||
/* prototypes */
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "cycles.h"
|
||||
#include "interrupt.h"
|
||||
#include "mmu.h"
|
||||
|
@ -33,10 +31,6 @@ serial_data_send_cb_t serial_data_send_cb;
|
|||
|
||||
interrupts_flags_t *serial_if;
|
||||
|
||||
/* mutexes for serial sync */
|
||||
pthread_cond_t serial_cond;
|
||||
pthread_mutex_t serial_mutex;
|
||||
|
||||
/* second message before the first was handled? */
|
||||
uint8_t serial_second_set = 0;
|
||||
uint8_t serial_second_data = 0;
|
||||
|
@ -86,17 +80,10 @@ void serial_init()
|
|||
|
||||
/* start as not connected */
|
||||
serial.peer_connected = 0;
|
||||
|
||||
/* init semaphore for sync */
|
||||
pthread_mutex_init(&serial_mutex, NULL);
|
||||
pthread_cond_init(&serial_cond, NULL);
|
||||
}
|
||||
|
||||
void serial_write_reg(uint16_t a, uint8_t v)
|
||||
{
|
||||
/* lock the serial */
|
||||
pthread_mutex_lock(&serial_mutex);
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case 0xFF01:
|
||||
|
@ -122,8 +109,6 @@ void serial_write_reg(uint16_t a, uint8_t v)
|
|||
}
|
||||
|
||||
end:
|
||||
/* unlock the serial */
|
||||
pthread_mutex_unlock(&serial_mutex);
|
||||
}
|
||||
|
||||
uint8_t serial_read_reg(uint16_t a)
|
||||
|
@ -144,9 +129,6 @@ uint8_t serial_read_reg(uint16_t a)
|
|||
|
||||
void serial_recv_byte(uint8_t v, uint8_t clock, uint8_t transfer_start)
|
||||
{
|
||||
/* lock the serial */
|
||||
pthread_mutex_lock(&serial_mutex);
|
||||
|
||||
/* second message during same span time? */
|
||||
if (serial.data_recv)
|
||||
{
|
||||
|
@ -166,20 +148,14 @@ void serial_recv_byte(uint8_t v, uint8_t clock, uint8_t transfer_start)
|
|||
serial.data_recv_transfer_start = transfer_start;
|
||||
|
||||
/* notify main thread in case it's waiting */
|
||||
if (serial_waiting_data)
|
||||
pthread_cond_signal(&serial_cond);
|
||||
//if (serial_waiting_data)
|
||||
//pthread_cond_signal(&serial_cond);
|
||||
|
||||
end:
|
||||
|
||||
/* unlock the serial */
|
||||
pthread_mutex_unlock(&serial_mutex);
|
||||
}
|
||||
|
||||
void serial_send_byte()
|
||||
{
|
||||
/* lock the serial */
|
||||
pthread_mutex_lock(&serial_mutex);
|
||||
|
||||
serial.data_sent = 1;
|
||||
serial.data_to_send = serial.data;
|
||||
serial.data_sent_clock = serial.clock;
|
||||
|
@ -188,9 +164,6 @@ void serial_send_byte()
|
|||
if (serial_data_send_cb)
|
||||
(*serial_data_send_cb) (serial.data, serial.clock,
|
||||
serial.transfer_start);
|
||||
|
||||
/* unlock the serial */
|
||||
pthread_mutex_unlock(&serial_mutex);
|
||||
}
|
||||
|
||||
void serial_set_send_cb(serial_data_send_cb_t cb)
|
||||
|
@ -200,9 +173,6 @@ void serial_set_send_cb(serial_data_send_cb_t cb)
|
|||
|
||||
void serial_wait_data()
|
||||
{
|
||||
/* lock the serial */
|
||||
pthread_mutex_lock(&serial_mutex);
|
||||
|
||||
if (serial.data_sent && serial.data_recv == 0)
|
||||
{
|
||||
/* wait max 3 seconds */
|
||||
|
@ -217,12 +187,9 @@ void serial_wait_data()
|
|||
serial_waiting_data = 1;
|
||||
|
||||
/* notify something has arrived */
|
||||
pthread_cond_timedwait(&serial_cond, &serial_mutex, &wait);
|
||||
// pthread_cond_timedwait(&serial_cond, &serial_mutex, &wait);
|
||||
|
||||
/* not waiting anymore */
|
||||
serial_waiting_data = 0;
|
||||
}
|
||||
|
||||
/* unlock the serial */
|
||||
pthread_mutex_unlock(&serial_mutex);
|
||||
}
|
||||
|
|
|
@ -396,18 +396,12 @@ void sound_push_samples(int16_t l, int16_t r)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
/* since we're accessing a shared buffer, lock it */
|
||||
pthread_mutex_lock(&sound_mutex);
|
||||
|
||||
/* put them in circular shared buffer */
|
||||
for (i=0; i<SOUND_BUF_TMP_SZ; i++)
|
||||
sound_push_sample(sound.buf_tmp[i]);
|
||||
|
||||
/* reset counter */
|
||||
sound.buf_tmp_wr = 0;
|
||||
|
||||
/* set it free */
|
||||
pthread_mutex_unlock(&sound_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,7 +425,7 @@ void sound_push_sample(int16_t s)
|
|||
{
|
||||
sound.buf_empty = 0;
|
||||
|
||||
pthread_cond_signal(&sound_cond);
|
||||
//pthread_cond_signal(&sound_cond);
|
||||
}
|
||||
|
||||
/* wait for the audio to be played */
|
||||
|
@ -460,24 +454,14 @@ size_t sound_available_samples()
|
|||
/* read a block of data from circular buffer */
|
||||
void sound_read_samples(int to_read, int16_t *buf)
|
||||
{
|
||||
/* lock the buffer */
|
||||
pthread_mutex_lock(&sound_mutex);
|
||||
|
||||
/* am i shutting down? exit */
|
||||
if (global_quit)
|
||||
{
|
||||
pthread_mutex_unlock(&sound_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* not enough samples? read what we got */
|
||||
if (sound.buf_available < to_read)
|
||||
{
|
||||
/* stop until we got enough samples */
|
||||
sound.buf_empty = 1;
|
||||
|
||||
while (sound.buf_empty && !global_quit)
|
||||
pthread_cond_wait(&sound_cond, &sound_mutex);
|
||||
//while (sound.buf_empty && !global_quit)
|
||||
//pthread_cond_wait(&sound_cond, &sound_mutex);
|
||||
}
|
||||
|
||||
if (sound.buf_rd + to_read >= SOUND_BUF_SZ)
|
||||
|
@ -503,9 +487,6 @@ void sound_read_samples(int to_read, int16_t *buf)
|
|||
|
||||
/* update avaiable samples */
|
||||
sound.buf_available -= to_read;
|
||||
|
||||
/* unlock the buffer */
|
||||
pthread_mutex_unlock(&sound_mutex);
|
||||
}
|
||||
|
||||
/* calc the new frequency by sweep module */
|
||||
|
@ -1426,12 +1407,3 @@ void sound_rebuild_wave()
|
|||
sound.channel_three.wave[sound.channel_three.index];
|
||||
|
||||
}
|
||||
|
||||
void sound_term()
|
||||
{
|
||||
if (sound.buf_empty)
|
||||
{
|
||||
sound.buf_empty = 0;
|
||||
pthread_cond_signal(&sound_cond);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -325,7 +325,6 @@ void sound_step_ch2();
|
|||
void sound_step_ch3();
|
||||
void sound_step_ch4();
|
||||
void sound_step_sample();
|
||||
void sound_term();
|
||||
void sound_write_reg(uint16_t a, uint8_t v);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -336,84 +336,3 @@ void rumble_cb(uint8_t rumble)
|
|||
if (rumble)
|
||||
printf("RUMBLE\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns 1 if a directory has been created,
|
||||
* 2 if it already existed, and 0 on failure.
|
||||
*/
|
||||
int __mkdirp (char *path, mode_t omode)
|
||||
{
|
||||
struct stat sb;
|
||||
mode_t numask, oumask;
|
||||
int first, last, retval;
|
||||
char *p;
|
||||
|
||||
p = path;
|
||||
oumask = 0;
|
||||
retval = 1;
|
||||
|
||||
if (p[0] == '/') /* Skip leading '/'. */
|
||||
++p;
|
||||
|
||||
for (first = 1, last = 0; !last ; ++p)
|
||||
{
|
||||
if (p[0] == '\0')
|
||||
last = 1;
|
||||
else if (p[0] != '/')
|
||||
continue;
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if (!last && p[1] == '\0')
|
||||
last = 1;
|
||||
|
||||
if (first)
|
||||
{
|
||||
oumask = umask(0);
|
||||
numask = oumask & ~(S_IWUSR | S_IXUSR);
|
||||
(void) umask(numask);
|
||||
first = 0;
|
||||
}
|
||||
|
||||
if (last)
|
||||
(void) umask(oumask);
|
||||
|
||||
if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
|
||||
{
|
||||
if (errno == EEXIST || errno == EISDIR)
|
||||
{
|
||||
if (stat(path, &sb) < 0)
|
||||
{
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
else if (!S_ISDIR(sb.st_mode))
|
||||
{
|
||||
if (last)
|
||||
errno = EEXIST;
|
||||
else
|
||||
errno = ENOTDIR;
|
||||
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (last)
|
||||
retval = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!last)
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
if (!first && !last)
|
||||
(void) umask(oumask);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue