Compare commits

..

No commits in common. "master" and "switch_to_glfw" have entirely different histories.

58 changed files with 11909 additions and 13738 deletions

View File

@ -1,38 +0,0 @@
name: CMake
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
BUILD_TYPE: Release
jobs:
build:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.allow_failure }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-18.04, ubuntu-20.04, ubuntu-latest ]
allow_failure: [ false ]
# include:
# - os: macos-latest
# allow_failure: true
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Install needed dependencies
run: sudo apt update && sudo apt install xorg-dev libglu1-mesa-dev
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

View File

@ -1,62 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '43 19 * * 5'
env:
BUILD_TYPE: Debug
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: true
- name: Install needed dependencies
run: sudo apt update && sudo apt install xorg-dev libglu1-mesa-dev
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
- name: Running Cmake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Building
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

3
.gitignore vendored
View File

@ -8,7 +8,6 @@
*.orig
*.rej
rom/
ROMs/
.idea/
*.zip
*.sav
@ -25,4 +24,4 @@ wonderswan
# Build folder
cmake-*/
build*/
build*/

View File

@ -1,63 +1,38 @@
dist: bionic
language: c
os:
- linux
# - osx
#matrix:
# allow_failures:
# - os: osx
addons:
apt:
packages:
- xorg-dev
- libglu1-mesa-dev
- libsdl1.2debian
- libsdl1.2-dev
compiler:
- clang
- gcc
script:
- make
- mkdir build
- cd build
- cmake ..
- make
jobs:
include:
- os: linux
dist: bionic
arch: amd64
compiler: gcc
cache:
directories:
- '$HOME/.sonar/cache'
- os: linux
dist: bionic
arch: amd64
compiler: clang
#before_install:
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glew; fi
- os: linux
dist: focal
arch: amd64
compiler: gcc
#install: true
- os: linux
dist: focal
arch: amd64
compiler: clang
- os: osx
compiler: clang
osx_image: xcode12.2
- os: linux
dist: focal
arch: arm64
compiler: gcc
- os: osx
compiler: clang
osx_image: xcode10.3
- os: osx
compiler: clang
osx_image: xcode11.6
- os: osx
compiler: clang
osx_image: xcode12
allow_failures:
- os: linux
arch: arm64
- os: osx
#after_success:
# - bash <(curl -s https://codecov.io/bash)

View File

@ -17,35 +17,20 @@ 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})
set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-write-strings -Werror")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-write-strings -Werror")
message("-- Building version ${VERSION}")
add_executable(wonderswan main.c)
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_custom_command(
TARGET wonderswan POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/irom_stub/*.bin
${CMAKE_CURRENT_BINARY_DIR}/
)
add_subdirectory(source)
target_link_libraries(wonderswan wswan glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
add_executable(dumpinfo dumpinfo.c)
add_executable(testserial testserial.c)
add_executable(dumpinfo dumpinfo.c)

57
Makefile Normal file
View File

@ -0,0 +1,57 @@
wonderswan_CXX_SRCS = main.cpp \
source/audio.cpp \
source/gpu.cpp \
source/io.cpp \
source/log.cpp \
source/memory.cpp \
source/emulate.cpp \
source/rom.cpp \
source/ws.cpp \
source/nec/nec.cpp
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
OPTIONS = -D_REENTRANT -I. -DVERSION=\"`git describe --tags --long --dirty`\"
LIBRARY_PATH =
SDL_LIBS = `sdl-config --libs`
LIBS = -g $(LIBRARY_PATH) $(SDL_LIBS)
ALLCFLAGS = $(CFLAGS) $(CEXTRA) $(OPTIONS) $(ALLFLAGS)
ALLCXXFLAGS=$(CXXFLAGS) $(CXXEXTRA) $(OPTIONS) $(ALLFLAGS)
CLEAN_FILES = wonderswan
.SUFFIXES: .cpp
main.o: main.cpp
.c.o:
$(CC) -c $(ALLCFLAGS) -o $@ $<
.cpp.o:
$(CXX) -c $(ALLCXXFLAGS) -o $@ $<
.PHONY: all install uninstall clean distclean depend dummy
$(SUBDIRS:%=%/__clean__): dummy
cd `dirname $@` && $(MAKE) clean
$(EXTRASUBDIRS:%=%/__clean__): dummy
-cd `dirname $@` && $(RM) $(CLEAN_FILES)
clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
$(RM) $(CLEAN_FILES) $(RC_SRCS:.rc=.res) $(OBJS) $(EXES:%.exe=%) $(EXES:%=%.so) $(EXES:%=%.spec.o) $(DLLS:%=%.so) $(DLLS:%=%.spec.o)
dumpinfo: dumpinfo.o
$(CXX) $(LIBS) -o $@ $(<)
wonderswan: $(OBJS)
$(CXX) -o $@ $(OBJS) $(LIBS)

View File

@ -1,76 +0,0 @@
NewOswan *(name likely to change)*
==================================
[![CMake](https://github.com/Godzil/NewOswan/actions/workflows/cmake.yml/badge.svg)](https://github.com/Godzil/NewOswan/actions/workflows/cmake.yml)
### What is this project?
NewOswan is a WonderSwan emulator originally based on oswan-unix and heavily modified to be more accurate and better
hardware support.
### I don't care about the blabla, just show me the thing running
Ok ok, here are some screenshots:
Using a Swan Crystal boot rom:
![Console configuration menu](./doc/configmenu.png)
Wonderswan Crystal boot splash:
![SwanCrystal boot splash](./doc/bootsplash.png)
Clock Tower:
![Boot screen of ClockTower](./doc/clocktower.png)
Star Hearts:
![Boot screen of Star Hearts](./doc/starhearts1.png)
![Ingame screen of Star Hearts](./doc/starhearts2.png)
### What's different from oswan-unix?
A couple of things:
- NewOswan do properly support the internal EEPROM and cartridge EEPROM.
The original version was based in improper and innacurate hardware documentation and was accessing and storing the
information in an incorrect way.
- NewOswan support the internal bootrom of all the three model of the WonderSwan.
- NewOswan also provide stub version for the bootrom if you don't own the original console, you can still
use the emulator withtout copyright infreigement. (no copyrighted materiel is included with the emulator for obvious
reasons)
- NewOswan use OpenGL instead of SDL
- Sound is currently not supported
- NewOswan is currently not meant as a fully operational emulator as this project mostly started as a way to test game
and the original hardware. Still the idea is to make it overtime as accurate as possible
- It is now pure C (the original code was based on a C project with some unneeded C++ here and there)
- 64-Bit clean, the original code was making assumption on some type size that can break on a 64bit system
- Build and run on Mac OS X, Linux x86 and ARM, and probably more systems.
- Some crude debugging tools that can only be enabled at compile time
- Tons of fancy logs in the console! Like:
```
IEEP: RA:143F RD:0006 A:03F C:WRI - Write? Yes : 0006
IEEP: RA:1440 RD:0101 A:040 C:WRI - Write? Yes : 0101
IEEP: RA:1441 RD:0016 A:041 C:WRI - Write? Yes : 0016
IEEP: RA:1442 RD:0000 A:042 C:WRI - Write? Yes : 0000
WriteIO(6A, 00) [F000:0018h];
WriteIO(6B, 00) [F000:0018h];
Icons H
WriteIO(6A, 00) [F000:0018h];
WriteIO(6B, 00) [F000:0018h];
```
- And many more thing I probably forgot about as this project was originally not version managed as it was just a crude
hack on the original code and are not in the logs.
### Futur plans
- Complete refactor of the code.
- Add a proper CPU debugger
- Add other nice debugging tool like the GPU status and other things that could be needed. Acheiving the level of the tools
provided by the NES emulator [Mesen](https://www.mesen.ca) would be nice.
- Being able to rotate the screen
- Maybe being able to change the game at runtime instead of start time
- Full Audio support
### The boot rom stubs
You can find the source and file in the `irom_stub` folder.
They are identical and for now provide only the logic to boot a cart. There is no bootsplash nor configuration menu.
A bootsplash may be added later.
Feel free to use these stub for your own emulator if you wish, just be nice and put a line saying you are using it and
a link to this project in your documentation :)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 KiB

View File

@ -1,11 +1,3 @@
/*******************************************************************************
* NewOswan
* dumpinfo.c: Tool to dump the metadata info about a cart rom image.
*
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@ -25,7 +17,7 @@ char *load_file(char *filename, uint32_t *fileSize)
fstat(fd, &FileStat);
ret_ptr = (char *)mmap(NULL, FileStat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
ret_ptr = (char *)mmap(NULL, FileStat.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
*fileSize = FileStat.st_size;
@ -40,7 +32,7 @@ char *load_file(char *filename, uint32_t *fileSize)
}
#pragma pack(1)
struct cart_metadata
struct cart_metadata
{
uint8_t farjump[5];
uint8_t flagExt;
@ -72,26 +64,29 @@ int main(int argc, char *argv[])
if (content != NULL)
{
data = (struct cart_metadata *)&(content[size - sizeof(struct cart_metadata)]);
data = (struct cart_metadata*)&(content[size - sizeof(struct cart_metadata)]);
printf("%s:\n", argv[1]);
if (data->farjump[0] == 0xEA)
{
printf("[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", data->publishId, data->gameId[0],
data->gameId[1], data->flags2, data->romInfo, data->saveInfo, data->flags & 0xFF,
(data->flags >> 8) & 0xFF, data->crc & 0xFF, (data->crc >> 8) & 0xFF);
printf(" - Reset @ %02X%02X:%02X%02Xh\n", data->farjump[4], data->farjump[3], data->farjump[2],
data->farjump[1]);
printf("[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]",
data->publishId, data->gameId[0], data->gameId[1], data->flags2, data->romInfo, data->saveInfo,
data->flags & 0xFF, (data->flags>>8) & 0xFF, data->crc & 0xFF, (data->crc>>8) & 0xFF);
printf(" - Reset @ %02X%02X:%02X%02Xh\n",
data->farjump[4], data->farjump[3],
data->farjump[2], data->farjump[1]);
printf(" - publisher: %02X, gameId: %01X%02X\n", data->publishId, data->gameId[0], data->gameId[1]);
printf(" - %s want to write to EEPROM\n", data->flags2 & 0x80 ? "Do" : "Do not");
printf(" - %s user defined bootsplash\n", data->flagExt & 0x80 ? "Dissallow" : "Allow");
printf(" - Is %sbootable on a normal swan\n", data->flagExt & 0x0F ? "not " : "");
printf(" - %s want to write to EEPROM\n", data->flags2&0x80?"Do":"Do not");
printf(" - %s user defined bootsplash\n", data->flagExt&0x80?"Dissallow":"Allow");
printf(" - Is %sbootable on a normal swan\n", data->flagExt&0x0F?"not ":"");
printf(" - ROM Size: %02Xh\n", data->romInfo);
printf(" - Save type & Size: %02Xh\n", data->saveInfo);
printf(" - Flags: %d cycles ROM, %d bit ROM bus, %sRTC, %s orientation\n", data->flags & 0x004 ? 1 : 3,
data->flags & 0x002 ? 8 : 16, data->flags & 0x100 ? "" : "No ",
data->flags & 0x001 ? "Vertical" : "Horizontal");
printf(" - Flags: %d cycles ROM, %d bit ROM bus, %sRTC, %s orientation\n",
data->flags & 0x004?1:3,
data->flags & 0x002?8:16,
data->flags & 0x100?"":"No ",
data->flags & 0x001?"Vertical":"Horizontal");
printf(" - CRC: %04Xh\n", data->crc);
ret = 0;
}

View File

@ -1,20 +0,0 @@
.PHONY: all clean
all: ws_irom.bin wsc_irom.bin wc_irom.bin
clean:
@echo " RM"
@rm -f *.bin
ws_irom.bin: irom_stub.asm
@echo " AS $@"
@nasm $^ -o $@ -DWONDERSWAN=1
wsc_irom.bin: irom_stub.asm
@echo " AS $@"
@nasm $^ -o $@ -DWONDERSWANCOLOR=1
wc_irom.bin: irom_stub.asm
@echo " AS $@"
@nasm $^ -o $@ -DSWANCRYSTAL=1

View File

@ -1,110 +0,0 @@
; WonderSwan Internal ROM Stub
; --------------------------------------
; Version 1.0
; This is a replacement for the internal rom to prevent using/including any copyrighted material.
; It does nothing, just lauching the cartridge.
; It may later include a bootsplah.
%ifdef WONDERSWAN
%define ROM_SIZE 4096
%define ROM_SEG 0FF00h
%else
%define ROM_SIZE 8192
%define ROM_SEG 0FE00h
%endif
; Setup NASM for a 80186
bits 16
cpu 186
org 0000h
%define JUMPER_LOCATION 0000h:0400h
; ---------------------------------------------------------------------------------------------
; Boot ROM jumper
; ---------------------------------------------------------------------------------------------
; Lock the bootrom
; Clear a bit of itself
; Jump to FFFF:FFF0
;
; Must be copied to 0000:0400 then jmp 0000:0400
ram_jumper:
; Lock the boot rom away
IN al, 0A0h
OR al, 001h ; Bit 0 lock the boot rom
out 0A0h, al
mov ax, cs
mov es, ax
mov di, 0400h
mov cx, (.rm_te_end - ram_jumper)
xor ax, ax
xor bx, bx
.rm_te_end:
rep stosb
jmp 0FFFFh:00000h
ram_jumper_end:
_start:
cli
cld
push cs
pop ds
in al, 0A0h
; Bit 2 - 1 = cart using 16bit data bus
or al, 004h
out 0A0h, al
xor ax, ax
mov es, ax
; Clear the IRAM
mov di, 0
mov cx, 16384
xor al, al
rep stosb ; STOSB -> ES:DI
; Copy the jumper
mov si, ram_jumper
mov cx, (ram_jumper_end - ram_jumper)
mov di, 0400h
xor ax, ax
mov es, ax
rep movsb ; DS:SI -> ES:DI
; Do some register cleanup
mov al, 0FFh
out 0C0h, al
out 0C1h, al
out 0C2h, al
xor ax, ax
xor cx, cx
xor dx, dx
mov ds, ax
mov es, ax
; Jump to the jumper!
jmp JUMPER_LOCATION
%ifdef WONDERSWAN
db "WonderSwan"
%elifdef WONDERSWANCOLOR
db "WonderSwan Color"
%elifdef SWANCRYSTAL
db "WonderSwan Crystal"
%else
%endif
db " internal ROM Stub for NewOswan (c)2021 986-Studio"
; Create at the end of the block, add padding if needed
TIMES (ROM_SIZE - 16) - ($-$$) DB 0FFh
jmp ROM_SEG:_start ; 0
db 00 ; ?? ; 5
db 0F0h ; Dev ID ; 6
db 00 ; Min Swan type ; 7
db 00000100b ; flags ; C
db 01 ; No RTC ; D
dw 0FFFFh ; CRC (need to update it after, but as not used by the rom, no need for now)

Binary file not shown.

Binary file not shown.

Binary file not shown.

195
main.c
View File

@ -1,195 +0,0 @@
/******************************************************************************
* NewOswan
* main.c: Entry point
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
// 13.04.2002: Fixed a small bug causing crashes
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "source/log.h"
#include "source/rom.h"
#include "source/nec/nec.h"
#include "source/memory.h"
#include "source/gpu.h"
#include "source/io.h"
#include "source/ws.h"
#include "source/emulate.h"
#include "source/audio.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define LOG_PATH "oswan.log"
int sram_path_explicit = 0;
int ieep_path_explicit = 0;
int ws_mk_savpath()
{
char *w;
if (sram_path_explicit)
{
return 0;
}
if (ws_sram_path != NULL)
{
free(ws_sram_path);
}
ws_sram_path = (char *)malloc(strlen(ws_rom_path) + 2);
strcpy(ws_sram_path, ws_rom_path);
w = strrchr(ws_sram_path, '.');
if (NULL == w)
{
strcpy(ws_sram_path, "error.sav");
return 1;
}
strcpy(w, ".sav");
return 0;
}
int ws_mk_ieppath()
{
char *w;
if (ieep_path_explicit)
{
return 0;
}
if (ws_ieep_path != NULL)
{
free(ws_ieep_path);
}
ws_ieep_path = (char *)malloc(strlen(ws_rom_path) + 2);
strcpy(ws_ieep_path, ws_rom_path);
w = strrchr(ws_ieep_path, '.');
if (NULL == w)
{
strcpy(ws_ieep_path, "error.iep");
return 1;
}
strcpy(w, ".iep");
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
wssystem_t ws_system = WS_SYSTEM_AUTODETECT;
snprintf(app_window_title, 255, "Oswan %s - Esc to return to GUI", VERSION);
Log(TLOG_ALWAYS, NULL, "NewOswan %s (built at: %s %s)", VERSION, __DATE__, __TIME__);
ws_rom_path = NULL;
for (int n = 1 ; n < argc ; ++n)
{
if (argv[n][0] == '-')
{
switch (argv[n][1])
{
case 'C':
if (++n < argc)
{
ws_cyclesByLine = atoi(argv[n]);
}
Log(TLOG_ALWAYS, "main", "Cycles by line set to %d", ws_cyclesByLine);
break;
case 'w':
if (++n < argc)
{
ws_system = atoi(argv[n]);
}
Log(TLOG_ALWAYS, "main", "WonderSwan set to %d", ws_system);
break;
case 's':
if (++n < argc)
{
ws_sram_path = argv[n];
}
sram_path_explicit = 1;
break;
default:break;
}
}
else
{
ws_rom_path = argv[n];
ws_mk_savpath();
ws_mk_ieppath();
}
}
while (!app_terminate)
{
if (!ws_rom_path)
{
exit(0);
}
if (ws_rom_path)
{
ws_set_system(ws_system);
if (ws_init(ws_rom_path))
{
ws_reset();
ws_emulate();
}
ws_done();
}
}
return (0);
}

216
main.cpp Normal file
View File

@ -0,0 +1,216 @@
///////////////////////////////////////////////////////////////////////////////
// Wonderswan emulator
////////////////////////////////////////////////////////////////////////////////
//
// 13.04.2002: Fixed a small bug causing crashes
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "source/log.h"
#include "source/rom.h"
#include "source/nec/nec.h"
#include "source/memory.h"
#include "source/gpu.h"
#include "source/io.h"
#include "source/ws.h"
#include "source/emulate.h"
#include "source/audio.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define LOG_PATH "oswan.log"
int gui_command=GUI_COMMAND_NONE;
int gui_mainDialogRunning;
int gui_controls_configuration_Running;
int gui_get_key_Running;
int gui_get_key_key;
int ws_videoEnhancementType=0;
int ws_colourScheme=COLOUR_SCHEME_DEFAULT;
int ws_system=WS_SYSTEM_COLOR;
int sram_path_explicit = 0;
int ieep_path_explicit = 0;
int ws_mk_savpath()
{
char *w;
if (sram_path_explicit)
{
return 0;
}
if (ws_sram_path != NULL)
{
free(ws_sram_path);
}
ws_sram_path = (char *)malloc(strlen(ws_rom_path) + 2);
strcpy(ws_sram_path, ws_rom_path);
w = strrchr(ws_sram_path, '.');
if (NULL == w)
{
strcpy(ws_sram_path, "error.sav");
return 1;
}
strcpy(w, ".sav");
return 0;
}
int ws_mk_ieppath()
{
char *w;
if (ieep_path_explicit)
{
return 0;
}
if (ws_ieep_path != NULL)
{
free(ws_ieep_path);
}
ws_ieep_path = (char *)malloc(strlen(ws_rom_path) + 2);
strcpy(ws_ieep_path, ws_rom_path);
w = strrchr(ws_ieep_path, '.');
if (NULL == w)
{
strcpy(ws_ieep_path, "error.iep");
return 1;
}
strcpy(w, ".iep");
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
if (!log_init(LOG_PATH))
{
printf("Warning: cannot open log file %s\n",LOG_PATH);
}
snprintf(app_window_title, 255, "Oswan %s - Esc to return to GUI", VERSION);
fprintf(log_get(),"Oswan-unix %s (built at: %s %s)\n",VERSION , __DATE__,__TIME__);
ws_system = WS_SYSTEM_COLOR;
ws_rom_path = NULL;
for (int n = 1; n < argc; ++n)
{
if (argv[n][0] == '-')
{
switch(argv[n][1])
{
case 'C':
if (++n < argc)
{
ws_cyclesByLine = atoi(argv[n]);
}
fprintf(log_get(), "Cycles by line set to %d\n", ws_cyclesByLine);
break;
case 'w':
if (++n < argc)
{
ws_system = atoi(argv[n]);
}
fprintf(log_get(), "WonderSwan set to %d\n", ws_system);
break;
case 's':
if (++n < argc)
{
ws_sram_path = argv[n];
}
sram_path_explicit = 1;
break;
default:
break;
}
}
else
{
ws_rom_path = argv[n];
ws_mk_savpath();
ws_mk_ieppath();
}
}
while (!app_terminate)
{
if (!ws_rom_path)
{
app_gameRunning=0;
exit(0);
}
if (ws_rom_path)
{
ws_set_system(ws_system);
if (ws_init(ws_rom_path))
{
app_rotated=ws_rotated();
app_gameRunning=1;
if (ws_system == WS_SYSTEM_COLOR)
{
ws_gpu_operatingInColor=1;
}
ws_set_colour_scheme(ws_colourScheme);
ws_reset();
ws_emulate();
}
ws_done();
}
}
log_done();
return(0);
}

50
resource.h Normal file
View File

@ -0,0 +1,50 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by gui.rc
//
#define IDD_DIALOG_MAIN 101
#define IDB_BITMAP1 102
#define IDB_BITMAP2 103
#define IDC_BUTTON_LOAD 1000
#define IDC_BUTTON_RESET 1001
#define IDC_BUTTON_EXIT 1002
#define IDC_RADIO1 1003
#define IDC_RADIO_WINDOWED 1003
#define IDC_RADIO2 1004
#define IDC_RADIO_FULLSCREEN 1004
#define IDC_BUTTON_LOADSTATE 1005
#define IDC_BUTTON_SAVESTATE 1006
#define IDC_RADIO3 1007
#define IDC_BUTTON_CONTINUE 1007
#define IDC_RADIO4 1008
#define IDC_BUTTON_CONTROLS 1008
#define IDC_RADIO5 1009
#define IDC_RADIO_STANDARD_MODE 1009
#define IDC_RADIO6 1010
#define IDC_RADIO_DOUBLESIZE_MODE 1010
#define IDC_RADIO7 1011
#define IDC_RADIO_SCANLINES_MODE 1011
#define IDC_RADIO8 1012
#define IDC_RADIO_50PRCTSCANLINES_MODE 1012
#define IDC_RADIO9 1013
#define IDC_RADIO_SPECIAL_MODE 1013
#define IDC_RADIO_SYSTEM_AUTODETECT 1014
#define IDC_RADIO_SYSTEM_MONO 1015
#define IDC_RADIO_SYSTEM_COLOR 1016
#define IDC_RADIO_2XSAI 1017
#define IDC_RADIO_SUPER2XSAI 1018
#define IDC_COLOUR_DEFAULT 1019
#define IDC_COLOUR_AMBER 1020
#define IDC_COLOUR_GREEN 1021
#define IDC_RADIO_SUPEREAGLE 1022
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1021
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,16 +1,10 @@
set(SOURCES audio.c emulate.c gpu.c io.c log.c memory.c rom.c ws.c)
set(HEADERS audio.h emulate.h gpu.h io.h log.h memory.h rom.h ws.h)
option(FAKE_DISPLAY "Disable OpenGL and fake displaying" OFF)
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})
if (FAKE_DISPLAY)
target_compile_options(wswan PRIVATE -DPRETENT_DISPLAY)
endif()
target_link_libraries(wswan nec_v30 glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
target_include_directories(wswan PUBLIC . nec/)
target_include_directories(wswan PUBLIC .)
add_subdirectory(nec)

File diff suppressed because it is too large Load Diff

1514
source/audio.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,5 @@
/*******************************************************************************
* NewOswan
* audio.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
@ -18,8 +12,6 @@
#ifndef __AUDIO_H__
#define __AUDIO_H__
#include <stdint.h>
void ws_audio_init();
void ws_audio_reset();
void ws_audio_port_write(uint32_t port, uint8_t value);

View File

@ -1,12 +1,6 @@
/*******************************************************************************
* NewOswan
* emulate.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Main emulation loop
////////////////////////////////////////////////////////////////////////////////
//
//
//
@ -27,16 +21,13 @@
#include <sys/mman.h>
#include <sys/time.h>
#ifndef PRETENT_DISPLAY
#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
#endif /* PRETENT_DISPLAY */
#include "log.h"
#include "io.h"
@ -48,12 +39,15 @@
#include "audio.h"
#include "memory.h"
char app_window_title[256];
int app_terminate = 0;
char app_window_title[256];
int app_gameRunning=0;
int app_terminate=0;
int app_fullscreen=0;
int app_rotated=0;
int ws_key_esc = 0;
#ifndef PRETENT_DISPLAY
/* Open GL stuffs */
typedef struct GLWindow_t GLWindow;
struct KeyArray
@ -74,13 +68,13 @@ struct GLWindow_t
};
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);
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);
@ -98,14 +92,12 @@ static void ShowScreen(GLWindow *g, int w, int h)
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));
@ -128,6 +120,10 @@ static void setupGL(GLWindow *g, int w, int h)
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);
@ -138,7 +134,6 @@ static void setupGL(GLWindow *g, int w, int h)
glDisable(GL_DEPTH_TEST);
}
void restoreGL(GLWindow *g)
{
//Tell OpenGL how to convert from coordinates to pixel values
@ -159,7 +154,6 @@ void restoreGL(GLWindow *g)
glEnable(GL_TEXTURE_RECTANGLE);
glDisable(GL_DEPTH_TEST);
}
static void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod)
{
struct KeyArray *keyArray;
@ -180,19 +174,16 @@ static void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod
/*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;
@ -207,7 +198,7 @@ static void initDisplay(GLWindow *g)
if (!(g->windows = glfwCreateWindow(g->WIDTH, g->HEIGHT, "Main", NULL, NULL)))
{
glfwTerminate();
Log(TLOG_PANIC, "emulate", "Window creation error...");
fprintf(stderr, "Window creation error...\n");
abort();
}
@ -225,12 +216,10 @@ static void initDisplay(GLWindow *g)
glfwSetKeyCallback(g->windows, kbHandler);
glfwSetWindowSizeCallback(g->windows, sizeHandler);
}
static void clearScreen(GLWindow *g)
{
memset(g->videoMemory, 0, sizeof(uint16_t) * g->WIDTH * g->HEIGHT);
memset(g->videoMemory, 0, sizeof(uint8_t) * g->WIDTH * g->HEIGHT * 4);
}
static void updateScreen(GLWindow *g)
{
/* Update windows code */
@ -239,6 +228,17 @@ static void updateScreen(GLWindow *g)
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)
{
@ -247,168 +247,99 @@ static inline int getKeyState(int key)
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;
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 (getKeyState(GLFW_KEY_E))
{
dump_memory();
dump_memory();
}
if (getKeyState(GLFW_KEY_R))
{
Log(TLOG_DEBUG, "emulate", "Boop reset");
ws_reset();
printf("Boop\n");
ws_reset();
}
if (getKeyState(GLFW_KEY_ESCAPE))
{
ws_key_esc = 1;
ws_key_esc = 1;
}
if (getKeyState(GLFW_KEY_UP))
if ( getKeyState(GLFW_KEY_UP))
{
ws_key_x1 = 1;
ws_key_x1=1;
}
if (getKeyState(GLFW_KEY_DOWN))
if ( getKeyState(GLFW_KEY_DOWN))
{
ws_key_x3 = 1;
ws_key_x3=1;
}
if (getKeyState(GLFW_KEY_RIGHT))
{
ws_key_x2 = 1;
ws_key_x2=1;
}
if (getKeyState(GLFW_KEY_LEFT))
{
ws_key_x4 = 1;
ws_key_x4=1;
}
if (getKeyState(GLFW_KEY_ENTER))
{
ws_key_start = 1;
ws_key_start=1;
}
if (getKeyState(GLFW_KEY_C))
{
ws_key_button_a = 1;
ws_key_button_a=1;
}
if (getKeyState(GLFW_KEY_X))
{
ws_key_button_b = 1;
ws_key_button_b=1;
}
if (getKeyState(GLFW_KEY_W))
{
ws_key_y1 = 1;
ws_key_y1=1;
}
if (getKeyState(GLFW_KEY_A))
{
ws_key_y4 = 1;
ws_key_y4=1;
}
if (getKeyState(GLFW_KEY_S))
{
ws_key_y3 = 1;
ws_key_y3=1;
}
if (getKeyState(GLFW_KEY_D))
{
ws_key_y2 = 1;
ws_key_y2=1;
}
if (getKeyState(GLFW_KEY_O))
{
ws_cyclesByLine += 10;
ws_cyclesByLine+=10;
}
if (getKeyState(GLFW_KEY_L))
{
ws_cyclesByLine -= 10;
ws_cyclesByLine-=10;
}
}
#else
typedef struct PseudoWindow_t
{
uint8_t *videoMemory;
int WIDTH;
int HEIGHT;
} PseudoWindow_t;
static PseudoWindow_t mainWindow;
static void GLWindowInitEx(PseudoWindow_t *g, int w, int h)
{
g->WIDTH = w;
g->HEIGHT = h;
}
static void initDisplay(PseudoWindow_t *g)
{
int w = g->WIDTH;
int h = g->HEIGHT;
g->videoMemory = (uint8_t *)malloc(w * h * sizeof(uint16_t));
memset(g->videoMemory, 0, w * h * sizeof(uint16_t));
}
static void clearScreen(PseudoWindow_t *g)
{
memset(g->videoMemory, 0, sizeof(uint16_t) * g->WIDTH * g->HEIGHT);
}
static void updateScreen(PseudoWindow_t *g)
{
}
static void read_keys()
{
static uint32_t i = 0;
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 (i > 1024)
{
ws_key_esc = 1;
}
i++;
}
#endif /* PRETENT_DISPLAY */
double getTicks()
{
struct timeval curTime;
double ticks;
/* Get datetime */
gettimeofday(&curTime, NULL);
ticks = (curTime.tv_sec * 1000.) + curTime.tv_usec / 1000.;
return ticks;
}
////////////////////////////////////////////////////////////////////////////////
//
@ -434,12 +365,10 @@ void ws_emulate(void)
initDisplay(&mainWindow);
clearScreen(&mainWindow);
updateScreen(&mainWindow);
int16_t *backBuffer = (int16_t *)mainWindow.videoMemory;
int16_t *backBuffer = (int16_t *)mainWindow.videoMemory;
dNormalLast = getTicks();
#define HCLK (1000. / 12000.)
dNormalLast = (double)getTicks();
while (1)
{
@ -447,17 +376,18 @@ void ws_emulate(void)
dTemp = getTicks();
dTime = dTemp - dNormalLast;
nCount = (int32_t)(dTime * HCLK); // does this calculation make sense?
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
{
/* Sleep for 500us */
usleep(500);
/* Sleep for 2ms */
usleep(2000);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / HCLK);
dNormalLast += nCount * (1 / 0.07547);
if (nCount > 10)
{
@ -476,7 +406,7 @@ void ws_emulate(void)
}
}
/* What is this mess? Frameskip? */
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backBuffer, 0))

View File

@ -1,27 +1,30 @@
/*******************************************************************************
* NewOswan
* emulate.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef EMULATE_H
#define EMULATE_H
#include <stdint.h>
#define KEY_ENTER 0x0D
#define KEY_SPACE 0x20
#define KEY_ESC 0x1b
#define KEY_UP 0x26
#define KEY_DOWN 0x28
#define KEY_LEFT 0x25
#define KEY_RIGHT 0x27
#define KEY_BUTTON1 0x57
#define KEY_BUTTON2 0x58
#define GUI_COMMAND_NONE 0
#define GUI_COMMAND_RESET 1
#define GUI_COMMAND_SCHEME_CHANGE 2
#define GUI_COMMAND_FILTER_CHANGE 3
extern char app_window_title[256];
extern int app_gameRunning;
extern int app_terminate;
extern int app_fullscreen;
extern int app_rotated;
extern char app_window_title[256];
extern int app_terminate;
void ws_emulate(void);
#endif /* EMULATE_H */

File diff suppressed because it is too large Load Diff

2313
source/gpu.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,31 @@
/*******************************************************************************
* NewOswan
* gpu.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __GPU_H__
#define __GPU_H__
#include <stdint.h>
#define COLOUR_SCHEME_DEFAULT 0
#define COLOUR_SCHEME_AMBER 1
#define COLOUR_SCHEME_GREEN 2
extern uint8_t ws_gpu_scanline;
extern uint8_t ws_gpu_operatingInColor;
extern uint8_t ws_videoMode;
extern int16_t ws_palette[16 * 4];
extern int8_t ws_paletteColors[8];
extern int16_t wsc_palette[16 * 16];
extern unsigned int ws_gpu_unknownPort;
extern uint8_t ws_gpu_scanline;
extern uint8_t ws_gpu_operatingInColor;
extern uint8_t ws_videoMode;
extern int16_t ws_palette[16*4];
extern int8_t ws_paletteColors[8];
extern int16_t wsc_palette[16*16];
extern unsigned int ws_gpu_unknownPort;
extern uint32_t vblank_count;
extern uint32_t vblank_count;
void ws_gpu_init(void);
void ws_gpu_done(void);
@ -29,7 +35,10 @@ void ws_gpu_changeVideoMode(uint8_t value);
void ws_gpu_write_byte(uint32_t offset, uint8_t value);
int ws_gpu_port_write(uint32_t port, uint8_t value);
uint8_t ws_gpu_port_read(uint8_t port);
void ws_gpu_set_colour_scheme(int scheme);
void ws_gpu_changeVideoMode(uint8_t value);
void ws_gpu_forceColorSystem(void);
void ws_gpu_forceMonoSystem(void);
void ws_gpu_clearCache(void);
#endif

191
source/ieeprom.h Normal file
View File

@ -0,0 +1,191 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
uint8_t DefaultBWEEprom[]=
{
0xff,0xff,0xff,0xff,0xff,0xff,192,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,127,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,252,0xff,1,0xff,253,0xff,253,0xff,253,0xff,253,
0xff,253,0xff,253,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,3,3,0x00,0x00,0x00,64,128,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135,5,140,9,5,12,139,12,144,0x00,0x00,2,
0x00,76,165,0x00,128,0x00,0x00,0x00,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,6,6,6,6,6,0x00,0x00,0x00,0x00,0x00,
1,128,15,0x00,1,1,1,15,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
'W'-54,'O'-54,'N'-54,'D'-54,'E'-54,'R'-54,'S'-54,'W'-54,'A'-54,'N'-54,0x00,0x00,0x00,0x00,0x00,
0x00,32,1,1,33,1,4,0x00,1,
0x00,152,60,127,74,1,53,1,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff
};
uint8_t DefaultColorEEprom[]=
{
0xff,0xff,0xff,0xff,0xff,0xff,192,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,127,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,252,0xff,1,0xff,253,0xff,253,0xff,253,0xff,253,
0xff,253,0xff,253,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,3,3,0x00,0x00,0x00,64,128,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135,5,140,9,5,12,139,12,144,0x00,0x00,2,
0x00,76,165,0x00,128,0x00,0x00,0x00,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,6,6,6,6,6,0x00,0x00,0x00,0x00,0x00,
1,128,15,0x00,1,1,1,15,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
'W'-54,'O'-54,'N'-54,'D'-54,'E'-54,'R'-54,'S'-54,'W'-54,'A'-54,'N'-54,0x00,0x00,0x00,0x00,0x00,
0x00,32,1,1,33,1,4,0x00,1,
0x00,152,60,127,74,1,53,1,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff
};

271
source/initialIo.h Normal file
View File

@ -0,0 +1,271 @@
////////////////////////////////////////////////////////////////////////////////
// Initial I/O values
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
uint8_t initialIoValue[256]=
{
0x00,//0
0x00,//1
0x9d,//2
0xbb,//3
0x00,//4
0x00,//5
0x00,//6
0x26,//7
0xfe,//8
0xde,//9
0xf9,//a
0xfb,//b
0xdb,//c
0xd7,//d
0x7f,//e
0xf5,//f
0x00,//10
0x00,//11
0x00,//12
0x00,//13
0x01,//14
0x00,//15
0x9e,//16
0x9b,//17
0x00,//18
0x00,//19
0x00,//1a
0x00,//1b
0x99,//1c
0xfd,//1d
0xb7,//1e
0xdf,//1f
0x30,//20
0x57,//21
0x75,//22
0x76,//23
0x15,//24
0x73,//25
0x77,//26
0x77,//27
0x20,//28
0x75,//29
0x50,//2a
0x36,//2b
0x70,//2c
0x67,//2d
0x50,//2e
0x77,//2f
0x57,//30
0x54,//31
0x75,//32
0x77,//33
0x75,//34
0x17,//35
0x37,//36
0x73,//37
0x50,//38
0x57,//39
0x60,//3a
0x77,//3b
0x70,//3c
0x77,//3d
0x10,//3e
0x73,//3f
0x00,//40
0x00,//41
0x00,//42
0x00,//43
0x00,//44
0x00,//45
0x00,//46
0x00,//47
0x00,//48
0x00,//49
0x00,//4a
0x00,//4b
0x00,//4c
0x00,//4d
0x00,//4e
0x00,//4f
0x00,//50
0x00,//51
0x00,//52
0x00,//53
0x00,//54
0x00,//55
0x00,//56
0x00,//57
0x00,//58
0x00,//59
0x00,//5a
0x00,//5b
0x00,//5c
0x00,//5d
0x00,//5e
0x00,//5f
0x0a,//60
0x00,//61
0x00,//62
0x00,//63
0x00,//64
0x00,//65
0x00,//66
0x00,//67
0x00,//68
0x00,//69
0x00,//6a
0x0f,//6b
0x00,//6c
0x00,//6d
0x00,//6e
0x00,//6f
0x00,//70
0x00,//71
0x00,//72
0x00,//73
0x00,//74
0x00,//75
0x00,//76
0x00,//77
0x00,//78
0x00,//79
0x00,//7a
0x00,//7b
0x00,//7c
0x00,//7d
0x00,//7e
0x00,//7f
0x00,//80
0x00,//81
0x00,//82
0x00,//83
0x00,//84
0x00,//85
0x00,//86
0x00,//87
0x00,//88
0x00,//89
0x00,//8a
0x00,//8b
0x00,//8c
0x1f,//8d 1d ?
0x00,//8e
0x00,//8f
0x00,//90
0x00,//91
0x00,//92
0x00,//93
0x00,//94
0x00,//95
0x00,//96
0x00,//97
0x00,//98
0x00,//99
0x00,//9a
0x00,//9b
0x00,//9c
0x00,//9d
0x03,//9e
0x00,//9f
0x80,//a0
0x00,//a1
0x00,//a2
0x00,//a3
0x0,//a4 2b
0x0,//a5 7f
0x4f,//a6
0xff,//a7 cf ?
0x00,//a8
0x00,//a9
0x00,//aa
0x00,//ab
0x00,//ac
0x00,//ad
0x00,//ae
0x00,//af
0x00,//b0
0xdb,//b1
0x00,//b2
0x00,//b3
0x00,//b4
0x40,//b5
0x00,//b6
0x00,//b7
0x00,//b8
0x00,//b9
0x01,//ba
0x00,//bb
0x42,//bc
0x00,//bd
0x83,//be
0x00,//bf
0x2f,//c0
0x3f,//c1
0xff,//c2
0xff,//c3
0x00,//c4
0x00,//c5
0x00,//c6
0x00,//c7
0xd1,//c8?
0xd1,//c9
0xd1,//ca
0xd1,//cb
0xd1,//cc
0xd1,//cd
0xd1,//ce
0xd1,//cf
0xd1,//d0
0xd1,//d1
0xd1,//d2
0xd1,//d3
0xd1,//d4
0xd1,//d5
0xd1,//d6
0xd1,//d7
0xd1,//d8
0xd1,//d9
0xd1,//da
0xd1,//db
0xd1,//dc
0xd1,//dd
0xd1,//de
0xd1,//df
0xd1,//e0
0xd1,//e1
0xd1,//e2
0xd1,//e3
0xd1,//e4
0xd1,//e5
0xd1,//e6
0xd1,//e7
0xd1,//e8
0xd1,//e9
0xd1,//ea
0xd1,//eb
0xd1,//ec
0xd1,//ed
0xd1,//ee
0xd1,//ef
0xd1,//f0
0xd1,//f1
0xd1,//f2
0xd1,//f3
0xd1,//f4
0xd1,//f5
0xd1,//f6
0xd1,//f7
0xd1,//f8
0xd1,//f9
0xd1,//fa
0xd1,//fb
0xd1,//fc
0xd1,//fd
0xd1,//fe
0xd1 //ff
};

File diff suppressed because it is too large Load Diff

1092
source/io.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,5 @@
/*******************************************************************************
* NewOswan
* io.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
@ -18,9 +12,7 @@
#ifndef __IO_H__
#define __IO_H__
#include <stdint.h>
extern uint8_t *ws_ioRam;
extern uint8_t *ws_ioRam;
extern uint8_t ws_key_start;
extern uint8_t ws_key_x4;
extern uint8_t ws_key_x2;
@ -33,13 +25,10 @@ extern uint8_t ws_key_y3;
extern uint8_t ws_key_button_a;
extern uint8_t ws_key_button_b;
void io_init(void);
void io_reset(void);
void io_flipControls(void);
void io_done(void);
uint8_t io_readport(uint8_t port);
void io_writeport(uint32_t port, uint8_t value);
void ws_io_init(void);
void ws_io_reset(void);
void ws_io_flipControls(void);
void ws_io_done(void);
#endif

View File

@ -1,139 +0,0 @@
/*******************************************************************************
* NewOswan
* log.c: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* Created by Manoël Trapier on 20/01/2009.
******************************************************************************/
#define __LOG_C_INTERNAL_
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <log.h>
#include <sys/time.h>
#include <time.h>
#include <syslog.h>
void log_displayPanic(int signal)
{
size_t size = 0;
//size = backtrace(array, 30);
/* Now flood user with unusefull data. */
fprintf(stderr, FYELLOW "\n\n ----- " FYELLOW " YICK! ERROR YICK! [bt:%zu]" FYELLOW "----- \n", size);
// get void*'s for all entries on the stack
// print out all the frames to stderr
fprintf(stderr, " ----- Error: signal: %d -----\n" FRED, signal);
//backtrace_symbols_fd(array, size, 2);
fprintf(stderr, FYELLOW "\n\n ----- " FYELLOW " YICK! ERROR YICK! " FYELLOW "----- " CNORMAL "\n");
}
void time_stamp_line(void)
{
/* Time "0" will be thefirst log line */
static char firstRun = 1;
static struct timeval firstTime;
struct timeval curTime;
int cMin, cSec;
long long cMSec;
/* Get datetime */
gettimeofday(&curTime, NULL);
if (firstRun == 1)
{
firstRun = 0;
firstTime.tv_sec = curTime.tv_sec;
firstTime.tv_usec = curTime.tv_usec;
}
cMSec = ((curTime.tv_sec - firstTime.tv_sec) * 1000) + (curTime.tv_usec - firstTime.tv_usec) / 1000;
cSec = (cMSec / 1000);
cMSec %= 1000;
cMin = cSec / 60;
cSec %= 60;
/* Put cursor at start of line */
fprintf(stderr, "%c[s", 0x1B);
fprintf(stderr, "%c[7000D", 0x1B);
fprintf(stderr, "%c[1C", 0x1B);
fprintf(stderr, FWHITE"[" FYELLOW "%03d" FRED "." FBLUE "%02d" FRED "." FGREEN "%03lld" FWHITE "]" CNORMAL, cMin,
cSec, cMSec);
fprintf(stderr, "%c[u", 0x1B);
}
void log_real(int level, const char *user, const char *fmt, ...)
{
int i;
va_list va;
/* The LOG_PANIC must always be displayed */
if ((level <= MAX_DEBUG_LEVEL) || (level <= TLOG_PANIC))
{
fprintf(stderr, CNORMAL);
time_stamp_line();
fprintf(stderr, CNORMAL " | ");
switch (level)
{
case TLOG_PANIC: fprintf(stderr, BRED FWHITE); break;
case TLOG_ERROR: fprintf(stderr, FRED); break;
case TLOG_WARNING: fprintf(stderr, FYELLOW); break;
default:
case TLOG_NORMAL: fprintf(stderr, FGREEN); break;
case TLOG_VERBOSE: fprintf(stderr, FCYAN); break;
case TLOG_DEBUG: fprintf(stderr, BBLUE FWHITE); break;
}
if (user != NULL)
{
i = strlen(user);
if (i < 12)
{
i = 12 - i;
for (; i >= 0 ; i--)
{
fprintf(stderr, " ");
}
}
fprintf(stderr, "%s", user);
}
else
{
switch (level)
{
case TLOG_PANIC: fprintf(stderr, " PANIC"); break;
case TLOG_ERROR: fprintf(stderr, " Error"); break;
case TLOG_WARNING: fprintf(stderr, " Warning"); break;
default:
case TLOG_NORMAL: fprintf(stderr, " Info"); break;
case TLOG_VERBOSE: fprintf(stderr, " Verbose"); break;
case TLOG_DEBUG: fprintf(stderr, " Debug"); break;
}
}
fprintf(stderr, CNORMAL " | ");
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
if (fmt[0] != 0)
{
fprintf(stderr, "\n");
}
#ifdef LOG_ALWAYS_FFLUSH
/* Systematicaly flush */
fflush(stderr);
#endif
}
}

67
source/log.cpp Normal file
View File

@ -0,0 +1,67 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include "log.h"
FILE *log_stream=NULL;
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
int log_init(char *path)
{
//log_stream=fopen(path,"wrt");
log_stream = stdout;
if (log_stream==NULL)
{
return(0);
}
return(1);
}
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
FILE *log_get(void)
{
return(log_stream);
}
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
void log_done(void)
{
fclose(log_stream);
}

View File

@ -1,124 +1,20 @@
/*******************************************************************************
* NewOswan
* log.h: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* Created by Manoël Trapier on 20/01/2009.
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef _LOG_H
#define _LOG_H
#ifndef __LOG_H__
#define __LOG_H__
int log_init(char *path);
FILE *log_get(void);
void log_done(void);
#ifdef __cplusplus
extern "C" {
#endif
#define ALLOW_COLORS
#ifdef ALLOW_COLORS
#define __C(c) "\x1B[" c "m"
#else
#define __C(c) ""
#endif
#define ANSI_COLOR __C
#define FBLACK ANSI_COLOR("30")
#define FRED ANSI_COLOR("31")
#define FGREEN ANSI_COLOR("32")
#define FYELLOW ANSI_COLOR("33")
#define FBLUE ANSI_COLOR("34")
#define FMAGENTA ANSI_COLOR("35")
#define FCYAN ANSI_COLOR("36")
#define FWHITE ANSI_COLOR("37")
#define BBLACK ANSI_COLOR("40")
#define BRED ANSI_COLOR("41")
#define BGREEN ANSI_COLOR("42")
#define BYELLOW ANSI_COLOR("43")
#define BBLUE ANSI_COLOR("44")
#define BMAGENTA ANSI_COLOR("45")
#define BCYAN ANSI_COLOR("46")
#define BWHITE ANSI_COLOR("47")
#define CNORMAL ANSI_COLOR("0")
enum
{
TLOG_ALWAYS = -1,
TLOG_PANIC = 0,
TLOG_ERROR,
TLOG_WARNING,
TLOG_NORMAL,
TLOG_VERBOSE,
TLOG_DEBUG,
};
//#define LOG_ALWAYS_FFLUSH
#define DYNA_LOG_LEVEL
#define SET_DEBUG_LOG
/* Set if DYNALOG is set the maximum compiled log level */
#ifndef MAXIMUM_DEBUG_LEVEL
#ifndef SET_DEBUG_LOG
#define MAXIMUM_DEBUG_LEVEL TLOG_NORMAL
#else
#define MAXIMUM_DEBUG_LEVEL TLOG_DEBUG
#endif
#endif /* MAXIMUM_DEBUG_LEVEL */
/* Set the default log level */
#ifndef SET_DEBUG_LOG
#define DEFAULT_DEBUG_LEVEL TLOG_PANIC
#else
#define DEFAULT_DEBUG_LEVEL TLOG_DEBUG
#endif
/******************************************************************************/
/* DO NOT MESS AFTER THIS LINE */
/******************************************************************************/
#ifdef DYNA_LOG_LEVEL
# ifdef MAX_DEBUG_LEVEL
# undef MAX_DEBUG_LEVEL
# endif
# ifdef __LOG_C_INTERNAL_
int MAX_DEBUG_LEVEL = DEFAULT_DEBUG_LEVEL;
#else
extern int MAX_DEBUG_LEVEL;
#endif
#else
# ifndef MAX_DEBUG_LEVEL
# define MAX_DEBUG_LEVEL DEFAULT_DEBUG_LEVEL
# endif
#endif
#define Log(_level, _user, _fmt, ...)\
if (_level <= MAXIMUM_DEBUG_LEVEL)\
if ((_level <= MAX_DEBUG_LEVEL) || (_level <= TLOG_PANIC))\
do { log_real(_level, _user, _fmt, ##__VA_ARGS__); } while(0)
void log_real(int level, const char *user, const char *fmt, ...);
#define LOG(_level, _str, ...) if ((_level <= MAX_DEBUG_LEVEL) || (_level <= TLOG_PANIC)) do { fputs(_str, stderr); } while(0)
#define LOGCODE(_level, _user, _code)\
if (_level <= MAXIMUM_DEBUG_LEVEL) do{\
Log(_level, _user, "");\
if ((_level <= MAX_DEBUG_LEVEL) || (_level <= TLOG_PANIC))\
do { _code; fprintf(stderr, "\n"); } while(0); } while(0)
#define INFOL(_level, _fmt) LOGCODE(_level, "INFOL", { printf _fmt; })
#define FUNC_IN() Log(TLOG_VERBOSE, NULL, ">>%s", __func__)
#define FUNC_OUT() Log(TLOG_VERBOSE, NULL, "<<%s", __func__)
#define FUNC_OUTR(out) Log(TLOG_VERBOSE, NULL, "<<%s (%d)", __func__, out)
void log_displayPanic(int signal);
#ifdef __cplusplus
}
#endif
#endif /* _LOG_H */

View File

@ -1,613 +0,0 @@
/*******************************************************************************
* NewOswan
* memory.c: Memory implementation
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// Notes: need to optimize mem_writemem20
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "ws.h"
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "io.h"
#include "gpu.h"
#include "audio.h"
#include "memory.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define IO_ROM_BANK_BASE_SELECTOR 0xC0
uint8_t *ws_rom;
uint8_t *ws_staticRam;
uint8_t *internalRam;
uint8_t *externalEeprom;
char *internalBWIRom;
char *internalColorIRom;
char *internalCrystalIRom;
char *internalBWEeprom;
char *internalColorEeprom;
char *internalCrystalEeprom;
uint16_t *internalEeprom;
extern uint8_t *ws_ioRam;
uint16_t ws_rom_checksum;
uint8_t ws_haveCrystalIRom;
uint8_t ws_haveColorIRom;
uint8_t ws_haveBWIRom;
uint32_t sramAddressMask;
uint32_t externalEepromAddressMask;
uint32_t romAddressMask;
uint32_t romSize;
uint32_t sramSize;
extern nec_Regs I;
void dump_memory()
{
int i;
FILE *fp;
printf("Dumping memory....\n");
fp = fopen("iram.bin", "wb");
fwrite(internalRam, 1, 0x10000, fp);
fclose(fp);
fp = fopen("sram.bin", "wb");
fwrite(ws_staticRam, 1, 0x10000, fp);
fclose(fp);
fp = fopen("rom.bin", "wb");
fwrite(ws_rom, 1, romSize, fp);
fclose(fp);
fp = fopen("memorydump.bin", "wb");
fwrite(internalRam, 1, 0x10000, fp);
/* page 1 */
fwrite(&(ws_staticRam[0 & sramAddressMask]), 1, 0x10000, fp);
fwrite(&(ws_rom[((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR + 2] & ((romSize >> 16) - 1)) << 16)]), 1, 0x10000, fp);
fwrite(&(ws_rom[((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR + 3] & ((romSize >> 16) - 1)) << 16)]), 1, 0x10000, fp);
for (i = 4 ; i < 0x10 ; i++)
{
int romBank = (256 - (((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR] & 0xf) << 4) | (i & 0xf)));
fwrite(&(ws_rom[(unsigned)(romSize - (romBank << 16))]), 1, 0x10000, fp);
}
fclose(fp);
fp = fopen("registers.bin", "wb");
fwrite(ws_ioRam, 1, 256, fp);
fclose(fp);
fp = fopen("cpuregs.bin", "wb");
/* CS */
fwrite(&I.sregs[CS], 1, 2, fp);
/* IP */
fwrite(&I.ip, 1, 2, fp);
fclose(fp);
}
#ifndef USE_PAGED_MEMORY_ACCESS
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void mem_writemem20(uint32_t addr, uint8_t value)
{
uint32_t offset = addr & 0xffff;
uint32_t bank = addr >> 16;
if (!bank)
{
// 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
ws_gpu_write_byte(offset, value);
ws_audio_write_byte(offset, value);
}
else if (bank == 1)
{
// 1 - SRAM (cart)
ws_staticRam[offset & sramAddressMask] = value;
}
// other banks are read-only
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t mem_readmem20(uint32_t addr)
{
uint32_t offset = addr & 0xffff;
uint32_t bank = addr >> 16;
//uint16_t romBank;
uint8_t hwReg;
uint32_t temp;
uint8_t ret;
wssystem_t currentSystem = ws_get_system();
switch (bank)
{
case 0:
/*
* So the original WonderSwan, and Color/Crystal in B&W mode have 16KB of IRAM Mapped.
* Color/Crystal in color mode have 64 KB IRAM mapped.
*/
if (ws_gpu_operatingInColor)
{
return (internalRam[offset]);
}
else if (offset < 0x4000)
{
return (internalRam[offset]);
}
return (0x90);
case 1: // 1 - SRAM (cart)
return ws_staticRam[offset & sramAddressMask];
case 2:
// Bank 2
hwReg = ws_ioRam[0xC2];
temp = hwReg << 16;
temp += offset;
temp &= (romSize - 1);
return ws_rom[temp];
case 3:
// Bank 3
hwReg = ws_ioRam[0xC3];
temp = hwReg << 16;
temp += offset;
temp &= (romSize - 1);
return ws_rom[temp];
case 0xF:
hwReg = ws_ioRam[0xA0];
if (!(hwReg & 1))
{
if (currentSystem == WS_SYSTEM_COLOR && ws_haveColorIRom)
{
if (addr >= 0xFE000)
{
ret = internalColorIRom[addr & ~0xFE000];
return ret;
}
}
else if (currentSystem == WS_SYSTEM_CRYSTAL && ws_haveColorIRom)
{
if (addr >= 0xFE000)
{
ret = internalCrystalIRom[addr & ~0xFE000];
return ret;
}
}
else if (currentSystem == WS_SYSTEM_MONO && ws_haveBWIRom)
{
if (addr >= 0xFF000)
{
ret = internalBWIRom[addr & ~0xFF000];
return ret;
}
}
}
// fall through
default:
hwReg = ws_ioRam[0xC0];
temp = hwReg << 20;
temp += addr & 0xFFFFF;
temp &= (romSize - 1);
return ws_rom[temp];
}
return (0x90);
}
#else
/* 256 page of 12 bits */
uint8_t *pagedMemory[0x100];
/* Memory address is 20bit and split in 8 (page) - 12 (offset) */
void mem_writemem20(uint32_t addr, uint8_t value)
{
uint8_t page = addr >> 12;
uint16_t offset = addr & 0xFFF;
if (page < 0x30)
{
/* Unmapped will be NULL so just check to be sure */
if (pagedMemory[page])
{
pagedMemory[page][offset] = value;
}
}
}
uint8_t mem_readmem20(uint32_t addr)
{
uint8_t page = addr >> 12;
uint16_t offset = addr & 0xFFF;
if (pagedMemory[page])
{
return pagedMemory[page][offset];
}
return 0x90;
}
/* Set memory bank with a granularity of 4-16 as it is the most common on the WonderSwan */
void set_memory_bank(uint8_t bank, uint8_t *pointer)
{
uint8_t page = bank << 4;
for(int i = 0; i < 16; i++)
{
pagedMemory[page | i] = pointer + (i * 0x1000);
}
}
void set_memory_page(uint8_t page, uint8_t *pointer)
{
pagedMemory[page] = pointer;
}
void set_irom_overlay()
{
/* Setup the boot rom */
if (ws_get_system() == WS_SYSTEM_MONO)
{
set_memory_page(0xFF, internalBWIRom);
}
else if (ws_get_system() == WS_SYSTEM_COLOR)
{
set_memory_page(0xFE, internalColorIRom);
set_memory_page(0xFF, internalColorIRom + 0x1000);
}
else if (ws_get_system() == WS_SYSTEM_CRYSTAL)
{
set_memory_page(0xFE, internalCrystalIRom);
set_memory_page(0xFF, internalCrystalIRom + 0x1000);
}
}
uint8_t *getRom(uint32_t *size)
{
*size = romSize;
return ws_rom;
}
uint8_t *getSram(uint32_t *size)
{
*size = sramSize;
return ws_staticRam;
}
#endif
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
char *load_file(char *filename)
{
int fd;
char *ret_ptr;
struct stat FileStat;
fd = open(filename, O_RDWR);
fstat(fd, &FileStat);
Log(TLOG_DEBUG, "memory", "Trying to load %s, size = %lu...", filename, (unsigned long)FileStat.st_size);
ret_ptr = (char *)mmap(NULL, FileStat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
char *create_file(char *filename, uint32_t size)
{
int fd;
uint32_t i;
char *ret_ptr;
char buf[] = {0};
Log(TLOG_DEBUG, "memory", "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);
fchmod(fd, 0644);
close(fd);
sync();
fd = open(filename, O_RDWR);
for (i = 0 ; i < size ; i++)
{
write(fd, buf, 1);
}
close(fd);
sync();
fd = open(filename, O_RDWR);
ret_ptr = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_init(uint8_t *rom, uint32_t wsRomSize)
{
ws_romHeaderStruct *ws_romHeader;
ws_rom = rom;
romSize = wsRomSize;
sramSize = ws_rom_sramSize(ws_rom, romSize);
ws_romHeader = ws_rom_getHeader(ws_rom, romSize);
ws_rom_checksum = ws_romHeader->checksum;
internalRam = (uint8_t *)malloc(0x10000);
sramAddressMask = 0x0;
externalEepromAddressMask = 0x0;
if (sramSize > 0)
{
sramAddressMask = ws_rom_sramSize(ws_rom, romSize) - 1;
}
if (ws_rom_eepromSize(ws_rom, romSize) > 0)
{
externalEepromAddressMask = ws_rom_eepromSize(ws_rom, romSize) - 1;
}
internalBWIRom = load_file("ws_irom.bin");
internalColorIRom = load_file("wsc_irom.bin");
internalCrystalIRom = load_file("wc_irom.bin");
internalBWEeprom = load_file("ws_ieeprom.bin");
if (internalBWEeprom == NULL)
{
internalBWEeprom = create_file("ws_ieeprom.bin", BW_IEEPROM_SIZE);
}
internalColorEeprom = load_file("wsc_ieeprom.bin");
if (internalColorEeprom == NULL)
{
internalColorEeprom = create_file("wsc_ieeprom.bin", COLOR_IEEPROM_SIZE);
}
internalCrystalEeprom = load_file("wc_ieeprom.bin");
if (internalCrystalEeprom == NULL)
{
internalCrystalEeprom = create_file("wc_ieeprom.bin", COLOR_IEEPROM_SIZE);
}
internalEeprom = (uint16_t *)internalBWEeprom;
if (ws_get_system() == WS_SYSTEM_COLOR)
{
internalEeprom = (uint16_t *)internalColorEeprom;
}
else if (ws_get_system() == WS_SYSTEM_CRYSTAL)
{
internalEeprom = (uint16_t *)internalCrystalEeprom;
}
ws_haveBWIRom = false;
ws_haveColorIRom = false;
ws_haveCrystalIRom = false;
if (internalColorIRom != NULL)
{
Log(TLOG_DEBUG, "memory", "B&W IROM Found!");
ws_haveColorIRom = true;
}
if (internalBWIRom != NULL)
{
Log(TLOG_DEBUG, "memory", "Color IROM Found!");
ws_haveBWIRom = true;
}
if (internalCrystalIRom != NULL)
{
Log(TLOG_DEBUG, "memory", "Crystal IROM Found!");
ws_haveCrystalIRom = true;
}
romAddressMask = romSize - 1;
#ifdef USE_PAGED_MEMORY_ACCESS
for(int i = 0; i < 0x100; i++)
{
pagedMemory[i] = NULL;
}
/* IRAM */
set_memory_bank(0, internalRam);
for(int i = 0x4; i < 0x10; i++)
{
set_memory_page(i, NULL);
}
/* Cart SRAM */
if (sramSize > 0)
{
set_memory_bank(0x1, ws_get_page_ptr(ws_staticRam, sramSize, 0xFF));
}
set_memory_bank(0x2, ws_get_page_ptr(ws_rom, romSize, 0xFF));
set_memory_bank(0x3, ws_get_page_ptr(ws_rom, romSize, 0xFF));
for(int i = 0x04; i < 0x10; i++)
{
set_memory_bank(i, ws_get_page_ptr(ws_rom, romSize, 0xF0 + i));
}
set_irom_overlay();
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_reset(void)
{
memset(internalRam, 0, 0x10000);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_done(void)
{
free(internalRam);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t *memory_getRom(void)
{
return (ws_rom);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t memory_getRomSize(void)
{
return (romSize);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint16_t memory_getRomCrc(void)
{
return (ws_rom_checksum);
}

448
source/memory.cpp Normal file
View File

@ -0,0 +1,448 @@
////////////////////////////////////////////////////////////////////////////////
// Memory
////////////////////////////////////////////////////////////////////////////////
// Notes: need to optimize cpu_writemem20
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "io.h"
#include "gpu.h"
#include "audio.h"
#include "memory.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define IO_ROM_BANK_BASE_SELECTOR 0xC0
uint8_t *ws_rom;
uint8_t *ws_staticRam;
uint8_t *internalRam;
uint8_t *externalEeprom;
char *internalBWIRom;
char *internalColorIRom;
char *internalBWEeprom;
char *internalColorEeprom;
uint16_t *internalEeprom;
extern uint8_t *ws_ioRam;
uint16_t ws_rom_checksum;
uint8_t ws_haveColorIRom;
uint8_t ws_haveBWIRom;
uint32_t sramAddressMask;
uint32_t externalEepromAddressMask;
uint32_t romAddressMask;
uint32_t romSize;
int ws_sram_dirty = 0;
extern nec_Regs I;
void dump_memory()
{
int i;
FILE *fp;
printf("Dumping memory....\n");
fp = fopen("iram.bin", "wb");
fwrite(internalRam, 1, 0x10000, fp);
fclose(fp);
fp = fopen("sram.bin", "wb");
fwrite(ws_staticRam, 1, 0x10000, fp);
fclose(fp);
fp = fopen("rom.bin", "wb");
fwrite(ws_rom, 1, romSize, fp);
fclose(fp);
fp = fopen("memorydump.bin", "wb");
fwrite(internalRam, 1, 0x10000, fp);
/* page 1 */
fwrite(&(ws_staticRam[0 & sramAddressMask]), 1, 0x10000, fp);
fwrite(&(ws_rom[((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR+2]&((romSize>>16)-1))<<16)]), 1, 0x10000, fp);
fwrite(&(ws_rom[((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR+3]&((romSize>>16)-1))<<16)]), 1, 0x10000, fp);
for(i = 4; i < 0x10; i++)
{
int romBank=(256-(((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR]&0xf)<<4)|(i&0xf)));
fwrite(&(ws_rom[(unsigned)(romSize-(romBank<<16))]), 1, 0x10000, fp);
}
fclose(fp);
fp = fopen("registers.bin", "wb");
fwrite(ws_ioRam, 1, 256, fp);
fclose(fp);
fp = fopen("cpuregs.bin", "wb");
/* CS */
fwrite(&I.sregs[CS], 1, 2, fp);
/* IP */
fwrite(&I.ip, 1, 2, fp);
fclose(fp);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void cpu_writemem20(uint32_t addr, uint8_t value)
{
uint32_t offset=addr&0xffff;
uint32_t bank=addr>>16;
if (!bank)
{
// 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
ws_gpu_write_byte(offset,value);
ws_audio_write_byte(offset,value);
}
else if (bank==1)
{
// 1 - SRAM (cart)
ws_staticRam[offset&sramAddressMask]=value;
ws_sram_dirty = 1;
}
// other banks are read-only
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t cpu_readmem20(uint32_t addr)
{
uint32_t offset=addr&0xffff;
uint32_t bank=addr>>16;
//uint16_t romBank;
uint8_t hwReg;
uint32_t temp;
uint8_t ret;
switch (bank)
{
case 0: // 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
if (ws_gpu_operatingInColor)
{
return(internalRam[offset]);
}
else if (offset<0x4000)
{
return(internalRam[offset]);
}
return(0x90);
case 1: // 1 - SRAM (cart)
return ws_staticRam[offset&sramAddressMask];
case 2:
// Bank 2
hwReg = ws_ioRam[0xC2];
temp = hwReg << 16;
temp += offset;
temp &= (romSize - 1);
return ws_rom[temp];
case 3:
// Bank 3
hwReg = ws_ioRam[0xC3];
temp = hwReg << 16;
temp += offset;
temp &= (romSize - 1);
return ws_rom[temp];
case 0xF:
hwReg = ws_ioRam[0xA0];
if (!(hwReg & 1))
{
if (ws_gpu_operatingInColor && ws_haveColorIRom)
{
if (addr >= 0xFE000)
{
ret = internalColorIRom[addr & ~0xFE000];
return ret;
}
}
else if (!ws_gpu_operatingInColor && ws_haveBWIRom)
{
if (addr >= 0xFF000)
{
ret = internalBWIRom[addr & ~0xFF000];
return ret;
}
}
}
// fall through
default:
hwReg = ws_ioRam[0xC0];
temp = hwReg << 20;
temp += addr & 0xFFFFF;
temp &= (romSize - 1);
return ws_rom[temp];
}
return(0x90);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
char *load_file(char *filename)
{
int fd;
char *ret_ptr;
struct stat FileStat;
fd = open(filename, O_RDWR);
fstat(fd, &FileStat);
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);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
char *create_file(char *filename, uint32_t size)
{
int fd;
uint32_t i;
char *ret_ptr;
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);
fchmod(fd, 0644);
close(fd);
sync();
fd = open(filename, O_RDWR);
for(i = 0; i < size; i++)
{
write(fd, buf, 1);
}
close(fd);
sync();
fd = open(filename, O_RDWR);
ret_ptr = (char *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_init(uint8_t *rom, uint32_t wsRomSize)
{
ws_romHeaderStruct *ws_romHeader;
ws_rom=rom;
romSize=wsRomSize;
ws_romHeader=ws_rom_getHeader(ws_rom,romSize);
ws_rom_checksum=ws_romHeader->checksum;
internalRam=(uint8_t*)malloc(0x10000);
sramAddressMask=ws_rom_sramSize(ws_rom,romSize)-1;
externalEepromAddressMask=ws_rom_eepromSize(ws_rom,romSize)-1;
internalBWIRom = load_file("ws_irom.bin");
internalColorIRom = load_file("wsc_irom.bin");
internalBWEeprom = load_file("ws_ieeprom.bin");
if ( internalBWEeprom == NULL )
{
internalBWEeprom = create_file("ws_ieeprom.bin", BW_IEEPROM_SIZE);
}
internalColorEeprom = load_file("wsc_ieeprom.bin");
if ( internalColorEeprom == NULL )
{
internalColorEeprom = create_file("wsc_ieeprom.bin", COLOR_IEEPROM_SIZE);
}
internalEeprom = (uint16_t *)internalBWEeprom;
if (ws_gpu_operatingInColor)
{
internalEeprom = (uint16_t *)internalColorEeprom;
}
ws_haveBWIRom = false;
ws_haveColorIRom = false;
if (internalBWIRom != NULL)
{
printf("Color IROM Found!\n");
ws_haveBWIRom = true;
}
if (internalColorIRom != NULL)
{
printf("B&W IROM Found!\n");
ws_haveColorIRom = true;
}
romAddressMask=romSize-1;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_reset(void)
{
memset(internalRam,0,0x10000);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_done(void)
{
free(internalRam);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t *memory_getRom(void)
{
return(ws_rom);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t memory_getRomSize(void)
{
return(romSize);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint16_t memory_getRomCrc(void)
{
return(ws_rom_checksum);
}

View File

@ -1,11 +1,5 @@
/*******************************************************************************
* NewOswan
* memory.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
@ -18,18 +12,16 @@
#ifndef __MEMORY_H__
#define __MEMORY_H__
#include <stdint.h>
extern uint8_t *ws_staticRam;
extern uint8_t *internalRam;
extern uint8_t *externalEeprom;
extern uint8_t *ws_staticRam;
extern uint8_t *internalRam;
extern uint8_t *externalEeprom;
void ws_memory_init(uint8_t *rom, uint32_t romSize);
void ws_memory_reset(void);
uint8_t *memory_getRom(void);
uint32_t memory_getRomSize(void);
uint16_t memory_getRomCrc(void);
void ws_memory_done(void);
void ws_memory_init(uint8_t *rom, uint32_t romSize);
void ws_memory_reset(void);
uint8_t *memory_getRom(void);
uint32_t memory_getRomSize(void);
uint16_t memory_getRomCrc(void);
void ws_memory_done(void);
void memory_load(int fp);
void memory_save(int fp);
@ -37,32 +29,6 @@ char *create_file(char *filename, uint32_t size);
char *load_file(char *filename);
void dump_memory();
//#define USE_PAGED_MEMORY_ACCESS
#ifdef USE_PAGED_MEMORY_ACCESS
/***
* Set a memory page with a ganularity of 4-16
* @param bank: the bank (0-F) to set
* @param pointer: a pointer to the memory to set
*/
void set_memory_bank(uint8_t bank, uint8_t *pointer);
/***
* Set a memory page with a ganularity of 8-12
* @param bank: the bank (0-FF) to set
* @param pointer: a pointer to the memory to set
*/
void set_memory_page(uint8_t page, uint8_t *pointer);
void set_irom_overlay();
uint8_t *getRom(uint32_t *size);
uint8_t *getSram(uint32_t *size);
#endif
#define mem_readop mem_readmem20
#define mem_readop_arg mem_readmem20
void mem_writemem20(uint32_t addr, uint8_t value);
uint8_t mem_readmem20(uint32_t addr);
#define BW_IEEPROM_SIZE (128)
#define COLOR_IEEPROM_SIZE (2048)

View File

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

File diff suppressed because it is too large Load Diff

3933
source/nec/nec.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,56 +1,37 @@
/******************************************************************************
* NewOswan
* nec.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
#ifndef __NEC_H_
#define __NEC_H_
#include <stdint.h>
#include <stdbool.h>
#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;
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 */
/* 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];
necbasicregs regs;
uint16_t sregs[4];
uint16_t ip;
uint16_t ip;
int32_t SignVal;
int32_t AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
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 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);
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()
@ -61,30 +42,37 @@ typedef struct
#define V30 8
#define V20 16
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
/* parameter x = result, y = source 1, z = source 2 */
#define SetTF(x) (I.TF = (x))
#define SetIF(x) (I.IF = (x))
#define SetDF(x) (I.DF = (x))
#define SetMD(x) (I.MF = (x)) /* OB [19.07.99] Mode Flag V30 */
#define SetTF(x) (I.TF = (x))
#define SetIF(x) (I.IF = (x))
#define SetDF(x) (I.DF = (x))
#define SetMD(x) (I.MF = (x)) /* OB [19.07.99] Mode Flag V30 */
#define SetCFB(x) (I.CarryVal = (x) & 0x100)
#define SetCFW(x) (I.CarryVal = (x) & 0x10000)
#define SetCFB(x) (I.CarryVal = (x) & 0x100)
#define SetCFW(x) (I.CarryVal = (x) & 0x10000)
#define SetAF(x, y, z) (I.AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
#define SetAF(x,y,z) (I.AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
#define SetSF(x) (I.SignVal = (x))
#define SetZF(x) (I.ZeroVal = (x))
#define SetPF(x) (I.ParityVal = (x))
#define SetSF(x) (I.SignVal = (x))
#define SetZF(x) (I.ZeroVal = (x))
#define SetPF(x) (I.ParityVal = (x))
#define SetSZPF_Byte(x) (I.SignVal=I.ZeroVal=I.ParityVal=(int8_t)(x))
#define SetSZPF_Word(x) (I.SignVal=I.ZeroVal=I.ParityVal=(int16_t)(x))
#define SetOFW_Add(x, y, z) (I.OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
#define SetOFB_Add(x, y, z) (I.OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
#define SetOFW_Sub(x, y, z) (I.OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
#define SetOFB_Sub(x, y, z) (I.OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
#define SetOFW_Add(x,y,z) (I.OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
#define SetOFB_Add(x,y,z) (I.OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
#define SetOFW_Sub(x,y,z) (I.OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
#define SetOFB_Sub(x,y,z) (I.OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
#define ADDB { uint32_t res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(uint8_t)res; }
#define ADDW { uint32_t res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(uint16_t)res; }
@ -101,44 +89,44 @@ typedef struct
#define XORB dst^=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
#define XORW dst^=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
#define CF (I.CarryVal!=0)
#define SF (I.SignVal<0)
#define ZF (I.ZeroVal==0)
#define PF parity_table[(uint8_t)I.ParityVal]
#define AF (I.AuxVal!=0)
#define OF (I.OverVal!=0)
#define MD (I.MF!=0)
#define CF (I.CarryVal!=0)
#define SF (I.SignVal<0)
#define ZF (I.ZeroVal==0)
#define PF parity_table[(uint8_t)I.ParityVal]
#define AF (I.AuxVal!=0)
#define OF (I.OverVal!=0)
#define MD (I.MF!=0)
/************************************************************************/
#define SegBase(Seg) (I.sregs[Seg] << 4)
#define DefaultBase(Seg) ((seg_prefix && (Seg==DS || Seg==SS)) ? (prefix_base) : (uint32_t)(I.sregs[Seg] << 4))
#define DefaultBase(Seg) ((seg_prefix && (Seg==DS || Seg==SS)) ? prefix_base : I.sregs[Seg] << 4)
#define GetMemB(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint8_t)mem_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint16_t) mem_readmem20((DefaultBase(Seg)+(Off))) + (mem_readmem20((DefaultBase(Seg)+((Off)+1)))<<8) )
#define GetMemB(Seg,Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint8_t)cpu_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg,Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint16_t) cpu_readmem20((DefaultBase(Seg)+(Off))) + (cpu_readmem20((DefaultBase(Seg)+((Off)+1)))<<8) )
#define PutMemB(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; mem_writemem20((DefaultBase(Seg)+(Off)),(x)); }
#define PutMemW(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; PutMemB(Seg,Off,(x)&0xff); PutMemB(Seg,(Off)+1,(uint8_t)((x)>>8)); }
#define PutMemB(Seg,Off,x) { /*nec_ICount-=((Off)&1)?1:0*/; cpu_writemem20((DefaultBase(Seg)+(Off)),(x)); }
#define PutMemW(Seg,Off,x) { /*nec_ICount-=((Off)&1)?1:0*/; PutMemB(Seg,Off,(x)&0xff); PutMemB(Seg,(Off)+1,(uint8_t)((x)>>8)); }
/* Todo: Remove these later - plus readword could overflow */
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (uint8_t)mem_readmem20((ea)))
#define ReadWord(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ mem_readmem20((ea))+(mem_readmem20(((ea)+1))<<8))
#define WriteByte(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; mem_writemem20((ea),val); }
#define WriteWord(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; mem_writemem20((ea),(uint8_t)(val)); mem_writemem20(((ea)+1),(val)>>8); }
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (uint8_t)cpu_readmem20((ea)))
#define ReadWord(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ cpu_readmem20((ea))+(cpu_readmem20(((ea)+1))<<8))
#define WriteByte(ea,val) { /*nec_ICount-=((ea)&1)?1:0*/; cpu_writemem20((ea),val); }
#define WriteWord(ea,val) { /*nec_ICount-=((ea)&1)?1:0*/; cpu_writemem20((ea),(uint8_t)(val)); cpu_writemem20(((ea)+1),(val)>>8); }
#define read_port(port) io_readport(port)
#define write_port(port, val) io_writeport(port,val)
#define read_port(port) cpu_readport(port)
#define write_port(port,val) cpu_writeport(port,val)
#define FETCH (mem_readop_arg((I.sregs[CS]<<4)+I.ip++))
#define FETCHOP (mem_readop((I.sregs[CS]<<4)+I.ip++))
#define FETCHWORD(var) { var=mem_readop_arg((((I.sregs[CS]<<4)+I.ip)))+(mem_readop_arg((((I.sregs[CS]<<4)+I.ip+1)))<<8); I.ip+=2; }
#define FETCH (cpu_readop_arg((I.sregs[CS]<<4)+I.ip++))
#define FETCHOP (cpu_readop((I.sregs[CS]<<4)+I.ip++))
#define FETCHWORD(var) { var=cpu_readop_arg((((I.sregs[CS]<<4)+I.ip)))+(cpu_readop_arg((((I.sregs[CS]<<4)+I.ip+1)))<<8); I.ip+=2; }
#define PUSH(val) { I.regs.w[SP]-=2; WriteWord((((I.sregs[SS]<<4)+I.regs.w[SP])),val); }
#define POP(var) { var = ReadWord((((I.sregs[SS]<<4)+I.regs.w[SP]))); I.regs.w[SP]+=2; }
#define PEEK(addr) ((uint8_t)mem_readop_arg(addr))
#define PEEKOP(addr) ((uint8_t)mem_readop(addr))
#define PEEK(addr) ((uint8_t)cpu_readop_arg(addr))
#define PEEKOP(addr) ((uint8_t)cpu_readop(addr))
#define GetModRM uint32_t ModRM=mem_readop_arg((I.sregs[CS]<<4)+I.ip++)
#define GetModRM uint32_t ModRM=cpu_readop_arg((I.sregs[CS]<<4)+I.ip++)
/* Cycle count macros:
CLK - cycle count is the same on all processors
@ -157,119 +145,121 @@ typedef struct
#define CLKM(v20,v30,v33,v20m,v30m,v33m) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33, mcount=(v20m<<16)|(v30m<<8)|v33m; nec_ICount-=( ModRM >=0xc0 )?((ccount>>cpu_type)&0x7f):((mcount>>cpu_type)&0x7f); }
#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall) { const uint32_t ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_ICount-=vall; else nec_ICount-=(I.ip&1)?((ocount>>cpu_type)&0x7f):((ecount>>cpu_type)&0x7f); }
*/
#define CLKS(v20, v30, v33) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
#define CLKS(v20,v30,v33) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
#define CLK(all) nec_ICount-=all
#define CLKW(v30MZo, v30MZe) { nec_ICount-=(I.ip&1)?v30MZo:v30MZe; }
#define CLKM(v30MZm, v30MZ) { nec_ICount-=( ModRM >=0xc0 )?v30MZ:v30MZm; }
#define CLKR(v30MZo, v30MZe, vall) { if (ModRM >=0xc0) nec_ICount-=vall; else nec_ICount-=(I.ip&1)?v30MZo:v30MZe; }
#define CLKW(v30MZo,v30MZe) { nec_ICount-=(I.ip&1)?v30MZo:v30MZe; }
#define CLKM(v30MZm,v30MZ) { nec_ICount-=( ModRM >=0xc0 )?v30MZ:v30MZm; }
#define CLKR(v30MZo,v30MZe,vall) { if (ModRM >=0xc0) nec_ICount-=vall; else nec_ICount-=(I.ip&1)?v30MZo:v30MZe; }
#define CompressFlags() (uint16_t)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
| (SF << 7) | (I.TF << 8) | (I.IF << 9) \
| (I.DF << 10) | (OF << 11))
| (SF << 7) | (I.TF << 8) | (I.IF << 9) \
| (I.DF << 10) | (OF << 11))
#define ExpandFlags(f) \
{ \
I.CarryVal = (f) & 1; \
I.ParityVal = !((f) & 4); \
I.AuxVal = (f) & 16; \
I.ZeroVal = !((f) & 64); \
I.SignVal = (f) & 128 ? -1 : 0; \
I.TF = ((f) & 256) == 256; \
I.IF = ((f) & 512) == 512; \
I.DF = ((f) & 1024) == 1024; \
I.OverVal = (f) & 2048; \
I.MF = ((f) & 0x8000) == 0x8000; \
I.CarryVal = (f) & 1; \
I.ParityVal = !((f) & 4); \
I.AuxVal = (f) & 16; \
I.ZeroVal = !((f) & 64); \
I.SignVal = (f) & 128 ? -1 : 0; \
I.TF = ((f) & 256) == 256; \
I.IF = ((f) & 512) == 512; \
I.DF = ((f) & 1024) == 1024; \
I.OverVal = (f) & 2048; \
I.MF = ((f) & 0x8000) == 0x8000; \
}
#define IncWordReg(Reg) \
uint16_t tmp = (uint16_t)I.regs.w[Reg]; \
uint16_t tmp1 = tmp+1; \
I.OverVal = (tmp == 0x7fff); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define IncWordReg(Reg) \
uint16_t tmp = (uint16_t)I.regs.w[Reg]; \
uint16_t tmp1 = tmp+1; \
I.OverVal = (tmp == 0x7fff); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define DecWordReg(Reg) \
uint16_t tmp = (uint16_t)I.regs.w[Reg]; \
uint16_t tmp1 = tmp-1; \
I.OverVal = (tmp == 0x8000); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define JMP(flag) \
int tmp = (int)((int8_t)FETCH); \
if (flag) \
{ \
I.ip = (uint16_t)(I.ip+tmp); \
nec_ICount-=3; \
return; \
#define DecWordReg(Reg) \
uint16_t tmp = (uint16_t)I.regs.w[Reg]; \
uint16_t tmp1 = tmp-1; \
I.OverVal = (tmp == 0x8000); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define JMP(flag) \
int tmp = (int)((int8_t)FETCH); \
if (flag) \
{ \
I.ip = (uint16_t)(I.ip+tmp); \
nec_ICount-=3; \
return; \
}
#define ADJ4(param1,param2) \
if (AF || ((I.regs.b[AL] & 0xf) > 9)) \
{ \
int tmp; \
I.regs.b[AL] = tmp = I.regs.b[AL] + param1; \
I.AuxVal = 1; \
} \
if (CF || (I.regs.b[AL] > 0x9f)) \
{ \
I.regs.b[AL] += param2; \
I.CarryVal = 1; \
} \
SetSZPF_Byte(I.regs.b[AL])
#define ADJB(param1,param2) \
if (AF || ((I.regs.b[AL] & 0xf) > 9)) \
{ \
I.regs.b[AL] += param1; \
I.regs.b[AH] += param2; \
I.AuxVal = 1; \
I.CarryVal = 1; \
} \
else \
{ \
I.AuxVal = 0; \
I.CarryVal = 0; \
} \
I.regs.b[AL] &= 0x0F
#define BITOP_BYTE \
ModRM = FETCH; \
if (ModRM >= 0xc0) { \
tmp=I.regs.b[Mod_RM.RM.b[ModRM]]; \
} \
else { \
(*GetEA[ModRM])(); \
tmp=ReadByte(EA); \
}
#define ADJ4(param1, param2) \
if (AF || ((I.regs.b[AL] & 0xf) > 9)) \
{ \
int tmp; \
I.regs.b[AL] = tmp = I.regs.b[AL] + param1; \
I.AuxVal = 1; \
} \
if (CF || (I.regs.b[AL] > 0x9f)) \
{ \
I.regs.b[AL] += param2; \
I.CarryVal = 1; \
} \
SetSZPF_Byte(I.regs.b[AL])
#define ADJB(param1, param2) \
if (AF || ((I.regs.b[AL] & 0xf) > 9)) \
{ \
I.regs.b[AL] += param1; \
I.regs.b[AH] += param2; \
I.AuxVal = 1; \
I.CarryVal = 1; \
} \
else \
{ \
I.AuxVal = 0; \
I.CarryVal = 0; \
} \
I.regs.b[AL] &= 0x0F
#define BITOP_BYTE \
ModRM = FETCH; \
if (ModRM >= 0xc0) { \
tmp=I.regs.b[Mod_RM.RM.b[ModRM]]; \
} \
else { \
(*GetEA[ModRM])(); \
tmp=ReadByte(EA); \
#define BITOP_WORD \
ModRM = FETCH; \
if (ModRM >= 0xc0) { \
tmp=I.regs.w[Mod_RM.RM.w[ModRM]]; \
} \
else { \
(*GetEA[ModRM])(); \
tmp=ReadWord(EA); \
}
#define BITOP_WORD \
ModRM = FETCH; \
if (ModRM >= 0xc0) { \
tmp=I.regs.w[Mod_RM.RM.w[ModRM]]; \
} \
else { \
(*GetEA[ModRM])(); \
tmp=ReadWord(EA); \
}
#define BIT_NOT \
if (tmp & (1<<tmp2)) \
tmp &= ~(1<<tmp2); \
else \
tmp |= (1<<tmp2)
#define BIT_NOT \
if (tmp & (1<<tmp2)) \
tmp &= ~(1<<tmp2); \
else \
tmp |= (1<<tmp2)
#define XchgAWReg(Reg) \
uint16_t tmp; \
tmp = I.regs.w[Reg]; \
I.regs.w[Reg] = I.regs.w[AW]; \
I.regs.w[AW] = tmp
#define XchgAWReg(Reg) \
uint16_t tmp; \
tmp = I.regs.w[Reg]; \
I.regs.w[Reg] = I.regs.w[AW]; \
I.regs.w[AW] = tmp
#define ROL_BYTE I.CarryVal = dst & 0x80; dst = (dst << 1)+CF
#define ROL_WORD I.CarryVal = dst & 0x8000; dst = (dst << 1)+CF
@ -279,126 +269,126 @@ typedef struct
#define ROLC_WORD dst = (dst << 1) + CF; SetCFW(dst)
#define RORC_BYTE dst = (CF<<8)+dst; I.CarryVal = dst & 0x01; dst >>= 1
#define RORC_WORD dst = (CF<<16)+dst; I.CarryVal = dst & 0x01; dst >>= 1
#define SHL_BYTE(c) dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHL_WORD(c) dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define SHL_BYTE(c) dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHL_WORD(c) dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define SHR_BYTE(c) dst >>= c-1; I.CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHR_WORD(c) dst >>= c-1; I.CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define SHRA_BYTE(c) dst = ((int8_t)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((int8_t)((uint8_t)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHRA_WORD(c) dst = ((int16_t)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((int16_t)((uint16_t)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define SHRA_BYTE(c) dst = ((int8_t)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((int8_t)((uint8_t)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHRA_WORD(c) dst = ((int16_t)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((int16_t)((uint16_t)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define DIVUB \
uresult = I.regs.w[AW]; \
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = uresult; \
I.regs.b[AH] = uresult2; \
}
#define DIVUB \
uresult = I.regs.w[AW]; \
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = uresult; \
I.regs.b[AH] = uresult2; \
}
#define DIVB \
result = (int16_t)I.regs.w[AW]; \
result2 = result % (int16_t)((int8_t)tmp); \
if ((result /= (int16_t)((int8_t)tmp)) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = result; \
I.regs.b[AH] = result2; \
}
#define DIVB \
result = (int16_t)I.regs.w[AW]; \
result2 = result % (int16_t)((int8_t)tmp); \
if ((result /= (int16_t)((int8_t)tmp)) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = result; \
I.regs.b[AH] = result2; \
}
#define DIVUW \
uresult = (((uint32_t)I.regs.w[DW]) << 16) | I.regs.w[AW];\
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xffff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.w[AW]=uresult; \
I.regs.w[DW]=uresult2; \
}
#define DIVUW \
uresult = (((uint32_t)I.regs.w[DW]) << 16) | I.regs.w[AW];\
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xffff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.w[AW]=uresult; \
I.regs.w[DW]=uresult2; \
}
#define DIVW \
result = ((uint32_t)I.regs.w[DW] << 16) + I.regs.w[AW]; \
result2 = result % (int32_t)((int16_t)tmp); \
if ((result /= (int32_t)((int16_t)tmp)) > 0xffff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.w[AW]=result; \
I.regs.w[DW]=result2; \
}
#define DIVW \
result = ((uint32_t)I.regs.w[DW] << 16) + I.regs.w[AW]; \
result2 = result % (int32_t)((int16_t)tmp); \
if ((result /= (int32_t)((int16_t)tmp)) > 0xffff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.w[AW]=result; \
I.regs.w[DW]=result2; \
}
#define ADD4S { \
int i,v1,v2,result; \
int count = (I.regs.b[CL]+1)/2; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(DS, si); \
tmp2 = GetMemB(ES, di); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
result = v1+v2+I.CarryVal; \
I.CarryVal = result > 99 ? 1 : 0; \
result = result % 100; \
v1 = ((result/10)<<4) | (result % 10); \
PutMemB(ES, di,v1); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
#define ADD4S { \
int i,v1,v2,result; \
int count = (I.regs.b[CL]+1)/2; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(DS, si); \
tmp2 = GetMemB(ES, di); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
result = v1+v2+I.CarryVal; \
I.CarryVal = result > 99 ? 1 : 0; \
result = result % 100; \
v1 = ((result/10)<<4) | (result % 10); \
PutMemB(ES, di,v1); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
}
#define SUB4S { \
int count = (I.regs.b[CL]+1)/2; \
int i,v1,v2,result; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(ES, di); \
tmp2 = GetMemB(DS, si); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
if (v1 < (v2+I.CarryVal)) { \
v1+=100; \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 1; \
} else { \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 0; \
} \
v1 = ((result/10)<<4) | (result % 10); \
PutMemB(ES, di,v1); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
#define SUB4S { \
int count = (I.regs.b[CL]+1)/2; \
int i,v1,v2,result; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(ES, di); \
tmp2 = GetMemB(DS, si); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
if (v1 < (v2+I.CarryVal)) { \
v1+=100; \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 1; \
} else { \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 0; \
} \
v1 = ((result/10)<<4) | (result % 10); \
PutMemB(ES, di,v1); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
}
#define CMP4S { \
int count = (I.regs.b[CL]+1)/2; \
int i,v1,v2,result; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(ES, di); \
tmp2 = GetMemB(DS, si); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
if (v1 < (v2+I.CarryVal)) { \
v1+=100; \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 1; \
} else { \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 0; \
} \
v1 = ((result/10)<<4) | (result % 10); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
#define CMP4S { \
int count = (I.regs.b[CL]+1)/2; \
int i,v1,v2,result; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(ES, di); \
tmp2 = GetMemB(DS, si); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
if (v1 < (v2+I.CarryVal)) { \
v1+=100; \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 1; \
} else { \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 0; \
} \
v1 = ((result/10)<<4) | (result % 10); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
}
#endif /* __NEC_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
/*
* NewOswan
* nec_debugger.h:
* Created by Manoël Trapier on 14/04/2021.
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
#ifndef NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H
#define NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H
int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsigned int bufferSize);
#endif /* NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H */

View File

@ -1,10 +1,3 @@
/******************************************************************************
* NewOswan
* necea.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
static uint32_t EA;
static uint16_t EO;
@ -12,206 +5,194 @@ static uint16_t E16;
static unsigned EA_000(void)
{
EO = I.regs.w[BW] + I.regs.w[IX];
EA = DefaultBase(DS) + EO;
return EA;
EO=I.regs.w[BW]+I.regs.w[IX];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_001(void)
{
EO = I.regs.w[BW] + I.regs.w[IY];
EA = DefaultBase(DS) + EO;
return EA;
EO=I.regs.w[BW]+I.regs.w[IY];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_002(void)
{
EO = I.regs.w[BP] + I.regs.w[IX];
EA = DefaultBase(SS) + EO;
return EA;
EO=I.regs.w[BP]+I.regs.w[IX];
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_003(void)
{
EO = I.regs.w[BP] + I.regs.w[IY];
EA = DefaultBase(SS) + EO;
return EA;
EO=I.regs.w[BP]+I.regs.w[IY];
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_004(void)
{
EO = I.regs.w[IX];
EA = DefaultBase(DS) + EO;
return EA;
EO=I.regs.w[IX];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_005(void)
{
EO = I.regs.w[IY];
EA = DefaultBase(DS) + EO;
return EA;
EO=I.regs.w[IY];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_006(void)
{
EO = FETCH;
EO += FETCH << 8;
EA = DefaultBase(DS) + EO;
return EA;
EO=FETCH;
EO+=FETCH<<8;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_007(void)
{
EO = I.regs.w[BW];
EA = DefaultBase(DS) + EO;
return EA;
EO=I.regs.w[BW];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_100(void)
{
EO = (I.regs.w[BW] + I.regs.w[IX] + (int8_t)FETCH);
EA = DefaultBase(DS) + EO;
return EA;
EO=(I.regs.w[BW]+I.regs.w[IX]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_101(void)
{
EO = (I.regs.w[BW] + I.regs.w[IY] + (int8_t)FETCH);
EA = DefaultBase(DS) + EO;
return EA;
EO=(I.regs.w[BW]+I.regs.w[IY]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_102(void)
{
EO = (I.regs.w[BP] + I.regs.w[IX] + (int8_t)FETCH);
EA = DefaultBase(SS) + EO;
return EA;
EO=(I.regs.w[BP]+I.regs.w[IX]+(int8_t)FETCH);
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_103(void)
{
EO = (I.regs.w[BP] + I.regs.w[IY] + (int8_t)FETCH);
EA = DefaultBase(SS) + EO;
return EA;
EO=(I.regs.w[BP]+I.regs.w[IY]+(int8_t)FETCH);
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_104(void)
{
EO = (I.regs.w[IX] + (int8_t)FETCH);
EA = DefaultBase(DS) + EO;
return EA;
EO=(I.regs.w[IX]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_105(void)
{
EO = (I.regs.w[IY] + (int8_t)FETCH);
EA = DefaultBase(DS) + EO;
return EA;
EO=(I.regs.w[IY]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_106(void)
{
EO = (I.regs.w[BP] + (int8_t)FETCH);
EA = DefaultBase(SS) + EO;
return EA;
EO=(I.regs.w[BP]+(int8_t)FETCH);
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_107(void)
{
EO = (I.regs.w[BW] + (int8_t)FETCH);
EA = DefaultBase(DS) + EO;
return EA;
EO=(I.regs.w[BW]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_200(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[BW] + I.regs.w[IX] + (int16_t)E16;
EA = DefaultBase(DS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BW]+I.regs.w[IX]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_201(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[BW] + I.regs.w[IY] + (int16_t)E16;
EA = DefaultBase(DS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BW]+I.regs.w[IY]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_202(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[BP] + I.regs.w[IX] + (int16_t)E16;
EA = DefaultBase(SS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BP]+I.regs.w[IX]+(int16_t)E16;
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_203(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[BP] + I.regs.w[IY] + (int16_t)E16;
EA = DefaultBase(SS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BP]+I.regs.w[IY]+(int16_t)E16;
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_204(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[IX] + (int16_t)E16;
EA = DefaultBase(DS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[IX]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_205(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[IY] + (int16_t)E16;
EA = DefaultBase(DS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[IY]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_206(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[BP] + (int16_t)E16;
EA = DefaultBase(SS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BP]+(int16_t)E16;
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_207(void)
{
E16 = FETCH;
E16 += FETCH << 8;
EO = I.regs.w[BW] + (int16_t)E16;
EA = DefaultBase(DS) + EO;
return EA;
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BW]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned (*GetEA[192])(void) =
{
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, EA_000, EA_001, EA_002, EA_003, EA_004, EA_005,
EA_006, EA_007, EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, EA_000, EA_001, EA_002, EA_003,
EA_004, EA_005, EA_006, EA_007, EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, EA_000, EA_001,
EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
static unsigned (*GetEA[192])(void)=
{
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, EA_100, EA_101, EA_102, EA_103, EA_104, EA_105,
EA_106, EA_107, EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, EA_100, EA_101, EA_102, EA_103,
EA_104, EA_105, EA_106, EA_107, EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, EA_100, EA_101,
EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, EA_200, EA_201, EA_202, EA_203, EA_204, EA_205,
EA_206, EA_207, EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, EA_200, EA_201, EA_202, EA_203,
EA_204, EA_205, EA_206, EA_207, EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, EA_200, EA_201,
EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207
};
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207
};

View File

@ -1,11 +1,3 @@
/******************************************************************************
* NewOswan
* necinstr.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
static void i_add_br8(void);
static void i_add_wr16(void);
static void i_add_r8b(void);
@ -255,261 +247,261 @@ static void i_ffpre(void);
static void i_wait(void);
void (*nec_instruction[256])(void) =
{
i_add_br8, /* 0x00 */
i_add_wr16, /* 0x01 */
i_add_r8b, /* 0x02 */
i_add_r16w, /* 0x03 */
i_add_ald8, /* 0x04 */
i_add_axd16, /* 0x05 */
i_push_es, /* 0x06 */
i_pop_es, /* 0x07 */
i_or_br8, /* 0x08 */
i_or_wr16, /* 0x09 */
i_or_r8b, /* 0x0a */
i_or_r16w, /* 0x0b */
i_or_ald8, /* 0x0c */
i_or_axd16, /* 0x0d */
i_push_cs, /* 0x0e */
i_pre_nec, /* 0x0f */
i_adc_br8, /* 0x10 */
i_adc_wr16, /* 0x11 */
i_adc_r8b, /* 0x12 */
i_adc_r16w, /* 0x13 */
i_adc_ald8, /* 0x14 */
i_adc_axd16, /* 0x15 */
i_push_ss, /* 0x16 */
i_pop_ss, /* 0x17 */
i_sbb_br8, /* 0x18 */
i_sbb_wr16, /* 0x19 */
i_sbb_r8b, /* 0x1a */
i_sbb_r16w, /* 0x1b */
i_sbb_ald8, /* 0x1c */
i_sbb_axd16, /* 0x1d */
i_push_ds, /* 0x1e */
i_pop_ds, /* 0x1f */
i_and_br8, /* 0x20 */
i_and_wr16, /* 0x21 */
i_and_r8b, /* 0x22 */
i_and_r16w, /* 0x23 */
i_and_ald8, /* 0x24 */
i_and_axd16, /* 0x25 */
i_es, /* 0x26 */
i_daa, /* 0x27 */
i_sub_br8, /* 0x28 */
i_sub_wr16, /* 0x29 */
i_sub_r8b, /* 0x2a */
i_sub_r16w, /* 0x2b */
i_sub_ald8, /* 0x2c */
i_sub_axd16, /* 0x2d */
i_cs, /* 0x2e */
i_das, /* 0x2f */
i_xor_br8, /* 0x30 */
i_xor_wr16, /* 0x31 */
i_xor_r8b, /* 0x32 */
i_xor_r16w, /* 0x33 */
i_xor_ald8, /* 0x34 */
i_xor_axd16, /* 0x35 */
i_ss, /* 0x36 */
i_aaa, /* 0x37 */
i_cmp_br8, /* 0x38 */
i_cmp_wr16, /* 0x39 */
i_cmp_r8b, /* 0x3a */
i_cmp_r16w, /* 0x3b */
i_cmp_ald8, /* 0x3c */
i_cmp_axd16, /* 0x3d */
i_ds, /* 0x3e */
i_aas, /* 0x3f */
i_inc_ax, /* 0x40 */
i_inc_cx, /* 0x41 */
i_inc_dx, /* 0x42 */
i_inc_bx, /* 0x43 */
i_inc_sp, /* 0x44 */
i_inc_bp, /* 0x45 */
i_inc_si, /* 0x46 */
i_inc_di, /* 0x47 */
i_dec_ax, /* 0x48 */
i_dec_cx, /* 0x49 */
i_dec_dx, /* 0x4a */
i_dec_bx, /* 0x4b */
i_dec_sp, /* 0x4c */
i_dec_bp, /* 0x4d */
i_dec_si, /* 0x4e */
i_dec_di, /* 0x4f */
i_push_ax, /* 0x50 */
i_push_cx, /* 0x51 */
i_push_dx, /* 0x52 */
i_push_bx, /* 0x53 */
i_push_sp, /* 0x54 */
i_push_bp, /* 0x55 */
i_push_si, /* 0x56 */
i_push_di, /* 0x57 */
i_pop_ax, /* 0x58 */
i_pop_cx, /* 0x59 */
i_pop_dx, /* 0x5a */
i_pop_bx, /* 0x5b */
i_pop_sp, /* 0x5c */
i_pop_bp, /* 0x5d */
i_pop_si, /* 0x5e */
i_pop_di, /* 0x5f */
i_pusha, /* 0x60 */
i_popa, /* 0x61 */
i_chkind, /* 0x62 */
i_invalid, /* 0x63 */
i_repnc, /* 0x64 */
i_repc, /* 0x65 */
i_invalid, /* 0x66 */
i_invalid, /* 0x67 */
i_push_d16, /* 0x68 */
i_imul_d16, /* 0x69 */
i_push_d8, /* 0x6a */
i_imul_d8, /* 0x6b */
i_insb, /* 0x6c */
i_insw, /* 0x6d */
i_outsb, /* 0x6e */
i_outsw, /* 0x6f */
i_jo, /* 0x70 */
i_jno, /* 0x71 */
i_jc, /* 0x72 */
i_jnc, /* 0x73 */
i_jz, /* 0x74 */
i_jnz, /* 0x75 */
i_jce, /* 0x76 */
i_jnce, /* 0x77 */
i_js, /* 0x78 */
i_jns, /* 0x79 */
i_jp, /* 0x7a */
i_jnp, /* 0x7b */
i_jl, /* 0x7c */
i_jnl, /* 0x7d */
i_jle, /* 0x7e */
i_jnle, /* 0x7f */
i_80pre, /* 0x80 */
i_81pre, /* 0x81 */
i_82pre, /* 0x82 */
i_83pre, /* 0x83 */
i_test_br8, /* 0x84 */
i_test_wr16, /* 0x85 */
i_xchg_br8, /* 0x86 */
i_xchg_wr16, /* 0x87 */
i_mov_br8, /* 0x88 */
i_mov_wr16, /* 0x89 */
i_mov_r8b, /* 0x8a */
i_mov_r16w, /* 0x8b */
i_mov_wsreg, /* 0x8c */
i_lea, /* 0x8d */
i_mov_sregw, /* 0x8e */
i_popw, /* 0x8f */
i_nop, /* 0x90 */
i_xchg_axcx, /* 0x91 */
i_xchg_axdx, /* 0x92 */
i_xchg_axbx, /* 0x93 */
i_xchg_axsp, /* 0x94 */
i_xchg_axbp, /* 0x95 */
i_xchg_axsi, /* 0x97 */
i_xchg_axdi, /* 0x97 */
i_cbw, /* 0x98 */
i_cwd, /* 0x99 */
i_call_far, /* 0x9a */
i_wait, /* 0x9b */
i_pushf, /* 0x9c */
i_popf, /* 0x9d */
i_sahf, /* 0x9e */
i_lahf, /* 0x9f */
i_mov_aldisp, /* 0xa0 */
i_mov_axdisp, /* 0xa1 */
i_mov_dispal, /* 0xa2 */
i_mov_dispax, /* 0xa3 */
i_movsb, /* 0xa4 */
i_movsw, /* 0xa5 */
i_cmpsb, /* 0xa6 */
i_cmpsw, /* 0xa7 */
i_test_ald8, /* 0xa8 */
i_test_axd16, /* 0xa9 */
i_stosb, /* 0xaa */
i_stosw, /* 0xab */
i_lodsb, /* 0xac */
i_lodsw, /* 0xad */
i_scasb, /* 0xae */
i_scasw, /* 0xaf */
i_mov_ald8, /* 0xb0 */
i_mov_cld8, /* 0xb1 */
i_mov_dld8, /* 0xb2 */
i_mov_bld8, /* 0xb3 */
i_mov_ahd8, /* 0xb4 */
i_mov_chd8, /* 0xb5 */
i_mov_dhd8, /* 0xb6 */
i_mov_bhd8, /* 0xb7 */
i_mov_axd16, /* 0xb8 */
i_mov_cxd16, /* 0xb9 */
i_mov_dxd16, /* 0xba */
i_mov_bxd16, /* 0xbb */
i_mov_spd16, /* 0xbc */
i_mov_bpd16, /* 0xbd */
i_mov_sid16, /* 0xbe */
i_mov_did16, /* 0xbf */
i_rotshft_bd8, /* 0xc0 */
i_rotshft_wd8, /* 0xc1 */
i_ret_d16, /* 0xc2 */
i_ret, /* 0xc3 */
i_les_dw, /* 0xc4 */
i_lds_dw, /* 0xc5 */
i_mov_bd8, /* 0xc6 */
i_mov_wd16, /* 0xc7 */
i_enter, /* 0xc8 */
i_leave, /* 0xc9 */
i_retf_d16, /* 0xca */
i_retf, /* 0xcb */
i_int3, /* 0xcc */
i_int, /* 0xcd */
i_into, /* 0xce */
i_iret, /* 0xcf */
i_rotshft_b, /* 0xd0 */
i_rotshft_w, /* 0xd1 */
i_rotshft_bcl, /* 0xd2 */
i_rotshft_wcl, /* 0xd3 */
i_aam, /* 0xd4 */
i_aad, /* 0xd5 */
i_setalc, /* 0xd6 */
i_trans, /* 0xd7 */
i_fpo, /* 0xd8 */
i_fpo, /* 0xd9 */
i_fpo, /* 0xda */
i_fpo, /* 0xdb */
i_fpo, /* 0xdc */
i_fpo, /* 0xdd */
i_fpo, /* 0xde */
i_fpo, /* 0xdf */
i_loopne, /* 0xe0 */
i_loope, /* 0xe1 */
i_loop, /* 0xe2 */
i_jcxz, /* 0xe3 */
i_inal, /* 0xe4 */
i_inax, /* 0xe5 */
i_outal, /* 0xe6 */
i_outax, /* 0xe7 */
i_call_d16, /* 0xe8 */
i_jmp_d16, /* 0xe9 */
i_jmp_far, /* 0xea */
i_jmp_d8, /* 0xeb */
i_inaldx, /* 0xec */
i_inaxdx, /* 0xed */
i_outdxal, /* 0xee */
i_outdxax, /* 0xef */
i_lock, /* 0xf0 */
i_invalid, /* 0xf1 */
i_repne, /* 0xf2 */
i_repe, /* 0xf3 */
i_hlt, /* 0xf4 */
i_cmc, /* 0xf5 */
i_f6pre, /* 0xf6 */
i_f7pre, /* 0xf7 */
i_clc, /* 0xf8 */
i_stc, /* 0xf9 */
i_di, /* 0xfa */
i_ei, /* 0xfb */
i_cld, /* 0xfc */
i_std, /* 0xfd */
i_fepre, /* 0xfe */
i_ffpre /* 0xff */
};
{
i_add_br8, /* 0x00 */
i_add_wr16, /* 0x01 */
i_add_r8b, /* 0x02 */
i_add_r16w, /* 0x03 */
i_add_ald8, /* 0x04 */
i_add_axd16, /* 0x05 */
i_push_es, /* 0x06 */
i_pop_es, /* 0x07 */
i_or_br8, /* 0x08 */
i_or_wr16, /* 0x09 */
i_or_r8b, /* 0x0a */
i_or_r16w, /* 0x0b */
i_or_ald8, /* 0x0c */
i_or_axd16, /* 0x0d */
i_push_cs, /* 0x0e */
i_pre_nec /* 0x0f */,
i_adc_br8, /* 0x10 */
i_adc_wr16, /* 0x11 */
i_adc_r8b, /* 0x12 */
i_adc_r16w, /* 0x13 */
i_adc_ald8, /* 0x14 */
i_adc_axd16, /* 0x15 */
i_push_ss, /* 0x16 */
i_pop_ss, /* 0x17 */
i_sbb_br8, /* 0x18 */
i_sbb_wr16, /* 0x19 */
i_sbb_r8b, /* 0x1a */
i_sbb_r16w, /* 0x1b */
i_sbb_ald8, /* 0x1c */
i_sbb_axd16, /* 0x1d */
i_push_ds, /* 0x1e */
i_pop_ds, /* 0x1f */
i_and_br8, /* 0x20 */
i_and_wr16, /* 0x21 */
i_and_r8b, /* 0x22 */
i_and_r16w, /* 0x23 */
i_and_ald8, /* 0x24 */
i_and_axd16, /* 0x25 */
i_es, /* 0x26 */
i_daa, /* 0x27 */
i_sub_br8, /* 0x28 */
i_sub_wr16, /* 0x29 */
i_sub_r8b, /* 0x2a */
i_sub_r16w, /* 0x2b */
i_sub_ald8, /* 0x2c */
i_sub_axd16, /* 0x2d */
i_cs, /* 0x2e */
i_das, /* 0x2f */
i_xor_br8, /* 0x30 */
i_xor_wr16, /* 0x31 */
i_xor_r8b, /* 0x32 */
i_xor_r16w, /* 0x33 */
i_xor_ald8, /* 0x34 */
i_xor_axd16, /* 0x35 */
i_ss, /* 0x36 */
i_aaa, /* 0x37 */
i_cmp_br8, /* 0x38 */
i_cmp_wr16, /* 0x39 */
i_cmp_r8b, /* 0x3a */
i_cmp_r16w, /* 0x3b */
i_cmp_ald8, /* 0x3c */
i_cmp_axd16, /* 0x3d */
i_ds, /* 0x3e */
i_aas, /* 0x3f */
i_inc_ax, /* 0x40 */
i_inc_cx, /* 0x41 */
i_inc_dx, /* 0x42 */
i_inc_bx, /* 0x43 */
i_inc_sp, /* 0x44 */
i_inc_bp, /* 0x45 */
i_inc_si, /* 0x46 */
i_inc_di, /* 0x47 */
i_dec_ax, /* 0x48 */
i_dec_cx, /* 0x49 */
i_dec_dx, /* 0x4a */
i_dec_bx, /* 0x4b */
i_dec_sp, /* 0x4c */
i_dec_bp, /* 0x4d */
i_dec_si, /* 0x4e */
i_dec_di, /* 0x4f */
i_push_ax, /* 0x50 */
i_push_cx, /* 0x51 */
i_push_dx, /* 0x52 */
i_push_bx, /* 0x53 */
i_push_sp, /* 0x54 */
i_push_bp, /* 0x55 */
i_push_si, /* 0x56 */
i_push_di, /* 0x57 */
i_pop_ax, /* 0x58 */
i_pop_cx, /* 0x59 */
i_pop_dx, /* 0x5a */
i_pop_bx, /* 0x5b */
i_pop_sp, /* 0x5c */
i_pop_bp, /* 0x5d */
i_pop_si, /* 0x5e */
i_pop_di, /* 0x5f */
i_pusha, /* 0x60 */
i_popa, /* 0x61 */
i_chkind, /* 0x62 */
i_invalid, /* 0x63 */
i_repnc, /* 0x64 */
i_repc, /* 0x65 */
i_invalid, /* 0x66 */
i_invalid, /* 0x67 */
i_push_d16, /* 0x68 */
i_imul_d16, /* 0x69 */
i_push_d8, /* 0x6a */
i_imul_d8, /* 0x6b */
i_insb, /* 0x6c */
i_insw, /* 0x6d */
i_outsb, /* 0x6e */
i_outsw, /* 0x6f */
i_jo, /* 0x70 */
i_jno, /* 0x71 */
i_jc, /* 0x72 */
i_jnc, /* 0x73 */
i_jz, /* 0x74 */
i_jnz, /* 0x75 */
i_jce, /* 0x76 */
i_jnce, /* 0x77 */
i_js, /* 0x78 */
i_jns, /* 0x79 */
i_jp, /* 0x7a */
i_jnp, /* 0x7b */
i_jl, /* 0x7c */
i_jnl, /* 0x7d */
i_jle, /* 0x7e */
i_jnle, /* 0x7f */
i_80pre, /* 0x80 */
i_81pre, /* 0x81 */
i_82pre, /* 0x82 */
i_83pre, /* 0x83 */
i_test_br8, /* 0x84 */
i_test_wr16, /* 0x85 */
i_xchg_br8, /* 0x86 */
i_xchg_wr16, /* 0x87 */
i_mov_br8, /* 0x88 */
i_mov_wr16, /* 0x89 */
i_mov_r8b, /* 0x8a */
i_mov_r16w, /* 0x8b */
i_mov_wsreg, /* 0x8c */
i_lea, /* 0x8d */
i_mov_sregw, /* 0x8e */
i_popw, /* 0x8f */
i_nop, /* 0x90 */
i_xchg_axcx, /* 0x91 */
i_xchg_axdx, /* 0x92 */
i_xchg_axbx, /* 0x93 */
i_xchg_axsp, /* 0x94 */
i_xchg_axbp, /* 0x95 */
i_xchg_axsi, /* 0x97 */
i_xchg_axdi, /* 0x97 */
i_cbw, /* 0x98 */
i_cwd, /* 0x99 */
i_call_far, /* 0x9a */
i_wait, /* 0x9b */
i_pushf, /* 0x9c */
i_popf, /* 0x9d */
i_sahf, /* 0x9e */
i_lahf, /* 0x9f */
i_mov_aldisp, /* 0xa0 */
i_mov_axdisp, /* 0xa1 */
i_mov_dispal, /* 0xa2 */
i_mov_dispax, /* 0xa3 */
i_movsb, /* 0xa4 */
i_movsw, /* 0xa5 */
i_cmpsb, /* 0xa6 */
i_cmpsw, /* 0xa7 */
i_test_ald8, /* 0xa8 */
i_test_axd16, /* 0xa9 */
i_stosb, /* 0xaa */
i_stosw, /* 0xab */
i_lodsb, /* 0xac */
i_lodsw, /* 0xad */
i_scasb, /* 0xae */
i_scasw, /* 0xaf */
i_mov_ald8, /* 0xb0 */
i_mov_cld8, /* 0xb1 */
i_mov_dld8, /* 0xb2 */
i_mov_bld8, /* 0xb3 */
i_mov_ahd8, /* 0xb4 */
i_mov_chd8, /* 0xb5 */
i_mov_dhd8, /* 0xb6 */
i_mov_bhd8, /* 0xb7 */
i_mov_axd16, /* 0xb8 */
i_mov_cxd16, /* 0xb9 */
i_mov_dxd16, /* 0xba */
i_mov_bxd16, /* 0xbb */
i_mov_spd16, /* 0xbc */
i_mov_bpd16, /* 0xbd */
i_mov_sid16, /* 0xbe */
i_mov_did16, /* 0xbf */
i_rotshft_bd8, /* 0xc0 */
i_rotshft_wd8, /* 0xc1 */
i_ret_d16, /* 0xc2 */
i_ret, /* 0xc3 */
i_les_dw, /* 0xc4 */
i_lds_dw, /* 0xc5 */
i_mov_bd8, /* 0xc6 */
i_mov_wd16, /* 0xc7 */
i_enter, /* 0xc8 */
i_leave, /* 0xc9 */
i_retf_d16, /* 0xca */
i_retf, /* 0xcb */
i_int3, /* 0xcc */
i_int, /* 0xcd */
i_into, /* 0xce */
i_iret, /* 0xcf */
i_rotshft_b, /* 0xd0 */
i_rotshft_w, /* 0xd1 */
i_rotshft_bcl, /* 0xd2 */
i_rotshft_wcl, /* 0xd3 */
i_aam, /* 0xd4 */
i_aad, /* 0xd5 */
i_setalc,
i_trans, /* 0xd7 */
i_fpo, /* 0xd8 */
i_fpo, /* 0xd9 */
i_fpo, /* 0xda */
i_fpo, /* 0xdb */
i_fpo, /* 0xdc */
i_fpo, /* 0xdd */
i_fpo, /* 0xde */
i_fpo, /* 0xdf */
i_loopne, /* 0xe0 */
i_loope, /* 0xe1 */
i_loop, /* 0xe2 */
i_jcxz, /* 0xe3 */
i_inal, /* 0xe4 */
i_inax, /* 0xe5 */
i_outal, /* 0xe6 */
i_outax, /* 0xe7 */
i_call_d16, /* 0xe8 */
i_jmp_d16, /* 0xe9 */
i_jmp_far, /* 0xea */
i_jmp_d8, /* 0xeb */
i_inaldx, /* 0xec */
i_inaxdx, /* 0xed */
i_outdxal, /* 0xee */
i_outdxax, /* 0xef */
i_lock, /* 0xf0 */
i_invalid, /* 0xf1 */
i_repne, /* 0xf2 */
i_repe, /* 0xf3 */
i_hlt, /* 0xf4 */
i_cmc, /* 0xf5 */
i_f6pre, /* 0xf6 */
i_f7pre, /* 0xf7 */
i_clc, /* 0xf8 */
i_stc, /* 0xf9 */
i_di, /* 0xfa */
i_ei, /* 0xfb */
i_cld, /* 0xfc */
i_std, /* 0xfd */
i_fepre, /* 0xfe */
i_ffpre /* 0xff */
};

View File

@ -1,48 +1,77 @@
/******************************************************************************
* NewOswan
* necintrf.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
/* ASG 971222 -- rewrote this interface */
#ifndef __NECITRF_H_
#define __NECITRF_H_
#include <stdint.h>
enum
{
NEC_IP = 1,
NEC_AW,
NEC_CW,
NEC_DW,
NEC_BW,
NEC_SP,
NEC_BP,
NEC_IX,
NEC_IY,
NEC_FLAGS,
NEC_ES,
NEC_CS,
NEC_SS,
NEC_DS,
NEC_VECTOR,
NEC_PENDING,
NEC_NMI_STATE,
NEC_IRQ_STATE
NEC_IP=1, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
NEC_VECTOR, NEC_PENDING, NEC_NMI_STATE, NEC_IRQ_STATE
};
/* Public variables */
extern int nec_ICount;
/* Public functions */
/*
#define v20_ICount nec_ICount
extern void v20_init(void);
extern void v20_reset(void *param);
extern void v20_exit(void);
extern int v20_execute(int cycles);
extern unsigned v20_get_context(void *dst);
extern void v20_set_context(void *src);
extern unsigned v20_get_reg(int regnum);
extern void v20_set_reg(int regnum, unsigned val);
extern void v20_set_irq_line(int irqline, int state);
extern void v20_set_irq_callback(int (*callback)(int irqline));
extern const char *v20_info(void *context, int regnum);
extern unsigned v20_dasm(char *buffer, unsigned pc);
#define v30_ICount nec_ICount
extern void v30_init(void);
extern void v30_reset(void *param);
extern void v30_exit(void);
extern int v30_execute(int cycles);
extern unsigned v30_get_context(void *dst);
extern void v30_set_context(void *src);
extern unsigned v30_get_reg(int regnum);
extern void v30_set_reg(int regnum, unsigned val);
extern void v30_set_irq_line(int irqline, int state);
extern void v30_set_irq_callback(int (*callback)(int irqline));
extern const char *v30_info(void *context, int regnum);
extern unsigned v30_dasm(char *buffer, unsigned pc);
#define v33_ICount nec_ICount
extern void v33_init(void);
extern void v33_reset(void *param);
extern void v33_exit(void);
extern int v33_execute(int cycles);
extern unsigned v33_get_context(void *dst);
extern void v33_set_context(void *src);
extern unsigned v33_get_reg(int regnum);
extern void v33_set_reg(int regnum, unsigned val);
extern void v33_set_irq_line(int irqline, int state);
extern void v33_set_irq_callback(int (*callback)(int irqline));
extern const char *v33_info(void *context, int regnum);
extern unsigned v33_dasm(char *buffer, unsigned pc);
*/
void nec_set_irq_line(int irqline, int state);
void nec_set_reg(int regnum, uint32_t val);
int nec_execute(int cycles);
unsigned nec_get_reg(int regnum);
void nec_reset(void *param);
void nec_reset (void *param);
void nec_int(uint16_t vector);
uint8_t cpu_readport(uint8_t);
void cpu_writeport(uint32_t, uint8_t);
#define cpu_readop cpu_readmem20
#define cpu_readop_arg cpu_readmem20
void cpu_writemem20(uint32_t, uint8_t);
uint8_t cpu_readmem20(uint32_t);
#endif /* __NECITRF_H_ */

View File

@ -1,115 +1,107 @@
/******************************************************************************
* NewOswan
* necmodrm.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
static struct
{
struct
{
WREGS w[256];
BREGS b[256];
} reg;
struct
{
WREGS w[256];
BREGS b[256];
} RM;
struct
{
WREGS w[256];
BREGS b[256];
} reg;
struct
{
WREGS w[256];
BREGS b[256];
} RM;
} Mod_RM;
#define RegWord(ModRM) I.regs.w[Mod_RM.reg.w[ModRM]]
#define RegByte(ModRM) I.regs.b[Mod_RM.reg.b[ModRM]]
#define GetRMWord(ModRM) \
((ModRM) >= 0xc0 ? I.regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(), ReadWord( EA ) ))
((ModRM) >= 0xc0 ? I.regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(), ReadWord( EA ) ))
#define PutbackRMWord(ModRM, val) \
{ \
if (ModRM >= 0xc0) I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
#define PutbackRMWord(ModRM,val) \
{ \
if (ModRM >= 0xc0) I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
else WriteWord(EA,val); \
}
#define GetnextRMWord ReadWord((EA&0xf0000)|((EA+2)&0xffff))
#define PutRMWord(ModRM, val) \
{ \
if (ModRM >= 0xc0) \
I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
else { \
(*GetEA[ModRM])(); \
WriteWord( EA ,val); \
} \
#define PutRMWord(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
else { \
(*GetEA[ModRM])(); \
WriteWord( EA ,val); \
} \
}
#define PutImmRMWord(ModRM) \
{ \
int16_t val; \
if (ModRM >= 0xc0) \
FETCHWORD(I.regs.w[Mod_RM.RM.w[ModRM]]) \
else { \
(*GetEA[ModRM])(); \
FETCHWORD(val) \
WriteWord( EA , val); \
} \
#define PutImmRMWord(ModRM) \
{ \
int16_t val; \
if (ModRM >= 0xc0) \
FETCHWORD(I.regs.w[Mod_RM.RM.w[ModRM]]) \
else { \
(*GetEA[ModRM])(); \
FETCHWORD(val) \
WriteWord( EA , val); \
} \
}
#define GetRMByte(ModRM) \
((ModRM) >= 0xc0 ? I.regs.b[Mod_RM.RM.b[ModRM]] : ReadByte( (*GetEA[ModRM])() ))
((ModRM) >= 0xc0 ? I.regs.b[Mod_RM.RM.b[ModRM]] : ReadByte( (*GetEA[ModRM])() ))
#define PutRMByte(ModRM, val) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
else \
WriteByte( (*GetEA[ModRM])() ,val); \
#define PutRMByte(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
else \
WriteByte( (*GetEA[ModRM])() ,val); \
}
#define PutImmRMByte(ModRM) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \
else { \
(*GetEA[ModRM])(); \
WriteByte( EA , FETCH ); \
} \
#define PutImmRMByte(ModRM) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \
else { \
(*GetEA[ModRM])(); \
WriteByte( EA , FETCH ); \
} \
}
#define PutbackRMByte(ModRM, val) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
else \
WriteByte(EA,val); \
#define PutbackRMByte(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
else \
WriteByte(EA,val); \
}
#define DEF_br8 \
uint32_t ModRM = FETCH,src,dst; \
src = RegByte(ModRM); \
#define DEF_br8 \
uint32_t ModRM = FETCH,src,dst; \
src = RegByte(ModRM); \
dst = GetRMByte(ModRM)
#define DEF_wr16 \
uint32_t ModRM = FETCH,src,dst; \
src = RegWord(ModRM); \
#define DEF_wr16 \
uint32_t ModRM = FETCH,src,dst; \
src = RegWord(ModRM); \
dst = GetRMWord(ModRM)
#define DEF_r8b \
uint32_t ModRM = FETCH,src,dst; \
dst = RegByte(ModRM); \
#define DEF_r8b \
uint32_t ModRM = FETCH,src,dst; \
dst = RegByte(ModRM); \
src = GetRMByte(ModRM)
#define DEF_r16w \
uint32_t ModRM = FETCH,src,dst; \
dst = RegWord(ModRM); \
#define DEF_r16w \
uint32_t ModRM = FETCH,src,dst; \
dst = RegWord(ModRM); \
src = GetRMWord(ModRM)
#define DEF_ald8 \
uint32_t src = FETCH; \
uint32_t dst = I.regs.b[AL]
#define DEF_ald8 \
uint32_t src = FETCH; \
uint32_t dst = I.regs.b[AL]
#define DEF_axd16 \
uint32_t src = FETCH; \
uint32_t dst = I.regs.w[AW]; \
#define DEF_axd16 \
uint32_t src = FETCH; \
uint32_t dst = I.regs.w[AW]; \
src += (FETCH << 8)

View File

@ -1,204 +0,0 @@
/*******************************************************************************
* NewOswan
* rom.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "log.h"
#include "rom.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t *ws_rom_load(char *path, uint32_t *romSize)
{
int fd;
uint8_t *ret_ptr;
struct stat FileStat;
fd = open(path, O_RDWR);
fstat(fd, &FileStat);
*romSize = FileStat.st_size;
ret_ptr = (uint8_t *)mmap(NULL, FileStat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
*romSize = 0;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
const char *eepromSizeName[] =
{
[WS_EEPROM_SIZE_NONE] = "none",
[WS_EEPROM_SIZE_1k] = "1kbits",
[WS_EEPROM_SIZE_16k] = "16kbits",
[WS_EEPROM_SIZE_8k] = "8kbits",
};
const char *sramSizeName[] =
{
[WS_SRAM_SIZE_NONE] = "none",
[WS_SRAM_SIZE_64k] = "64kbit",
[WS_SRAM_SIZE_256k] = "256kbit",
[WS_SRAM_SIZE_1M] = "1Mbits",
[WS_SRAM_SIZE_2M] = "2Mbits",
[WS_SRAM_SIZE_4M] = "4Mbits",
};
void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t romSize)
{
ws_romHeaderStruct *romHeader = ws_rom_getHeader(wsrom, romSize);
Log(TLOG_NORMAL, "rom", "developper Id 0x%.2x", romHeader->developperId);
Log(TLOG_NORMAL, "rom", "cart Id 0x%.2x", romHeader->cartId);
Log(TLOG_NORMAL, "rom", "minimum system %s", (romHeader->minimumSupportSystem == 0) ? "Wonderswan mono" : "Wonderswan color");
Log(TLOG_NORMAL, "rom", "size %i Mbits", (romSize >> 20) << 3);
Log(TLOG_NORMAL, "rom", "eeprom %s", eepromSizeName[romHeader->saveSize & 0xf]);
Log(TLOG_NORMAL, "rom", "sram %s", sramSizeName[romHeader->saveSize & 0xF0]);
Log(TLOG_NORMAL, "rom", "rtc %s", (romHeader->realtimeClock) ? "Yes" : "None");
Log(TLOG_NORMAL, "rom", "checksum 0x%.4x", romHeader->checksum);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *wsromHeader = (ws_romHeaderStruct *)(wsrom + wsromSize - sizeof(ws_romHeaderStruct));
return (wsromHeader);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *romHeader = ws_rom_getHeader(wsrom, wsromSize);
switch (romHeader->saveSize & 0x0f)
{
case WS_SRAM_SIZE_NONE:
return 0;
case WS_SRAM_SIZE_64k:
return 0x2000;
case WS_SRAM_SIZE_256k:
return 0x8000;
case WS_SRAM_SIZE_1M:
return 0x20000;
case WS_SRAM_SIZE_2M:
return 0x40000;
case WS_SRAM_SIZE_4M:
return 0x80000;
default:
Log(TLOG_PANIC, "ROM", "Invalid SRAM size (%02X)! Please check cart metadata!", romHeader->saveSize);
}
return (0);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *romHeader = ws_rom_getHeader(wsrom, wsromSize);
switch (romHeader->saveSize & 0xf0)
{
case WS_EEPROM_SIZE_NONE:
return 0;
case WS_EEPROM_SIZE_1k:
return 0x80;
case WS_EEPROM_SIZE_16k:
return 0x800;
case WS_EEPROM_SIZE_8k:
return 0x100;
default:
Log(TLOG_PANIC, "ROM", "Invalid SRAM size (%02X)! Please check cart metadata!", romHeader->saveSize);
}
return (0);
}

214
source/rom.cpp Normal file
View File

@ -0,0 +1,214 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "log.h"
#include "rom.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t *ws_rom_load(char *path, uint32_t *romSize)
{
int fd;
uint8_t *ret_ptr;
struct stat FileStat;
fd = open(path, O_RDWR);
fstat(fd, &FileStat);
*romSize = FileStat.st_size;
ret_ptr = (uint8_t *)mmap(NULL, FileStat.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
*romSize = 0;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t romSize)
{
ws_romHeaderStruct *romHeader=ws_rom_getHeader(wsrom,romSize);
fprintf(log_get(),"rom: developper Id 0x%.2x\n",romHeader->developperId);
fprintf(log_get(),"rom: cart Id 0x%.2x\n",romHeader->cartId);
fprintf(log_get(),"rom: minimum system %s\n",(romHeader->minimumSupportSystem==WS_SYSTEM_MONO)?"Wonderswan mono":"Wonderswan color");
fprintf(log_get(),"rom: size %i Mbits\n",(romSize>>20)<<3);
fprintf(log_get(),"rom: eeprom ");
switch (romHeader->eepromSize&0xf)
{
case WS_EEPROM_SIZE_NONE:
{
fprintf(log_get(),"none\n");
break;
}
case WS_EEPROM_SIZE_64k:
{
fprintf(log_get(),"64 kb\n");
break;
}
case WS_EEPROM_SIZE_256k:
{
fprintf(log_get(),"256 kb\n");
break;
}
}
fprintf(log_get(),"rom: sram ");
switch (romHeader->eepromSize&0xf0)
{
case WS_SRAM_SIZE_NONE:
{
fprintf(log_get(),"none\n");
break;
}
case WS_SRAM_SIZE_1k:
{
fprintf(log_get(),"1 kb\n");
break;
}
case WS_SRAM_SIZE_16k:
{
fprintf(log_get(),"16 kb\n");
break;
}
case WS_SRAM_SIZE_8k:
{
fprintf(log_get(),"8 kn\n");
break;
}
}
fprintf(log_get(),"rom: rtc %s\n",(romHeader->realtimeClock)?"Yes":"None");
fprintf(log_get(),"checksum 0x%.4x\n",romHeader->checksum);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *wsromHeader = (ws_romHeaderStruct *)(wsrom + wsromSize - 10);
return(wsromHeader);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *romHeader=ws_rom_getHeader(wsrom,wsromSize);
switch (romHeader->eepromSize&0xf0)
{
case WS_SRAM_SIZE_NONE:
return(0);
case WS_SRAM_SIZE_1k:
return(0x400);
case WS_SRAM_SIZE_16k:
return(0x4000);
case WS_SRAM_SIZE_8k:
return(0x2000);
}
return(0);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *romHeader=ws_rom_getHeader(wsrom,wsromSize);
switch (romHeader->eepromSize&0xf)
{
case WS_EEPROM_SIZE_NONE:
return(0);
case WS_EEPROM_SIZE_64k:
return(0x10000);
case WS_EEPROM_SIZE_256k:
return(0x40000);
}
return(0);
}

View File

@ -1,11 +1,5 @@
/*******************************************************************************
* NewOswan
* rom.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
@ -18,61 +12,46 @@
#ifndef __ROM_H__
#define __ROM_H__
#include <stdint.h>
#define WS_SYSTEM_MONO 0
#define WS_SYSTEM_COLOR 1
#define WS_ROM_SIZE_2MBIT 1
#define WS_ROM_SIZE_4MBIT 2
#define WS_ROM_SIZE_8MBIT 3
#define WS_ROM_SIZE_16MBIT 4
#define WS_ROM_SIZE_24MBIT 5
#define WS_ROM_SIZE_32MBIT 6
#define WS_ROM_SIZE_48MBIT 7
#define WS_ROM_SIZE_64MBIT 8
#define WS_ROM_SIZE_128MBIT 9
#define WS_ROM_SIZE_2MBIT 1
#define WS_ROM_SIZE_4MBIT 2
#define WS_ROM_SIZE_8MBIT 3
#define WS_ROM_SIZE_16MBIT 4
#define WS_ROM_SIZE_24MBIT 5
#define WS_ROM_SIZE_32MBIT 6
#define WS_ROM_SIZE_48MBIT 7
#define WS_ROM_SIZE_64MBIT 8
#define WS_ROM_SIZE_128MBIT 9
#define WS_EEPROM_SIZE_NONE 0
#define WS_EEPROM_SIZE_1k 0x10
#define WS_EEPROM_SIZE_16k 0x20
#define WS_EEPROM_SIZE_32k 0x30
/* 40 is not valid */
#define WS_EEPROM_SIZE_8k 0x50
#define WS_EEPROM_SIZE_4k 0x60
#define WS_EEPROM_SIZE_2k 0x70
#define WS_EEPROM_SIZE_NONE 0
#define WS_SRAM_SIZE_NONE 0
#define WS_EEPROM_SIZE_64k 1
#define WS_EEPROM_SIZE_256k 2
#define WS_SRAM_SIZE_1k 10
#define WS_SRAM_SIZE_16k 20
#define WS_SRAM_SIZE_8k 50
#define WS_SRAM_SIZE_NONE 0
#define WS_SRAM_SIZE_64k 0x01
#define WS_SRAM_SIZE_256k 0x02
#define WS_SRAM_SIZE_1M 0x03
#define WS_SRAM_SIZE_2M 0x04
#define WS_SRAM_SIZE_4M 0x05
#pragma pack(1)
typedef struct ws_romHeaderStruct
{
/* Miss "Fixed Data" (F5h) */
uint8_t developperId; /* Maker Code L */
uint8_t minimumSupportSystem; /* Maker Code H */
uint8_t cartId; /* Title code */
uint8_t gameVersion; /* Version */
uint8_t romSize; /* ROM Size */
uint8_t saveSize; /* XROM/XEROM Size */
uint8_t cartFlags; /* Boot loader */
uint8_t realtimeClock; /* Syb System LSI */
uint16_t checksum; /* Checksum */
uint8_t developperId;
uint8_t minimumSupportSystem;
uint8_t cartId;
uint8_t romSize;
uint8_t eepromSize;
uint8_t additionnalCapabilities;
uint8_t realtimeClock;
uint16_t checksum;
} ws_romHeaderStruct;
#pragma pack()
uint8_t *ws_rom_load(char *path, uint32_t *romSize);
void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t wsromSize);
ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize);
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize);
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize);
static inline uint8_t *ws_get_page_ptr(uint8_t *wsrom, uint32_t romSize, uint16_t page)
{
uint32_t temp = page << 16;
temp &= (romSize - 1);
return &wsrom[temp];
}
uint8_t *ws_rom_load(char *path, uint32_t *romSize);
void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t wsromSize);
ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize);
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize);
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize);
#endif

View File

@ -1,505 +0,0 @@
/*******************************************************************************
* NewOswan
* ws.c: Base wonderswan implementation
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
// 07.04.2002: speed problems partially fixed
// 13.04.2002: Set cycles by line to 256 (according to toshi)
// this seems to work well in most situations with
// the new nec v30 cpu core
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "./nec/necintrf.h"
#include "memory.h"
#include "gpu.h"
#include "io.h"
#include "audio.h"
#include "ws.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_cycles;
uint32_t ws_skip;
uint32_t ws_cyclesByLine = 0;
uint32_t vblank_count = 0;
char *ws_sram_path = NULL;
char *ws_ieep_path = NULL;
char *ws_rom_path = NULL;
wssystem_t systemType;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_patchRom(void)
{
uint8_t *rom = memory_getRom();
uint32_t romSize = memory_getRomSize();
Log(TLOG_DEBUG, "ws", "developper Id: 0x%.2x", rom[romSize - 10]);
Log(TLOG_DEBUG, "ws", "Game Id: 0x%.2x", rom[romSize - 8]);
if (!ws_cyclesByLine)
{
ws_cyclesByLine = 256;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_init(char *rompath)
{
uint8_t *rom;
uint32_t romSize;
if ((rom = ws_rom_load(rompath, &romSize)) == NULL)
{
Log(TLOG_PANIC, "ws", "Error: cannot load %s", rompath);
return (0);
}
ws_staticRam = (uint8_t *)load_file(ws_sram_path);
if (ws_staticRam == NULL)
{
ws_staticRam = (uint8_t *)create_file(ws_sram_path, 0x10000);
}
if (ws_staticRam == NULL)
{
Log(TLOG_PANIC, "ws", "Card SRAM load error!\n");
return 0;
}
externalEeprom = (uint8_t *)load_file(ws_ieep_path);
if (externalEeprom == NULL)
{
externalEeprom = (uint8_t *)create_file(ws_ieep_path, 0x100000);
}
if (externalEeprom == NULL)
{
Log(TLOG_PANIC, "ws", "Card EEPROM load error!\n");
return 0;
}
ws_memory_init(rom, romSize);
ws_patchRom();
io_init();
ws_audio_init();
ws_gpu_init();
if (ws_rotated())
{
io_flipControls();
}
return (1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_reset(void)
{
ws_memory_reset();
io_reset();
ws_audio_reset();
ws_gpu_reset();
nec_reset(NULL);
nec_set_reg(NEC_SP, 0x2000);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_executeLine(int16_t *framebuffer, int renderLine)
{
int drawWholeScreen = 0;
ws_audio_process();
// 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));
if (ws_cycles >= ws_cyclesByLine + ws_cyclesByLine)
{
ws_skip = ws_cycles / ws_cyclesByLine;
}
else
{
ws_skip = 1;
}
ws_cycles %= ws_cyclesByLine;
for (uint32_t uI = 0 ; uI < ws_skip ; uI++)
{
if (renderLine)
{
ws_gpu_renderScanline(framebuffer);
}
ws_gpu_scanline++;
if (ws_gpu_scanline == 144)
{
drawWholeScreen = 1;
}
}
if (ws_gpu_scanline > 158)
{
ws_gpu_scanline = 0;
{
if ((ws_ioRam[0xb2] & 32)) /* VBLANK Timer */
{
/* TODO: REPAIR THAT SHIT */
ws_ioRam[0xb6] &= ~32;
nec_int((ws_ioRam[0xb0] + 5) * 4);
}
}
}
ws_ioRam[2] = ws_gpu_scanline;
if (drawWholeScreen)
{
if (ws_ioRam[0xb2] & 64) /* VBLANK INT */
{
ws_ioRam[0xb6] &= ~64;
nec_int((ws_ioRam[0xb0] + 6) * 4);
}
vblank_count++;
}
if (ws_ioRam[0xa4] && (ws_ioRam[0xb2] & 128)) /*HBLANK TMR*/
{
/* TODO: Check that shit */
if (!ws_ioRam[0xa5])
{
ws_ioRam[0xa5] = ws_ioRam[0xa4];
}
if (ws_ioRam[0xa5])
{
ws_ioRam[0xa5]--;
}
if ((!ws_ioRam[0xa5]) && (ws_ioRam[0xb2] & 128))
{
ws_ioRam[0xb6] &= ~128;
nec_int((ws_ioRam[0xb0] + 7) * 4);
}
}
if ((ws_ioRam[0x2] == ws_ioRam[0x3]) && (ws_ioRam[0xb2] & 16)) /*SCANLINE INT*/
{
ws_ioRam[0xb6] &= ~16;
nec_int((ws_ioRam[0xb0] + 4) * 4);
}
return (drawWholeScreen);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_done(void)
{
ws_memory_done();
io_done();
ws_audio_done();
ws_gpu_done();
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_set_system(wssystem_t system)
{
if (system == WS_SYSTEM_AUTODETECT)
{
system = WS_SYSTEM_CRYSTAL;
}
systemType = system;
}
wssystem_t ws_get_system()
{
return systemType;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define MacroLoadNecRegisterFromFile(F, R) \
read(fp,&value,sizeof(value)); \
nec_set_reg(R,value);
int ws_loadState(char *statepath)
{
Log(TLOG_NORMAL, "ws", "loading %s\n", statepath);
uint16_t crc = memory_getRomCrc();
uint16_t newCrc;
unsigned value;
uint8_t ws_newVideoMode;
int fp = open(statepath, O_RDONLY);
if (fp == -1)
{
return (0);
}
read(fp, &newCrc, 2);
if (newCrc != crc)
{
return (-1);
}
MacroLoadNecRegisterFromFile(fp, NEC_IP);
MacroLoadNecRegisterFromFile(fp, NEC_AW);
MacroLoadNecRegisterFromFile(fp, NEC_BW);
MacroLoadNecRegisterFromFile(fp, NEC_CW);
MacroLoadNecRegisterFromFile(fp, NEC_DW);
MacroLoadNecRegisterFromFile(fp, NEC_CS);
MacroLoadNecRegisterFromFile(fp, NEC_DS);
MacroLoadNecRegisterFromFile(fp, NEC_ES);
MacroLoadNecRegisterFromFile(fp, NEC_SS);
MacroLoadNecRegisterFromFile(fp, NEC_IX);
MacroLoadNecRegisterFromFile(fp, NEC_IY);
MacroLoadNecRegisterFromFile(fp, NEC_BP);
MacroLoadNecRegisterFromFile(fp, NEC_SP);
MacroLoadNecRegisterFromFile(fp, NEC_FLAGS);
MacroLoadNecRegisterFromFile(fp, NEC_VECTOR);
MacroLoadNecRegisterFromFile(fp, NEC_PENDING);
MacroLoadNecRegisterFromFile(fp, NEC_NMI_STATE);
MacroLoadNecRegisterFromFile(fp, NEC_IRQ_STATE);
read(fp, internalRam, 65536);
read(fp, ws_staticRam, 65536);
read(fp, ws_ioRam, 256);
read(fp, ws_paletteColors, 8);
read(fp, ws_palette, 16 * 4 * 2);
read(fp, wsc_palette, 16 * 16 * 2);
read(fp, &ws_newVideoMode, 1);
read(fp, &ws_gpu_scanline, 1);
read(fp, externalEeprom, 131072);
ws_audio_readState(fp);
close(fp);
// force a video mode change to make all tiles dirty
ws_gpu_clearCache();
return (1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define MacroStoreNecRegisterToFile(F, R) \
value=nec_get_reg(R); \
write(fp,&value,sizeof(value));
int ws_saveState(char *statepath)
{
uint16_t crc = memory_getRomCrc();
uint32_t value;
char newPath[1024];
Log(TLOG_DEBUG, "ws", "saving %s\n", statepath);
if (strlen(statepath) < 4)
{
sprintf(newPath, "%s.wss", statepath);
}
else
{
int len = strlen(statepath);
if ((statepath[len - 1] != 's') && (statepath[len - 1] != 'S'))
{
sprintf(newPath, "%s.wss", statepath);
}
else if ((statepath[len - 2] != 's') && (statepath[len - 2] != 'S'))
{
sprintf(newPath, "%s.wss", statepath);
}
else if ((statepath[len - 3] != 'w') && (statepath[len - 3] != 'w'))
{
sprintf(newPath, "%s.wss", statepath);
}
else if (statepath[len - 4] != '.')
{
sprintf(newPath, "%s.wss", statepath);
}
else
{
sprintf(newPath, "%s", statepath);
}
}
int fp = open(newPath, O_RDWR | O_CREAT, 0644);
if (fp == -1)
{
return (0);
}
write(fp, &crc, 2);
MacroStoreNecRegisterToFile(fp, NEC_IP);
MacroStoreNecRegisterToFile(fp, NEC_AW);
MacroStoreNecRegisterToFile(fp, NEC_BW);
MacroStoreNecRegisterToFile(fp, NEC_CW);
MacroStoreNecRegisterToFile(fp, NEC_DW);
MacroStoreNecRegisterToFile(fp, NEC_CS);
MacroStoreNecRegisterToFile(fp, NEC_DS);
MacroStoreNecRegisterToFile(fp, NEC_ES);
MacroStoreNecRegisterToFile(fp, NEC_SS);
MacroStoreNecRegisterToFile(fp, NEC_IX);
MacroStoreNecRegisterToFile(fp, NEC_IY);
MacroStoreNecRegisterToFile(fp, NEC_BP);
MacroStoreNecRegisterToFile(fp, NEC_SP);
MacroStoreNecRegisterToFile(fp, NEC_FLAGS);
MacroStoreNecRegisterToFile(fp, NEC_VECTOR);
MacroStoreNecRegisterToFile(fp, NEC_PENDING);
MacroStoreNecRegisterToFile(fp, NEC_NMI_STATE);
MacroStoreNecRegisterToFile(fp, NEC_IRQ_STATE);
write(fp, internalRam, 65536);
write(fp, ws_staticRam, 65536);
write(fp, ws_ioRam, 256);
write(fp, ws_paletteColors, 8);
write(fp, ws_palette, 16 * 4 * 2);
write(fp, wsc_palette, 16 * 16 * 2);
write(fp, &ws_videoMode, 1);
write(fp, &ws_gpu_scanline, 1);
write(fp, externalEeprom, 131072);
ws_audio_writeState(fp);
close(fp);
return (1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_rotated(void)
{
uint8_t *rom = memory_getRom();
uint32_t romSize = memory_getRomSize();
return (rom[romSize - 4] & 1);
}

523
source/ws.cpp Normal file
View File

@ -0,0 +1,523 @@
////////////////////////////////////////////////////////////////////////////////
// Wonderswan emulator
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
// 07.04.2002: speed problems partially fixed
// 13.04.2002: Set cycles by line to 256 (according to toshi)
// this seems to work well in most situations with
// the new nec v30 cpu core
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "./nec/necintrf.h"
#include "memory.h"
#include "gpu.h"
#include "io.h"
#include "audio.h"
#include "ws.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_cycles;
uint32_t ws_skip;
uint32_t ws_cyclesByLine=0;
uint32_t vblank_count=0;
char *ws_sram_path = NULL;
char *ws_ieep_path = NULL;
char *ws_rom_path = NULL;
extern int ws_gpu_forceColorSystemBool;
extern int ws_gpu_forceMonoSystemBool;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_patchRom(void)
{
uint8_t *rom=memory_getRom();
uint32_t romSize=memory_getRomSize();
fprintf(log_get(),"developper Id: 0x%.2x\nGame Id: 0x%.2x\n",rom[romSize-10],rom[romSize-8]);
if (!ws_cyclesByLine)
{
ws_cyclesByLine=256;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_init(char *rompath)
{
uint8_t *rom;
uint32_t romSize;
if ((rom=ws_rom_load(rompath,&romSize))==NULL)
{
printf("Error: cannot load %s\n",rompath);
return(0);
}
if ((ws_gpu_forceColorSystemBool == 0) && (ws_gpu_forceMonoSystemBool == 0))
{
/* Nothing forced try to "auto detect" */
if (rompath[strlen(rompath)-1]=='c')
{
ws_gpu_operatingInColor=1;
}
else
{
ws_gpu_operatingInColor=0;
}
}
ws_memory_init(rom, romSize);
ws_patchRom();
ws_staticRam = (uint8_t *)load_file(ws_ieep_path);
if (ws_staticRam == NULL)
{
ws_staticRam = (uint8_t *)create_file(ws_sram_path, 0x10000);
}
if (ws_staticRam == NULL)
{
printf("Card SRAM load error!\n");
return 0;
}
externalEeprom = (uint8_t *)load_file(ws_ieep_path);
if (externalEeprom == NULL)
{
externalEeprom = (uint8_t *)create_file(ws_ieep_path, 0x100000);
}
if (externalEeprom == NULL)
{
printf("Card EEPROM load error!\n");
return 0;
}
ws_io_init();
ws_audio_init();
ws_gpu_init();
if (ws_rotated())
{
ws_io_flipControls();
}
return(1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_reset(void)
{
ws_memory_reset();
ws_io_reset();
ws_audio_reset();
ws_gpu_reset();
nec_reset(NULL);
nec_set_reg(NEC_SP,0x2000);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_executeLine(int16_t *framebuffer, int renderLine)
{
int drawWholeScreen=0;
ws_audio_process();
// 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));
if(ws_cycles>=ws_cyclesByLine+ws_cyclesByLine)
{
ws_skip=ws_cycles/ws_cyclesByLine;
}
else
{
ws_skip=1;
}
ws_cycles%=ws_cyclesByLine;
for(uint32_t uI=0; uI<ws_skip; uI++)
{
if (renderLine)
{
ws_gpu_renderScanline(framebuffer);
}
ws_gpu_scanline++;
if(ws_gpu_scanline==144)
{
drawWholeScreen=1;
}
}
if(ws_gpu_scanline>158)
{
ws_gpu_scanline=0;
{
if((ws_ioRam[0xb2]&32)) /* VBLANK Timer */
{
/* TODO: REPAIR THAT SHIT */
ws_ioRam[0xb6]&=~32;
nec_int((ws_ioRam[0xb0]+5)*4);
}
}
}
ws_ioRam[2]=ws_gpu_scanline;
if(drawWholeScreen)
{
if(ws_ioRam[0xb2]&64) /* VBLANK INT */
{
ws_ioRam[0xb6]&=~64;
nec_int((ws_ioRam[0xb0]+6)*4);
}
vblank_count++;
}
if(ws_ioRam[0xa4]&&(ws_ioRam[0xb2]&128)) /*HBLANK TMR*/
{
/* TODO: Check that shit */
if(!ws_ioRam[0xa5])
{
ws_ioRam[0xa5]=ws_ioRam[0xa4];
}
if(ws_ioRam[0xa5])
{
ws_ioRam[0xa5]--;
}
if((!ws_ioRam[0xa5])&&(ws_ioRam[0xb2]&128))
{
ws_ioRam[0xb6]&=~128;
nec_int((ws_ioRam[0xb0]+7)*4);
}
}
if((ws_ioRam[0x2]==ws_ioRam[0x3])&&(ws_ioRam[0xb2]&16)) /*SCANLINE INT*/
{
ws_ioRam[0xb6]&=~16;
nec_int((ws_ioRam[0xb0]+4)*4);
}
return(drawWholeScreen);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_done(void)
{
ws_memory_done();
ws_io_done();
ws_audio_done();
ws_gpu_done();
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_set_colour_scheme(int scheme)
{
ws_gpu_set_colour_scheme(scheme);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_set_system(int system)
{
if (system==WS_SYSTEM_COLOR)
{
ws_gpu_forceColorSystem();
}
else if (system==WS_SYSTEM_MONO)
{
ws_gpu_forceMonoSystem();
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define MacroLoadNecRegisterFromFile(F,R) \
read(fp,&value,sizeof(value)); \
nec_set_reg(R,value);
int ws_loadState(char *statepath)
{
fprintf(log_get(),"loading %s\n",statepath);
uint16_t crc=memory_getRomCrc();
uint16_t newCrc;
unsigned value;
uint8_t ws_newVideoMode;
int fp = open(statepath, O_RDONLY);
if (fp == -1)
{
return(0);
}
read(fp, &newCrc, 2);
if (newCrc!=crc)
{
return(-1);
}
MacroLoadNecRegisterFromFile(fp,NEC_IP);
MacroLoadNecRegisterFromFile(fp,NEC_AW);
MacroLoadNecRegisterFromFile(fp,NEC_BW);
MacroLoadNecRegisterFromFile(fp,NEC_CW);
MacroLoadNecRegisterFromFile(fp,NEC_DW);
MacroLoadNecRegisterFromFile(fp,NEC_CS);
MacroLoadNecRegisterFromFile(fp,NEC_DS);
MacroLoadNecRegisterFromFile(fp,NEC_ES);
MacroLoadNecRegisterFromFile(fp,NEC_SS);
MacroLoadNecRegisterFromFile(fp,NEC_IX);
MacroLoadNecRegisterFromFile(fp,NEC_IY);
MacroLoadNecRegisterFromFile(fp,NEC_BP);
MacroLoadNecRegisterFromFile(fp,NEC_SP);
MacroLoadNecRegisterFromFile(fp,NEC_FLAGS);
MacroLoadNecRegisterFromFile(fp,NEC_VECTOR);
MacroLoadNecRegisterFromFile(fp,NEC_PENDING);
MacroLoadNecRegisterFromFile(fp,NEC_NMI_STATE);
MacroLoadNecRegisterFromFile(fp,NEC_IRQ_STATE);
read(fp,internalRam,65536);
read(fp,ws_staticRam,65536);
read(fp,ws_ioRam,256);
read(fp,ws_paletteColors,8);
read(fp,ws_palette,16*4*2);
read(fp,wsc_palette,16*16*2);
read(fp,&ws_newVideoMode,1);
read(fp,&ws_gpu_scanline,1);
read(fp,externalEeprom,131072);
ws_audio_readState(fp);
close(fp);
// force a video mode change to make all tiles dirty
ws_gpu_clearCache();
return(1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define MacroStoreNecRegisterToFile(F,R) \
value=nec_get_reg(R); \
write(fp,&value,sizeof(value));
int ws_saveState(char *statepath)
{
uint16_t crc=memory_getRomCrc();
uint32_t value;
char *newPath;
fprintf(log_get(),"saving %s\n",statepath);
newPath=new char[1024];
if (strlen(statepath)<4)
{
sprintf(newPath,"%s.wss",statepath);
}
else
{
int len=strlen(statepath);
if ((statepath[len-1]!='s')&&(statepath[len-1]!='S'))
{
sprintf(newPath,"%s.wss",statepath);
}
else if ((statepath[len-2]!='s')&&(statepath[len-2]!='S'))
{
sprintf(newPath,"%s.wss",statepath);
}
else if ((statepath[len-3]!='w')&&(statepath[len-3]!='w'))
{
sprintf(newPath,"%s.wss",statepath);
}
else if (statepath[len-4]!='.')
{
sprintf(newPath,"%s.wss",statepath);
}
else
{
sprintf(newPath,"%s",statepath);
}
}
int fp=open(newPath, O_RDWR|O_CREAT, 0644);
delete newPath;
if (fp==-1)
{
return(0);
}
write(fp,&crc,2);
MacroStoreNecRegisterToFile(fp,NEC_IP);
MacroStoreNecRegisterToFile(fp,NEC_AW);
MacroStoreNecRegisterToFile(fp,NEC_BW);
MacroStoreNecRegisterToFile(fp,NEC_CW);
MacroStoreNecRegisterToFile(fp,NEC_DW);
MacroStoreNecRegisterToFile(fp,NEC_CS);
MacroStoreNecRegisterToFile(fp,NEC_DS);
MacroStoreNecRegisterToFile(fp,NEC_ES);
MacroStoreNecRegisterToFile(fp,NEC_SS);
MacroStoreNecRegisterToFile(fp,NEC_IX);
MacroStoreNecRegisterToFile(fp,NEC_IY);
MacroStoreNecRegisterToFile(fp,NEC_BP);
MacroStoreNecRegisterToFile(fp,NEC_SP);
MacroStoreNecRegisterToFile(fp,NEC_FLAGS);
MacroStoreNecRegisterToFile(fp,NEC_VECTOR);
MacroStoreNecRegisterToFile(fp,NEC_PENDING);
MacroStoreNecRegisterToFile(fp,NEC_NMI_STATE);
MacroStoreNecRegisterToFile(fp,NEC_IRQ_STATE);
write(fp,internalRam,65536);
write(fp,ws_staticRam,65536);
write(fp,ws_ioRam,256);
write(fp,ws_paletteColors,8);
write(fp,ws_palette,16*4*2);
write(fp,wsc_palette,16*16*2);
write(fp,&ws_videoMode,1);
write(fp,&ws_gpu_scanline,1);
write(fp,externalEeprom,131072);
ws_audio_writeState(fp);
close(fp);
return(1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_rotated(void)
{
uint8_t *rom=memory_getRom();
uint32_t romSize=memory_getRomSize();
return(rom[romSize-4]&1);
}

View File

@ -1,11 +1,5 @@
/*******************************************************************************
* NewOswan
* ws.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
@ -18,25 +12,22 @@
#ifndef __WS_H__
#define __WS_H__
#include <stdint.h>
#define WS_SYSTEM_MONO 0
#define WS_SYSTEM_COLOR 1
#define WS_SYSTEM_AUTODETECT 2
typedef enum wssystem_t
{
WS_SYSTEM_AUTODETECT = 0, WS_SYSTEM_MONO, WS_SYSTEM_COLOR, WS_SYSTEM_CRYSTAL,
} wssystem_t;
extern uint32_t ws_cyclesByLine;
extern uint32_t ws_cyclesByLine;
int ws_init(char *rompath);
int ws_rotated(void);
void ws_set_system(wssystem_t system);
wssystem_t ws_get_system();
void ws_reset(void);
int ws_executeLine(int16_t *framebuffer, int renderLine);
void ws_patchRom(void);
int ws_loadState(char *statepath);
int ws_saveState(char *statepath);
void ws_done(void);
int ws_init(char *rompath);
int ws_rotated(void);
void ws_set_colour_scheme(int scheme);
void ws_set_system(int system);
void ws_reset(void);
int ws_executeLine(int16_t *framebuffer, int renderLine);
void ws_patchRom(void);
int ws_loadState(char *statepath);
int ws_saveState(char *statepath);
void ws_done(void);
extern char *ws_sram_path;
extern char *ws_ieep_path;

View File

@ -1,11 +1,3 @@
/******************************************************************************
* NewOswan
* testserial.c: A simple tool to test serial in/out
*
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -15,10 +7,6 @@
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
/*
* The code, as is, was part of a fuzzer for the WonderSwan Tetris game.
*/
/* Serial port */
#define BDR_9600 (0)
#define BDR_38400 (1)