Move everything in the root folder

This commit is contained in:
Godzil
2020-01-15 19:06:45 +00:00
parent ec2a2f937f
commit f592057e48
30 changed files with 0 additions and 0 deletions

314
source/SDLptc.h Normal file
View File

@@ -0,0 +1,314 @@
/* Some simple emulation classes to get PTC code running on SDL */
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
#define randomize() srand(time(NULL))
#define random(max) (rand()%(max))
#ifndef stricmp
#define stricmp strcasecmp
#endif
class Error
{
public:
Error(const char *message)
{
strcpy(_message, message);
}
void report(void)
{
printf("Error: %s\n", _message);
}
private:
char _message[1024];
};
class Area
{
public:
Area(int left, int top, int right, int bottom)
{
_left = left;
_top = top;
_right = right;
_bottom = bottom;
}
int left(void) const
{
return(_left);
}
int right(void) const
{
return(_right);
}
int top(void) const
{
return(_top);
}
int bottom(void) const
{
return(_bottom);
}
int width(void) const
{
return(_right-_left);
}
int height(void) const
{
return(_bottom-_top);
}
private:
int _left, _top, _right, _bottom;
};
class Format
{
public:
Format(int bpp, int maskR = 0, int maskG = 0, int maskB = 0)
{
_bpp = bpp;
_maskR = maskR;
_maskG = maskG;
_maskB = maskB;
}
Uint8 BPP(void) const
{
return(_bpp);
}
Uint32 MaskR(void) const
{
return(_maskR);
}
Uint32 MaskG(void) const
{
return(_maskG);
}
Uint32 MaskB(void) const
{
return(_maskB);
}
private:
Uint8 _bpp;
Uint32 _maskR, _maskG, _maskB;
};
class Surface
{
public:
Surface(int w, int h, const Format &format)
{
surface = SDL_AllocSurface(SDL_SWSURFACE, w, h, format.BPP(),
format.MaskR(),format.MaskG(),format.MaskB(),0);
if ( surface == NULL )
{
throw Error(SDL_GetError());
}
nupdates = 0;
is_console = 0;
}
Surface(void)
{
nupdates = 0;
is_console = 1;
}
virtual ~Surface()
{
if ( ! is_console )
{
SDL_FreeSurface(surface);
}
}
virtual int width(void)
{
return surface->w;
}
virtual int height(void)
{
return surface->h;
}
virtual int pitch(void)
{
return surface->pitch;
}
virtual void palette(int32_t *pcolors)
{
SDL_Color colors[256];
for ( int i=0; i<256; ++i )
{
colors[i].r = (pcolors[i]>>16)&0xFF;
colors[i].g = (pcolors[i]>>8)&0xFF;
colors[i].b = (pcolors[i]>>0)&0xFF;
}
SDL_SetColors(surface, colors, 0, 256);
}
virtual void *lock(void)
{
if ( SDL_MUSTLOCK(surface) )
{
while ( SDL_LockSurface(surface) < 0 )
{
SDL_Delay(10);
}
}
return (Uint8 *)surface->pixels;
}
virtual void unlock(void)
{
if ( SDL_MUSTLOCK(surface) )
{
SDL_UnlockSurface(surface);
}
}
virtual void copy(Surface &dst,
const Area &srcarea, const Area &dstarea)
{
SDL_Rect srcrect, dstrect;
srcrect.x = srcarea.left();
srcrect.y = srcarea.top();
srcrect.w = srcarea.width();
srcrect.h = srcarea.height();
dstrect.x = dstarea.left();
dstrect.y = dstarea.top();
dstrect.w = dstarea.width();
dstrect.h = dstarea.height();
SDL_BlitSurface(surface, &srcrect, dst.surface, &dstrect);
dst.updates[dst.nupdates++] = dstrect;
}
virtual void copy(Surface &dst)
{
SDL_Rect srcrect, dstrect;
srcrect.x = 0;
srcrect.y = 0;
srcrect.w = surface->w;
srcrect.h = surface->h;
dstrect.x = 0;
dstrect.y = 0;
dstrect.w = surface->w;
dstrect.h = surface->h;
SDL_LowerBlit(surface, &srcrect, dst.surface, &dstrect);
dst.updates[dst.nupdates++] = dstrect;
}
virtual void update(void)
{
SDL_UpdateRects(surface, nupdates, updates);
nupdates = 0;
}
protected:
SDL_Surface *surface;
int nupdates;
SDL_Rect updates[1]; /* Definitely increase this.. */
int is_console;
};
class Console : public Surface
{
int fullscreen;
public:
Console() : Surface()
{
fullscreen=0;
}
~Console()
{
SDL_Quit();
}
void close(void)
{
SDL_Quit();
}
void option(char *option)
{
if (!stricmp(option,"fullscreen output"))
{
fullscreen=1;
}
else if (!stricmp(option,"windowed output"))
{
fullscreen=0;
}
}
void open(const char *title, int width, int height, const Format &format)
{
uint32_t flags;
if ( SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
{
throw Error(SDL_GetError());
}
flags = (SDL_HWSURFACE|SDL_HWPALETTE);
if (fullscreen)
{
flags|=SDL_FULLSCREEN;
}
surface = SDL_SetVideoMode(width, height, 0, flags);
if ( surface == NULL )
{
throw Error(SDL_GetError());
}
SDL_WM_SetCaption(title, title);
}
int key(void)
{
SDL_Event event;
int keyevent;
keyevent = 0;
while ( SDL_PollEvent(&event) )
{
/* Real key events trigger this function */
if ( event.type == SDL_KEYDOWN )
{
keyevent = 1;
}
/* So do quit events -- let the app know about it */
if ( event.type == SDL_QUIT )
{
keyevent = 1;
}
}
return(keyevent);
}
private:
};

1515
source/audio.cpp Normal file

File diff suppressed because it is too large Load Diff

43
source/audio.h Normal file
View File

@@ -0,0 +1,43 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __AUDIO_H__
#define __AUDIO_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

560
source/emulate.cpp Normal file
View File

@@ -0,0 +1,560 @@
////////////////////////////////////////////////////////////////////////////////
// Main emulation loop
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h> /* UNIX standard function definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/mman.h>
#include "SDL.h"
#include "SDLptc.h"
#include "log.h"
#include "io.h"
#include "ws.h"
#include "rom.h"
#include "./nec/nec.h"
#include "./nec/necintrf.h"
#include "gpu.h"
#include "audio.h"
#include "memory.h"
SDL_Joystick *joystick=NULL;
char app_window_title[256];
int app_gameRunning=0;
int app_terminate=0;
int app_fullscreen=0;
SDL_Event app_input_event;
int app_rotated=0;
int ws_key_esc = 0;
static void read_keys()
{
static int testJoystick=1;
if (testJoystick==1)
{
testJoystick=0;
fprintf(log_get(),"%i joysticks were found.\n\n", SDL_NumJoysticks() );
fprintf(log_get(),"The names of the joysticks are:\n");
for(int tti=0; tti < SDL_NumJoysticks(); tti++ )
{
fprintf(log_get()," %s\n", SDL_JoystickName(tti));
}
SDL_JoystickEventState(SDL_ENABLE);
joystick = SDL_JoystickOpen(0);
}
else
{
if (joystick!=NULL)
{
SDL_JoystickClose(0);
SDL_JoystickEventState(SDL_ENABLE);
joystick = SDL_JoystickOpen(0);
}
}
while ( SDL_PollEvent(&app_input_event) )
{
if ( app_input_event.type == SDL_QUIT )
{
ws_key_esc = 1;
}
}
if (joystick)
{
if (SDL_JoystickGetButton(joystick,0))
{
ws_key_start=1;
}
else
{
ws_key_start=0;
}
if (SDL_JoystickGetButton(joystick,1))
{
ws_key_button_a=1;
}
else
{
ws_key_button_a=0;
}
if (SDL_JoystickGetButton(joystick,2))
{
ws_key_button_b=1;
}
else
{
ws_key_button_b=0;
}
if (SDL_JoystickGetAxis(joystick,0)<-7000)
{
ws_key_x4=1;
}
else
{
ws_key_x4=0;
}
if (SDL_JoystickGetAxis(joystick,0)>7000)
{
ws_key_x2=1;
}
else
{
ws_key_x2=0;
}
if (SDL_JoystickGetAxis(joystick,1)<-7000)
{
ws_key_x1=1;
}
else
{
ws_key_x1=0;
}
if (SDL_JoystickGetAxis(joystick,1)>7000)
{
ws_key_x3=1;
}
else
{
ws_key_x3=0;
}
ws_key_y4=0;
ws_key_y2=0;
ws_key_y1=0;
ws_key_y3=0;
}
else
{
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;
}
uint8_t *keystate = SDL_GetKeyState(NULL);
if ( keystate[SDLK_e])
{
dump_memory();
}
if ( keystate[SDLK_r])
{
printf("Boop\n");
ws_reset();
}
if ( keystate[SDLK_ESCAPE] )
{
ws_key_esc = 1;
}
if ( keystate[SDLK_UP] )
{
ws_key_x1=1;
}
if ( keystate[SDLK_DOWN] )
{
ws_key_x3=1;
}
if ( keystate[SDLK_RIGHT] )
{
ws_key_x2=1;
}
if ( keystate[SDLK_LEFT] )
{
ws_key_x4=1;
}
if (keystate[SDLK_RETURN])
{
ws_key_start=1;
}
if (keystate[SDLK_c])
{
ws_key_button_a=1;
}
if (keystate[SDLK_x])
{
ws_key_button_b=1;
}
if (keystate[SDLK_w])
{
ws_key_y1=1;
}
if (keystate[SDLK_a])
{
ws_key_y4=1;
}
if (keystate[SDLK_s])
{
ws_key_y3=1;
}
if (keystate[SDLK_d])
{
ws_key_y2=1;
}
if (keystate[SDLK_o])
{
ws_cyclesByLine+=10;
}
if (keystate[SDLK_l])
{
ws_cyclesByLine-=10;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
static void ws_drawDoubledScanline(int16_t *vs, int16_t *backbuffer_alias)
{
register int32_t *vs_alias = (int32_t *)vs;
register int32_t data;
for (int pixel = 0 ; pixel < 224 ; pixel += 8)
{
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
static void ws_drawDoubledRotatedScanline(int16_t *vs, int16_t *backbuffer_alias)
{
register int32_t *vs_alias = (int32_t *)vs;
register int32_t data;
for (int pixel = 0 ; pixel < 144 ; pixel += 8)
{
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
data = *backbuffer_alias++;
data |= (data << 16);
*vs_alias++ = data;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_rotate_backbuffer(int16_t *backbuffer)
{
static int16_t temp[224*144];
memcpy(temp,backbuffer,224*144*2);
for (int line=0; line<144; line++)
for (int column=0; column<224; column++)
{
backbuffer[line+((223-column)<<7)+((223-column)<<4)]=temp[column+(line<<7)+(line<<6)+(line<<5)];
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate(void)
{
int32_t nCount = 0;
int i = 0;
double dTime = 0.0, dNormalLast = 0.0, dTemp;
int32_t surfacePitch;
// 15 bits RGB555
Format format(16, 0x007c00, 0x00003e0, 0x0000001f);
Console console;
Surface *surface;
if (app_rotated)
{
surface = new Surface(144 * 2, 224 * 2, format);
int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t));
memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t));
surfacePitch = (surface->pitch() >> 1);
dNormalLast = (double)SDL_GetTicks();
console.open(app_window_title, 144 * 2, 224 * 2, format);
while (1)
{
dTemp = (double)SDL_GetTicks();
dTime = dTemp - dNormalLast;
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
{
SDL_Delay(2);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / 0.07547);
if (nCount > 10)
{
nCount = 10;
}
read_keys();
if (ws_key_esc)
{
console.close();
app_terminate = 1;
if ((ws_rom_path != NULL) || (app_terminate))
{
break;
}
console.open(app_window_title, 144 * 2, 224 * 2, format);
}
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backbuffer, 0))
{
}
}
while (!ws_executeLine(backbuffer, 1))
{
}
ws_rotate_backbuffer(backbuffer);
int16_t *vs = (int16_t *)surface->lock();
int16_t *backbuffer_alias = backbuffer;
for (int line = 0 ; line < 224 ; line++)
{
ws_drawDoubledRotatedScanline(vs, backbuffer_alias);
vs += surfacePitch;
ws_drawDoubledRotatedScanline(vs, backbuffer_alias);
vs += surfacePitch;
backbuffer_alias += 144;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
console.close();
delete surface;
}
else
{
surface = new Surface(224 * 2, 144 * 2, format);
int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t));
memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t));
surfacePitch = (surface->pitch() >> 1);
dNormalLast = (double)SDL_GetTicks();
console.open(app_window_title, 224 * 2, 144 * 2, format);
while (1)
{
dTemp = (double)SDL_GetTicks();
dTime = dTemp - dNormalLast;
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
if (nCount <= 0)
{
SDL_Delay(2);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / 0.07547);
if (nCount > 10)
{
nCount = 10;
}
read_keys();
if (ws_key_esc)
{
console.close();
app_terminate = 1;
if ((ws_rom_path != NULL) || (app_terminate))
{
break;
}
console.open(app_window_title, 224 * 2, 144 * 2, format);
}
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backbuffer, 0))
{
}
}
while (!ws_executeLine(backbuffer, 1))
{
}
int16_t *vs = (int16_t *)surface->lock();
int16_t *backbuffer_alias = backbuffer;
for (int line = 0 ; line < 144 ; line++)
{
ws_drawDoubledScanline(vs, backbuffer_alias);
vs += surfacePitch;
ws_drawDoubledScanline(vs, backbuffer_alias);
vs += surfacePitch;
backbuffer_alias += 224;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
console.close();
delete surface;
}
}

31
source/emulate.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef EMULATE_H
#define EMULATE_H
#define KEY_ENTER 0x0D
#define KEY_SPACE 0x20
#define KEY_ESC 0x1b
#define KEY_UP 0x26
#define KEY_DOWN 0x28
#define KEY_LEFT 0x25
#define KEY_RIGHT 0x27
#define KEY_BUTTON1 0x57
#define KEY_BUTTON2 0x58
#define GUI_COMMAND_NONE 0
#define GUI_COMMAND_RESET 1
#define GUI_COMMAND_SCHEME_CHANGE 2
#define GUI_COMMAND_FILTER_CHANGE 3
extern char app_window_title[256];
extern int app_gameRunning;
extern int app_terminate;
extern int app_fullscreen;
extern SDL_Event app_input_event;
extern int app_rotated;
void ws_emulate(void);
#endif /* EMULATE_H */

2313
source/gpu.cpp Normal file

File diff suppressed because it is too large Load Diff

45
source/gpu.h Normal file
View File

@@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __GPU_H__
#define __GPU_H__
#define COLOUR_SCHEME_DEFAULT 0
#define COLOUR_SCHEME_AMBER 1
#define COLOUR_SCHEME_GREEN 2
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_set_colour_scheme(int scheme);
void ws_gpu_changeVideoMode(uint8_t value);
void ws_gpu_forceColorSystem(void);
void ws_gpu_forceMonoSystem(void);
void ws_gpu_clearCache(void);
#endif

191
source/ieeprom.h Normal file
View File

@@ -0,0 +1,191 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
uint8_t DefaultBWEEprom[]=
{
0xff,0xff,0xff,0xff,0xff,0xff,192,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,127,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,252,0xff,1,0xff,253,0xff,253,0xff,253,0xff,253,
0xff,253,0xff,253,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,3,3,0x00,0x00,0x00,64,128,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135,5,140,9,5,12,139,12,144,0x00,0x00,2,
0x00,76,165,0x00,128,0x00,0x00,0x00,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,6,6,6,6,6,0x00,0x00,0x00,0x00,0x00,
1,128,15,0x00,1,1,1,15,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
'W'-54,'O'-54,'N'-54,'D'-54,'E'-54,'R'-54,'S'-54,'W'-54,'A'-54,'N'-54,0x00,0x00,0x00,0x00,0x00,
0x00,32,1,1,33,1,4,0x00,1,
0x00,152,60,127,74,1,53,1,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff
};
uint8_t DefaultColorEEprom[]=
{
0xff,0xff,0xff,0xff,0xff,0xff,192,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,127,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,252,0xff,1,0xff,253,0xff,253,0xff,253,0xff,253,
0xff,253,0xff,253,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,3,3,0x00,0x00,0x00,64,128,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135,5,140,9,5,12,139,12,144,0x00,0x00,2,
0x00,76,165,0x00,128,0x00,0x00,0x00,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,0xff,127,
0xff,127,0xff,127,0xff,127,0xff,127,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0x00,0x00,6,6,6,6,6,0x00,0x00,0x00,0x00,0x00,
1,128,15,0x00,1,1,1,15,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
'W'-54,'O'-54,'N'-54,'D'-54,'E'-54,'R'-54,'S'-54,'W'-54,'A'-54,'N'-54,0x00,0x00,0x00,0x00,0x00,
0x00,32,1,1,33,1,4,0x00,1,
0x00,152,60,127,74,1,53,1,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff
};

271
source/initialIo.h Normal file
View File

@@ -0,0 +1,271 @@
////////////////////////////////////////////////////////////////////////////////
// Initial I/O values
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
uint8_t initialIoValue[256]=
{
0x00,//0
0x00,//1
0x9d,//2
0xbb,//3
0x00,//4
0x00,//5
0x00,//6
0x26,//7
0xfe,//8
0xde,//9
0xf9,//a
0xfb,//b
0xdb,//c
0xd7,//d
0x7f,//e
0xf5,//f
0x00,//10
0x00,//11
0x00,//12
0x00,//13
0x01,//14
0x00,//15
0x9e,//16
0x9b,//17
0x00,//18
0x00,//19
0x00,//1a
0x00,//1b
0x99,//1c
0xfd,//1d
0xb7,//1e
0xdf,//1f
0x30,//20
0x57,//21
0x75,//22
0x76,//23
0x15,//24
0x73,//25
0x77,//26
0x77,//27
0x20,//28
0x75,//29
0x50,//2a
0x36,//2b
0x70,//2c
0x67,//2d
0x50,//2e
0x77,//2f
0x57,//30
0x54,//31
0x75,//32
0x77,//33
0x75,//34
0x17,//35
0x37,//36
0x73,//37
0x50,//38
0x57,//39
0x60,//3a
0x77,//3b
0x70,//3c
0x77,//3d
0x10,//3e
0x73,//3f
0x00,//40
0x00,//41
0x00,//42
0x00,//43
0x00,//44
0x00,//45
0x00,//46
0x00,//47
0x00,//48
0x00,//49
0x00,//4a
0x00,//4b
0x00,//4c
0x00,//4d
0x00,//4e
0x00,//4f
0x00,//50
0x00,//51
0x00,//52
0x00,//53
0x00,//54
0x00,//55
0x00,//56
0x00,//57
0x00,//58
0x00,//59
0x00,//5a
0x00,//5b
0x00,//5c
0x00,//5d
0x00,//5e
0x00,//5f
0x0a,//60
0x00,//61
0x00,//62
0x00,//63
0x00,//64
0x00,//65
0x00,//66
0x00,//67
0x00,//68
0x00,//69
0x00,//6a
0x0f,//6b
0x00,//6c
0x00,//6d
0x00,//6e
0x00,//6f
0x00,//70
0x00,//71
0x00,//72
0x00,//73
0x00,//74
0x00,//75
0x00,//76
0x00,//77
0x00,//78
0x00,//79
0x00,//7a
0x00,//7b
0x00,//7c
0x00,//7d
0x00,//7e
0x00,//7f
0x00,//80
0x00,//81
0x00,//82
0x00,//83
0x00,//84
0x00,//85
0x00,//86
0x00,//87
0x00,//88
0x00,//89
0x00,//8a
0x00,//8b
0x00,//8c
0x1f,//8d 1d ?
0x00,//8e
0x00,//8f
0x00,//90
0x00,//91
0x00,//92
0x00,//93
0x00,//94
0x00,//95
0x00,//96
0x00,//97
0x00,//98
0x00,//99
0x00,//9a
0x00,//9b
0x00,//9c
0x00,//9d
0x03,//9e
0x00,//9f
0x80,//a0
0x00,//a1
0x00,//a2
0x00,//a3
0x0,//a4 2b
0x0,//a5 7f
0x4f,//a6
0xff,//a7 cf ?
0x00,//a8
0x00,//a9
0x00,//aa
0x00,//ab
0x00,//ac
0x00,//ad
0x00,//ae
0x00,//af
0x00,//b0
0xdb,//b1
0x00,//b2
0x00,//b3
0x00,//b4
0x40,//b5
0x00,//b6
0x00,//b7
0x00,//b8
0x00,//b9
0x01,//ba
0x00,//bb
0x42,//bc
0x00,//bd
0x83,//be
0x00,//bf
0x2f,//c0
0x3f,//c1
0xff,//c2
0xff,//c3
0x00,//c4
0x00,//c5
0x00,//c6
0x00,//c7
0xd1,//c8?
0xd1,//c9
0xd1,//ca
0xd1,//cb
0xd1,//cc
0xd1,//cd
0xd1,//ce
0xd1,//cf
0xd1,//d0
0xd1,//d1
0xd1,//d2
0xd1,//d3
0xd1,//d4
0xd1,//d5
0xd1,//d6
0xd1,//d7
0xd1,//d8
0xd1,//d9
0xd1,//da
0xd1,//db
0xd1,//dc
0xd1,//dd
0xd1,//de
0xd1,//df
0xd1,//e0
0xd1,//e1
0xd1,//e2
0xd1,//e3
0xd1,//e4
0xd1,//e5
0xd1,//e6
0xd1,//e7
0xd1,//e8
0xd1,//e9
0xd1,//ea
0xd1,//eb
0xd1,//ec
0xd1,//ed
0xd1,//ee
0xd1,//ef
0xd1,//f0
0xd1,//f1
0xd1,//f2
0xd1,//f3
0xd1,//f4
0xd1,//f5
0xd1,//f6
0xd1,//f7
0xd1,//f8
0xd1,//f9
0xd1,//fa
0xd1,//fb
0xd1,//fc
0xd1,//fd
0xd1,//fe
0xd1 //ff
};

1090
source/io.cpp Normal file

File diff suppressed because it is too large Load Diff

34
source/io.h Normal file
View File

@@ -0,0 +1,34 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __IO_H__
#define __IO_H__
extern uint8_t *ws_ioRam;
extern uint8_t ws_key_start;
extern uint8_t ws_key_x4;
extern uint8_t ws_key_x2;
extern uint8_t ws_key_x1;
extern uint8_t ws_key_x3;
extern uint8_t ws_key_y4;
extern uint8_t ws_key_y2;
extern uint8_t ws_key_y1;
extern uint8_t ws_key_y3;
extern uint8_t ws_key_button_a;
extern uint8_t ws_key_button_b;
void ws_io_init(void);
void ws_io_reset(void);
void ws_io_flipControls(void);
void ws_io_done(void);
#endif

67
source/log.cpp Normal file
View File

@@ -0,0 +1,67 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include "log.h"
FILE *log_stream=NULL;
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
int log_init(char *path)
{
//log_stream=fopen(path,"wrt");
log_stream = stdout;
if (log_stream==NULL)
{
return(0);
}
return(1);
}
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
FILE *log_get(void)
{
return(log_stream);
}
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
void log_done(void)
{
fclose(log_stream);
}

20
source/log.h Normal file
View File

@@ -0,0 +1,20 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __LOG_H__
#define __LOG_H__
int log_init(char *path);
FILE *log_get(void);
void log_done(void);
#endif

448
source/memory.cpp Normal file
View File

@@ -0,0 +1,448 @@
////////////////////////////////////////////////////////////////////////////////
// Memory
////////////////////////////////////////////////////////////////////////////////
// Notes: need to optimize cpu_writemem20
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "log.h"
#include "rom.h"
#include "./nec/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 *internalBWEeprom;
char *internalColorEeprom;
uint16_t *internalEeprom;
extern uint8_t *ws_ioRam;
uint16_t ws_rom_checksum;
uint8_t ws_haveColorIRom;
uint8_t ws_haveBWIRom;
uint32_t sramAddressMask;
uint32_t externalEepromAddressMask;
uint32_t romAddressMask;
uint32_t romSize;
int ws_sram_dirty = 0;
extern nec_Regs I;
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);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void cpu_writemem20(uint32_t addr, uint8_t value)
{
uint32_t offset=addr&0xffff;
uint32_t bank=addr>>16;
if (!bank)
{
// 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
ws_gpu_write_byte(offset,value);
ws_audio_write_byte(offset,value);
}
else if (bank==1)
{
// 1 - SRAM (cart)
ws_staticRam[offset&sramAddressMask]=value;
ws_sram_dirty = 1;
}
// other banks are read-only
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t cpu_readmem20(uint32_t addr)
{
uint32_t offset=addr&0xffff;
uint32_t bank=addr>>16;
//uint16_t romBank;
uint8_t hwReg;
uint32_t temp;
uint8_t ret;
switch (bank)
{
case 0: // 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
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 (ws_gpu_operatingInColor && ws_haveColorIRom)
{
if (addr >= 0xFE000)
{
ret = internalColorIRom[addr & ~0xFE000];
return ret;
}
}
else if (!ws_gpu_operatingInColor && 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);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
char *load_file(char *filename)
{
int fd;
char *ret_ptr;
struct stat FileStat;
fd = open(filename, O_RDWR);
fstat(fd, &FileStat);
printf("Trying to load %s, size = %lu...\n",filename, 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 };
printf("Trying to create %s, size = %u...\n",filename, size);
fd = open(filename, O_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_TRUNC);
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;
ws_romHeader=ws_rom_getHeader(ws_rom,romSize);
ws_rom_checksum=ws_romHeader->checksum;
internalRam=(uint8_t*)malloc(0x10000);
sramAddressMask=ws_rom_sramSize(ws_rom,romSize)-1;
externalEepromAddressMask=ws_rom_eepromSize(ws_rom,romSize)-1;
internalBWIRom = load_file("ws_irom.bin");
internalColorIRom = load_file("wsc_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);
}
internalEeprom = (uint16_t *)internalBWEeprom;
if (ws_gpu_operatingInColor)
{
internalEeprom = (uint16_t *)internalColorEeprom;
}
ws_haveBWIRom = false;
ws_haveColorIRom = false;
if (internalBWIRom != NULL)
{
printf("Color IROM Found!\n");
ws_haveBWIRom = true;
}
if (internalColorIRom != NULL)
{
printf("B&W IROM Found!\n");
ws_haveColorIRom = true;
}
romAddressMask=romSize-1;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
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);
}

37
source/memory.h Normal file
View File

@@ -0,0 +1,37 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __MEMORY_H__
#define __MEMORY_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 BW_IEEPROM_SIZE (128)
#define COLOR_IEEPROM_SIZE (2048)
#endif

3933
source/nec/nec.cpp Normal file

File diff suppressed because it is too large Load Diff

394
source/nec/nec.h Normal file
View File

@@ -0,0 +1,394 @@
#ifndef __NEC_H_
#define __NEC_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
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
/* 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 : I.sregs[Seg] << 4)
#define GetMemB(Seg,Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint8_t)cpu_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg,Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint16_t) cpu_readmem20((DefaultBase(Seg)+(Off))) + (cpu_readmem20((DefaultBase(Seg)+((Off)+1)))<<8) )
#define PutMemB(Seg,Off,x) { /*nec_ICount-=((Off)&1)?1:0*/; cpu_writemem20((DefaultBase(Seg)+(Off)),(x)); }
#define PutMemW(Seg,Off,x) { /*nec_ICount-=((Off)&1)?1:0*/; PutMemB(Seg,Off,(x)&0xff); PutMemB(Seg,(Off)+1,(uint8_t)((x)>>8)); }
/* Todo: Remove these later - plus readword could overflow */
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (uint8_t)cpu_readmem20((ea)))
#define ReadWord(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ cpu_readmem20((ea))+(cpu_readmem20(((ea)+1))<<8))
#define WriteByte(ea,val) { /*nec_ICount-=((ea)&1)?1:0*/; cpu_writemem20((ea),val); }
#define WriteWord(ea,val) { /*nec_ICount-=((ea)&1)?1:0*/; cpu_writemem20((ea),(uint8_t)(val)); cpu_writemem20(((ea)+1),(val)>>8); }
#define read_port(port) cpu_readport(port)
#define write_port(port,val) cpu_writeport(port,val)
#define FETCH (cpu_readop_arg((I.sregs[CS]<<4)+I.ip++))
#define FETCHOP (cpu_readop((I.sregs[CS]<<4)+I.ip++))
#define FETCHWORD(var) { var=cpu_readop_arg((((I.sregs[CS]<<4)+I.ip)))+(cpu_readop_arg((((I.sregs[CS]<<4)+I.ip+1)))<<8); I.ip+=2; }
#define PUSH(val) { I.regs.w[SP]-=2; WriteWord((((I.sregs[SS]<<4)+I.regs.w[SP])),val); }
#define POP(var) { var = ReadWord((((I.sregs[SS]<<4)+I.regs.w[SP]))); I.regs.w[SP]+=2; }
#define PEEK(addr) ((uint8_t)cpu_readop_arg(addr))
#define PEEKOP(addr) ((uint8_t)cpu_readop(addr))
#define GetModRM uint32_t ModRM=cpu_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_ */

198
source/nec/necea.h Normal file
View File

@@ -0,0 +1,198 @@
static uint32_t EA;
static uint16_t EO;
static uint16_t E16;
static unsigned EA_000(void)
{
EO=I.regs.w[BW]+I.regs.w[IX];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_001(void)
{
EO=I.regs.w[BW]+I.regs.w[IY];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_002(void)
{
EO=I.regs.w[BP]+I.regs.w[IX];
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_003(void)
{
EO=I.regs.w[BP]+I.regs.w[IY];
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_004(void)
{
EO=I.regs.w[IX];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_005(void)
{
EO=I.regs.w[IY];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_006(void)
{
EO=FETCH;
EO+=FETCH<<8;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_007(void)
{
EO=I.regs.w[BW];
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_100(void)
{
EO=(I.regs.w[BW]+I.regs.w[IX]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_101(void)
{
EO=(I.regs.w[BW]+I.regs.w[IY]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_102(void)
{
EO=(I.regs.w[BP]+I.regs.w[IX]+(int8_t)FETCH);
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_103(void)
{
EO=(I.regs.w[BP]+I.regs.w[IY]+(int8_t)FETCH);
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_104(void)
{
EO=(I.regs.w[IX]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_105(void)
{
EO=(I.regs.w[IY]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_106(void)
{
EO=(I.regs.w[BP]+(int8_t)FETCH);
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_107(void)
{
EO=(I.regs.w[BW]+(int8_t)FETCH);
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_200(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BW]+I.regs.w[IX]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_201(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BW]+I.regs.w[IY]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_202(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BP]+I.regs.w[IX]+(int16_t)E16;
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_203(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BP]+I.regs.w[IY]+(int16_t)E16;
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_204(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[IX]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_205(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[IY]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned EA_206(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BP]+(int16_t)E16;
EA=DefaultBase(SS)+EO;
return EA;
}
static unsigned EA_207(void)
{
E16=FETCH;
E16+=FETCH<<8;
EO=I.regs.w[BW]+(int16_t)E16;
EA=DefaultBase(DS)+EO;
return EA;
}
static unsigned (*GetEA[192])(void)=
{
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207,
EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207
};

507
source/nec/necinstr.h Normal file
View File

@@ -0,0 +1,507 @@
static void i_add_br8(void);
static void i_add_wr16(void);
static void i_add_r8b(void);
static void i_add_r16w(void);
static void i_add_ald8(void);
static void i_add_axd16(void);
static void i_push_es(void);
static void i_pop_es(void);
static void i_or_br8(void);
static void i_or_r8b(void);
static void i_or_wr16(void);
static void i_or_r16w(void);
static void i_or_ald8(void);
static void i_or_axd16(void);
static void i_push_cs(void);
static void i_pre_nec(void);
static void i_adc_br8(void);
static void i_adc_wr16(void);
static void i_adc_r8b(void);
static void i_adc_r16w(void);
static void i_adc_ald8(void);
static void i_adc_axd16(void);
static void i_push_ss(void);
static void i_pop_ss(void);
static void i_sbb_br8(void);
static void i_sbb_wr16(void);
static void i_sbb_r8b(void);
static void i_sbb_r16w(void);
static void i_sbb_ald8(void);
static void i_sbb_axd16(void);
static void i_push_ds(void);
static void i_pop_ds(void);
static void i_and_br8(void);
static void i_and_r8b(void);
static void i_and_wr16(void);
static void i_and_r16w(void);
static void i_and_ald8(void);
static void i_and_axd16(void);
static void i_es(void);
static void i_daa(void);
static void i_sub_br8(void);
static void i_sub_wr16(void);
static void i_sub_r8b(void);
static void i_sub_r16w(void);
static void i_sub_ald8(void);
static void i_sub_axd16(void);
static void i_cs(void);
static void i_das(void);
static void i_xor_br8(void);
static void i_xor_r8b(void);
static void i_xor_wr16(void);
static void i_xor_r16w(void);
static void i_xor_ald8(void);
static void i_xor_axd16(void);
static void i_ss(void);
static void i_aaa(void);
static void i_cmp_br8(void);
static void i_cmp_wr16(void);
static void i_cmp_r8b(void);
static void i_cmp_r16w(void);
static void i_cmp_ald8(void);
static void i_cmp_axd16(void);
static void i_ds(void);
static void i_aas(void);
static void i_inc_ax(void);
static void i_inc_cx(void);
static void i_inc_dx(void);
static void i_inc_bx(void);
static void i_inc_sp(void);
static void i_inc_bp(void);
static void i_inc_si(void);
static void i_inc_di(void);
static void i_dec_ax(void);
static void i_dec_cx(void);
static void i_dec_dx(void);
static void i_dec_bx(void);
static void i_dec_sp(void);
static void i_dec_bp(void);
static void i_dec_si(void);
static void i_dec_di(void);
static void i_push_ax(void);
static void i_push_cx(void);
static void i_push_dx(void);
static void i_push_bx(void);
static void i_push_sp(void);
static void i_push_bp(void);
static void i_push_si(void);
static void i_push_di(void);
static void i_pop_ax(void);
static void i_pop_cx(void);
static void i_pop_dx(void);
static void i_pop_bx(void);
static void i_pop_sp(void);
static void i_pop_bp(void);
static void i_pop_si(void);
static void i_pop_di(void);
static void i_pusha(void);
static void i_popa(void);
static void i_chkind(void);
static void i_repnc(void);
static void i_repc(void);
static void i_push_d16(void);
static void i_imul_d16(void);
static void i_push_d8(void);
static void i_imul_d8(void);
static void i_insb(void);
static void i_insw(void);
static void i_outsb(void);
static void i_outsw(void);
static void i_jo(void);
static void i_jno(void);
static void i_jc(void);
static void i_jnc(void);
static void i_jz(void);
static void i_jnz(void);
static void i_jce(void);
static void i_jnce(void);
static void i_js(void);
static void i_jns(void);
static void i_jp(void);
static void i_jnp(void);
static void i_jl(void);
static void i_jnl(void);
static void i_jle(void);
static void i_jnle(void);
static void i_80pre(void);
static void i_82pre(void);
static void i_81pre(void);
static void i_83pre(void);
static void i_test_br8(void);
static void i_test_wr16(void);
static void i_xchg_br8(void);
static void i_xchg_wr16(void);
static void i_mov_br8(void);
static void i_mov_r8b(void);
static void i_mov_wr16(void);
static void i_mov_r16w(void);
static void i_mov_wsreg(void);
static void i_lea(void);
static void i_mov_sregw(void);
static void i_invalid(void);
static void i_popw(void);
static void i_nop(void);
static void i_xchg_axcx(void);
static void i_xchg_axdx(void);
static void i_xchg_axbx(void);
static void i_xchg_axsp(void);
static void i_xchg_axbp(void);
static void i_xchg_axsi(void);
static void i_xchg_axdi(void);
static void i_cbw(void);
static void i_cwd(void);
static void i_call_far(void);
static void i_pushf(void);
static void i_popf(void);
static void i_sahf(void);
static void i_lahf(void);
static void i_mov_aldisp(void);
static void i_mov_axdisp(void);
static void i_mov_dispal(void);
static void i_mov_dispax(void);
static void i_movsb(void);
static void i_movsw(void);
static void i_cmpsb(void);
static void i_cmpsw(void);
static void i_test_ald8(void);
static void i_test_axd16(void);
static void i_stosb(void);
static void i_stosw(void);
static void i_lodsb(void);
static void i_lodsw(void);
static void i_scasb(void);
static void i_scasw(void);
static void i_mov_ald8(void);
static void i_mov_cld8(void);
static void i_mov_dld8(void);
static void i_mov_bld8(void);
static void i_mov_ahd8(void);
static void i_mov_chd8(void);
static void i_mov_dhd8(void);
static void i_mov_bhd8(void);
static void i_mov_axd16(void);
static void i_mov_cxd16(void);
static void i_mov_dxd16(void);
static void i_mov_bxd16(void);
static void i_mov_spd16(void);
static void i_mov_bpd16(void);
static void i_mov_sid16(void);
static void i_mov_did16(void);
static void i_rotshft_bd8(void);
static void i_rotshft_wd8(void);
static void i_ret_d16(void);
static void i_ret(void);
static void i_les_dw(void);
static void i_lds_dw(void);
static void i_mov_bd8(void);
static void i_mov_wd16(void);
static void i_enter(void);
static void i_leave(void);
static void i_retf_d16(void);
static void i_retf(void);
static void i_int3(void);
static void i_int(void);
static void i_into(void);
static void i_iret(void);
static void i_rotshft_b(void);
static void i_rotshft_w(void);
static void i_rotshft_bcl(void);
static void i_rotshft_wcl(void);
static void i_aam(void);
static void i_aad(void);
static void i_setalc(void);
static void i_trans(void);
static void i_fpo(void);
static void i_loopne(void);
static void i_loope(void);
static void i_loop(void);
static void i_jcxz(void);
static void i_inal(void);
static void i_inax(void);
static void i_outal(void);
static void i_outax(void);
static void i_call_d16(void);
static void i_jmp_d16(void);
static void i_jmp_far(void);
static void i_jmp_d8(void);
static void i_inaldx(void);
static void i_inaxdx(void);
static void i_outdxal(void);
static void i_outdxax(void);
static void i_lock(void);
static void i_repne(void);
static void i_repe(void);
static void i_hlt(void);
static void i_cmc(void);
static void i_f6pre(void);
static void i_f7pre(void);
static void i_clc(void);
static void i_stc(void);
static void i_di(void);
static void i_ei(void);
static void i_cld(void);
static void i_std(void);
static void i_fepre(void);
static void i_ffpre(void);
static void i_wait(void);
void (*nec_instruction[256])(void) =
{
i_add_br8, /* 0x00 */
i_add_wr16, /* 0x01 */
i_add_r8b, /* 0x02 */
i_add_r16w, /* 0x03 */
i_add_ald8, /* 0x04 */
i_add_axd16, /* 0x05 */
i_push_es, /* 0x06 */
i_pop_es, /* 0x07 */
i_or_br8, /* 0x08 */
i_or_wr16, /* 0x09 */
i_or_r8b, /* 0x0a */
i_or_r16w, /* 0x0b */
i_or_ald8, /* 0x0c */
i_or_axd16, /* 0x0d */
i_push_cs, /* 0x0e */
i_pre_nec /* 0x0f */,
i_adc_br8, /* 0x10 */
i_adc_wr16, /* 0x11 */
i_adc_r8b, /* 0x12 */
i_adc_r16w, /* 0x13 */
i_adc_ald8, /* 0x14 */
i_adc_axd16, /* 0x15 */
i_push_ss, /* 0x16 */
i_pop_ss, /* 0x17 */
i_sbb_br8, /* 0x18 */
i_sbb_wr16, /* 0x19 */
i_sbb_r8b, /* 0x1a */
i_sbb_r16w, /* 0x1b */
i_sbb_ald8, /* 0x1c */
i_sbb_axd16, /* 0x1d */
i_push_ds, /* 0x1e */
i_pop_ds, /* 0x1f */
i_and_br8, /* 0x20 */
i_and_wr16, /* 0x21 */
i_and_r8b, /* 0x22 */
i_and_r16w, /* 0x23 */
i_and_ald8, /* 0x24 */
i_and_axd16, /* 0x25 */
i_es, /* 0x26 */
i_daa, /* 0x27 */
i_sub_br8, /* 0x28 */
i_sub_wr16, /* 0x29 */
i_sub_r8b, /* 0x2a */
i_sub_r16w, /* 0x2b */
i_sub_ald8, /* 0x2c */
i_sub_axd16, /* 0x2d */
i_cs, /* 0x2e */
i_das, /* 0x2f */
i_xor_br8, /* 0x30 */
i_xor_wr16, /* 0x31 */
i_xor_r8b, /* 0x32 */
i_xor_r16w, /* 0x33 */
i_xor_ald8, /* 0x34 */
i_xor_axd16, /* 0x35 */
i_ss, /* 0x36 */
i_aaa, /* 0x37 */
i_cmp_br8, /* 0x38 */
i_cmp_wr16, /* 0x39 */
i_cmp_r8b, /* 0x3a */
i_cmp_r16w, /* 0x3b */
i_cmp_ald8, /* 0x3c */
i_cmp_axd16, /* 0x3d */
i_ds, /* 0x3e */
i_aas, /* 0x3f */
i_inc_ax, /* 0x40 */
i_inc_cx, /* 0x41 */
i_inc_dx, /* 0x42 */
i_inc_bx, /* 0x43 */
i_inc_sp, /* 0x44 */
i_inc_bp, /* 0x45 */
i_inc_si, /* 0x46 */
i_inc_di, /* 0x47 */
i_dec_ax, /* 0x48 */
i_dec_cx, /* 0x49 */
i_dec_dx, /* 0x4a */
i_dec_bx, /* 0x4b */
i_dec_sp, /* 0x4c */
i_dec_bp, /* 0x4d */
i_dec_si, /* 0x4e */
i_dec_di, /* 0x4f */
i_push_ax, /* 0x50 */
i_push_cx, /* 0x51 */
i_push_dx, /* 0x52 */
i_push_bx, /* 0x53 */
i_push_sp, /* 0x54 */
i_push_bp, /* 0x55 */
i_push_si, /* 0x56 */
i_push_di, /* 0x57 */
i_pop_ax, /* 0x58 */
i_pop_cx, /* 0x59 */
i_pop_dx, /* 0x5a */
i_pop_bx, /* 0x5b */
i_pop_sp, /* 0x5c */
i_pop_bp, /* 0x5d */
i_pop_si, /* 0x5e */
i_pop_di, /* 0x5f */
i_pusha, /* 0x60 */
i_popa, /* 0x61 */
i_chkind, /* 0x62 */
i_invalid, /* 0x63 */
i_repnc, /* 0x64 */
i_repc, /* 0x65 */
i_invalid, /* 0x66 */
i_invalid, /* 0x67 */
i_push_d16, /* 0x68 */
i_imul_d16, /* 0x69 */
i_push_d8, /* 0x6a */
i_imul_d8, /* 0x6b */
i_insb, /* 0x6c */
i_insw, /* 0x6d */
i_outsb, /* 0x6e */
i_outsw, /* 0x6f */
i_jo, /* 0x70 */
i_jno, /* 0x71 */
i_jc, /* 0x72 */
i_jnc, /* 0x73 */
i_jz, /* 0x74 */
i_jnz, /* 0x75 */
i_jce, /* 0x76 */
i_jnce, /* 0x77 */
i_js, /* 0x78 */
i_jns, /* 0x79 */
i_jp, /* 0x7a */
i_jnp, /* 0x7b */
i_jl, /* 0x7c */
i_jnl, /* 0x7d */
i_jle, /* 0x7e */
i_jnle, /* 0x7f */
i_80pre, /* 0x80 */
i_81pre, /* 0x81 */
i_82pre, /* 0x82 */
i_83pre, /* 0x83 */
i_test_br8, /* 0x84 */
i_test_wr16, /* 0x85 */
i_xchg_br8, /* 0x86 */
i_xchg_wr16, /* 0x87 */
i_mov_br8, /* 0x88 */
i_mov_wr16, /* 0x89 */
i_mov_r8b, /* 0x8a */
i_mov_r16w, /* 0x8b */
i_mov_wsreg, /* 0x8c */
i_lea, /* 0x8d */
i_mov_sregw, /* 0x8e */
i_popw, /* 0x8f */
i_nop, /* 0x90 */
i_xchg_axcx, /* 0x91 */
i_xchg_axdx, /* 0x92 */
i_xchg_axbx, /* 0x93 */
i_xchg_axsp, /* 0x94 */
i_xchg_axbp, /* 0x95 */
i_xchg_axsi, /* 0x97 */
i_xchg_axdi, /* 0x97 */
i_cbw, /* 0x98 */
i_cwd, /* 0x99 */
i_call_far, /* 0x9a */
i_wait, /* 0x9b */
i_pushf, /* 0x9c */
i_popf, /* 0x9d */
i_sahf, /* 0x9e */
i_lahf, /* 0x9f */
i_mov_aldisp, /* 0xa0 */
i_mov_axdisp, /* 0xa1 */
i_mov_dispal, /* 0xa2 */
i_mov_dispax, /* 0xa3 */
i_movsb, /* 0xa4 */
i_movsw, /* 0xa5 */
i_cmpsb, /* 0xa6 */
i_cmpsw, /* 0xa7 */
i_test_ald8, /* 0xa8 */
i_test_axd16, /* 0xa9 */
i_stosb, /* 0xaa */
i_stosw, /* 0xab */
i_lodsb, /* 0xac */
i_lodsw, /* 0xad */
i_scasb, /* 0xae */
i_scasw, /* 0xaf */
i_mov_ald8, /* 0xb0 */
i_mov_cld8, /* 0xb1 */
i_mov_dld8, /* 0xb2 */
i_mov_bld8, /* 0xb3 */
i_mov_ahd8, /* 0xb4 */
i_mov_chd8, /* 0xb5 */
i_mov_dhd8, /* 0xb6 */
i_mov_bhd8, /* 0xb7 */
i_mov_axd16, /* 0xb8 */
i_mov_cxd16, /* 0xb9 */
i_mov_dxd16, /* 0xba */
i_mov_bxd16, /* 0xbb */
i_mov_spd16, /* 0xbc */
i_mov_bpd16, /* 0xbd */
i_mov_sid16, /* 0xbe */
i_mov_did16, /* 0xbf */
i_rotshft_bd8, /* 0xc0 */
i_rotshft_wd8, /* 0xc1 */
i_ret_d16, /* 0xc2 */
i_ret, /* 0xc3 */
i_les_dw, /* 0xc4 */
i_lds_dw, /* 0xc5 */
i_mov_bd8, /* 0xc6 */
i_mov_wd16, /* 0xc7 */
i_enter, /* 0xc8 */
i_leave, /* 0xc9 */
i_retf_d16, /* 0xca */
i_retf, /* 0xcb */
i_int3, /* 0xcc */
i_int, /* 0xcd */
i_into, /* 0xce */
i_iret, /* 0xcf */
i_rotshft_b, /* 0xd0 */
i_rotshft_w, /* 0xd1 */
i_rotshft_bcl, /* 0xd2 */
i_rotshft_wcl, /* 0xd3 */
i_aam, /* 0xd4 */
i_aad, /* 0xd5 */
i_setalc,
i_trans, /* 0xd7 */
i_fpo, /* 0xd8 */
i_fpo, /* 0xd9 */
i_fpo, /* 0xda */
i_fpo, /* 0xdb */
i_fpo, /* 0xdc */
i_fpo, /* 0xdd */
i_fpo, /* 0xde */
i_fpo, /* 0xdf */
i_loopne, /* 0xe0 */
i_loope, /* 0xe1 */
i_loop, /* 0xe2 */
i_jcxz, /* 0xe3 */
i_inal, /* 0xe4 */
i_inax, /* 0xe5 */
i_outal, /* 0xe6 */
i_outax, /* 0xe7 */
i_call_d16, /* 0xe8 */
i_jmp_d16, /* 0xe9 */
i_jmp_far, /* 0xea */
i_jmp_d8, /* 0xeb */
i_inaldx, /* 0xec */
i_inaxdx, /* 0xed */
i_outdxal, /* 0xee */
i_outdxax, /* 0xef */
i_lock, /* 0xf0 */
i_invalid, /* 0xf1 */
i_repne, /* 0xf2 */
i_repe, /* 0xf3 */
i_hlt, /* 0xf4 */
i_cmc, /* 0xf5 */
i_f6pre, /* 0xf6 */
i_f7pre, /* 0xf7 */
i_clc, /* 0xf8 */
i_stc, /* 0xf9 */
i_di, /* 0xfa */
i_ei, /* 0xfb */
i_cld, /* 0xfc */
i_std, /* 0xfd */
i_fepre, /* 0xfe */
i_ffpre /* 0xff */
};

77
source/nec/necintrf.h Normal file
View File

@@ -0,0 +1,77 @@
/* ASG 971222 -- rewrote this interface */
#ifndef __NECITRF_H_
#define __NECITRF_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 */
/*
#define v20_ICount nec_ICount
extern void v20_init(void);
extern void v20_reset(void *param);
extern void v20_exit(void);
extern int v20_execute(int cycles);
extern unsigned v20_get_context(void *dst);
extern void v20_set_context(void *src);
extern unsigned v20_get_reg(int regnum);
extern void v20_set_reg(int regnum, unsigned val);
extern void v20_set_irq_line(int irqline, int state);
extern void v20_set_irq_callback(int (*callback)(int irqline));
extern const char *v20_info(void *context, int regnum);
extern unsigned v20_dasm(char *buffer, unsigned pc);
#define v30_ICount nec_ICount
extern void v30_init(void);
extern void v30_reset(void *param);
extern void v30_exit(void);
extern int v30_execute(int cycles);
extern unsigned v30_get_context(void *dst);
extern void v30_set_context(void *src);
extern unsigned v30_get_reg(int regnum);
extern void v30_set_reg(int regnum, unsigned val);
extern void v30_set_irq_line(int irqline, int state);
extern void v30_set_irq_callback(int (*callback)(int irqline));
extern const char *v30_info(void *context, int regnum);
extern unsigned v30_dasm(char *buffer, unsigned pc);
#define v33_ICount nec_ICount
extern void v33_init(void);
extern void v33_reset(void *param);
extern void v33_exit(void);
extern int v33_execute(int cycles);
extern unsigned v33_get_context(void *dst);
extern void v33_set_context(void *src);
extern unsigned v33_get_reg(int regnum);
extern void v33_set_reg(int regnum, unsigned val);
extern void v33_set_irq_line(int irqline, int state);
extern void v33_set_irq_callback(int (*callback)(int irqline));
extern const char *v33_info(void *context, int regnum);
extern unsigned v33_dasm(char *buffer, unsigned pc);
*/
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);
uint8_t cpu_readport(uint8_t);
void cpu_writeport(uint32_t, uint8_t);
#define cpu_readop cpu_readmem20
#define cpu_readop_arg cpu_readmem20
void cpu_writemem20(uint32_t, uint8_t);
uint8_t cpu_readmem20(uint32_t);
#endif /* __NECITRF_H_ */

107
source/nec/necmodrm.h Normal file
View File

@@ -0,0 +1,107 @@
static struct
{
struct
{
WREGS w[256];
BREGS b[256];
} reg;
struct
{
WREGS w[256];
BREGS b[256];
} RM;
} Mod_RM;
#define RegWord(ModRM) I.regs.w[Mod_RM.reg.w[ModRM]]
#define RegByte(ModRM) I.regs.b[Mod_RM.reg.b[ModRM]]
#define GetRMWord(ModRM) \
((ModRM) >= 0xc0 ? I.regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(), ReadWord( EA ) ))
#define PutbackRMWord(ModRM,val) \
{ \
if (ModRM >= 0xc0) I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
else WriteWord(EA,val); \
}
#define GetnextRMWord ReadWord((EA&0xf0000)|((EA+2)&0xffff))
#define PutRMWord(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
I.regs.w[Mod_RM.RM.w[ModRM]]=val; \
else { \
(*GetEA[ModRM])(); \
WriteWord( EA ,val); \
} \
}
#define PutImmRMWord(ModRM) \
{ \
int16_t val; \
if (ModRM >= 0xc0) \
FETCHWORD(I.regs.w[Mod_RM.RM.w[ModRM]]) \
else { \
(*GetEA[ModRM])(); \
FETCHWORD(val) \
WriteWord( EA , val); \
} \
}
#define GetRMByte(ModRM) \
((ModRM) >= 0xc0 ? I.regs.b[Mod_RM.RM.b[ModRM]] : ReadByte( (*GetEA[ModRM])() ))
#define PutRMByte(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
else \
WriteByte( (*GetEA[ModRM])() ,val); \
}
#define PutImmRMByte(ModRM) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \
else { \
(*GetEA[ModRM])(); \
WriteByte( EA , FETCH ); \
} \
}
#define PutbackRMByte(ModRM,val) \
{ \
if (ModRM >= 0xc0) \
I.regs.b[Mod_RM.RM.b[ModRM]]=val; \
else \
WriteByte(EA,val); \
}
#define DEF_br8 \
uint32_t ModRM = FETCH,src,dst; \
src = RegByte(ModRM); \
dst = GetRMByte(ModRM)
#define DEF_wr16 \
uint32_t ModRM = FETCH,src,dst; \
src = RegWord(ModRM); \
dst = GetRMWord(ModRM)
#define DEF_r8b \
uint32_t ModRM = FETCH,src,dst; \
dst = RegByte(ModRM); \
src = GetRMByte(ModRM)
#define DEF_r16w \
uint32_t ModRM = FETCH,src,dst; \
dst = RegWord(ModRM); \
src = GetRMWord(ModRM)
#define DEF_ald8 \
uint32_t src = FETCH; \
uint32_t dst = I.regs.b[AL]
#define DEF_axd16 \
uint32_t src = FETCH; \
uint32_t dst = I.regs.w[AW]; \
src += (FETCH << 8)

214
source/rom.cpp Normal file
View File

@@ -0,0 +1,214 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "log.h"
#include "rom.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t *ws_rom_load(char *path, uint32_t *romSize)
{
int fd;
uint8_t *ret_ptr;
struct stat FileStat;
fd = open(path, O_RDWR);
fstat(fd, &FileStat);
*romSize = FileStat.st_size;
ret_ptr = (uint8_t *)mmap(NULL, FileStat.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
if (ret_ptr == MAP_FAILED)
{
ret_ptr = NULL;
*romSize = 0;
}
return ret_ptr;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_rom_dumpInfo(uint8_t *wsrom, uint32_t romSize)
{
ws_romHeaderStruct *romHeader=ws_rom_getHeader(wsrom,romSize);
fprintf(log_get(),"rom: developper Id 0x%.2x\n",romHeader->developperId);
fprintf(log_get(),"rom: cart Id 0x%.2x\n",romHeader->cartId);
fprintf(log_get(),"rom: minimum system %s\n",(romHeader->minimumSupportSystem==WS_SYSTEM_MONO)?"Wonderswan mono":"Wonderswan color");
fprintf(log_get(),"rom: size %i Mbits\n",(romSize>>20)<<3);
fprintf(log_get(),"rom: eeprom ");
switch (romHeader->eepromSize&0xf)
{
case WS_EEPROM_SIZE_NONE:
{
fprintf(log_get(),"none\n");
break;
}
case WS_EEPROM_SIZE_64k:
{
fprintf(log_get(),"64 kb\n");
break;
}
case WS_EEPROM_SIZE_256k:
{
fprintf(log_get(),"256 kb\n");
break;
}
}
fprintf(log_get(),"rom: sram ");
switch (romHeader->eepromSize&0xf0)
{
case WS_SRAM_SIZE_NONE:
{
fprintf(log_get(),"none\n");
break;
}
case WS_SRAM_SIZE_1k:
{
fprintf(log_get(),"1 kb\n");
break;
}
case WS_SRAM_SIZE_16k:
{
fprintf(log_get(),"16 kb\n");
break;
}
case WS_SRAM_SIZE_8k:
{
fprintf(log_get(),"8 kn\n");
break;
}
}
fprintf(log_get(),"rom: rtc %s\n",(romHeader->realtimeClock)?"Yes":"None");
fprintf(log_get(),"checksum 0x%.4x\n",romHeader->checksum);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
ws_romHeaderStruct *ws_rom_getHeader(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *wsromHeader = (ws_romHeaderStruct *)(wsrom + wsromSize - 10);
return(wsromHeader);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_rom_sramSize(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *romHeader=ws_rom_getHeader(wsrom,wsromSize);
switch (romHeader->eepromSize&0xf0)
{
case WS_SRAM_SIZE_NONE:
return(0);
case WS_SRAM_SIZE_1k:
return(0x400);
case WS_SRAM_SIZE_16k:
return(0x4000);
case WS_SRAM_SIZE_8k:
return(0x2000);
}
return(0);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_rom_eepromSize(uint8_t *wsrom, uint32_t wsromSize)
{
ws_romHeaderStruct *romHeader=ws_rom_getHeader(wsrom,wsromSize);
switch (romHeader->eepromSize&0xf)
{
case WS_EEPROM_SIZE_NONE:
return(0);
case WS_EEPROM_SIZE_64k:
return(0x10000);
case WS_EEPROM_SIZE_256k:
return(0x40000);
}
return(0);
}

57
source/rom.h Normal file
View File

@@ -0,0 +1,57 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __ROM_H__
#define __ROM_H__
#define WS_SYSTEM_MONO 0
#define WS_SYSTEM_COLOR 1
#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_SRAM_SIZE_NONE 0
#define WS_EEPROM_SIZE_64k 1
#define WS_EEPROM_SIZE_256k 2
#define WS_SRAM_SIZE_1k 10
#define WS_SRAM_SIZE_16k 20
#define WS_SRAM_SIZE_8k 50
typedef struct ws_romHeaderStruct
{
uint8_t developperId;
uint8_t minimumSupportSystem;
uint8_t cartId;
uint8_t romSize;
uint8_t eepromSize;
uint8_t additionnalCapabilities;
uint8_t realtimeClock;
uint16_t checksum;
} ws_romHeaderStruct;
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);
#endif

522
source/ws.cpp Normal file
View File

@@ -0,0 +1,522 @@
////////////////////////////////////////////////////////////////////////////////
// Wonderswan emulator
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
// 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>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "./nec/necintrf.h"
#include "memory.h"
#include "gpu.h"
#include "io.h"
#include "audio.h"
#include "ws.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32_t ws_cycles;
uint32_t ws_skip;
uint32_t ws_cyclesByLine=0;
uint32_t vblank_count=0;
char *ws_sram_path = NULL;
char *ws_ieep_path = NULL;
char *ws_rom_path = NULL;
extern int ws_gpu_forceColorSystemBool;
extern int ws_gpu_forceMonoSystemBool;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_patchRom(void)
{
uint8_t *rom=memory_getRom();
uint32_t romSize=memory_getRomSize();
fprintf(log_get(),"developper Id: 0x%.2x\nGame Id: 0x%.2x\n",rom[romSize-10],rom[romSize-8]);
if (!ws_cyclesByLine)
{
ws_cyclesByLine=256;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_init(char *rompath)
{
uint8_t *rom;
uint32_t romSize;
if ((rom=ws_rom_load(rompath,&romSize))==NULL)
{
printf("Error: cannot load %s\n",rompath);
return(0);
}
if ((ws_gpu_forceColorSystemBool == 0) && (ws_gpu_forceMonoSystemBool == 0))
{
/* Nothing forced try to "auto detect" */
if (rompath[strlen(rompath)-1]=='c')
{
ws_gpu_operatingInColor=1;
}
else
{
ws_gpu_operatingInColor=0;
}
}
ws_memory_init(rom, romSize);
ws_patchRom();
ws_staticRam = (uint8_t *)load_file(ws_ieep_path);
if (ws_staticRam == NULL)
{
ws_staticRam = (uint8_t *)create_file(ws_sram_path, 0x10000);
}
if (ws_staticRam == NULL)
{
printf("Card SRAM load error!\n");
return 0;
}
externalEeprom = (uint8_t *)load_file(ws_ieep_path);
if (externalEeprom == NULL)
{
externalEeprom = (uint8_t *)create_file(ws_ieep_path, 0x100000);
}
if (externalEeprom == NULL)
{
printf("Card EEPROM load error!\n");
return 0;
}
ws_io_init();
ws_audio_init();
ws_gpu_init();
if (ws_rotated())
{
ws_io_flipControls();
}
return(1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_reset(void)
{
ws_memory_reset();
ws_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();
// update scanline register
ws_ioRam[2]=ws_gpu_scanline;
ws_cycles=nec_execute((ws_cyclesByLine>>1)+(rand()&7));
ws_cycles+=nec_execute((ws_cyclesByLine>>1)+(rand()&7));
if(ws_cycles>=ws_cyclesByLine+ws_cyclesByLine)
{
ws_skip=ws_cycles/ws_cyclesByLine;
}
else
{
ws_skip=1;
}
ws_cycles%=ws_cyclesByLine;
for(uint32_t uI=0; uI<ws_skip; uI++)
{
if (renderLine)
{
ws_gpu_renderScanline(framebuffer);
}
ws_gpu_scanline++;
if(ws_gpu_scanline==144)
{
drawWholeScreen=1;
}
}
if(ws_gpu_scanline>158)
{
ws_gpu_scanline=0;
{
if((ws_ioRam[0xb2]&32)) /* VBLANK Timer */
{
/* TODO: REPAIR THAT SHIT */
ws_ioRam[0xb6]&=~32;
nec_int((ws_ioRam[0xb0]+5)*4);
}
}
}
ws_ioRam[2]=ws_gpu_scanline;
if(drawWholeScreen)
{
if(ws_ioRam[0xb2]&64) /* VBLANK INT */
{
ws_ioRam[0xb6]&=~64;
nec_int((ws_ioRam[0xb0]+6)*4);
}
vblank_count++;
}
if(ws_ioRam[0xa4]&&(ws_ioRam[0xb2]&128)) /*HBLANK TMR*/
{
/* TODO: Check that shit */
if(!ws_ioRam[0xa5])
{
ws_ioRam[0xa5]=ws_ioRam[0xa4];
}
if(ws_ioRam[0xa5])
{
ws_ioRam[0xa5]--;
}
if((!ws_ioRam[0xa5])&&(ws_ioRam[0xb2]&128))
{
ws_ioRam[0xb6]&=~128;
nec_int((ws_ioRam[0xb0]+7)*4);
}
}
if((ws_ioRam[0x2]==ws_ioRam[0x3])&&(ws_ioRam[0xb2]&16)) /*SCANLINE INT*/
{
ws_ioRam[0xb6]&=~16;
nec_int((ws_ioRam[0xb0]+4)*4);
}
return(drawWholeScreen);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_done(void)
{
ws_memory_done();
ws_io_done();
ws_audio_done();
ws_gpu_done();
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_set_colour_scheme(int scheme)
{
ws_gpu_set_colour_scheme(scheme);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_set_system(int system)
{
if (system==WS_SYSTEM_COLOR)
{
ws_gpu_forceColorSystem();
}
else if (system==WS_SYSTEM_MONO)
{
ws_gpu_forceMonoSystem();
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define MacroLoadNecRegisterFromFile(F,R) \
read(fp,&value,sizeof(value)); \
nec_set_reg(R,value);
int ws_loadState(char *statepath)
{
fprintf(log_get(),"loading %s\n",statepath);
uint16_t crc=memory_getRomCrc();
uint16_t newCrc;
unsigned value;
uint8_t ws_newVideoMode;
int fp = open(statepath, O_RDONLY);
if (fp == -1)
{
return(0);
}
read(fp, &newCrc, 2);
if (newCrc!=crc)
{
return(-1);
}
MacroLoadNecRegisterFromFile(fp,NEC_IP);
MacroLoadNecRegisterFromFile(fp,NEC_AW);
MacroLoadNecRegisterFromFile(fp,NEC_BW);
MacroLoadNecRegisterFromFile(fp,NEC_CW);
MacroLoadNecRegisterFromFile(fp,NEC_DW);
MacroLoadNecRegisterFromFile(fp,NEC_CS);
MacroLoadNecRegisterFromFile(fp,NEC_DS);
MacroLoadNecRegisterFromFile(fp,NEC_ES);
MacroLoadNecRegisterFromFile(fp,NEC_SS);
MacroLoadNecRegisterFromFile(fp,NEC_IX);
MacroLoadNecRegisterFromFile(fp,NEC_IY);
MacroLoadNecRegisterFromFile(fp,NEC_BP);
MacroLoadNecRegisterFromFile(fp,NEC_SP);
MacroLoadNecRegisterFromFile(fp,NEC_FLAGS);
MacroLoadNecRegisterFromFile(fp,NEC_VECTOR);
MacroLoadNecRegisterFromFile(fp,NEC_PENDING);
MacroLoadNecRegisterFromFile(fp,NEC_NMI_STATE);
MacroLoadNecRegisterFromFile(fp,NEC_IRQ_STATE);
read(fp,internalRam,65536);
read(fp,ws_staticRam,65536);
read(fp,ws_ioRam,256);
read(fp,ws_paletteColors,8);
read(fp,ws_palette,16*4*2);
read(fp,wsc_palette,16*16*2);
read(fp,&ws_newVideoMode,1);
read(fp,&ws_gpu_scanline,1);
read(fp,externalEeprom,131072);
ws_audio_readState(fp);
close(fp);
// force a video mode change to make all tiles dirty
ws_gpu_clearCache();
return(1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define MacroStoreNecRegisterToFile(F,R) \
value=nec_get_reg(R); \
write(fp,&value,sizeof(value));
int ws_saveState(char *statepath)
{
uint16_t crc=memory_getRomCrc();
uint32_t value;
char *newPath;
fprintf(log_get(),"saving %s\n",statepath);
newPath=new char[1024];
if (strlen(statepath)<4)
{
sprintf(newPath,"%s.wss",statepath);
}
else
{
int len=strlen(statepath);
if ((statepath[len-1]!='s')&&(statepath[len-1]!='S'))
{
sprintf(newPath,"%s.wss",statepath);
}
else if ((statepath[len-2]!='s')&&(statepath[len-2]!='S'))
{
sprintf(newPath,"%s.wss",statepath);
}
else if ((statepath[len-3]!='w')&&(statepath[len-3]!='w'))
{
sprintf(newPath,"%s.wss",statepath);
}
else if (statepath[len-4]!='.')
{
sprintf(newPath,"%s.wss",statepath);
}
else
{
sprintf(newPath,"%s",statepath);
}
}
int fp=open(newPath, O_RDWR|O_CREAT);
delete newPath;
if (fp==-1)
{
return(0);
}
write(fp,&crc,2);
MacroStoreNecRegisterToFile(fp,NEC_IP);
MacroStoreNecRegisterToFile(fp,NEC_AW);
MacroStoreNecRegisterToFile(fp,NEC_BW);
MacroStoreNecRegisterToFile(fp,NEC_CW);
MacroStoreNecRegisterToFile(fp,NEC_DW);
MacroStoreNecRegisterToFile(fp,NEC_CS);
MacroStoreNecRegisterToFile(fp,NEC_DS);
MacroStoreNecRegisterToFile(fp,NEC_ES);
MacroStoreNecRegisterToFile(fp,NEC_SS);
MacroStoreNecRegisterToFile(fp,NEC_IX);
MacroStoreNecRegisterToFile(fp,NEC_IY);
MacroStoreNecRegisterToFile(fp,NEC_BP);
MacroStoreNecRegisterToFile(fp,NEC_SP);
MacroStoreNecRegisterToFile(fp,NEC_FLAGS);
MacroStoreNecRegisterToFile(fp,NEC_VECTOR);
MacroStoreNecRegisterToFile(fp,NEC_PENDING);
MacroStoreNecRegisterToFile(fp,NEC_NMI_STATE);
MacroStoreNecRegisterToFile(fp,NEC_IRQ_STATE);
write(fp,internalRam,65536);
write(fp,ws_staticRam,65536);
write(fp,ws_ioRam,256);
write(fp,ws_paletteColors,8);
write(fp,ws_palette,16*4*2);
write(fp,wsc_palette,16*16*2);
write(fp,&ws_videoMode,1);
write(fp,&ws_gpu_scanline,1);
write(fp,externalEeprom,131072);
ws_audio_writeState(fp);
close(fp);
return(1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_rotated(void)
{
uint8_t *rom=memory_getRom();
uint32_t romSize=memory_getRomSize();
return(rom[romSize-4]&1);
}

37
source/ws.h Normal file
View File

@@ -0,0 +1,37 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __WS_H__
#define __WS_H__
#define WS_SYSTEM_MONO 0
#define WS_SYSTEM_COLOR 1
#define WS_SYSTEM_AUTODETECT 2
extern uint32_t ws_cyclesByLine;
int ws_init(char *rompath);
int ws_rotated(void);
void ws_set_colour_scheme(int scheme);
void ws_set_system(int 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