13 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
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
49 changed files with 1915 additions and 2749 deletions

View File

@@ -2,7 +2,7 @@
* 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.
*
******************************************************************************/

55
main.c
View File

@@ -1,47 +1,28 @@
/******************************************************************************
* NewOswan
* main.c: Entry point
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
// 13.04.2002: Fixed a small bug causing crashes
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "source/log.h"
#include "source/rom.h"
#include "source/nec/nec.h"
#include "source/memory.h"
#include "source/gpu.h"
#include "source/io.h"
#include "source/ws.h"
#include "source/emulate.h"
#include "source/audio.h"
#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;
@@ -103,18 +84,6 @@ int ws_mk_ieppath()
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
wssystem_t ws_system = WS_SYSTEM_AUTODETECT;
@@ -182,7 +151,6 @@ int main(int argc, char *argv[])
if (ws_init(ws_rom_path))
{
ws_reset();
ws_emulate();
}
@@ -192,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,20 +1,12 @@
/*******************************************************************************
* NewOswan
* emulate.c:
*
* 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 <stdint.h>
@@ -38,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;
@@ -247,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;
@@ -339,6 +332,7 @@ static void read_keys()
{
ws_cyclesByLine -= 10;
}
#endif
}
#else
typedef struct PseudoWindow_t
@@ -410,17 +404,6 @@ double getTicks()
return ticks;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate(void)
{
int32_t nCount = 0;
@@ -479,7 +462,7 @@ 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))
{
}
}

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,68 +1,36 @@
/*******************************************************************************
* NewOswan
* gpu.c:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// GPU
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
// 7.04.2002: Fixed sprites order
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#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;
@@ -105,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);
@@ -137,17 +94,6 @@ void ws_gpu_init(void)
memset(wsc_modified_tile, 0x01, 1024);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_gpu_done(void)
{
free(ws_tile_cache);
@@ -158,17 +104,6 @@ void ws_gpu_done(void)
free(wsc_modified_tile);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_gpu_changeVideoMode(uint8_t value)
{
if (ws_videoMode != (value >> 5))
@@ -187,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);
@@ -208,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)
@@ -447,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)
@@ -542,17 +432,6 @@ void ws_drawClippedSpriteLine(int16_t *framebuffer, uint16_t scanline, uint32_t
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_gpu_renderScanline(int16_t *framebuffer)
{
@@ -1901,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
@@ -1968,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)
@@ -2038,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)
@@ -2080,3 +1926,5 @@ uint8_t ws_gpu_port_read(uint8_t port)
return (ws_ioRam[port]);
}
#endif

View File

@@ -1,20 +1,12 @@
/*******************************************************************************
* NewOswan
* audio.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* 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__ */

View File

@@ -1,19 +1,12 @@
/*******************************************************************************
* NewOswan
* emulate.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef EMULATE_H
#define 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,8 +1,9 @@
/*******************************************************************************
* NewOswan
* gpu.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
@@ -11,6 +12,12 @@
#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,9 +1,10 @@
/*******************************************************************************
* NewOswan
* log.h: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* Created by Manoël Trapier on 20/01/2009.
* Copyright (c) 2009-2022 986-Studio. All rights reserved.
*
******************************************************************************/
#ifndef _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,8 +1,9 @@
/******************************************************************************
* NewOswan
* nec.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/

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,14 +1,15 @@
/******************************************************************************
* NewOswan
* necintrf.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* 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>
@@ -45,4 +46,4 @@ unsigned nec_get_reg(int regnum);
void nec_reset(void *param);
void nec_int(uint16_t vector);
#endif /* __NECITRF_H_ */
#endif /* __NECITRF_H__ */

View File

@@ -1,20 +1,12 @@
/*******************************************************************************
* NewOswan
* rom.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __ROM_H__
#define __ROM_H__
@@ -75,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,20 +1,12 @@
/*******************************************************************************
* NewOswan
* ws.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __WS_H__
#define __WS_H__
@@ -43,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,45 +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 io_init(void);
void io_reset(void);
void io_flipControls(void);
void io_done(void);
uint8_t io_readport(uint8_t port);
void io_writeport(uint32_t port, uint8_t value);
#endif

View File

@@ -1,9 +1,10 @@
/*******************************************************************************
* NewOswan
* log.c: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* 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,261 +1,22 @@
/*******************************************************************************
* NewOswan
* memory.c: Memory implementation
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// Notes: need to optimize mem_writemem20
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "ws.h"
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "io.h"
#include "gpu.h"
#include "audio.h"
#include "memory.h"
#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 mem_writemem20(uint32_t addr, uint8_t value)
{
uint32_t offset = addr & 0xffff;
uint32_t bank = addr >> 16;
if (!bank)
{
// 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
ws_gpu_write_byte(offset, value);
ws_audio_write_byte(offset, value);
}
else if (bank == 1)
{
// 1 - SRAM (cart)
ws_staticRam[offset & sramAddressMask] = value;
}
// other banks are read-only
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t mem_readmem20(uint32_t addr)
{
uint32_t offset = addr & 0xffff;
uint32_t bank = addr >> 16;
//uint16_t romBank;
uint8_t hwReg;
uint32_t temp;
uint8_t ret;
wssystem_t currentSystem = ws_get_system();
switch (bank)
{
case 0:
/*
* So the original WonderSwan, and Color/Crystal in B&W mode have 16KB of IRAM Mapped.
* Color/Crystal in color mode have 64 KB IRAM mapped.
*/
if (ws_gpu_operatingInColor)
{
return (internalRam[offset]);
}
else if (offset < 0x4000)
{
return (internalRam[offset]);
}
return (0x90);
case 1: // 1 - SRAM (cart)
return ws_staticRam[offset & sramAddressMask];
case 2:
// Bank 2
hwReg = ws_ioRam[0xC2];
temp = hwReg << 16;
temp += offset;
temp &= (romSize - 1);
return ws_rom[temp];
case 3:
// Bank 3
hwReg = ws_ioRam[0xC3];
temp = hwReg << 16;
temp += offset;
temp &= (romSize - 1);
return ws_rom[temp];
case 0xF:
hwReg = ws_ioRam[0xA0];
if (!(hwReg & 1))
{
if (currentSystem == WS_SYSTEM_COLOR && ws_haveColorIRom)
{
if (addr >= 0xFE000)
{
ret = internalColorIRom[addr & ~0xFE000];
return ret;
}
}
else if (currentSystem == WS_SYSTEM_CRYSTAL && ws_haveColorIRom)
{
if (addr >= 0xFE000)
{
ret = internalCrystalIRom[addr & ~0xFE000];
return ret;
}
}
else if (currentSystem == WS_SYSTEM_MONO && ws_haveBWIRom)
{
if (addr >= 0xFF000)
{
ret = internalBWIRom[addr & ~0xFF000];
return ret;
}
}
}
// fall through
default:
hwReg = ws_ioRam[0xC0];
temp = hwReg << 20;
temp += addr & 0xFFFFF;
temp &= (romSize - 1);
return ws_rom[temp];
}
return (0x90);
}
#else
/* 256 page of 12 bits */
uint8_t *pagedMemory[0x100];
@@ -264,6 +25,8 @@ 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 */
@@ -278,6 +41,7 @@ uint8_t mem_readmem20(uint32_t addr)
{
uint8_t page = addr >> 12;
uint16_t offset = addr & 0xFFF;
if (pagedMemory[page])
{
return pagedMemory[page][offset];
@@ -299,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,71 +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 mem_readop mem_readmem20
#define mem_readop_arg mem_readmem20
void mem_writemem20(uint32_t addr, uint8_t value);
uint8_t mem_readmem20(uint32_t addr);
#define BW_IEEPROM_SIZE (128)
#define COLOR_IEEPROM_SIZE (2048)
#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,8 +1,9 @@
/******************************************************************************
* NewOswan
* nec.c:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
@@ -40,12 +41,12 @@
#include <log.h>
#include "memory.h"
#include "io.h"
#include <memory.h>
#include <io.h>
#include "nec.h"
#include "necintrf.h"
#include "nec_debugger.h"
#include <nec.h>
#include <necintrf.h>
#include <nec_debugger.h>
/***************************************************************************/
/* cpu state */
@@ -4225,21 +4226,21 @@ int nec_execute(int cycles)
while (nec_ICount > 0)
{
#if 0
if ((I.sregs[CS] == 0xF000) && (I.ip >= 0x0000) )
if ( ws_ioRam[0xA0] & 0x01 )
{
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",
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,23 +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 "memory.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.
*/
@@ -790,7 +791,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
/* Special case for C6 and C7, they are valid ONLY if reg == 0 */
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;
@@ -800,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);

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,8 +1,9 @@
/******************************************************************************
* NewOswan
* necea.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/

View File

@@ -1,8 +1,9 @@
/******************************************************************************
* NewOswan
* necinstr.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/

View File

@@ -1,8 +1,9 @@
/******************************************************************************
* NewOswan
* necmodrm.h:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/

View File

@@ -1,22 +1,12 @@
/*******************************************************************************
* NewOswan
* audio.c:
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 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
//
//
//
////////////////////////////////////////////////////////////////////////////////
// alternate the commenting of the following defines to get audio port tracing
#define dbgprintf(...)
//#define dbgprintf(...) printf(...)
@@ -30,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"
@@ -72,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;
@@ -108,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;
@@ -131,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");
@@ -150,17 +197,6 @@ void ws_audio_init(void)
ws_audio_reset();
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_reset(void)
{
WaveMap = -1;
@@ -183,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;
@@ -410,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)
@@ -534,18 +526,6 @@ unsigned int ws_audio_mrand(unsigned int Degree)
return ShiftReg;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_audio_seal_init(void)
{
#if 0
@@ -692,17 +672,6 @@ int ws_audio_seal_init(void)
return 1;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_seal_done(void)
{
#if 0
@@ -747,17 +716,6 @@ void ws_audio_seal_done(void)
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_clear_channel(int Channel)
{
#if 0
@@ -783,17 +741,6 @@ void ws_audio_clear_channel(int Channel)
#endif
}
////////////////////////////////////////////////////////////////////////////////
// start playing a channel
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_audio_play_channel(int Channel)
{
#if 0
@@ -822,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
@@ -859,17 +795,6 @@ int ws_audio_stop_channel(int Channel)
return (0);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_set_channel_frequency(int Channel, int Period)
{
#if 0
@@ -915,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
@@ -955,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
@@ -1031,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
@@ -1069,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
@@ -1100,17 +981,6 @@ void ws_audio_set_channels_pbuf(int Addr, int Data)
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_rst_channel(int Channel)
{
#if 0
@@ -1122,17 +992,6 @@ void ws_audio_rst_channel(int Channel)
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_audio_int(void)
{
#if 0
@@ -1176,17 +1035,7 @@ int ws_audio_int(void)
#endif
return 1;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#if 0
static uint32_t PCMPos=0;
uint32_t TickZ=0,PcmCount;
@@ -1221,17 +1070,6 @@ void ws_audio_set_pcm(int Data)
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_flash_pcm(void)
{
#if 0
@@ -1263,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;
@@ -1357,17 +1173,6 @@ void ws_audio_process(void)
ws_audio_set_pcm(b);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_readState(int fp)
{
#if 0
@@ -1458,17 +1263,6 @@ void ws_audio_readState(int fp)
#endif
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_audio_writeState(int fp)
{
#if 0
@@ -1537,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,20 +1,12 @@
/*******************************************************************************
* NewOswan
* rom.c:
*
* 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 <stdint.h>
@@ -24,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;
@@ -63,18 +44,6 @@ uint8_t *ws_rom_load(char *path, uint32_t *romSize)
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
const char *eepromSizeName[] =
{
[WS_EEPROM_SIZE_NONE] = "none",
@@ -107,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));
@@ -125,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);
@@ -167,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,25 +1,12 @@
/*******************************************************************************
* NewOswan
* ws.c: Base wonderswan implementation
*
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
// 07.04.2002: speed problems partially fixed
// 13.04.2002: Set cycles by line to 256 (according to toshi)
// this seems to work well in most situations with
// the new nec v30 cpu core
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -27,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;
@@ -59,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;
@@ -106,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)
{
@@ -129,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
io_init();
ws_audio_init();
ws_gpu_init();
if (ws_rotated())
{
io_flipControls();
}
//ws_audio_init();
//ws_gpu_init();
return (1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_reset(void)
{
ws_memory_reset();
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));
@@ -201,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);
@@ -214,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 */
@@ -270,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();
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)
@@ -317,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;
@@ -388,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];
@@ -481,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

@@ -2,7 +2,7 @@
* NewOswan
* testserial.c: A simple tool to test serial in/out
*
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
*
******************************************************************************/