Merge the latest changes.
This commit is contained in:
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
36
main.c
36
main.c
@@ -1,20 +1,12 @@
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
@@ -31,17 +23,6 @@
|
||||
#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;
|
||||
@@ -191,4 +160,3 @@ int main(int argc, char *argv[])
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
set(SOURCES audio.c emulate.c gpu.c io.c log.c memory.c rom.c ws.c)
|
||||
set(HEADERS includes/audio.h includes/emulate.h includes/gpu.h includes/io.h includes/log.h includes/memory.h includes/rom.h includes/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)
|
||||
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})
|
||||
|
||||
if (FAKE_DISPLAY)
|
||||
target_compile_options(wswan PRIVATE -DPRETENT_DISPLAY)
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
|
||||
83
source/file_access.c
Normal file
83
source/file_access.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* file_access.c: File manipulation functions
|
||||
*
|
||||
* Based on the original Oswan-unix
|
||||
* 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;
|
||||
}
|
||||
168
source/gpu.c
168
source/gpu.c
@@ -1,26 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* 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>
|
||||
@@ -34,36 +20,17 @@
|
||||
#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;
|
||||
@@ -106,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);
|
||||
@@ -138,17 +94,6 @@ void ws_gpu_init(void)
|
||||
memset(wsc_modified_tile, 0x01, 1024);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_done(void)
|
||||
{
|
||||
free(ws_tile_cache);
|
||||
@@ -159,17 +104,6 @@ void ws_gpu_done(void)
|
||||
free(wsc_modified_tile);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_gpu_changeVideoMode(uint8_t value)
|
||||
{
|
||||
if (ws_videoMode != (value >> 5))
|
||||
@@ -190,17 +124,6 @@ void ws_gpu_changeVideoMode(uint8_t value)
|
||||
(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
|
||||
@@ -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__
|
||||
|
||||
|
||||
@@ -1,24 +1,52 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* device.h:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* 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
|
||||
|
||||
#ifndef NEWOSWAN_DEVICE_H
|
||||
#define NEWOSWAN_DEVICE_H
|
||||
|
||||
typedef void (*device_init)(void);
|
||||
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;
|
||||
device_reset *reset;
|
||||
device_free *free;
|
||||
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 /* NEWOSWAN_DEVICE_H */
|
||||
#endif /* __DEVICE_H__ */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
19
source/includes/file_access.h
Normal file
19
source/includes/file_access.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* memory.h:
|
||||
*
|
||||
* Based on the original Oswan-unix
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __FILE_ACCESS_H__
|
||||
#define __FILE_ACCESS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
char *create_file(char *filename, uint32_t size);
|
||||
char *load_file(char *filename, bool readOnly);
|
||||
|
||||
#endif /* __FILE_ACCESS_H__ */
|
||||
@@ -1,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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
32
source/includes/interrupt_controller.h
Normal file
32
source/includes/interrupt_controller.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* interrupt_controller.h:
|
||||
*
|
||||
* Created by mlt on 14/03/2022.
|
||||
* Copyright (c) 2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __INTERRUPT_CONTROLLER_H__
|
||||
#define __INTERRUPT_CONTROLLER_H__
|
||||
|
||||
#include <device.h>
|
||||
|
||||
typedef enum hw_interrupt_type_t
|
||||
{
|
||||
/* They are in the same order as the hardware */
|
||||
HWI_SERIAL_TX = 0,
|
||||
HWI_KEY,
|
||||
HWI_CART,
|
||||
HWI_SERIAL_RX,
|
||||
HWI_LINE_COMPARE,
|
||||
HWI_VBLANK_TIMER,
|
||||
HWI_VBLANK,
|
||||
HWI_HBLANK_TIMER,
|
||||
} hw_interrupt_type_t;
|
||||
|
||||
extern device_t InterruptController;
|
||||
|
||||
void trigger_interrupt(hw_interrupt_type_t type);
|
||||
|
||||
#endif /* __INTERRUPT_CONTROLLER_H__ */
|
||||
@@ -1,42 +1,20 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* io.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 __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);
|
||||
void io_cleanup(void);
|
||||
|
||||
uint8_t io_readport(uint8_t port);
|
||||
void io_writeport(uint8_t port, uint8_t value);
|
||||
@@ -44,7 +22,10 @@ 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 port, io_read *readHook, io_write writeHook, void *pdata);
|
||||
void register_io_hook_array(uint8_t *portList, uint8_t listLen, io_read *readHook, io_write writeHook, void *pdata);
|
||||
void register_io_hook(uint8_t baseAddress, uint8_t port, io_read readHook, void *pdata, io_write writeHook);
|
||||
void register_io_hook_array(uint8_t baseAddress, const uint8_t *portList, uint8_t listLen, io_read readHook, io_write writeHook,
|
||||
void *pdata);
|
||||
|
||||
#define UNUSED_PARAMETER(_s) (void *)(_s)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,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
|
||||
|
||||
@@ -1,53 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* memory.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 __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
|
||||
* 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 ganularity of 8-12
|
||||
* 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
|
||||
*/
|
||||
@@ -58,24 +33,10 @@ void set_irom_overlay();
|
||||
uint8_t *getRom(uint32_t *size);
|
||||
uint8_t *getSram(uint32_t *size);
|
||||
|
||||
void mem_dump_info();
|
||||
|
||||
typedef enum {
|
||||
IRAM_FULL_ACCESS,
|
||||
IRAM_LIMITED_ACCESS,
|
||||
} iram_access_t;
|
||||
|
||||
void set_iram_access(iram_access_t mode);
|
||||
|
||||
#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
|
||||
#endif /* __MEMORY_H__ */
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* NewOswan
|
||||
* nec_debugger.h:
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H
|
||||
#define NEWOSWAN_SOURCE_NEC_NEC_DEBUGGER_H
|
||||
#ifndef __NEC_DEBUGGER_H__
|
||||
#define __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 */
|
||||
#endif /* __NEC_DEBUGGER_H__ */
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
724
source/io.c
724
source/io.c
@@ -1,19 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* io.c: I/O ports implementaton
|
||||
*
|
||||
* 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>
|
||||
@@ -32,13 +25,13 @@
|
||||
#include <io.h>
|
||||
|
||||
//#define IO_DUMP
|
||||
//define EEPROM_DEBUG
|
||||
|
||||
typedef struct ioregistry_t
|
||||
{
|
||||
io_read read; /***< Read function for a specific IO port */
|
||||
io_write write; /***< Write function for a specific IO port */
|
||||
void *private; /***< Private data for the peripheral if needed. */
|
||||
io_read read; /***< Read function for a specific IO port */
|
||||
io_write write; /***< Write function for a specific IO port */
|
||||
void *private; /***< Private data for the peripheral if needed. */
|
||||
uint8_t base_address; /***< Base IO address. Used create a "local" value when calling the read/write function */
|
||||
} ioregistry_t;
|
||||
ioregistry_t io_registry[0x100];
|
||||
|
||||
@@ -47,719 +40,82 @@ extern nec_Regs I;
|
||||
extern uint64_t nec_monotonicCycles;
|
||||
extern uint32_t sramSize;
|
||||
|
||||
uint8_t *ws_ioRam = NULL;
|
||||
|
||||
uint8_t ws_key_start;
|
||||
uint8_t ws_key_x4;
|
||||
uint8_t ws_key_x2;
|
||||
uint8_t ws_key_x1;
|
||||
uint8_t ws_key_x3;
|
||||
uint8_t ws_key_y4;
|
||||
uint8_t ws_key_y2;
|
||||
uint8_t ws_key_y1;
|
||||
uint8_t ws_key_y3;
|
||||
uint8_t ws_key_button_a;
|
||||
uint8_t ws_key_button_b;
|
||||
uint8_t ws_key_flipped;
|
||||
|
||||
FILE *ioLogFp = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void io_reset(void)
|
||||
{
|
||||
ws_key_start = 0;
|
||||
ws_key_x4 = 0;
|
||||
ws_key_x2 = 0;
|
||||
ws_key_x1 = 0;
|
||||
ws_key_x3 = 0;
|
||||
ws_key_y4 = 0;
|
||||
ws_key_y2 = 0;
|
||||
ws_key_y1 = 0;
|
||||
ws_key_y3 = 0;
|
||||
ws_key_button_a = 0;
|
||||
ws_key_button_b = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < 0x100 ; i++)
|
||||
{
|
||||
/*
|
||||
* 0x90 should probably be a better value as for some reason
|
||||
* the Swan seems to like to returh 0x90 for not connected memory/IO
|
||||
* Keep 0x00 for now until the whole IO "default" value is solved.
|
||||
*/
|
||||
ws_ioRam[i] = 0x00;
|
||||
}
|
||||
|
||||
ws_ioRam[0xC0] = 0xFF;
|
||||
ws_ioRam[0xC1] = 0xFF;
|
||||
ws_ioRam[0xC2] = 0xFF;
|
||||
ws_ioRam[0xC3] = 0xFF;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void io_init(void)
|
||||
{
|
||||
if (ws_ioRam == NULL)
|
||||
{
|
||||
ws_ioRam = (uint8_t *)malloc(0x100);
|
||||
}
|
||||
|
||||
io_reset();
|
||||
ws_key_flipped = 0;
|
||||
|
||||
#ifdef IO_DUMP
|
||||
ioLogFp = fopen("iodump.csv", "wt");
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void io_flipControls(void)
|
||||
void io_cleanup(void)
|
||||
{
|
||||
ws_key_flipped = !ws_key_flipped;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void io_done(void)
|
||||
{
|
||||
if (ws_ioRam == NULL)
|
||||
{
|
||||
free(ws_ioRam);
|
||||
}
|
||||
|
||||
#ifdef IO_DUMP
|
||||
fclose(ioLogFp);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t io_readport_new(uint8_t port)
|
||||
void register_io_hook(uint8_t baseAddress, uint8_t port, io_read readHook, void *pdata, io_write writeHook)
|
||||
{
|
||||
if (io_registry[port].read)
|
||||
{
|
||||
return io_registry[port].read(io_registry[port].private, port);
|
||||
}
|
||||
return 0x90;
|
||||
io_registry[baseAddress + port].base_address = baseAddress;
|
||||
io_registry[baseAddress + port].read = readHook;
|
||||
io_registry[baseAddress + port].write = writeHook;
|
||||
io_registry[baseAddress + port].private = pdata;
|
||||
}
|
||||
|
||||
void io_writeport_new(uint8_t port, uint8_t value)
|
||||
{
|
||||
if (io_registry[port].write)
|
||||
{
|
||||
return io_registry[port].write(io_registry[port].private, port, value);
|
||||
}
|
||||
}
|
||||
|
||||
void register_io_hook(uint8_t port, io_read *readHook, io_write writeHook, void *pdata)
|
||||
{
|
||||
io_registry[port].read = readHook;
|
||||
io_registry[port].write = writeHook;
|
||||
io_registry[port].private = pdata;
|
||||
}
|
||||
|
||||
void register_io_hook_array(uint8_t *portList, uint8_t listLen, io_read *readHook, io_write writeHook, void *pdata)
|
||||
void register_io_hook_array(uint8_t baseAddress, const uint8_t *portList, uint8_t listLen, io_read readHook, io_write writeHook,
|
||||
void *pdata)
|
||||
{
|
||||
uint16_t i;
|
||||
for(i = 0; i < listLen; i++)
|
||||
{
|
||||
io_registry[portList[i]].read = readHook;
|
||||
io_registry[portList[i]].write = writeHook;
|
||||
io_registry[portList[i]].private = pdata;
|
||||
io_registry[baseAddress + portList[i]].base_address = baseAddress;
|
||||
io_registry[baseAddress + portList[i]].read = readHook;
|
||||
io_registry[baseAddress + portList[i]].write = writeHook;
|
||||
io_registry[baseAddress + portList[i]].private = pdata;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t io_readport(uint8_t port)
|
||||
{
|
||||
int w1, w2;
|
||||
uint8_t retVal = 0;
|
||||
|
||||
switch (port)
|
||||
if (io_registry[port].read)
|
||||
{
|
||||
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;
|
||||
|
||||
case 0xb5:
|
||||
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);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
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 0xc0 : // ???
|
||||
retVal = ((ws_ioRam[0xc0] & 0xf) | 0x20);
|
||||
goto exit;
|
||||
|
||||
|
||||
case 0xD0:
|
||||
retVal = 0;
|
||||
goto exit;
|
||||
|
||||
case 0xCC:
|
||||
case 0xCD:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
retVal = ws_ioRam[port];
|
||||
if (port > 0xD0)
|
||||
{
|
||||
Log(TLOG_DEBUG, "io", "ReadIO(%02X) <= %02X [%04X:%04Xh];", port, retVal, I.sregs[CS], I.ip);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
case 0xAA:
|
||||
case 0xAB:
|
||||
case 0xAC:
|
||||
case 0xAD:
|
||||
retVal = ws_gpu_port_read(port);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (port == 0xA0)
|
||||
{
|
||||
Log(TLOG_ALWAYS, "A0", "Hello I'm A0 and read %02X!!!", retVal);
|
||||
}
|
||||
|
||||
if (port >= 0xC4)
|
||||
{
|
||||
Log(TLOG_DEBUG, "io", "ReadMBCIO(%02X) <= %02X [%04X:%04Xh];", port, retVal, I.sregs[CS], I.ip);
|
||||
}
|
||||
|
||||
|
||||
exit:
|
||||
|
||||
if (port < 0xC0)
|
||||
{
|
||||
switch(port)
|
||||
{
|
||||
case 0x02:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x90:
|
||||
case 0x91:
|
||||
case 0xB5:
|
||||
break;
|
||||
|
||||
default:
|
||||
Log(TLOG_DEBUG, "io", "ReadIO(%02X) <= %02X [%04X:%04Xh];", port, retVal, I.sregs[CS], I.ip);
|
||||
break;
|
||||
}
|
||||
uint8_t localPort = port - io_registry[port].base_address;
|
||||
retVal = io_registry[port].read(io_registry[port].private, localPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(TLOG_DEBUG, "IO", "CPU tried to read IO %02Xh - May be a bug", port);
|
||||
}
|
||||
|
||||
#ifdef IO_DUMP
|
||||
if (ioLogFp)
|
||||
{
|
||||
fprintf(ioLogFp, "%llu, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
|
||||
fprintf(ioLogFp, "%lu, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
|
||||
}
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void io_writeport(uint32_t port, uint8_t value)
|
||||
void io_writeport(uint8_t port, uint8_t value)
|
||||
{
|
||||
int unknown_io_port = 0;
|
||||
if (io_registry[port].write)
|
||||
{
|
||||
uint8_t localPort = port - io_registry[port].base_address;
|
||||
io_registry[port].write(io_registry[port].private, localPort, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(TLOG_DEBUG, "IO", "CPU tried to write %02Xh to IO %02Xh - MAy be a bug", value, port);
|
||||
}
|
||||
|
||||
#ifdef IO_DUMP
|
||||
if (ioLogFp)
|
||||
{
|
||||
fprintf(ioLogFp, "%llu, W, %02X, %02X\n", nec_monotonicCycles, port, value);
|
||||
}
|
||||
|
||||
if (port > 0x100)
|
||||
{
|
||||
port &= 0xFF;
|
||||
if (port > 0x100)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((port == 0xA0) && (ws_ioRam[port] & 0x01) && (~value & 0x01))
|
||||
{
|
||||
value |= 0x01;
|
||||
}
|
||||
|
||||
ws_ioRam[port] = value;
|
||||
|
||||
switch (port)
|
||||
{
|
||||
/* GPU IOs */
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Audio */
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
ws_audio_port_write(port, value);
|
||||
break;
|
||||
|
||||
/* DMA Start! */
|
||||
case 0x52:
|
||||
break;
|
||||
|
||||
/* GPU (again) */
|
||||
case 0x60:
|
||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
||||
if (ws_get_system() != WS_SYSTEM_MONO)
|
||||
{
|
||||
if (value & 0x80)
|
||||
{
|
||||
set_iram_access(IRAM_FULL_ACCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_iram_access(IRAM_LIMITED_ACCESS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* System */
|
||||
case 0x62:
|
||||
Log(TLOG_DEBUG, "io", "HeyHo!");
|
||||
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;
|
||||
|
||||
/* Hardware */
|
||||
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;
|
||||
|
||||
/* Timers */
|
||||
case 0xA2:
|
||||
case 0xA4:
|
||||
case 0xA5:
|
||||
case 0xA6:
|
||||
case 0xA7:
|
||||
case 0xA8:
|
||||
case 0xA9:
|
||||
case 0xAA:
|
||||
case 0xAB:
|
||||
break;
|
||||
|
||||
|
||||
/* Intc */
|
||||
case 0xB0:
|
||||
case 0xB2:
|
||||
case 0xB4:
|
||||
case 0xB6:
|
||||
break;
|
||||
|
||||
/* buttons */
|
||||
case 0xB5:
|
||||
break;
|
||||
|
||||
/* MBC */
|
||||
#ifndef USE_PAGED_MEMORY_ACCESS
|
||||
case 0xC0:
|
||||
case 0xC1:
|
||||
case 0xC2:
|
||||
case 0xC3:
|
||||
break;
|
||||
#else
|
||||
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
|
||||
|
||||
|
||||
case 0xB7:
|
||||
break; /* Somwthing to write there, but what? */
|
||||
|
||||
default:
|
||||
unknown_io_port = 1;
|
||||
}
|
||||
|
||||
if ((ws_gpu_port_write(port, value) == 1) && (unknown_io_port == 1))
|
||||
{
|
||||
Log(TLOG_DEBUG, "io", "WriteIO(%02X, %02X) [%04X:%04Xh];", port, value, I.sregs[CS], I.ip);
|
||||
}
|
||||
if (port >= 0xC4)
|
||||
{
|
||||
Log(TLOG_DEBUG, "io", "WriteMBCIO(%02X, %02X) [%04X:%04Xh];", port, value, I.sregs[CS], I.ip);
|
||||
}
|
||||
|
||||
|
||||
if (port < 0xC0)
|
||||
{
|
||||
switch(port)
|
||||
{
|
||||
case 0x05: case 0x06:
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
case 0x1C: case 0x1D: case 0x1E: case 0x1F:
|
||||
case 0xB5:
|
||||
case 0xB6:
|
||||
break;
|
||||
|
||||
default:
|
||||
Log(TLOG_DEBUG, "io", "WriteIO(%02X, %02X) [%04X:%04Xh];", port, value, I.sregs[CS], I.ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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_
|
||||
|
||||
600
source/memory.c
600
source/memory.c
@@ -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.h"
|
||||
#include <io.h>
|
||||
#include <gpu.h>
|
||||
#include <audio.h>
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define IO_ROM_BANK_BASE_SELECTOR 0xC0
|
||||
|
||||
uint8_t *ws_rom;
|
||||
uint8_t *ws_staticRam;
|
||||
uint8_t *internalRam;
|
||||
uint8_t *externalEeprom;
|
||||
char *internalBWIRom;
|
||||
char *internalColorIRom;
|
||||
char *internalCrystalIRom;
|
||||
|
||||
char *internalBWEeprom;
|
||||
char *internalColorEeprom;
|
||||
char *internalCrystalEeprom;
|
||||
|
||||
uint16_t *internalEeprom;
|
||||
|
||||
extern uint8_t *ws_ioRam;
|
||||
|
||||
uint16_t ws_rom_checksum;
|
||||
|
||||
uint8_t ws_haveCrystalIRom;
|
||||
uint8_t ws_haveColorIRom;
|
||||
uint8_t ws_haveBWIRom;
|
||||
|
||||
uint32_t sramAddressMask;
|
||||
uint32_t externalEepromAddressMask;
|
||||
uint32_t romAddressMask;
|
||||
uint32_t romSize;
|
||||
uint32_t sramSize;
|
||||
|
||||
extern nec_Regs I;
|
||||
#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,353 +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;
|
||||
}
|
||||
|
||||
void set_iram_access(iram_access_t mode)
|
||||
{
|
||||
/* IRAM */
|
||||
set_memory_bank(0, internalRam);
|
||||
|
||||
if (mode == IRAM_LIMITED_ACCESS)
|
||||
{
|
||||
for (int i = 0x4 ; i < 0x10 ; i++)
|
||||
{
|
||||
set_memory_page(i, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mem_dump_info()
|
||||
{
|
||||
if (ws_get_system() == WS_SYSTEM_MONO)
|
||||
{
|
||||
Log(TLOG_VERBOSE, "MEM", "System is B&W");
|
||||
Log(TLOG_VERBOSE, "MEM", "internal ROM: %09p", internalBWIRom);
|
||||
}
|
||||
else if (ws_get_system() == WS_SYSTEM_COLOR)
|
||||
{
|
||||
Log(TLOG_VERBOSE, "MEM", "System is Color");
|
||||
Log(TLOG_VERBOSE, "MEM", "internal ROM: %09p", internalColorIRom);
|
||||
}
|
||||
else if (ws_get_system() == WS_SYSTEM_CRYSTAL)
|
||||
{
|
||||
Log(TLOG_VERBOSE, "MEM", "System is Crystal");
|
||||
Log(TLOG_VERBOSE, "MEM", "internal ROM: %09p", internalCrystalIRom);
|
||||
}
|
||||
|
||||
Log(TLOG_VERBOSE, "MEM", "internal RAM: %p", internalRam);
|
||||
Log(TLOG_VERBOSE, "MEM", "Cart : %p", ws_rom);
|
||||
for(int i = 0; i < 0x100; i += 4)
|
||||
{
|
||||
Log(TLOG_VERBOSE, "MEM", "Page %02X [%011p] | Page %02X [%011p] | Page %02X [%011p] | Page %02X [%011p]",
|
||||
i, pagedMemory[i], i+1, pagedMemory[i+1], i+2, pagedMemory[i+2], i+3, pagedMemory[i+3]);
|
||||
}
|
||||
}
|
||||
#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 (internalBWIRom != NULL)
|
||||
{
|
||||
Log(TLOG_DEBUG, "memory", "B&W IROM Found!");
|
||||
ws_haveColorIRom = true;
|
||||
}
|
||||
if (internalColorIRom != 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;
|
||||
}
|
||||
|
||||
/* We start in B&W mode */
|
||||
set_iram_access(IRAM_LIMITED_ACCESS);
|
||||
|
||||
/* 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));
|
||||
}
|
||||
mem_dump_info();
|
||||
|
||||
set_irom_overlay();
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_memory_reset(void)
|
||||
{
|
||||
memset(internalRam, 0, 0x10000);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_memory_done(void)
|
||||
{
|
||||
free(internalRam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint8_t *memory_getRom(void)
|
||||
{
|
||||
return (ws_rom);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t memory_getRomSize(void)
|
||||
{
|
||||
return (romSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
uint16_t memory_getRomCrc(void)
|
||||
{
|
||||
return (ws_rom_checksum);
|
||||
}
|
||||
|
||||
@@ -1,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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
/******************************************************************************
|
||||
* 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>
|
||||
@@ -17,7 +18,7 @@
|
||||
#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, ®, 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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -2,21 +2,10 @@
|
||||
* 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(...)
|
||||
@@ -28,12 +17,12 @@
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <log.h>
|
||||
#include <rom.h>
|
||||
#include "log.h"
|
||||
#include "rom.h"
|
||||
#include "nec.h"
|
||||
#include <memory.h>
|
||||
#include <io.h>
|
||||
#include <audio.h>
|
||||
#include "memory.h"
|
||||
#include "io.h"
|
||||
#include "audio.h"
|
||||
|
||||
#define SNDP ws_ioRam[0x80]
|
||||
#define SNDV ws_ioRam[0x88]
|
||||
@@ -72,6 +61,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 +173,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 +185,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 +196,6 @@ void ws_audio_init(void)
|
||||
ws_audio_reset();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_reset(void)
|
||||
{
|
||||
WaveMap = -1;
|
||||
@@ -183,17 +218,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 +434,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 +525,6 @@ unsigned int ws_audio_mrand(unsigned int Degree)
|
||||
return ShiftReg;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_seal_init(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -692,17 +671,6 @@ int ws_audio_seal_init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_seal_done(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -747,17 +715,6 @@ void ws_audio_seal_done(void)
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_clear_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -783,17 +740,6 @@ void ws_audio_clear_channel(int Channel)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// start playing a channel
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_play_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -822,17 +768,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 +794,6 @@ int ws_audio_stop_channel(int Channel)
|
||||
return (0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_set_channel_frequency(int Channel, int Period)
|
||||
{
|
||||
#if 0
|
||||
@@ -915,17 +839,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 +868,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 +933,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 +960,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 +980,6 @@ void ws_audio_set_channels_pbuf(int Addr, int Data)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_rst_channel(int Channel)
|
||||
{
|
||||
#if 0
|
||||
@@ -1122,17 +991,6 @@ void ws_audio_rst_channel(int Channel)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int ws_audio_int(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -1176,17 +1034,7 @@ int ws_audio_int(void)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
static uint32_t PCMPos=0;
|
||||
uint32_t TickZ=0,PcmCount;
|
||||
@@ -1221,17 +1069,6 @@ void ws_audio_set_pcm(int Data)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_flash_pcm(void)
|
||||
{
|
||||
#if 0
|
||||
@@ -1263,37 +1100,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 +1172,6 @@ void ws_audio_process(void)
|
||||
ws_audio_set_pcm(b);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_readState(int fp)
|
||||
{
|
||||
#if 0
|
||||
@@ -1458,17 +1262,6 @@ void ws_audio_readState(int fp)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ws_audio_writeState(int fp)
|
||||
{
|
||||
#if 0
|
||||
@@ -1537,3 +1330,5 @@ void ws_audio_writeState(int fp)
|
||||
write(fp,&lpnStatus,sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,42 @@
|
||||
* buttons.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
case 0xb5:
|
||||
|
||||
read
|
||||
w1 = ws_ioRam[0xb5];
|
||||
|
||||
if (w1 & 0x40)
|
||||
{
|
||||
w2 = 0x00;
|
||||
w2 = (ws_key_start << 1) | (ws_key_button_a << 2) | (ws_key_button_b << 3);
|
||||
retVal = (uint8_t)((w1 & 0xf0) | w2);
|
||||
break;
|
||||
}
|
||||
|
||||
if (w1 & 0x20)
|
||||
{
|
||||
w2 = 0x00;
|
||||
w2 = (ws_key_x1 << 0) | (ws_key_x2 << 1) | (ws_key_x3 << 2) | (ws_key_x4 << 3);
|
||||
retVal = (uint8_t)((w1 & 0xf0) | w2);
|
||||
break;
|
||||
}
|
||||
|
||||
if (w1 & 0x10)
|
||||
{
|
||||
w2 = 0x00;
|
||||
w2 = (ws_key_y1 << 0) | (ws_key_y2 << 1) | (ws_key_y3 << 2) | (ws_key_y4 << 3);
|
||||
retVal = (uint8_t)((w1 & 0xf0) | w2);
|
||||
}
|
||||
|
||||
write:
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
8
source/peripherals/color_gpu.c
Normal file
8
source/peripherals/color_gpu.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* color_gpu.c: Implementation of the color GPU (Wonderswan Color & SwanCrystal)
|
||||
*
|
||||
* Created by Manoël Trapier on 14/03/2022.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -1,9 +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-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#if 0
|
||||
Shall we split color and crystal, there are some subtles differences on some registers
|
||||
|
||||
READ
|
||||
|
||||
case 0x62:
|
||||
switch (ws_get_system())
|
||||
{
|
||||
case WS_SYSTEM_AUTODETECT:
|
||||
case WS_SYSTEM_MONO:
|
||||
case WS_SYSTEM_COLOR:
|
||||
retVal = 0x00;
|
||||
break;
|
||||
|
||||
case WS_SYSTEM_CRYSTAL:
|
||||
retVal = 0x80;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
WRITE
|
||||
|
||||
if ((port == 0xA0) && (ws_ioRam[port] & 0x01) && (~value & 0x01))
|
||||
{
|
||||
value |= 0x01;
|
||||
}
|
||||
|
||||
case 0xA0:
|
||||
|
||||
/* Force cart handshake to be set */
|
||||
ws_ioRam[port] |= 0x80;
|
||||
|
||||
if (value & 0x01)
|
||||
{
|
||||
Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value);
|
||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
||||
uint32_t romSize;
|
||||
uint8_t *rom = getRom(&romSize);
|
||||
set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* debug.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,9 +1,106 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* dma.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
Need to check how to differenciate all the DMA types.
|
||||
|
||||
|
||||
WRITE:
|
||||
|
||||
case 0x48: // DMA
|
||||
|
||||
// bit 7 set to start dma transfer
|
||||
if (value & 0x80)
|
||||
{
|
||||
uint32_t dma_start = (ws_ioRam[0x41] << 8) | (ws_ioRam[0x40]) | (ws_ioRam[0x42] << 16);
|
||||
uint32_t dma_dest = (ws_ioRam[0x45] << 8) | (ws_ioRam[0x44]) | (ws_ioRam[0x43] << 16);
|
||||
uint32_t dma_size = (ws_ioRam[0x47] << 8) | (ws_ioRam[0x46]);
|
||||
|
||||
uint8_t dma_inc = (value & 0x01) ? -1: 1;
|
||||
|
||||
Log(TLOG_VERBOSE, "DMA", "Starting DMA from %08X to %08X (len: %08X, inc: %d)",
|
||||
dma_start, dma_dest, dma_size, dma_inc);
|
||||
|
||||
|
||||
|
||||
for (uint32_t ix = 0 ; ix < dma_size ; ix++)
|
||||
{
|
||||
mem_writemem20(dma_dest, mem_readmem20(dma_start));
|
||||
dma_start += dma_inc;
|
||||
dma_dest += dma_inc;
|
||||
}
|
||||
|
||||
ws_ioRam[0x47] = 0;
|
||||
ws_ioRam[0x46] = 0;
|
||||
ws_ioRam[0x41] = (uint8_t)(dma_start >> 8);
|
||||
ws_ioRam[0x40] = (uint8_t)(dma_start & 0xff);
|
||||
ws_ioRam[0x45] = (uint8_t)(dma_dest >> 8);
|
||||
ws_ioRam[0x44] = (uint8_t)(dma_dest & 0xff);
|
||||
ws_ioRam[0x48] = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* DMAs */
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
case 0x47:
|
||||
break;
|
||||
|
||||
case 0x48: // DMA
|
||||
|
||||
// bit 7 set to start dma transfer
|
||||
if (value & 0x80)
|
||||
{
|
||||
uint32_t dma_start = (ws_ioRam[0x41] << 8) | (ws_ioRam[0x40]) | (ws_ioRam[0x42] << 16);
|
||||
uint32_t dma_dest = (ws_ioRam[0x45] << 8) | (ws_ioRam[0x44]) | (ws_ioRam[0x43] << 16);
|
||||
uint32_t dma_size = (ws_ioRam[0x47] << 8) | (ws_ioRam[0x46]);
|
||||
|
||||
uint8_t dma_inc = (value & 0x01) ? -1: 1;
|
||||
|
||||
Log(TLOG_VERBOSE, "DMA", "Starting DMA from %08X to %08X (len: %08X, inc: %d)",
|
||||
dma_start, dma_dest, dma_size, dma_inc);
|
||||
|
||||
|
||||
|
||||
for (uint32_t ix = 0 ; ix < dma_size ; ix++)
|
||||
{
|
||||
mem_writemem20(dma_dest, mem_readmem20(dma_start));
|
||||
dma_start += dma_inc;
|
||||
dma_dest += dma_inc;
|
||||
}
|
||||
|
||||
ws_ioRam[0x47] = 0;
|
||||
ws_ioRam[0x46] = 0;
|
||||
ws_ioRam[0x41] = (uint8_t)(dma_start >> 8);
|
||||
ws_ioRam[0x40] = (uint8_t)(dma_start & 0xff);
|
||||
ws_ioRam[0x45] = (uint8_t)(dma_dest >> 8);
|
||||
ws_ioRam[0x44] = (uint8_t)(dma_dest & 0xff);
|
||||
ws_ioRam[0x48] = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* DMA Start! */
|
||||
case 0x52:
|
||||
break;
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* eeprom.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -187,11 +187,11 @@ void rs232_io_write(void *pdata, uint8_t port, uint8_t value)
|
||||
#endif
|
||||
if (ws_gpu_operatingInColor)
|
||||
{
|
||||
memset(internalEeprom, 0, COLOR_IEEPROM_SIZE);
|
||||
//memset(internalEeprom, 0, COLOR_IEEPROM_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(internalEeprom, 0, BW_IEEPROM_SIZE);
|
||||
//memset(internalEeprom, 0, BW_IEEPROM_SIZE);
|
||||
}
|
||||
}
|
||||
#ifdef EEPROM_DEBUG
|
||||
|
||||
98
source/peripherals/interrupt_controller.c
Normal file
98
source/peripherals/interrupt_controller.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* interrupt_controller.c:
|
||||
*
|
||||
* Created by mlt on 14/03/2022.
|
||||
* Copyright (c) 2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <device.h>
|
||||
#include <io.h>
|
||||
#include <interrupt_controller.h>
|
||||
|
||||
/* device internal parameters */
|
||||
typedef struct ic_params_t
|
||||
{
|
||||
uint8_t address_base;
|
||||
uint8_t int_enable_mask;
|
||||
uint8_t int_status;
|
||||
} ic_params_t;
|
||||
|
||||
static ic_params_t interrupt_controller;
|
||||
|
||||
static uint8_t IC_IO_read(void *pdata, uint8_t port)
|
||||
{
|
||||
ic_params_t *params = (ic_params_t *)pdata;
|
||||
|
||||
switch(port)
|
||||
{
|
||||
case 0x0: return params->address_base;
|
||||
case 0x2: return params->int_enable_mask;
|
||||
case 0x4: return params->int_status;
|
||||
}
|
||||
|
||||
return 0x90;
|
||||
}
|
||||
|
||||
static void IC_IO_write(void *pdata, uint8_t port, uint8_t value)
|
||||
{
|
||||
ic_params_t *params = (ic_params_t *)pdata;
|
||||
|
||||
switch(port)
|
||||
{
|
||||
case 0x0: params->address_base = value; break;
|
||||
case 0x2: params->int_enable_mask = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
static void IC_IO_write_ack(void *pdata, uint8_t port, uint8_t value)
|
||||
{
|
||||
ic_params_t *params = (ic_params_t *)pdata;
|
||||
|
||||
// De-assert CPU interrupt accordingly to the mask in value
|
||||
}
|
||||
|
||||
|
||||
static void IC_init(uint8_t baseAddress, void *params)
|
||||
{
|
||||
UNUSED_PARAMETER(params);
|
||||
|
||||
register_io_hook(baseAddress, 0x0, IC_IO_read, IC_IO_write, &interrupt_controller);
|
||||
register_io_hook(baseAddress, 0x2, IC_IO_read, IC_IO_write, &interrupt_controller);
|
||||
register_io_hook(baseAddress, 0x4, IC_IO_read, NULL, &interrupt_controller);
|
||||
register_io_hook(baseAddress, 0x6, NULL, IC_IO_write_ack, &interrupt_controller);
|
||||
}
|
||||
|
||||
static void IC_reset()
|
||||
{
|
||||
interrupt_controller.int_enable_mask = 0;
|
||||
interrupt_controller.address_base = 0;
|
||||
}
|
||||
|
||||
device_t InterruptController =
|
||||
{
|
||||
.init = IC_init,
|
||||
.reset = IC_reset,
|
||||
.free = NULL,
|
||||
.deviceType = DT_INTERRUPT_CONTROLLER,
|
||||
};
|
||||
|
||||
/* Exported functions */
|
||||
void trigger_interrupt(hw_interrupt_type_t type)
|
||||
{
|
||||
uint16_t int_vector = interrupt_controller.address_base & 0xF8 + (uint8_t)type;
|
||||
|
||||
/* Check that the INT is enabled */
|
||||
if ((interrupt_controller.int_enable_mask >> type) & 0x1)
|
||||
{
|
||||
/* TODO: Do we have to enable that even if the int is not enabled? */
|
||||
interrupt_controller.int_status |= (1 << type);
|
||||
|
||||
// Fire the NEC interrupt
|
||||
|
||||
}
|
||||
}
|
||||
128
source/peripherals/mono_gpu.c
Normal file
128
source/peripherals/mono_gpu.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* mono_gpu.c: Implementation of the monochrome GPU
|
||||
*
|
||||
* Created by Manoël Trapier on 14/03/2022.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#if 0
|
||||
|
||||
READ
|
||||
|
||||
case 0xA0:
|
||||
case 0xAA:
|
||||
case 0xAB:
|
||||
case 0xAC:
|
||||
case 0xAD:
|
||||
retVal = ws_gpu_port_read(port);
|
||||
|
||||
WRITE
|
||||
|
||||
case 0x00:
|
||||
Log(TLOG_DEBUG, "GPU", "Screen enabled: W2:%c W2M:%c, SW:%c, S:%c, S2:%c, S1:%c",
|
||||
(value & 0x20)?'Y':'N',
|
||||
(value & 0x10)?'I':'O',
|
||||
(value & 0x08)?'Y':'N',
|
||||
(value & 0x04)?'Y':'N',
|
||||
(value & 0x02)?'Y':'N',
|
||||
(value & 0x01)?'Y':'N');
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
if (ws_gpu_operatingInColor)
|
||||
{
|
||||
Log(TLOG_DEBUG, "GPU", "Sprite base: %04X", (value & 0x1F) << 9);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(TLOG_DEBUG, "GPU", "Sprite base: %04X", (value & 0x3F) << 9);
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
if (ws_gpu_operatingInColor)
|
||||
{
|
||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen1 base: %04X", (value & 0x7) << 11);
|
||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen2 base: %04X", (value & 0x70) << (11-4));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen1 base: %04X", (value & 0xF) << 11);
|
||||
Log(TLOG_DEBUG, "GPU", "Sprite Screen2 base: %04X", (value & 0xF0) << (11-4));
|
||||
}
|
||||
break;
|
||||
case 0x10:
|
||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen1 X scroll: %d", value);
|
||||
break;
|
||||
case 0x11:
|
||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen1 T scroll: %d", value);
|
||||
break;
|
||||
case 0x12:
|
||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen2 X scroll: %d", value);
|
||||
break;
|
||||
case 0x13:
|
||||
//Log(TLOG_DEBUG, "GPU", "Sprite Screen2 Y scroll: %d", value);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x0D:
|
||||
case 0x0E:
|
||||
case 0x0F:
|
||||
case 0x14:
|
||||
break;
|
||||
|
||||
case 0x15:
|
||||
Log(TLOG_DEBUG, "io", "Icons %c %c %c %c %c %c %c %c", (value >> 7) & 1 ? '?' : ' ', (value >> 6) & 1 ? '?' : ' ',
|
||||
(value >> 5) & 1 ? '3' : ' ', (value >> 4) & 1 ? '2' : ' ', (value >> 3) & 1 ? '1' : ' ',
|
||||
(value >> 2) & 1 ? 'H' : ' ', (value >> 1) & 1 ? 'V' : ' ', (value >> 0) & 1 ? 'S' : ' ');
|
||||
break;
|
||||
|
||||
|
||||
/* Palettes ? */
|
||||
case 0x1C:
|
||||
case 0x25:
|
||||
case 0x2F:
|
||||
case 0x38:
|
||||
case 0x1D:
|
||||
case 0x26:
|
||||
case 0x30:
|
||||
case 0x39:
|
||||
case 0x1E:
|
||||
case 0x27:
|
||||
case 0x31:
|
||||
case 0x3A:
|
||||
case 0x1F:
|
||||
case 0x28:
|
||||
case 0x32:
|
||||
case 0x3B:
|
||||
case 0x20:
|
||||
case 0x29:
|
||||
case 0x33:
|
||||
case 0x3C:
|
||||
case 0x21:
|
||||
case 0x2A:
|
||||
case 0x34:
|
||||
case 0x3E:
|
||||
case 0x22:
|
||||
case 0x2B:
|
||||
case 0x35:
|
||||
case 0x3F:
|
||||
case 0x23:
|
||||
case 0x2C:
|
||||
case 0x36:
|
||||
case 0x24:
|
||||
case 0x2E:
|
||||
case 0x37:
|
||||
break;
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,91 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* mono_system.c: IOs specific to the original WonderSwan
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#if 0
|
||||
READ
|
||||
|
||||
|
||||
case 0x62:
|
||||
switch (ws_get_system())
|
||||
{
|
||||
case WS_SYSTEM_AUTODETECT:
|
||||
case WS_SYSTEM_MONO:
|
||||
case WS_SYSTEM_COLOR:
|
||||
retVal = 0x00;
|
||||
break;
|
||||
|
||||
case WS_SYSTEM_CRYSTAL:
|
||||
retVal = 0x80;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
WRITE
|
||||
|
||||
if ((port == 0xA0) && (ws_ioRam[port] & 0x01) && (~value & 0x01))
|
||||
{
|
||||
value |= 0x01;
|
||||
}
|
||||
|
||||
case 0xA0:
|
||||
|
||||
/* Force cart handshake to be set */
|
||||
ws_ioRam[port] |= 0x80;
|
||||
|
||||
if (value & 0x01)
|
||||
{
|
||||
Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value);
|
||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
||||
uint32_t romSize;
|
||||
uint8_t *rom = getRom(&romSize);
|
||||
set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
case 0x62:
|
||||
switch (ws_get_system())
|
||||
{
|
||||
case WS_SYSTEM_AUTODETECT:
|
||||
case WS_SYSTEM_MONO:
|
||||
case WS_SYSTEM_COLOR:
|
||||
retVal = 0x00;
|
||||
break;
|
||||
|
||||
case WS_SYSTEM_CRYSTAL:
|
||||
retVal = 0x80;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 0xA0:
|
||||
|
||||
/* Force cart handshake to be set */
|
||||
ws_ioRam[port] |= 0x80;
|
||||
|
||||
if (value & 0x01)
|
||||
{
|
||||
Log(TLOG_WARNING, "A0", "Oh yeah %02X BABY", value);
|
||||
#ifdef USE_PAGED_MEMORY_ACCESS
|
||||
uint32_t romSize;
|
||||
uint8_t *rom = getRom(&romSize);
|
||||
set_memory_bank(0xF, ws_get_page_ptr(rom, romSize, (ws_ioRam[0xC0] & 0x0F << 4) + 0x0F));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* rs232.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
/*
|
||||
/*******************************************************************************
|
||||
* NewOswan
|
||||
* rtc.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 19/12/2021.
|
||||
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
|
||||
* 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)
|
||||
{
|
||||
case (port)
|
||||
uint8_t retVal = 0;
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0xca : // RTC Command and status register
|
||||
// set ack to always 1
|
||||
@@ -78,6 +84,9 @@ uint8_t rtc_io_read(void *pdata, uint8_t port)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void rtc_io_write(void *pdata, uint8_t port, uint8_t value)
|
||||
|
||||
8
source/peripherals/timer.c
Normal file
8
source/peripherals/timer.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* NewOswan
|
||||
* timer.c:
|
||||
*
|
||||
* Created by Manoël Trapier on 26/06/2022.
|
||||
* Copyright (c) 2014-2022 986-Studio. All rights reserved.
|
||||
*
|
||||
*/
|
||||
@@ -1,9 +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-2021 986-Studio. All rights reserved.
|
||||
* 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
|
||||
68
source/rom.c
68
source/rom.c
@@ -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>
|
||||
@@ -27,17 +19,6 @@
|
||||
#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);
|
||||
|
||||
199
source/ws.c
199
source/ws.c
@@ -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>
|
||||
@@ -37,18 +24,6 @@
|
||||
#include <audio.h>
|
||||
#include <ws.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint32_t ws_cycles;
|
||||
uint32_t ws_skip;
|
||||
uint32_t ws_cyclesByLine = 0;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user