28 Commits

Author SHA1 Message Date
Godzil
330cba592d Cosmetic, and add missing files to the CMakeLists. 2022-06-27 22:33:36 +01:00
Godzil
e48f7a76a7 Merge the latest changes. 2022-06-27 22:14:47 +01:00
Godzil
4800cf0823 Commented some code to let it build. 2022-06-27 18:20:11 +01:00
Godzil
a37414b079 Cleanup memory and added file_access. 2022-06-27 18:19:51 +01:00
Godzil
e9d7f1aa04 Add base address for IO ports to easily allow multiple instance of the same device. 2022-06-27 17:57:03 +01:00
Godzil
37e4b219d4 Add a skeleton for the interrupt controller 2022-06-27 17:04:55 +01:00
Godzil
d6a2a77303 Add the possibility to pass parameter to device_init
and add a device_type_t used to know what parameter to pass to init
when needed.
2022-06-27 17:04:37 +01:00
Godzil
f45995167e Add some temporary disabled code for each peripheral
(copied from io.c)
2022-06-27 17:02:35 +01:00
Godzil
83e4b8d5d9 Some more cosmetics. 2022-06-27 17:01:07 +01:00
Godzil
4d345079ae Fix building
Most patches are temporary and there just to let the code to build. It will not work in the current state.
Also now force the use of paged memory. It was not working properly because of the way the old GPU code is working.
2022-06-27 16:59:11 +01:00
Godzil
5f61fb612a Merge branch 'master' into rewrite 2022-06-25 21:23:05 +01:00
Godzil
2305ce975b Mostly cosmetic changes
Update headers year
Remove useless /// headers that eat lines for no reasons
Fixed build issues because of stupid me doing stupid stuff in prototypes.
Added color and mono GPU stub.
Also a tad of code cleaning.
2022-03-14 14:50:41 +00:00
Manoël Trapier
01ffa3a834 Add apt update. part 2 2022-03-12 12:04:45 +00:00
Manoël Trapier
fce2815300 Add apt update. 2022-03-12 12:04:18 +00:00
Manoël Trapier
662a45d02f Create codeql-analysis.yml 2022-02-28 15:32:33 +00:00
Manoël Trapier
bb324dc12e Remplace travis build badge with github's one. 2022-02-28 12:33:51 +00:00
Godzil
017983f692 Trying to make the google action to work. 2022-02-28 12:31:43 +00:00
Godzil
b4b1bd83d0 Fix a typo 2022-02-25 18:19:00 +00:00
Manoël Trapier
a85e1ff083 Need to checkout with submodule silly! 2022-02-23 18:02:31 +00:00
Manoël Trapier
4c9ba704ea Testing github action
Travis is no longer free. So need to test alternatives.
2022-02-23 17:59:53 +00:00
Godzil
6f56a8efda Starting a rewrite of how the IO works.
Currently 100% broken, also going to change how devices are selected
for each system so no more if/else everywhere and system should be more accurate.
2021-12-20 19:12:33 +00:00
Godzil
8fa2ef06ab Rename some functions and a tad of cleanup. 2021-12-20 19:12:33 +00:00
Godzil
4fc5193bc7 Add testserial part of the build. 2021-12-20 19:12:30 +00:00
Godzil
1df15b0192 Uniformise copyright headers. 2021-12-20 19:12:12 +00:00
Godzil
6f539fff1e Not sure how I missed the R_RM8 and R_RM16 decoder. 2021-04-16 00:39:26 +01:00
Godzil
c90b99d650 Fix table size. 2021-04-16 00:33:48 +01:00
Godzil
49a1943cda Add proper support for indirect call/jmp 2021-04-16 00:32:56 +01:00
Godzil
4082d37cb0 Add missing mov cs, rm and mov rm, cs opcode. 2021-04-16 00:32:08 +01:00
54 changed files with 2317 additions and 2940 deletions

38
.github/workflows/cmake.yml vendored Normal file
View 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
View 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

View File

@@ -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)

View File

@@ -1,6 +1,6 @@
NewOswan *(name likely to change)*
==================================
![TravisBadge](https://travis-ci.org/Godzil/NewOswan.svg?branch=master)
[![CMake](https://github.com/Godzil/NewOswan/actions/workflows/cmake.yml/badge.svg)](https://github.com/Godzil/NewOswan/actions/workflows/cmake.yml)
### What is this project?
NewOswan is a WonderSwan emulator originally based on oswan-unix and heavily modified to be more accurate and better

View File

@@ -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
View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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))
{
}
}

View File

@@ -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
View 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;
}

View File

@@ -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

View File

@@ -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
View 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
View 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 */

View 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__ */

View File

@@ -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;

View 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
View 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

View File

@@ -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
View 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__ */

View File

@@ -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

View 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__ */

View File

@@ -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__ */

View File

@@ -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__ */

View File

@@ -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__ */

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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_

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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/)

View File

@@ -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]();

View File

@@ -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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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, &reg, 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

View File

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

View File

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

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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

View 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

View 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.
*
******************************************************************************/

View 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

View 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
View 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
View 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;
}
}

View 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
}
}

View 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

View 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
View 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
View 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;
}
}

View 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.
*
******************************************************************************/

View 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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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)