34 Commits

Author SHA1 Message Date
Godzil
61937a1391 Merge branch 'master' into debugger 2021-04-04 22:13:59 +01:00
Godzil
e28317d29e Disable the IO Dump by default. 2021-04-04 21:17:34 +01:00
Godzil
f32928b0c3 Remove -Werror by default and add a cmake option to enable them. 2021-04-04 21:14:53 +01:00
Godzil
e4cf98bfe1 Add a debug function to log all access to IO regs. 2021-04-04 21:05:48 +01:00
Godzil
a89e253d9c Now use glfw/OpenGL for displaying.
Code is a bit crude, but the whole emulator would need a proper refactor at some point anyway.
2021-04-04 20:55:40 +01:00
Godzil
88468d6028 Now build without SDL
But of course, display nothing.
2020-12-12 19:28:21 +00:00
Godzil
875f0edb46 printf can be a pain at time. 2020-11-14 20:30:09 +00:00
Godzil
8bd2170f44 Remove some of the Rotation code.
And add a call placeholder for read_key for now to make the compiler happy.
2020-11-14 20:28:31 +00:00
Godzil
564e0ea2e6 Remove more SDL references 2020-11-14 20:27:58 +00:00
Godzil
8976d4363f Remove SDLptc.h, the "Console" class and related code. 2020-11-14 20:27:25 +00:00
Godzil
f3aca9a3c7 Start working on implementing the video interface.
First disabling/removing all the SDL related function call/variables

Also removing some nonsensical dunction (line doubling and rotation are useless in GL mode)
2020-11-14 20:16:46 +00:00
Godzil
ece8a07dcf Remove SDL refenrence in the non working audio emulation. 2020-11-14 20:15:50 +00:00
Godzil
9035a922c3 Add GLFW in the CMakeLists, and remove all SDL references. 2020-11-14 20:14:57 +00:00
Godzil
02c16b7987 Add glfw as an external module 2020-11-14 19:36:54 +00:00
Godzil
8c79f6f417 Clang should be happy now? 2020-02-11 00:53:32 +00:00
Godzil
2802e64697 clang don't like these unused tables. 2020-02-11 00:42:33 +00:00
Godzil
e8d7d8473e GCC quirkness makes no sense sometimes. 2020-02-11 00:38:17 +00:00
Godzil
ed93d90c51 Make sure we are not forcing to GCC and add a bit of debug.
CMake find the proper lib but not the makefile? WTF
2020-02-11 00:29:34 +00:00
Godzil
6e857bf630 Stupid names ubuntu; "libsdl1.2debian", seriously? 2020-02-11 00:24:04 +00:00
Godzil
62c43f311c Trying to add SDL lib package (seems -dev don't install it) 2020-02-11 00:21:17 +00:00
Godzil
3552bb8bf9 Silly me... 2020-02-11 00:20:36 +00:00
Godzil
466f910c9a Try to also build cmake build. 2020-02-11 00:18:06 +00:00
Godzil
a5ce89d14f Hmmm it was lurking in other places! 2020-02-11 00:17:38 +00:00
Godzil
c26f935072 Interesting that not all GCC versions complain here. 2020-02-11 00:14:36 +00:00
Godzil
4967dcab21 I honestly don't care about the return value of write. 2020-02-11 00:07:16 +00:00
Godzil
a0e5006a18 Add dumpinfo to cmake, and set the CXX standard to C++98 as it should on that project. 2020-02-11 00:05:22 +00:00
Godzil
6d78199031 Update .gitignore 2020-02-11 00:04:42 +00:00
Godzil
6d5658eb68 Make gcc happy (and fix a potential issue) 2020-02-11 00:00:23 +00:00
Godzil
667f655d22 Add preliminary CMake build. Not replacing the makefile for now, will in the future. 2020-02-10 23:59:01 +00:00
Godzil
3e6f096191 Add CMake module to get Git version. 2020-02-10 23:58:18 +00:00
Godzil
0fadff165b Update travis to use latest ubuntu instead of the old 14.04 2020-02-07 18:00:54 +00:00
Godzil
cf80c9624c Add tentative travis build script 2020-02-07 17:58:12 +00:00
Godzil
b5488bacba Add portaudio for futur audio work. 2020-02-07 17:57:59 +00:00
Godzil
778c624664 Early changes to add a x86 debugger. 2020-02-07 17:39:46 +00:00
23 changed files with 680 additions and 779 deletions

4
.gitignore vendored
View File

@@ -21,3 +21,7 @@ rom/
dumpinfo
testserial
wonderswan
# Build folder
cmake-*/
build*/

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[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

38
.travis.yml Normal file
View File

@@ -0,0 +1,38 @@
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)

43
CMakeLists.txt Normal file
View File

@@ -0,0 +1,43 @@
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)

View File

@@ -16,12 +16,13 @@ OBJS = $(wonderswan_CXX_SRCS:.cpp=.o)
all: wonderswan dumpinfo
CXX = g++
CXXFLAGS = -g -O2 `sdl-config --cflags` -Wall -Werror -std=c++98 -Wno-write-strings
# CXX = g++
CXXFLAGS = -g -O2 `sdl-config --cflags` -Wall -std=c++98 -Wno-write-strings -Wno-unused-result
OPTIONS = -D_REENTRANT -I. -DVERSION=\"`git describe --tags --long --dirty`\"
LIBRARY_PATH =
LIBS = -g $(LIBRARY_PATH) `sdl-config --libs`
SDL_LIBS = `sdl-config --libs`
LIBS = -g $(LIBRARY_PATH) $(SDL_LIBS)
ALLCFLAGS = $(CFLAGS) $(CEXTRA) $(OPTIONS) $(ALLFLAGS)
ALLCXXFLAGS=$(CXXFLAGS) $(CXXEXTRA) $(OPTIONS) $(ALLFLAGS)
@@ -53,4 +54,4 @@ dumpinfo: dumpinfo.o
$(CXX) $(LIBS) -o $@ $(<)
wonderswan: $(OBJS)
$(CXX) $(LIBS) -o $@ $(OBJS)
$(CXX) -o $@ $(OBJS) $(LIBS)

View File

@@ -0,0 +1,168 @@
# - 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()

View File

@@ -0,0 +1,41 @@
#
# 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 Submodule

Submodule external/glfw added at 0ef149c8f2

1
external/portaudio vendored Submodule

Submodule external/portaudio added at c5d2c51bd6

View File

@@ -15,8 +15,6 @@
#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"
@@ -123,9 +121,6 @@ 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);

10
source/CMakeLists.txt Normal file
View File

@@ -0,0 +1,10 @@
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)

View File

@@ -1,314 +0,0 @@
/* 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:
};

View File

@@ -29,8 +29,6 @@
#include "io.h"
#include "audio.h"
#include "SDL.h"
#define SNDP ws_ioRam[0x80]
#define SNDV ws_ioRam[0x88]
#define SNDSWP ws_ioRam[0x8C]
@@ -91,6 +89,7 @@ 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,
@@ -101,6 +100,7 @@ const long TblMainVol[4]= // 1,1/2,1/4,1/8
{
0,-602,-1204,-1806
};
*/
////////////////////////////////////////////////////////////////////////////////
// seal audio specific
@@ -142,7 +142,6 @@ void ws_audio_init(void)
ws_audio_log=0;
//ws_audio_seal_init();
ws_audio_reset();
SDL_PauseAudio(0);
}
////////////////////////////////////////////////////////////////////////////////
//

View File

@@ -19,9 +19,16 @@
#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"
@@ -32,336 +39,308 @@
#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()
{
static int testJoystick=1;
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;
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])
if (getKeyState(GLFW_KEY_E))
{
dump_memory();
}
if ( keystate[SDLK_r])
if (getKeyState(GLFW_KEY_R))
{
printf("Boop\n");
ws_reset();
}
if ( keystate[SDLK_ESCAPE] )
if (getKeyState(GLFW_KEY_ESCAPE))
{
ws_key_esc = 1;
}
if ( keystate[SDLK_UP] )
if ( getKeyState(GLFW_KEY_UP))
{
ws_key_x1=1;
}
if ( keystate[SDLK_DOWN] )
if ( getKeyState(GLFW_KEY_DOWN))
{
ws_key_x3=1;
}
if ( keystate[SDLK_RIGHT] )
if (getKeyState(GLFW_KEY_RIGHT))
{
ws_key_x2=1;
}
if ( keystate[SDLK_LEFT] )
if (getKeyState(GLFW_KEY_LEFT))
{
ws_key_x4=1;
}
if (keystate[SDLK_RETURN])
if (getKeyState(GLFW_KEY_ENTER))
{
ws_key_start=1;
}
if (keystate[SDLK_c])
if (getKeyState(GLFW_KEY_C))
{
ws_key_button_a=1;
}
if (keystate[SDLK_x])
if (getKeyState(GLFW_KEY_X))
{
ws_key_button_b=1;
}
if (keystate[SDLK_w])
if (getKeyState(GLFW_KEY_W))
{
ws_key_y1=1;
}
if (keystate[SDLK_a])
if (getKeyState(GLFW_KEY_A))
{
ws_key_y4=1;
}
if (keystate[SDLK_s])
if (getKeyState(GLFW_KEY_S))
{
ws_key_y3=1;
}
if (keystate[SDLK_d])
if (getKeyState(GLFW_KEY_D))
{
ws_key_y2=1;
}
if (keystate[SDLK_o])
if (getKeyState(GLFW_KEY_O))
{
ws_cyclesByLine+=10;
}
if (keystate[SDLK_l])
if (getKeyState(GLFW_KEY_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)];
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
@@ -379,182 +358,67 @@ 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);
Console console;
Surface *surface;
// 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;
if (app_rotated)
dNormalLast = (double)getTicks();
while (1)
{
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);
dNormalLast = (double)SDL_GetTicks();
dTemp = getTicks();
dTime = dTemp - dNormalLast;
console.open(app_window_title, 144 * 2, 224 * 2, format);
while (1)
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
{
dTemp = (double)SDL_GetTicks();
dTime = dTemp - dNormalLast;
dNormalLast += nCount * (1 / 0.07547);
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
if (nCount > 10)
{
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, 144 * 2, 224 * 2, format);
}
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backbuffer, 0))
{
}
}
while (!ws_executeLine(backbuffer, 1))
{
}
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();
nCount = 10;
}
}
console.close();
delete surface;
read_keys();
}
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)
if (ws_key_esc)
{
SDL_Delay(2);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / 0.07547);
app_terminate = 1;
if (nCount > 10)
if ((ws_rom_path != NULL) || (app_terminate))
{
nCount = 10;
break;
}
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;
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backBuffer, 0))
{
}
}
while (!ws_executeLine(backBuffer, 1))
{
}
updateScreen(&mainWindow);
}
}
}

View File

@@ -21,7 +21,6 @@ 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;

View File

@@ -29,10 +29,13 @@
#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
{
@@ -86,6 +89,8 @@ uint8_t ws_key_flipped;
int rtcDataRegisterReadCount=0;
FILE *ioLogFp = NULL;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
@@ -139,6 +144,10 @@ void ws_io_init(void)
ws_io_reset();
ws_key_flipped=0;
#ifdef IO_DUMP
ioLogFp = fopen("iodump.csv", "wt");
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
@@ -172,6 +181,10 @@ void ws_io_done(void)
{
free(ws_ioRam);
}
#ifdef IO_DUMP
fclose(ioLogFp);
#endif
}
/* Serial port */
@@ -329,6 +342,7 @@ uint8_t cpu_readport(uint8_t port)
int w1,w2;
uint8_t retVal = 0;
/*
if (port > 0x100)
{
port &= 0xFF;
@@ -337,7 +351,7 @@ uint8_t cpu_readport(uint8_t port)
return 0x00;
}
}
*/
switch (port)
{
@@ -581,6 +595,10 @@ uint8_t cpu_readport(uint8_t port)
exit:
if (ioLogFp)
{
fprintf(ioLogFp, "%ld, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
}
return retVal;
}
////////////////////////////////////////////////////////////////////////////////
@@ -599,6 +617,11 @@ 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;
@@ -1046,6 +1069,7 @@ void cpu_writeport(uint32_t port,uint8_t value)
}
fflush(stdout);
}
break;
case 0xca:
if(value==0x15)

View File

@@ -252,7 +252,7 @@ char *load_file(char *filename)
fstat(fd, &FileStat);
printf("Trying to load %s, size = %lu...\n",filename, FileStat.st_size);
printf("Trying to load %s, size = %lu...\n",filename, (unsigned long)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);
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC, 0644);
fchmod(fd, 0644);
close(fd);
sync();

View File

@@ -0,0 +1,4 @@
set(SOURCES nec.cpp)
set(HEADERS nec.h necea.h necinstr.h necintrf.h necmodrm.h)
add_library(nec_v30 ${SOURCES} ${HEADERS})

View File

@@ -38,6 +38,7 @@
/* cpu state */
/***************************************************************************/
uint64_t nec_monotonicCycles;
int nec_ICount;
nec_Regs I;
@@ -65,6 +66,7 @@ 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) );
@@ -3889,7 +3891,7 @@ void nec_set_reg(int regnum, uint32_t val)
}
}
char *instructionsName[256] =
const 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 ",
@@ -3912,7 +3914,7 @@ char *instructionsName[256] =
int nec_execute(int cycles)
{
int done;
nec_ICount=cycles;
// cpu_type=V30;
@@ -3920,14 +3922,28 @@ int nec_execute(int cycles)
while(nec_ICount>0)
{
#if 0
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);
#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);
}
#endif
nec_instruction[FETCHOP]();
// nec_ICount++;
}
return cycles - nec_ICount;
done = cycles - nec_ICount;
nec_monotonicCycles += done;
return done;
}

View File

@@ -4,37 +4,6 @@
#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 */

View File

@@ -2,7 +2,36 @@
#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
{

2
source/nec/v30debug.cpp Normal file
View File

@@ -0,0 +1,2 @@
/* v30 debugger */

View File

@@ -191,6 +191,7 @@ 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));
@@ -459,7 +460,7 @@ int ws_saveState(char *statepath)
}
}
int fp=open(newPath, O_RDWR|O_CREAT);
int fp=open(newPath, O_RDWR|O_CREAT, 0644);
delete newPath;
if (fp==-1)