Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
330cba592d | ||
|
|
e48f7a76a7 | ||
|
|
4800cf0823 | ||
|
|
a37414b079 | ||
|
|
e9d7f1aa04 | ||
|
|
37e4b219d4 | ||
|
|
d6a2a77303 | ||
|
|
f45995167e | ||
|
|
83e4b8d5d9 | ||
|
|
4d345079ae | ||
|
|
5f61fb612a | ||
|
|
2305ce975b | ||
|
|
01ffa3a834 | ||
|
|
fce2815300 | ||
|
|
662a45d02f | ||
|
|
bb324dc12e | ||
|
|
017983f692 | ||
|
|
b4b1bd83d0 | ||
|
|
a85e1ff083 | ||
|
|
4c9ba704ea | ||
|
|
6f56a8efda | ||
|
|
8fa2ef06ab | ||
|
|
4fc5193bc7 | ||
|
|
1df15b0192 | ||
|
|
6f539fff1e | ||
|
|
c90b99d650 | ||
|
|
49a1943cda | ||
|
|
4082d37cb0 |
38
.github/workflows/cmake.yml
vendored
Normal file
38
.github/workflows/cmake.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
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
Normal file
62
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
# 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
|
||||
@@ -47,4 +47,5 @@ add_subdirectory(source)
|
||||
|
||||
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)
|
||||
@@ -1,6 +1,6 @@
|
||||
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
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* dumpinfo.c: Tool to dump the metadata info about a cart rom image.
|
||||
*
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
60
main.c
60
main.c
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* main.c: Entry point
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 13.04.2002: Fixed a small bug causing crashes
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -20,27 +13,16 @@
|
||||
#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"
|
||||
#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;
|
||||
@@ -102,18 +84,6 @@ int ws_mk_ieppath()
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
wssystem_t ws_system = WS_SYSTEM_AUTODETECT;
|
||||
@@ -181,7 +151,6 @@ int main(int argc, char *argv[])
|
||||
if (ws_init(ws_rom_path))
|
||||
{
|
||||
ws_reset();
|
||||
|
||||
ws_emulate();
|
||||
}
|
||||
|
||||
@@ -191,4 +160,3 @@ int main(int argc, char *argv[])
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
set(SOURCES audio.c emulate.c gpu.c io.c log.c memory.c rom.c ws.c)
|
||||
set(HEADERS audio.h emulate.h gpu.h io.h log.h memory.h rom.h ws.h)
|
||||
set(SOURCES emulate.c gpu.c io.c log.c memory.c rom.c ws.c file_access.c)
|
||||
set(PERIPHERAL_SOURCES peripherals/audio.c peripherals/buttons.c peripherals/color_gpu.c peripherals/color_system.c
|
||||
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)
|
||||
@@ -11,6 +18,6 @@ endif()
|
||||
|
||||
target_link_libraries(wswan nec_v30 glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
|
||||
|
||||
target_include_directories(wswan PUBLIC . nec/)
|
||||
target_include_directories(wswan PUBLIC includes/)
|
||||
|
||||
add_subdirectory(nec)
|
||||
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* emulate.c:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -37,15 +30,15 @@
|
||||
#endif
|
||||
#endif /* PRETENT_DISPLAY */
|
||||
|
||||
#include "log.h"
|
||||
#include "io.h"
|
||||
#include "ws.h"
|
||||
#include "rom.h"
|
||||
#include "./nec/nec.h"
|
||||
#include "./nec/necintrf.h"
|
||||
#include "gpu.h"
|
||||
#include "audio.h"
|
||||
#include "memory.h"
|
||||
#include <log.h>
|
||||
#include <io.h>
|
||||
#include <ws.h>
|
||||
#include <rom.h>
|
||||
#include "nec.h"
|
||||
#include "necintrf.h"
|
||||
#include <gpu.h>
|
||||
#include <audio.h>
|
||||
#include <memory.h>
|
||||
|
||||
char app_window_title[256];
|
||||
int app_terminate = 0;
|
||||
@@ -246,6 +239,7 @@ static inline int getKeyState(int key)
|
||||
|
||||
static void read_keys()
|
||||
{
|
||||
#if 0
|
||||
ws_key_start = 0;
|
||||
ws_key_x4 = 0;
|
||||
ws_key_x2 = 0;
|
||||
@@ -338,6 +332,7 @@ static void read_keys()
|
||||
{
|
||||
ws_cyclesByLine -= 10;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
typedef struct PseudoWindow_t
|
||||
@@ -409,17 +404,6 @@ double getTicks()
|
||||
return ticks;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_emulate(void)
|
||||
{
|
||||
int32_t nCount = 0;
|
||||
@@ -438,24 +422,25 @@ void ws_emulate(void)
|
||||
|
||||
dNormalLast = getTicks();
|
||||
|
||||
#define HCLK (1000. / 12000.)
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
dTemp = getTicks();
|
||||
dTime = dTemp - dNormalLast;
|
||||
|
||||
|
||||
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
|
||||
nCount = (int32_t)(dTime * HCLK); // does this calculation make sense?
|
||||
|
||||
if (nCount <= 0)
|
||||
{
|
||||
/* Sleep for 2ms */
|
||||
usleep(2000);
|
||||
/* Sleep for 500us */
|
||||
usleep(500);
|
||||
} // No need to do anything for a bit
|
||||
else
|
||||
{
|
||||
|
||||
dNormalLast += nCount * (1 / 0.07547);
|
||||
dNormalLast += nCount * (1 / HCLK);
|
||||
|
||||
if (nCount > 10)
|
||||
{
|
||||
@@ -474,10 +459,10 @@ void ws_emulate(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* What is this mess? Frameskip? */
|
||||
for (i = 0 ; i < nCount - 1 ; i++)
|
||||
{
|
||||
while (!ws_executeLine(backBuffer, 0))
|
||||
while (!ws_executeLine(backBuffer, 1))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* NewOswan
|
||||
* emulate.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef EMULATE_H
|
||||
#define EMULATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern char app_window_title[256];
|
||||
extern int app_terminate;
|
||||
|
||||
void ws_emulate(void);
|
||||
|
||||
#endif /* EMULATE_H */
|
||||
83
source/file_access.c
Normal file
83
source/file_access.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
188
source/gpu.c
188
source/gpu.c
@@ -1,60 +1,36 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// GPU
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// 7.04.2002: Fixed sprites order
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* gpu.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 <fcntl.h>
|
||||
#include <time.h>
|
||||
#include "log.h"
|
||||
#include "rom.h"
|
||||
#include "./nec/nec.h"
|
||||
#include "io.h"
|
||||
#include "gpu.h"
|
||||
#include "ws.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <log.h>
|
||||
#include <rom.h>
|
||||
#include "nec.h"
|
||||
#include <io.h>
|
||||
#include <gpu.h>
|
||||
#include <ws.h>
|
||||
#include <memory.h>
|
||||
#if 0
|
||||
extern uint8_t *internalRam;
|
||||
|
||||
// TODO: Temporary to let build for now
|
||||
static uint8_t ws_ioRam[0x100];
|
||||
|
||||
enum VideoModes
|
||||
{
|
||||
DISPLAY_MODE_GRAY = 0, DISPLAY_MODE_2BPP = 4, DISPLAY_MODE_P_4BPP = 7, DISPLAY_MODE_L_4BPP = 6,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define RGB555(R, G, B) ((((int)(R))<<10)|(((int)(G))<<5)|((int)(B)))
|
||||
|
||||
uint8_t ws_gpu_operatingInColor = 0;
|
||||
@@ -97,17 +73,6 @@ uint8_t *wsc_hflipped_tile_cache;
|
||||
uint8_t *ws_modified_tile;
|
||||
uint8_t *wsc_modified_tile;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_init(void)
|
||||
{
|
||||
ws_tile_cache = (uint8_t *)malloc(1024 * 8 * 8);
|
||||
@@ -129,17 +94,6 @@ void ws_gpu_init(void)
|
||||
memset(wsc_modified_tile, 0x01, 1024);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_done(void)
|
||||
{
|
||||
free(ws_tile_cache);
|
||||
@@ -150,17 +104,6 @@ void ws_gpu_done(void)
|
||||
free(wsc_modified_tile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_changeVideoMode(uint8_t value)
|
||||
{
|
||||
if (ws_videoMode != (value >> 5))
|
||||
@@ -179,20 +122,8 @@ void ws_gpu_changeVideoMode(uint8_t value)
|
||||
(value & 0x80)?'Y':'N',
|
||||
(value & 0x40)?'4':'2',
|
||||
(value & 0x20)?"Packed":"Planar");
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_reset(void)
|
||||
{
|
||||
memset(ws_modified_tile, 0x01, 1024);
|
||||
@@ -200,33 +131,11 @@ void ws_gpu_reset(void)
|
||||
ws_gpu_changeVideoMode(0x00);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_clearCache(void)
|
||||
{
|
||||
memset(ws_modified_tile, 0x01, 1024);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t *ws_tileCache_getTileRow(uint32_t tileIndex, uint32_t line, uint32_t vFlip, uint32_t hFlip, uint32_t bank)
|
||||
{
|
||||
if (ws_gpu_operatingInColor)
|
||||
@@ -439,17 +348,6 @@ uint8_t *ws_tileCache_getTileRow(uint32_t tileIndex, uint32_t line, uint32_t vFl
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_drawClippedSpriteLine(int16_t *framebuffer, uint16_t scanline, uint32_t x, uint32_t y, uint32_t tileIndex,
|
||||
uint32_t paletteIndex, uint32_t vFlip, uint32_t hFlip, uint32_t clip_x0, uint32_t clip_y0,
|
||||
uint32_t clip_x1, uint32_t clip_y1)
|
||||
@@ -534,17 +432,6 @@ void ws_drawClippedSpriteLine(int16_t *framebuffer, uint16_t scanline, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_renderScanline(int16_t *framebuffer)
|
||||
{
|
||||
|
||||
@@ -1893,17 +1780,6 @@ void ws_gpu_renderScanline(int16_t *framebuffer)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_write_byte(uint32_t offset, uint8_t value)
|
||||
{
|
||||
// ws 4 color tiles
|
||||
@@ -1960,17 +1836,6 @@ void ws_gpu_write_byte(uint32_t offset, uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
unsigned int ws_gpu_unknownPort;
|
||||
|
||||
int ws_gpu_port_write(uint32_t port, uint8_t value)
|
||||
@@ -2030,17 +1895,6 @@ int ws_gpu_port_write(uint32_t port, uint8_t value)
|
||||
return ws_gpu_unknownPort;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t ws_gpu_port_read(uint8_t port)
|
||||
{
|
||||
switch (port)
|
||||
@@ -2072,3 +1926,5 @@ uint8_t ws_gpu_port_read(uint8_t port)
|
||||
|
||||
return (ws_ioRam[port]);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* audio.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __AUDIO_H__
|
||||
#define __AUDIO_H__
|
||||
52
source/includes/device.h
Normal file
52
source/includes/device.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* 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__ */
|
||||
20
source/includes/emulate.h
Normal file
20
source/includes/emulate.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*******************************************************************************
|
||||
* 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 */
|
||||
19
source/includes/file_access.h
Normal file
19
source/includes/file_access.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*******************************************************************************
|
||||
* 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,15 +1,23 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* gpu.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* 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;
|
||||
32
source/includes/interrupt_controller.h
Normal file
32
source/includes/interrupt_controller.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* 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__ */
|
||||
31
source/includes/io.h
Normal file
31
source/includes/io.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*******************************************************************************
|
||||
* 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,10 +1,11 @@
|
||||
/*
|
||||
* C Fancy Logger
|
||||
* log.h:
|
||||
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
@@ -13,7 +14,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ALLOW_COLORS
|
||||
//#define ALLOW_COLORS
|
||||
|
||||
#ifdef ALLOW_COLORS
|
||||
#define __C(c) "\x1B[" c "m"
|
||||
37
source/includes/memory.h
Normal file
37
source/includes/memory.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*******************************************************************************
|
||||
* 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,10 +1,12 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* nec.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __NEC_H_
|
||||
#define __NEC_H_
|
||||
|
||||
@@ -114,30 +116,30 @@ typedef struct
|
||||
|
||||
#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)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 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*/; cpu_writemem20((DefaultBase(Seg)+(Off)),(x)); }
|
||||
#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)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 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) cpu_readport(port)
|
||||
#define write_port(port, val) cpu_writeport(port,val)
|
||||
#define read_port(port) io_readport(port)
|
||||
#define write_port(port, val) io_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 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)cpu_readop_arg(addr))
|
||||
#define PEEKOP(addr) ((uint8_t)cpu_readop(addr))
|
||||
#define PEEK(addr) ((uint8_t)mem_readop_arg(addr))
|
||||
#define PEEKOP(addr) ((uint8_t)mem_readop(addr))
|
||||
|
||||
#define GetModRM uint32_t ModRM=cpu_readop_arg((I.sregs[CS]<<4)+I.ip++)
|
||||
#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
|
||||
16
source/includes/nec_debugger.h
Normal file
16
source/includes/nec_debugger.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/******************************************************************************
|
||||
* 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,13 +1,15 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* necintrf.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* 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_
|
||||
#ifndef __NECITRF_H__
|
||||
#define __NECITRF_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -44,11 +46,4 @@ 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_ */
|
||||
#endif /* __NECITRF_H__ */
|
||||
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* rom.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __ROM_H__
|
||||
#define __ROM_H__
|
||||
@@ -32,7 +25,11 @@
|
||||
#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
|
||||
@@ -44,15 +41,16 @@
|
||||
#pragma pack(1)
|
||||
typedef struct ws_romHeaderStruct
|
||||
{
|
||||
uint8_t developperId;
|
||||
uint8_t minimumSupportSystem;
|
||||
uint8_t cartId;
|
||||
uint8_t gameVertion;
|
||||
uint8_t romSize;
|
||||
uint8_t saveSize;
|
||||
uint8_t cartFlags;
|
||||
uint8_t realtimeClock;
|
||||
uint16_t checksum;
|
||||
/* 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()
|
||||
|
||||
@@ -69,4 +67,4 @@ static inline uint8_t *ws_get_page_ptr(uint8_t *wsrom, uint32_t romSize, uint16_
|
||||
return &wsrom[temp];
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* __ROM_H__ */
|
||||
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* ws.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WS_H__
|
||||
#define __WS_H__
|
||||
@@ -42,4 +35,4 @@ extern char *ws_ieep_path;
|
||||
extern char *ws_rom_path;
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* __WS_H__ */
|
||||
1261
source/io.c
1261
source/io.c
File diff suppressed because it is too large
Load Diff
41
source/io.h
41
source/io.h
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* NewOswan
|
||||
* io.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __IO_H__
|
||||
#define __IO_H__
|
||||
|
||||
#include <stdint.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
|
||||
|
||||
11
source/log.c
11
source/log.c
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* C Fancy Logger
|
||||
* log.c:
|
||||
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
|
||||
/*******************************************************************************
|
||||
* 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_
|
||||
|
||||
|
||||
575
source/memory.c
575
source/memory.c
@@ -1,268 +1,32 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* memory.c: Memory implementatoion
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* memory.c: Memory implementation
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Notes: need to optimize cpu_writemem20
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
* 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 <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "ws.h"
|
||||
#include "log.h"
|
||||
#include "rom.h"
|
||||
#include "./nec/nec.h"
|
||||
#include "io.h"
|
||||
#include "gpu.h"
|
||||
#include "audio.h"
|
||||
#include "memory.h"
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define IO_ROM_BANK_BASE_SELECTOR 0xC0
|
||||
|
||||
uint8_t *ws_rom;
|
||||
uint8_t *ws_staticRam;
|
||||
uint8_t *internalRam;
|
||||
uint8_t *externalEeprom;
|
||||
char *internalBWIRom;
|
||||
char *internalColorIRom;
|
||||
char *internalCrystalIRom;
|
||||
|
||||
char *internalBWEeprom;
|
||||
char *internalColorEeprom;
|
||||
char *internalCrystalEeprom;
|
||||
|
||||
uint16_t *internalEeprom;
|
||||
|
||||
extern uint8_t *ws_ioRam;
|
||||
|
||||
uint16_t ws_rom_checksum;
|
||||
|
||||
uint8_t ws_haveCrystalIRom;
|
||||
uint8_t ws_haveColorIRom;
|
||||
uint8_t ws_haveBWIRom;
|
||||
|
||||
uint32_t sramAddressMask;
|
||||
uint32_t externalEepromAddressMask;
|
||||
uint32_t romAddressMask;
|
||||
uint32_t romSize;
|
||||
uint32_t sramSize;
|
||||
|
||||
extern nec_Regs I;
|
||||
#include <log.h>
|
||||
|
||||
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);
|
||||
// TODO: Need complete rewrite
|
||||
}
|
||||
|
||||
#ifndef USE_PAGED_MEMORY_ACCESS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
wssystem_t currentSystem = ws_get_system();
|
||||
|
||||
switch (bank)
|
||||
{
|
||||
case 0:
|
||||
/*
|
||||
* So the original WonderSwan, and Color/Crystal in B&W mode have 16KB of IRAM Mapped.
|
||||
* Color/Crystal in color mode have 64 KB IRAM mapped.
|
||||
*/
|
||||
if (ws_gpu_operatingInColor)
|
||||
{
|
||||
return (internalRam[offset]);
|
||||
}
|
||||
else if (offset < 0x4000)
|
||||
{
|
||||
return (internalRam[offset]);
|
||||
}
|
||||
|
||||
return (0x90);
|
||||
|
||||
case 1: // 1 - SRAM (cart)
|
||||
return ws_staticRam[offset & sramAddressMask];
|
||||
|
||||
case 2:
|
||||
// Bank 2
|
||||
hwReg = ws_ioRam[0xC2];
|
||||
temp = hwReg << 16;
|
||||
temp += offset;
|
||||
temp &= (romSize - 1);
|
||||
return ws_rom[temp];
|
||||
case 3:
|
||||
// Bank 3
|
||||
hwReg = ws_ioRam[0xC3];
|
||||
temp = hwReg << 16;
|
||||
temp += offset;
|
||||
temp &= (romSize - 1);
|
||||
return ws_rom[temp];
|
||||
|
||||
case 0xF:
|
||||
hwReg = ws_ioRam[0xA0];
|
||||
|
||||
if (!(hwReg & 1))
|
||||
{
|
||||
if (currentSystem == WS_SYSTEM_COLOR && ws_haveColorIRom)
|
||||
{
|
||||
if (addr >= 0xFE000)
|
||||
{
|
||||
ret = internalColorIRom[addr & ~0xFE000];
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if (currentSystem == WS_SYSTEM_CRYSTAL && ws_haveColorIRom)
|
||||
{
|
||||
if (addr >= 0xFE000)
|
||||
{
|
||||
ret = internalCrystalIRom[addr & ~0xFE000];
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if (currentSystem == WS_SYSTEM_MONO && ws_haveBWIRom)
|
||||
{
|
||||
if (addr >= 0xFF000)
|
||||
{
|
||||
ret = internalBWIRom[addr & ~0xFF000];
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
|
||||
default:
|
||||
hwReg = ws_ioRam[0xC0];
|
||||
temp = hwReg << 20;
|
||||
temp += addr & 0xFFFFF;
|
||||
temp &= (romSize - 1);
|
||||
return ws_rom[temp];
|
||||
}
|
||||
|
||||
return (0x90);
|
||||
}
|
||||
#else
|
||||
/* 256 page of 12 bits */
|
||||
uint8_t *pagedMemory[0x100];
|
||||
|
||||
/* Memory address is 20bit and split in 8 (page) - 12 (offset) */
|
||||
void cpu_writemem20(uint32_t addr, uint8_t value)
|
||||
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 */
|
||||
@@ -273,10 +37,11 @@ void cpu_writemem20(uint32_t addr, uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t cpu_readmem20(uint32_t addr)
|
||||
uint8_t mem_readmem20(uint32_t addr)
|
||||
{
|
||||
uint8_t page = addr >> 12;
|
||||
uint16_t offset = addr & 0xFFF;
|
||||
|
||||
if (pagedMemory[page])
|
||||
{
|
||||
return pagedMemory[page][offset];
|
||||
@@ -298,315 +63,3 @@ void set_memory_page(uint8_t page, uint8_t *pointer)
|
||||
{
|
||||
pagedMemory[page] = pointer;
|
||||
}
|
||||
|
||||
void set_irom_overlay()
|
||||
{
|
||||
/* Setup the boot rom */
|
||||
if (ws_get_system() == WS_SYSTEM_MONO)
|
||||
{
|
||||
set_memory_page(0xFF, internalBWIRom);
|
||||
}
|
||||
else if (ws_get_system() == WS_SYSTEM_COLOR)
|
||||
{
|
||||
set_memory_page(0xFE, internalColorIRom);
|
||||
set_memory_page(0xFF, internalColorIRom + 0x1000);
|
||||
}
|
||||
else if (ws_get_system() == WS_SYSTEM_CRYSTAL)
|
||||
{
|
||||
set_memory_page(0xFE, internalCrystalIRom);
|
||||
set_memory_page(0xFF, internalCrystalIRom + 0x1000);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *getRom(uint32_t *size)
|
||||
{
|
||||
*size = romSize;
|
||||
return ws_rom;
|
||||
}
|
||||
|
||||
uint8_t *getSram(uint32_t *size)
|
||||
{
|
||||
*size = sramSize;
|
||||
return ws_staticRam;
|
||||
}
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
char *load_file(char *filename)
|
||||
{
|
||||
int fd;
|
||||
char *ret_ptr;
|
||||
struct stat FileStat;
|
||||
|
||||
fd = open(filename, O_RDWR);
|
||||
|
||||
fstat(fd, &FileStat);
|
||||
|
||||
Log(TLOG_DEBUG, "memory", "Trying to load %s, size = %lu...", filename, (unsigned long)FileStat.st_size);
|
||||
|
||||
ret_ptr = (char *)mmap(NULL, FileStat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (ret_ptr == MAP_FAILED)
|
||||
{
|
||||
ret_ptr = NULL;
|
||||
}
|
||||
|
||||
return ret_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
char *create_file(char *filename, uint32_t size)
|
||||
{
|
||||
int fd;
|
||||
uint32_t i;
|
||||
char *ret_ptr;
|
||||
char buf[] = {0};
|
||||
|
||||
Log(TLOG_DEBUG, "memory", "Trying to create %s, size = %u...\n", filename, size);
|
||||
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC, 0644);
|
||||
fchmod(fd, 0644);
|
||||
close(fd);
|
||||
sync();
|
||||
|
||||
fd = open(filename, O_RDWR);
|
||||
|
||||
for (i = 0 ; i < size ; i++)
|
||||
{
|
||||
write(fd, buf, 1);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
sync();
|
||||
|
||||
fd = open(filename, O_RDWR);
|
||||
ret_ptr = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (ret_ptr == MAP_FAILED)
|
||||
{
|
||||
ret_ptr = NULL;
|
||||
}
|
||||
|
||||
return ret_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_memory_init(uint8_t *rom, uint32_t wsRomSize)
|
||||
{
|
||||
ws_romHeaderStruct *ws_romHeader;
|
||||
|
||||
ws_rom = rom;
|
||||
romSize = wsRomSize;
|
||||
sramSize = ws_rom_sramSize(ws_rom, romSize);
|
||||
ws_romHeader = ws_rom_getHeader(ws_rom, romSize);
|
||||
ws_rom_checksum = ws_romHeader->checksum;
|
||||
internalRam = (uint8_t *)malloc(0x10000);
|
||||
sramAddressMask = 0x0;
|
||||
externalEepromAddressMask = 0x0;
|
||||
|
||||
if (sramSize > 0)
|
||||
{
|
||||
sramAddressMask = ws_rom_sramSize(ws_rom, romSize) - 1;
|
||||
}
|
||||
if (ws_rom_eepromSize(ws_rom, romSize) > 0)
|
||||
{
|
||||
externalEepromAddressMask = ws_rom_eepromSize(ws_rom, romSize) - 1;
|
||||
}
|
||||
|
||||
internalBWIRom = load_file("ws_irom.bin");
|
||||
internalColorIRom = load_file("wsc_irom.bin");
|
||||
internalCrystalIRom = load_file("wc_irom.bin");
|
||||
|
||||
internalBWEeprom = load_file("ws_ieeprom.bin");
|
||||
if (internalBWEeprom == NULL)
|
||||
{
|
||||
internalBWEeprom = create_file("ws_ieeprom.bin", BW_IEEPROM_SIZE);
|
||||
}
|
||||
|
||||
internalColorEeprom = load_file("wsc_ieeprom.bin");
|
||||
if (internalColorEeprom == NULL)
|
||||
{
|
||||
internalColorEeprom = create_file("wsc_ieeprom.bin", COLOR_IEEPROM_SIZE);
|
||||
}
|
||||
|
||||
internalCrystalEeprom = load_file("wc_ieeprom.bin");
|
||||
if (internalCrystalEeprom == NULL)
|
||||
{
|
||||
internalCrystalEeprom = create_file("wc_ieeprom.bin", COLOR_IEEPROM_SIZE);
|
||||
}
|
||||
|
||||
internalEeprom = (uint16_t *)internalBWEeprom;
|
||||
if (ws_get_system() == WS_SYSTEM_COLOR)
|
||||
{
|
||||
internalEeprom = (uint16_t *)internalColorEeprom;
|
||||
}
|
||||
else if (ws_get_system() == WS_SYSTEM_CRYSTAL)
|
||||
{
|
||||
internalEeprom = (uint16_t *)internalCrystalEeprom;
|
||||
}
|
||||
|
||||
ws_haveBWIRom = false;
|
||||
ws_haveColorIRom = false;
|
||||
ws_haveCrystalIRom = false;
|
||||
|
||||
if (internalColorIRom != NULL)
|
||||
{
|
||||
Log(TLOG_DEBUG, "memory", "B&W IROM Found!");
|
||||
ws_haveColorIRom = true;
|
||||
}
|
||||
if (internalBWIRom != NULL)
|
||||
{
|
||||
Log(TLOG_DEBUG, "memory", "Color IROM Found!");
|
||||
ws_haveBWIRom = true;
|
||||
}
|
||||
if (internalCrystalIRom != NULL)
|
||||
{
|
||||
Log(TLOG_DEBUG, "memory", "Crystal IROM Found!");
|
||||
ws_haveCrystalIRom = true;
|
||||
}
|
||||
|
||||
romAddressMask = romSize - 1;
|
||||
|
||||
|
||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
||||
for(int i = 0; i < 0x100; i++)
|
||||
{
|
||||
pagedMemory[i] = NULL;
|
||||
}
|
||||
|
||||
/* IRAM */
|
||||
set_memory_bank(0, internalRam);
|
||||
for(int i = 0x4; i < 0x10; i++)
|
||||
{
|
||||
set_memory_page(i, NULL);
|
||||
}
|
||||
|
||||
/* Cart SRAM */
|
||||
if (sramSize > 0)
|
||||
{
|
||||
set_memory_bank(0x1, ws_get_page_ptr(ws_staticRam, sramSize, 0xFF));
|
||||
}
|
||||
|
||||
set_memory_bank(0x2, ws_get_page_ptr(ws_rom, romSize, 0xFF));
|
||||
set_memory_bank(0x3, ws_get_page_ptr(ws_rom, romSize, 0xFF));
|
||||
|
||||
for(int i = 0x04; i < 0x10; i++)
|
||||
{
|
||||
set_memory_bank(i, ws_get_page_ptr(ws_rom, romSize, 0xF0 + i));
|
||||
}
|
||||
|
||||
set_irom_overlay();
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_memory_reset(void)
|
||||
{
|
||||
memset(internalRam, 0, 0x10000);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_memory_done(void)
|
||||
{
|
||||
free(internalRam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t *memory_getRom(void)
|
||||
{
|
||||
return (ws_rom);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t memory_getRomSize(void)
|
||||
{
|
||||
return (romSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint16_t memory_getRomCrc(void)
|
||||
{
|
||||
return (ws_rom_checksum);
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* NewOswan
|
||||
* memory.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __MEMORY_H__
|
||||
#define __MEMORY_H__
|
||||
|
||||
#include <stdint.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 USE_PAGED_MEMORY_ACCESS
|
||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
||||
/***
|
||||
* Set a memory page with a ganularity of 4-16
|
||||
* @param bank: the bank (0-F) to set
|
||||
* @param pointer: a pointer to the memory to set
|
||||
*/
|
||||
void set_memory_bank(uint8_t bank, uint8_t *pointer);
|
||||
|
||||
/***
|
||||
* Set a memory page with a ganularity of 8-12
|
||||
* @param bank: the bank (0-FF) to set
|
||||
* @param pointer: a pointer to the memory to set
|
||||
*/
|
||||
void set_memory_page(uint8_t page, uint8_t *pointer);
|
||||
|
||||
void set_irom_overlay();
|
||||
|
||||
uint8_t *getRom(uint32_t *size);
|
||||
uint8_t *getSram(uint32_t *size);
|
||||
#endif
|
||||
|
||||
#define BW_IEEPROM_SIZE (128)
|
||||
#define COLOR_IEEPROM_SIZE (2048)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(SOURCES nec.c nec_debugger.c)
|
||||
set(HEADERS nec.h necea.h necinstr.h necintrf.h necmodrm.h nec_debugger.h)
|
||||
set(HEADERS ../includes/nec.h necea.h necinstr.h ../includes/necintrf.h necmodrm.h ../includes/nec_debugger.h)
|
||||
|
||||
add_library(nec_v30 ${SOURCES} ${HEADERS})
|
||||
|
||||
target_include_directories(nec_v30 PUBLIC . ..)
|
||||
target_include_directories(nec_v30 PUBLIC ../includes/)
|
||||
@@ -1,10 +1,12 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* nec.c:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
NEC V30MZ(V20/V30/V33) emulator
|
||||
@@ -39,9 +41,12 @@
|
||||
|
||||
#include <log.h>
|
||||
|
||||
#include "nec.h"
|
||||
#include "necintrf.h"
|
||||
#include "nec_debugger.h"
|
||||
#include <memory.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <nec.h>
|
||||
#include <necintrf.h>
|
||||
#include <nec_debugger.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* cpu state */
|
||||
@@ -4221,21 +4226,21 @@ int nec_execute(int cycles)
|
||||
while (nec_ICount > 0)
|
||||
{
|
||||
#if 0
|
||||
if ((I.sregs[CS] == 0x0600) /* && (I.ip > 0x0050) */)
|
||||
if ( ws_ioRam[0xA0] & 0x01 )
|
||||
{
|
||||
int tmp;
|
||||
char buffer[256];
|
||||
uint8_t op = cpu_readmem20((I.sregs[CS] << 4) + I.ip);
|
||||
uint8_t op = mem_readmem20((I.sregs[CS] << 4) + I.ip);
|
||||
//Log(TLOG_NORMAL, "NEC v30", "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, instructionsName[op], I.IF);
|
||||
printf("AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n",
|
||||
fprintf(stderr, "AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n",
|
||||
I.regs.w[AW], I.regs.w[BW], I.regs.w[CW], I.regs.w[DW],
|
||||
I.regs.w[IX], I.regs.w[IY], I.regs.w[SP]);
|
||||
printf("CS: %04X, DS: %04X, SS: %04X, ES: %04X\n",
|
||||
fprintf(stderr, "CS: %04X, DS: %04X, SS: %04X, ES: %04X\n",
|
||||
I.sregs[CS], I.sregs[DS], I.sregs[SS], I.sregs[ES]);
|
||||
memset(buffer, 0, 256);
|
||||
nec_decode_instruction(I.sregs[CS], I.ip, buffer, 255);
|
||||
printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF);
|
||||
tmp = getchar();
|
||||
fprintf(stderr, "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF);
|
||||
//tmp = getchar();
|
||||
}
|
||||
#endif
|
||||
nec_instruction[FETCHOP]();
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* nec_debugger.c:
|
||||
* Created by Manoël Trapier on 14/04/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* Created by Manoël Trapier on 14/04/2021.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "nec_debugger.h"
|
||||
#include "necintrf.h"
|
||||
#include <log.h>
|
||||
#include <nec_debugger.h>
|
||||
#include <necintrf.h>
|
||||
#include <memory.h>
|
||||
|
||||
/***
|
||||
* Note: the while code to decode instruction is not meant to be optimised, but to be easy to maintain.
|
||||
* Note: the whole code to decode instruction is not meant to be optimised, but to be easy to maintain.
|
||||
* It probably could be more concise, but this is code for the debugger, not runtime, so optimisation does
|
||||
* not really matter here.
|
||||
*/
|
||||
@@ -282,10 +284,10 @@ enum extendedOpcodes
|
||||
|
||||
OP_GP2_INC = 0,
|
||||
OP_GP2_DEC = 1,
|
||||
OP_GP2_CALL1 = 2,
|
||||
OP_GP2_CALL2 = 3,
|
||||
OP_GP2_JMP1 = 4,
|
||||
OP_GP2_JMP2 = 5,
|
||||
OP_GP2_CALL = 2,
|
||||
OP_GP2_CALLF = 3,
|
||||
OP_GP2_JMP = 4,
|
||||
OP_GP2_JMPF = 5,
|
||||
OP_GP2_PUSH = 6,
|
||||
};
|
||||
|
||||
@@ -327,7 +329,7 @@ typedef enum modrmValues
|
||||
|
||||
const char *modrmReg8List[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
|
||||
const char *modrmReg16List[8] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
|
||||
const char *segmentRegList[4] = { "ds", "cs", "ss", "es" };
|
||||
const char *segmentRegList[8] = { "es", "cs", "ss", "ds", "ILLEGAL", "ILLEGAL", "ILLEGAL", "ILLEGAL" };
|
||||
static inline void get_mod_reg_rm(uint8_t value, uint8_t *mod, uint8_t *reg, uint8_t *rm, uint8_t *modrm)
|
||||
{
|
||||
if (mod)
|
||||
@@ -353,8 +355,8 @@ static inline void get_mod_reg_rm(uint8_t value, uint8_t *mod, uint8_t *reg, uin
|
||||
|
||||
static int decode_modrm(uint16_t segment, uint16_t offset, modrmValues modrm, bool is8bit, char *buffer, uint32_t bufferLength)
|
||||
{
|
||||
uint8_t disp8 = cpu_readmem20(MAKE_LINEAR(segment, offset));
|
||||
uint16_t disp16 = (cpu_readmem20(MAKE_LINEAR(segment, offset + 1)) << 8) | disp8;
|
||||
uint8_t disp8 = mem_readmem20(MAKE_LINEAR(segment, offset));
|
||||
uint16_t disp16 = (mem_readmem20(MAKE_LINEAR(segment, offset + 1)) << 8) | disp8;
|
||||
char buf[63];
|
||||
int offsetReturn = 0;
|
||||
|
||||
@@ -544,7 +546,7 @@ static int decode_modrm(uint16_t segment, uint16_t offset, modrmValues modrm, bo
|
||||
|
||||
int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsigned int bufferSize)
|
||||
{
|
||||
uint8_t opcode = cpu_readmem20(MAKE_LINEAR(segment, offset));
|
||||
uint8_t opcode = mem_readmem20(MAKE_LINEAR(segment, offset));
|
||||
uint16_t currentOffset = offset;
|
||||
int16_t param1, param2;
|
||||
uint8_t modrm, reg;
|
||||
@@ -562,7 +564,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
{
|
||||
/* Need to handle opcode group */
|
||||
case OP_IMMED:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
||||
switch (reg)
|
||||
{
|
||||
@@ -631,7 +633,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case OP_SHIFT:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
||||
switch (reg)
|
||||
{
|
||||
@@ -666,7 +668,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case OP_GRP1:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
||||
switch (reg)
|
||||
{
|
||||
@@ -711,7 +713,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case OP_GRP2:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
||||
switch (reg)
|
||||
{
|
||||
@@ -721,10 +723,9 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
case OP_GP2_DEC:
|
||||
strncat(buffer, "dec", bufferSize);
|
||||
break;
|
||||
case OP_GP2_CALL1:
|
||||
case OP_GP2_CALL:
|
||||
if (opcode == 0xFF)
|
||||
{
|
||||
// TODO: Understand this opcode
|
||||
strncat(buffer, "call", bufferSize);
|
||||
}
|
||||
else
|
||||
@@ -733,11 +734,10 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
opcodeParams = PR_NONE;
|
||||
}
|
||||
break;
|
||||
case OP_GP2_CALL2:
|
||||
case OP_GP2_CALLF:
|
||||
if (opcode == 0xFF)
|
||||
{
|
||||
// TODO: Understand this opcode
|
||||
strncat(buffer, "call", bufferSize);
|
||||
strncat(buffer, "call far", bufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -745,10 +745,9 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
opcodeParams = PR_NONE;
|
||||
}
|
||||
break;
|
||||
case OP_GP2_JMP1:
|
||||
case OP_GP2_JMP:
|
||||
if (opcode == 0xFF)
|
||||
{
|
||||
// TODO: Understand this opcode
|
||||
strncat(buffer, "jmp", bufferSize);
|
||||
}
|
||||
else
|
||||
@@ -757,11 +756,10 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
opcodeParams = PR_NONE;
|
||||
}
|
||||
break;
|
||||
case OP_GP2_JMP2:
|
||||
case OP_GP2_JMPF:
|
||||
if (opcode == 0xFF)
|
||||
{
|
||||
// TODO: Understand this opcode
|
||||
strncat(buffer, "jmp", bufferSize);
|
||||
strncat(buffer, "jmp far", bufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -791,9 +789,9 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
|
||||
case OP_MOVG:
|
||||
/* Special case for C6 and C7, they are valid ONLY if reg == 0 */
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
||||
if (reg > 0)
|
||||
if (reg != 0)
|
||||
{
|
||||
strncat(buffer, "illegal", bufferSize);
|
||||
opcodeParams = PR_NONE;
|
||||
@@ -803,6 +801,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
{
|
||||
strncat(buffer, "mov", bufferSize);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
strncat(buffer, opcodeName, bufferSize);
|
||||
@@ -856,202 +855,202 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
|
||||
/******* Immediate values *******/
|
||||
case PR_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
/******* Register / Immediate *******/
|
||||
case PR_AL_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " al, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_AH_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " ah, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_AX_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " ax, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_AX_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " ax, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " ax, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_IM8_AL:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " 0%Xh, al", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_IM8_AX:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " 0%Xh, ax", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_BL_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " bl, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_BH_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " bh, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_BX_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " bx, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " bx, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_CL_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " cl, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_CH_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " ch, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_CX_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " cx, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " cx, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_DL_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " dl, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_DH_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " dh, 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset++;
|
||||
break;
|
||||
|
||||
case PR_DX_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " dx, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " dx, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_SP_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " sp, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " sp, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_BP_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " bp, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " bp, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_DI_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " di, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " di, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_SI_IM16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " si, 0%Xh", param1 & 0xFF);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
snprintf(buf, 63, " si, 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
/******* Register / Memory *******/
|
||||
case PR_M8_AL:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
/* TODO: If having a list of known label, try to match and display label instead of value */
|
||||
snprintf(buf, 63, " byte [0%Xh], al", param1 & 0xFF);
|
||||
snprintf(buf, 63, " byte [0%Xh], al", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_M16_AX:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
/* TODO: If having a list of known label, try to match and display label instead of value */
|
||||
snprintf(buf, 63, " word [0%Xh], ax", param1 & 0xFF);
|
||||
snprintf(buf, 63, " word [0%Xh], ax", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_AL_M8:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
/* TODO: If having a list of known label, try to match and display label instead of value */
|
||||
snprintf(buf, 63, " al, byte [0%Xh]", param1 & 0xFF);
|
||||
snprintf(buf, 63, " al, byte [0%Xh]", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
case PR_AX_M16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
/* TODO: If having a list of known label, try to match and display label instead of value */
|
||||
snprintf(buf, 63, " ax, word [0%Xh]", param1 & 0xFF);
|
||||
snprintf(buf, 63, " ax, word [0%Xh]", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 2;
|
||||
break;
|
||||
|
||||
/******* Address calculation *******/
|
||||
case PR_REL8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
param1 = currentOffset + (int8_t)param1;
|
||||
/* TODO: If having a list of known label, try to match and display label instead of value */
|
||||
@@ -1061,8 +1060,8 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_REL16:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset += 2;
|
||||
param1 = currentOffset + (int16_t) param1;
|
||||
|
||||
@@ -1073,21 +1072,21 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_ABS32:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param2 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 3)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param2 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 3)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
||||
/* TODO: If having a list of known label, try to match and display label instead of value */
|
||||
snprintf(buf, 63, " 0%Xh:0%Xh", param2, param1);
|
||||
snprintf(buf, 63, " 0%Xh:0%Xh", param2 & 0xFFFF, param1 & 0xFFFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 4;
|
||||
break;
|
||||
|
||||
/******* Other cases *******/
|
||||
case PR_IM16_IM8:
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param2 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param2 = mem_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
||||
snprintf(buf, 63, " 0%Xh:0%Xh", param1, param2);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += 3;
|
||||
@@ -1097,55 +1096,55 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
************************************************ Complicated cases ************************************************
|
||||
******************************************************************************************************************/
|
||||
case PR_RM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_RM16:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_RM_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
snprintf(buf, 63, ", 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_RM16_IM8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset ++;
|
||||
snprintf(buf, 63, ", 0%Xh", param1 & 0xFF);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_RM_IM16:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset += 2;
|
||||
snprintf(buf, 63, ", 0%Xh", param1);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_RM8_1:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
||||
@@ -1153,7 +1152,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_RM16_1:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
@@ -1161,7 +1160,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_RM8_CL:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
||||
@@ -1169,7 +1168,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_RM16_CL:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
@@ -1177,7 +1176,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_RM_R8:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
||||
@@ -1186,7 +1185,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
break;
|
||||
|
||||
case PR_RM_R16:
|
||||
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
@@ -1194,12 +1193,46 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
strncat(buffer, buf, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_R_RM8:
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
||||
snprintf(buf, 63, " %s,", modrmReg8List[reg]);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_R_RM16:
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
||||
snprintf(buf, 63, " %s,", modrmReg16List[reg]);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_RM16_SEG:
|
||||
// TODO: Find how to decode the segment value
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset += 2;
|
||||
snprintf(buf, 63, ", %s", segmentRegList[reg]);
|
||||
strncat(buffer, buf, bufferSize);
|
||||
break;
|
||||
|
||||
case PR_SEG_RM16:
|
||||
// TODO: Find how to decode the segment value
|
||||
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset++;
|
||||
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
||||
snprintf(buf, 63, ", %s", segmentRegList[reg]);
|
||||
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
||||
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
||||
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
||||
currentOffset += 2;
|
||||
strncat(buffer, buf, bufferSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1216,3 +1249,22 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
||||
|
||||
return currentOffset - offset;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((I.sregs[CS] == 0x0600) /* && (I.ip > 0x0050) */)
|
||||
{
|
||||
int tmp;
|
||||
char buffer[256];
|
||||
uint8_t op = mem_readmem20((I.sregs[CS] << 4) + I.ip);
|
||||
//Log(TLOG_NORMAL, "NEC v30", "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, instructionsName[op], I.IF);
|
||||
printf("AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n",
|
||||
I.regs.w[AW], I.regs.w[BW], I.regs.w[CW], I.regs.w[DW],
|
||||
I.regs.w[IX], I.regs.w[IY], I.regs.w[SP]);
|
||||
printf("CS: %04X, DS: %04X, SS: %04X, ES: %04X\n",
|
||||
I.sregs[CS], I.sregs[DS], I.sregs[SS], I.sregs[ES]);
|
||||
memset(buffer, 0, 256);
|
||||
nec_decode_instruction(I.sregs[CS], I.ip, buffer, 255);
|
||||
printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF);
|
||||
tmp = getchar();
|
||||
}
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* NewOswan
|
||||
* nec_debugger.h:
|
||||
* Created by Manoël Trapier on 14/04/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H
|
||||
#define NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H
|
||||
|
||||
|
||||
int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsigned int bufferSize);
|
||||
|
||||
#endif /* NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H */
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* necea.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t EA;
|
||||
static uint16_t EO;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* necinstr.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* 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_wr16(void);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* necmodrm.h:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static struct
|
||||
{
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* audio.c:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Sound information thanks to toshi (wscamp wonderswan emulator)
|
||||
// Note that sound is far from perfect for now.
|
||||
//
|
||||
// fixes by zalas 2002-08-21
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// alternate the commenting of the following defines to get audio port tracing
|
||||
#define dbgprintf(...)
|
||||
@@ -29,7 +20,7 @@
|
||||
#include <unistd.h>
|
||||
#include "log.h"
|
||||
#include "rom.h"
|
||||
#include "./nec/nec.h"
|
||||
#include "nec.h"
|
||||
#include "memory.h"
|
||||
#include "io.h"
|
||||
#include "audio.h"
|
||||
@@ -71,6 +62,82 @@
|
||||
#define PDIV 3
|
||||
#define PH POFF+PDIV*8
|
||||
#define PL POFF-PDIV*7
|
||||
#if 0
|
||||
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8e:
|
||||
case 0x8f:
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
case 0x92:
|
||||
case 0x93:
|
||||
case 0x94:
|
||||
retVal = ws_audio_port_read(port);
|
||||
break;
|
||||
|
||||
|
||||
/* Audio */
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
ws_audio_port_write(port, value);
|
||||
break;
|
||||
|
||||
/* Audio */
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
case 0x88:
|
||||
case 0x89:
|
||||
case 0x8a:
|
||||
case 0x8b:
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
case 0x8e:
|
||||
case 0x8f:
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
case 0x92:
|
||||
case 0x93:
|
||||
case 0x94:
|
||||
case 0x95:
|
||||
case 0x96:
|
||||
case 0x97:
|
||||
case 0x98:
|
||||
case 0x99:
|
||||
case 0x9A:
|
||||
case 0x9B:
|
||||
case 0x9C:
|
||||
case 0x9D:
|
||||
case 0x9E:
|
||||
ws_audio_port_write(port, value);
|
||||
break;
|
||||
|
||||
|
||||
int WaveMap;
|
||||
int ChPerInit;
|
||||
@@ -107,17 +174,6 @@ const long TblMainVol[4]= // 1,1/2,1/4,1/8
|
||||
};
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// seal audio specific
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//HAC ws_audio_pcm_voice[4];
|
||||
//HAC ws_audio_noise_voice;
|
||||
//HAC ws_audio_sweep_voice;
|
||||
@@ -130,17 +186,9 @@ uint32_t ws_audio_channel_isPlaying[6];
|
||||
|
||||
static unsigned int ws_audio_log;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO: Temporary to let build for now
|
||||
static uint8_t ws_ioRam[0x100];
|
||||
|
||||
void ws_audio_init(void)
|
||||
{
|
||||
Log(TLOG_NORMAL, "audio", "audio init");
|
||||
@@ -149,17 +197,6 @@ void ws_audio_init(void)
|
||||
ws_audio_reset();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_reset(void)
|
||||
{
|
||||
WaveMap = -1;
|
||||
@@ -182,17 +219,6 @@ void ws_audio_reset(void)
|
||||
ws_audio_set_channel_frequency(4, 1792);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_port_write(uint32_t port, uint8_t value)
|
||||
{
|
||||
uint32_t n, i, j, k, b;
|
||||
@@ -210,8 +236,8 @@ void ws_audio_port_write(uint32_t port, uint8_t value)
|
||||
|
||||
for (k = 0 ; k < n ; k++)
|
||||
{
|
||||
b = cpu_readmem20(i);
|
||||
cpu_writemem20(j, b);
|
||||
b = mem_readmem20(i);
|
||||
mem_writemem20(j, b);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
@@ -409,49 +435,16 @@ void ws_audio_port_write(uint32_t port, uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t ws_audio_port_read(uint8_t port)
|
||||
{
|
||||
return (ws_ioRam[port]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_done(void)
|
||||
{
|
||||
ws_audio_seal_done();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
unsigned int ws_audio_mrand(unsigned int Degree)
|
||||
{
|
||||
#define BIT(n) (1<<n)
|
||||
@@ -533,18 +526,6 @@ unsigned int ws_audio_mrand(unsigned int Degree)
|
||||
return ShiftReg;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_seal_init(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -691,17 +672,6 @@ int ws_audio_seal_init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_seal_done(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -746,17 +716,6 @@ void ws_audio_seal_done(void)
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_clear_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -782,17 +741,6 @@ void ws_audio_clear_channel(int Channel)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// start playing a channel
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_play_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -821,17 +769,6 @@ int ws_audio_play_channel(int Channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// stop playing a channel
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_stop_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -858,17 +795,6 @@ int ws_audio_stop_channel(int Channel)
|
||||
return (0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_set_channel_frequency(int Channel, int Period)
|
||||
{
|
||||
#if 0
|
||||
@@ -914,17 +840,6 @@ void ws_audio_set_channel_frequency(int Channel, int Period)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_set_channel_volume(int Channel, int Vol)
|
||||
{
|
||||
#if 0
|
||||
@@ -954,17 +869,6 @@ void ws_audio_set_channel_volume(int Channel, int Vol)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_set_channel_pan(int Channel, int Left, int Right)
|
||||
{
|
||||
#if 0
|
||||
@@ -1030,17 +934,6 @@ void ws_audio_set_channel_pan(int Channel, int Left, int Right)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_set_channel_pdata(int Channel, int Index)
|
||||
{
|
||||
#if 0
|
||||
@@ -1068,17 +961,6 @@ void ws_audio_set_channel_pdata(int Channel, int Index)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_set_channels_pbuf(int Addr, int Data)
|
||||
{
|
||||
#if 0
|
||||
@@ -1099,17 +981,6 @@ void ws_audio_set_channels_pbuf(int Addr, int Data)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_rst_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -1121,17 +992,6 @@ void ws_audio_rst_channel(int Channel)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_int(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -1175,17 +1035,7 @@ int ws_audio_int(void)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
static uint32_t PCMPos=0;
|
||||
uint32_t TickZ=0,PcmCount;
|
||||
@@ -1220,17 +1070,6 @@ void ws_audio_set_pcm(int Data)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_flash_pcm(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -1262,37 +1101,15 @@ void ws_audio_flash_pcm(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_write_byte(uint32_t offset, uint8_t value)
|
||||
{
|
||||
if (!((offset - WaveMap) & 0xFFC0))
|
||||
{
|
||||
ws_audio_set_channels_pbuf(offset & 0x003F, value);
|
||||
internalRam[offset] = value;
|
||||
//internalRam[offset] = value;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_process(void)
|
||||
{
|
||||
uint32_t i, j, b;
|
||||
@@ -1304,7 +1121,7 @@ void ws_audio_process(void)
|
||||
{
|
||||
i = (SDMACH << 8) | SDMACL;
|
||||
j = (SDMASB << 16) | (SDMASH << 8) | SDMASL;
|
||||
b = cpu_readmem20(j);
|
||||
b = mem_readmem20(j);
|
||||
|
||||
if (!ws_audio_channel_isPlaying[5])
|
||||
{
|
||||
@@ -1356,17 +1173,6 @@ void ws_audio_process(void)
|
||||
ws_audio_set_pcm(b);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_readState(int fp)
|
||||
{
|
||||
#if 0
|
||||
@@ -1457,17 +1263,6 @@ void ws_audio_readState(int fp)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_writeState(int fp)
|
||||
{
|
||||
#if 0
|
||||
@@ -1536,3 +1331,5 @@ void ws_audio_writeState(int fp)
|
||||
write(fp,&lpnStatus,sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
44
source/peripherals/buttons.c
Normal file
44
source/peripherals/buttons.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
8
source/peripherals/color_gpu.c
Normal file
8
source/peripherals/color_gpu.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
57
source/peripherals/color_system.c
Normal file
57
source/peripherals/color_system.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
|
||||
36
source/peripherals/debug.c
Normal file
36
source/peripherals/debug.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
106
source/peripherals/dma.c
Normal file
106
source/peripherals/dma.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
336
source/peripherals/eeprom.c
Normal file
336
source/peripherals/eeprom.c
Normal file
@@ -0,0 +1,336 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
}
|
||||
}
|
||||
98
source/peripherals/interrupt_controller.c
Normal file
98
source/peripherals/interrupt_controller.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
|
||||
}
|
||||
}
|
||||
128
source/peripherals/mono_gpu.c
Normal file
128
source/peripherals/mono_gpu.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
91
source/peripherals/mono_system.c
Normal file
91
source/peripherals/mono_system.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
230
source/peripherals/rs232.c
Normal file
230
source/peripherals/rs232.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/*******************************************************************************
|
||||
* 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()
|
||||
{
|
||||
|
||||
}
|
||||
103
source/peripherals/rtc.c
Normal file
103
source/peripherals/rtc.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
8
source/peripherals/timer.c
Normal file
8
source/peripherals/timer.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* timer.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 26/06/2022.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
81
source/peripherals/universal_luxor.c
Normal file
81
source/peripherals/universal_luxor.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
79
source/rom.c
79
source/rom.c
@@ -1,18 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* tom.c:
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* rom.c:
|
||||
*
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -23,20 +16,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "log.h"
|
||||
#include "rom.h"
|
||||
#include <log.h>
|
||||
#include <rom.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t *ws_rom_load(char *path, uint32_t *romSize)
|
||||
{
|
||||
int fd;
|
||||
@@ -62,18 +44,6 @@ uint8_t *ws_rom_load(char *path, uint32_t *romSize)
|
||||
return ret_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const char *eepromSizeName[] =
|
||||
{
|
||||
[WS_EEPROM_SIZE_NONE] = "none",
|
||||
@@ -106,17 +76,6 @@ void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t romSize)
|
||||
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));
|
||||
@@ -124,17 +83,6 @@ ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize)
|
||||
return (wsromHeader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize)
|
||||
{
|
||||
ws_romHeaderStruct *romHeader = ws_rom_getHeader(wsrom, wsromSize);
|
||||
@@ -166,17 +114,6 @@ uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize)
|
||||
return (0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize)
|
||||
{
|
||||
ws_romHeaderStruct *romHeader = ws_rom_getHeader(wsrom, wsromSize);
|
||||
|
||||
224
source/ws.c
224
source/ws.c
@@ -1,23 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* ws.c: Base wonderswan implementation
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// 07.04.2002: speed problems partially fixed
|
||||
// 13.04.2002: Set cycles by line to 256 (according to toshi)
|
||||
// this seems to work well in most situations with
|
||||
// the new nec v30 cpu core
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -26,27 +14,15 @@
|
||||
#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"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#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;
|
||||
@@ -58,43 +34,11 @@ char *ws_ieep_path = NULL;
|
||||
char *ws_rom_path = NULL;
|
||||
wssystem_t systemType;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_patchRom(void)
|
||||
{
|
||||
|
||||
uint8_t *rom = memory_getRom();
|
||||
uint32_t romSize = memory_getRomSize();
|
||||
|
||||
Log(TLOG_DEBUG, "ws", "developper Id: 0x%.2x", rom[romSize - 10]);
|
||||
Log(TLOG_DEBUG, "ws", "Game Id: 0x%.2x", rom[romSize - 8]);
|
||||
|
||||
if (!ws_cyclesByLine)
|
||||
{
|
||||
ws_cyclesByLine = 256;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_init(char *rompath)
|
||||
{
|
||||
uint8_t *rom;
|
||||
@@ -105,7 +49,7 @@ int ws_init(char *rompath)
|
||||
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)
|
||||
{
|
||||
@@ -128,62 +72,34 @@ int ws_init(char *rompath)
|
||||
Log(TLOG_PANIC, "ws", "Card EEPROM load error!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ws_memory_init(rom, romSize);
|
||||
ws_patchRom();
|
||||
#endif
|
||||
|
||||
ws_io_init();
|
||||
ws_audio_init();
|
||||
ws_gpu_init();
|
||||
|
||||
if (ws_rotated())
|
||||
{
|
||||
ws_io_flipControls();
|
||||
}
|
||||
io_init();
|
||||
//ws_audio_init();
|
||||
//ws_gpu_init();
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_reset(void)
|
||||
{
|
||||
ws_memory_reset();
|
||||
ws_io_reset();
|
||||
ws_audio_reset();
|
||||
ws_gpu_reset();
|
||||
//io_reset();
|
||||
//ws_audio_reset();
|
||||
//ws_gpu_reset();
|
||||
nec_reset(NULL);
|
||||
nec_set_reg(NEC_SP, 0x2000);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_executeLine(int16_t *framebuffer, int renderLine)
|
||||
{
|
||||
int drawWholeScreen = 0;
|
||||
|
||||
ws_audio_process();
|
||||
//ws_audio_process();
|
||||
|
||||
// update scanline register
|
||||
ws_ioRam[2] = ws_gpu_scanline;
|
||||
//ws_ioRam[2] = ws_gpu_scanline;
|
||||
|
||||
/* Why twice like that and random cycle count???? */
|
||||
ws_cycles = nec_execute((ws_cyclesByLine >> 1) + (rand() & 7));
|
||||
@@ -200,8 +116,10 @@ int ws_executeLine(int16_t *framebuffer, int renderLine)
|
||||
|
||||
ws_cycles %= ws_cyclesByLine;
|
||||
|
||||
#if 0
|
||||
for (uint32_t uI = 0 ; uI < ws_skip ; uI++)
|
||||
{
|
||||
|
||||
if (renderLine)
|
||||
{
|
||||
ws_gpu_renderScanline(framebuffer);
|
||||
@@ -213,36 +131,41 @@ int ws_executeLine(int16_t *framebuffer, int renderLine)
|
||||
{
|
||||
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 */
|
||||
@@ -269,40 +192,18 @@ int ws_executeLine(int16_t *framebuffer, int renderLine)
|
||||
ws_ioRam[0xb6] &= ~16;
|
||||
nec_int((ws_ioRam[0xb0] + 4) * 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (drawWholeScreen);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_done(void)
|
||||
{
|
||||
ws_memory_done();
|
||||
ws_io_done();
|
||||
ws_audio_done();
|
||||
ws_gpu_done();
|
||||
io_cleanup();
|
||||
//ws_audio_done();
|
||||
//ws_gpu_done();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_set_system(wssystem_t system)
|
||||
{
|
||||
if (system == WS_SYSTEM_AUTODETECT)
|
||||
@@ -316,23 +217,15 @@ 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;
|
||||
@@ -387,25 +280,18 @@ int ws_loadState(char *statepath)
|
||||
|
||||
// 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];
|
||||
@@ -480,25 +366,15 @@ int ws_saveState(char *statepath)
|
||||
|
||||
ws_audio_writeState(fp);
|
||||
close(fp);
|
||||
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_rotated(void)
|
||||
{
|
||||
uint8_t *rom = memory_getRom();
|
||||
uint32_t romSize = memory_getRomSize();
|
||||
//uint8_t *rom = memory_getRom();
|
||||
//uint32_t romSize = memory_getRomSize();
|
||||
|
||||
return (rom[romSize - 4] & 1);
|
||||
//return (rom[romSize - 4] & 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
13
testserial.c
13
testserial.c
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* testserial.c: A simple tool to test serial in/out
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -14,6 +15,10 @@
|
||||
#include <errno.h> /* Error number definitions */
|
||||
#include <termios.h> /* POSIX terminal control definitions */
|
||||
|
||||
/*
|
||||
* The code, as is, was part of a fuzzer for the WonderSwan Tetris game.
|
||||
*/
|
||||
|
||||
/* Serial port */
|
||||
#define BDR_9600 (0)
|
||||
#define BDR_38400 (1)
|
||||
|
||||
Reference in New Issue
Block a user