Initial Commit
This commit is contained in:
773
oswan/source/2xSaI.cpp
Normal file
773
oswan/source/2xSaI.cpp
Normal 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
22
oswan/source/2xSaI.h
Normal 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
246
oswan/source/SDLptc.h
Normal 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
1382
oswan/source/audio.cpp
Normal file
File diff suppressed because it is too large
Load Diff
43
oswan/source/audio.h
Normal file
43
oswan/source/audio.h
Normal 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
|
||||
|
||||
56
oswan/source/filters/2xsai.h
Normal file
56
oswan/source/filters/2xsai.h
Normal 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"
|
||||
}
|
||||
}
|
||||
220
oswan/source/filters/doubled.h
Normal file
220
oswan/source/filters/doubled.h
Normal 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"
|
||||
}
|
||||
}
|
||||
13
oswan/source/filters/filter_partA.h
Normal file
13
oswan/source/filters/filter_partA.h
Normal 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;
|
||||
23
oswan/source/filters/filter_partB.h
Normal file
23
oswan/source/filters/filter_partB.h
Normal 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");
|
||||
}
|
||||
77
oswan/source/filters/filter_partC.h
Normal file
77
oswan/source/filters/filter_partC.h
Normal 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");
|
||||
10
oswan/source/filters/filter_partD.h
Normal file
10
oswan/source/filters/filter_partD.h
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (i=0;i<nCount-1;i++)
|
||||
while (!ws_executeLine(backbuffer,0));
|
||||
|
||||
while (!ws_executeLine(backbuffer,1));
|
||||
totalFrames++;
|
||||
|
||||
4
oswan/source/filters/filter_partE.h
Normal file
4
oswan/source/filters/filter_partE.h
Normal file
@@ -0,0 +1,4 @@
|
||||
endTime=clock();
|
||||
float fps=totalFrames/(((float)(endTime-startTime))/(float)CLOCKS_PER_SEC);
|
||||
console.close();
|
||||
delete surface;
|
||||
86
oswan/source/filters/halfscanlines.h
Normal file
86
oswan/source/filters/halfscanlines.h
Normal 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"
|
||||
}
|
||||
}
|
||||
188
oswan/source/filters/interpolate.h
Normal file
188
oswan/source/filters/interpolate.h
Normal 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;
|
||||
}
|
||||
68
oswan/source/filters/scanlines.h
Normal file
68
oswan/source/filters/scanlines.h
Normal 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"
|
||||
}
|
||||
}
|
||||
71
oswan/source/filters/special.h
Normal file
71
oswan/source/filters/special.h
Normal 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"
|
||||
}
|
||||
}
|
||||
75
oswan/source/filters/standard.h
Normal file
75
oswan/source/filters/standard.h
Normal 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"
|
||||
}
|
||||
}
|
||||
54
oswan/source/filters/super2xsai.h
Normal file
54
oswan/source/filters/super2xsai.h
Normal 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"
|
||||
}
|
||||
}
|
||||
54
oswan/source/filters/supereagle.h
Normal file
54
oswan/source/filters/supereagle.h
Normal 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
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
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
45
oswan/source/gpu.h
Normal 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
100
oswan/source/ieeprom.h
Normal 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
271
oswan/source/initialIo.h
Normal 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
715
oswan/source/io.cpp
Normal 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
30
oswan/source/io.h
Normal 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
63
oswan/source/log.cpp
Normal 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
20
oswan/source/log.h
Normal 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
308
oswan/source/memory.cpp
Normal 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
34
oswan/source/memory.h
Normal 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
921
oswan/source/nec/nec.cpp
Normal 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
390
oswan/source/nec/nec.h
Normal 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
60
oswan/source/nec/necea.h
Normal 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
507
oswan/source/nec/necinstr.h
Normal 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 */
|
||||
};
|
||||
67
oswan/source/nec/necintrf.h
Normal file
67
oswan/source/nec/necintrf.h
Normal 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
104
oswan/source/nec/necmodrm.h
Normal 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
153
oswan/source/rom.cpp
Normal 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
60
oswan/source/rom.h
Normal 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
98
oswan/source/temp/key.h
Normal 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
BIN
oswan/source/ticker
Normal file
Binary file not shown.
42
oswan/source/ticker.asm
Normal file
42
oswan/source/ticker.asm
Normal 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
5
oswan/source/ticker.h
Normal file
@@ -0,0 +1,5 @@
|
||||
extern "C"
|
||||
{
|
||||
long ticker();
|
||||
};
|
||||
|
||||
44
oswan/source/types.h
Normal file
44
oswan/source/types.h
Normal 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
461
oswan/source/ws.cpp
Normal 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
33
oswan/source/ws.h
Normal 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
|
||||
Reference in New Issue
Block a user