Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61937a1391 | ||
|
|
778c624664 |
38
.github/workflows/cmake.yml
vendored
38
.github/workflows/cmake.yml
vendored
@@ -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}}
|
|
||||||
|
|
||||||
62
.github/workflows/codeql-analysis.yml
vendored
62
.github/workflows/codeql-analysis.yml
vendored
@@ -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
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,7 +8,6 @@
|
|||||||
*.orig
|
*.orig
|
||||||
*.rej
|
*.rej
|
||||||
rom/
|
rom/
|
||||||
ROMs/
|
|
||||||
.idea/
|
.idea/
|
||||||
*.zip
|
*.zip
|
||||||
*.sav
|
*.sav
|
||||||
|
|||||||
71
.travis.yml
71
.travis.yml
@@ -1,63 +1,38 @@
|
|||||||
|
dist: bionic
|
||||||
language: c
|
language: c
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
# - osx
|
||||||
|
#matrix:
|
||||||
|
# allow_failures:
|
||||||
|
# - os: osx
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- xorg-dev
|
- libsdl1.2debian
|
||||||
- libglu1-mesa-dev
|
- libsdl1.2-dev
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- clang
|
||||||
|
- gcc
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- make
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake ..
|
- cmake ..
|
||||||
- make
|
- make
|
||||||
|
|
||||||
jobs:
|
cache:
|
||||||
include:
|
directories:
|
||||||
- os: linux
|
- '$HOME/.sonar/cache'
|
||||||
dist: bionic
|
|
||||||
arch: amd64
|
|
||||||
compiler: gcc
|
|
||||||
|
|
||||||
- os: linux
|
#before_install:
|
||||||
dist: bionic
|
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||||
arch: amd64
|
# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install glew; fi
|
||||||
compiler: clang
|
|
||||||
|
|
||||||
- os: linux
|
#install: true
|
||||||
dist: focal
|
|
||||||
arch: amd64
|
|
||||||
compiler: gcc
|
|
||||||
|
|
||||||
- os: linux
|
#after_success:
|
||||||
dist: focal
|
# - bash <(curl -s https://codecov.io/bash)
|
||||||
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
|
|
||||||
|
|||||||
@@ -29,23 +29,15 @@ set(CMAKE_CXX_FLAGS ${COMP_FLAGS})
|
|||||||
|
|
||||||
message("-- Building version ${VERSION}")
|
message("-- Building version ${VERSION}")
|
||||||
|
|
||||||
add_executable(wonderswan main.c)
|
add_executable(wonderswan main.cpp)
|
||||||
|
|
||||||
set_property(TARGET wonderswan PROPERTY CXX_STANDARD 98)
|
set_property(TARGET wonderswan PROPERTY CXX_STANDARD 98)
|
||||||
|
|
||||||
target_compile_definitions(wonderswan PUBLIC VERSION="${VERSION}")
|
target_compile_definitions(wonderswan PUBLIC VERSION="${VERSION}")
|
||||||
target_include_directories(wonderswan PUBLIC source)
|
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)
|
add_subdirectory(source)
|
||||||
|
|
||||||
target_link_libraries(wonderswan wswan glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
|
target_link_libraries(wonderswan wswan glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
|
||||||
|
|
||||||
add_executable(dumpinfo dumpinfo.c)
|
add_executable(dumpinfo dumpinfo.c)
|
||||||
add_executable(testserial testserial.c)
|
|
||||||
57
Makefile
Normal file
57
Makefile
Normal 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)
|
||||||
76
README.md
76
README.md
@@ -1,76 +0,0 @@
|
|||||||
NewOswan *(name likely to change)*
|
|
||||||
==================================
|
|
||||||
[](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:
|
|
||||||

|
|
||||||
|
|
||||||
Wonderswan Crystal boot splash:
|
|
||||||

|
|
||||||
|
|
||||||
Clock Tower:
|
|
||||||

|
|
||||||
|
|
||||||
Star Hearts:
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
### 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 |
37
dumpinfo.c
37
dumpinfo.c
@@ -1,11 +1,3 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* dumpinfo.c: Tool to dump the metadata info about a cart rom image.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -25,7 +17,7 @@ char *load_file(char *filename, uint32_t *fileSize)
|
|||||||
|
|
||||||
fstat(fd, &FileStat);
|
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;
|
*fileSize = FileStat.st_size;
|
||||||
|
|
||||||
@@ -72,26 +64,29 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (content != NULL)
|
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]);
|
printf("%s:\n", argv[1]);
|
||||||
if (data->farjump[0] == 0xEA)
|
if (data->farjump[0] == 0xEA)
|
||||||
{
|
{
|
||||||
printf("[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", data->publishId, data->gameId[0],
|
printf("[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]",
|
||||||
data->gameId[1], data->flags2, data->romInfo, data->saveInfo, data->flags & 0xFF,
|
data->publishId, data->gameId[0], data->gameId[1], data->flags2, data->romInfo, data->saveInfo,
|
||||||
(data->flags >> 8) & 0xFF, data->crc & 0xFF, (data->crc >> 8) & 0xFF);
|
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],
|
printf(" - Reset @ %02X%02X:%02X%02Xh\n",
|
||||||
data->farjump[1]);
|
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(" - 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 want to write to EEPROM\n", data->flags2&0x80?"Do":"Do not");
|
||||||
printf(" - %s user defined bootsplash\n", data->flagExt & 0x80 ? "Dissallow" : "Allow");
|
printf(" - %s user defined bootsplash\n", data->flagExt&0x80?"Dissallow":"Allow");
|
||||||
printf(" - Is %sbootable on a normal swan\n", data->flagExt & 0x0F ? "not " : "");
|
printf(" - Is %sbootable on a normal swan\n", data->flagExt&0x0F?"not ":"");
|
||||||
printf(" - ROM Size: %02Xh\n", data->romInfo);
|
printf(" - ROM Size: %02Xh\n", data->romInfo);
|
||||||
printf(" - Save type & Size: %02Xh\n", data->saveInfo);
|
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,
|
printf(" - Flags: %d cycles ROM, %d bit ROM bus, %sRTC, %s orientation\n",
|
||||||
data->flags & 0x002 ? 8 : 16, data->flags & 0x100 ? "" : "No ",
|
data->flags & 0x004?1:3,
|
||||||
data->flags & 0x001 ? "Vertical" : "Horizontal");
|
data->flags & 0x002?8:16,
|
||||||
|
data->flags & 0x100?"":"No ",
|
||||||
|
data->flags & 0x001?"Vertical":"Horizontal");
|
||||||
printf(" - CRC: %04Xh\n", data->crc);
|
printf(" - CRC: %04Xh\n", data->crc);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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.
162
main.c
162
main.c
@@ -1,162 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* main.c: Entry point
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <log.h>
|
|
||||||
#include <rom.h>
|
|
||||||
#include <nec.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <gpu.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <ws.h>
|
|
||||||
#include <emulate.h>
|
|
||||||
#include <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
216
main.cpp
Normal 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
50
resource.h
Normal 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
|
||||||
@@ -1,23 +1,10 @@
|
|||||||
set(SOURCES emulate.c gpu.c io.c log.c memory.c rom.c ws.c file_access.c)
|
set(SOURCES audio.cpp emulate.cpp gpu.cpp io.cpp log.cpp memory.cpp rom.cpp ws.cpp)
|
||||||
set(PERIPHERAL_SOURCES peripherals/audio.c peripherals/buttons.c peripherals/color_gpu.c peripherals/color_system.c
|
set(HEADERS audio.h emulate.h gpu.h ieeprom.h initialIo.h io.h log.h memory.h rom.h ws.h)
|
||||||
peripherals/debug.c peripherals/dma.c peripherals/eeprom.c peripherals/mono_gpu.c peripherals/mono_system.c
|
|
||||||
peripherals/rtc.c peripherals/universal_luxor.c peripherals/interrupt_controller.c peripherals/rs232.c
|
|
||||||
peripherals/timer.c)
|
|
||||||
set(PERIPHERAL_HEADERS includes/interrupt_controller.h)
|
|
||||||
set(HEADERS includes/audio.h includes/device.h includes/emulate.h includes/gpu.h includes/io.h includes/log.h
|
|
||||||
includes/memory.h includes/nec.h includes/nec_debugger.h includes/necintrf.h includes/rom.h includes/ws.h
|
|
||||||
includes/file_access.h)
|
|
||||||
|
|
||||||
option(FAKE_DISPLAY "Disable OpenGL and fake displaying" OFF)
|
add_library(wswan ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
add_library(wswan ${SOURCES} ${PERIPHERAL_SOURCES} ${HEADERS} ${PERIPHERAL_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_link_libraries(wswan nec_v30 glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
|
||||||
|
|
||||||
target_include_directories(wswan PUBLIC includes/)
|
target_include_directories(wswan PUBLIC .)
|
||||||
|
|
||||||
add_subdirectory(nec)
|
add_subdirectory(nec)
|
||||||
1514
source/audio.cpp
Normal file
1514
source/audio.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,17 @@
|
|||||||
/*******************************************************************************
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
* NewOswan
|
//
|
||||||
* audio.h:
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
*
|
//
|
||||||
* Based on the original Oswan-unix
|
//
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
//
|
||||||
*
|
//
|
||||||
******************************************************************************/
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef __AUDIO_H__
|
#ifndef __AUDIO_H__
|
||||||
#define __AUDIO_H__
|
#define __AUDIO_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void ws_audio_init();
|
void ws_audio_init();
|
||||||
void ws_audio_reset();
|
void ws_audio_reset();
|
||||||
void ws_audio_port_write(uint32_t port, uint8_t value);
|
void ws_audio_port_write(uint32_t port, uint8_t value);
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
/*******************************************************************************
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
* NewOswan
|
// Main emulation loop
|
||||||
* emulate.c:
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
*
|
//
|
||||||
* Based on the original Oswan-unix
|
//
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
//
|
||||||
*
|
//
|
||||||
******************************************************************************/
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -19,33 +21,33 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#ifndef PRETENT_DISPLAY
|
|
||||||
#define GLFW_INCLUDE_GLEXT
|
#define GLFW_INCLUDE_GLEXT
|
||||||
#define GL_SILENCE_DEPRECATION
|
#define GL_SILENCE_DEPRECATION
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
/* "Apple" fix */
|
/* "Apple" fix */
|
||||||
#ifndef GL_TEXTURE_RECTANGLE
|
#ifndef GL_TEXTURE_RECTANGLE
|
||||||
#define GL_TEXTURE_RECTANGLE GL_TEXTURE_RECTANGLE_EXT
|
#define GL_TEXTURE_RECTANGLE GL_TEXTURE_RECTANGLE_EXT
|
||||||
#endif
|
#endif
|
||||||
#endif /* PRETENT_DISPLAY */
|
|
||||||
|
|
||||||
#include <log.h>
|
#include "log.h"
|
||||||
#include <io.h>
|
#include "io.h"
|
||||||
#include <ws.h>
|
#include "ws.h"
|
||||||
#include <rom.h>
|
#include "rom.h"
|
||||||
#include "nec.h"
|
#include "./nec/nec.h"
|
||||||
#include "necintrf.h"
|
#include "./nec/necintrf.h"
|
||||||
#include <gpu.h>
|
#include "gpu.h"
|
||||||
#include <audio.h>
|
#include "audio.h"
|
||||||
#include <memory.h>
|
#include "memory.h"
|
||||||
|
|
||||||
char app_window_title[256];
|
char app_window_title[256];
|
||||||
int app_terminate = 0;
|
int app_gameRunning=0;
|
||||||
|
int app_terminate=0;
|
||||||
|
int app_fullscreen=0;
|
||||||
|
int app_rotated=0;
|
||||||
|
|
||||||
|
|
||||||
int ws_key_esc = 0;
|
int ws_key_esc = 0;
|
||||||
|
|
||||||
#ifndef PRETENT_DISPLAY
|
|
||||||
/* Open GL stuffs */
|
/* Open GL stuffs */
|
||||||
typedef struct GLWindow_t GLWindow;
|
typedef struct GLWindow_t GLWindow;
|
||||||
struct KeyArray
|
struct KeyArray
|
||||||
@@ -66,13 +68,13 @@ struct GLWindow_t
|
|||||||
};
|
};
|
||||||
static GLWindow mainWindow;
|
static GLWindow mainWindow;
|
||||||
static int window_num = 0;
|
static int window_num = 0;
|
||||||
|
|
||||||
static void ShowScreen(GLWindow *g, int w, int h)
|
static void ShowScreen(GLWindow *g, int w, int h)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
|
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
|
||||||
|
|
||||||
// glTexSubImage2D is faster when not using a texture range
|
// 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);
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
glTexCoord2f(0.0f, 0.0f);
|
glTexCoord2f(0.0f, 0.0f);
|
||||||
@@ -90,14 +92,12 @@ static void ShowScreen(GLWindow *g, int w, int h)
|
|||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GLWindowInitEx(GLWindow *g, int w, int h)
|
static void GLWindowInitEx(GLWindow *g, int w, int h)
|
||||||
{
|
{
|
||||||
g->WIDTH = w;
|
g->WIDTH = w;
|
||||||
g->HEIGHT = h;
|
g->HEIGHT = h;
|
||||||
g->videoTexture = window_num++;
|
g->videoTexture = window_num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupGL(GLWindow *g, int w, int h)
|
static void setupGL(GLWindow *g, int w, int h)
|
||||||
{
|
{
|
||||||
g->videoMemory = (uint8_t *)malloc(w * h * sizeof(uint16_t));
|
g->videoMemory = (uint8_t *)malloc(w * h * sizeof(uint16_t));
|
||||||
@@ -120,6 +120,10 @@ static void setupGL(GLWindow *g, int w, int h)
|
|||||||
glEnable(GL_TEXTURE_RECTANGLE);
|
glEnable(GL_TEXTURE_RECTANGLE);
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE, g->videoTexture);
|
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_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -130,7 +134,6 @@ static void setupGL(GLWindow *g, int w, int h)
|
|||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreGL(GLWindow *g)
|
void restoreGL(GLWindow *g)
|
||||||
{
|
{
|
||||||
//Tell OpenGL how to convert from coordinates to pixel values
|
//Tell OpenGL how to convert from coordinates to pixel values
|
||||||
@@ -151,7 +154,6 @@ void restoreGL(GLWindow *g)
|
|||||||
glEnable(GL_TEXTURE_RECTANGLE);
|
glEnable(GL_TEXTURE_RECTANGLE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod)
|
static void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod)
|
||||||
{
|
{
|
||||||
struct KeyArray *keyArray;
|
struct KeyArray *keyArray;
|
||||||
@@ -172,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,
|
/*printf("key:%d, state:%d debounce:%d, laststate:%d\n", key, keyArray[key].curState,
|
||||||
keyArray[key].debounced, keyArray[key].lastState);*/
|
keyArray[key].debounced, keyArray[key].lastState);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sizeHandler(GLFWwindow *window, int xs, int ys)
|
static void sizeHandler(GLFWwindow *window, int xs, int ys)
|
||||||
{
|
{
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glViewport(0, 0, xs, ys);
|
glViewport(0, 0, xs, ys);
|
||||||
ShowScreen(&mainWindow, 244, 144);
|
ShowScreen(&mainWindow, 244, 144);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void error_callback(int error, const char *description)
|
static void error_callback(int error, const char *description)
|
||||||
{
|
{
|
||||||
puts(description);
|
puts(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initDisplay(GLWindow *g)
|
static void initDisplay(GLWindow *g)
|
||||||
{
|
{
|
||||||
int h = g->HEIGHT;
|
int h = g->HEIGHT;
|
||||||
@@ -199,7 +198,7 @@ static void initDisplay(GLWindow *g)
|
|||||||
if (!(g->windows = glfwCreateWindow(g->WIDTH, g->HEIGHT, "Main", NULL, NULL)))
|
if (!(g->windows = glfwCreateWindow(g->WIDTH, g->HEIGHT, "Main", NULL, NULL)))
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
Log(TLOG_PANIC, "emulate", "Window creation error...");
|
fprintf(stderr, "Window creation error...\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,12 +216,10 @@ static void initDisplay(GLWindow *g)
|
|||||||
glfwSetKeyCallback(g->windows, kbHandler);
|
glfwSetKeyCallback(g->windows, kbHandler);
|
||||||
glfwSetWindowSizeCallback(g->windows, sizeHandler);
|
glfwSetWindowSizeCallback(g->windows, sizeHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clearScreen(GLWindow *g)
|
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)
|
static void updateScreen(GLWindow *g)
|
||||||
{
|
{
|
||||||
/* Update windows code */
|
/* Update windows code */
|
||||||
@@ -231,6 +228,17 @@ static void updateScreen(GLWindow *g)
|
|||||||
glfwSwapBuffers(g->windows);
|
glfwSwapBuffers(g->windows);
|
||||||
glfwPollEvents();
|
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)
|
static inline int getKeyState(int key)
|
||||||
{
|
{
|
||||||
@@ -239,18 +247,17 @@ static inline int getKeyState(int key)
|
|||||||
|
|
||||||
static void read_keys()
|
static void read_keys()
|
||||||
{
|
{
|
||||||
#if 0
|
ws_key_start=0;
|
||||||
ws_key_start = 0;
|
ws_key_x4=0;
|
||||||
ws_key_x4 = 0;
|
ws_key_x2=0;
|
||||||
ws_key_x2 = 0;
|
ws_key_x1=0;
|
||||||
ws_key_x1 = 0;
|
ws_key_x3=0;
|
||||||
ws_key_x3 = 0;
|
ws_key_y4=0;
|
||||||
ws_key_y4 = 0;
|
ws_key_y2=0;
|
||||||
ws_key_y2 = 0;
|
ws_key_y1=0;
|
||||||
ws_key_y1 = 0;
|
ws_key_y3=0;
|
||||||
ws_key_y3 = 0;
|
ws_key_button_a=0;
|
||||||
ws_key_button_a = 0;
|
ws_key_button_b=0;
|
||||||
ws_key_button_b = 0;
|
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_E))
|
if (getKeyState(GLFW_KEY_E))
|
||||||
{
|
{
|
||||||
@@ -259,7 +266,7 @@ static void read_keys()
|
|||||||
|
|
||||||
if (getKeyState(GLFW_KEY_R))
|
if (getKeyState(GLFW_KEY_R))
|
||||||
{
|
{
|
||||||
Log(TLOG_DEBUG, "emulate", "Boop reset");
|
printf("Boop\n");
|
||||||
ws_reset();
|
ws_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,142 +275,83 @@ static void read_keys()
|
|||||||
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))
|
if (getKeyState(GLFW_KEY_RIGHT))
|
||||||
{
|
{
|
||||||
ws_key_x2 = 1;
|
ws_key_x2=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_LEFT))
|
if (getKeyState(GLFW_KEY_LEFT))
|
||||||
{
|
{
|
||||||
ws_key_x4 = 1;
|
ws_key_x4=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_ENTER))
|
if (getKeyState(GLFW_KEY_ENTER))
|
||||||
{
|
{
|
||||||
ws_key_start = 1;
|
ws_key_start=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_C))
|
if (getKeyState(GLFW_KEY_C))
|
||||||
{
|
{
|
||||||
ws_key_button_a = 1;
|
ws_key_button_a=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_X))
|
if (getKeyState(GLFW_KEY_X))
|
||||||
{
|
{
|
||||||
ws_key_button_b = 1;
|
ws_key_button_b=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_W))
|
if (getKeyState(GLFW_KEY_W))
|
||||||
{
|
{
|
||||||
ws_key_y1 = 1;
|
ws_key_y1=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_A))
|
if (getKeyState(GLFW_KEY_A))
|
||||||
{
|
{
|
||||||
ws_key_y4 = 1;
|
ws_key_y4=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_S))
|
if (getKeyState(GLFW_KEY_S))
|
||||||
{
|
{
|
||||||
ws_key_y3 = 1;
|
ws_key_y3=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_D))
|
if (getKeyState(GLFW_KEY_D))
|
||||||
{
|
{
|
||||||
ws_key_y2 = 1;
|
ws_key_y2=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_O))
|
if (getKeyState(GLFW_KEY_O))
|
||||||
{
|
{
|
||||||
ws_cyclesByLine += 10;
|
ws_cyclesByLine+=10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyState(GLFW_KEY_L))
|
if (getKeyState(GLFW_KEY_L))
|
||||||
{
|
{
|
||||||
ws_cyclesByLine -= 10;
|
ws_cyclesByLine-=10;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void ws_emulate(void)
|
void ws_emulate(void)
|
||||||
{
|
{
|
||||||
int32_t nCount = 0;
|
int32_t nCount = 0;
|
||||||
@@ -420,9 +368,7 @@ void ws_emulate(void)
|
|||||||
int16_t *backBuffer = (int16_t *)mainWindow.videoMemory;
|
int16_t *backBuffer = (int16_t *)mainWindow.videoMemory;
|
||||||
|
|
||||||
|
|
||||||
dNormalLast = getTicks();
|
dNormalLast = (double)getTicks();
|
||||||
|
|
||||||
#define HCLK (1000. / 12000.)
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -430,17 +376,18 @@ void ws_emulate(void)
|
|||||||
dTemp = getTicks();
|
dTemp = getTicks();
|
||||||
dTime = dTemp - dNormalLast;
|
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)
|
if (nCount <= 0)
|
||||||
{
|
{
|
||||||
/* Sleep for 500us */
|
/* Sleep for 2ms */
|
||||||
usleep(500);
|
usleep(2000);
|
||||||
} // No need to do anything for a bit
|
} // No need to do anything for a bit
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
dNormalLast += nCount * (1 / HCLK);
|
dNormalLast += nCount * (1 / 0.07547);
|
||||||
|
|
||||||
if (nCount > 10)
|
if (nCount > 10)
|
||||||
{
|
{
|
||||||
@@ -459,10 +406,10 @@ void ws_emulate(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* What is this mess? Frameskip? */
|
|
||||||
for (i = 0 ; i < nCount - 1 ; i++)
|
for (i = 0 ; i < nCount - 1 ; i++)
|
||||||
{
|
{
|
||||||
while (!ws_executeLine(backBuffer, 1))
|
while (!ws_executeLine(backBuffer, 0))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
30
source/emulate.h
Normal file
30
source/emulate.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef EMULATE_H
|
||||||
|
#define EMULATE_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;
|
||||||
|
|
||||||
|
|
||||||
|
void ws_emulate(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* EMULATE_H */
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* file_access.c: File manipulation functions
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 27/06/2022.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is OS specific and this need to be changed at some point.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <file_access.h>
|
|
||||||
#include <log.h>
|
|
||||||
|
|
||||||
char *load_file(char *filename, bool readOnly)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char *ret_ptr;
|
|
||||||
struct stat FileStat;
|
|
||||||
int flags = readOnly?MAP_ANONYMOUS:MAP_SHARED;
|
|
||||||
|
|
||||||
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, flags, 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;
|
|
||||||
}
|
|
||||||
1930
source/gpu.c
1930
source/gpu.c
File diff suppressed because it is too large
Load Diff
2313
source/gpu.cpp
Normal file
2313
source/gpu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
45
source/gpu.h
Normal file
45
source/gpu.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __GPU_H__
|
||||||
|
#define __GPU_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 uint32_t vblank_count;
|
||||||
|
|
||||||
|
|
||||||
|
void ws_gpu_init(void);
|
||||||
|
void ws_gpu_done(void);
|
||||||
|
void ws_gpu_reset(void);
|
||||||
|
void ws_gpu_renderScanline(int16_t *framebuffer);
|
||||||
|
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
191
source/ieeprom.h
Normal 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
|
||||||
|
};
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* device.h:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __DEVICE_H__
|
|
||||||
#define __DEVICE_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Ticks are the fasted clock in the system
|
|
||||||
* Each device which need to be clocked use a multiple of the tick
|
|
||||||
* number as their own clock.
|
|
||||||
*/
|
|
||||||
typedef uint64_t tick_t;
|
|
||||||
|
|
||||||
typedef void (*device_init)(uint8_t baseAddress, void *param);
|
|
||||||
typedef void (*device_reset)(void);
|
|
||||||
typedef void (*device_free)(void);
|
|
||||||
typedef void (*device_update)(tick_t ticks);
|
|
||||||
|
|
||||||
typedef enum device_type_t
|
|
||||||
{
|
|
||||||
DT_INTERRUPT_CONTROLLER,
|
|
||||||
DT_GPU,
|
|
||||||
DT_BUTTONS,
|
|
||||||
DT_DMA,
|
|
||||||
DT_LUXOR,
|
|
||||||
DT_AUDIO,
|
|
||||||
DT_SYSTEM,
|
|
||||||
DT_RTC,
|
|
||||||
DT_RS232,
|
|
||||||
DT_EEPROM,
|
|
||||||
DT_DEBUG,
|
|
||||||
} device_type_t;
|
|
||||||
|
|
||||||
typedef struct device_t
|
|
||||||
{
|
|
||||||
device_init init; /***< Function called to init the device - Non optional */
|
|
||||||
device_update update; /***< Function called on updates - Optional */
|
|
||||||
device_reset reset; /***< Function called to reset the device - Optional */
|
|
||||||
device_free free; /***< Function called to deinit the device - Optional */
|
|
||||||
device_type_t deviceType; /***< Used to tell the type of device, could be useful to pass the
|
|
||||||
* right parameters to init - Non optional */
|
|
||||||
} device_t;
|
|
||||||
|
|
||||||
#endif /* __DEVICE_H__ */
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* emulate.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef EMULATE_H
|
|
||||||
#define EMULATE_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
extern char app_window_title[256];
|
|
||||||
extern int app_terminate;
|
|
||||||
|
|
||||||
void ws_emulate(void);
|
|
||||||
|
|
||||||
#endif /* EMULATE_H */
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* file_access.h:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 26/06/2022.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __FILE_ACCESS_H__
|
|
||||||
#define __FILE_ACCESS_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
char *create_file(char *filename, uint32_t size);
|
|
||||||
char *load_file(char *filename, bool readOnly);
|
|
||||||
|
|
||||||
#endif /* __FILE_ACCESS_H__ */
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* gpu.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __GPU_H__
|
|
||||||
#define __GPU_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
struct ws_gpu_t
|
|
||||||
{
|
|
||||||
uint8_t scanline;
|
|
||||||
uint32_t cyclecount;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
void ws_gpu_init(void);
|
|
||||||
void ws_gpu_done(void);
|
|
||||||
void ws_gpu_reset(void);
|
|
||||||
void ws_gpu_renderScanline(int16_t *framebuffer);
|
|
||||||
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_changeVideoMode(uint8_t value);
|
|
||||||
void ws_gpu_clearCache(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* interrupt_controller.h:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 14/03/2022.
|
|
||||||
* Copyright (c) 2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __INTERRUPT_CONTROLLER_H__
|
|
||||||
#define __INTERRUPT_CONTROLLER_H__
|
|
||||||
|
|
||||||
#include <device.h>
|
|
||||||
|
|
||||||
typedef enum hw_interrupt_type_t
|
|
||||||
{
|
|
||||||
/* They are in the same order as the hardware */
|
|
||||||
HWI_SERIAL_TX = 0,
|
|
||||||
HWI_KEY,
|
|
||||||
HWI_CART,
|
|
||||||
HWI_SERIAL_RX,
|
|
||||||
HWI_LINE_COMPARE,
|
|
||||||
HWI_VBLANK_TIMER,
|
|
||||||
HWI_VBLANK,
|
|
||||||
HWI_HBLANK_TIMER,
|
|
||||||
} hw_interrupt_type_t;
|
|
||||||
|
|
||||||
extern device_t InterruptController;
|
|
||||||
|
|
||||||
void trigger_interrupt(hw_interrupt_type_t type);
|
|
||||||
|
|
||||||
#endif /* __INTERRUPT_CONTROLLER_H__ */
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* io.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __IO_H__
|
|
||||||
#define __IO_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void io_init(void);
|
|
||||||
void io_reset(void);
|
|
||||||
void io_cleanup(void);
|
|
||||||
|
|
||||||
uint8_t io_readport(uint8_t port);
|
|
||||||
void io_writeport(uint8_t port, uint8_t value);
|
|
||||||
|
|
||||||
typedef uint8_t (*io_read)(void *pdata, uint8_t port);
|
|
||||||
typedef void (*io_write)(void *pdata, uint8_t port, uint8_t value);
|
|
||||||
|
|
||||||
void register_io_hook(uint8_t baseAddress, uint8_t port, io_read readHook, void *pdata, io_write writeHook);
|
|
||||||
void register_io_hook_array(uint8_t baseAddress, const uint8_t *portList, uint8_t listLen, io_read readHook, io_write writeHook,
|
|
||||||
void *pdata);
|
|
||||||
|
|
||||||
#define UNUSED_PARAMETER(_s) (void *)(_s)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* log.h: C Fancy Logger
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 20/01/2009.
|
|
||||||
* Copyright (c) 2009-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _LOG_H
|
|
||||||
#define _LOG_H
|
|
||||||
|
|
||||||
#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 */
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* memory.h:
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __MEMORY_H__
|
|
||||||
#define __MEMORY_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void dump_memory();
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Set a memory page with a granularity 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 granularity 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);
|
|
||||||
|
|
||||||
#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);
|
|
||||||
|
|
||||||
#endif /* __MEMORY_H__ */
|
|
||||||
|
|
||||||
@@ -1,405 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* nec.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 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;
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
/* eight general registers */
|
|
||||||
uint16_t w[8]; /* viewed as 16 bits registers */
|
|
||||||
uint8_t b[16]; /* or as 8 bit registers */
|
|
||||||
} necbasicregs;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
necbasicregs regs;
|
|
||||||
uint16_t sregs[4];
|
|
||||||
|
|
||||||
uint16_t ip;
|
|
||||||
|
|
||||||
int32_t SignVal;
|
|
||||||
int32_t AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
|
|
||||||
|
|
||||||
uint32_t TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
|
|
||||||
|
|
||||||
uint32_t int_vector;
|
|
||||||
uint32_t pending_irq;
|
|
||||||
uint32_t nmi_state;
|
|
||||||
uint32_t irq_state;
|
|
||||||
int (*irq_callback)(int irqline);
|
|
||||||
} nec_Regs;
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
#define NEC_NMI_INT_VECTOR 2
|
|
||||||
|
|
||||||
/* Cpu types, steps of 8 to help the cycle count calculation */
|
|
||||||
#define V33 0
|
|
||||||
#define V30 8
|
|
||||||
#define V20 16
|
|
||||||
|
|
||||||
/* 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 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 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 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; }
|
|
||||||
|
|
||||||
#define SUBB { uint32_t res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(uint8_t)res; }
|
|
||||||
#define SUBW { uint32_t res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(uint16_t)res; }
|
|
||||||
|
|
||||||
#define ORB dst|=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
|
|
||||||
#define ORW dst|=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
|
|
||||||
|
|
||||||
#define ANDB dst&=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
|
|
||||||
#define ANDW dst&=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
|
|
||||||
|
|
||||||
#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 SegBase(Seg) (I.sregs[Seg] << 4)
|
|
||||||
|
|
||||||
#define DefaultBase(Seg) ((seg_prefix && (Seg==DS || Seg==SS)) ? (prefix_base) : (uint32_t)(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 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)); }
|
|
||||||
|
|
||||||
/* 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 read_port(port) io_readport(port)
|
|
||||||
#define write_port(port, val) io_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 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 GetModRM uint32_t ModRM=mem_readop_arg((I.sregs[CS]<<4)+I.ip++)
|
|
||||||
|
|
||||||
/* Cycle count macros:
|
|
||||||
CLK - cycle count is the same on all processors
|
|
||||||
CLKS - cycle count differs between processors, list all counts
|
|
||||||
CLKW - cycle count for word read/write differs for odd/even source/destination address
|
|
||||||
CLKM - cycle count for reg/mem instructions
|
|
||||||
CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
|
|
||||||
|
|
||||||
|
|
||||||
Prefetch & buswait time is not emulated.
|
|
||||||
Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
|
|
||||||
|
|
||||||
#define CLK(all) nec_ICount-=all
|
|
||||||
#define CLKS(v20,v30,v33) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
|
|
||||||
#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e) { const uint32_t ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_ICount-=(I.ip&1)?((ocount>>cpu_type)&0x7f):((ecount>>cpu_type)&0x7f); }
|
|
||||||
#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 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 CompressFlags() (uint16_t)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
|
|
||||||
| (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; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#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 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 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 ROL_BYTE I.CarryVal = dst & 0x80; dst = (dst << 1)+CF
|
|
||||||
#define ROL_WORD I.CarryVal = dst & 0x8000; dst = (dst << 1)+CF
|
|
||||||
#define ROR_BYTE I.CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7)
|
|
||||||
#define ROR_WORD I.CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15)
|
|
||||||
#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst)
|
|
||||||
#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 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 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 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 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 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_ */
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* nec_debugger.h:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 14/04/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __NEC_DEBUGGER_H__
|
|
||||||
#define __NEC_DEBUGGER_H__
|
|
||||||
|
|
||||||
|
|
||||||
int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsigned int bufferSize);
|
|
||||||
|
|
||||||
#endif /* __NEC_DEBUGGER_H__ */
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* necintrf.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 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
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Public variables */
|
|
||||||
extern int nec_ICount;
|
|
||||||
|
|
||||||
/* Public functions */
|
|
||||||
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_int(uint16_t vector);
|
|
||||||
|
|
||||||
#endif /* __NECITRF_H__ */
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* rom.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __ROM_H__
|
|
||||||
#define __ROM_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#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_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 */
|
|
||||||
} 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];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __ROM_H__ */
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* ws.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __WS_H__
|
|
||||||
#define __WS_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef enum wssystem_t
|
|
||||||
{
|
|
||||||
WS_SYSTEM_AUTODETECT = 0, WS_SYSTEM_MONO, WS_SYSTEM_COLOR, WS_SYSTEM_CRYSTAL,
|
|
||||||
} wssystem_t;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
extern char *ws_sram_path;
|
|
||||||
extern char *ws_ieep_path;
|
|
||||||
extern char *ws_rom_path;
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __WS_H__ */
|
|
||||||
271
source/initialIo.h
Normal file
271
source/initialIo.h
Normal 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
|
||||||
|
};
|
||||||
121
source/io.c
121
source/io.c
@@ -1,121 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* io.c: I/O ports implementaton
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <log.h>
|
|
||||||
#include <rom.h>
|
|
||||||
#include <nec.h>
|
|
||||||
#include <necintrf.h>
|
|
||||||
#include <gpu.h>
|
|
||||||
#include <audio.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <ws.h>
|
|
||||||
#include <io.h>
|
|
||||||
|
|
||||||
//#define IO_DUMP
|
|
||||||
|
|
||||||
typedef struct ioregistry_t
|
|
||||||
{
|
|
||||||
io_read read; /***< Read function for a specific IO port */
|
|
||||||
io_write write; /***< Write function for a specific IO port */
|
|
||||||
void *private; /***< Private data for the peripheral if needed. */
|
|
||||||
uint8_t base_address; /***< Base IO address. Used create a "local" value when calling the read/write function */
|
|
||||||
} ioregistry_t;
|
|
||||||
ioregistry_t io_registry[0x100];
|
|
||||||
|
|
||||||
extern uint32_t romAddressMask;
|
|
||||||
extern nec_Regs I;
|
|
||||||
extern uint64_t nec_monotonicCycles;
|
|
||||||
extern uint32_t sramSize;
|
|
||||||
|
|
||||||
FILE *ioLogFp = NULL;
|
|
||||||
|
|
||||||
void io_init(void)
|
|
||||||
{
|
|
||||||
#ifdef IO_DUMP
|
|
||||||
ioLogFp = fopen("iodump.csv", "wt");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void io_cleanup(void)
|
|
||||||
{
|
|
||||||
#ifdef IO_DUMP
|
|
||||||
fclose(ioLogFp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_io_hook(uint8_t baseAddress, uint8_t port, io_read readHook, void *pdata, io_write writeHook)
|
|
||||||
{
|
|
||||||
io_registry[baseAddress + port].base_address = baseAddress;
|
|
||||||
io_registry[baseAddress + port].read = readHook;
|
|
||||||
io_registry[baseAddress + port].write = writeHook;
|
|
||||||
io_registry[baseAddress + port].private = pdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_io_hook_array(uint8_t baseAddress, const uint8_t *portList, uint8_t listLen, io_read readHook, io_write writeHook,
|
|
||||||
void *pdata)
|
|
||||||
{
|
|
||||||
uint16_t i;
|
|
||||||
for(i = 0; i < listLen; i++)
|
|
||||||
{
|
|
||||||
io_registry[baseAddress + portList[i]].base_address = baseAddress;
|
|
||||||
io_registry[baseAddress + portList[i]].read = readHook;
|
|
||||||
io_registry[baseAddress + portList[i]].write = writeHook;
|
|
||||||
io_registry[baseAddress + portList[i]].private = pdata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t io_readport(uint8_t port)
|
|
||||||
{
|
|
||||||
uint8_t retVal = 0;
|
|
||||||
if (io_registry[port].read)
|
|
||||||
{
|
|
||||||
uint8_t localPort = port - io_registry[port].base_address;
|
|
||||||
retVal = io_registry[port].read(io_registry[port].private, localPort);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "IO", "CPU tried to read IO %02Xh - May be a bug", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IO_DUMP
|
|
||||||
if (ioLogFp)
|
|
||||||
{
|
|
||||||
fprintf(ioLogFp, "%lu, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void io_writeport(uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
if (io_registry[port].write)
|
|
||||||
{
|
|
||||||
uint8_t localPort = port - io_registry[port].base_address;
|
|
||||||
io_registry[port].write(io_registry[port].private, localPort, value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "IO", "CPU tried to write %02Xh to IO %02Xh - MAy be a bug", value, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IO_DUMP
|
|
||||||
if (ioLogFp)
|
|
||||||
{
|
|
||||||
fprintf(ioLogFp, "%llu, W, %02X, %02X\n", nec_monotonicCycles, port, value);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
1114
source/io.cpp
Normal file
1114
source/io.cpp
Normal file
File diff suppressed because it is too large
Load Diff
34
source/io.h
Normal file
34
source/io.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __IO_H__
|
||||||
|
#define __IO_H__
|
||||||
|
|
||||||
|
extern uint8_t *ws_ioRam;
|
||||||
|
extern uint8_t ws_key_start;
|
||||||
|
extern uint8_t ws_key_x4;
|
||||||
|
extern uint8_t ws_key_x2;
|
||||||
|
extern uint8_t ws_key_x1;
|
||||||
|
extern uint8_t ws_key_x3;
|
||||||
|
extern uint8_t ws_key_y4;
|
||||||
|
extern uint8_t ws_key_y2;
|
||||||
|
extern uint8_t ws_key_y1;
|
||||||
|
extern uint8_t ws_key_y3;
|
||||||
|
extern uint8_t ws_key_button_a;
|
||||||
|
extern uint8_t ws_key_button_b;
|
||||||
|
|
||||||
|
void ws_io_init(void);
|
||||||
|
void ws_io_reset(void);
|
||||||
|
void ws_io_flipControls(void);
|
||||||
|
void ws_io_done(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
140
source/log.c
140
source/log.c
@@ -1,140 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* log.c: C Fancy Logger
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 20/01/2009.
|
|
||||||
* Copyright (c) 2009-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#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
67
source/log.cpp
Normal 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);
|
||||||
|
}
|
||||||
20
source/log.h
Normal file
20
source/log.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __LOG_H__
|
||||||
|
#define __LOG_H__
|
||||||
|
|
||||||
|
int log_init(char *path);
|
||||||
|
FILE *log_get(void);
|
||||||
|
void log_done(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* memory.c: Memory implementation
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <memory.h>
|
|
||||||
|
|
||||||
#include <log.h>
|
|
||||||
|
|
||||||
void dump_memory()
|
|
||||||
{
|
|
||||||
// TODO: Need complete rewrite
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* Everything from 3000:0000h is readonly, so we ignore all tentative to write there. */
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
448
source/memory.cpp
Normal file
448
source/memory.cpp
Normal 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);
|
||||||
|
}
|
||||||
37
source/memory.h
Normal file
37
source/memory.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __MEMORY_H__
|
||||||
|
#define __MEMORY_H__
|
||||||
|
|
||||||
|
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 memory_load(int fp);
|
||||||
|
void memory_save(int fp);
|
||||||
|
|
||||||
|
char *create_file(char *filename, uint32_t size);
|
||||||
|
char *load_file(char *filename);
|
||||||
|
|
||||||
|
void dump_memory();
|
||||||
|
|
||||||
|
#define BW_IEEPROM_SIZE (128)
|
||||||
|
#define COLOR_IEEPROM_SIZE (2048)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
set(SOURCES nec.c nec_debugger.c)
|
set(SOURCES nec.cpp)
|
||||||
set(HEADERS ../includes/nec.h necea.h necinstr.h ../includes/necintrf.h necmodrm.h ../includes/nec_debugger.h)
|
set(HEADERS nec.h necea.h necinstr.h necintrf.h necmodrm.h)
|
||||||
|
|
||||||
add_library(nec_v30 ${SOURCES} ${HEADERS})
|
add_library(nec_v30 ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
target_include_directories(nec_v30 PUBLIC ../includes/)
|
|
||||||
4256
source/nec/nec.c
4256
source/nec/nec.c
File diff suppressed because it is too large
Load Diff
3949
source/nec/nec.cpp
Normal file
3949
source/nec/nec.cpp
Normal file
File diff suppressed because it is too large
Load Diff
363
source/nec/nec.h
Normal file
363
source/nec/nec.h
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
#ifndef __NEC_H_
|
||||||
|
#define __NEC_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include "necintrf.h"
|
||||||
|
|
||||||
|
#define NEC_NMI_INT_VECTOR 2
|
||||||
|
|
||||||
|
/* Cpu types, steps of 8 to help the cycle count calculation */
|
||||||
|
#define V33 0
|
||||||
|
#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 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 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 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; }
|
||||||
|
|
||||||
|
#define SUBB { uint32_t res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(uint8_t)res; }
|
||||||
|
#define SUBW { uint32_t res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(uint16_t)res; }
|
||||||
|
|
||||||
|
#define ORB dst|=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
|
||||||
|
#define ORW dst|=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
|
||||||
|
|
||||||
|
#define ANDB dst&=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
|
||||||
|
#define ANDW dst&=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
|
||||||
|
|
||||||
|
#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 SegBase(Seg) (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)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*/; 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)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) cpu_readport(port)
|
||||||
|
#define write_port(port,val) cpu_writeport(port,val)
|
||||||
|
|
||||||
|
#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)cpu_readop_arg(addr))
|
||||||
|
#define PEEKOP(addr) ((uint8_t)cpu_readop(addr))
|
||||||
|
|
||||||
|
#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
|
||||||
|
CLKS - cycle count differs between processors, list all counts
|
||||||
|
CLKW - cycle count for word read/write differs for odd/even source/destination address
|
||||||
|
CLKM - cycle count for reg/mem instructions
|
||||||
|
CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
|
||||||
|
|
||||||
|
|
||||||
|
Prefetch & buswait time is not emulated.
|
||||||
|
Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
|
||||||
|
|
||||||
|
#define CLK(all) nec_ICount-=all
|
||||||
|
#define CLKS(v20,v30,v33) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
|
||||||
|
#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e) { const uint32_t ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_ICount-=(I.ip&1)?((ocount>>cpu_type)&0x7f):((ecount>>cpu_type)&0x7f); }
|
||||||
|
#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 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 CompressFlags() (uint16_t)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
|
||||||
|
| (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; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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 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 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 ROL_BYTE I.CarryVal = dst & 0x80; dst = (dst << 1)+CF
|
||||||
|
#define ROL_WORD I.CarryVal = dst & 0x8000; dst = (dst << 1)+CF
|
||||||
|
#define ROR_BYTE I.CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7)
|
||||||
|
#define ROR_WORD I.CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15)
|
||||||
|
#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst)
|
||||||
|
#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 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 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 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 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 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
@@ -1,11 +1,3 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* necea.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static uint32_t EA;
|
static uint32_t EA;
|
||||||
static uint16_t EO;
|
static uint16_t EO;
|
||||||
@@ -13,206 +5,194 @@ static uint16_t E16;
|
|||||||
|
|
||||||
static unsigned EA_000(void)
|
static unsigned EA_000(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[BW] + I.regs.w[IX];
|
EO=I.regs.w[BW]+I.regs.w[IX];
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_001(void)
|
static unsigned EA_001(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[BW] + I.regs.w[IY];
|
EO=I.regs.w[BW]+I.regs.w[IY];
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_002(void)
|
static unsigned EA_002(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[BP] + I.regs.w[IX];
|
EO=I.regs.w[BP]+I.regs.w[IX];
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_003(void)
|
static unsigned EA_003(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[BP] + I.regs.w[IY];
|
EO=I.regs.w[BP]+I.regs.w[IY];
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_004(void)
|
static unsigned EA_004(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[IX];
|
EO=I.regs.w[IX];
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_005(void)
|
static unsigned EA_005(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[IY];
|
EO=I.regs.w[IY];
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_006(void)
|
static unsigned EA_006(void)
|
||||||
{
|
{
|
||||||
EO = FETCH;
|
EO=FETCH;
|
||||||
EO += FETCH << 8;
|
EO+=FETCH<<8;
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_007(void)
|
static unsigned EA_007(void)
|
||||||
{
|
{
|
||||||
EO = I.regs.w[BW];
|
EO=I.regs.w[BW];
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_100(void)
|
static unsigned EA_100(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[BW] + I.regs.w[IX] + (int8_t)FETCH);
|
EO=(I.regs.w[BW]+I.regs.w[IX]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_101(void)
|
static unsigned EA_101(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[BW] + I.regs.w[IY] + (int8_t)FETCH);
|
EO=(I.regs.w[BW]+I.regs.w[IY]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_102(void)
|
static unsigned EA_102(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[BP] + I.regs.w[IX] + (int8_t)FETCH);
|
EO=(I.regs.w[BP]+I.regs.w[IX]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_103(void)
|
static unsigned EA_103(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[BP] + I.regs.w[IY] + (int8_t)FETCH);
|
EO=(I.regs.w[BP]+I.regs.w[IY]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_104(void)
|
static unsigned EA_104(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[IX] + (int8_t)FETCH);
|
EO=(I.regs.w[IX]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_105(void)
|
static unsigned EA_105(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[IY] + (int8_t)FETCH);
|
EO=(I.regs.w[IY]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_106(void)
|
static unsigned EA_106(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[BP] + (int8_t)FETCH);
|
EO=(I.regs.w[BP]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_107(void)
|
static unsigned EA_107(void)
|
||||||
{
|
{
|
||||||
EO = (I.regs.w[BW] + (int8_t)FETCH);
|
EO=(I.regs.w[BW]+(int8_t)FETCH);
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_200(void)
|
static unsigned EA_200(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[BW] + I.regs.w[IX] + (int16_t)E16;
|
EO=I.regs.w[BW]+I.regs.w[IX]+(int16_t)E16;
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_201(void)
|
static unsigned EA_201(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[BW] + I.regs.w[IY] + (int16_t)E16;
|
EO=I.regs.w[BW]+I.regs.w[IY]+(int16_t)E16;
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_202(void)
|
static unsigned EA_202(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[BP] + I.regs.w[IX] + (int16_t)E16;
|
EO=I.regs.w[BP]+I.regs.w[IX]+(int16_t)E16;
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_203(void)
|
static unsigned EA_203(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[BP] + I.regs.w[IY] + (int16_t)E16;
|
EO=I.regs.w[BP]+I.regs.w[IY]+(int16_t)E16;
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_204(void)
|
static unsigned EA_204(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[IX] + (int16_t)E16;
|
EO=I.regs.w[IX]+(int16_t)E16;
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_205(void)
|
static unsigned EA_205(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[IY] + (int16_t)E16;
|
EO=I.regs.w[IY]+(int16_t)E16;
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_206(void)
|
static unsigned EA_206(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[BP] + (int16_t)E16;
|
EO=I.regs.w[BP]+(int16_t)E16;
|
||||||
EA = DefaultBase(SS) + EO;
|
EA=DefaultBase(SS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned EA_207(void)
|
static unsigned EA_207(void)
|
||||||
{
|
{
|
||||||
E16 = FETCH;
|
E16=FETCH;
|
||||||
E16 += FETCH << 8;
|
E16+=FETCH<<8;
|
||||||
EO = I.regs.w[BW] + (int16_t)E16;
|
EO=I.regs.w[BW]+(int16_t)E16;
|
||||||
EA = DefaultBase(DS) + EO;
|
EA=DefaultBase(DS)+EO;
|
||||||
return EA;
|
return EA;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned (*GetEA[192])(void) =
|
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_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
|
||||||
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_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
|
||||||
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_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
|
||||||
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_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
|
||||||
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_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
|
||||||
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_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
|
||||||
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_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
|
||||||
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_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
|
||||||
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_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
|
||||||
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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* necinstr.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static void i_add_br8(void);
|
static void i_add_br8(void);
|
||||||
static void i_add_wr16(void);
|
static void i_add_wr16(void);
|
||||||
static void i_add_r8b(void);
|
static void i_add_r8b(void);
|
||||||
@@ -256,7 +247,7 @@ static void i_ffpre(void);
|
|||||||
static void i_wait(void);
|
static void i_wait(void);
|
||||||
|
|
||||||
void (*nec_instruction[256])(void) =
|
void (*nec_instruction[256])(void) =
|
||||||
{
|
{
|
||||||
i_add_br8, /* 0x00 */
|
i_add_br8, /* 0x00 */
|
||||||
i_add_wr16, /* 0x01 */
|
i_add_wr16, /* 0x01 */
|
||||||
i_add_r8b, /* 0x02 */
|
i_add_r8b, /* 0x02 */
|
||||||
@@ -272,7 +263,7 @@ void (*nec_instruction[256])(void) =
|
|||||||
i_or_ald8, /* 0x0c */
|
i_or_ald8, /* 0x0c */
|
||||||
i_or_axd16, /* 0x0d */
|
i_or_axd16, /* 0x0d */
|
||||||
i_push_cs, /* 0x0e */
|
i_push_cs, /* 0x0e */
|
||||||
i_pre_nec, /* 0x0f */
|
i_pre_nec /* 0x0f */,
|
||||||
i_adc_br8, /* 0x10 */
|
i_adc_br8, /* 0x10 */
|
||||||
i_adc_wr16, /* 0x11 */
|
i_adc_wr16, /* 0x11 */
|
||||||
i_adc_r8b, /* 0x12 */
|
i_adc_r8b, /* 0x12 */
|
||||||
@@ -471,7 +462,7 @@ void (*nec_instruction[256])(void) =
|
|||||||
i_rotshft_wcl, /* 0xd3 */
|
i_rotshft_wcl, /* 0xd3 */
|
||||||
i_aam, /* 0xd4 */
|
i_aam, /* 0xd4 */
|
||||||
i_aad, /* 0xd5 */
|
i_aad, /* 0xd5 */
|
||||||
i_setalc, /* 0xd6 */
|
i_setalc,
|
||||||
i_trans, /* 0xd7 */
|
i_trans, /* 0xd7 */
|
||||||
i_fpo, /* 0xd8 */
|
i_fpo, /* 0xd8 */
|
||||||
i_fpo, /* 0xd9 */
|
i_fpo, /* 0xd9 */
|
||||||
@@ -513,4 +504,4 @@ void (*nec_instruction[256])(void) =
|
|||||||
i_std, /* 0xfd */
|
i_std, /* 0xfd */
|
||||||
i_fepre, /* 0xfe */
|
i_fepre, /* 0xfe */
|
||||||
i_ffpre /* 0xff */
|
i_ffpre /* 0xff */
|
||||||
};
|
};
|
||||||
|
|||||||
106
source/nec/necintrf.h
Normal file
106
source/nec/necintrf.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/* ASG 971222 -- rewrote this interface */
|
||||||
|
#ifndef __NECITRF_H_
|
||||||
|
#define __NECITRF_H_
|
||||||
|
|
||||||
|
typedef enum { ES, CS, SS, DS } SREGS;
|
||||||
|
typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
|
||||||
|
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,IXL,IXH,IYL,IYH } BREGS;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
/* eight general registers */
|
||||||
|
uint16_t w[8]; /* viewed as 16 bits registers */
|
||||||
|
uint8_t b[16]; /* or as 8 bit registers */
|
||||||
|
} necbasicregs;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
necbasicregs regs;
|
||||||
|
uint16_t sregs[4];
|
||||||
|
|
||||||
|
uint16_t ip;
|
||||||
|
|
||||||
|
int32_t SignVal;
|
||||||
|
int32_t AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
|
||||||
|
|
||||||
|
uint32_t TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
|
||||||
|
|
||||||
|
uint32_t int_vector;
|
||||||
|
uint32_t pending_irq;
|
||||||
|
uint32_t nmi_state;
|
||||||
|
uint32_t irq_state;
|
||||||
|
int (*irq_callback)(int irqline);
|
||||||
|
} nec_Regs;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
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_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_ */
|
||||||
@@ -1,12 +1,3 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* necmodrm.h:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
@@ -27,7 +18,7 @@ static struct
|
|||||||
#define GetRMWord(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) \
|
#define PutbackRMWord(ModRM,val) \
|
||||||
{ \
|
{ \
|
||||||
if (ModRM >= 0xc0) I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
|
if (ModRM >= 0xc0) I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
|
||||||
else WriteWord(EA,val); \
|
else WriteWord(EA,val); \
|
||||||
@@ -35,7 +26,7 @@ static struct
|
|||||||
|
|
||||||
#define GetnextRMWord ReadWord((EA&0xf0000)|((EA+2)&0xffff))
|
#define GetnextRMWord ReadWord((EA&0xf0000)|((EA+2)&0xffff))
|
||||||
|
|
||||||
#define PutRMWord(ModRM, val) \
|
#define PutRMWord(ModRM,val) \
|
||||||
{ \
|
{ \
|
||||||
if (ModRM >= 0xc0) \
|
if (ModRM >= 0xc0) \
|
||||||
I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
|
I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
|
||||||
@@ -60,7 +51,7 @@ static struct
|
|||||||
#define GetRMByte(ModRM) \
|
#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) \
|
#define PutRMByte(ModRM,val) \
|
||||||
{ \
|
{ \
|
||||||
if (ModRM >= 0xc0) \
|
if (ModRM >= 0xc0) \
|
||||||
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
|
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
|
||||||
@@ -78,7 +69,7 @@ static struct
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PutbackRMByte(ModRM, val) \
|
#define PutbackRMByte(ModRM,val) \
|
||||||
{ \
|
{ \
|
||||||
if (ModRM >= 0xc0) \
|
if (ModRM >= 0xc0) \
|
||||||
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
|
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
|
||||||
|
|||||||
2
source/nec/v30debug.cpp
Normal file
2
source/nec/v30debug.cpp
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/* v30 debugger */
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* buttons.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
case 0xb5:
|
|
||||||
|
|
||||||
read
|
|
||||||
w1 = ws_ioRam[0xb5];
|
|
||||||
|
|
||||||
if (w1 & 0x40)
|
|
||||||
{
|
|
||||||
w2 = 0x00;
|
|
||||||
w2 = (ws_key_start << 1) | (ws_key_button_a << 2) | (ws_key_button_b << 3);
|
|
||||||
retVal = (uint8_t)((w1 & 0xf0) | w2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w1 & 0x20)
|
|
||||||
{
|
|
||||||
w2 = 0x00;
|
|
||||||
w2 = (ws_key_x1 << 0) | (ws_key_x2 << 1) | (ws_key_x3 << 2) | (ws_key_x4 << 3);
|
|
||||||
retVal = (uint8_t)((w1 & 0xf0) | w2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (w1 & 0x10)
|
|
||||||
{
|
|
||||||
w2 = 0x00;
|
|
||||||
w2 = (ws_key_y1 << 0) | (ws_key_y2 << 1) | (ws_key_y3 << 2) | (ws_key_y4 << 3);
|
|
||||||
retVal = (uint8_t)((w1 & 0xf0) | w2);
|
|
||||||
}
|
|
||||||
|
|
||||||
write:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* color_gpu.c: Implementation of the color GPU (Wonderswan Color & SwanCrystal)
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 14/03/2022.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* color_system.c: IO specific to the WonderSwan Color systems.
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
Shall we split color and crystal, there are some subtles differences on some registers
|
|
||||||
|
|
||||||
READ
|
|
||||||
|
|
||||||
case 0x62:
|
|
||||||
switch (ws_get_system())
|
|
||||||
{
|
|
||||||
case WS_SYSTEM_AUTODETECT:
|
|
||||||
case WS_SYSTEM_MONO:
|
|
||||||
case WS_SYSTEM_COLOR:
|
|
||||||
retVal = 0x00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WS_SYSTEM_CRYSTAL:
|
|
||||||
retVal = 0x80;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WRITE
|
|
||||||
|
|
||||||
if ((port == 0xA0) && (ws_ioRam[port] & 0x01) && (~value & 0x01))
|
|
||||||
{
|
|
||||||
value |= 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xA0:
|
|
||||||
|
|
||||||
/* Force cart handshake to be set */
|
|
||||||
ws_ioRam[port] |= 0x80;
|
|
||||||
|
|
||||||
if (value & 0x01)
|
|
||||||
{
|
|
||||||
Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value);
|
|
||||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
|
||||||
uint32_t romSize;
|
|
||||||
uint8_t *rom = getRom(&romSize);
|
|
||||||
set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* debug.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
extern uint8_t *ws_ioRam;
|
|
||||||
|
|
||||||
uint8_t debug_io_read(void *pdata, uint8_t port)
|
|
||||||
{
|
|
||||||
switch (port)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void debug_io_write(void *pdata, uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
switch (port)
|
|
||||||
{
|
|
||||||
case 0xF1:
|
|
||||||
printf("%d\n", (signed short)((value << 8) | ws_ioRam[0xF0]));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xF2:
|
|
||||||
printf("%c", value);
|
|
||||||
fflush(stdout);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* dma.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
Need to check how to differenciate all the DMA types.
|
|
||||||
|
|
||||||
|
|
||||||
WRITE:
|
|
||||||
|
|
||||||
case 0x48: // DMA
|
|
||||||
|
|
||||||
// bit 7 set to start dma transfer
|
|
||||||
if (value & 0x80)
|
|
||||||
{
|
|
||||||
uint32_t dma_start = (ws_ioRam[0x41] << 8) | (ws_ioRam[0x40]) | (ws_ioRam[0x42] << 16);
|
|
||||||
uint32_t dma_dest = (ws_ioRam[0x45] << 8) | (ws_ioRam[0x44]) | (ws_ioRam[0x43] << 16);
|
|
||||||
uint32_t dma_size = (ws_ioRam[0x47] << 8) | (ws_ioRam[0x46]);
|
|
||||||
|
|
||||||
uint8_t dma_inc = (value & 0x01) ? -1: 1;
|
|
||||||
|
|
||||||
Log(TLOG_VERBOSE, "DMA", "Starting DMA from %08X to %08X (len: %08X, inc: %d)",
|
|
||||||
dma_start, dma_dest, dma_size, dma_inc);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (uint32_t ix = 0 ; ix < dma_size ; ix++)
|
|
||||||
{
|
|
||||||
mem_writemem20(dma_dest, mem_readmem20(dma_start));
|
|
||||||
dma_start += dma_inc;
|
|
||||||
dma_dest += dma_inc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ws_ioRam[0x47] = 0;
|
|
||||||
ws_ioRam[0x46] = 0;
|
|
||||||
ws_ioRam[0x41] = (uint8_t)(dma_start >> 8);
|
|
||||||
ws_ioRam[0x40] = (uint8_t)(dma_start & 0xff);
|
|
||||||
ws_ioRam[0x45] = (uint8_t)(dma_dest >> 8);
|
|
||||||
ws_ioRam[0x44] = (uint8_t)(dma_dest & 0xff);
|
|
||||||
ws_ioRam[0x48] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
/* DMAs */
|
|
||||||
case 0x40:
|
|
||||||
case 0x41:
|
|
||||||
case 0x42:
|
|
||||||
case 0x43:
|
|
||||||
case 0x44:
|
|
||||||
case 0x45:
|
|
||||||
case 0x46:
|
|
||||||
case 0x47:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x48: // DMA
|
|
||||||
|
|
||||||
// bit 7 set to start dma transfer
|
|
||||||
if (value & 0x80)
|
|
||||||
{
|
|
||||||
uint32_t dma_start = (ws_ioRam[0x41] << 8) | (ws_ioRam[0x40]) | (ws_ioRam[0x42] << 16);
|
|
||||||
uint32_t dma_dest = (ws_ioRam[0x45] << 8) | (ws_ioRam[0x44]) | (ws_ioRam[0x43] << 16);
|
|
||||||
uint32_t dma_size = (ws_ioRam[0x47] << 8) | (ws_ioRam[0x46]);
|
|
||||||
|
|
||||||
uint8_t dma_inc = (value & 0x01) ? -1: 1;
|
|
||||||
|
|
||||||
Log(TLOG_VERBOSE, "DMA", "Starting DMA from %08X to %08X (len: %08X, inc: %d)",
|
|
||||||
dma_start, dma_dest, dma_size, dma_inc);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (uint32_t ix = 0 ; ix < dma_size ; ix++)
|
|
||||||
{
|
|
||||||
mem_writemem20(dma_dest, mem_readmem20(dma_start));
|
|
||||||
dma_start += dma_inc;
|
|
||||||
dma_dest += dma_inc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ws_ioRam[0x47] = 0;
|
|
||||||
ws_ioRam[0x46] = 0;
|
|
||||||
ws_ioRam[0x41] = (uint8_t)(dma_start >> 8);
|
|
||||||
ws_ioRam[0x40] = (uint8_t)(dma_start & 0xff);
|
|
||||||
ws_ioRam[0x45] = (uint8_t)(dma_dest >> 8);
|
|
||||||
ws_ioRam[0x44] = (uint8_t)(dma_dest & 0xff);
|
|
||||||
ws_ioRam[0x48] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* DMA Start! */
|
|
||||||
case 0x52:
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,336 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* eeprom.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <memory.h>
|
|
||||||
#include <nec.h>
|
|
||||||
#include <log.h>
|
|
||||||
#include <gpu.h>
|
|
||||||
|
|
||||||
extern uint8_t *externalEeprom;
|
|
||||||
extern uint16_t *internalEeprom;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
EEPROM_SUBCOMMAND = 0, /* 00 00 */
|
|
||||||
EEPROM_WRITE, /* 01 xx */
|
|
||||||
EEPROM_READ, /* 10 xx */
|
|
||||||
EEPROM_ERASE, /* 11 xx */
|
|
||||||
EEPROM_WRITEDISABLE, /* 00 00 */
|
|
||||||
EEPROM_WRITEALL, /* 00 01 */
|
|
||||||
EEPROM_ERASEALL, /* 00 10 */
|
|
||||||
EEPROM_WRITEENABLE /* 00 11 */
|
|
||||||
};
|
|
||||||
|
|
||||||
char *eii_CommandName[] = {
|
|
||||||
"SUB", "WRI", "RED", "ERA", "WRD", "WRA", "ERL", "WRE",
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t iee_WriteEnable = false;
|
|
||||||
uint16_t iee_SelAddress = 0;
|
|
||||||
uint16_t iee_Databuffer = 0;
|
|
||||||
uint8_t iee_Mode = EEPROM_READ;
|
|
||||||
|
|
||||||
uint8_t cee_WriteEnable = true;
|
|
||||||
uint16_t cee_SelAddress = 0;
|
|
||||||
uint16_t cee_Databuffer = 0;
|
|
||||||
uint8_t cee_Mode = EEPROM_READ;
|
|
||||||
|
|
||||||
// TODO: temporary
|
|
||||||
extern uint8_t *ws_ioRam;
|
|
||||||
|
|
||||||
uint8_t rs232_io_read(void *pdata, uint8_t port)
|
|
||||||
{
|
|
||||||
uint8_t retVal;
|
|
||||||
switch (port)
|
|
||||||
{
|
|
||||||
case 0xba: // eeprom even byte read
|
|
||||||
retVal = iee_Databuffer & 0x00FF;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xbb: // eeprom odd byte read
|
|
||||||
retVal = (iee_Databuffer & 0xFF00) >> 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xbe: // internal eeprom status/command register
|
|
||||||
// ack eeprom write
|
|
||||||
if (ws_ioRam[0xbe] & 0x20)
|
|
||||||
{
|
|
||||||
retVal = ws_ioRam[0xbe] | 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ack eeprom read
|
|
||||||
if (ws_ioRam[0xbe] & 0x10)
|
|
||||||
{
|
|
||||||
retVal = ws_ioRam[0xbe] | 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// else ack both
|
|
||||||
retVal = ws_ioRam[0xbe] | 3;
|
|
||||||
break;
|
|
||||||
case 0xC8:
|
|
||||||
// ack eeprom write
|
|
||||||
if (ws_ioRam[0xbe] & 0x20)
|
|
||||||
{
|
|
||||||
retVal = ws_ioRam[0xbe] | 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ack eeprom read
|
|
||||||
if (ws_ioRam[0xbe] & 0x10)
|
|
||||||
{
|
|
||||||
retVal = ws_ioRam[0xbe] | 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// else ack both
|
|
||||||
retVal = ws_ioRam[0xbe] | 3;
|
|
||||||
break;
|
|
||||||
case 0xC4: // eeprom even byte read
|
|
||||||
return cee_Databuffer & 0x00FF;
|
|
||||||
case 0xC5: // eeprom odd byte read
|
|
||||||
return (cee_Databuffer & 0xFF00) >> 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rs232_io_write(void *pdata, uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
uint8_t retVal;
|
|
||||||
switch (port)
|
|
||||||
{
|
|
||||||
/* Internal EEPROM */
|
|
||||||
case 0xba: /* DATA Low */
|
|
||||||
iee_Databuffer = iee_Databuffer & 0xFF00;
|
|
||||||
iee_Databuffer = iee_Databuffer | (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xbb: /* Data High */
|
|
||||||
iee_Databuffer = iee_Databuffer & 0x00FF;
|
|
||||||
iee_Databuffer = iee_Databuffer | (value << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xBC: /* Address Low */
|
|
||||||
case 0xBD: /* Address High */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xBE: /* Command / Status */
|
|
||||||
{
|
|
||||||
uint16_t address, command, subcmd;
|
|
||||||
|
|
||||||
iee_SelAddress = (ws_ioRam[0xBD] << 8) | ws_ioRam[0xBC];
|
|
||||||
|
|
||||||
if (ws_gpu_operatingInColor)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
13 00
|
|
||||||
S CCaa AAAA AAAA
|
|
||||||
0001 0011 0000 0000
|
|
||||||
|
|
||||||
*/
|
|
||||||
/* S CC aaAAAAAAAA */
|
|
||||||
command = (iee_SelAddress >> 10) & 0x3;
|
|
||||||
address = iee_SelAddress & 0x3FF;
|
|
||||||
subcmd = (iee_SelAddress >> 8) & 0x03;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* S CC aaAAAA */
|
|
||||||
command = (iee_SelAddress >> 6) & 0x3;
|
|
||||||
address = iee_SelAddress & 0x3F;
|
|
||||||
subcmd = (iee_SelAddress >> 4) & 0x03;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (command == EEPROM_SUBCOMMAND)
|
|
||||||
{
|
|
||||||
command = EEPROM_WRITEDISABLE + subcmd;
|
|
||||||
}
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf("IEEP: RA:%04X RD:%04X A:%03X C:%s", iee_SelAddress, iee_Databuffer, address, eii_CommandName[command]);
|
|
||||||
#endif
|
|
||||||
if (value & 0x40)
|
|
||||||
{
|
|
||||||
/* Sub command */
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" - Sub");
|
|
||||||
#endif
|
|
||||||
if (command == EEPROM_WRITEENABLE)
|
|
||||||
{
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" Write Enable\n");
|
|
||||||
#endif
|
|
||||||
iee_WriteEnable = true;
|
|
||||||
}
|
|
||||||
else if (command == EEPROM_WRITEDISABLE)
|
|
||||||
{
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" Write Disable\n");
|
|
||||||
#endif
|
|
||||||
iee_WriteEnable = false;
|
|
||||||
}
|
|
||||||
else if (command == EEPROM_ERASEALL)
|
|
||||||
{
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" Erase All\n");
|
|
||||||
#endif
|
|
||||||
if (ws_gpu_operatingInColor)
|
|
||||||
{
|
|
||||||
//memset(internalEeprom, 0, COLOR_IEEPROM_SIZE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//memset(internalEeprom, 0, BW_IEEPROM_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" Write All?\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (value & 0x20)
|
|
||||||
{
|
|
||||||
/* Write */
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" - Write?");
|
|
||||||
#endif
|
|
||||||
if (iee_WriteEnable)
|
|
||||||
{
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" Yes : %04X\n", iee_Databuffer);
|
|
||||||
#endif
|
|
||||||
internalEeprom[address] = iee_Databuffer;
|
|
||||||
}
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" No\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (value & 0x10)
|
|
||||||
{
|
|
||||||
/* Read */
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" - Read");
|
|
||||||
#endif
|
|
||||||
iee_Databuffer = internalEeprom[address];
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
printf(" Data : %04X\n", iee_Databuffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef EEPROM_DEBUG
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" Unknown value: %02X\n", value);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Cart EEPROM */
|
|
||||||
case 0xC4: /* Data High */
|
|
||||||
cee_Databuffer = cee_Databuffer & 0xFF00;
|
|
||||||
cee_Databuffer = cee_Databuffer | (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xC5: /* Data High */
|
|
||||||
cee_Databuffer = cee_Databuffer & 0x00FF;
|
|
||||||
cee_Databuffer = cee_Databuffer | (value << 8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xC6: /* Address Low */
|
|
||||||
case 0xC7: /* Address High */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xC8: /* Command / Status */
|
|
||||||
{
|
|
||||||
uint16_t address, command, subcmd; /*, start;*/
|
|
||||||
|
|
||||||
cee_SelAddress = (ws_ioRam[0xBD] << 8) | ws_ioRam[0xBC];
|
|
||||||
|
|
||||||
/* S CC aaAAAA */
|
|
||||||
command = (cee_SelAddress >> 6) & 0x3;
|
|
||||||
address = cee_SelAddress & 0x3F;
|
|
||||||
subcmd = (cee_SelAddress >> 4) & 0x03;
|
|
||||||
|
|
||||||
|
|
||||||
if (command == EEPROM_SUBCOMMAND)
|
|
||||||
{
|
|
||||||
command = EEPROM_WRITEDISABLE + subcmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("CEEP: RA:%04X RD:%04X A:%03X C:%s", cee_SelAddress, cee_Databuffer, address, eii_CommandName[command]);
|
|
||||||
|
|
||||||
if (value & 0x40)
|
|
||||||
{
|
|
||||||
/* Sub command */
|
|
||||||
printf(" - Sub");
|
|
||||||
if (command == EEPROM_WRITEENABLE)
|
|
||||||
{
|
|
||||||
printf(" Write Enable\n");
|
|
||||||
cee_WriteEnable = true;
|
|
||||||
}
|
|
||||||
else if (command == EEPROM_WRITEDISABLE)
|
|
||||||
{
|
|
||||||
printf(" Write Disable\n");
|
|
||||||
cee_WriteEnable = false;
|
|
||||||
}
|
|
||||||
else if (command == EEPROM_ERASEALL)
|
|
||||||
{
|
|
||||||
printf(" Erase All\n");
|
|
||||||
/* Nothing here at the moment */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" Write All?\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (value & 0x20)
|
|
||||||
{
|
|
||||||
/* Write */
|
|
||||||
printf(" - Write?");
|
|
||||||
if (cee_WriteEnable)
|
|
||||||
{
|
|
||||||
printf(" Yes : %04X\n", cee_Databuffer);
|
|
||||||
externalEeprom[address] = cee_Databuffer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" No\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (value & 0x10)
|
|
||||||
{
|
|
||||||
/* Read */
|
|
||||||
printf(" - Read");
|
|
||||||
cee_Databuffer = externalEeprom[address];
|
|
||||||
printf(" Data : %04X\n", cee_Databuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf(" Unknown value: %02X@", value);
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xCB:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* interrupt_controller.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 14/03/2022.
|
|
||||||
* Copyright (c) 2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <device.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <interrupt_controller.h>
|
|
||||||
|
|
||||||
/* device internal parameters */
|
|
||||||
typedef struct ic_params_t
|
|
||||||
{
|
|
||||||
uint8_t address_base;
|
|
||||||
uint8_t int_enable_mask;
|
|
||||||
uint8_t int_status;
|
|
||||||
} ic_params_t;
|
|
||||||
|
|
||||||
static ic_params_t interrupt_controller;
|
|
||||||
|
|
||||||
static uint8_t IC_IO_read(void *pdata, uint8_t port)
|
|
||||||
{
|
|
||||||
ic_params_t *params = (ic_params_t *)pdata;
|
|
||||||
|
|
||||||
switch(port)
|
|
||||||
{
|
|
||||||
case 0x0: return params->address_base;
|
|
||||||
case 0x2: return params->int_enable_mask;
|
|
||||||
case 0x4: return params->int_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0x90;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void IC_IO_write(void *pdata, uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
ic_params_t *params = (ic_params_t *)pdata;
|
|
||||||
|
|
||||||
switch(port)
|
|
||||||
{
|
|
||||||
case 0x0: params->address_base = value; break;
|
|
||||||
case 0x2: params->int_enable_mask = value; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void IC_IO_write_ack(void *pdata, uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
ic_params_t *params = (ic_params_t *)pdata;
|
|
||||||
|
|
||||||
// De-assert CPU interrupt accordingly to the mask in value
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void IC_init(uint8_t baseAddress, void *params)
|
|
||||||
{
|
|
||||||
UNUSED_PARAMETER(params);
|
|
||||||
|
|
||||||
register_io_hook(baseAddress, 0x0, IC_IO_read, IC_IO_write, &interrupt_controller);
|
|
||||||
register_io_hook(baseAddress, 0x2, IC_IO_read, IC_IO_write, &interrupt_controller);
|
|
||||||
register_io_hook(baseAddress, 0x4, IC_IO_read, NULL, &interrupt_controller);
|
|
||||||
register_io_hook(baseAddress, 0x6, NULL, IC_IO_write_ack, &interrupt_controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void IC_reset()
|
|
||||||
{
|
|
||||||
interrupt_controller.int_enable_mask = 0;
|
|
||||||
interrupt_controller.address_base = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
device_t InterruptController =
|
|
||||||
{
|
|
||||||
.init = IC_init,
|
|
||||||
.reset = IC_reset,
|
|
||||||
.free = NULL,
|
|
||||||
.deviceType = DT_INTERRUPT_CONTROLLER,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Exported functions */
|
|
||||||
void trigger_interrupt(hw_interrupt_type_t type)
|
|
||||||
{
|
|
||||||
uint16_t int_vector = interrupt_controller.address_base & 0xF8 + (uint8_t)type;
|
|
||||||
|
|
||||||
/* Check that the INT is enabled */
|
|
||||||
if ((interrupt_controller.int_enable_mask >> type) & 0x1)
|
|
||||||
{
|
|
||||||
/* TODO: Do we have to enable that even if the int is not enabled? */
|
|
||||||
interrupt_controller.int_status |= (1 << type);
|
|
||||||
|
|
||||||
// Fire the NEC interrupt
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* mono_gpu.c: Implementation of the monochrome GPU
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 14/03/2022.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
READ
|
|
||||||
|
|
||||||
case 0xA0:
|
|
||||||
case 0xAA:
|
|
||||||
case 0xAB:
|
|
||||||
case 0xAC:
|
|
||||||
case 0xAD:
|
|
||||||
retVal = ws_gpu_port_read(port);
|
|
||||||
|
|
||||||
WRITE
|
|
||||||
|
|
||||||
case 0x00:
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Screen enabled: W2:%c W2M:%c, SW:%c, S:%c, S2:%c, S1:%c",
|
|
||||||
(value & 0x20)?'Y':'N',
|
|
||||||
(value & 0x10)?'I':'O',
|
|
||||||
(value & 0x08)?'Y':'N',
|
|
||||||
(value & 0x04)?'Y':'N',
|
|
||||||
(value & 0x02)?'Y':'N',
|
|
||||||
(value & 0x01)?'Y':'N');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x04:
|
|
||||||
if (ws_gpu_operatingInColor)
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Sprite base: %04X", (value & 0x1F) << 9);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Sprite base: %04X", (value & 0x3F) << 9);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
if (ws_gpu_operatingInColor)
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen1 base: %04X", (value & 0x7) << 11);
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen2 base: %04X", (value & 0x70) << (11-4));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen1 base: %04X", (value & 0xF) << 11);
|
|
||||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen2 base: %04X", (value & 0xF0) << (11-4));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen1 X scroll: %d", value);
|
|
||||||
break;
|
|
||||||
case 0x11:
|
|
||||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen1 T scroll: %d", value);
|
|
||||||
break;
|
|
||||||
case 0x12:
|
|
||||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen2 X scroll: %d", value);
|
|
||||||
break;
|
|
||||||
case 0x13:
|
|
||||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen2 Y scroll: %d", value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x01:
|
|
||||||
case 0x02:
|
|
||||||
case 0x03:
|
|
||||||
case 0x05:
|
|
||||||
case 0x06:
|
|
||||||
case 0x08:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0A:
|
|
||||||
case 0x0B:
|
|
||||||
case 0x0C:
|
|
||||||
case 0x0D:
|
|
||||||
case 0x0E:
|
|
||||||
case 0x0F:
|
|
||||||
case 0x14:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x15:
|
|
||||||
Log(TLOG_DEBUG, "io", "Icons %c %c %c %c %c %c %c %c", (value >> 7) & 1 ? '?' : ' ', (value >> 6) & 1 ? '?' : ' ',
|
|
||||||
(value >> 5) & 1 ? '3' : ' ', (value >> 4) & 1 ? '2' : ' ', (value >> 3) & 1 ? '1' : ' ',
|
|
||||||
(value >> 2) & 1 ? 'H' : ' ', (value >> 1) & 1 ? 'V' : ' ', (value >> 0) & 1 ? 'S' : ' ');
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
/* Palettes ? */
|
|
||||||
case 0x1C:
|
|
||||||
case 0x25:
|
|
||||||
case 0x2F:
|
|
||||||
case 0x38:
|
|
||||||
case 0x1D:
|
|
||||||
case 0x26:
|
|
||||||
case 0x30:
|
|
||||||
case 0x39:
|
|
||||||
case 0x1E:
|
|
||||||
case 0x27:
|
|
||||||
case 0x31:
|
|
||||||
case 0x3A:
|
|
||||||
case 0x1F:
|
|
||||||
case 0x28:
|
|
||||||
case 0x32:
|
|
||||||
case 0x3B:
|
|
||||||
case 0x20:
|
|
||||||
case 0x29:
|
|
||||||
case 0x33:
|
|
||||||
case 0x3C:
|
|
||||||
case 0x21:
|
|
||||||
case 0x2A:
|
|
||||||
case 0x34:
|
|
||||||
case 0x3E:
|
|
||||||
case 0x22:
|
|
||||||
case 0x2B:
|
|
||||||
case 0x35:
|
|
||||||
case 0x3F:
|
|
||||||
case 0x23:
|
|
||||||
case 0x2C:
|
|
||||||
case 0x36:
|
|
||||||
case 0x24:
|
|
||||||
case 0x2E:
|
|
||||||
case 0x37:
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* mono_system.c: IOs specific to the original WonderSwan
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
READ
|
|
||||||
|
|
||||||
|
|
||||||
case 0x62:
|
|
||||||
switch (ws_get_system())
|
|
||||||
{
|
|
||||||
case WS_SYSTEM_AUTODETECT:
|
|
||||||
case WS_SYSTEM_MONO:
|
|
||||||
case WS_SYSTEM_COLOR:
|
|
||||||
retVal = 0x00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WS_SYSTEM_CRYSTAL:
|
|
||||||
retVal = 0x80;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
WRITE
|
|
||||||
|
|
||||||
if ((port == 0xA0) && (ws_ioRam[port] & 0x01) && (~value & 0x01))
|
|
||||||
{
|
|
||||||
value |= 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xA0:
|
|
||||||
|
|
||||||
/* Force cart handshake to be set */
|
|
||||||
ws_ioRam[port] |= 0x80;
|
|
||||||
|
|
||||||
if (value & 0x01)
|
|
||||||
{
|
|
||||||
Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value);
|
|
||||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
|
||||||
uint32_t romSize;
|
|
||||||
uint8_t *rom = getRom(&romSize);
|
|
||||||
set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
case 0x62:
|
|
||||||
switch (ws_get_system())
|
|
||||||
{
|
|
||||||
case WS_SYSTEM_AUTODETECT:
|
|
||||||
case WS_SYSTEM_MONO:
|
|
||||||
case WS_SYSTEM_COLOR:
|
|
||||||
retVal = 0x00;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WS_SYSTEM_CRYSTAL:
|
|
||||||
retVal = 0x80;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case 0xA0:
|
|
||||||
|
|
||||||
/* Force cart handshake to be set */
|
|
||||||
ws_ioRam[port] |= 0x80;
|
|
||||||
|
|
||||||
if (value & 0x01)
|
|
||||||
{
|
|
||||||
Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value);
|
|
||||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
|
||||||
uint32_t romSize;
|
|
||||||
uint8_t *rom = getRom(&romSize);
|
|
||||||
set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* rs232.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <unistd.h> /* UNIX standard function definitions */
|
|
||||||
#include <errno.h> /* Error number definitions */
|
|
||||||
#include <termios.h> /* POSIX terminal control definitions */
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <nec.h>
|
|
||||||
#include <log.h>
|
|
||||||
|
|
||||||
/* Temporary */
|
|
||||||
extern uint8_t *ws_ioRam;
|
|
||||||
|
|
||||||
/* Serial port */
|
|
||||||
#define BDR_9600 (0)
|
|
||||||
#define BDR_38400 (1)
|
|
||||||
#define SERIAL_PORT "/dev/tty.USA19H141P1.1"
|
|
||||||
static int serialfd = -1;
|
|
||||||
static int serial_have_data = 0;
|
|
||||||
static unsigned char serial_data = 0;
|
|
||||||
static int serial_speed = BDR_9600;
|
|
||||||
|
|
||||||
static void open_serial()
|
|
||||||
{
|
|
||||||
if (serialfd < 0)
|
|
||||||
{
|
|
||||||
serialfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
|
|
||||||
|
|
||||||
//set_baudrate(serial_speed);
|
|
||||||
serial_have_data = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_baudrate(int speed)
|
|
||||||
{
|
|
||||||
struct termios options;
|
|
||||||
|
|
||||||
if (serialfd < 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tcgetattr(serialfd, &options);
|
|
||||||
|
|
||||||
options.c_cflag &= ~PARENB;
|
|
||||||
options.c_cflag &= ~CSTOPB;
|
|
||||||
options.c_cflag &= ~CSIZE;
|
|
||||||
options.c_cflag |= CS8;
|
|
||||||
|
|
||||||
if (speed == BDR_9600)
|
|
||||||
{
|
|
||||||
cfsetispeed(&options, B9600);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cfsetospeed(&options, B38400);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
options.c_cflag &= ~CNEW_RTSCTS;
|
|
||||||
#else
|
|
||||||
options.c_cflag &= ~CRTSCTS;
|
|
||||||
#endif
|
|
||||||
options.c_cflag |= (CLOCAL | CREAD);
|
|
||||||
|
|
||||||
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
|
||||||
|
|
||||||
options.c_oflag &= ~OPOST;
|
|
||||||
|
|
||||||
tcsetattr(serialfd, TCSANOW, &options);
|
|
||||||
|
|
||||||
/* Make sure read is not blocking */
|
|
||||||
fcntl(serialfd, F_SETFL, FNDELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void close_serial()
|
|
||||||
{
|
|
||||||
close(serialfd);
|
|
||||||
serialfd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_serial_data()
|
|
||||||
{
|
|
||||||
unsigned char buf[10];
|
|
||||||
int f;
|
|
||||||
|
|
||||||
if (serialfd < 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serial_have_data == 0)
|
|
||||||
{
|
|
||||||
f = read(serialfd, buf, 1);
|
|
||||||
|
|
||||||
if (f > 0)
|
|
||||||
{
|
|
||||||
Log(TLOG_DEBUG, "serial", "Have data from serial [%d]!", f);
|
|
||||||
fflush(stdout);
|
|
||||||
serial_have_data = 0x01;
|
|
||||||
serial_data = buf[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serial_have_data > 0)
|
|
||||||
{
|
|
||||||
/* Gen an int if enabled */
|
|
||||||
if (ws_ioRam[0xB2] & 0x04)
|
|
||||||
{
|
|
||||||
ws_ioRam[0xb6] &= ~0x04;
|
|
||||||
Log(TLOG_DEBUG, "serial", "SERIAL INNNNNTTTT!!!!!!!");
|
|
||||||
nec_int((ws_ioRam[0xb0] + 3) * 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char read_serial()
|
|
||||||
{
|
|
||||||
unsigned char buf[10];
|
|
||||||
int f;
|
|
||||||
|
|
||||||
if (serialfd < 0)
|
|
||||||
{
|
|
||||||
return 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serial_have_data > 0)
|
|
||||||
{
|
|
||||||
serial_have_data = 0;
|
|
||||||
return serial_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
f = read(serialfd, buf, 1);
|
|
||||||
|
|
||||||
if (f == 1)
|
|
||||||
{
|
|
||||||
return buf[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0x42;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_serial(unsigned char value)
|
|
||||||
{
|
|
||||||
if (serialfd < 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
write(serialfd, &value, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t rs232_io_read(void *pdata, uint8_t port)
|
|
||||||
{
|
|
||||||
uint8_t retVal;
|
|
||||||
switch(port)
|
|
||||||
{
|
|
||||||
case 0xB1:
|
|
||||||
retVal = read_serial();
|
|
||||||
Log(TLOG_DEBUG, "serial", "Read %02X", retVal);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 0xB3:
|
|
||||||
check_serial_data();
|
|
||||||
|
|
||||||
if (ws_ioRam[0xB3] & 0x80)
|
|
||||||
{
|
|
||||||
retVal = (ws_ioRam[0xB3] & ~1) | serial_have_data | 0x04;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
retVal = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(TLOG_DEBUG, "serial", "<<<<RS232STA: %02X [%c%c%cxx%c%c%c]", retVal, (retVal & 0x80) ? 'E' : 'd',
|
|
||||||
(retVal & 0x40) ? '3' : '9', (retVal & 0x20) ? 'R' : 'n', (retVal & 0x04) ? 'E' : 'f',
|
|
||||||
(retVal & 0x02) ? 'V' : 'n', (retVal & 0x01) ? 'D' : 'e');
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rs232_io_write(void *pdata, uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
switch(port)
|
|
||||||
{
|
|
||||||
case 0xB1:
|
|
||||||
write_serial(value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xB3:
|
|
||||||
Log(TLOG_DEBUG, "serial", ">>>>RS232STA: %02X [%c%c%cxx%c%c%c]", value, (value & 0x80) ? 'E' : 'd', (value & 0x40) ? '3' : '9',
|
|
||||||
(value & 0x20) ? 'R' : 'n', (value & 0x04) ? 'E' : 'f', (value & 0x02) ? 'V' : 'n',
|
|
||||||
(value & 0x01) ? 'D' : 'e');
|
|
||||||
|
|
||||||
/* Serial status: 7 = Enable, 6 = baudrate, 5 = Overrun reset
|
|
||||||
2 = Send Buffer empty
|
|
||||||
1 = Overrun
|
|
||||||
0 = Data Received
|
|
||||||
*/
|
|
||||||
serial_speed = ((value & 040) == 0x00) ? BDR_9600 : BDR_38400;
|
|
||||||
|
|
||||||
if ((value & 0x80) == 0x80)
|
|
||||||
{
|
|
||||||
open_serial();
|
|
||||||
set_baudrate(serial_speed);
|
|
||||||
check_serial_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rs232_init()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* rtc.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
static int rtcDataRegisterReadCount = 0;
|
|
||||||
|
|
||||||
// TODO: Temporary to let build for now
|
|
||||||
static uint8_t ws_ioRam[0x100];
|
|
||||||
|
|
||||||
uint8_t rtc_io_read(void *pdata, uint8_t port)
|
|
||||||
{
|
|
||||||
uint8_t retVal = 0;
|
|
||||||
|
|
||||||
switch (port)
|
|
||||||
{
|
|
||||||
case 0xca : // RTC Command and status register
|
|
||||||
// set ack to always 1
|
|
||||||
retVal = (ws_ioRam[0xca] | 0x80);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 0xcb : // RTC data register
|
|
||||||
|
|
||||||
if (ws_ioRam[0xca] == 0x15) // get time command
|
|
||||||
{
|
|
||||||
struct tm *newtime;
|
|
||||||
time_t long_time;
|
|
||||||
time(&long_time);
|
|
||||||
newtime = localtime(&long_time);
|
|
||||||
|
|
||||||
#define BCD(value) ((value/10)<<4)|(value%10)
|
|
||||||
|
|
||||||
switch (rtcDataRegisterReadCount)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
rtcDataRegisterReadCount++;
|
|
||||||
retVal = BCD(newtime->tm_year - 100);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
rtcDataRegisterReadCount++;
|
|
||||||
retVal = BCD(newtime->tm_mon);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
rtcDataRegisterReadCount++;
|
|
||||||
retVal = BCD(newtime->tm_mday);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
rtcDataRegisterReadCount++;
|
|
||||||
retVal = BCD(newtime->tm_wday);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
rtcDataRegisterReadCount++;
|
|
||||||
retVal = BCD(newtime->tm_hour);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
rtcDataRegisterReadCount++;
|
|
||||||
retVal = BCD(newtime->tm_min);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
rtcDataRegisterReadCount = 0;
|
|
||||||
retVal = BCD(newtime->tm_sec);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// set ack
|
|
||||||
retVal = (ws_ioRam[0xcb] | 0x80);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rtc_io_write(void *pdata, uint8_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
switch(port)
|
|
||||||
{
|
|
||||||
case 0xca:
|
|
||||||
if (value == 0x15)
|
|
||||||
{
|
|
||||||
rtcDataRegisterReadCount = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* timer.c:
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 26/06/2022.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* universal_luxor.c: Implement a "universal" version of both known version
|
|
||||||
* of Luxor (Bandai 2001 and Bandai 2003) as there is no way from the ROM
|
|
||||||
* to really know which version is on the original cart.
|
|
||||||
*
|
|
||||||
* Created by Manoël Trapier on 19/12/2021.
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
READ
|
|
||||||
|
|
||||||
case 0xc0 : // ???
|
|
||||||
retVal = ((ws_ioRam[0xc0] & 0xf) | 0x20);
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 0xD0:
|
|
||||||
retVal = 0;
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
case 0xCC:
|
|
||||||
case 0xCD:
|
|
||||||
retVal = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WRITE
|
|
||||||
|
|
||||||
case 0xC0:
|
|
||||||
{
|
|
||||||
/* page 4 to F */
|
|
||||||
uint32_t romSize;
|
|
||||||
uint8_t *rom = getRom(&romSize);
|
|
||||||
for (int i = 0x04 ; i < 0x10 ; i++)
|
|
||||||
{
|
|
||||||
set_memory_bank(i, ws_get_page_ptr(rom, romSize, (value << 4) + i));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ws_ioRam[0xA0] & 0x01))
|
|
||||||
{
|
|
||||||
set_irom_overlay();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xC1:
|
|
||||||
/* Sram bank */
|
|
||||||
if (sramSize > 0)
|
|
||||||
{
|
|
||||||
uint32_t sramSize;
|
|
||||||
uint8_t *sram = getSram(&sramSize);
|
|
||||||
set_memory_bank(0x1, ws_get_page_ptr(sram, sramSize, value));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xC2:
|
|
||||||
{
|
|
||||||
/* page 4 to F */
|
|
||||||
uint32_t romSize;
|
|
||||||
uint8_t *rom = getRom(&romSize);
|
|
||||||
/* Page 2 */
|
|
||||||
set_memory_bank(0x2, ws_get_page_ptr(rom, romSize, value));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xC3:
|
|
||||||
{
|
|
||||||
/* page 4 to F */
|
|
||||||
uint32_t romSize;
|
|
||||||
uint8_t *rom = getRom(&romSize);
|
|
||||||
/* Page 3 */
|
|
||||||
set_memory_bank(0x3, ws_get_page_ptr(rom, romSize, value));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
140
source/rom.c
140
source/rom.c
@@ -1,140 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* rom.c:
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 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
214
source/rom.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
57
source/rom.h
Normal file
57
source/rom.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __ROM_H__
|
||||||
|
#define __ROM_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_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
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ws_romHeaderStruct
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
380
source/ws.c
380
source/ws.c
@@ -1,380 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* ws.c: Base wonderswan implementation
|
|
||||||
*
|
|
||||||
* Based on the original Oswan-unix
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#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.h"
|
|
||||||
#include "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)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
#if 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();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
io_init();
|
|
||||||
//ws_audio_init();
|
|
||||||
//ws_gpu_init();
|
|
||||||
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ws_reset(void)
|
|
||||||
{
|
|
||||||
//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;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
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 0
|
|
||||||
if ((ws_ioRam[0xb2] & 32)) /* VBLANK Timer */
|
|
||||||
{
|
|
||||||
/* TODO: REPAIR THAT SHIT */
|
|
||||||
ws_ioRam[0xb6] &= ~32;
|
|
||||||
nec_int((ws_ioRam[0xb0] + 5) * 4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
ws_ioRam[2] = ws_gpu_scanline;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (drawWholeScreen)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (ws_ioRam[0xb2] & 64) /* VBLANK INT */
|
|
||||||
{
|
|
||||||
ws_ioRam[0xb6] &= ~64;
|
|
||||||
nec_int((ws_ioRam[0xb0] + 6) * 4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
vblank_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (drawWholeScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ws_done(void)
|
|
||||||
{
|
|
||||||
io_cleanup();
|
|
||||||
//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)
|
|
||||||
{
|
|
||||||
// TODO: need a complete rewrite
|
|
||||||
#if 0
|
|
||||||
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();
|
|
||||||
#endif
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MacroStoreNecRegisterToFile(F, R) \
|
|
||||||
value=nec_get_reg(R); \
|
|
||||||
write(fp,&value,sizeof(value));
|
|
||||||
|
|
||||||
int ws_saveState(char *statepath)
|
|
||||||
{
|
|
||||||
// TODO: need a complete rewrite
|
|
||||||
#if 0
|
|
||||||
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);
|
|
||||||
#endif
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ws_rotated(void)
|
|
||||||
{
|
|
||||||
//uint8_t *rom = memory_getRom();
|
|
||||||
//uint32_t romSize = memory_getRomSize();
|
|
||||||
|
|
||||||
//return (rom[romSize - 4] & 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
523
source/ws.cpp
Normal file
523
source/ws.cpp
Normal 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);
|
||||||
|
}
|
||||||
37
source/ws.h
Normal file
37
source/ws.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __WS_H__
|
||||||
|
#define __WS_H__
|
||||||
|
|
||||||
|
#define WS_SYSTEM_MONO 0
|
||||||
|
#define WS_SYSTEM_COLOR 1
|
||||||
|
#define WS_SYSTEM_AUTODETECT 2
|
||||||
|
|
||||||
|
extern uint32_t ws_cyclesByLine;
|
||||||
|
|
||||||
|
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;
|
||||||
|
extern char *ws_rom_path;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
12
testserial.c
12
testserial.c
@@ -1,11 +1,3 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NewOswan
|
|
||||||
* testserial.c: A simple tool to test serial in/out
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -15,10 +7,6 @@
|
|||||||
#include <errno.h> /* Error number definitions */
|
#include <errno.h> /* Error number definitions */
|
||||||
#include <termios.h> /* POSIX terminal control definitions */
|
#include <termios.h> /* POSIX terminal control definitions */
|
||||||
|
|
||||||
/*
|
|
||||||
* The code, as is, was part of a fuzzer for the WonderSwan Tetris game.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Serial port */
|
/* Serial port */
|
||||||
#define BDR_9600 (0)
|
#define BDR_9600 (0)
|
||||||
#define BDR_38400 (1)
|
#define BDR_38400 (1)
|
||||||
|
|||||||
Reference in New Issue
Block a user