From c51f057715587f133abe9bfb32d6d453a7af698b Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 1 Apr 2014 19:43:58 -0700 Subject: Initial work on Windows port --- Makefile | 28 ++++++++++++++++++---- config.c | 25 ++++++++++++++++++++ mem_win.c | 15 ++++++++++++ render.h | 30 +++++++++++++----------- runtime_win.S | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util.c | 2 ++ 6 files changed, 155 insertions(+), 19 deletions(-) create mode 100644 mem_win.c create mode 100644 runtime_win.S diff --git a/Makefile b/Makefile index 61e8a19..a0b995f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,21 @@ + +ifdef WINDOWS + +MEM:=mem_win.o +BLASTEM:=blastem.exe +RUNTIME32:=runtime_win.S + +CC:=wine gcc.exe +CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -DDISABLE_OPENGL -I"C:/MinGW/usr/include/SDL" +LDFLAGS:= -L"C:/MinGW/usr/lib" -lm -lmingw32 -lSDLmain -lSDL -mwindows +CPU:=i686 + +else + +MEM:=mem.o +BLASTEM:=blastem +RUNTIME32:=runtime_32.S + ifdef NOGL LIBS=sdl else @@ -22,17 +40,17 @@ endif ifndef CPU CPU:=$(shell uname -m) endif +endif - -TRANSOBJS=gen.o backend.o mem.o +TRANSOBJS=gen.o backend.o $(MEM) M68KOBJS=68kinst.o m68k_core.o ifeq ($(CPU),x86_64) M68KOBJS+= runtime.o m68k_core_x86.o TRANSOBJS+= gen_x86.o backend_x86.o else ifeq ($(CPU),i686) -M68KOBJS+= runtime_32.o m68k_core_x86.o +M68KOBJS+= $(RUNTIME32) m68k_core_x86.o TRANSOBJS+= gen_x86.o backend_x86.o NOZ80:=1 endif @@ -61,8 +79,8 @@ endif all : dis zdis stateview vgmplay blastem -blastem : $(MAINOBJS) - $(CC) -o blastem $(MAINOBJS) $(LDFLAGS) +$(BLASTEM) : $(MAINOBJS) + $(CC) -o $(BLASTEM) $(MAINOBJS) $(LDFLAGS) dis : dis.o 68kinst.o $(CC) -o dis dis.o 68kinst.o diff --git a/config.c b/config.c index d1efc87..b9adf6f 100644 --- a/config.c +++ b/config.c @@ -11,6 +11,27 @@ #define MAX_NEST 30 //way more than I'll ever need +#ifdef _WIN32 +char * strtok_r(char * input, char * sep, char ** state) +{ + if (input) { + *state = input; + } + char * ret = *state; + while (**state && **state != *sep) + { + ++*state; + } + if (**state) + { + **state = 0; + ++*state; + return ret; + } + return NULL; +} +#endif + tern_node * parse_config(char * config_data) { char *state, *curline; @@ -100,6 +121,9 @@ open_fail: tern_node * load_config() { +#ifdef _WIN32 + tern_node * ret = parse_config_file("default.cfg"); +#else char * exe_dir; char * home = getenv("HOME"); if (!home) { @@ -119,6 +143,7 @@ load_in_app_dir: path = alloc_concat(exe_dir, "/default.cfg"); ret = parse_config_file(path); free(path); +#endif success: if (ret) { return ret; diff --git a/mem_win.c b/mem_win.c new file mode 100644 index 0000000..8a76712 --- /dev/null +++ b/mem_win.c @@ -0,0 +1,15 @@ +/* + Copyright 2013 Michael Pavone + This file is part of BlastEm. + BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. +*/ + +#include "mem.h" +#include + +void * alloc_code(size_t *size) +{ + *size += PAGE_SIZE - (*size & (PAGE_SIZE - 1)); + + return VirtualAlloc(NULL, *size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +} diff --git a/render.h b/render.h index ccc556d..982b3a2 100644 --- a/render.h +++ b/render.h @@ -6,6 +6,22 @@ #ifndef RENDER_H_ #define RENDER_H_ +//TODO: Throw an ifdef in here once there's more than one renderer +#include +#define RENDERKEY_UP SDLK_UP +#define RENDERKEY_DOWN SDLK_DOWN +#define RENDERKEY_LEFT SDLK_LEFT +#define RENDERKEY_RIGHT SDLK_RIGHT +#define RENDERKEY_ESC SDLK_ESCAPE +#define RENDERKEY_LSHIFT SDLK_LSHIFT +#define RENDERKEY_RSHIFT SDLK_RSHIFT +#define RENDER_DPAD_UP SDL_HAT_UP +#define RENDER_DPAD_DOWN SDL_HAT_DOWN +#define RENDER_DPAD_LEFT SDL_HAT_LEFT +#define RENDER_DPAD_RIGHT SDL_HAT_RIGHT + +#define MAX_JOYSTICKS 8 + #include "vdp.h" #include "psg.h" #include "ym2612.h" @@ -35,21 +51,7 @@ int render_joystick_num_buttons(int joystick); int render_joystick_num_hats(int joystick); int render_num_joysticks(); -//TODO: Throw an ifdef in here once there's more than one renderer -#include -#define RENDERKEY_UP SDLK_UP -#define RENDERKEY_DOWN SDLK_DOWN -#define RENDERKEY_LEFT SDLK_LEFT -#define RENDERKEY_RIGHT SDLK_RIGHT -#define RENDERKEY_ESC SDLK_ESCAPE -#define RENDERKEY_LSHIFT SDLK_LSHIFT -#define RENDERKEY_RSHIFT SDLK_RSHIFT -#define RENDER_DPAD_UP SDL_HAT_UP -#define RENDER_DPAD_DOWN SDL_HAT_DOWN -#define RENDER_DPAD_LEFT SDL_HAT_LEFT -#define RENDER_DPAD_RIGHT SDL_HAT_RIGHT -#define MAX_JOYSTICKS 8 #endif //RENDER_H_ diff --git a/runtime_win.S b/runtime_win.S new file mode 100644 index 0000000..c107030 --- /dev/null +++ b/runtime_win.S @@ -0,0 +1,74 @@ + + +invalid_msg: + .asciz "Invalid instruction at %X\n" + + .global _m68k_invalid +_m68k_invalid: + push %ecx + push invalid_msg + xor %eax, %eax + call _printf + push $1 + call _exit + + .global _bcd_add +_bcd_add: + xchg %eax, %edi + + mov %cl, %ch + mov %al, %ah + and $0xF, %ch + and $0xF, %ah + and $0xF0, %cl + and $0xF0, %al + add %ah, %ch + cmp $10, %ch + jb no_adjust + add $6, %ch +no_adjust: + add %ch, %al + add %al, %cl + mov $0, %ch + jc def_adjust + cmp $0xA0, %cl + jb no_adjust_h +def_adjust: + add $0x60, %cl + mov $1, %ch +no_adjust_h: + + mov %edi, %eax + ret + + .global _bcd_sub +_bcd_sub: + xchg %eax, %edi + + mov %cl, %ch + mov %al, %ah + and $0xF, %ch + and $0xF, %ah + and $0xF0, %cl + and $0xF0, %al + sub %ah, %ch + cmp $10, %ch + jb no_adjusts + sub $6, %ch +no_adjusts: + add %ch, %cl + sub %al, %cl + mov $0, %ch + jc def_adjusts + cmp $0xA0, %cl + jb no_adjust_hs +def_adjusts: + sub $0x60, %cl + mov $1, %ch +no_adjust_hs: + + mov %edi, %eax + ret + + + diff --git a/util.c b/util.c index 2bc3109..7fee9db 100644 --- a/util.c +++ b/util.c @@ -75,6 +75,7 @@ void set_exe_str(char * str) exe_str = str; } +#ifndef _WIN32 char * readlink_alloc(char * path) { char * linktext = NULL; @@ -138,3 +139,4 @@ fallback: } return exe_dir; } +#endif -- cgit v1.2.3 From 4468c6074eccd86951fb02d6126b3f4408f1c53e Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 1 Apr 2014 21:12:00 -0700 Subject: Make Windows port a little less half-assed --- Makefile | 13 +++++++++++-- config.c | 6 +----- render_sdl.c | 18 +++++++++++++++++- util.c | 37 ++++++++++++++++++++++++++++++++++++- util.h | 2 ++ 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index a0b995f..83f50f1 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,12 @@ BLASTEM:=blastem.exe RUNTIME32:=runtime_win.S CC:=wine gcc.exe -CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -DDISABLE_OPENGL -I"C:/MinGW/usr/include/SDL" -LDFLAGS:= -L"C:/MinGW/usr/lib" -lm -lmingw32 -lSDLmain -lSDL -mwindows +CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -I"C:/MinGW/usr/include/SDL" -DGLEW_STATIC +LDFLAGS:= -L"C:/MinGW/usr/lib" -lm -lmingw32 -lSDLmain -lSDL +ifndef NOGL +LDFLAGS+= -lopengl32 -lglu32 +endif +LDFLAGS+= -mwindows CPU:=i686 else @@ -76,6 +80,11 @@ else MAINOBJS+= $(Z80OBJS) endif +ifdef WINDOWS +ifndef NOGL +MAINOBJS+= glew.o +endif +endif all : dis zdis stateview vgmplay blastem diff --git a/config.c b/config.c index b9adf6f..eab0308 100644 --- a/config.c +++ b/config.c @@ -121,11 +121,8 @@ open_fail: tern_node * load_config() { -#ifdef _WIN32 - tern_node * ret = parse_config_file("default.cfg"); -#else char * exe_dir; - char * home = getenv("HOME"); + char * home = get_home_dir(); if (!home) { goto load_in_app_dir; } @@ -143,7 +140,6 @@ load_in_app_dir: path = alloc_concat(exe_dir, "/default.cfg"); ret = parse_config_file(path); free(path); -#endif success: if (ret) { return ret; diff --git a/render_sdl.c b/render_sdl.c index e5f5c96..769af96 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -113,14 +113,22 @@ const GLushort element_data[] = {0, 1, 2, 3}; GLuint load_shader(char * fname, GLenum shader_type) { - char * parts[] = {getenv("HOME"), "/.config/blastem/shaders/", fname}; + char * parts[] = {get_home_dir(), "/.config/blastem/shaders/", fname}; char * shader_path = alloc_concat_m(3, parts); + printf("Trying to find shader at %s\n", shader_path); FILE * f = fopen(shader_path, "r"); free(shader_path); if (!f) { +#ifdef _WIN32 + parts[0] = "shaders/"; + parts[1] = fname; + shader_path = alloc_concat_m(2, parts); +#else parts[0] = get_exe_dir(); parts[1] = "/shaders/"; shader_path = alloc_concat_m(3, parts); +#endif + printf("Trying to find shader at %s\n", shader_path); f = fopen(shader_path, "r"); free(shader_path); if (!f) { @@ -128,6 +136,7 @@ GLuint load_shader(char * fname, GLenum shader_type) return 0; } } + puts("reading shader"); long fsize = file_size(f); GLchar * text = malloc(fsize); if (fread(text, 1, fsize, f) != fsize) { @@ -138,6 +147,7 @@ GLuint load_shader(char * fname, GLenum shader_type) GLuint ret = glCreateShader(shader_type); glShaderSource(ret, 1, (const GLchar **)&text, (const GLint *)&fsize); free(text); + puts("compiling shader"); glCompileShader(ret); GLint compile_status, loglen; glGetShaderiv(ret, GL_COMPILE_STATUS, &compile_status); @@ -162,6 +172,7 @@ void render_alloc_surfaces(vdp_context * context) context->oddbuf = context->framebuf = malloc(512 * 256 * 4 * 2); memset(context->oddbuf, 0, 512 * 256 * 4 * 2); context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; + puts("generating textures"); glGenTextures(3, textures); for (int i = 0; i < 3; i++) { @@ -182,11 +193,15 @@ void render_alloc_surfaces(vdp_context * context) glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); + puts("Loading vertex shader"); vshader = load_shader(tern_find_ptr_default(config, "videovertex_shader", "default.v.glsl"), GL_VERTEX_SHADER); + puts("loading fragment shader"); fshader = load_shader(tern_find_ptr_default(config, "videofragment_shader", "default.f.glsl"), GL_FRAGMENT_SHADER); + puts("creating program"); program = glCreateProgram(); glAttachShader(program, vshader); glAttachShader(program, fshader); + puts("linking program"); glLinkProgram(program); GLint link_status; glGetProgramiv(program, GL_LINK_STATUS, &link_status); @@ -205,6 +220,7 @@ void render_alloc_surfaces(vdp_context * context) #ifndef DISABLE_OPENGL } #endif + puts("alloc surfaces done"); } uint8_t render_depth() diff --git a/util.c b/util.c index 7fee9db..45eb9b8 100644 --- a/util.c +++ b/util.c @@ -75,7 +75,41 @@ void set_exe_str(char * str) exe_str = str; } -#ifndef _WIN32 +#ifdef _WIN32 +#include "Shlobj.h" +#include "Windows.h" + +char * get_home_dir() +{ + static char path[MAX_PATH]; + SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path); + return path; +} + +char * get_exe_dir() +{ + static char path[MAX_PATH]; + HMODULE module = GetModuleHandleA(NULL); + GetModuleFileNameA(module, path, MAX_PATH); + + int pathsize = strlen(path); + for(char * cur = path + pathsize - 1; cur != path; cur--) + { + if (*cur == '\\') { + *cur = 0; + break; + } + } + return path; +} + +#else + +char * get_home_dir() +{ + return getenv("HOME"); +} + char * readlink_alloc(char * path) { char * linktext = NULL; @@ -139,4 +173,5 @@ fallback: } return exe_dir; } + #endif diff --git a/util.h b/util.h index d82ac50..780f538 100644 --- a/util.h +++ b/util.h @@ -19,6 +19,8 @@ char * split_keyval(char * text); void set_exe_str(char * str); //Returns the directory the executable is in char * get_exe_dir(); +//Returns the user's home directory +char * get_home_dir(); //Returns the contents of a symlink in a newly allocated string char * readlink_alloc(char * path); -- cgit v1.2.3 From 632c82bd63a13da242c90a5d93dfe7482a0bebe6 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 28 May 2015 21:09:33 -0700 Subject: Adjusted Makefile to support linking against the static glew library from the standard download --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 83f50f1..b7b0eee 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ endif ifdef WINDOWS ifndef NOGL -MAINOBJS+= glew.o +MAINOBJS+= glew32s.lib endif endif -- cgit v1.2.3 From 93a29403d334c8dd1253221fd4588209a706f500 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 28 May 2015 22:31:21 -0700 Subject: Get windows build compiling again post-merge --- Makefile | 8 ++++---- debug.c | 8 ++++++++ io.c | 15 +++++++++++++-- render_sdl.c | 1 + 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index b3e966b..fc6a29a 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,8 @@ MEM:=mem_win.o BLASTEM:=blastem.exe CC:=wine gcc.exe -CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror= -LDFLAGS:= -L"C:/MinGW/usr/lib" -lm -lmingw32 -lSDLmain -lSDL -mwindows +CFLAGS:=-g -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -I"C:/MinGW/usr/include/SDL2" -DGLEW_STATIC +LDFLAGS:= -L"C:/MinGW/usr/lib" -lm -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lglu32 -mwindows CPU:=i686 else @@ -63,7 +63,7 @@ ifeq ($(OS),Darwin) LDFLAGS+= -framework OpenGL endif -TRANSOBJS=gen.o backend.o mem.o +TRANSOBJS=gen.o backend.o $(MEM) M68KOBJS=68kinst.o m68k_core.o ifeq ($(CPU),x86_64) M68KOBJS+= m68k_core_x86.o @@ -97,7 +97,7 @@ else MAINOBJS+= $(Z80OBJS) endif -ifdef WINDOWS +ifeq ($(OS),Windows) MAINOBJS+= glew32s.lib endif diff --git a/debug.c b/debug.c index ac5c34d..6ff8917 100644 --- a/debug.c +++ b/debug.c @@ -3,7 +3,9 @@ #include "68kinst.h" #include #include +#ifndef _WIN32 #include +#endif #include "render.h" static bp_def * breakpoints = NULL; @@ -510,16 +512,21 @@ m68k_context * debugger(m68k_context * context, uint32_t address) printf("%X: %s\n", address, input_buf); uint32_t after = address + (after_pc-pc)*2; int debugging = 1; +#ifdef _WIN32 +#define prompt 1 +#else int prompt = 1; fd_set read_fds; FD_ZERO(&read_fds); struct timeval timeout; +#endif while (debugging) { if (prompt) { fputs(">", stdout); fflush(stdout); } process_events(); +#ifndef _WIN32 timeout.tv_sec = 0; timeout.tv_usec = 16667; FD_SET(fileno(stdin), &read_fds); @@ -529,6 +536,7 @@ m68k_context * debugger(m68k_context * context, uint32_t address) } else { prompt = 1; } +#endif if (!fgets(input_buf, sizeof(input_buf), stdin)) { fputs("fgets failed", stderr); break; diff --git a/io.c b/io.c index d50133d..d6d55c7 100644 --- a/io.c +++ b/io.c @@ -3,6 +3,7 @@ This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ +#ifndef _WIN32 #include #include #include @@ -10,7 +11,9 @@ #include #include #include +#endif #include +#include #include "io.h" #include "blastem.h" @@ -544,7 +547,7 @@ void setup_io_devices(tern_node * config, io_port * ports) for (int i = 0; i < 3; i++) { - +#ifndef _WIN32 if (ports[i].device_type == IO_SEGA_PARALLEL) { char *pipe_name = tern_find_ptr(config, "ioparallel_pipe"); @@ -606,7 +609,9 @@ cleanup_sock: close(ports[i].device.stream.listen_fd); ports[i].device_type = IO_NONE; } - } else if (ports[i].device_type == IO_GAMEPAD3 || ports[i].device_type == IO_GAMEPAD6) { + } else +#endif + if (ports[i].device_type == IO_GAMEPAD3 || ports[i].device_type == IO_GAMEPAD6) { printf("IO port %s connected to gamepad #%d with type '%s'\n", io_name(i), ports[i].device.pad.gamepad_num + 1, device_type_names[ports[i].device_type]); } else { printf("IO port %s connected to device '%s'\n", io_name(i), device_type_names[ports[i].device_type]); @@ -770,6 +775,7 @@ void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction } } +#ifndef _WIN32 static void wait_for_connection(io_port * port) { if (port->device.stream.data_fd == -1) @@ -869,6 +875,7 @@ static void service_socket(io_port *port) } } } +#endif void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle) { @@ -889,12 +896,14 @@ void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle) } port->output = value; break; +#ifndef _WIN32 case IO_GENERIC: wait_for_connection(port); port->input[IO_STATE] = IO_WRITE_PENDING; port->output = value; service_socket(port); break; +#endif default: port->output = value; } @@ -938,6 +947,7 @@ uint8_t io_data_read(io_port * port, uint32_t current_cycle) } break; } +#ifndef _WIN32 case IO_SEGA_PARALLEL: if (!th) { @@ -954,6 +964,7 @@ uint8_t io_data_read(io_port * port, uint32_t current_cycle) service_socket(port); input = ~port->input[IO_TH0]; break; +#endif default: input = 0; break; diff --git a/render_sdl.c b/render_sdl.c index 53a0e2f..38b7ed4 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include "render.h" #include "blastem.h" -- cgit v1.2.3 From 66aedc9c1a87c8811be4dba263dbcd7ec026cc70 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 28 May 2015 23:04:49 -0700 Subject: Fix crash bug in windows build --- Makefile | 2 +- render_sdl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fc6a29a..eed9d6d 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ MEM:=mem_win.o BLASTEM:=blastem.exe CC:=wine gcc.exe -CFLAGS:=-g -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -I"C:/MinGW/usr/include/SDL2" -DGLEW_STATIC +CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -I"C:/MinGW/usr/include/SDL2" -DGLEW_STATIC LDFLAGS:= -L"C:/MinGW/usr/lib" -lm -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lglu32 -mwindows CPU:=i686 diff --git a/render_sdl.c b/render_sdl.c index 38b7ed4..9de86dd 100644 --- a/render_sdl.c +++ b/render_sdl.c @@ -107,7 +107,7 @@ const GLushort element_data[] = {0, 1, 2, 3}; GLuint load_shader(char * fname, GLenum shader_type) { - char * parts[] = {getenv("HOME"), "/.config/blastem/shaders/", fname}; + char * parts[] = {get_home_dir(), "/.config/blastem/shaders/", fname}; char * shader_path = alloc_concat_m(3, parts); FILE * f = fopen(shader_path, "r"); free(shader_path); -- cgit v1.2.3