Initial Commit

This commit is contained in:
Godzil
2019-09-01 21:43:40 +01:00
commit 56b69d2281
176 changed files with 41262 additions and 0 deletions

773
oswan/source/2xSaI.cpp Normal file
View File

@@ -0,0 +1,773 @@
/*
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
*
* (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and
* Jerremy Koot (jkoot@snes9x.com)
*
* Super FX C emulator code
* (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and
* Gary Henderson.
* Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
*
* DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
* C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
* C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk).
*
* DOS port code contains the works of other authors. See headers in
* individual files.
*
* Snes9x homepage: www.snes9x.com
*
* Permission to use, copy, modify and distribute Snes9x in both binary and
* source form, for non-commercial purposes, is hereby granted without fee,
* providing that this license information and copyright notice appear with
* all copies and any derived work.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event shall the authors be held liable for any damages
* arising from the use of this software.
*
* Snes9x is freeware for PERSONAL USE only. Commercial users should
* seek permission of the copyright holders first. Commercial use includes
* charging money for Snes9x or software derived from Snes9x.
*
* The copyright holders request that bug fixes and improvements to the code
* should be forwarded to them so everyone can benefit from the modifications
* in future versions.
*
* Super NES and Super Nintendo Entertainment System are trademarks of
* Nintendo Co., Limited and its subsidiary companies.
*/
#include "types.h"
#include "2xSaI.h"
static u32 colorMask = 0xF7DEF7DE;
static u32 lowPixelMask = 0x08210821;
static u32 qcolorMask = 0xE79CE79C;
static u32 qlowpixelMask = 0x18631863;
static u32 redblueMask = 0xF81F;
static u32 greenMask = 0x7E0;
int Init_2xSaI(u32 BitFormat)
{
if (BitFormat == 565) {
colorMask = 0xF7DEF7DE;
lowPixelMask = 0x08210821;
qcolorMask = 0xE79CE79C;
qlowpixelMask = 0x18631863;
redblueMask = 0xF81F;
greenMask = 0x7E0;
} else if (BitFormat == 555) {
colorMask = 0x7BDE7BDE;
lowPixelMask = 0x04210421;
qcolorMask = 0x739C739C;
qlowpixelMask = 0x0C630C63;
redblueMask = 0x7C1F;
greenMask = 0x3E0;
} else {
return 0;
}
return 1;
}
static inline int GetResult1 (u32 A, u32 B, u32 C, u32 D,
u32 /* E */)
{
int x = 0;
int y = 0;
int r = 0;
if (A == C)
x += 1;
else if (B == C)
y += 1;
if (A == D)
x += 1;
else if (B == D)
y += 1;
if (x <= 1)
r += 1;
if (y <= 1)
r -= 1;
return r;
}
static inline int GetResult2 (u32 A, u32 B, u32 C, u32 D,
u32 /* E */)
{
int x = 0;
int y = 0;
int r = 0;
if (A == C)
x += 1;
else if (B == C)
y += 1;
if (A == D)
x += 1;
else if (B == D)
y += 1;
if (x <= 1)
r -= 1;
if (y <= 1)
r += 1;
return r;
}
static inline int GetResult (u32 A, u32 B, u32 C, u32 D)
{
int x = 0;
int y = 0;
int r = 0;
if (A == C)
x += 1;
else if (B == C)
y += 1;
if (A == D)
x += 1;
else if (B == D)
y += 1;
if (x <= 1)
r += 1;
if (y <= 1)
r -= 1;
return r;
}
static inline u32 INTERPOLATE (u32 A, u32 B)
{
if (A != B) {
return (((A & colorMask) >> 1) + ((B & colorMask) >> 1) +
(A & B & lowPixelMask));
} else
return A;
}
static inline u32 Q_INTERPOLATE (u32 A, u32 B, u32 C, u32 D)
{
register u32 x = ((A & qcolorMask) >> 2) +
((B & qcolorMask) >> 2) +
((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2);
register u32 y = (A & qlowpixelMask) +
(B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask);
y = (y >> 2) & qlowpixelMask;
return x + y;
}
#define BLUE_MASK565 0x001F001F
#define RED_MASK565 0xF800F800
#define GREEN_MASK565 0x07E007E0
#define BLUE_MASK555 0x001F001F
#define RED_MASK555 0x7C007C00
#define GREEN_MASK555 0x03E003E0
void Super2xSaI (u8 *srcPtr, u32 srcPitch,
u8 *deltaPtr, u8 *dstPtr, u32 dstPitch,
int width, int height)
{
u16 *bP;
u8 *dP;
u32 inc_bP;
u32 Nextline = srcPitch >> 1;
{
inc_bP = 1;
for (; height; height--) {
bP = (u16 *) srcPtr;
dP = (u8 *) dstPtr;
for (u32 finish = width; finish; finish -= inc_bP) {
u32 color4, color5, color6;
u32 color1, color2, color3;
u32 colorA0, colorA1, colorA2, colorA3,
colorB0, colorB1, colorB2, colorB3, colorS1, colorS2;
u32 product1a, product1b, product2a, product2b;
//--------------------------------------- B1 B2
// 4 5 6 S2
// 1 2 3 S1
// A1 A2
colorB0 = *(bP - Nextline - 1);
colorB1 = *(bP - Nextline);
colorB2 = *(bP - Nextline + 1);
colorB3 = *(bP - Nextline + 2);
color4 = *(bP - 1);
color5 = *(bP);
color6 = *(bP + 1);
colorS2 = *(bP + 2);
color1 = *(bP + Nextline - 1);
color2 = *(bP + Nextline);
color3 = *(bP + Nextline + 1);
colorS1 = *(bP + Nextline + 2);
colorA0 = *(bP + Nextline + Nextline - 1);
colorA1 = *(bP + Nextline + Nextline);
colorA2 = *(bP + Nextline + Nextline + 1);
colorA3 = *(bP + Nextline + Nextline + 2);
//--------------------------------------
if (color2 == color6 && color5 != color3) {
product2b = product1b = color2;
} else if (color5 == color3 && color2 != color6) {
product2b = product1b = color5;
} else if (color5 == color3 && color2 == color6) {
register int r = 0;
r += GetResult (color6, color5, color1, colorA1);
r += GetResult (color6, color5, color4, colorB1);
r += GetResult (color6, color5, colorA2, colorS1);
r += GetResult (color6, color5, colorB2, colorS2);
if (r > 0)
product2b = product1b = color6;
else if (r < 0)
product2b = product1b = color5;
else {
product2b = product1b = INTERPOLATE (color5, color6);
}
} else {
if (color6 == color3 && color3 == colorA1
&& color2 != colorA2 && color3 != colorA0)
product2b =
Q_INTERPOLATE (color3, color3, color3, color2);
else if (color5 == color2 && color2 == colorA2
&& colorA1 != color3 && color2 != colorA3)
product2b =
Q_INTERPOLATE (color2, color2, color2, color3);
else
product2b = INTERPOLATE (color2, color3);
if (color6 == color3 && color6 == colorB1
&& color5 != colorB2 && color6 != colorB0)
product1b =
Q_INTERPOLATE (color6, color6, color6, color5);
else if (color5 == color2 && color5 == colorB2
&& colorB1 != color6 && color5 != colorB3)
product1b =
Q_INTERPOLATE (color6, color5, color5, color5);
else
product1b = INTERPOLATE (color5, color6);
}
if (color5 == color3 && color2 != color6 && color4 == color5
&& color5 != colorA2)
product2a = INTERPOLATE (color2, color5);
else
if (color5 == color1 && color6 == color5
&& color4 != color2 && color5 != colorA0)
product2a = INTERPOLATE (color2, color5);
else
product2a = color2;
if (color2 == color6 && color5 != color3 && color1 == color2
&& color2 != colorB2)
product1a = INTERPOLATE (color2, color5);
else
if (color4 == color2 && color3 == color2
&& color1 != color5 && color2 != colorB0)
product1a = INTERPOLATE (color2, color5);
else
product1a = color5;
product1a = product1a | (product1b << 16);
product2a = product2a | (product2b << 16);
*((u32 *) dP) = product1a;
*((u32 *) (dP + dstPitch)) = product2a;
bP += inc_bP;
dP += sizeof (u32);
} // end of for ( finish= width etc..)
srcPtr += srcPitch;
dstPtr += dstPitch * 2;
// deltaPtr += srcPitch;
} // endof: for (; height; height--)
}
}
void SuperEagle (u8 *srcPtr, u32 srcPitch, u8 *deltaPtr,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u8 *dP;
u16 *bP;
u16 *xP;
u32 inc_bP;
{
inc_bP = 1;
u32 Nextline = srcPitch >> 1;
for (; height; height--) {
bP = (u16 *) srcPtr;
// xP = (u16 *) deltaPtr;
dP = dstPtr;
for (u32 finish = width; finish; finish -= inc_bP) {
u32 color4, color5, color6;
u32 color1, color2, color3;
u32 colorA1, colorA2, colorB1, colorB2, colorS1, colorS2;
u32 product1a, product1b, product2a, product2b;
colorB1 = *(bP - Nextline);
colorB2 = *(bP - Nextline + 1);
color4 = *(bP - 1);
color5 = *(bP);
color6 = *(bP + 1);
colorS2 = *(bP + 2);
color1 = *(bP + Nextline - 1);
color2 = *(bP + Nextline);
color3 = *(bP + Nextline + 1);
colorS1 = *(bP + Nextline + 2);
colorA1 = *(bP + Nextline + Nextline);
colorA2 = *(bP + Nextline + Nextline + 1);
// --------------------------------------
if (color2 == color6 && color5 != color3) {
product1b = product2a = color2;
if ((color1 == color2) || (color6 == colorB2)) {
product1a = INTERPOLATE (color2, color5);
product1a = INTERPOLATE (color2, product1a);
// product1a = color2;
} else {
product1a = INTERPOLATE (color5, color6);
}
if ((color6 == colorS2) || (color2 == colorA1)) {
product2b = INTERPOLATE (color2, color3);
product2b = INTERPOLATE (color2, product2b);
// product2b = color2;
} else {
product2b = INTERPOLATE (color2, color3);
}
} else if (color5 == color3 && color2 != color6) {
product2b = product1a = color5;
if ((colorB1 == color5) || (color3 == colorS1)) {
product1b = INTERPOLATE (color5, color6);
product1b = INTERPOLATE (color5, product1b);
// product1b = color5;
} else {
product1b = INTERPOLATE (color5, color6);
}
if ((color3 == colorA2) || (color4 == color5)) {
product2a = INTERPOLATE (color5, color2);
product2a = INTERPOLATE (color5, product2a);
// product2a = color5;
} else {
product2a = INTERPOLATE (color2, color3);
}
} else if (color5 == color3 && color2 == color6) {
register int r = 0;
r += GetResult (color6, color5, color1, colorA1);
r += GetResult (color6, color5, color4, colorB1);
r += GetResult (color6, color5, colorA2, colorS1);
r += GetResult (color6, color5, colorB2, colorS2);
if (r > 0) {
product1b = product2a = color2;
product1a = product2b = INTERPOLATE (color5, color6);
} else if (r < 0) {
product2b = product1a = color5;
product1b = product2a = INTERPOLATE (color5, color6);
} else {
product2b = product1a = color5;
product1b = product2a = color2;
}
} else {
product2b = product1a = INTERPOLATE (color2, color6);
product2b =
Q_INTERPOLATE (color3, color3, color3, product2b);
product1a =
Q_INTERPOLATE (color5, color5, color5, product1a);
product2a = product1b = INTERPOLATE (color5, color3);
product2a =
Q_INTERPOLATE (color2, color2, color2, product2a);
product1b =
Q_INTERPOLATE (color6, color6, color6, product1b);
// product1a = color5;
// product1b = color6;
// product2a = color2;
// product2b = color3;
}
product1a = product1a | (product1b << 16);
product2a = product2a | (product2b << 16);
*((u32 *) dP) = product1a;
*((u32 *) (dP + dstPitch)) = product2a;
// *xP = color5;
bP += inc_bP;
// xP += inc_bP;
dP += sizeof (u32);
} // end of for ( finish= width etc..)
srcPtr += srcPitch;
dstPtr += dstPitch * 2;
// deltaPtr += srcPitch;
} // endof: for (height; height; height--)
}
}
void _2xSaI (u8 *srcPtr, u32 srcPitch, u8 *deltaPtr,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u8 *dP;
u16 *bP;
u32 inc_bP;
{
inc_bP = 1;
u32 Nextline = srcPitch >> 1;
for (; height; height--) {
bP = (u16 *) srcPtr;
dP = dstPtr;
for (u32 finish = width; finish; finish -= inc_bP) {
register u32 colorA, colorB;
u32 colorC, colorD,
colorE, colorF, colorG, colorH,
colorI, colorJ, colorK, colorL,
colorM, colorN, colorO, colorP;
u32 product, product1, product2;
//---------------------------------------
// Map of the pixels: I|E F|J
// G|A B|K
// H|C D|L
// M|N O|P
colorI = *(bP - Nextline - 1);
colorE = *(bP - Nextline);
colorF = *(bP - Nextline + 1);
colorJ = *(bP - Nextline + 2);
colorG = *(bP - 1);
colorA = *(bP);
colorB = *(bP + 1);
colorK = *(bP + 2);
colorH = *(bP + Nextline - 1);
colorC = *(bP + Nextline);
colorD = *(bP + Nextline + 1);
colorL = *(bP + Nextline + 2);
colorM = *(bP + Nextline + Nextline - 1);
colorN = *(bP + Nextline + Nextline);
colorO = *(bP + Nextline + Nextline + 1);
colorP = *(bP + Nextline + Nextline + 2);
if ((colorA == colorD) && (colorB != colorC)) {
if (((colorA == colorE) && (colorB == colorL)) ||
((colorA == colorC) && (colorA == colorF)
&& (colorB != colorE) && (colorB == colorJ))) {
product = colorA;
} else {
product = INTERPOLATE (colorA, colorB);
}
if (((colorA == colorG) && (colorC == colorO)) ||
((colorA == colorB) && (colorA == colorH)
&& (colorG != colorC) && (colorC == colorM))) {
product1 = colorA;
} else {
product1 = INTERPOLATE (colorA, colorC);
}
product2 = colorA;
} else if ((colorB == colorC) && (colorA != colorD)) {
if (((colorB == colorF) && (colorA == colorH)) ||
((colorB == colorE) && (colorB == colorD)
&& (colorA != colorF) && (colorA == colorI))) {
product = colorB;
} else {
product = INTERPOLATE (colorA, colorB);
}
if (((colorC == colorH) && (colorA == colorF)) ||
((colorC == colorG) && (colorC == colorD)
&& (colorA != colorH) && (colorA == colorI))) {
product1 = colorC;
} else {
product1 = INTERPOLATE (colorA, colorC);
}
product2 = colorB;
} else if ((colorA == colorD) && (colorB == colorC)) {
if (colorA == colorB) {
product = colorA;
product1 = colorA;
product2 = colorA;
} else {
register int r = 0;
product1 = INTERPOLATE (colorA, colorC);
product = INTERPOLATE (colorA, colorB);
r +=
GetResult1 (colorA, colorB, colorG, colorE,
colorI);
r +=
GetResult2 (colorB, colorA, colorK, colorF,
colorJ);
r +=
GetResult2 (colorB, colorA, colorH, colorN,
colorM);
r +=
GetResult1 (colorA, colorB, colorL, colorO,
colorP);
if (r > 0)
product2 = colorA;
else if (r < 0)
product2 = colorB;
else {
product2 =
Q_INTERPOLATE (colorA, colorB, colorC,
colorD);
}
}
} else {
product2 = Q_INTERPOLATE (colorA, colorB, colorC, colorD);
if ((colorA == colorC) && (colorA == colorF)
&& (colorB != colorE) && (colorB == colorJ)) {
product = colorA;
} else if ((colorB == colorE) && (colorB == colorD)
&& (colorA != colorF) && (colorA == colorI)) {
product = colorB;
} else {
product = INTERPOLATE (colorA, colorB);
}
if ((colorA == colorB) && (colorA == colorH)
&& (colorG != colorC) && (colorC == colorM)) {
product1 = colorA;
} else if ((colorC == colorG) && (colorC == colorD)
&& (colorA != colorH) && (colorA == colorI)) {
product1 = colorC;
} else {
product1 = INTERPOLATE (colorA, colorC);
}
}
product = colorA | (product << 16);
product1 = product1 | (product2 << 16);
*((s32 *) dP) = product;
*((u32 *) (dP + dstPitch)) = product1;
bP += inc_bP;
dP += sizeof (u32);
} // end of for ( finish= width etc..)
srcPtr += srcPitch;
dstPtr += dstPitch * 2;
// deltaPtr += srcPitch;
} // endof: for (height; height; height--)
}
}
static u32 Bilinear (u32 A, u32 B, u32 x)
{
unsigned long areaA, areaB;
unsigned long result;
if (A == B)
return A;
areaB = (x >> 11) & 0x1f; // reduce 16 bit fraction to 5 bits
areaA = 0x20 - areaB;
A = (A & redblueMask) | ((A & greenMask) << 16);
B = (B & redblueMask) | ((B & greenMask) << 16);
result = ((areaA * A) + (areaB * B)) >> 5;
return (result & redblueMask) | ((result >> 16) & greenMask);
}
static u32 Bilinear4 (u32 A, u32 B, u32 C, u32 D, u32 x,
u32 y)
{
unsigned long areaA, areaB, areaC, areaD;
unsigned long result, xy;
x = (x >> 11) & 0x1f;
y = (y >> 11) & 0x1f;
xy = (x * y) >> 5;
A = (A & redblueMask) | ((A & greenMask) << 16);
B = (B & redblueMask) | ((B & greenMask) << 16);
C = (C & redblueMask) | ((C & greenMask) << 16);
D = (D & redblueMask) | ((D & greenMask) << 16);
areaA = 0x20 + xy - x - y;
areaB = x - xy;
areaC = y - xy;
areaD = xy;
result = ((areaA * A) + (areaB * B) + (areaC * C) + (areaD * D)) >> 5;
return (result & redblueMask) | ((result >> 16) & greenMask);
}
void Scale_2xSaI (u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch,
u32 dstWidth, u32 dstHeight, int width, int height)
{
u8 *dP;
u16 *bP;
u32 w;
u32 h;
u32 dw;
u32 dh;
u32 hfinish;
u32 wfinish;
u32 Nextline = srcPitch >> 1;
wfinish = (width - 1) << 16; // convert to fixed point
dw = wfinish / (dstWidth - 1);
hfinish = (height - 1) << 16; // convert to fixed point
dh = hfinish / (dstHeight - 1);
for (h = 0; h < hfinish; h += dh) {
u32 y1, y2;
y1 = h & 0xffff; // fraction part of fixed point
bP = (u16 *) (srcPtr + ((h >> 16) * srcPitch));
dP = dstPtr;
y2 = 0x10000 - y1;
w = 0;
for (; w < wfinish;) {
u32 A, B, C, D;
u32 E, F, G, H;
u32 I, J, K, L;
u32 x1, x2, a1, f1, f2;
u32 position, product1;
position = w >> 16;
A = bP[position]; // current pixel
B = bP[position + 1]; // next pixel
C = bP[position + Nextline];
D = bP[position + Nextline + 1];
E = bP[position - Nextline];
F = bP[position - Nextline + 1];
G = bP[position - 1];
H = bP[position + Nextline - 1];
I = bP[position + 2];
J = bP[position + Nextline + 2];
K = bP[position + Nextline + Nextline];
L = bP[position + Nextline + Nextline + 1];
x1 = w & 0xffff; // fraction part of fixed point
x2 = 0x10000 - x1;
/*0*/
if (A == B && C == D && A == C)
product1 = A;
else /*1*/ if (A == D && B != C) {
f1 = (x1 >> 1) + (0x10000 >> 2);
f2 = (y1 >> 1) + (0x10000 >> 2);
if (y1 <= f1 && A == J && A != E) // close to B
{
a1 = f1 - y1;
product1 = Bilinear (A, B, a1);
} else if (y1 >= f1 && A == G && A != L) // close to C
{
a1 = y1 - f1;
product1 = Bilinear (A, C, a1);
}
else if (x1 >= f2 && A == E && A != J) // close to B
{
a1 = x1 - f2;
product1 = Bilinear (A, B, a1);
}
else if (x1 <= f2 && A == L && A != G) // close to C
{
a1 = f2 - x1;
product1 = Bilinear (A, C, a1);
}
else if (y1 >= x1) // close to C
{
a1 = y1 - x1;
product1 = Bilinear (A, C, a1);
}
else if (y1 <= x1) // close to B
{
a1 = x1 - y1;
product1 = Bilinear (A, B, a1);
}
}
else
/*2*/
if (B == C && A != D)
{
f1 = (x1 >> 1) + (0x10000 >> 2);
f2 = (y1 >> 1) + (0x10000 >> 2);
if (y2 >= f1 && B == H && B != F) // close to A
{
a1 = y2 - f1;
product1 = Bilinear (B, A, a1);
}
else if (y2 <= f1 && B == I && B != K) // close to D
{
a1 = f1 - y2;
product1 = Bilinear (B, D, a1);
}
else if (x2 >= f2 && B == F && B != H) // close to A
{
a1 = x2 - f2;
product1 = Bilinear (B, A, a1);
}
else if (x2 <= f2 && B == K && B != I) // close to D
{
a1 = f2 - x2;
product1 = Bilinear (B, D, a1);
}
else if (y2 >= x1) // close to A
{
a1 = y2 - x1;
product1 = Bilinear (B, A, a1);
}
else if (y2 <= x1) // close to D
{
a1 = x1 - y2;
product1 = Bilinear (B, D, a1);
}
}
/*3*/
else
{
product1 = Bilinear4 (A, B, C, D, x1, y1);
}
//end First Pixel
*(u32 *) dP = product1;
dP += 2;
w += dw;
}
dstPtr += dstPitch;
}
}

22
oswan/source/2xSaI.h Normal file
View File

@@ -0,0 +1,22 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __2XSAI_H__
#define __2XSAI_H__
int Init_2xSaI(u32 BitFormat);
void Super2xSaI (u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height);
void SuperEagle (u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height);
void _2xSaI (u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height);
void Scale_2xSaI (u8 *srcPtr, u32 srcPitch, u8 * /*deltaPtr */, u8 *dstPtr, u32 dstPitch, u32 dstWidth, u32 dstHeight, int width, int height);
#endif

246
oswan/source/SDLptc.h Normal file
View File

@@ -0,0 +1,246 @@
/* Some simple emulation classes to get PTC code running on SDL */
#include <stdlib.h>
#include <string.h>
#include "SDL.h"
typedef Uint8 char8;
typedef Sint32 int32;
#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;
}
~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 *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 flags;
if ( SDL_InitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 ) {
throw Error(SDL_GetError());
}
//flags = (SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
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:
};

1382
oswan/source/audio.cpp Normal file

File diff suppressed because it is too large Load Diff

43
oswan/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(DWORD port,BYTE value);
BYTE ws_audio_port_read(BYTE 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(DWORD offset, BYTE value);
void ws_audio_process();
void ws_audio_readState(int fp);
void ws_audio_writeState(int fp);
Uint32 timer_callupdate(Uint32, void*);
#endif

View File

@@ -0,0 +1,56 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_2xSaI(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
_2xSaI ((u8*)backbuffer,144*2, NULL,(u8*)vs, surfacePitch<<1,144,224);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
int16 *vs = (int16 *)surface->lock();
_2xSaI ((u8*)backbuffer,224*2, NULL,(u8*)vs, surfacePitch<<1,224,144);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,220 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
__inline void ws_drawDoubledScanline(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 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;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
__inline void ws_drawDoubledRotatedScanline(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 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;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint16 ws_halfBrightnessTable[32];
#define M_HALFBRIGHTNESS(D) (ws_halfBrightnessTable[(D>>10)&0x1f]<<10)|(ws_halfBrightnessTable[(D>>5)&0x1f]<<5)|(ws_halfBrightnessTable[D&0x1f]);
__inline void ws_drawDoubledHalfBrightnessScanline(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 data;
for (int pixel=0;pixel<224;pixel+=4)
{
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
}
}
__inline void ws_drawDoubledHalfBrightnessScanlineSpecialEven(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 data;
for (int pixel=0;pixel<224;pixel+=4)
{
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
}
}
__inline void ws_drawDoubledHalfBrightnessScanlineSpecialOdd(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 data;
for (int pixel=0;pixel<224;pixel+=4)
{
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
}
}
__inline void ws_drawDoubledHalfBrightnessRotatedScanline(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 data;
for (int pixel=0;pixel<144;pixel+=4)
{
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
}
}
__inline void ws_drawDoubledHalfBrightnessRotatedScanlineSpecialEven(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 data;
for (int pixel=0;pixel<144;pixel+=4)
{
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
}
}
__inline void ws_drawDoubledHalfBrightnessRotatedScanlineSpecialOdd(int16 *vs, int16 *backbuffer_alias)
{
register int32 *vs_alias=(int32*)vs;
register int32 data;
for (int pixel=0;pixel<144;pixel+=4)
{
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data|=(data<<16); *vs_alias++=data;
data=*backbuffer_alias++; data=M_HALFBRIGHTNESS(data); data|=(data<<16); *vs_alias++=data;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_doubled(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
int16 *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();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
int16 *vs = (int16 *)surface->lock();
int16 *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();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,13 @@
Sint32 startTime, endTime, totalFrames;
Uint32 nNormalLast=0;
Sint32 nNormalFrac=0;
Sint32 nTime=0,nCount=0; int i=0;
double dTime = 0.0, dNormalLast = 0.0, dTemp;
Sint32 surfacePitch;
// 15 bits RGB555
Format format(16,0x007c00,0x00003e0,0x0000001f);
Console console;
Surface *surface;

View File

@@ -0,0 +1,23 @@
int16 *backbuffer=(int16*)malloc(224*144*sizeof(int16));
memset(backbuffer,0x00,224*144*sizeof(int16));
surfacePitch=(surface->pitch()>>1);
console.option("DirectX");
if (app_fullscreen)
console.option("fullscreen output");
else
console.option("windowed output");
console.option("fixed window");
console.option("center window");
totalFrames=0;
startTime=clock();
nNormalLast=0;// Last value of timeGetTime()
nNormalFrac=0; // Extra fraction we did
//nNormalLast=timeGetTime();
// hopefully, we only care about time delta, not time of day...
//nNormalLast = SDL_GetTicks();
dNormalLast = (double) SDL_GetTicks();
// filter change
if (gui_command==GUI_COMMAND_FILTER_CHANGE)
{
ws_loadState("oswan.wss");
}

View File

@@ -0,0 +1,77 @@
//nTime=SDL_GetTicks()-nNormalLast; // calcule le temps <20>coul<75> depuis le dernier affichage
dTemp = (double) SDL_GetTicks();
dTime = dTemp - dNormalLast;
// nTime est en mili-secondes.
// d<>termine le nombre de trames <20> passer + 1
//nCount = (Sint32) ((((double)nTime)*600.0 - (double)nNormalFrac) / 10000.0);
nCount = (Sint32) (dTime * 0.07547); // does this calculation make sense?
// 75.47Hz vblank is according to wstech22.txt
//printf("%d ", nCount);
// si le nombre de trames <20> passer + 1 est nul ou n<>gatif,
// ne rien faire pendant 2 ms
//AUpdateAudio();
if (nCount<=0)
{
SDL_Delay(2);
} // No need to do anything for a bit
else
{
//nNormalFrac+=nCount*10000; //
//nNormalLast+=nNormalFrac/600; // add the duration of nNormalFrac frames
//nNormalFrac%=600; //
//dNormalLast = dTemp;
dNormalLast += nCount * (1/0.07547);
// Pas plus de 9 (10-1) trames non affich<63>es
if (nCount>10)
nCount=10;
/*
ws_key_start=0;
ws_key_left=0;
ws_key_right=0;
ws_key_up=0;
ws_key_down=0;
ws_key_button_1=0;
ws_key_button_2=0;
*/
int ws_key_esc=0;
#include "source/temp/key.h"
if (ws_key_esc)
{
console.close();
if (ws_rom_path)
strcpy(old_rom_path,ws_rom_path);
//gui_open();
#ifndef GUI_OPEN_WARNED
#warning XXX something ought to take place here...
#define GUI_OPEN_WARNED
#endif
app_terminate = 1;
if ((ws_rom_path!=NULL)||(app_terminate))
break;
if (gui_command)
{
if (gui_command==GUI_COMMAND_RESET)
ws_reset();
if (gui_command==GUI_COMMAND_SCHEME_CHANGE)
ws_set_colour_scheme(ws_colourScheme);
if (gui_command==GUI_COMMAND_FILTER_CHANGE)
{
ws_saveState("oswan.wss");
ws_rom_path=old_rom_path;
delete surface;
return;
}
}
console.option("DirectX");
if (app_fullscreen)
console.option("fullscreen output");
else
console.option("windowed output");
console.option("fixed window");
console.option("center window");

View File

@@ -0,0 +1,10 @@
}
for (i=0;i<nCount-1;i++)
while (!ws_executeLine(backbuffer,0));
while (!ws_executeLine(backbuffer,1));
totalFrames++;

View File

@@ -0,0 +1,4 @@
endTime=clock();
float fps=totalFrames/(((float)(endTime-startTime))/(float)CLOCKS_PER_SEC);
console.close();
delete surface;

View File

@@ -0,0 +1,86 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_buildHalfBrightnessTable(void)
{
for (int i=0;i<32;i++)
ws_halfBrightnessTable[i]=0.65*i;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_halfBrightnessScanlines(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
int16 *backbuffer_alias=backbuffer;
for (int line=0;line<224;line++)
{
ws_drawDoubledRotatedScanline(vs,backbuffer_alias);
vs+=surfacePitch;
ws_drawDoubledHalfBrightnessRotatedScanline(vs,backbuffer_alias);
vs+=surfacePitch;
backbuffer_alias+=144;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
int16 *vs = (int16 *)surface->lock();
int16 *backbuffer_alias=backbuffer;
for (int line=0;line<144;line++)
{
ws_drawDoubledScanline(vs,backbuffer_alias);
vs+=surfacePitch;
ws_drawDoubledHalfBrightnessScanline(vs,backbuffer_alias);
vs+=surfacePitch;
backbuffer_alias+=224;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,188 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define M_R(A) ((A&0x7c00)>>10)
#define M_G(A) ((A&0x03e0)>>5)
#define M_B(A) (A&0x1f)
#define NB_BUFFERS 8
#define NB_BUFFERS_DIV 3
void ws_mergeBackbuffers(int16 **buffers)
{
int16 *buffersAlias[NB_BUFFERS+1];
memcpy(buffersAlias,buffers,sizeof(int16*)*(NB_BUFFERS+1));
for (int i=0;i<224*144;i++)
{
int r,g,b;
r=g=b=0;
for (int j=0;j<NB_BUFFERS;j++)
{
r+=M_R(*buffersAlias[j]);
g+=M_G(*buffersAlias[j]);
b+=M_B(*buffersAlias[j]);
buffersAlias[j]++;
}
r>>=NB_BUFFERS_DIV;
g>>=NB_BUFFERS_DIV;
b>>=NB_BUFFERS_DIV;
*buffersAlias[NB_BUFFERS]++=(r<<10)|(g<<5)|b;
}
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_standard_interpolate(void)
{
#define KEY_ENTER 0x0D
#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
uint32 startTime, endTime, totalFrames;
unsigned int nNormalLast=0;
int nNormalFrac=0;
int nTime=0,nCount=0; int i=0;
// 15 bits RGB555
Format format(16,0x007c00,0x00003e0,0x0000001f);
Console console;
Surface *surface;
if (app_rotated)
surface=new Surface(144,224,format);
else
surface=new Surface(224,144,format);
console.option("DirectX");
if (app_fullscreen)
console.option("fullscreen output");
else
console.option("windowed output");
console.option("fixed window");
console.option("center window");
console.open("Oswan",224,144,format);
int16 *backbuffer[NB_BUFFERS+1];
for (int fr=0;fr<NB_BUFFERS+1;fr++)
{
backbuffer[fr]=(int16*)malloc(224*144*sizeof(int16));
memset(backbuffer[fr],0x00,224*144*sizeof(int16));
}
totalFrames=0;
startTime=clock();
nNormalLast=0;// Last value of timeGetTime()
nNormalFrac=0; // Extra fraction we did
nNormalLast=timeGetTime();
// filter change
if (gui_command==GUI_COMMAND_FILTER_CHANGE)
{
ws_loadState("oswan.wss");
}
while (1)
{
nTime=timeGetTime()-nNormalLast; // calcule le temps <20>coul<75> depuis le dernier affichage
// nTime est en mili-secondes.
// d<>termine le nombre de trames <20> passer + 1
nCount=(nTime*600 - nNormalFrac) /10000;
// si le nombre de trames <20> passer + 1 est nul ou n<>gatif,
// ne rien faire pendant 2 ms
if (nCount<=0)
{
Sleep(2);
} // No need to do anything for a bit
else
{
nNormalFrac+=nCount*10000; //
nNormalLast+=nNormalFrac/600; // add the duration of nNormalFrac frames
nNormalFrac%=600; //
// Pas plus de 9 (10-1) trames non affich<63>es
if (nCount>10)
nCount=10;
/*
ws_key_start=0;
ws_key_left=0;
ws_key_right=0;
ws_key_up=0;
ws_key_down=0;
ws_key_button_1=0;
ws_key_button_2=0;
*/ int ws_key_esc=0;
#include "./source/temp/key.h"
if (ws_key_esc)
{
console.close();
strcpy(old_rom_path,ws_rom_path);
gui_open();
if ((ws_rom_path!=NULL)||(app_terminate))
break;
if (gui_command)
{
if (gui_command==GUI_COMMAND_RESET)
ws_reset();
if (gui_command==GUI_COMMAND_SCHEME_CHANGE)
ws_set_colour_scheme(ws_colourScheme);
if (gui_command==GUI_COMMAND_FILTER_CHANGE)
{
ws_saveState("oswan.wss");
ws_rom_path=old_rom_path;
delete surface;
return;
}
}
console.option("DirectX");
if (app_fullscreen)
console.option("fullscreen output");
else
console.option("windowed output");
console.option("fixed window");
console.option("center window");
console.open("Oswan",224,144,format);
}
for (i=0;i<nCount-1;i++)
while (!ws_executeLine(backbuffer[0],0));
while (!ws_executeLine(backbuffer[totalFrames&(NB_BUFFERS-1)],1));
ws_mergeBackbuffers(backbuffer);
if (app_rotated)
ws_rotate_backbuffer(backbuffer[NB_BUFFERS]);
totalFrames++;
int32 *vs = (int32 *)surface->lock();
memcpy(vs,backbuffer[NB_BUFFERS],224*144*2);
surface->unlock();
surface->copy(console);
console.update();
}
}
endTime=clock();
float fps=totalFrames/(((float)(endTime-startTime))/(float)CLOCKS_PER_SEC);
printf("%f fps (%i %% the original speed)\n",fps, (int)((fps*100)/60));
console.close();
delete surface;
}

View File

@@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_scanlines(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
int16 *backbuffer_alias=backbuffer;
for (int line=0;line<224;line++)
{
ws_drawDoubledRotatedScanline(vs,backbuffer_alias);
vs+=surfacePitch;
vs+=surfacePitch;
backbuffer_alias+=144;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
int16 *vs = (int16 *)surface->lock();
int16 *backbuffer_alias=backbuffer;
for (int line=0;line<144;line++)
{
ws_drawDoubledScanline(vs,backbuffer_alias);
vs+=surfacePitch;
vs+=surfacePitch;
backbuffer_alias+=224;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,71 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_special(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
int16 *backbuffer_alias=backbuffer;
for (int line=0;line<224;line++)
{
ws_drawDoubledHalfBrightnessRotatedScanlineSpecialEven(vs,backbuffer_alias);
vs+=surfacePitch;
ws_drawDoubledHalfBrightnessRotatedScanlineSpecialOdd(vs,backbuffer_alias);
vs+=surfacePitch;
backbuffer_alias+=144;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
while (!ws_executeLine(backbuffer,1));
int16 *vs = (int16 *)surface->lock();
int16 *backbuffer_alias=backbuffer;
for (int line=0;line<144;line++)
{
ws_drawDoubledHalfBrightnessScanlineSpecialEven(vs,backbuffer_alias);
vs+=surfacePitch;
ws_drawDoubledHalfBrightnessScanlineSpecialOdd(vs,backbuffer_alias);
vs+=surfacePitch;
backbuffer_alias+=224;
}
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,75 @@
////////////////////////////////////////////////////////////////////////////////
// VERY SLOW !!!!
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_rotate_backbuffer(int16 *backbuffer)
{
static int16 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_standard(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144,224,format);
#include "filter_partB.h"
surfacePitch>>=1;
console.open(app_window_title,144,224,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144,224,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int32 *vs = (int32 *)surface->lock();
memcpy(vs,backbuffer,224*144*2);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224,144,format);
#include "filter_partB.h"
console.open(app_window_title,224,144,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224,144,format);
#include "filter_partD.h"
int32 *vs = (int32 *)surface->lock();
memcpy(vs,backbuffer,224*144*2);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,54 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_Super2xSaI(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
Super2xSaI ((u8*)backbuffer,144*2, NULL,(u8*)vs, surfacePitch<<1,144,224);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
int16 *vs = (int16 *)surface->lock();
Super2xSaI ((u8*)backbuffer,224*2, NULL,(u8*)vs, surfacePitch<<1,224,144);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

View File

@@ -0,0 +1,54 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_emulate_SuperEagle(void)
{
#include "filter_partA.h"
if (app_rotated)
{
surface=new Surface(144*2,224*2,format);
#include "filter_partB.h"
console.open(app_window_title,144*2,224*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,144*2,224*2,format);
#include "filter_partD.h"
ws_rotate_backbuffer(backbuffer);
int16 *vs = (int16 *)surface->lock();
SuperEagle ((u8*)backbuffer,144*2, NULL,(u8*)vs, surfacePitch<<1,144,224);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
else
{
surface=new Surface(224*2,144*2,format);
#include "filter_partB.h"
console.open(app_window_title,224*2,144*2,format);
while (1)
{
#include "filter_partC.h"
console.open(app_window_title,224*2,144*2,format);
#include "filter_partD.h"
int16 *vs = (int16 *)surface->lock();
SuperEagle ((u8*)backbuffer,224*2, NULL,(u8*)vs, surfacePitch<<1,224,144);
surface->unlock();
surface->copy(console);
console.update();
}
}
#include "filter_partE.h"
}
}

1605
oswan/source/gpu.cpp Normal file

File diff suppressed because it is too large Load Diff

1580
oswan/source/gpu.cpp.orig Normal file

File diff suppressed because it is too large Load Diff

45
oswan/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 ws_gpu_scanline;
extern uint8 ws_gpu_operatingInColor;
extern uint8 ws_videoMode;
extern int16 ws_palette[16*4];
extern int8 ws_paletteColors[8];
extern int16 wsc_palette[16*16];
extern unsigned int ws_gpu_unknownPort;
extern uint32 vblank_count;
void ws_gpu_init(void);
void ws_gpu_done(void);
void ws_gpu_reset(void);
void ws_gpu_renderScanline(int16 *framebuffer);
void ws_gpu_changeVideoMode(uint8 value);
void ws_gpu_write_byte(DWORD offset, BYTE value);
int ws_gpu_port_write(DWORD port,BYTE value);
BYTE ws_gpu_port_read(BYTE port);
void ws_gpu_set_colour_scheme(int scheme);
void ws_gpu_changeVideoMode(uint8 value);
void ws_gpu_forceColorSystem(void);
void ws_gpu_forceMonoSystem(void);
void ws_gpu_clearCache(void);
#endif

100
oswan/source/ieeprom.h Normal file
View File

@@ -0,0 +1,100 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
uint8 internalEeprom[]=
{
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,
'D'-54,'A'-54,'V'-54,'I'-54,'D'-54,0x00,0x00,0x00,0x00,0x00,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
oswan/source/initialIo.h Normal file
View File

@@ -0,0 +1,271 @@
////////////////////////////////////////////////////////////////////////////////
// Initial I/O values
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
uint8 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
0x87-2,//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
};

715
oswan/source/io.cpp Normal file
View File

@@ -0,0 +1,715 @@
////////////////////////////////////////////////////////////////////////////////
// I/O ports
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.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 "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "initialIo.h"
#include "ieeprom.h"
#include "gpu.h"
#include "audio.h"
extern uint8 *externalEeprom;
extern uint32 externalEepromAddressMask;
extern uint32 romAddressMask;
uint8 *ws_ioRam=NULL;
uint8 ws_key_start;
uint8 ws_key_left;
uint8 ws_key_right;
uint8 ws_key_up;
uint8 ws_key_down;
uint8 ws_key_button_1;
uint8 ws_key_button_2;
uint8 ws_key_flipped;
int rtcDataRegisterReadCount=0;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_reset(void)
{
ws_key_start=0;
ws_key_left=0;
ws_key_right=0;
ws_key_up=0;
ws_key_down=0;
ws_key_button_1=0;
ws_key_button_2=0;
int i;
for (i=0;i<0x100;i++)
ws_ioRam[i]=initialIoValue[i];
for (i=0;i<0xc9;i++)
cpu_writeport(i,initialIoValue[i]);
rtcDataRegisterReadCount=0;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_init(void)
{
if (ws_ioRam==NULL)
ws_ioRam=(uint8*)malloc(0x100);
ws_io_reset();
ws_key_flipped=0;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_flipControls(void)
{
ws_key_flipped=!ws_key_flipped;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_done(void)
{
if (ws_ioRam==NULL)
free(ws_ioRam);
}
/* Serial port */
#define BDR_9600 (0)
#define BDR_38400 (1)
#define SERIAL_PORT "/dev/tty.USA19H141P1.1"
int serialfd = -1;
int serial_have_data = 0;
unsigned char serial_data = 0;
int serial_speed = BDR_9600;
void open_serial()
{
if (serialfd < 0)
{
serialfd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
//set_baudrate(serial_speed);
serial_have_data = 0;
}
}
void set_baudrate(int speed)
{
struct termios options;
if (serialfd < 0)
return;
tcgetattr(serialfd, &options);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
if (speed == BDR_9600)
{
cfsetispeed(&options, B9600);
}
else
{
cfsetospeed(&options, B38400);
}
options.c_cflag &= ~CNEW_RTSCTS;
options.c_cflag |= (CLOCAL | CREAD);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
tcsetattr(serialfd, TCSANOW, &options);
/* Make sure read is not blocking */
fcntl(serialfd, F_SETFL, FNDELAY);
}
void close_serial()
{
close(serialfd);
serialfd = -1;
}
void nec_int(DWORD wektor);
void check_serial_data()
{
unsigned char buf[10];
int f;
if (serialfd < 0)
return;
if (serial_have_data == 0)
{
f = read(serialfd, buf, 1);
if (f > 0)
{
printf("Ho [%d]!\n", f);fflush(stdout);
serial_have_data = 0x01;
serial_data = buf[0];
}
}
if(serial_have_data > 0)
{
/* Gen an int if enabled */
if(ws_ioRam[0xB2] & 0x04)
{
ws_ioRam[0xb6] &= ~ 0x04;
printf("INNNNNTTTT!!!!!!!");
nec_int((ws_ioRam[0xb0]+3)*4);
}
}
}
unsigned char read_serial()
{
unsigned char buf[10];
int f;
if (serialfd < 0)
return 0xFF;
if (serial_have_data > 0)
{
serial_have_data = 0;
return serial_data;
}
f = read(serialfd, buf, 1);
if (f == 1)
return buf[0];
return 0x42;
}
void write_serial(unsigned char value)
{
if (serialfd < 0)
return;
write(serialfd, &value, 1);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
BYTE cpu_readport(BYTE port)
{
int w1,w2;
BYTE retVal;
if (port >= 0xBA) && (port <= 0xBE)
{
printf("Reading IEEP %02X\n", port);
}
switch (port)
{
case 0x4e:
case 0x4f:
case 0x50:
case 0x51:
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x87:
case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
return(ws_audio_port_read(port));
//case 0xaa: return 0xff;
/*case 0xb3: // ???
if (ws_ioRam[0xb3]<0x80)
return 0;
if (ws_ioRam[0xb3]<0xc0)
return 0x84;
return 0xc4;*/
case 0xb5:
w1=ws_ioRam[0xb5];
if(w1&0x40)
{
w2=0x00;
if (ws_key_flipped)
w2=(ws_key_start<<1);
else
w2=(ws_key_start<<1)|(ws_key_button_1<<2)|(ws_key_button_2<<3);
return (uint8)((w1&0xf0)|w2);
}
if(w1&0x20)
{
w2=0x00;
if (ws_key_flipped)
w2=(ws_key_button_1)|(ws_key_button_2<<2);
else
w2=(ws_key_up<<0)|(ws_key_right<<1)|(ws_key_down<<2)|(ws_key_left<<3);
return (uint8)((w1&0xf0)|w2);
}
if(w1&0x10)
{
w2=0x00;
if (ws_key_flipped)
w2=(ws_key_up<<1)|(ws_key_right<<2)|(ws_key_down<<3)|(ws_key_left);
return (uint8)((w1&0xf0)|w2);
}
break;
case 0xbe: // internal eeprom status/command register
// ack eeprom write
if(ws_ioRam[0xbe]&0x20)
return ws_ioRam[0xbe]|2;
// ack eeprom read
if(ws_ioRam[0xbe]&0x10)
return ws_ioRam[0xbe]|1;
// else ack both
return ws_ioRam[0xbe]|3;
case 0xba: // eeprom even byte read
w1=((((uint16)ws_ioRam[0xbd])<<8)|((uint16)ws_ioRam[0xbc]));
w1=(w1<<1)&0x3ff;
return internalEeprom[w1];
case 0xbb: // eeprom odd byte read
w1=((((uint16)ws_ioRam[0xbd])<<8)|((uint16)ws_ioRam[0xbc]));
w1=((w1<<1)+1)&0x3ff;
return internalEeprom[w1];
case 0xc0 : // ???
retVal = ((ws_ioRam[0xc0]&0xf)|0x20);
goto exit;
case 0xc4: // external eeprom even byte read
w1=(((((WORD)ws_ioRam[0xc7])<<8)|((WORD)ws_ioRam[0xc6]))<<1)&(externalEepromAddressMask);
retVal = externalEeprom[w1];
goto exit;
case 0xc5: // external eeprom odd byte read
w1=(((((WORD)ws_ioRam[0xc7])<<8)|((WORD)ws_ioRam[0xc6]))<<1)&(externalEepromAddressMask);
retVal = externalEeprom[w1+1];
goto exit;
case 0xc8: // external eeprom status/command register
// ack eeprom write
if(ws_ioRam[0xc8]&0x20)
{
retVal = ws_ioRam[0xc8]|2;
goto exit;
}
// ack eeprom read
if(ws_ioRam[0xc8]&0x10)
{
retVal = ws_ioRam[0xc8]|1;
goto exit;
}
// else ack both
retVal = ws_ioRam[0xc8]|3;
goto exit;
case 0xca : // RTC Command and status register
// set ack to always 1
retVal = (ws_ioRam[0xca]|0x80);
goto exit;
case 0xcb : // RTC data register
if(ws_ioRam[0xca]==0x15) // get time command
{
struct tm *newtime;
time_t long_time;
time( &long_time );
newtime = localtime( &long_time );
#define BCD(value) ((value/10)<<4)|(value%10)
switch(rtcDataRegisterReadCount)
{
case 0: rtcDataRegisterReadCount++;
retVal = BCD(newtime->tm_year-100);
goto exit;
case 1: rtcDataRegisterReadCount++;
retVal = BCD(newtime->tm_mon);
goto exit;
case 2: rtcDataRegisterReadCount++;
retVal = BCD(newtime->tm_mday);
goto exit;
case 3: rtcDataRegisterReadCount++;
retVal = BCD(newtime->tm_wday);
goto exit;
case 4: rtcDataRegisterReadCount++;
retVal = BCD(newtime->tm_hour);
goto exit;
case 5: rtcDataRegisterReadCount++;
retVal = BCD(newtime->tm_min);
goto exit;
case 6: rtcDataRegisterReadCount=0;
retVal = BCD(newtime->tm_sec);
goto exit;
}
return 0;
}
else
{
// set ack
retVal = (ws_ioRam[0xcb]|0x80);
goto exit;
}
case 0xD0:
retVal = 0;
goto exit;
/* Serial port link.. */
case 0xB1:
retVal = read_serial();
printf("RS232: Read %02X\n", retVal);
goto exit;
case 0xB3:
check_serial_data();
if (ws_ioRam[0xB3] & 0x80)
retVal = (ws_ioRam[0xB3] & ~1) | serial_have_data | 0x04;
else
retVal = 0x00;
printf("<<<<RS232STA: %02X [%c%c%cxx%c%c%c]\n", retVal,
(retVal & 0x80)?'E':'d',
(retVal & 0x40)?'3':'9',
(retVal & 0x20)?'R':'n',
(retVal & 0x04)?'E':'f',
(retVal & 0x02)?'V':'n',
(retVal & 0x01)?'D':'e'
);
goto exit;
default:
if (port > 0xD0) printf("ReadIO %02X <= %02X\n", port, retVal);
break;
}
retVal = ws_gpu_port_read(port);
exit:
return retVal;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void cpu_writeport(DWORD port,BYTE value)
{
unsigned short F0dbg = 0;
int w1,w2;
int unknown_io_port=0;
if (port >= 0xBA) && (port <= 0xBE)
{
printf("Writing IEEP %02X <= %02X\n", port, value);
}
if ((ws_ioRam[port]==value) && (port < 0xF0) && ((port < 0xB0) || (port > 0xBF)) )
return;
ws_ioRam[port]=value;
switch (port)
{
/* GPU IOs */
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
break;
case 0x15: printf("Icons %c %c %c %c %c %c %c %c\n",
(value>>7)&1?'?':' ',
(value>>6)&1?'?':' ',
(value>>5)&1?'3':' ',
(value>>4)&1?'2':' ',
(value>>3)&1?'1':' ',
(value>>2)&1?'H':' ',
(value>>1)&1?'V':' ',
(value>>0)&1?'S':' '
); break;
/* Palettes ? */
case 0x1C: case 0x25: case 0x2F: case 0x38:
case 0x1D: case 0x26: case 0x30: case 0x39:
case 0x1E: case 0x27: case 0x31: case 0x3A:
case 0x1F: case 0x28: case 0x32: case 0x3B:
case 0x20: case 0x29: case 0x33: case 0x3C:
case 0x21: case 0x2A: case 0x34: case 0x3E:
case 0x22: case 0x2B: case 0x35: case 0x3F:
case 0x23: case 0x2C: case 0x36:
case 0x24: case 0x2E: case 0x37:
break;
/* DMAs */
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
break;
case 0x48: // DMA
// bit 7 set to start dma transfer
if(value&0x80)
{
int dma_start = (((DWORD)ws_ioRam[0x41])<<8)|(((DWORD)ws_ioRam[0x40]))|(((DWORD)ws_ioRam[0x42])<<16);
int dma_end = (((DWORD)ws_ioRam[0x45])<<8)|(((DWORD)ws_ioRam[0x44]))|(((DWORD)ws_ioRam[0x43])<<16);
int dma_size = (((DWORD)ws_ioRam[0x47])<<8)|(((DWORD)ws_ioRam[0x46]));
for(int ix=0;ix<dma_size;ix++)
cpu_writemem20(dma_end++,cpu_readmem20(dma_start++));
ws_ioRam[0x47]=0;
ws_ioRam[0x46]=0;
ws_ioRam[0x41]=(BYTE)(dma_start>>8);
ws_ioRam[0x40]=(BYTE)(dma_start&0xff);
ws_ioRam[0x45]=(BYTE)(dma_end>>8);
ws_ioRam[0x44]=(BYTE)(dma_end&0xff);
ws_ioRam[0x48]=0;
}
break;
/* Audio */
case 0x4a:
case 0x4b:
case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
ws_audio_port_write(port, value);
break;
/* DMA Start! */
case 0x52: break;
/* GPU (again) */
case 0x60:
break;
/* Audio */
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x87:
case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
ws_audio_port_write(port,value);
break;
/* Hardeware */
case 0xA0:
break;
/*Timers */
case 0xA2:
case 0xA4:
case 0xA5:
case 0xA6:
case 0xA7:
case 0xA8:
case 0xA9:
case 0xAA:
case 0xAB:
break;
/* Hardware */
case 0xB0: break;
case 0xB1: write_serial(value); /*printf("RS232 TX: %02X\n", value);*/ break;
case 0xB2: break;
case 0xB3: printf(">>>>RS232STA: %02X [%c%c%cxx%c%c%c]\n", value,
(value & 0x80)?'E':'d',
(value & 0x40)?'3':'9',
(value & 0x20)?'R':'n',
(value & 0x04)?'E':'f',
(value & 0x02)?'V':'n',
(value & 0x01)?'D':'e'
);
/* Serial status: 7 = Enable, 6 = baudrate, 5 = Overrun reset
2 = Send Buffer empty
1 = Overrun
0 = Data Received
*/
serial_speed = ((value&040) == 0x00)?BDR_9600:BDR_38400;
if ((value & 0x80) == 0x80)
{
open_serial();
set_baudrate(serial_speed);
check_serial_data();
}
break;
case 0xB5:
break;
/* buttons */
case 0xB6:
break;
/* Internal EEPROM */
case 0xba: w1=(((((WORD)ws_ioRam[0xbd])<<8)|((WORD)ws_ioRam[0xbc])));
w1=(w1<<1)&0x3ff;
internalEeprom[w1]=value;
return;
case 0xbb: w1=(((((WORD)ws_ioRam[0xbd])<<8)|((WORD)ws_ioRam[0xbc])));
w1=((w1<<1)+1)&0x3ff;
internalEeprom[w1]=value;
return;
case 0xBC: case 0xBD: case 0xBE: break;
/* MBC */
case 0xC0: case 0xC1: case 0xC2: case 0xC3: break;
case 0xc4: w1=(((((WORD)ws_ioRam[0xc7])<<8)|((WORD)ws_ioRam[0xc6]))<<1)&externalEepromAddressMask;
externalEeprom[w1]=value;
return;
case 0xc5: w1=(((((WORD)ws_ioRam[0xc7])<<8)|((WORD)ws_ioRam[0xc6]))<<1)&externalEepromAddressMask;
externalEeprom[w1+1]=value;
return;
case 0xC6: case 0xC7: case 0xC8: break;
case 0xca: if(value==0x15)
rtcDataRegisterReadCount=0;
break;
break;
case 0xCB: break;
case 0xF0: break;
case 0xF1: printf("%d\n", (signed short)((value << 8) | ws_ioRam[0xF0])); break;
case 0xF2: printf("%c", value); fflush(stdout); break;
default:
unknown_io_port=1;
}
if ((ws_gpu_port_write(port,value) == 1) && (unknown_io_port == 1))
{
fprintf(log_get(),"WriteIO(%02X, %02X);\n",port, value);
}
/*if (port >= 0xC0)
{
fprintf(log_get(),"WriteMBCIO(%02X, %02X);\n",port, value);
}*/
// if ((ws_gpu_unknownPort)&&(unknown_io_port))
// {
// fprintf(log_get(),"io: writing 0x%.2x to unknown port 0x%.2x\n",value,port);
// }
}

30
oswan/source/io.h Normal file
View File

@@ -0,0 +1,30 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __IO_H__
#define __IO_H__
extern uint8 *ws_ioRam;
extern uint8 ws_key_start;
extern uint8 ws_key_left;
extern uint8 ws_key_right;
extern uint8 ws_key_up;
extern uint8 ws_key_down;
extern uint8 ws_key_button_1;
extern uint8 ws_key_button_2;
void ws_io_init(void);
void ws_io_reset(void);
void ws_io_flipControls(void);
void ws_io_done(void);
#endif

63
oswan/source/log.cpp Normal file
View File

@@ -0,0 +1,63 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#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
oswan/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

308
oswan/source/memory.cpp Normal file
View File

@@ -0,0 +1,308 @@
////////////////////////////////////////////////////////////////////////////////
// Memory
////////////////////////////////////////////////////////////////////////////////
// Notes: need to optimize cpu_writemem20
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include "log.h"
#include "rom.h"
#include "./nec/nec.h"
#include "io.h"
#include "gpu.h"
#include "audio.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
#define IO_ROM_BANK_BASE_SELECTOR 0xC0
uint8 *ws_rom;
uint8 *ws_staticRam;
uint8 *internalRam;
uint8 *externalEeprom;
extern uint8 *ws_ioRam;
uint16 ws_rom_checksum;
uint32 sramAddressMask;
uint32 externalEepromAddressMask;
uint32 romAddressMask;
uint32 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[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(DWORD addr,BYTE value)
{
uint32 offset=addr&0xffff;
uint32 bank=addr>>16;
// 0 - RAM - 16 KB (WS) / 64 KB (WSC) internal RAM
if (!bank)
{
ws_gpu_write_byte(offset,value);
ws_audio_write_byte(offset,value);
}
else
// 1 - SRAM (cart)
if (bank==1)
{
ws_staticRam[offset&sramAddressMask]=value;
ws_sram_dirty = 1;
}
// other banks are read-only
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
BYTE cpu_readmem20(DWORD addr)
{
uint32 offset=addr&0xffff;
uint32 bank=addr>>16;
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:
case 3: return ws_rom[offset+((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR+bank]&((romSize>>16)-1))<<16)];
default:
int romBank=(256-(((ws_ioRam[IO_ROM_BANK_BASE_SELECTOR]&0xf)<<4)|(bank&0xf)));
return ws_rom[(unsigned)(offset+romSize-(romBank<<16))];
}
return(0xff);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_init(uint8 *rom, uint32 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*)malloc(0x10000);
ws_staticRam=(uint8*)malloc(0x10000);
externalEeprom=(uint8*)malloc(131072);//ws_rom_eepromSize(ws_rom,romSize));
sramAddressMask=ws_rom_sramSize(ws_rom,romSize)-1;
externalEepromAddressMask=ws_rom_eepromSize(ws_rom,romSize)-1;
romAddressMask=romSize-1;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_reset(void)
{
memset(internalRam,0,0x10000);
//memset(ws_staticRam,0,0x10000); // should the sram really be cleared? ...
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_memory_done(void)
{
free(ws_rom);
free(ws_staticRam);
free(internalRam);
free(externalEeprom);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8 *memory_getRom(void)
{
return(ws_rom);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32 memory_getRomSize(void)
{
return(romSize);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint16 memory_getRomCrc(void)
{
return(ws_rom_checksum);
}
void ws_sram_load(char *path)
{
FILE *f;
size_t read;
f = fopen(path, "r");
if (NULL == f)
{
memset(ws_staticRam, 0, 0x10000);
return;
}
read = fread(ws_staticRam, 1, 0x8000, f);
//fprintf(log_get(), "read 0x%x (of 0x%x?) bytes of save ram from %s\n", read, ws_rom_sramSize(ws_rom, romSize), path);
fclose(f);
}
void ws_sram_save(char *path)
{
FILE *f;
size_t wrote;
f = fopen(path, "wb");
if (NULL == f)
{
fprintf(log_get(), "error opening %s for writing save ram. (%s)\n", path, strerror(errno));
return;
}
wrote = fwrite(ws_staticRam, 1, 0x8000, f);
fflush(f);
//fprintf(log_get(), "wrote 0x%x bytes of save ram to %s\n", wrote, path);
fclose(f);
}

34
oswan/source/memory.h Normal file
View File

@@ -0,0 +1,34 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __MEMORY_H__
#define __MEMORY_H__
extern uint8 *ws_staticRam;
extern uint8 *internalRam;
extern uint8 *externalEeprom;
void ws_memory_init(uint8 *rom, uint32 romSize);
void ws_memory_reset(void);
uint8 *memory_getRom(void);
uint32 memory_getRomSize(void);
uint16 memory_getRomCrc(void);
void ws_memory_done(void);
void memory_load(int fp);
void memory_save(int fp);
void ws_sram_load(char *path);
void ws_sram_save(char *path);
void dump_memory();
#endif

921
oswan/source/nec/nec.cpp Normal file
View File

@@ -0,0 +1,921 @@
/****************************************************************************
NEC V30MZ(V20/V30/V33) emulator
Small changes made by toshi (Cycle count macros changed , "THROUGH" macro added)
Small changes made by dox@space.pl (Corrected bug in NEG instruction , different AUX flag handling in some opcodes)
(Re)Written June-September 2000 by Bryan McPhail (mish@tendril.co.uk) based
on code by Oliver Bergmann (Raul_Bloodworth@hotmail.com) who based code
on the i286 emulator by Fabrice Frances which had initial work based on
David Hedley's pcemu(!).
This new core features 99% accurate cycle counts for each processor,
there are still some complex situations where cycle counts are wrong,
typically where a few instructions have differing counts for odd/even
source and odd/even destination memory operands.
Flag settings are also correct for the NEC processors rather than the
I86 versions.
Nb: This emulation should be faster than previous NEC cores, but
because the old cycle count values were far too high in many cases
the processor has to do more 'work' than before, so the overall effect
may be a slower core.
****************************************************************************/
#include <stdio.h>
#include <string.h>
/*
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned int
#define INT8 signed char
#define INT16 signed short
#define INT32 signed int
*/
#include "source/types.h"
#include "nec.h"
#include "necintrf.h"
/***************************************************************************/
/* cpu state */
/***************************************************************************/
int nec_ICount;
nec_Regs I;
static UINT32 cpu_type;
static UINT32 prefix_base; /* base address of the latest prefix segment */
char seg_prefix; /* prefix segment indicator */
/* The interrupt number of a pending external interrupt pending NMI is 2. */
/* For INTR interrupts, the level is caught on the bus during an INTA cycle */
#include "necinstr.h"
#include "necea.h"
#include "necmodrm.h"
static int no_interrupt;
static UINT8 parity_table[256];
/***************************************************************************/
void nec_reset (void *param)
{
unsigned int i,j,c;
BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
memset( &I, 0, sizeof(I) );
no_interrupt=0;
I.sregs[CS] = 0xffff;
for (i = 0;i < 256; i++)
{
for (j = i, c = 0; j > 0; j >>= 1)
if (j & 1) c++;
parity_table[i] = !(c & 1);
}
I.ZeroVal = I.ParityVal = 1;
SetMD(1); /* set the mode-flag = native mode */
for (i = 0; i < 256; i++)
{
Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ;
}
for (i = 0xc0; i < 0x100; i++)
{
Mod_RM.RM.w[i] = (WREGS)( i & 7 );
Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
}
}
void nec_exit (void)
{
}
void nec_int(DWORD wektor)
{
DWORD dest_seg, dest_off;
if(I.IF)
{
i_pushf();
I.TF = I.IF = 0;
dest_off = ReadWord(wektor);
dest_seg = ReadWord(wektor+2);
PUSH(I.sregs[CS]);
PUSH(I.ip);
I.ip = (WORD)dest_off;
I.sregs[CS] = (WORD)dest_seg;
}
}
static void nec_interrupt(unsigned int_num, /*BOOLEAN*/ int md_flag)
{
UINT32 dest_seg, dest_off;
if (int_num == -1)
return;
i_pushf();
I.TF = I.IF = 0;
dest_off = ReadWord((int_num)*4);
dest_seg = ReadWord((int_num)*4+2);
PUSH(I.sregs[CS]);
PUSH(I.ip);
I.ip = (WORD)dest_off;
I.sregs[CS] = (WORD)dest_seg;
}
/****************************************************************************/
/* OPCODES */
/****************************************************************************/
#define OP(num,func_name) static void func_name(void)
OP( 0x00, i_add_br8 ) { DEF_br8; ADDB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x01, i_add_wr16 ) { DEF_wr16; ADDW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x02, i_add_r8b ) { DEF_r8b; ADDB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x03, i_add_r16w ) { DEF_r16w; ADDW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x04, i_add_ald8 ) { DEF_ald8; ADDB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x05, i_add_axd16) { DEF_axd16; ADDW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x06, i_push_es ) { PUSH(I.sregs[ES]); CLK(2); }
OP( 0x07, i_pop_es ) { POP(I.sregs[ES]); CLK(3); }
OP( 0x08, i_or_br8 ) { DEF_br8; ORB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x09, i_or_wr16 ) { DEF_wr16; ORW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x0a, i_or_r8b ) { DEF_r8b; ORB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x0b, i_or_r16w ) { DEF_r16w; ORW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x0e, i_push_cs ) { PUSH(I.sregs[CS]); CLK(2); }
OP( 0x0f, i_pre_nec ) { UINT32 ModRM, tmp, tmp2; /* pop cs at V30MZ? */
switch (FETCH) {
case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = I.regs.b[CL] & 0x7; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = I.regs.b[CL] & 0xf; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = I.regs.b[CL] & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
case 0x13 : BITOP_WORD; CLKS(5,5,4); tmp2 = I.regs.b[CL] & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
case 0x14 : BITOP_BYTE; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
case 0x15 : BITOP_WORD; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = I.regs.b[CL] & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH) & 0x7; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH) & 0xf; I.ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; I.CarryVal=I.OverVal=0; break; /* Test */
case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */
case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */
case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */
case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */
case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */
case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */
case 0x20 : ADD4S; CLKS(7,7,2); break;
case 0x22 : SUB4S; CLKS(7,7,2); break;
case 0x26 : CMP4S; CLKS(7,7,2); break;
case 0x28 : ModRM = FETCH; tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= I.regs.b[AL] & 0xf; I.regs.b[AL] = (I.regs.b[AL] & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(9,15); break;
case 0x2a : ModRM = FETCH; tmp = GetRMByte(ModRM); tmp2 = (I.regs.b[AL] & 0xf)<<4; I.regs.b[AL] = (I.regs.b[AL] & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(13,19); break;
case 0x31 : ModRM = FETCH; ModRM=0; break;
case 0x33 : ModRM = FETCH; ModRM=0; break;
case 0x92 : CLK(2); break; /* V25/35 FINT */
case 0xe0 : ModRM = FETCH; ModRM=0; break;
case 0xf0 : ModRM = FETCH; ModRM=0; break;
case 0xff : ModRM = FETCH; ModRM=0; break;
default: break;
}
}
OP( 0x10, i_adc_br8 ) { DEF_br8; src+=CF; ADDB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x11, i_adc_wr16 ) { DEF_wr16; src+=CF; ADDW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x12, i_adc_r8b ) { DEF_r8b; src+=CF; ADDB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x13, i_adc_r16w ) { DEF_r16w; src+=CF; ADDW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x14, i_adc_ald8 ) { DEF_ald8; src+=CF; ADDB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x15, i_adc_axd16) { DEF_axd16; src+=CF; ADDW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x16, i_push_ss ) { PUSH(I.sregs[SS]); CLK(2); }
OP( 0x17, i_pop_ss ) { POP(I.sregs[SS]); CLK(3); no_interrupt=1; }
OP( 0x18, i_sbb_br8 ) { DEF_br8; src+=CF; SUBB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x19, i_sbb_wr16 ) { DEF_wr16; src+=CF; SUBW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x1a, i_sbb_r8b ) { DEF_r8b; src+=CF; SUBB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x1b, i_sbb_r16w ) { DEF_r16w; src+=CF; SUBW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x1c, i_sbb_ald8 ) { DEF_ald8; src+=CF; SUBB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x1d, i_sbb_axd16) { DEF_axd16; src+=CF; SUBW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x1e, i_push_ds ) { PUSH(I.sregs[DS]); CLK(2); }
OP( 0x1f, i_pop_ds ) { POP(I.sregs[DS]); CLK(3); }
OP( 0x20, i_and_br8 ) { DEF_br8; ANDB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x21, i_and_wr16 ) { DEF_wr16; ANDW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x22, i_and_r8b ) { DEF_r8b; ANDB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x23, i_and_r16w ) { DEF_r16w; ANDW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x24, i_and_ald8 ) { DEF_ald8; ANDB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x25, i_and_axd16) { DEF_axd16; ANDW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x26, i_es ) { seg_prefix=TRUE; prefix_base=I.sregs[ES]<<4; CLK(1); nec_instruction[FETCHOP](); seg_prefix=FALSE; }
OP( 0x27, i_daa ) { ADJ4(6,0x60); CLK(10); }
OP( 0x28, i_sub_br8 ) { DEF_br8; SUBB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x29, i_sub_wr16 ) { DEF_wr16; SUBW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x2a, i_sub_r8b ) { DEF_r8b; SUBB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x2b, i_sub_r16w ) { DEF_r16w; SUBW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x2c, i_sub_ald8 ) { DEF_ald8; SUBB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x2d, i_sub_axd16) { DEF_axd16; SUBW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x2e, i_cs ) { seg_prefix=TRUE; prefix_base=I.sregs[CS]<<4; CLK(1); nec_instruction[FETCHOP](); seg_prefix=FALSE; }
OP( 0x2f, i_das ) { ADJ4(-6,-0x60); CLK(10); }
OP( 0x30, i_xor_br8 ) { DEF_br8; XORB; PutbackRMByte(ModRM,dst); CLKM(3,1); }
OP( 0x31, i_xor_wr16 ) { DEF_wr16; XORW; PutbackRMWord(ModRM,dst); CLKM(3,1); }
OP( 0x32, i_xor_r8b ) { DEF_r8b; XORB; RegByte(ModRM)=dst; CLKM(2,1); }
OP( 0x33, i_xor_r16w ) { DEF_r16w; XORW; RegWord(ModRM)=dst; CLKM(2,1); }
OP( 0x34, i_xor_ald8 ) { DEF_ald8; XORB; I.regs.b[AL]=dst; CLK(1); }
OP( 0x35, i_xor_axd16) { DEF_axd16; XORW; I.regs.w[AW]=dst; CLK(1); }
OP( 0x36, i_ss ) { seg_prefix=TRUE; prefix_base=I.sregs[SS]<<4; CLK(1); nec_instruction[FETCHOP](); seg_prefix=FALSE; }
OP( 0x37, i_aaa ) { ADJB(6,1); CLK(9); }
OP( 0x38, i_cmp_br8 ) { DEF_br8; SUBB; CLKM(2,1); }
OP( 0x39, i_cmp_wr16 ) { DEF_wr16; SUBW; CLKM(2,1); }
OP( 0x3a, i_cmp_r8b ) { DEF_r8b; SUBB; CLKM(2,1); }
OP( 0x3b, i_cmp_r16w ) { DEF_r16w; SUBW; CLKM(2,1); }
OP( 0x3c, i_cmp_ald8 ) { DEF_ald8; SUBB; CLK(1); }
OP( 0x3d, i_cmp_axd16) { DEF_axd16; SUBW; CLK(1); }
OP( 0x3e, i_ds ) { seg_prefix=TRUE; prefix_base=I.sregs[DS]<<4; CLK(1); nec_instruction[FETCHOP](); seg_prefix=FALSE; }
OP( 0x3f, i_aas ) { ADJB(-6,-1); CLK(9); }
OP( 0x40, i_inc_ax ) { IncWordReg(AW); CLK(1); }
OP( 0x41, i_inc_cx ) { IncWordReg(CW); CLK(1); }
OP( 0x42, i_inc_dx ) { IncWordReg(DW); CLK(1); }
OP( 0x43, i_inc_bx ) { IncWordReg(BW); CLK(1); }
OP( 0x44, i_inc_sp ) { IncWordReg(SP); CLK(1); }
OP( 0x45, i_inc_bp ) { IncWordReg(BP); CLK(1); }
OP( 0x46, i_inc_si ) { IncWordReg(IX); CLK(1); }
OP( 0x47, i_inc_di ) { IncWordReg(IY); CLK(1); }
OP( 0x48, i_dec_ax ) { DecWordReg(AW); CLK(1); }
OP( 0x49, i_dec_cx ) { DecWordReg(CW); CLK(1); }
OP( 0x4a, i_dec_dx ) { DecWordReg(DW); CLK(1); }
OP( 0x4b, i_dec_bx ) { DecWordReg(BW); CLK(1); }
OP( 0x4c, i_dec_sp ) { DecWordReg(SP); CLK(1); }
OP( 0x4d, i_dec_bp ) { DecWordReg(BP); CLK(1); }
OP( 0x4e, i_dec_si ) { DecWordReg(IX); CLK(1); }
OP( 0x4f, i_dec_di ) { DecWordReg(IY); CLK(1); }
OP( 0x50, i_push_ax ) { PUSH(I.regs.w[AW]); CLK(1); }
OP( 0x51, i_push_cx ) { PUSH(I.regs.w[CW]); CLK(1); }
OP( 0x52, i_push_dx ) { PUSH(I.regs.w[DW]); CLK(1); }
OP( 0x53, i_push_bx ) { PUSH(I.regs.w[BW]); CLK(1); }
OP( 0x54, i_push_sp ) { PUSH(I.regs.w[SP]); CLK(1); }
OP( 0x55, i_push_bp ) { PUSH(I.regs.w[BP]); CLK(1); }
OP( 0x56, i_push_si ) { PUSH(I.regs.w[IX]); CLK(1); }
OP( 0x57, i_push_di ) { PUSH(I.regs.w[IY]); CLK(1); }
OP( 0x58, i_pop_ax ) { POP(I.regs.w[AW]); CLK(1); }
OP( 0x59, i_pop_cx ) { POP(I.regs.w[CW]); CLK(1); }
OP( 0x5a, i_pop_dx ) { POP(I.regs.w[DW]); CLK(1); }
OP( 0x5b, i_pop_bx ) { POP(I.regs.w[BW]); CLK(1); }
OP( 0x5c, i_pop_sp ) { POP(I.regs.w[SP]); CLK(1); }
OP( 0x5d, i_pop_bp ) { POP(I.regs.w[BP]); CLK(1); }
OP( 0x5e, i_pop_si ) { POP(I.regs.w[IX]); CLK(1); }
OP( 0x5f, i_pop_di ) { POP(I.regs.w[IY]); CLK(1); }
OP( 0x60, i_pusha ) {
unsigned tmp=I.regs.w[SP];
PUSH(I.regs.w[AW]);
PUSH(I.regs.w[CW]);
PUSH(I.regs.w[DW]);
PUSH(I.regs.w[BW]);
PUSH(tmp);
PUSH(I.regs.w[BP]);
PUSH(I.regs.w[IX]);
PUSH(I.regs.w[IY]);
CLK(9);
}
OP( 0x61, i_popa ) {
unsigned tmp;
POP(I.regs.w[IY]);
POP(I.regs.w[IX]);
POP(I.regs.w[BP]);
POP(tmp);
POP(I.regs.w[BW]);
POP(I.regs.w[DW]);
POP(I.regs.w[CW]);
POP(I.regs.w[AW]);
CLK(8);
}
OP( 0x62, i_chkind ) {
UINT32 low,high,tmp;
GetModRM;
low = GetRMWord(ModRM);
high= GetnextRMWord;
tmp= RegWord(ModRM);
if (tmp<low || tmp>high) {
nec_interrupt(5,0);
CLK(7);
}
CLK(13);
}
/* OP 0x64 - 0x67 is nop at V30MZ */
OP( 0x64, i_repnc ) { UINT32 next = FETCHOP; UINT16 c = I.regs.w[CW];
switch(next) { /* Segments */
case 0x26: seg_prefix=TRUE; prefix_base=I.sregs[ES]<<4; next = FETCHOP; CLK(2); break;
case 0x2e: seg_prefix=TRUE; prefix_base=I.sregs[CS]<<4; next = FETCHOP; CLK(2); break;
case 0x36: seg_prefix=TRUE; prefix_base=I.sregs[SS]<<4; next = FETCHOP; CLK(2); break;
case 0x3e: seg_prefix=TRUE; prefix_base=I.sregs[DS]<<4; next = FETCHOP; CLK(2); break;
}
switch(next) {
case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xa6: CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xa7: CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xae: CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
case 0xaf: CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && !CF); I.regs.w[CW]=c; break;
default: nec_instruction[next]();
}
seg_prefix=FALSE;
}
OP( 0x65, i_repc ) { UINT32 next = FETCHOP; UINT16 c = I.regs.w[CW];
switch(next) { /* Segments */
case 0x26: seg_prefix=TRUE; prefix_base=I.sregs[ES]<<4; next = FETCHOP; CLK(2); break;
case 0x2e: seg_prefix=TRUE; prefix_base=I.sregs[CS]<<4; next = FETCHOP; CLK(2); break;
case 0x36: seg_prefix=TRUE; prefix_base=I.sregs[SS]<<4; next = FETCHOP; CLK(2); break;
case 0x3e: seg_prefix=TRUE; prefix_base=I.sregs[DS]<<4; next = FETCHOP; CLK(2); break;
}
switch(next) {
case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xa6: CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xa7: CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xae: CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
case 0xaf: CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && CF); I.regs.w[CW]=c; break;
default: nec_instruction[next]();
}
seg_prefix=FALSE;
}
OP( 0x68, i_push_d16 ) { UINT32 tmp; FETCHWORD(tmp); PUSH(tmp); CLK(1); }
OP( 0x69, i_imul_d16 ) { UINT32 tmp; DEF_r16w; FETCHWORD(tmp); dst = (INT32)((INT16)src)*(INT32)((INT16)tmp); I.CarryVal = I.OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; CLKM(4,3);}
OP( 0x6a, i_push_d8 ) { UINT32 tmp = (WORD)((INT16)((INT8)FETCH)); PUSH(tmp); CLK(1); }
OP( 0x6b, i_imul_d8 ) { UINT32 src2; DEF_r16w; src2= (WORD)((INT16)((INT8)FETCH)); dst = (INT32)((INT16)src)*(INT32)((INT16)src2); I.CarryVal = I.OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; CLKM(4,3); }
OP( 0x6c, i_insb ) { PutMemB(ES,I.regs.w[IY],read_port(I.regs.w[DW])); I.regs.w[IY]+= -2 * I.DF + 1; CLK(6); }
OP( 0x6d, i_insw ) { PutMemB(ES,I.regs.w[IY],read_port(I.regs.w[DW])); PutMemB(ES,(I.regs.w[IY]+1)&0xffff,read_port((I.regs.w[DW]+1)&0xffff)); I.regs.w[IY]+= -4 * I.DF + 2; CLK(6); }
OP( 0x6e, i_outsb ) { write_port(I.regs.w[DW],GetMemB(DS,I.regs.w[IX])); I.regs.w[IX]+= -2 * I.DF + 1; CLK(7); }
OP( 0x6f, i_outsw ) { write_port(I.regs.w[DW],GetMemB(DS,I.regs.w[IX])); write_port((I.regs.w[DW]+1)&0xffff,GetMemB(DS,(I.regs.w[IX]+1)&0xffff)); I.regs.w[IX]+= -4 * I.DF + 2; CLK(7); }
OP( 0x70, i_jo ) { JMP( OF); CLK(1); }
OP( 0x71, i_jno ) { JMP(!OF); CLK(1); }
OP( 0x72, i_jc ) { JMP( CF); CLK(1); }
OP( 0x73, i_jnc ) { JMP(!CF); CLK(1); }
OP( 0x74, i_jz ) { JMP( ZF); CLK(1); }
OP( 0x75, i_jnz ) { JMP(!ZF); CLK(1); }
OP( 0x76, i_jce ) { JMP(CF || ZF); CLK(1); }
OP( 0x77, i_jnce ) { JMP(!(CF || ZF)); CLK(1); }
OP( 0x78, i_js ) { JMP( SF); CLK(1); }
OP( 0x79, i_jns ) { JMP(!SF); CLK(1); }
OP( 0x7a, i_jp ) { JMP( PF); CLK(1); }
OP( 0x7b, i_jnp ) { JMP(!PF); CLK(1); }
OP( 0x7c, i_jl ) { JMP((SF!=OF)&&(!ZF)); CLK(1); }
OP( 0x7d, i_jnl ) { JMP((ZF)||(SF==OF)); CLK(1); }
OP( 0x7e, i_jle ) { JMP((ZF)||(SF!=OF)); CLK(1); }
OP( 0x7f, i_jnle ) { JMP((SF==OF)&&(!ZF)); CLK(1); }
OP( 0x80, i_80pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH;
CLKM(3,1)
switch (ModRM & 0x38) {
case 0x00: ADDB; PutbackRMByte(ModRM,dst); break;
case 0x08: ORB; PutbackRMByte(ModRM,dst); break;
case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break;
case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break;
case 0x20: ANDB; PutbackRMByte(ModRM,dst); break;
case 0x28: SUBB; PutbackRMByte(ModRM,dst); break;
case 0x30: XORB; PutbackRMByte(ModRM,dst); break;
case 0x38: SUBB; break; /* CMP */
}
}
OP( 0x81, i_81pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH; src+= (FETCH << 8);
CLKM(3,1)
switch (ModRM & 0x38) {
case 0x00: ADDW; PutbackRMWord(ModRM,dst); break;
case 0x08: ORW; PutbackRMWord(ModRM,dst); break;
case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break;
case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break;
case 0x20: ANDW; PutbackRMWord(ModRM,dst); break;
case 0x28: SUBW; PutbackRMWord(ModRM,dst); break;
case 0x30: XORW; PutbackRMWord(ModRM,dst); break;
case 0x38: SUBW; break; /* CMP */
}
}
OP( 0x82, i_82pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((INT8)FETCH);
CLKM(3,1)
switch (ModRM & 0x38) {
case 0x00: ADDB; PutbackRMByte(ModRM,dst); break;
case 0x08: ORB; PutbackRMByte(ModRM,dst); break;
case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break;
case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break;
case 0x20: ANDB; PutbackRMByte(ModRM,dst); break;
case 0x28: SUBB; PutbackRMByte(ModRM,dst); break;
case 0x30: XORB; PutbackRMByte(ModRM,dst); break;
case 0x38: SUBB; break; /* CMP */
}
}
OP( 0x83, i_83pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((INT16)((INT8)FETCH));
CLKM(3,1)
switch (ModRM & 0x38) {
case 0x00: ADDW; PutbackRMWord(ModRM,dst); break;
case 0x08: ORW; PutbackRMWord(ModRM,dst); break;
case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break;
case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break;
case 0x20: ANDW; PutbackRMWord(ModRM,dst); break;
case 0x28: SUBW; PutbackRMWord(ModRM,dst); break;
case 0x30: XORW; PutbackRMWord(ModRM,dst); break;
case 0x38: SUBW; break; /* CMP */
}
}
OP( 0x84, i_test_br8 ) { DEF_br8; ANDB; CLKM(2,1); }
OP( 0x85, i_test_wr16 ) { DEF_wr16; ANDW; CLKM(2,1); }
OP( 0x86, i_xchg_br8 ) { DEF_br8; RegByte(ModRM)=dst; PutbackRMByte(ModRM,src); CLKM(5,3); }
OP( 0x87, i_xchg_wr16 ) { DEF_wr16; RegWord(ModRM)=dst; PutbackRMWord(ModRM,src); CLKM(5,3); }
OP( 0x88, i_mov_br8 ) { UINT8 src; GetModRM; src = RegByte(ModRM); PutRMByte(ModRM,src); CLKM(1,1); }
OP( 0x89, i_mov_wr16 ) { UINT16 src; GetModRM; src = RegWord(ModRM); PutRMWord(ModRM,src); CLKM(1,1); }
OP( 0x8a, i_mov_r8b ) { UINT8 src; GetModRM; src = GetRMByte(ModRM); RegByte(ModRM)=src; CLKM(1,1); }
OP( 0x8b, i_mov_r16w ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); RegWord(ModRM)=src; CLKM(1,1); }
OP( 0x8c, i_mov_wsreg ) { GetModRM; PutRMWord(ModRM,I.sregs[(ModRM & 0x38) >> 3]); CLKM(1,1); }
OP( 0x8d, i_lea ) { UINT16 ModRM = FETCH; (void)(*GetEA[ModRM])(); RegWord(ModRM)=EO; CLK(1); }
OP( 0x8e, i_mov_sregw ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); CLKM(3,2);
switch (ModRM & 0x38) {
case 0x00: I.sregs[ES] = src; break; /* mov es,ew */
case 0x08: I.sregs[CS] = src; break; /* mov cs,ew */
case 0x10: I.sregs[SS] = src; break; /* mov ss,ew */
case 0x18: I.sregs[DS] = src; break; /* mov ds,ew */
default: ;
}
no_interrupt=1;
}
OP( 0x8f, i_popw ) { UINT16 tmp; GetModRM; POP(tmp); PutRMWord(ModRM,tmp); CLKM(3,1); }
OP( 0x90, i_nop ) { CLK(1);
/* Cycle skip for idle loops (0: NOP 1: JMP 0) */
if (no_interrupt==0 && nec_ICount>0 && (PEEKOP((I.sregs[CS]<<4)+I.ip))==0xeb && (PEEK((I.sregs[CS]<<4)+I.ip+1))==0xfd)
nec_ICount%=15;
}
OP( 0x91, i_xchg_axcx ) { XchgAWReg(CW); CLK(3); }
OP( 0x92, i_xchg_axdx ) { XchgAWReg(DW); CLK(3); }
OP( 0x93, i_xchg_axbx ) { XchgAWReg(BW); CLK(3); }
OP( 0x94, i_xchg_axsp ) { XchgAWReg(SP); CLK(3); }
OP( 0x95, i_xchg_axbp ) { XchgAWReg(BP); CLK(3); }
OP( 0x96, i_xchg_axsi ) { XchgAWReg(IX); CLK(3); }
OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); }
OP( 0x98, i_cbw ) { I.regs.b[AH] = (I.regs.b[AL] & 0x80) ? 0xff : 0; CLK(1); }
OP( 0x99, i_cwd ) { I.regs.w[DW] = (I.regs.b[AH] & 0x80) ? 0xffff : 0; CLK(1); }
OP( 0x9a, i_call_far ) { UINT32 tmp, tmp2; FETCHWORD(tmp); FETCHWORD(tmp2); PUSH(I.sregs[CS]); PUSH(I.ip); I.ip = (WORD)tmp; I.sregs[CS] = (WORD)tmp2; CLK(10); }
OP( 0x9b, i_wait ) { ; }
OP( 0x9c, i_pushf ) { PUSH( CompressFlags() ); CLK(2); }
OP( 0x9d, i_popf ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLK(3);}
OP( 0x9e, i_sahf ) { UINT32 tmp = (CompressFlags() & 0xff00) | (I.regs.b[AH] & 0xd5); ExpandFlags(tmp); CLK(4); }
OP( 0x9f, i_lahf ) { I.regs.b[AH] = CompressFlags() & 0xff; CLK(2); }
OP( 0xa0, i_mov_aldisp ) { UINT32 addr; FETCHWORD(addr); I.regs.b[AL] = GetMemB(DS, addr); CLK(1); }
OP( 0xa1, i_mov_axdisp ) { UINT32 addr; FETCHWORD(addr); I.regs.b[AL] = GetMemB(DS, addr); I.regs.b[AH] = GetMemB(DS, (addr+1)&0xffff); CLK(1); }
OP( 0xa2, i_mov_dispal ) { UINT32 addr; FETCHWORD(addr); PutMemB(DS, addr, I.regs.b[AL]); CLK(1); }
OP( 0xa3, i_mov_dispax ) { UINT32 addr; FETCHWORD(addr); PutMemB(DS, addr, I.regs.b[AL]); PutMemB(DS, (addr+1)&0xffff, I.regs.b[AH]); CLK(1); }
OP( 0xa4, i_movsb ) { UINT32 tmp = GetMemB(DS,I.regs.w[IX]); PutMemB(ES,I.regs.w[IY], tmp); I.regs.w[IY] += -2 * I.DF + 1; I.regs.w[IX] += -2 * I.DF + 1; CLK(5); }
OP( 0xa5, i_movsw ) { UINT32 tmp = GetMemW(DS,I.regs.w[IX]); PutMemW(ES,I.regs.w[IY], tmp); I.regs.w[IY] += -4 * I.DF + 2; I.regs.w[IX] += -4 * I.DF + 2; CLK(5); }
OP( 0xa6, i_cmpsb ) { UINT32 src = GetMemB(ES, I.regs.w[IY]); UINT32 dst = GetMemB(DS, I.regs.w[IX]); SUBB; I.regs.w[IY] += -2 * I.DF + 1; I.regs.w[IX] += -2 * I.DF + 1; CLK(6); }
OP( 0xa7, i_cmpsw ) { UINT32 src = GetMemW(ES, I.regs.w[IY]); UINT32 dst = GetMemW(DS, I.regs.w[IX]); SUBW; I.regs.w[IY] += -4 * I.DF + 2; I.regs.w[IX] += -4 * I.DF + 2; CLK(6); }
OP( 0xa8, i_test_ald8 ) { DEF_ald8; ANDB; CLK(1); }
OP( 0xa9, i_test_axd16 ) { DEF_axd16; ANDW; CLK(1); }
OP( 0xaa, i_stosb ) { PutMemB(ES,I.regs.w[IY],I.regs.b[AL]); I.regs.w[IY] += -2 * I.DF + 1; CLK(3); }
OP( 0xab, i_stosw ) { PutMemW(ES,I.regs.w[IY],I.regs.w[AW]); I.regs.w[IY] += -4 * I.DF + 2; CLK(3); }
OP( 0xac, i_lodsb ) { I.regs.b[AL] = GetMemB(DS,I.regs.w[IX]); I.regs.w[IX] += -2 * I.DF + 1; CLK(3); }
OP( 0xad, i_lodsw ) { I.regs.w[AW] = GetMemW(DS,I.regs.w[IX]); I.regs.w[IX] += -4 * I.DF + 2; CLK(3); }
OP( 0xae, i_scasb ) { UINT32 src = GetMemB(ES, I.regs.w[IY]); UINT32 dst = I.regs.b[AL]; SUBB; I.regs.w[IY] += -2 * I.DF + 1; CLK(4); }
OP( 0xaf, i_scasw ) { UINT32 src = GetMemW(ES, I.regs.w[IY]); UINT32 dst = I.regs.w[AW]; SUBW; I.regs.w[IY] += -4 * I.DF + 2; CLK(4); }
OP( 0xb0, i_mov_ald8 ) { I.regs.b[AL] = FETCH; CLK(1); }
OP( 0xb1, i_mov_cld8 ) { I.regs.b[CL] = FETCH; CLK(1); }
OP( 0xb2, i_mov_dld8 ) { I.regs.b[DL] = FETCH; CLK(1); }
OP( 0xb3, i_mov_bld8 ) { I.regs.b[BL] = FETCH; CLK(1); }
OP( 0xb4, i_mov_ahd8 ) { I.regs.b[AH] = FETCH; CLK(1); }
OP( 0xb5, i_mov_chd8 ) { I.regs.b[CH] = FETCH; CLK(1); }
OP( 0xb6, i_mov_dhd8 ) { I.regs.b[DH] = FETCH; CLK(1); }
OP( 0xb7, i_mov_bhd8 ) { I.regs.b[BH] = FETCH; CLK(1); }
OP( 0xb8, i_mov_axd16 ) { I.regs.b[AL] = FETCH; I.regs.b[AH] = FETCH; CLK(1); }
OP( 0xb9, i_mov_cxd16 ) { I.regs.b[CL] = FETCH; I.regs.b[CH] = FETCH; CLK(1); }
OP( 0xba, i_mov_dxd16 ) { I.regs.b[DL] = FETCH; I.regs.b[DH] = FETCH; CLK(1); }
OP( 0xbb, i_mov_bxd16 ) { I.regs.b[BL] = FETCH; I.regs.b[BH] = FETCH; CLK(1); }
OP( 0xbc, i_mov_spd16 ) { I.regs.b[SPL] = FETCH; I.regs.b[SPH] = FETCH; CLK(1); }
OP( 0xbd, i_mov_bpd16 ) { I.regs.b[BPL] = FETCH; I.regs.b[BPH] = FETCH; CLK(1); }
OP( 0xbe, i_mov_sid16 ) { I.regs.b[IXL] = FETCH; I.regs.b[IXH] = FETCH; CLK(1); }
OP( 0xbf, i_mov_did16 ) { I.regs.b[IYL] = FETCH; I.regs.b[IYH] = FETCH; CLK(1); }
OP( 0xc0, i_rotshft_bd8 ) {
UINT32 src, dst; UINT8 c;
GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src;
c=FETCH;
c&=0x1f;
CLKM(5,3);
if (c) switch (ModRM & 0x38) {
case 0x00: do { ROL_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x08: do { ROR_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x10: do { ROLC_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x18: do { RORC_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x20: SHL_BYTE(c); I.AuxVal = 1; break;//
case 0x28: SHR_BYTE(c); I.AuxVal = 1; break;//
case 0x30: break;
case 0x38: SHRA_BYTE(c); break;
}
}
OP( 0xc1, i_rotshft_wd8 ) {
UINT32 src, dst; UINT8 c;
GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src;
c=FETCH;
c&=0x1f;
CLKM(5,3);
if (c) switch (ModRM & 0x38) {
case 0x00: do { ROL_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x08: do { ROR_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x10: do { ROLC_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x18: do { RORC_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x20: SHL_WORD(c); I.AuxVal = 1; break;
case 0x28: SHR_WORD(c); I.AuxVal = 1; break;
case 0x30: break;
case 0x38: SHRA_WORD(c); break;
}
}
OP( 0xc2, i_ret_d16 ) { UINT32 count = FETCH; count += FETCH << 8; POP(I.ip); I.regs.w[SP]+=count; CLK(6); }
OP( 0xc3, i_ret ) { POP(I.ip); CLK(6); }
OP( 0xc4, i_les_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; I.sregs[ES] = GetnextRMWord; CLK(6); }
OP( 0xc5, i_lds_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; I.sregs[DS] = GetnextRMWord; CLK(6); }
OP( 0xc6, i_mov_bd8 ) { GetModRM; PutImmRMByte(ModRM); CLK(1); }
OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); CLK(1); }
OP( 0xc8, i_enter ) {
UINT32 nb = FETCH;
UINT32 i,level;
CLK(19);
nb += FETCH << 8;
level = FETCH;
PUSH(I.regs.w[BP]);
I.regs.w[BP]=I.regs.w[SP];
I.regs.w[SP] -= nb;
for (i=1;i<level;i++) {
PUSH(GetMemW(SS,I.regs.w[BP]-i*2));
CLK(4);
}
if (level) PUSH(I.regs.w[BP]);
}
OP( 0xc9, i_leave ) {
I.regs.w[SP]=I.regs.w[BP];
POP(I.regs.w[BP]);
CLK(2);
}
OP( 0xca, i_retf_d16 ) { UINT32 count = FETCH; count += FETCH << 8; POP(I.ip); POP(I.sregs[CS]); I.regs.w[SP]+=count; CLK(9); }
OP( 0xcb, i_retf ) { POP(I.ip); POP(I.sregs[CS]); CLK(8); }
OP( 0xcc, i_int3 ) { nec_interrupt(3,0); CLK(9); }
OP( 0xcd, i_int ) { nec_interrupt(FETCH,0); CLK(10); }
OP( 0xce, i_into ) { if (OF) { nec_interrupt(4,0); CLK(13); } else CLK(6); }
OP( 0xcf, i_iret ) { POP(I.ip); POP(I.sregs[CS]); i_popf(); CLK(10); }
OP( 0xd0, i_rotshft_b ) {
UINT32 src, dst; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
CLKM(3,1);
switch (ModRM & 0x38) {
case 0x00: ROL_BYTE; PutbackRMByte(ModRM,(BYTE)dst); I.OverVal = (src^dst)&0x80; break;
case 0x08: ROR_BYTE; PutbackRMByte(ModRM,(BYTE)dst); I.OverVal = (src^dst)&0x80; break;
case 0x10: ROLC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); I.OverVal = (src^dst)&0x80; break;
case 0x18: RORC_BYTE; PutbackRMByte(ModRM,(BYTE)dst); I.OverVal = (src^dst)&0x80; break;
case 0x20: SHL_BYTE(1); I.OverVal = (src^dst)&0x80;I.AuxVal = 1; break;
case 0x28: SHR_BYTE(1); I.OverVal = (src^dst)&0x80;I.AuxVal = 1; break;
case 0x30: break;
case 0x38: SHRA_BYTE(1); I.OverVal = 0; break;
}
}
OP( 0xd1, i_rotshft_w ) {
UINT32 src, dst; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
CLKM(3,1);
switch (ModRM & 0x38) {
case 0x00: ROL_WORD; PutbackRMWord(ModRM,(WORD)dst); I.OverVal = (src^dst)&0x8000; break;
case 0x08: ROR_WORD; PutbackRMWord(ModRM,(WORD)dst); I.OverVal = (src^dst)&0x8000; break;
case 0x10: ROLC_WORD; PutbackRMWord(ModRM,(WORD)dst); I.OverVal = (src^dst)&0x8000; break;
case 0x18: RORC_WORD; PutbackRMWord(ModRM,(WORD)dst); I.OverVal = (src^dst)&0x8000; break;
case 0x20: SHL_WORD(1); I.AuxVal = 1;I.OverVal = (src^dst)&0x8000; break;
case 0x28: SHR_WORD(1); I.AuxVal = 1;I.OverVal = (src^dst)&0x8000; break;
case 0x30: break;
case 0x38: SHRA_WORD(1); I.AuxVal = 1;I.OverVal = 0; break;
}
}
OP( 0xd2, i_rotshft_bcl ) {
UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src;
c=I.regs.b[CL];
CLKM(5,3);
c&=0x1f;
if (c) switch (ModRM & 0x38) {
case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x08: do { ROR_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x10: do { ROLC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x18: do { RORC_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break;
case 0x20: SHL_BYTE(c); I.AuxVal = 1; break;
case 0x28: SHR_BYTE(c); I.AuxVal = 1;break;
case 0x30: break;
case 0x38: SHRA_BYTE(c); break;
}
}
OP( 0xd3, i_rotshft_wcl ) {
UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src;
c=I.regs.b[CL];
c&=0x1f;
CLKM(5,3);
if (c) switch (ModRM & 0x38) {
case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x08: do { ROR_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x10: do { ROLC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x18: do { RORC_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break;
case 0x20: SHL_WORD(c); I.AuxVal = 1; break;
case 0x28: SHR_WORD(c); I.AuxVal = 1; break;
case 0x30: break;
case 0x38: SHRA_WORD(c); break;
}
}
OP( 0xd4, i_aam ) { UINT32 mult=FETCH; mult=0; I.regs.b[AH] = I.regs.b[AL] / 10; I.regs.b[AL] %= 10; SetSZPF_Word(I.regs.w[AW]); CLK(17); }
OP( 0xd5, i_aad ) { UINT32 mult=FETCH; mult=0; I.regs.b[AL] = I.regs.b[AH] * 10 + I.regs.b[AL]; I.regs.b[AH] = 0; SetSZPF_Byte(I.regs.b[AL]); CLK(6); }
OP( 0xd6, i_setalc ) { I.regs.b[AL] = (CF)?0xff:0x00; CLK(3); } /* nop at V30MZ? */
OP( 0xd7, i_trans ) { UINT32 dest = (I.regs.w[BW]+I.regs.b[AL])&0xffff; I.regs.b[AL] = GetMemB(DS, dest); CLK(5); }
OP( 0xd8, i_fpo ) { GetModRM; CLK(3); } /* nop at V30MZ? */
OP( 0xe0, i_loopne ) { INT8 disp = (INT8)FETCH; I.regs.w[CW]--; if (!ZF && I.regs.w[CW]) { I.ip = (WORD)(I.ip+disp); CLK(6); } else CLK(3); }
OP( 0xe1, i_loope ) { INT8 disp = (INT8)FETCH; I.regs.w[CW]--; if ( ZF && I.regs.w[CW]) { I.ip = (WORD)(I.ip+disp); CLK(6); } else CLK(3); }
OP( 0xe2, i_loop ) { INT8 disp = (INT8)FETCH; I.regs.w[CW]--; if (I.regs.w[CW]) { I.ip = (WORD)(I.ip+disp); CLK(5); } else CLK(2); }
OP( 0xe3, i_jcxz ) { INT8 disp = (INT8)FETCH; if (I.regs.w[CW] == 0) { I.ip = (WORD)(I.ip+disp); CLK(4); } else CLK(1); }
OP( 0xe4, i_inal ) { UINT8 port = FETCH; I.regs.b[AL] = read_port(port); CLK(6); }
OP( 0xe5, i_inax ) { UINT8 port = FETCH; I.regs.b[AL] = read_port(port); I.regs.b[AH] = read_port(port+1); CLK(6); }
OP( 0xe6, i_outal ) { UINT8 port = FETCH; write_port(port, I.regs.b[AL]); CLK(6); }
OP( 0xe7, i_outax ) { UINT8 port = FETCH; write_port(port, I.regs.b[AL]); write_port(port+1, I.regs.b[AH]); CLK(6); }
OP( 0xe8, i_call_d16 ) { UINT32 tmp; FETCHWORD(tmp); PUSH(I.ip); I.ip = (WORD)(I.ip+(INT16)tmp); CLK(5); }
OP( 0xe9, i_jmp_d16 ) { UINT32 tmp; FETCHWORD(tmp); I.ip = (WORD)(I.ip+(INT16)tmp); CLK(4); }
OP( 0xea, i_jmp_far ) { UINT32 tmp,tmp1; FETCHWORD(tmp); FETCHWORD(tmp1); I.sregs[CS] = (WORD)tmp1; I.ip = (WORD)tmp; CLK(7); }
OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((INT8)FETCH); CLK(4);
if (tmp==-2 && no_interrupt==0 && nec_ICount>0) nec_ICount%=12; /* cycle skip */
I.ip = (WORD)(I.ip+tmp);
}
OP( 0xec, i_inaldx ) { I.regs.b[AL] = read_port(I.regs.w[DW]); CLK(6);}
OP( 0xed, i_inaxdx ) { UINT32 port = I.regs.w[DW]; I.regs.b[AL] = read_port(port); I.regs.b[AH] = read_port(port+1); CLK(6); }
OP( 0xee, i_outdxal ) { write_port(I.regs.w[DW], I.regs.b[AL]); CLK(6); }
OP( 0xef, i_outdxax ) { UINT32 port = I.regs.w[DW]; write_port(port, I.regs.b[AL]); write_port(port+1, I.regs.b[AH]); CLK(6); }
OP( 0xf0, i_lock ) { no_interrupt=1; CLK(1); }
#define THROUGH \
if(nec_ICount<0){ \
if(seg_prefix) \
I.ip-=(UINT16)3; \
else \
I.ip-=(UINT16)2; \
break;}
OP( 0xf2, i_repne ) { UINT32 next = FETCHOP; UINT16 c = I.regs.w[CW];
switch(next) { /* Segments */
case 0x26: seg_prefix=TRUE; prefix_base=I.sregs[ES]<<4; next = FETCHOP; CLK(2); break;
case 0x2e: seg_prefix=TRUE; prefix_base=I.sregs[CS]<<4; next = FETCHOP; CLK(2); break;
case 0x36: seg_prefix=TRUE; prefix_base=I.sregs[SS]<<4; next = FETCHOP; CLK(2); break;
case 0x3e: seg_prefix=TRUE; prefix_base=I.sregs[DS]<<4; next = FETCHOP; CLK(2); break;
}
switch(next) {
case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xa6: CLK(5); if (c) do { THROUGH; i_cmpsb(); c--; CLK(3); } while (c>0 && ZF==0); I.regs.w[CW]=c; break;
case 0xa7: CLK(5); if (c) do { THROUGH; i_cmpsw(); c--; CLK(3); } while (c>0 && ZF==0); I.regs.w[CW]=c; break;
case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0); I.regs.w[CW]=c; break;
case 0xae: CLK(5); if (c) do { THROUGH; i_scasb(); c--; CLK(5); } while (c>0 && ZF==0); I.regs.w[CW]=c; break;
case 0xaf: CLK(5); if (c) do { THROUGH; i_scasw(); c--; CLK(5); } while (c>0 && ZF==0); I.regs.w[CW]=c; break;
default: nec_instruction[next]();
}
seg_prefix=FALSE;
}
OP( 0xf3, i_repe ) { UINT32 next = FETCHOP; UINT16 c = I.regs.w[CW];
switch(next) { /* Segments */
case 0x26: seg_prefix=TRUE; prefix_base=I.sregs[ES]<<4; next = FETCHOP; CLK(2); break;
case 0x2e: seg_prefix=TRUE; prefix_base=I.sregs[CS]<<4; next = FETCHOP; CLK(2); break;
case 0x36: seg_prefix=TRUE; prefix_base=I.sregs[SS]<<4; next = FETCHOP; CLK(2); break;
case 0x3e: seg_prefix=TRUE; prefix_base=I.sregs[DS]<<4; next = FETCHOP; CLK(2); break;
}
switch(next) {
case 0x6c: CLK(5); if (c) do { THROUGH; i_insb(); c--; CLK( 0); } while (c>0); I.regs.w[CW]=c; break;
case 0x6d: CLK(5); if (c) do { THROUGH; i_insw(); c--; CLK( 0); } while (c>0); I.regs.w[CW]=c; break;
case 0x6e: CLK(5); if (c) do { THROUGH; i_outsb(); c--; CLK(-1); } while (c>0); I.regs.w[CW]=c; break;
case 0x6f: CLK(5); if (c) do { THROUGH; i_outsw(); c--; CLK(-1); } while (c>0); I.regs.w[CW]=c; break;
case 0xa4: CLK(5); if (c) do { THROUGH; i_movsb(); c--; CLK( 2); } while (c>0); I.regs.w[CW]=c; break;
case 0xa5: CLK(5); if (c) do { THROUGH; i_movsw(); c--; CLK( 2); } while (c>0); I.regs.w[CW]=c; break;
case 0xa6: CLK(5); if (c) do { THROUGH; i_cmpsb(); c--; CLK( 4); } while (c>0 && ZF==1); I.regs.w[CW]=c; break;
case 0xa7: CLK(5); if (c) do { THROUGH; i_cmpsw(); c--; CLK( 4); } while (c>0 && ZF==1); I.regs.w[CW]=c; break;
case 0xaa: CLK(5); if (c) do { THROUGH; i_stosb(); c--; CLK( 3); } while (c>0); I.regs.w[CW]=c; break;
case 0xab: CLK(5); if (c) do { THROUGH; i_stosw(); c--; CLK( 3); } while (c>0); I.regs.w[CW]=c; break;
case 0xac: CLK(5); if (c) do { THROUGH; i_lodsb(); c--; CLK( 3); } while (c>0); I.regs.w[CW]=c; break;
case 0xad: CLK(5); if (c) do { THROUGH; i_lodsw(); c--; CLK( 3); } while (c>0); I.regs.w[CW]=c; break;
case 0xae: CLK(5); if (c) do { THROUGH; i_scasb(); c--; CLK( 4); } while (c>0 && ZF==1); I.regs.w[CW]=c; break;
case 0xaf: CLK(5); if (c) do { THROUGH; i_scasw(); c--; CLK( 4); } while (c>0 && ZF==1); I.regs.w[CW]=c; break;
default: nec_instruction[next]();
}
seg_prefix=FALSE;
}
OP( 0xf4, i_hlt ) { nec_ICount=0; }
OP( 0xf5, i_cmc ) { I.CarryVal = !CF; CLK(4); }
OP( 0xf6, i_f6pre ) { UINT32 tmp; UINT32 uresult,uresult2; INT32 result,result2;
GetModRM; tmp = GetRMByte(ModRM);
switch (ModRM & 0x38) {
case 0x00: tmp &= FETCH; I.CarryVal = I.OverVal = I.AuxVal=0; SetSZPF_Byte(tmp); CLKM(2,1); break; /* TEST */
case 0x08: break;
case 0x10: PutbackRMByte(ModRM,~tmp); CLKM(3,1); break; /* NOT */
case 0x18: I.CarryVal=(tmp!=0);tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); CLKM(3,1); break; /* NEG */
case 0x20: uresult = I.regs.b[AL]*tmp; I.regs.w[AW]=(WORD)uresult; I.CarryVal=I.OverVal=(I.regs.b[AH]!=0); CLKM(4,3); break; /* MULU */
case 0x28: result = (INT16)((INT8)I.regs.b[AL])*(INT16)((INT8)tmp); I.regs.w[AW]=(WORD)result; I.CarryVal=I.OverVal=(I.regs.b[AH]!=0); CLKM(4,3); break; /* MUL */
case 0x30: if (tmp) { DIVUB; } else nec_interrupt(0,0); CLKM(16,15); break;
case 0x38: if (tmp) { DIVB; } else nec_interrupt(0,0); CLKM(18,17); break;
}
}
OP( 0xf7, i_f7pre ) { UINT32 tmp,tmp2; UINT32 uresult,uresult2; INT32 result,result2;
GetModRM; tmp = GetRMWord(ModRM);
switch (ModRM & 0x38) {
case 0x00: FETCHWORD(tmp2); tmp &= tmp2; I.CarryVal = I.OverVal = I.AuxVal=0; SetSZPF_Word(tmp); CLKM(2,1); break; /* TEST */
case 0x08: break;
case 0x10: PutbackRMWord(ModRM,~tmp); CLKM(3,1); break; /* NOT */
case 0x18: I.CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); CLKM(3,1); break; /* NEG */
case 0x20: uresult = I.regs.w[AW]*tmp; I.regs.w[AW]=uresult&0xffff; I.regs.w[DW]=((UINT32)uresult)>>16; I.CarryVal=I.OverVal=(I.regs.w[DW]!=0); CLKM(4,3); break; /* MULU */
case 0x28: result = (INT32)((INT16)I.regs.w[AW])*(INT32)((INT16)tmp); I.regs.w[AW]=result&0xffff; I.regs.w[DW]=result>>16; I.CarryVal=I.OverVal=(I.regs.w[DW]!=0); CLKM(4,3); break; /* MUL */
case 0x30: if (tmp) { DIVUW; } else nec_interrupt(0,0); CLKM(24,23); break;
case 0x38: if (tmp) { DIVW; } else nec_interrupt(0,0); CLKM(25,24); break;
}
}
OP( 0xf8, i_clc ) { I.CarryVal = 0; CLK(4); }
OP( 0xf9, i_stc ) { I.CarryVal = 1; CLK(4); }
OP( 0xfa, i_di ) { SetIF(0); CLK(4); }
OP( 0xfb, i_ei ) { SetIF(1); CLK(4); }
OP( 0xfc, i_cld ) { SetDF(0); CLK(4); }
OP( 0xfd, i_std ) { SetDF(1); CLK(4); }
OP( 0xfe, i_fepre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMByte(ModRM);
switch(ModRM & 0x38) {
case 0x00: tmp1 = tmp+1; I.OverVal = (tmp==0x7f); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(3,1); break; /* INC */
case 0x08: tmp1 = tmp-1; I.OverVal = (tmp==0x80); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(BYTE)tmp1); CLKM(3,1); break; /* DEC */
}
}
OP( 0xff, i_ffpre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMWord(ModRM);
switch(ModRM & 0x38) {
case 0x00: tmp1 = tmp+1; I.OverVal = (tmp==0x7fff); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(3,1); break; /* INC */
case 0x08: tmp1 = tmp-1; I.OverVal = (tmp==0x8000); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(WORD)tmp1); CLKM(3,1); break; /* DEC */
case 0x10: PUSH(I.ip); I.ip = (WORD)tmp; CLKM(6,5); break; /* CALL */
case 0x18: tmp1 = I.sregs[CS]; I.sregs[CS] = GetnextRMWord; PUSH(tmp1); PUSH(I.ip); I.ip = tmp; CLKM(12,1); break; /* CALL FAR */
case 0x20: I.ip = tmp; CLKM(5,4); break; /* JMP */
case 0x28: I.ip = tmp; I.sregs[CS] = GetnextRMWord; CLKM(10,1); break; /* JMP FAR */
case 0x30: PUSH(tmp); CLKM(2,1); break;
default: ;
}
}
static void i_invalid(void)
{
CLK(10);
}
/*****************************************************************************/
unsigned nec_get_reg(int regnum)
{
switch( regnum )
{
case NEC_IP: return I.ip;
case NEC_SP: return I.regs.w[SP];
case NEC_FLAGS: return CompressFlags();
case NEC_AW: return I.regs.w[AW];
case NEC_CW: return I.regs.w[CW];
case NEC_DW: return I.regs.w[DW];
case NEC_BW: return I.regs.w[BW];
case NEC_BP: return I.regs.w[BP];
case NEC_IX: return I.regs.w[IX];
case NEC_IY: return I.regs.w[IY];
case NEC_ES: return I.sregs[ES];
case NEC_CS: return I.sregs[CS];
case NEC_SS: return I.sregs[SS];
case NEC_DS: return I.sregs[DS];
case NEC_VECTOR: return I.int_vector;
case NEC_PENDING: return I.pending_irq;
case NEC_NMI_STATE: return I.nmi_state;
case NEC_IRQ_STATE: return I.irq_state;
}
return 0;
}
void nec_set_irq_line(int irqline, int state);
void nec_set_reg(int regnum, unsigned val)
{
switch( regnum )
{
case NEC_IP: I.ip = val; break;
case NEC_SP: I.regs.w[SP] = val; break;
case NEC_FLAGS: ExpandFlags(val); break;
case NEC_AW: I.regs.w[AW] = val; break;
case NEC_CW: I.regs.w[CW] = val; break;
case NEC_DW: I.regs.w[DW] = val; break;
case NEC_BW: I.regs.w[BW] = val; break;
case NEC_BP: I.regs.w[BP] = val; break;
case NEC_IX: I.regs.w[IX] = val; break;
case NEC_IY: I.regs.w[IY] = val; break;
case NEC_ES: I.sregs[ES] = val; break;
case NEC_CS: I.sregs[CS] = val; break;
case NEC_SS: I.sregs[SS] = val; break;
case NEC_DS: I.sregs[DS] = val; break;
case NEC_VECTOR: I.int_vector = val; break;
}
}
int nec_execute(int cycles)
{
nec_ICount=cycles;
// cpu_type=V30;
while(nec_ICount>0) {
nec_instruction[FETCHOP]();
// nec_ICount++;
}
return cycles - nec_ICount;
}

390
oswan/source/nec/nec.h Normal file
View File

@@ -0,0 +1,390 @@
BYTE cpu_readport(BYTE);
void cpu_writeport(DWORD,BYTE);
#define cpu_readop cpu_readmem20
#define cpu_readop_arg cpu_readmem20
void cpu_writemem20(DWORD,BYTE);
BYTE cpu_readmem20(DWORD);
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 w[8]; /* viewed as 16 bits registers */
UINT8 b[16]; /* or as 8 bit registers */
} necbasicregs;
typedef struct
{
necbasicregs regs;
UINT16 sregs[4];
UINT16 ip;
INT32 SignVal;
UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
UINT8 TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */
UINT32 int_vector;
UINT32 pending_irq;
UINT32 nmi_state;
UINT32 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)(x))
#define SetSZPF_Word(x) (I.SignVal=I.ZeroVal=I.ParityVal=(INT16)(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 res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
#define ADDW { UINT32 res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
#define SUBB { UINT32 res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
#define SUBW { UINT32 res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)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[(BYTE)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)cpu_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg,Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (UINT16) 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,(BYTE)((x)>>8)); }
/* Todo: Remove these later - plus readword could overflow */
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (BYTE)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),(BYTE)(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) ((BYTE)cpu_readop_arg(addr))
#define PEEKOP(addr) ((BYTE)cpu_readop(addr))
#define GetModRM UINT32 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 ccount=(v20<<16)|(v30<<8)|v33; nec_ICount-=(ccount>>cpu_type)&0x7f; }
#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e) { const UINT32 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 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 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 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() (WORD)(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) \
unsigned tmp = (unsigned)I.regs.w[Reg]; \
unsigned tmp1 = tmp+1; \
I.OverVal = (tmp == 0x7fff); \
SetAF(tmp1,tmp,1); \
SetSZPF_Word(tmp1); \
I.regs.w[Reg]=tmp1
#define DecWordReg(Reg) \
unsigned tmp = (unsigned)I.regs.w[Reg]; \
unsigned 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)FETCH); \
if (flag) \
{ \
I.ip = (WORD)(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) \
WORD 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,(BYTE)dst)
#define SHL_WORD(c) dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
#define SHR_BYTE(c) dst >>= c-1; I.CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
#define SHR_WORD(c) dst >>= c-1; I.CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
#define SHRA_BYTE(c) dst = ((INT8)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((INT8)((BYTE)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
#define SHRA_WORD(c) dst = ((INT16)dst) >> (c-1); I.CarryVal = dst & 0x1; dst = ((INT16)((WORD)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)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)I.regs.w[AW]; \
result2 = result % (INT16)((INT8)tmp); \
if ((result /= (INT16)((INT8)tmp)) > 0xff) { \
nec_interrupt(0,0); break; \
} else { \
I.regs.b[AL] = result; \
I.regs.b[AH] = result2; \
}
#define DIVUW \
uresult = (((UINT32)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)I.regs.w[DW] << 16) + I.regs.w[AW]; \
result2 = result % (INT32)((INT16)tmp); \
if ((result /= (INT32)((INT16)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; \
unsigned di = I.regs.w[IY]; \
unsigned 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; \
unsigned di = I.regs.w[IY]; \
unsigned 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; \
unsigned di = I.regs.w[IY]; \
unsigned 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++; \
} \
}

60
oswan/source/nec/necea.h Normal file
View File

@@ -0,0 +1,60 @@
static UINT32 EA;
static UINT16 EO;
static UINT16 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)FETCH); EA=DefaultBase(DS)+EO; return EA; }
static unsigned EA_101(void) { EO=(I.regs.w[BW]+I.regs.w[IY]+(INT8)FETCH); EA=DefaultBase(DS)+EO; return EA; }
static unsigned EA_102(void) { EO=(I.regs.w[BP]+I.regs.w[IX]+(INT8)FETCH); EA=DefaultBase(SS)+EO; return EA; }
static unsigned EA_103(void) { EO=(I.regs.w[BP]+I.regs.w[IY]+(INT8)FETCH); EA=DefaultBase(SS)+EO; return EA; }
static unsigned EA_104(void) { EO=(I.regs.w[IX]+(INT8)FETCH); EA=DefaultBase(DS)+EO; return EA; }
static unsigned EA_105(void) { EO=(I.regs.w[IY]+(INT8)FETCH); EA=DefaultBase(DS)+EO; return EA; }
static unsigned EA_106(void) { EO=(I.regs.w[BP]+(INT8)FETCH); EA=DefaultBase(SS)+EO; return EA; }
static unsigned EA_107(void) { EO=(I.regs.w[BW]+(INT8)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)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)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)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)E16; EA=DefaultBase(SS)+EO; return EA; }
static unsigned EA_204(void) { E16=FETCH; E16+=FETCH<<8; EO=I.regs.w[IX]+(INT16)E16; EA=DefaultBase(DS)+EO; return EA; }
static unsigned EA_205(void) { E16=FETCH; E16+=FETCH<<8; EO=I.regs.w[IY]+(INT16)E16; EA=DefaultBase(DS)+EO; return EA; }
static unsigned EA_206(void) { E16=FETCH; E16+=FETCH<<8; EO=I.regs.w[BP]+(INT16)E16; EA=DefaultBase(SS)+EO; return EA; }
static unsigned EA_207(void) { E16=FETCH; E16+=FETCH<<8; EO=I.regs.w[BW]+(INT16)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
oswan/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 */
};

View File

@@ -0,0 +1,67 @@
/* ASG 971222 -- rewrote this interface */
#ifndef __NEC_H_
#define __NEC_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_reg(int,unsigned);
int nec_execute(int cycles);
unsigned nec_get_reg(int regnum);
void nec_reset (void *param);
void nec_int(DWORD wektor);
#endif

104
oswan/source/nec/necmodrm.h Normal file
View File

@@ -0,0 +1,104 @@
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) \
{ \
WORD 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 ModRM = FETCH,src,dst; \
src = RegByte(ModRM); \
dst = GetRMByte(ModRM)
#define DEF_wr16 \
UINT32 ModRM = FETCH,src,dst; \
src = RegWord(ModRM); \
dst = GetRMWord(ModRM)
#define DEF_r8b \
UINT32 ModRM = FETCH,src,dst; \
dst = RegByte(ModRM); \
src = GetRMByte(ModRM)
#define DEF_r16w \
UINT32 ModRM = FETCH,src,dst; \
dst = RegWord(ModRM); \
src = GetRMWord(ModRM)
#define DEF_ald8 \
UINT32 src = FETCH; \
UINT32 dst = I.regs.b[AL]
#define DEF_axd16 \
UINT32 src = FETCH; \
UINT32 dst = I.regs.w[AW]; \
src += (FETCH << 8)

153
oswan/source/rom.cpp Normal file
View File

@@ -0,0 +1,153 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "types.h"
#include "log.h"
#include "rom.h"
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint8 *ws_rom_load(char *path, uint32 *romSize)
{
uint8 *rom=NULL;
Uint32 filepos;
FILE *fp=fopen(path,"rb");
if (fp==NULL)
return(NULL);
fseek(fp,0,SEEK_END);
//fgetpos(fp,&filepos);
filepos = ftell(fp);
*romSize=(uint32)filepos;
fseek(fp,0,SEEK_SET);
rom=(uint8*)malloc(*romSize);
fread(rom,1,*romSize,fp);
fclose(fp);
return(rom);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_rom_dumpInfo(uint8 *wsrom, uint32 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 *wsrom, uint32 wsromSize)
{
ws_romHeaderStruct *wsromHeader=(ws_romHeaderStruct *)malloc(sizeof(ws_romHeaderStruct));
memcpy(wsromHeader,wsrom+(wsromSize-10),10);
return(wsromHeader);
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32 ws_rom_sramSize(uint8 *wsrom, uint32 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 ws_rom_eepromSize(uint8 *wsrom, uint32 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);
}

60
oswan/source/rom.h Normal file
View File

@@ -0,0 +1,60 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __ROM_H__
#define __ROM_H__
#include "types.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 developperId;
uint8 minimumSupportSystem;
uint8 cartId;
uint8 romSize;
uint8 eepromSize;
uint8 additionnalCapabilities;
uint8 realtimeClock;
uint16 checksum;
} ws_romHeaderStruct;
uint8 *ws_rom_load(char *path, uint32 *romSize);
void ws_rom_dumpInfo(uint8 *wsrom, uint32 wsromSize);
ws_romHeaderStruct *ws_rom_getHeader(uint8 *wsrom, uint32 wsromSize);
uint32 ws_rom_sramSize(uint8 *wsrom, uint32 wsromSize);
uint32 ws_rom_eepromSize(uint8 *wsrom, uint32 wsromSize);
#endif

98
oswan/source/temp/key.h Normal file
View File

@@ -0,0 +1,98 @@
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_1=1;
else
ws_key_button_1=0;
if (SDL_JoystickGetButton(joystick,2))
ws_key_button_2=1;
else
ws_key_button_2=0;
if (SDL_JoystickGetAxis(joystick,0)<-7000)
ws_key_left=1;
else
ws_key_left=0;
if (SDL_JoystickGetAxis(joystick,0)>7000)
ws_key_right=1;
else
ws_key_right=0;
if (SDL_JoystickGetAxis(joystick,1)<-7000)
ws_key_up=1;
else
ws_key_up=0;
if (SDL_JoystickGetAxis(joystick,1)>7000)
ws_key_down=1;
else
ws_key_down=0;
}
else
{
ws_key_start=0;
ws_key_left=0;
ws_key_right=0;
ws_key_up=0;
ws_key_down=0;
ws_key_button_1=0;
ws_key_button_2=0;
}
uint8 *keystate = SDL_GetKeyState(NULL);
if ( keystate[SDLK_d])
{
dump_memory();
}
if ( keystate[SDLK_ESCAPE] )
ws_key_esc = 1;
if ( keystate[SDLK_UP] )
ws_key_up=1;
if ( keystate[SDLK_DOWN] )
ws_key_down=1;
if ( keystate[SDLK_RIGHT] )
ws_key_right=1;
if ( keystate[SDLK_LEFT] )
ws_key_left=1;
if (keystate[SDLK_RETURN])
ws_key_start=1;
if (keystate[SDLK_c])
ws_key_button_1=1;
if (keystate[SDLK_x])
ws_key_button_2=1;
if (keystate[SDLK_p])
ws_cyclesByLine+=10;
if (keystate[SDLK_o])
ws_cyclesByLine-=10;

BIN
oswan/source/ticker Normal file

Binary file not shown.

42
oswan/source/ticker.asm Normal file
View File

@@ -0,0 +1,42 @@
bits 32
section .data
bits 32
times ($$-$)&7 db 0
section .text
bits 32
global rdtscCapableCpu_
global _rdtscCapableCpu
global _ticker
global ticker_
_ticker:
ticker_:
push edx
rdtsc
shr eax,8
shl edx,24
and edx,0xff000000
or eax,edx
pop edx
ret
rdtscCapableCpu_:
_rdtscCapableCpu:
push ebx
push ecx
push edx
mov eax,1
xor ebx,ebx
xor ecx,ecx
xor edx,edx
cpuid
test edx,0x10
setne al
and eax,1
pop edx
pop ecx
pop ebx
ret
end

5
oswan/source/ticker.h Normal file
View File

@@ -0,0 +1,5 @@
extern "C"
{
long ticker();
};

44
oswan/source/types.h Normal file
View File

@@ -0,0 +1,44 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
// this file is a travesty. [SU]int(8|16|32) should be used instead.
#ifndef __TYPES_H__
#define __TYPES_H__
#include "SDL.h"
#define UINT8 Uint8
#define UINT16 Uint16
#define INT8 Sint8
#define INT16 Sint16
#define INT32 Sint32
#define UINT32 Uint32
#define uint8 UINT8
#define uint16 UINT16
#define uint32 UINT32
#define int8 INT8
#define int16 INT16
#define int32 INT32
#define u8 uint8
#define u16 uint16
#define u32 uint32
#define s8 int8
#define s16 int16
#define s32 int32
#define BYTE Uint8
#define WORD Uint16
#define DWORD Uint32
#endif

461
oswan/source/ws.cpp Normal file
View File

@@ -0,0 +1,461 @@
////////////////////////////////////////////////////////////////////////////////
// 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 <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"
#ifndef O_BINARY
// silly windows systems with their CR/LF screwiness...
#define O_BINARY 0
#endif
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
uint32 ws_cycles;
uint32 ws_skip;
uint32 ws_cyclesByLine=0;
uint32 vblank_count=0;
char *ws_sram_path = NULL;
extern int ws_sram_dirty;
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_patchRom(void)
{
uint8 *rom=memory_getRom();
uint32 romSize=memory_getRomSize();
fprintf(log_get(),"developper Id: 0x%.2x\nGame Id: 0x%.2x\n",rom[romSize-10],rom[romSize-8]);
if((rom[romSize-10]==0x01)&&(rom[romSize-8]==0x27)) // Detective Conan
{
// WS cpu is using cache/pipeline or
// there's protected ROM bank where
// pointing CS
rom[0xfffe8]=0xea;
rom[0xfffe9]=0x00;
rom[0xfffea]=0x00;
rom[0xfffeb]=0x00;
rom[0xfffec]=0x20;
}
if (!ws_cyclesByLine) ws_cyclesByLine=256;
}
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
int ws_init(char *rompath)
{
uint8 *rom;
uint32 romSize;
if ((rom=ws_rom_load(rompath,&romSize))==NULL)
{
printf("Error: cannot load %s\n",rompath);
return(0);
}
if (rompath[strlen(rompath)-1]=='c')
ws_gpu_operatingInColor=1;
else
ws_gpu_operatingInColor=0;
ws_memory_init(rom,romSize);
ws_patchRom();
ws_sram_load(ws_sram_path);
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 *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 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 END INT*/
{
if(ws_ioRam[0xa7]!=0x35)/*Beatmania Fix*/
{
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 INT*/
{
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);
}
if (drawWholeScreen && ws_sram_dirty)
{
ws_sram_save(ws_sram_path);
ws_sram_dirty = 0;
}
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 crc=memory_getRomCrc();
uint16 newCrc;
unsigned value;
uint8 ws_newVideoMode;
int fp = open(statepath,O_BINARY|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 crc=memory_getRomCrc();
unsigned 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_BINARY|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 *rom=memory_getRom();
uint32 romSize=memory_getRomSize();
return(rom[romSize-4]&1);
}

33
oswan/source/ws.h Normal file
View File

@@ -0,0 +1,33 @@
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __WS_H__
#define __WS_H__
#define WS_SYSTEM_MONO 0
#define WS_SYSTEM_COLOR 1
#define WS_SYSTEM_AUTODETECT 2
// <20> supprimer !
extern uint32 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 *framebuffer, int renderLine);
void ws_patchRom(void);
int ws_loadState(char *statepath);
int ws_saveState(char *statepath);
void ws_done(void);
#endif