Starting a rewrite of how the IO works.

Currently 100% broken, also going to change how devices are selected
for each system so no more if/else everywhere and system should be more accurate.
This commit is contained in:
Godzil
2021-12-20 15:43:04 +00:00
parent 8fa2ef06ab
commit 6f56a8efda
33 changed files with 1017 additions and 699 deletions

51
source/includes/audio.h Normal file
View File

@@ -0,0 +1,51 @@
/*******************************************************************************
* NewOswan
* audio.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __AUDIO_H__
#define __AUDIO_H__
#include <stdint.h>
void ws_audio_init();
void ws_audio_reset();
void ws_audio_port_write(uint32_t port, uint8_t value);
uint8_t ws_audio_port_read(uint8_t port);
void ws_audio_done();
unsigned int ws_audio_mrand(unsigned int Degree);
int ws_audio_seal_init();
void ws_audio_seal_done();
int ws_audio_play_channel(int Channel);
int ws_audio_stop_channel(int Channel);
void ws_audio_clear_channel(int Channel);
void ws_audio_set_channel_frequency(int Channel,int Period);
void ws_audio_set_channel_volume(int Channel,int Vol);
void ws_audio_set_channel_pan(int Channel,int Left,int Right);
void ws_audio_set_channel_pdata(int Channel,int Index);
void ws_audio_set_channels_pbuf(int Addr,int Data);
void ws_audio_rst_channel(int Channel);
int ws_audio_int();
void ws_audio_set_pcm(int Data);
void ws_audio_flash_pcm();
void ws_audio_write_byte(uint32_t offset, uint8_t value);
void ws_audio_process();
void ws_audio_readState(int fp);
void ws_audio_writeState(int fp);
uint32_t timer_callupdate(uint32_t, void*);
#endif

24
source/includes/device.h Normal file
View File

@@ -0,0 +1,24 @@
/*
* NewOswan
* device.h:
*
* Created by Manoël Trapier on 19/12/2021.
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
#ifndef NEWOSWAN_DEVICE_H
#define NEWOSWAN_DEVICE_H
typedef void (*device_init)(void);
typedef void (*device_reset)(void);
typedef void (*device_free)(void);
typedef struct device_t
{
device_init *init;
device_reset *reset;
device_free *free;
} device_t;
#endif /* NEWOSWAN_DEVICE_H */

27
source/includes/emulate.h Normal file
View File

@@ -0,0 +1,27 @@
/*******************************************************************************
* NewOswan
* emulate.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef EMULATE_H
#define EMULATE_H
#include <stdint.h>
extern char app_window_title[256];
extern int app_terminate;
void ws_emulate(void);
#endif /* EMULATE_H */

42
source/includes/gpu.h Normal file
View File

@@ -0,0 +1,42 @@
/*******************************************************************************
* NewOswan
* gpu.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
#ifndef __GPU_H__
#define __GPU_H__
#include <stdint.h>
struct ws_gpu_t
{
uint8_t scanline;
uint32_t cyclecount;
};
extern uint8_t ws_gpu_scanline;
extern uint8_t ws_gpu_operatingInColor;
extern uint8_t ws_videoMode;
extern int16_t ws_palette[16 * 4];
extern int8_t ws_paletteColors[8];
extern int16_t wsc_palette[16 * 16];
extern unsigned int ws_gpu_unknownPort;
extern uint32_t vblank_count;
void ws_gpu_init(void);
void ws_gpu_done(void);
void ws_gpu_reset(void);
void ws_gpu_renderScanline(int16_t *framebuffer);
void ws_gpu_changeVideoMode(uint8_t value);
void ws_gpu_write_byte(uint32_t offset, uint8_t value);
int ws_gpu_port_write(uint32_t port, uint8_t value);
uint8_t ws_gpu_port_read(uint8_t port);
void ws_gpu_changeVideoMode(uint8_t value);
void ws_gpu_clearCache(void);
#endif

50
source/includes/io.h Normal file
View File

@@ -0,0 +1,50 @@
/*******************************************************************************
* NewOswan
* io.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __IO_H__
#define __IO_H__
#include <stdint.h>
extern uint8_t *ws_ioRam;
extern uint8_t ws_key_start;
extern uint8_t ws_key_x4;
extern uint8_t ws_key_x2;
extern uint8_t ws_key_x1;
extern uint8_t ws_key_x3;
extern uint8_t ws_key_y4;
extern uint8_t ws_key_y2;
extern uint8_t ws_key_y1;
extern uint8_t ws_key_y3;
extern uint8_t ws_key_button_a;
extern uint8_t ws_key_button_b;
void io_init(void);
void io_reset(void);
void io_flipControls(void);
void io_done(void);
uint8_t io_readport(uint8_t port);
void io_writeport(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);
#endif

124
source/includes/log.h Normal file
View File

@@ -0,0 +1,124 @@
/*******************************************************************************
* NewOswan
* log.h: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* Created by Manoël Trapier on 20/01/2009.
******************************************************************************/
#ifndef _LOG_H
#define _LOG_H
#ifdef __cplusplus
extern "C" {
#endif
//#define ALLOW_COLORS
#ifdef ALLOW_COLORS
#define __C(c) "\x1B[" c "m"
#else
#define __C(c) ""
#endif
#define ANSI_COLOR __C
#define FBLACK ANSI_COLOR("30")
#define FRED ANSI_COLOR("31")
#define FGREEN ANSI_COLOR("32")
#define FYELLOW ANSI_COLOR("33")
#define FBLUE ANSI_COLOR("34")
#define FMAGENTA ANSI_COLOR("35")
#define FCYAN ANSI_COLOR("36")
#define FWHITE ANSI_COLOR("37")
#define BBLACK ANSI_COLOR("40")
#define BRED ANSI_COLOR("41")
#define BGREEN ANSI_COLOR("42")
#define BYELLOW ANSI_COLOR("43")
#define BBLUE ANSI_COLOR("44")
#define BMAGENTA ANSI_COLOR("45")
#define BCYAN ANSI_COLOR("46")
#define BWHITE ANSI_COLOR("47")
#define CNORMAL ANSI_COLOR("0")
enum
{
TLOG_ALWAYS = -1,
TLOG_PANIC = 0,
TLOG_ERROR,
TLOG_WARNING,
TLOG_NORMAL,
TLOG_VERBOSE,
TLOG_DEBUG,
};
//#define LOG_ALWAYS_FFLUSH
#define DYNA_LOG_LEVEL
#define SET_DEBUG_LOG
/* Set if DYNALOG is set the maximum compiled log level */
#ifndef MAXIMUM_DEBUG_LEVEL
#ifndef SET_DEBUG_LOG
#define MAXIMUM_DEBUG_LEVEL TLOG_NORMAL
#else
#define MAXIMUM_DEBUG_LEVEL TLOG_DEBUG
#endif
#endif /* MAXIMUM_DEBUG_LEVEL */
/* Set the default log level */
#ifndef SET_DEBUG_LOG
#define DEFAULT_DEBUG_LEVEL TLOG_PANIC
#else
#define DEFAULT_DEBUG_LEVEL TLOG_DEBUG
#endif
/******************************************************************************/
/* DO NOT MESS AFTER THIS LINE */
/******************************************************************************/
#ifdef DYNA_LOG_LEVEL
# ifdef MAX_DEBUG_LEVEL
# undef MAX_DEBUG_LEVEL
# endif
# ifdef __LOG_C_INTERNAL_
int MAX_DEBUG_LEVEL = DEFAULT_DEBUG_LEVEL;
#else
extern int MAX_DEBUG_LEVEL;
#endif
#else
# ifndef MAX_DEBUG_LEVEL
# define MAX_DEBUG_LEVEL DEFAULT_DEBUG_LEVEL
# endif
#endif
#define Log(_level, _user, _fmt, ...)\
if (_level <= MAXIMUM_DEBUG_LEVEL)\
if ((_level <= MAX_DEBUG_LEVEL) || (_level <= TLOG_PANIC))\
do { log_real(_level, _user, _fmt, ##__VA_ARGS__); } while(0)
void log_real(int level, const char *user, const char *fmt, ...);
#define LOG(_level, _str, ...) if ((_level <= MAX_DEBUG_LEVEL) || (_level <= TLOG_PANIC)) do { fputs(_str, stderr); } while(0)
#define LOGCODE(_level, _user, _code)\
if (_level <= MAXIMUM_DEBUG_LEVEL) do{\
Log(_level, _user, "");\
if ((_level <= MAX_DEBUG_LEVEL) || (_level <= TLOG_PANIC))\
do { _code; fprintf(stderr, "\n"); } while(0); } while(0)
#define INFOL(_level, _fmt) LOGCODE(_level, "INFOL", { printf _fmt; })
#define FUNC_IN() Log(TLOG_VERBOSE, NULL, ">>%s", __func__)
#define FUNC_OUT() Log(TLOG_VERBOSE, NULL, "<<%s", __func__)
#define FUNC_OUTR(out) Log(TLOG_VERBOSE, NULL, "<<%s (%d)", __func__, out)
void log_displayPanic(int signal);
#ifdef __cplusplus
}
#endif
#endif /* _LOG_H */

81
source/includes/memory.h Normal file
View File

@@ -0,0 +1,81 @@
/*******************************************************************************
* NewOswan
* memory.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __MEMORY_H__
#define __MEMORY_H__
#include <stdint.h>
extern uint8_t *ws_staticRam;
extern uint8_t *internalRam;
extern uint8_t *externalEeprom;
void ws_memory_init(uint8_t *rom, uint32_t romSize);
void ws_memory_reset(void);
uint8_t *memory_getRom(void);
uint32_t memory_getRomSize(void);
uint16_t memory_getRomCrc(void);
void ws_memory_done(void);
void memory_load(int fp);
void memory_save(int fp);
char *create_file(char *filename, uint32_t size);
char *load_file(char *filename);
void dump_memory();
//#define USE_PAGED_MEMORY_ACCESS
#ifdef USE_PAGED_MEMORY_ACCESS
/***
* Set a memory page with a ganularity of 4-16
* @param bank: the bank (0-F) to set
* @param pointer: a pointer to the memory to set
*/
void set_memory_bank(uint8_t bank, uint8_t *pointer);
/***
* Set a memory page with a ganularity of 8-12
* @param bank: the bank (0-FF) to set
* @param pointer: a pointer to the memory to set
*/
void set_memory_page(uint8_t page, uint8_t *pointer);
void set_irom_overlay();
uint8_t *getRom(uint32_t *size);
uint8_t *getSram(uint32_t *size);
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

404
source/includes/nec.h Normal file
View File

@@ -0,0 +1,404 @@
/******************************************************************************
* NewOswan
* nec.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
#ifndef __NEC_H_
#define __NEC_H_
#include <stdint.h>
#include <stdbool.h>
#include "necintrf.h"
typedef enum
{
ES, CS, SS, DS
} SREGS;
typedef enum
{
AW, CW, DW, BW, SP, BP, IX, IY
} WREGS;
typedef enum
{
AL, AH, CL, CH, DL, DH, BL, BH, SPL, SPH, BPL, BPH, IXL, IXH, IYL, IYH
} BREGS;
#pragma pack(1)
typedef union
{
/* eight general registers */
uint16_t w[8]; /* viewed as 16 bits registers */
uint8_t b[16]; /* or as 8 bit registers */
} necbasicregs;
typedef struct
{
necbasicregs regs;
uint16_t sregs[4];
uint16_t ip;
int32_t SignVal;
int32_t AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
uint32_t TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
uint32_t int_vector;
uint32_t pending_irq;
uint32_t nmi_state;
uint32_t irq_state;
int (*irq_callback)(int irqline);
} nec_Regs;
#pragma pack()
#define NEC_NMI_INT_VECTOR 2
/* Cpu types, steps of 8 to help the cycle count calculation */
#define V33 0
#define V30 8
#define V20 16
/* parameter x = result, y = source 1, z = source 2 */
#define SetTF(x) (I.TF = (x))
#define SetIF(x) (I.IF = (x))
#define SetDF(x) (I.DF = (x))
#define SetMD(x) (I.MF = (x)) /* OB [19.07.99] Mode Flag V30 */
#define SetCFB(x) (I.CarryVal = (x) & 0x100)
#define SetCFW(x) (I.CarryVal = (x) & 0x10000)
#define SetAF(x, y, z) (I.AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
#define SetSF(x) (I.SignVal = (x))
#define SetZF(x) (I.ZeroVal = (x))
#define SetPF(x) (I.ParityVal = (x))
#define SetSZPF_Byte(x) (I.SignVal=I.ZeroVal=I.ParityVal=(int8_t)(x))
#define SetSZPF_Word(x) (I.SignVal=I.ZeroVal=I.ParityVal=(int16_t)(x))
#define SetOFW_Add(x, y, z) (I.OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
#define SetOFB_Add(x, y, z) (I.OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
#define SetOFW_Sub(x, y, z) (I.OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
#define SetOFB_Sub(x, y, z) (I.OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
#define ADDB { uint32_t res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(uint8_t)res; }
#define ADDW { uint32_t res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(uint16_t)res; }
#define SUBB { uint32_t res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(uint8_t)res; }
#define SUBW { uint32_t res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(uint16_t)res; }
#define ORB dst|=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
#define ORW dst|=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
#define ANDB dst&=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
#define ANDW dst&=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
#define XORB dst^=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Byte(dst)
#define XORW dst^=src; I.CarryVal=I.OverVal=I.AuxVal=0; SetSZPF_Word(dst)
#define CF (I.CarryVal!=0)
#define SF (I.SignVal<0)
#define ZF (I.ZeroVal==0)
#define PF parity_table[(uint8_t)I.ParityVal]
#define AF (I.AuxVal!=0)
#define OF (I.OverVal!=0)
#define MD (I.MF!=0)
/************************************************************************/
#define SegBase(Seg) (I.sregs[Seg] << 4)
#define DefaultBase(Seg) ((seg_prefix && (Seg==DS || Seg==SS)) ? (prefix_base) : (uint32_t)(I.sregs[Seg] << 4))
#define GetMemB(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint8_t)mem_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint16_t) mem_readmem20((DefaultBase(Seg)+(Off))) + (mem_readmem20((DefaultBase(Seg)+((Off)+1)))<<8) )
#define PutMemB(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; mem_writemem20((DefaultBase(Seg)+(Off)),(x)); }
#define PutMemW(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; PutMemB(Seg,Off,(x)&0xff); PutMemB(Seg,(Off)+1,(uint8_t)((x)>>8)); }
/* Todo: Remove these later - plus readword could overflow */
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (uint8_t)mem_readmem20((ea)))
#define ReadWord(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ mem_readmem20((ea))+(mem_readmem20(((ea)+1))<<8))
#define WriteByte(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; mem_writemem20((ea),val); }
#define WriteWord(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; mem_writemem20((ea),(uint8_t)(val)); mem_writemem20(((ea)+1),(val)>>8); }
#define read_port(port) io_readport(port)
#define write_port(port, val) io_writeport(port,val)
#define FETCH (mem_readop_arg((I.sregs[CS]<<4)+I.ip++))
#define FETCHOP (mem_readop((I.sregs[CS]<<4)+I.ip++))
#define FETCHWORD(var) { var=mem_readop_arg((((I.sregs[CS]<<4)+I.ip)))+(mem_readop_arg((((I.sregs[CS]<<4)+I.ip+1)))<<8); I.ip+=2; }
#define PUSH(val) { I.regs.w[SP]-=2; WriteWord((((I.sregs[SS]<<4)+I.regs.w[SP])),val); }
#define POP(var) { var = ReadWord((((I.sregs[SS]<<4)+I.regs.w[SP]))); I.regs.w[SP]+=2; }
#define PEEK(addr) ((uint8_t)mem_readop_arg(addr))
#define PEEKOP(addr) ((uint8_t)mem_readop(addr))
#define GetModRM uint32_t ModRM=mem_readop_arg((I.sregs[CS]<<4)+I.ip++)
/* Cycle count macros:
CLK - cycle count is the same on all processors
CLKS - cycle count differs between processors, list all counts
CLKW - cycle count for word read/write differs for odd/even source/destination address
CLKM - cycle count for reg/mem instructions
CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
Prefetch & buswait time is not emulated.
Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
#define CLK(all) nec_ICount-=all
#define CLKS(v20,v30,v33) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e) { const uint32_t ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_ICount-=(I.ip&1)?((ocount>>cpu_type)&0x7f):((ecount>>cpu_type)&0x7f); }
#define CLKM(v20,v30,v33,v20m,v30m,v33m) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33, mcount=(v20m<<16)|(v30m<<8)|v33m; nec_ICount-=( ModRM >=0xc0 )?((ccount>>cpu_type)&0x7f):((mcount>>cpu_type)&0x7f); }
#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall) { const uint32_t ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_ICount-=vall; else nec_ICount-=(I.ip&1)?((ocount>>cpu_type)&0x7f):((ecount>>cpu_type)&0x7f); }
*/
#define CLKS(v20, v30, v33) { const uint32_t ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
#define CLK(all) nec_ICount-=all
#define CLKW(v30MZo, v30MZe) { nec_ICount-=(I.ip&1)?v30MZo:v30MZe; }
#define CLKM(v30MZm, v30MZ) { nec_ICount-=( ModRM >=0xc0 )?v30MZ:v30MZm; }
#define CLKR(v30MZo, v30MZe, vall) { if (ModRM >=0xc0) nec_ICount-=vall; else nec_ICount-=(I.ip&1)?v30MZo:v30MZe; }
#define CompressFlags() (uint16_t)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
| (SF << 7) | (I.TF << 8) | (I.IF << 9) \
| (I.DF << 10) | (OF << 11))
#define ExpandFlags(f) \
{ \
I.CarryVal = (f) & 1; \
I.ParityVal = !((f) & 4); \
I.AuxVal = (f) & 16; \
I.ZeroVal = !((f) & 64); \
I.SignVal = (f) & 128 ? -1 : 0; \
I.TF = ((f) & 256) == 256; \
I.IF = ((f) & 512) == 512; \
I.DF = ((f) & 1024) == 1024; \
I.OverVal = (f) & 2048; \
I.MF = ((f) & 0x8000) == 0x8000; \
}
#define IncWordReg(Reg) \
uint16_t tmp = (uint16_t)I.regs.w[Reg]; \
uint16_t tmp1 = tmp+1; \
I.OverVal = (tmp == 0x7fff); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define DecWordReg(Reg) \
uint16_t tmp = (uint16_t)I.regs.w[Reg]; \
uint16_t tmp1 = tmp-1; \
I.OverVal = (tmp == 0x8000); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define JMP(flag) \
int tmp = (int)((int8_t)FETCH); \
if (flag) \
{ \
I.ip = (uint16_t)(I.ip+tmp); \
nec_ICount-=3; \
return; \
}
#define ADJ4(param1, param2) \
if (AF || ((I.regs.b[AL] & 0xf) > 9)) \
{ \
int tmp; \
I.regs.b[AL] = tmp = I.regs.b[AL] + param1; \
I.AuxVal = 1; \
} \
if (CF || (I.regs.b[AL] > 0x9f)) \
{ \
I.regs.b[AL] += param2; \
I.CarryVal = 1; \
} \
SetSZPF_Byte(I.regs.b[AL])
#define ADJB(param1, param2) \
if (AF || ((I.regs.b[AL] & 0xf) > 9)) \
{ \
I.regs.b[AL] += param1; \
I.regs.b[AH] += param2; \
I.AuxVal = 1; \
I.CarryVal = 1; \
} \
else \
{ \
I.AuxVal = 0; \
I.CarryVal = 0; \
} \
I.regs.b[AL] &= 0x0F
#define BITOP_BYTE \
ModRM = FETCH; \
if (ModRM >= 0xc0) { \
tmp=I.regs.b[Mod_RM.RM.b[ModRM]]; \
} \
else { \
(*GetEA[ModRM])(); \
tmp=ReadByte(EA); \
}
#define BITOP_WORD \
ModRM = FETCH; \
if (ModRM >= 0xc0) { \
tmp=I.regs.w[Mod_RM.RM.w[ModRM]]; \
} \
else { \
(*GetEA[ModRM])(); \
tmp=ReadWord(EA); \
}
#define BIT_NOT \
if (tmp & (1<<tmp2)) \
tmp &= ~(1<<tmp2); \
else \
tmp |= (1<<tmp2)
#define XchgAWReg(Reg) \
uint16_t tmp; \
tmp = I.regs.w[Reg]; \
I.regs.w[Reg] = I.regs.w[AW]; \
I.regs.w[AW] = tmp
#define ROL_BYTE I.CarryVal = dst & 0x80; dst = (dst << 1)+CF
#define ROL_WORD I.CarryVal = dst & 0x8000; dst = (dst << 1)+CF
#define ROR_BYTE I.CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7)
#define ROR_WORD I.CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15)
#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst)
#define ROLC_WORD dst = (dst << 1) + CF; SetCFW(dst)
#define RORC_BYTE dst = (CF<<8)+dst; I.CarryVal = dst & 0x01; dst >>= 1
#define RORC_WORD dst = (CF<<16)+dst; I.CarryVal = dst & 0x01; dst >>= 1
#define SHL_BYTE(c) dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHL_WORD(c) dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define SHR_BYTE(c) dst >>= c-1; I.CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHR_WORD(c) dst >>= c-1; I.CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define SHRA_BYTE(c) dst = ((int8_t)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((int8_t)((uint8_t)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(uint8_t)dst)
#define SHRA_WORD(c) dst = ((int16_t)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((int16_t)((uint16_t)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(uint16_t)dst)
#define DIVUB \
uresult = I.regs.w[AW]; \
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = uresult; \
I.regs.b[AH] = uresult2; \
}
#define DIVB \
result = (int16_t)I.regs.w[AW]; \
result2 = result % (int16_t)((int8_t)tmp); \
if ((result /= (int16_t)((int8_t)tmp)) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = result; \
I.regs.b[AH] = result2; \
}
#define DIVUW \
uresult = (((uint32_t)I.regs.w[DW]) << 16) | I.regs.w[AW];\
uresult2 = uresult % tmp; \
if ((uresult /= tmp) > 0xffff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.w[AW]=uresult; \
I.regs.w[DW]=uresult2; \
}
#define DIVW \
result = ((uint32_t)I.regs.w[DW] << 16) + I.regs.w[AW]; \
result2 = result % (int32_t)((int16_t)tmp); \
if ((result /= (int32_t)((int16_t)tmp)) > 0xffff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.w[AW]=result; \
I.regs.w[DW]=result2; \
}
#define ADD4S { \
int i,v1,v2,result; \
int count = (I.regs.b[CL]+1)/2; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(DS, si); \
tmp2 = GetMemB(ES, di); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
result = v1+v2+I.CarryVal; \
I.CarryVal = result > 99 ? 1 : 0; \
result = result % 100; \
v1 = ((result/10)<<4) | (result % 10); \
PutMemB(ES, di,v1); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
}
#define SUB4S { \
int count = (I.regs.b[CL]+1)/2; \
int i,v1,v2,result; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(ES, di); \
tmp2 = GetMemB(DS, si); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
if (v1 < (v2+I.CarryVal)) { \
v1+=100; \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 1; \
} else { \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 0; \
} \
v1 = ((result/10)<<4) | (result % 10); \
PutMemB(ES, di,v1); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
}
#define CMP4S { \
int count = (I.regs.b[CL]+1)/2; \
int i,v1,v2,result; \
uint16_t di = I.regs.w[IY]; \
uint16_t si = I.regs.w[IX]; \
I.ZeroVal = I.CarryVal = 0; \
for (i=0;i<count;i++) { \
tmp = GetMemB(ES, di); \
tmp2 = GetMemB(DS, si); \
v1 = (tmp>>4)*10 + (tmp&0xf); \
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
if (v1 < (v2+I.CarryVal)) { \
v1+=100; \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 1; \
} else { \
result = v1-(v2+I.CarryVal); \
I.CarryVal = 0; \
} \
v1 = ((result/10)<<4) | (result % 10); \
if (v1) I.ZeroVal = 1; \
si++; \
di++; \
} \
}
#endif /* __NEC_H_ */

View File

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

View File

@@ -0,0 +1,48 @@
/******************************************************************************
* NewOswan
* necintrf.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
/* ASG 971222 -- rewrote this interface */
#ifndef __NECITRF_H_
#define __NECITRF_H_
#include <stdint.h>
enum
{
NEC_IP = 1,
NEC_AW,
NEC_CW,
NEC_DW,
NEC_BW,
NEC_SP,
NEC_BP,
NEC_IX,
NEC_IY,
NEC_FLAGS,
NEC_ES,
NEC_CS,
NEC_SS,
NEC_DS,
NEC_VECTOR,
NEC_PENDING,
NEC_NMI_STATE,
NEC_IRQ_STATE
};
/* Public variables */
extern int nec_ICount;
/* Public functions */
void nec_set_irq_line(int irqline, int state);
void nec_set_reg(int regnum, uint32_t val);
int nec_execute(int cycles);
unsigned nec_get_reg(int regnum);
void nec_reset(void *param);
void nec_int(uint16_t vector);
#endif /* __NECITRF_H_ */

78
source/includes/rom.h Normal file
View File

@@ -0,0 +1,78 @@
/*******************************************************************************
* NewOswan
* rom.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __ROM_H__
#define __ROM_H__
#include <stdint.h>
#define WS_ROM_SIZE_2MBIT 1
#define WS_ROM_SIZE_4MBIT 2
#define WS_ROM_SIZE_8MBIT 3
#define WS_ROM_SIZE_16MBIT 4
#define WS_ROM_SIZE_24MBIT 5
#define WS_ROM_SIZE_32MBIT 6
#define WS_ROM_SIZE_48MBIT 7
#define WS_ROM_SIZE_64MBIT 8
#define WS_ROM_SIZE_128MBIT 9
#define WS_EEPROM_SIZE_NONE 0
#define WS_EEPROM_SIZE_1k 0x10
#define WS_EEPROM_SIZE_16k 0x20
#define WS_EEPROM_SIZE_32k 0x30
/* 40 is not valid */
#define WS_EEPROM_SIZE_8k 0x50
#define WS_EEPROM_SIZE_4k 0x60
#define WS_EEPROM_SIZE_2k 0x70
#define WS_SRAM_SIZE_NONE 0
#define WS_SRAM_SIZE_64k 0x01
#define WS_SRAM_SIZE_256k 0x02
#define WS_SRAM_SIZE_1M 0x03
#define WS_SRAM_SIZE_2M 0x04
#define WS_SRAM_SIZE_4M 0x05
#pragma pack(1)
typedef struct ws_romHeaderStruct
{
/* Miss "Fixed Data" (F5h) */
uint8_t developperId; /* Maker Code L */
uint8_t minimumSupportSystem; /* Maker Code H */
uint8_t cartId; /* Title code */
uint8_t gameVertion; /* Version */
uint8_t romSize; /* ROM Size */
uint8_t saveSize; /* XROM/XEROM Size */
uint8_t cartFlags; /* Boot loader */
uint8_t realtimeClock; /* Syb System LSI */
uint16_t checksum; /* Checksum */
} ws_romHeaderStruct;
#pragma pack()
uint8_t *ws_rom_load(char *path, uint32_t *romSize);
void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t wsromSize);
ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize);
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize);
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize);
static inline uint8_t *ws_get_page_ptr(uint8_t *wsrom, uint32_t romSize, uint16_t page)
{
uint32_t temp = page << 16;
temp &= (romSize - 1);
return &wsrom[temp];
}
#endif

46
source/includes/ws.h Normal file
View File

@@ -0,0 +1,46 @@
/*******************************************************************************
* NewOswan
* ws.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __WS_H__
#define __WS_H__
#include <stdint.h>
typedef enum wssystem_t
{
WS_SYSTEM_AUTODETECT = 0, WS_SYSTEM_MONO, WS_SYSTEM_COLOR, WS_SYSTEM_CRYSTAL,
} wssystem_t;
extern uint32_t ws_cyclesByLine;
int ws_init(char *rompath);
int ws_rotated(void);
void ws_set_system(wssystem_t system);
wssystem_t ws_get_system();
void ws_reset(void);
int ws_executeLine(int16_t *framebuffer, int renderLine);
void ws_patchRom(void);
int ws_loadState(char *statepath);
int ws_saveState(char *statepath);
void ws_done(void);
extern char *ws_sram_path;
extern char *ws_ieep_path;
extern char *ws_rom_path;
#endif