Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba6f5d76c9 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -21,7 +21,3 @@ rom/
|
||||
dumpinfo
|
||||
testserial
|
||||
wonderswan
|
||||
|
||||
# Build folder
|
||||
cmake-*/
|
||||
build*/
|
||||
9
.gitmodules
vendored
9
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "external/portaudio"]
|
||||
path = external/portaudio
|
||||
url = https://git.assembla.com/portaudio.git
|
||||
[submodule "external/glfw"]
|
||||
path = external/glfw
|
||||
url = https://github.com/glfw/glfw.git
|
||||
[submodule "external/nanogui"]
|
||||
path = external/nanogui
|
||||
url = git@github.com:Godzil/nanogui.git
|
||||
|
||||
38
.travis.yml
38
.travis.yml
@@ -1,38 +0,0 @@
|
||||
dist: bionic
|
||||
language: c
|
||||
os:
|
||||
- linux
|
||||
# - osx
|
||||
#matrix:
|
||||
# allow_failures:
|
||||
# - os: osx
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libsdl1.2debian
|
||||
- libsdl1.2-dev
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
script:
|
||||
- make
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.sonar/cache'
|
||||
|
||||
#before_install:
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glew; fi
|
||||
|
||||
#install: true
|
||||
|
||||
#after_success:
|
||||
# - bash <(curl -s https://codecov.io/bash)
|
||||
@@ -1,43 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
# External cmake modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/external/cmake ${CMAKE_MODULE_PATH})
|
||||
|
||||
project("NewOswan")
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
git_describe(VERSION --tags --dirty=-dirty)
|
||||
|
||||
# Include GLFW3
|
||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory("external/glfw")
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
|
||||
option(WARN_AS_ERROR "Enable warning as error" OFF)
|
||||
|
||||
set(COMP_FLAGS "-march=native -Wall -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-write-strings")
|
||||
if (WARN_AS_ERROR)
|
||||
set(COMP_FLAGS "${COMP_FLAGS} -Werror")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS ${COMP_FLAGS})
|
||||
set(CMAKE_CXX_FLAGS ${COMP_FLAGS})
|
||||
|
||||
message("-- Building version ${VERSION}")
|
||||
|
||||
add_executable(wonderswan main.cpp)
|
||||
|
||||
set_property(TARGET wonderswan PROPERTY CXX_STANDARD 98)
|
||||
|
||||
target_compile_definitions(wonderswan PUBLIC VERSION="${VERSION}")
|
||||
target_include_directories(wonderswan PUBLIC source)
|
||||
|
||||
add_subdirectory(source)
|
||||
|
||||
target_link_libraries(wonderswan wswan glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
|
||||
|
||||
add_executable(dumpinfo dumpinfo.c)
|
||||
9
Makefile
9
Makefile
@@ -16,13 +16,12 @@ OBJS = $(wonderswan_CXX_SRCS:.cpp=.o)
|
||||
|
||||
all: wonderswan dumpinfo
|
||||
|
||||
# CXX = g++
|
||||
CXXFLAGS = -g -O2 `sdl-config --cflags` -Wall -std=c++98 -Wno-write-strings -Wno-unused-result
|
||||
CXX = g++
|
||||
CXXFLAGS = -g -O2 `sdl-config --cflags` -Wall -Werror -std=c++98 -Wno-write-strings
|
||||
OPTIONS = -D_REENTRANT -I. -DVERSION=\"`git describe --tags --long --dirty`\"
|
||||
|
||||
LIBRARY_PATH =
|
||||
SDL_LIBS = `sdl-config --libs`
|
||||
LIBS = -g $(LIBRARY_PATH) $(SDL_LIBS)
|
||||
LIBS = -g $(LIBRARY_PATH) `sdl-config --libs`
|
||||
|
||||
ALLCFLAGS = $(CFLAGS) $(CEXTRA) $(OPTIONS) $(ALLFLAGS)
|
||||
ALLCXXFLAGS=$(CXXFLAGS) $(CXXEXTRA) $(OPTIONS) $(ALLFLAGS)
|
||||
@@ -54,4 +53,4 @@ dumpinfo: dumpinfo.o
|
||||
$(CXX) $(LIBS) -o $@ $(<)
|
||||
|
||||
wonderswan: $(OBJS)
|
||||
$(CXX) -o $@ $(OBJS) $(LIBS)
|
||||
$(CXX) $(LIBS) -o $@ $(OBJS)
|
||||
|
||||
168
external/cmake/GetGitRevisionDescription.cmake
vendored
168
external/cmake/GetGitRevisionDescription.cmake
vendored
@@ -1,168 +0,0 @@
|
||||
# - Returns a version string from Git
|
||||
#
|
||||
# These functions force a re-configure on each git commit so that you can
|
||||
# trust the values of the variables in your build system.
|
||||
#
|
||||
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the refspec and sha hash of the current head revision
|
||||
#
|
||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the source tree, and adjusting
|
||||
# the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe --exact-match on the source tree,
|
||||
# and adjusting the output so that it tests false if there was no exact
|
||||
# matching tag.
|
||||
#
|
||||
# git_local_changes(<var>)
|
||||
#
|
||||
# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
|
||||
# Uses the return code of "git diff-index --quiet HEAD --".
|
||||
# Does not regard untracked files.
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__get_git_revision_description)
|
||||
return()
|
||||
endif()
|
||||
set(__get_git_revision_description YES)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
|
||||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
|
||||
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
|
||||
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
|
||||
# We have reached the root directory, we are not in git
|
||||
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
endwhile()
|
||||
# check if this is a submodule
|
||||
if(NOT IS_DIRECTORY ${GIT_DIR})
|
||||
file(READ ${GIT_DIR} submodule)
|
||||
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
|
||||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
|
||||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
|
||||
endif()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${GIT_DIR}/HEAD")
|
||||
return()
|
||||
endif()
|
||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
||||
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
|
||||
|
||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
||||
"${GIT_DATA}/grabRef.cmake"
|
||||
@ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
|
||||
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO sanitize
|
||||
#if((${ARGN}" MATCHES "&&") OR
|
||||
# (ARGN MATCHES "||") OR
|
||||
# (ARGN MATCHES "\\;"))
|
||||
# message("Please report the following error to the project!")
|
||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
||||
#endif()
|
||||
|
||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
describe
|
||||
#${hash}
|
||||
${ARGN}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
git_describe(out --exact-match ${ARGN})
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_local_changes _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
diff-index --quiet HEAD --
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(res EQUAL 0)
|
||||
set(${_var} "CLEAN" PARENT_SCOPE)
|
||||
else()
|
||||
set(${_var} "DIRTY" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -1,41 +0,0 @@
|
||||
#
|
||||
# Internal file for GetGitRevisionDescription.cmake
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
set(HEAD_HASH)
|
||||
|
||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
||||
|
||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
||||
if(HEAD_CONTENTS MATCHES "ref")
|
||||
# named branch
|
||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
else()
|
||||
configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
|
||||
file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
|
||||
if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
|
||||
set(HEAD_HASH "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# detached HEAD
|
||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
||||
endif()
|
||||
|
||||
if(NOT HEAD_HASH)
|
||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
||||
endif()
|
||||
1
external/glfw
vendored
1
external/glfw
vendored
Submodule external/glfw deleted from 0ef149c8f2
1
external/nanogui
vendored
Submodule
1
external/nanogui
vendored
Submodule
Submodule external/nanogui added at 2427ffdbff
1
external/portaudio
vendored
1
external/portaudio
vendored
Submodule external/portaudio deleted from c5d2c51bd6
5
main.cpp
5
main.cpp
@@ -15,6 +15,8 @@
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "SDL.h"
|
||||
#include "source/SDLptc.h"
|
||||
#include "source/log.h"
|
||||
#include "source/rom.h"
|
||||
#include "source/nec/nec.h"
|
||||
@@ -121,6 +123,9 @@ int ws_mk_ieppath()
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
atexit(SDL_Quit);
|
||||
SDL_Init(SDL_INIT_TIMER);
|
||||
|
||||
if (!log_init(LOG_PATH))
|
||||
{
|
||||
printf("Warning: cannot open log file %s\n",LOG_PATH);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
set(SOURCES audio.cpp emulate.cpp gpu.cpp io.cpp log.cpp memory.cpp rom.cpp ws.cpp)
|
||||
set(HEADERS audio.h emulate.h gpu.h ieeprom.h initialIo.h io.h log.h memory.h rom.h ws.h)
|
||||
|
||||
add_library(wswan ${SOURCES} ${HEADERS})
|
||||
|
||||
target_link_libraries(wswan nec_v30 glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
|
||||
|
||||
target_include_directories(wswan PUBLIC .)
|
||||
|
||||
add_subdirectory(nec)
|
||||
314
source/SDLptc.h
Normal file
314
source/SDLptc.h
Normal file
@@ -0,0 +1,314 @@
|
||||
|
||||
/* Some simple emulation classes to get PTC code running on SDL */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#define randomize() srand(time(NULL))
|
||||
#define random(max) (rand()%(max))
|
||||
|
||||
#ifndef stricmp
|
||||
#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
class Error
|
||||
{
|
||||
|
||||
public:
|
||||
Error(const char *message)
|
||||
{
|
||||
strcpy(_message, message);
|
||||
}
|
||||
|
||||
void report(void)
|
||||
{
|
||||
printf("Error: %s\n", _message);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char _message[1024];
|
||||
};
|
||||
|
||||
class Area
|
||||
{
|
||||
|
||||
public:
|
||||
Area(int left, int top, int right, int bottom)
|
||||
{
|
||||
_left = left;
|
||||
_top = top;
|
||||
_right = right;
|
||||
_bottom = bottom;
|
||||
}
|
||||
|
||||
int left(void) const
|
||||
{
|
||||
return(_left);
|
||||
}
|
||||
int right(void) const
|
||||
{
|
||||
return(_right);
|
||||
}
|
||||
int top(void) const
|
||||
{
|
||||
return(_top);
|
||||
}
|
||||
int bottom(void) const
|
||||
{
|
||||
return(_bottom);
|
||||
}
|
||||
int width(void) const
|
||||
{
|
||||
return(_right-_left);
|
||||
}
|
||||
int height(void) const
|
||||
{
|
||||
return(_bottom-_top);
|
||||
}
|
||||
|
||||
private:
|
||||
int _left, _top, _right, _bottom;
|
||||
};
|
||||
|
||||
|
||||
class Format
|
||||
{
|
||||
|
||||
public:
|
||||
Format(int bpp, int maskR = 0, int maskG = 0, int maskB = 0)
|
||||
{
|
||||
_bpp = bpp;
|
||||
_maskR = maskR;
|
||||
_maskG = maskG;
|
||||
_maskB = maskB;
|
||||
}
|
||||
|
||||
Uint8 BPP(void) const
|
||||
{
|
||||
return(_bpp);
|
||||
}
|
||||
Uint32 MaskR(void) const
|
||||
{
|
||||
return(_maskR);
|
||||
}
|
||||
Uint32 MaskG(void) const
|
||||
{
|
||||
return(_maskG);
|
||||
}
|
||||
Uint32 MaskB(void) const
|
||||
{
|
||||
return(_maskB);
|
||||
}
|
||||
|
||||
private:
|
||||
Uint8 _bpp;
|
||||
Uint32 _maskR, _maskG, _maskB;
|
||||
};
|
||||
|
||||
class Surface
|
||||
{
|
||||
|
||||
public:
|
||||
Surface(int w, int h, const Format &format)
|
||||
{
|
||||
surface = SDL_AllocSurface(SDL_SWSURFACE, w, h, format.BPP(),
|
||||
format.MaskR(),format.MaskG(),format.MaskB(),0);
|
||||
|
||||
if ( surface == NULL )
|
||||
{
|
||||
throw Error(SDL_GetError());
|
||||
}
|
||||
|
||||
nupdates = 0;
|
||||
is_console = 0;
|
||||
}
|
||||
Surface(void)
|
||||
{
|
||||
nupdates = 0;
|
||||
is_console = 1;
|
||||
}
|
||||
virtual ~Surface()
|
||||
{
|
||||
if ( ! is_console )
|
||||
{
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
virtual int width(void)
|
||||
{
|
||||
return surface->w;
|
||||
}
|
||||
virtual int height(void)
|
||||
{
|
||||
return surface->h;
|
||||
}
|
||||
virtual int pitch(void)
|
||||
{
|
||||
return surface->pitch;
|
||||
}
|
||||
|
||||
virtual void palette(int32_t *pcolors)
|
||||
{
|
||||
SDL_Color colors[256];
|
||||
|
||||
for ( int i=0; i<256; ++i )
|
||||
{
|
||||
colors[i].r = (pcolors[i]>>16)&0xFF;
|
||||
colors[i].g = (pcolors[i]>>8)&0xFF;
|
||||
colors[i].b = (pcolors[i]>>0)&0xFF;
|
||||
}
|
||||
|
||||
SDL_SetColors(surface, colors, 0, 256);
|
||||
}
|
||||
|
||||
virtual void *lock(void)
|
||||
{
|
||||
if ( SDL_MUSTLOCK(surface) )
|
||||
{
|
||||
while ( SDL_LockSurface(surface) < 0 )
|
||||
{
|
||||
SDL_Delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
return (Uint8 *)surface->pixels;
|
||||
}
|
||||
|
||||
virtual void unlock(void)
|
||||
{
|
||||
if ( SDL_MUSTLOCK(surface) )
|
||||
{
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void copy(Surface &dst,
|
||||
const Area &srcarea, const Area &dstarea)
|
||||
{
|
||||
SDL_Rect srcrect, dstrect;
|
||||
srcrect.x = srcarea.left();
|
||||
srcrect.y = srcarea.top();
|
||||
srcrect.w = srcarea.width();
|
||||
srcrect.h = srcarea.height();
|
||||
dstrect.x = dstarea.left();
|
||||
dstrect.y = dstarea.top();
|
||||
dstrect.w = dstarea.width();
|
||||
dstrect.h = dstarea.height();
|
||||
SDL_BlitSurface(surface, &srcrect, dst.surface, &dstrect);
|
||||
dst.updates[dst.nupdates++] = dstrect;
|
||||
}
|
||||
virtual void copy(Surface &dst)
|
||||
{
|
||||
SDL_Rect srcrect, dstrect;
|
||||
srcrect.x = 0;
|
||||
srcrect.y = 0;
|
||||
srcrect.w = surface->w;
|
||||
srcrect.h = surface->h;
|
||||
dstrect.x = 0;
|
||||
dstrect.y = 0;
|
||||
dstrect.w = surface->w;
|
||||
dstrect.h = surface->h;
|
||||
SDL_LowerBlit(surface, &srcrect, dst.surface, &dstrect);
|
||||
dst.updates[dst.nupdates++] = dstrect;
|
||||
}
|
||||
|
||||
virtual void update(void)
|
||||
{
|
||||
SDL_UpdateRects(surface, nupdates, updates);
|
||||
nupdates = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
SDL_Surface *surface;
|
||||
int nupdates;
|
||||
SDL_Rect updates[1]; /* Definitely increase this.. */
|
||||
int is_console;
|
||||
};
|
||||
|
||||
class Console : public Surface
|
||||
{
|
||||
int fullscreen;
|
||||
public:
|
||||
Console() : Surface()
|
||||
{
|
||||
fullscreen=0;
|
||||
}
|
||||
~Console()
|
||||
{
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
void close(void)
|
||||
{
|
||||
SDL_Quit();
|
||||
}
|
||||
void option(char *option)
|
||||
{
|
||||
if (!stricmp(option,"fullscreen output"))
|
||||
{
|
||||
fullscreen=1;
|
||||
}
|
||||
else if (!stricmp(option,"windowed output"))
|
||||
{
|
||||
fullscreen=0;
|
||||
}
|
||||
}
|
||||
void open(const char *title, int width, int height, const Format &format)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
if ( SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
|
||||
{
|
||||
throw Error(SDL_GetError());
|
||||
}
|
||||
|
||||
flags = (SDL_HWSURFACE|SDL_HWPALETTE);
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
flags|=SDL_FULLSCREEN;
|
||||
}
|
||||
|
||||
surface = SDL_SetVideoMode(width, height, 0, flags);
|
||||
|
||||
if ( surface == NULL )
|
||||
{
|
||||
throw Error(SDL_GetError());
|
||||
}
|
||||
|
||||
SDL_WM_SetCaption(title, title);
|
||||
}
|
||||
|
||||
int key(void)
|
||||
{
|
||||
SDL_Event event;
|
||||
int keyevent;
|
||||
|
||||
keyevent = 0;
|
||||
|
||||
while ( SDL_PollEvent(&event) )
|
||||
{
|
||||
/* Real key events trigger this function */
|
||||
if ( event.type == SDL_KEYDOWN )
|
||||
{
|
||||
keyevent = 1;
|
||||
}
|
||||
|
||||
/* So do quit events -- let the app know about it */
|
||||
if ( event.type == SDL_QUIT )
|
||||
{
|
||||
keyevent = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(keyevent);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "io.h"
|
||||
#include "audio.h"
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#define SNDP ws_ioRam[0x80]
|
||||
#define SNDV ws_ioRam[0x88]
|
||||
#define SNDSWP ws_ioRam[0x8C]
|
||||
@@ -89,7 +91,6 @@ int RandData[BUFSIZEN];
|
||||
int CntSwp=0;
|
||||
int PcmWrPos=0;
|
||||
|
||||
/*
|
||||
const long TblChVol[16]= // n/15 n=0~15
|
||||
{
|
||||
-10000,-2352,-1750,-1398,-1148,-954,-796,-662,
|
||||
@@ -100,7 +101,6 @@ const long TblMainVol[4]= // 1,1/2,1/4,1/8
|
||||
{
|
||||
0,-602,-1204,-1806
|
||||
};
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// seal audio specific
|
||||
@@ -142,6 +142,7 @@ void ws_audio_init(void)
|
||||
ws_audio_log=0;
|
||||
//ws_audio_seal_init();
|
||||
ws_audio_reset();
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -19,16 +19,9 @@
|
||||
#include <errno.h> /* Error number definitions */
|
||||
#include <termios.h> /* POSIX terminal control definitions */
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define GLFW_INCLUDE_GLEXT
|
||||
#define GL_SILENCE_DEPRECATION
|
||||
#include <GLFW/glfw3.h>
|
||||
/* "Apple" fix */
|
||||
#ifndef GL_TEXTURE_RECTANGLE
|
||||
#define GL_TEXTURE_RECTANGLE GL_TEXTURE_RECTANGLE_EXT
|
||||
#endif
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDLptc.h"
|
||||
#include "log.h"
|
||||
#include "io.h"
|
||||
#include "ws.h"
|
||||
@@ -39,308 +32,336 @@
|
||||
#include "audio.h"
|
||||
#include "memory.h"
|
||||
|
||||
SDL_Joystick *joystick=NULL;
|
||||
char app_window_title[256];
|
||||
int app_gameRunning=0;
|
||||
int app_terminate=0;
|
||||
int app_fullscreen=0;
|
||||
SDL_Event app_input_event;
|
||||
int app_rotated=0;
|
||||
|
||||
|
||||
int ws_key_esc = 0;
|
||||
|
||||
/* Open GL stuffs */
|
||||
typedef struct GLWindow_t GLWindow;
|
||||
struct KeyArray
|
||||
{
|
||||
uint8_t lastState;
|
||||
uint8_t curState;
|
||||
uint8_t debounced;
|
||||
GLFWwindow *window;
|
||||
};
|
||||
struct GLWindow_t
|
||||
{
|
||||
struct KeyArray keyArray[512];
|
||||
GLFWwindow *windows;
|
||||
uint8_t *videoMemory;
|
||||
GLuint videoTexture;
|
||||
int WIDTH;
|
||||
int HEIGHT;
|
||||
};
|
||||
static GLWindow mainWindow;
|
||||
static int window_num = 0;
|
||||
static void ShowScreen(GLWindow *g, int w, int h)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
|
||||
|
||||
// glTexSubImage2D is faster when not using a texture range
|
||||
glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, w, h,
|
||||
GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, g->videoMemory);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(0.0f, h);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(w, h);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
|
||||
glTexCoord2f(w, 0.0f);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
glEnd();
|
||||
|
||||
glFlush();
|
||||
}
|
||||
static void GLWindowInitEx(GLWindow *g, int w, int h)
|
||||
{
|
||||
g->WIDTH = w;
|
||||
g->HEIGHT = h;
|
||||
g->videoTexture = window_num++;
|
||||
}
|
||||
static void setupGL(GLWindow *g, int w, int h)
|
||||
{
|
||||
g->videoMemory = (uint8_t *)malloc(w * h * sizeof(uint16_t));
|
||||
memset(g->videoMemory, 0, w * h * sizeof(uint16_t));
|
||||
//Tell OpenGL how to convert from coordinates to pixel values
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_RECTANGLE);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
|
||||
|
||||
// glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_NV_EXT, 0, NULL);
|
||||
|
||||
// glTexParameteri(GL_TEXTURE_RECTANGLE_NV_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_CACHED_APPLE);
|
||||
// glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, g->videoMemory);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
void restoreGL(GLWindow *g)
|
||||
{
|
||||
//Tell OpenGL how to convert from coordinates to pixel values
|
||||
glViewport(0, 0, g->WIDTH, g->HEIGHT);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_RECTANGLE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
static void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod)
|
||||
{
|
||||
struct KeyArray *keyArray;
|
||||
|
||||
keyArray = (struct KeyArray *)glfwGetWindowUserPointer(window);
|
||||
|
||||
keyArray[key].lastState = keyArray[key].curState;
|
||||
if (action == GLFW_RELEASE)
|
||||
{
|
||||
keyArray[key].curState = GLFW_RELEASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyArray[key].curState = GLFW_PRESS;
|
||||
}
|
||||
keyArray[key].debounced |= (keyArray[key].lastState == GLFW_RELEASE) && (keyArray[key].curState == GLFW_PRESS);
|
||||
keyArray[key].window = window;
|
||||
/*printf("key:%d, state:%d debounce:%d, laststate:%d\n", key, keyArray[key].curState,
|
||||
keyArray[key].debounced, keyArray[key].lastState);*/
|
||||
}
|
||||
static void sizeHandler(GLFWwindow *window, int xs, int ys)
|
||||
{
|
||||
glfwMakeContextCurrent(window);
|
||||
glViewport(0, 0, xs, ys);
|
||||
ShowScreen(&mainWindow, 244, 144);
|
||||
}
|
||||
static void error_callback(int error, const char *description)
|
||||
{
|
||||
puts(description);
|
||||
}
|
||||
static void initDisplay(GLWindow *g)
|
||||
{
|
||||
int h = g->HEIGHT;
|
||||
int w = g->WIDTH;
|
||||
|
||||
/// Initialize GLFW
|
||||
glfwInit();
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
// Open screen OpenGL window
|
||||
if (!(g->windows = glfwCreateWindow(g->WIDTH, g->HEIGHT, "Main", NULL, NULL)))
|
||||
{
|
||||
glfwTerminate();
|
||||
fprintf(stderr, "Window creation error...\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
glfwSetWindowAspectRatio(g->windows, 244, 144);
|
||||
|
||||
glfwMakeContextCurrent(g->windows);
|
||||
setupGL(g, g->WIDTH, g->HEIGHT);
|
||||
|
||||
glfwSwapInterval(1); // We need vsync
|
||||
|
||||
glfwGetWindowSize(g->windows, &w, &h);
|
||||
|
||||
glfwSetWindowUserPointer(g->windows, g->keyArray);
|
||||
|
||||
glfwSetKeyCallback(g->windows, kbHandler);
|
||||
glfwSetWindowSizeCallback(g->windows, sizeHandler);
|
||||
}
|
||||
static void clearScreen(GLWindow *g)
|
||||
{
|
||||
memset(g->videoMemory, 0, sizeof(uint8_t) * g->WIDTH * g->HEIGHT * 4);
|
||||
}
|
||||
static void updateScreen(GLWindow *g)
|
||||
{
|
||||
/* Update windows code */
|
||||
glfwMakeContextCurrent(g->windows);
|
||||
ShowScreen(g, g->WIDTH, g->HEIGHT);
|
||||
glfwSwapBuffers(g->windows);
|
||||
glfwPollEvents();
|
||||
}
|
||||
uint64_t getTicks()
|
||||
{
|
||||
struct timeval curTime;
|
||||
uint64_t ticks;
|
||||
/* Get datetime */
|
||||
gettimeofday(&curTime, NULL);
|
||||
|
||||
ticks = (curTime.tv_sec* 1000) + curTime.tv_usec / 1000;
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static inline int getKeyState(int key)
|
||||
{
|
||||
return mainWindow.keyArray[key].curState;
|
||||
}
|
||||
|
||||
static void read_keys()
|
||||
{
|
||||
ws_key_start=0;
|
||||
ws_key_x4=0;
|
||||
ws_key_x2=0;
|
||||
ws_key_x1=0;
|
||||
ws_key_x3=0;
|
||||
ws_key_y4=0;
|
||||
ws_key_y2=0;
|
||||
ws_key_y1=0;
|
||||
ws_key_y3=0;
|
||||
ws_key_button_a=0;
|
||||
ws_key_button_b=0;
|
||||
static int testJoystick=1;
|
||||
|
||||
if (getKeyState(GLFW_KEY_E))
|
||||
if (testJoystick==1)
|
||||
{
|
||||
testJoystick=0;
|
||||
fprintf(log_get(),"%i joysticks were found.\n\n", SDL_NumJoysticks() );
|
||||
fprintf(log_get(),"The names of the joysticks are:\n");
|
||||
|
||||
for(int tti=0; tti < SDL_NumJoysticks(); tti++ )
|
||||
{
|
||||
fprintf(log_get()," %s\n", SDL_JoystickName(tti));
|
||||
}
|
||||
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
joystick = SDL_JoystickOpen(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (joystick!=NULL)
|
||||
{
|
||||
SDL_JoystickClose(0);
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
joystick = SDL_JoystickOpen(0);
|
||||
}
|
||||
}
|
||||
|
||||
while ( SDL_PollEvent(&app_input_event) )
|
||||
{
|
||||
if ( app_input_event.type == SDL_QUIT )
|
||||
{
|
||||
ws_key_esc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
if (SDL_JoystickGetButton(joystick,0))
|
||||
{
|
||||
ws_key_start=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_start=0;
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(joystick,1))
|
||||
{
|
||||
ws_key_button_a=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_button_a=0;
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetButton(joystick,2))
|
||||
{
|
||||
ws_key_button_b=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_button_b=0;
|
||||
}
|
||||
|
||||
|
||||
if (SDL_JoystickGetAxis(joystick,0)<-7000)
|
||||
{
|
||||
ws_key_x4=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_x4=0;
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetAxis(joystick,0)>7000)
|
||||
{
|
||||
ws_key_x2=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_x2=0;
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetAxis(joystick,1)<-7000)
|
||||
{
|
||||
ws_key_x1=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_x1=0;
|
||||
}
|
||||
|
||||
if (SDL_JoystickGetAxis(joystick,1)>7000)
|
||||
{
|
||||
ws_key_x3=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_x3=0;
|
||||
}
|
||||
ws_key_y4=0;
|
||||
ws_key_y2=0;
|
||||
ws_key_y1=0;
|
||||
ws_key_y3=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_key_start=0;
|
||||
ws_key_x4=0;
|
||||
ws_key_x2=0;
|
||||
ws_key_x1=0;
|
||||
ws_key_x3=0;
|
||||
ws_key_y4=0;
|
||||
ws_key_y2=0;
|
||||
ws_key_y1=0;
|
||||
ws_key_y3=0;
|
||||
ws_key_button_a=0;
|
||||
ws_key_button_b=0;
|
||||
}
|
||||
|
||||
uint8_t *keystate = SDL_GetKeyState(NULL);
|
||||
|
||||
if ( keystate[SDLK_e])
|
||||
{
|
||||
dump_memory();
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_R))
|
||||
if ( keystate[SDLK_r])
|
||||
{
|
||||
printf("Boop\n");
|
||||
ws_reset();
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_ESCAPE))
|
||||
if ( keystate[SDLK_ESCAPE] )
|
||||
{
|
||||
ws_key_esc = 1;
|
||||
}
|
||||
|
||||
if ( getKeyState(GLFW_KEY_UP))
|
||||
if ( keystate[SDLK_UP] )
|
||||
{
|
||||
ws_key_x1=1;
|
||||
}
|
||||
|
||||
if ( getKeyState(GLFW_KEY_DOWN))
|
||||
if ( keystate[SDLK_DOWN] )
|
||||
{
|
||||
ws_key_x3=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_RIGHT))
|
||||
if ( keystate[SDLK_RIGHT] )
|
||||
{
|
||||
ws_key_x2=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_LEFT))
|
||||
if ( keystate[SDLK_LEFT] )
|
||||
{
|
||||
ws_key_x4=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_ENTER))
|
||||
if (keystate[SDLK_RETURN])
|
||||
{
|
||||
ws_key_start=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_C))
|
||||
if (keystate[SDLK_c])
|
||||
{
|
||||
ws_key_button_a=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_X))
|
||||
if (keystate[SDLK_x])
|
||||
{
|
||||
ws_key_button_b=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_W))
|
||||
if (keystate[SDLK_w])
|
||||
{
|
||||
ws_key_y1=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_A))
|
||||
if (keystate[SDLK_a])
|
||||
{
|
||||
ws_key_y4=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_S))
|
||||
if (keystate[SDLK_s])
|
||||
{
|
||||
ws_key_y3=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_D))
|
||||
if (keystate[SDLK_d])
|
||||
{
|
||||
ws_key_y2=1;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_O))
|
||||
if (keystate[SDLK_o])
|
||||
{
|
||||
ws_cyclesByLine+=10;
|
||||
}
|
||||
|
||||
if (getKeyState(GLFW_KEY_L))
|
||||
if (keystate[SDLK_l])
|
||||
{
|
||||
ws_cyclesByLine-=10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void ws_drawDoubledScanline(int16_t *vs, int16_t *backbuffer_alias)
|
||||
{
|
||||
register int32_t *vs_alias = (int32_t *)vs;
|
||||
register int32_t data;
|
||||
|
||||
for (int pixel = 0 ; pixel < 224 ; pixel += 8)
|
||||
{
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void ws_drawDoubledRotatedScanline(int16_t *vs, int16_t *backbuffer_alias)
|
||||
{
|
||||
register int32_t *vs_alias = (int32_t *)vs;
|
||||
register int32_t data;
|
||||
|
||||
for (int pixel = 0 ; pixel < 144 ; pixel += 8)
|
||||
{
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
data = *backbuffer_alias++;
|
||||
data |= (data << 16);
|
||||
*vs_alias++ = data;
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_rotate_backbuffer(int16_t *backbuffer)
|
||||
{
|
||||
static int16_t temp[224*144];
|
||||
|
||||
memcpy(temp,backbuffer,224*144*2);
|
||||
|
||||
for (int line=0; line<144; line++)
|
||||
for (int column=0; column<224; column++)
|
||||
{
|
||||
backbuffer[line+((223-column)<<7)+((223-column)<<4)]=temp[column+(line<<7)+(line<<6)+(line<<5)];
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -358,67 +379,182 @@ void ws_emulate(void)
|
||||
int i = 0;
|
||||
|
||||
double dTime = 0.0, dNormalLast = 0.0, dTemp;
|
||||
int32_t surfacePitch;
|
||||
|
||||
// 15 bits RGB555
|
||||
//Format format(16, 0x007c00, 0x00003e0, 0x0000001f);
|
||||
GLWindowInitEx(&mainWindow, 224, 144);
|
||||
initDisplay(&mainWindow);
|
||||
clearScreen(&mainWindow);
|
||||
updateScreen(&mainWindow);
|
||||
int16_t *backBuffer = (int16_t *)mainWindow.videoMemory;
|
||||
// 15 bits RGB555
|
||||
Format format(16, 0x007c00, 0x00003e0, 0x0000001f);
|
||||
Console console;
|
||||
Surface *surface;
|
||||
|
||||
|
||||
dNormalLast = (double)getTicks();
|
||||
|
||||
while (1)
|
||||
if (app_rotated)
|
||||
{
|
||||
surface = new Surface(144 * 2, 224 * 2, format);
|
||||
int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t));
|
||||
memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t));
|
||||
surfacePitch = (surface->pitch() >> 1);
|
||||
|
||||
dTemp = getTicks();
|
||||
dTime = dTemp - dNormalLast;
|
||||
dNormalLast = (double)SDL_GetTicks();
|
||||
|
||||
console.open(app_window_title, 144 * 2, 224 * 2, format);
|
||||
|
||||
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
|
||||
|
||||
if (nCount <= 0)
|
||||
{
|
||||
/* Sleep for 2ms */
|
||||
usleep(2000);
|
||||
} // No need to do anything for a bit
|
||||
else
|
||||
while (1)
|
||||
{
|
||||
|
||||
dNormalLast += nCount * (1 / 0.07547);
|
||||
dTemp = (double)SDL_GetTicks();
|
||||
dTime = dTemp - dNormalLast;
|
||||
|
||||
if (nCount > 10)
|
||||
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
|
||||
|
||||
if (nCount <= 0)
|
||||
{
|
||||
nCount = 10;
|
||||
}
|
||||
|
||||
read_keys();
|
||||
|
||||
if (ws_key_esc)
|
||||
SDL_Delay(2);
|
||||
} // No need to do anything for a bit
|
||||
else
|
||||
{
|
||||
app_terminate = 1;
|
||||
|
||||
if ((ws_rom_path != NULL) || (app_terminate))
|
||||
dNormalLast += nCount * (1 / 0.07547);
|
||||
|
||||
if (nCount > 10)
|
||||
{
|
||||
break;
|
||||
nCount = 10;
|
||||
}
|
||||
|
||||
read_keys();
|
||||
|
||||
if (ws_key_esc)
|
||||
{
|
||||
console.close();
|
||||
|
||||
app_terminate = 1;
|
||||
|
||||
if ((ws_rom_path != NULL) || (app_terminate))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
console.open(app_window_title, 144 * 2, 224 * 2, format);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i < nCount - 1 ; i++)
|
||||
{
|
||||
while (!ws_executeLine(backBuffer, 0))
|
||||
for (i = 0 ; i < nCount - 1 ; i++)
|
||||
{
|
||||
while (!ws_executeLine(backbuffer, 0))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
while (!ws_executeLine(backbuffer, 1))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
while (!ws_executeLine(backBuffer, 1))
|
||||
{
|
||||
}
|
||||
|
||||
updateScreen(&mainWindow);
|
||||
ws_rotate_backbuffer(backbuffer);
|
||||
|
||||
int16_t *vs = (int16_t *)surface->lock();
|
||||
int16_t *backbuffer_alias = backbuffer;
|
||||
|
||||
for (int line = 0 ; line < 224 ; line++)
|
||||
{
|
||||
ws_drawDoubledRotatedScanline(vs, backbuffer_alias);
|
||||
vs += surfacePitch;
|
||||
ws_drawDoubledRotatedScanline(vs, backbuffer_alias);
|
||||
vs += surfacePitch;
|
||||
backbuffer_alias += 144;
|
||||
}
|
||||
|
||||
surface->unlock();
|
||||
surface->copy(console);
|
||||
console.update();
|
||||
}
|
||||
}
|
||||
|
||||
console.close();
|
||||
delete surface;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
surface = new Surface(224 * 2, 144 * 2, format);
|
||||
int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t));
|
||||
memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t));
|
||||
surfacePitch = (surface->pitch() >> 1);
|
||||
|
||||
dNormalLast = (double)SDL_GetTicks();
|
||||
|
||||
console.open(app_window_title, 224 * 2, 144 * 2, format);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
dTemp = (double)SDL_GetTicks();
|
||||
dTime = dTemp - dNormalLast;
|
||||
|
||||
|
||||
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
|
||||
|
||||
if (nCount <= 0)
|
||||
{
|
||||
SDL_Delay(2);
|
||||
} // No need to do anything for a bit
|
||||
else
|
||||
{
|
||||
|
||||
dNormalLast += nCount * (1 / 0.07547);
|
||||
|
||||
if (nCount > 10)
|
||||
{
|
||||
nCount = 10;
|
||||
}
|
||||
|
||||
read_keys();
|
||||
|
||||
if (ws_key_esc)
|
||||
{
|
||||
console.close();
|
||||
|
||||
app_terminate = 1;
|
||||
|
||||
if ((ws_rom_path != NULL) || (app_terminate))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
console.open(app_window_title, 224 * 2, 144 * 2, format);
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (i = 0 ; i < nCount - 1 ; i++)
|
||||
{
|
||||
while (!ws_executeLine(backbuffer, 0))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
while (!ws_executeLine(backbuffer, 1))
|
||||
{
|
||||
}
|
||||
|
||||
int16_t *vs = (int16_t *)surface->lock();
|
||||
int16_t *backbuffer_alias = backbuffer;
|
||||
|
||||
for (int line = 0 ; line < 144 ; line++)
|
||||
{
|
||||
ws_drawDoubledScanline(vs, backbuffer_alias);
|
||||
vs += surfacePitch;
|
||||
ws_drawDoubledScanline(vs, backbuffer_alias);
|
||||
vs += surfacePitch;
|
||||
backbuffer_alias += 224;
|
||||
}
|
||||
|
||||
surface->unlock();
|
||||
surface->copy(console);
|
||||
console.update();
|
||||
}
|
||||
}
|
||||
|
||||
console.close();
|
||||
delete surface;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ extern char app_window_title[256];
|
||||
extern int app_gameRunning;
|
||||
extern int app_terminate;
|
||||
extern int app_fullscreen;
|
||||
extern SDL_Event app_input_event;
|
||||
extern int app_rotated;
|
||||
|
||||
|
||||
|
||||
@@ -29,13 +29,10 @@
|
||||
#include "audio.h"
|
||||
#include "memory.h"
|
||||
|
||||
//#define IO_DUMP
|
||||
|
||||
extern uint8_t *externalEeprom;
|
||||
extern uint32_t romAddressMask;
|
||||
extern uint16_t *internalEeprom;
|
||||
extern nec_Regs I;
|
||||
extern uint64_t nec_monotonicCycles;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -89,8 +86,6 @@ uint8_t ws_key_flipped;
|
||||
|
||||
int rtcDataRegisterReadCount=0;
|
||||
|
||||
FILE *ioLogFp = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -144,10 +139,6 @@ void ws_io_init(void)
|
||||
|
||||
ws_io_reset();
|
||||
ws_key_flipped=0;
|
||||
|
||||
#ifdef IO_DUMP
|
||||
ioLogFp = fopen("iodump.csv", "wt");
|
||||
#endif
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -181,10 +172,6 @@ void ws_io_done(void)
|
||||
{
|
||||
free(ws_ioRam);
|
||||
}
|
||||
|
||||
#ifdef IO_DUMP
|
||||
fclose(ioLogFp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Serial port */
|
||||
@@ -342,7 +329,6 @@ uint8_t cpu_readport(uint8_t port)
|
||||
int w1,w2;
|
||||
uint8_t retVal = 0;
|
||||
|
||||
/*
|
||||
if (port > 0x100)
|
||||
{
|
||||
port &= 0xFF;
|
||||
@@ -351,7 +337,7 @@ uint8_t cpu_readport(uint8_t port)
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
switch (port)
|
||||
{
|
||||
@@ -595,10 +581,6 @@ uint8_t cpu_readport(uint8_t port)
|
||||
|
||||
|
||||
exit:
|
||||
if (ioLogFp)
|
||||
{
|
||||
fprintf(ioLogFp, "%ld, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -617,11 +599,6 @@ void cpu_writeport(uint32_t port,uint8_t value)
|
||||
int unknown_io_port=0;
|
||||
|
||||
|
||||
if (ioLogFp)
|
||||
{
|
||||
fprintf(ioLogFp, "%ld, W, %02X, %02X\n", nec_monotonicCycles, port, value);
|
||||
}
|
||||
|
||||
if (port > 0x100)
|
||||
{
|
||||
port &= 0xFF;
|
||||
@@ -1069,7 +1046,6 @@ void cpu_writeport(uint32_t port,uint8_t value)
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xca:
|
||||
if(value==0x15)
|
||||
|
||||
@@ -252,7 +252,7 @@ char *load_file(char *filename)
|
||||
|
||||
fstat(fd, &FileStat);
|
||||
|
||||
printf("Trying to load %s, size = %lu...\n",filename, (unsigned long)FileStat.st_size);
|
||||
printf("Trying to load %s, size = %lu...\n",filename, FileStat.st_size);
|
||||
|
||||
ret_ptr = (char *)mmap(NULL, FileStat.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
@@ -284,7 +284,7 @@ char *create_file(char *filename, uint32_t size)
|
||||
char buf[] = { 0 };
|
||||
|
||||
printf("Trying to create %s, size = %u...\n",filename, size);
|
||||
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC, 0644);
|
||||
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC);
|
||||
fchmod(fd, 0644);
|
||||
close(fd);
|
||||
sync();
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
set(SOURCES nec.cpp)
|
||||
set(HEADERS nec.h necea.h necinstr.h necintrf.h necmodrm.h)
|
||||
|
||||
add_library(nec_v30 ${SOURCES} ${HEADERS})
|
||||
@@ -38,7 +38,6 @@
|
||||
/* cpu state */
|
||||
/***************************************************************************/
|
||||
|
||||
uint64_t nec_monotonicCycles;
|
||||
int nec_ICount;
|
||||
|
||||
nec_Regs I;
|
||||
@@ -66,7 +65,6 @@ void nec_reset (void *param)
|
||||
unsigned int i,j,c;
|
||||
BREGS reg_name[8]= { AL, CL, DL, BL, AH, CH, DH, BH };
|
||||
|
||||
nec_monotonicCycles = 0;
|
||||
|
||||
memset( &I, 0, sizeof(I) );
|
||||
|
||||
@@ -3891,7 +3889,7 @@ void nec_set_reg(int regnum, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
const char *instructionsName[256] =
|
||||
char *instructionsName[256] =
|
||||
{
|
||||
"ADD ", "ADD ", "ADD ", "ADD ", "ADD ", "ADD ", "PUSH", "POP ", "OR ", "OR ", "OR ", "OR ", "OR ", "OR ", "PUSH", "----",
|
||||
"ADC ", "ADC ", "ADC ", "ADC ", "ADC ", "ADC ", "PUSH", "POP ", "SBB ", "SBB ", "SBB ", "SBB ", "SBB ", "SBB ", "PUSH", "POP ",
|
||||
@@ -3914,7 +3912,7 @@ const char *instructionsName[256] =
|
||||
|
||||
int nec_execute(int cycles)
|
||||
{
|
||||
int done;
|
||||
|
||||
|
||||
nec_ICount=cycles;
|
||||
// cpu_type=V30;
|
||||
@@ -3922,28 +3920,14 @@ int nec_execute(int cycles)
|
||||
while(nec_ICount>0)
|
||||
{
|
||||
#if 0
|
||||
|
||||
#define MK_LP(_seg, _off) (((_seg) << 4) + (_off))
|
||||
|
||||
if ( MK_LP(I.sregs[CS], I.ip) == 0x5E820 )
|
||||
{
|
||||
uint8_t op = cpu_readmem20((I.sregs[CS]<<4) + I.ip);
|
||||
|
||||
printf("AX = %04Xh - [%04X:%04Xh] = %04Xh\n", I.regs.w[AW], I.sregs[DS], 0x127f, cpu_readmem20(MK_LP(I.sregs[DS], 0x127f)));
|
||||
|
||||
printf("CS: %04Xh - DS: %04Xh - ES: %04Xh - SS: %04Xh\n", I.sregs[CS], I.sregs[DS], I.sregs[ES], I.sregs[SS]);
|
||||
printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip,
|
||||
op, instructionsName[op], I.IF);
|
||||
}
|
||||
uint8_t op = cpu_readmem20((I.sregs[CS]<<4) + I.ip);
|
||||
printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip,
|
||||
op, instructionsName[op], I.IF);
|
||||
#endif
|
||||
nec_instruction[FETCHOP]();
|
||||
// nec_ICount++;
|
||||
}
|
||||
|
||||
done = cycles - nec_ICount;
|
||||
|
||||
nec_monotonicCycles += done;
|
||||
|
||||
return done;
|
||||
return cycles - nec_ICount;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,37 @@
|
||||
|
||||
#include "necintrf.h"
|
||||
|
||||
typedef enum { ES, CS, SS, DS } SREGS;
|
||||
typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
|
||||
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,IXL,IXH,IYL,IYH } BREGS;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef union
|
||||
{
|
||||
/* eight general registers */
|
||||
uint16_t w[8]; /* viewed as 16 bits registers */
|
||||
uint8_t b[16]; /* or as 8 bit registers */
|
||||
} necbasicregs;
|
||||
typedef struct
|
||||
{
|
||||
necbasicregs regs;
|
||||
uint16_t sregs[4];
|
||||
|
||||
uint16_t ip;
|
||||
|
||||
int32_t SignVal;
|
||||
int32_t AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
|
||||
|
||||
uint32_t TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
|
||||
|
||||
uint32_t int_vector;
|
||||
uint32_t pending_irq;
|
||||
uint32_t nmi_state;
|
||||
uint32_t irq_state;
|
||||
int (*irq_callback)(int irqline);
|
||||
} nec_Regs;
|
||||
#pragma pack()
|
||||
|
||||
#define NEC_NMI_INT_VECTOR 2
|
||||
|
||||
/* Cpu types, steps of 8 to help the cycle count calculation */
|
||||
|
||||
@@ -2,36 +2,7 @@
|
||||
#ifndef __NECITRF_H_
|
||||
#define __NECITRF_H_
|
||||
|
||||
typedef enum { ES, CS, SS, DS } SREGS;
|
||||
typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
|
||||
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,IXL,IXH,IYL,IYH } BREGS;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef union
|
||||
{
|
||||
/* eight general registers */
|
||||
uint16_t w[8]; /* viewed as 16 bits registers */
|
||||
uint8_t b[16]; /* or as 8 bit registers */
|
||||
} necbasicregs;
|
||||
typedef struct
|
||||
{
|
||||
necbasicregs regs;
|
||||
uint16_t sregs[4];
|
||||
|
||||
uint16_t ip;
|
||||
|
||||
int32_t SignVal;
|
||||
int32_t AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
|
||||
|
||||
uint32_t TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
|
||||
|
||||
uint32_t int_vector;
|
||||
uint32_t pending_irq;
|
||||
uint32_t nmi_state;
|
||||
uint32_t irq_state;
|
||||
int (*irq_callback)(int irqline);
|
||||
} nec_Regs;
|
||||
#pragma pack()
|
||||
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
/* v30 debugger */
|
||||
|
||||
@@ -191,7 +191,6 @@ int ws_executeLine(int16_t *framebuffer, int renderLine)
|
||||
// update scanline register
|
||||
ws_ioRam[2]=ws_gpu_scanline;
|
||||
|
||||
/* Why twice like that and random cycle count???? */
|
||||
ws_cycles=nec_execute((ws_cyclesByLine>>1)+(rand()&7));
|
||||
ws_cycles+=nec_execute((ws_cyclesByLine>>1)+(rand()&7));
|
||||
|
||||
@@ -460,7 +459,7 @@ int ws_saveState(char *statepath)
|
||||
}
|
||||
}
|
||||
|
||||
int fp=open(newPath, O_RDWR|O_CREAT, 0644);
|
||||
int fp=open(newPath, O_RDWR|O_CREAT);
|
||||
delete newPath;
|
||||
|
||||
if (fp==-1)
|
||||
|
||||
Reference in New Issue
Block a user