#include "compiler.h"
#include "cpucore.h"
#include "i286c.h"
#include "v30patch.h"
#include "pccore.h"
#include "iocore.h"
#include "dmap.h"
#include "i286c.mcr"
I286CORE i286core;
const UINT8 iflags[512] = { // Z_FLAG, S_FLAG, P_FLAG
0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04,
0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80,
0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84,
0x45, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05,
0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81,
0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85};
// ----
#if !defined(MEMOPTIMIZE)
UINT8 _szpflag16[0x10000];
#endif
#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2)
UINT8 *_reg8_b53[256];
UINT8 *_reg8_b20[256];
#endif
#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2)
UINT16 *_reg16_b53[256];
UINT16 *_reg16_b20[256];
#endif
void i286c_initialize(void) {
#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2)
UINT i;
#endif
#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2)
for (i=0; i<0x100; i++) {
int pos;
#if defined(BYTESEX_LITTLE)
pos = ((i & 0x20)?1:0);
#else
pos = ((i & 0x20)?0:1);
#endif
pos += ((i >> 3) & 3) * 2;
_reg8_b53[i] = ((UINT8 *)&I286_REG) + pos;
#if defined(BYTESEX_LITTLE)
pos = ((i & 0x4)?1:0);
#else
pos = ((i & 0x4)?0:1);
#endif
pos += (i & 3) * 2;
_reg8_b20[i] = ((UINT8 *)&I286_REG) + pos;
#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2)
_reg16_b53[i] = ((UINT16 *)&I286_REG) + ((i >> 3) & 7);
_reg16_b20[i] = ((UINT16 *)&I286_REG) + (i & 7);
#endif
}
#endif
#if !defined(MEMOPTIMIZE)
for (i=0; i<0x10000; i++) {
REG8 f;
UINT bit;
f = P_FLAG;
for (bit=0x80; bit; bit>>=1) {
if (i & bit) {
f ^= P_FLAG;
}
}
if (!i) {
f |= Z_FLAG;
}
if (i & 0x8000) {
f |= S_FLAG;
}
_szpflag16[i] = f;
}
#endif
#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2)
i286cea_initialize();
#endif
v30cinit();
ZeroMemory(&i286core, sizeof(i286core));
}
void i286c_deinitialize(void) {
if (CPU_EXTMEM) {
_MFREE(CPU_EXTMEM);
CPU_EXTMEM = NULL;
CPU_EXTMEMSIZE = 0;
}
}
static void i286c_initreg(void) {
I286_CS = 0xf000;
CS_BASE = 0xf0000;
I286_IP = 0xfff0;
I286_ADRSMASK = 0xfffff;
}
void i286c_reset(void) {
ZeroMemory(&i286core.s, sizeof(i286core.s));
i286c_initreg();
}
void i286c_shut(void) {
ZeroMemory(&i286core.s, offsetof(I286STAT, cpu_type));
i286c_initreg();
}
void i286c_setextsize(UINT32 size) {
if (CPU_EXTMEMSIZE != size) {
_MFREE(CPU_EXTMEM);
if (size) {
CPU_EXTMEM = (BYTE *)_MALLOC(size + 16, "EXTMEM");
if (CPU_EXTMEM == NULL) {
size = 0;
}
}
CPU_EXTMEMSIZE = size;
}
i286core.e.ems[0] = mem + 0xc0000;
i286core.e.ems[1] = mem + 0xc4000;
i286core.e.ems[2] = mem + 0xc8000;
i286core.e.ems[3] = mem + 0xcc000;
}
void i286c_setemm(UINT frame, UINT32 addr) {
BYTE *ptr;
frame &= 3;
if (addr < USE_HIMEM) {
ptr = mem + addr;
}
else if ((addr - 0x100000 + 0x4000) <= CPU_EXTMEMSIZE) {
ptr = CPU_EXTMEM + (addr - 0x100000);
}
else {
ptr = mem + 0xc0000 + (frame << 14);
}
i286core.e.ems[frame] = ptr;
}
void CPUCALL i286c_intnum(UINT vect, REG16 IP) {
const BYTE *ptr;
REGPUSH0(REAL_FLAGREG)
REGPUSH0(I286_CS)
REGPUSH0(IP)
I286_FLAG &= ~(T_FLAG | I_FLAG);
I286_TRAP = 0;
ptr = mem + (vect * 4);
I286_IP = LOADINTELWORD(ptr+0); // real mode!
I286_CS = LOADINTELWORD(ptr+2); // real mode!
CS_BASE = I286_CS << 4;
I286_WORKCLOCK(20);
}
void CPUCALL i286c_interrupt(REG8 vect) {
UINT op;
const BYTE *ptr;
op = i286_memoryread(I286_IP + CS_BASE);
if (op == 0xf4) { // hlt
I286_IP++;
}
REGPUSH0(REAL_FLAGREG) // ここV30で辻褄が合わない
REGPUSH0(I286_CS)
REGPUSH0(I286_IP)
I286_FLAG &= ~(T_FLAG | I_FLAG);
I286_TRAP = 0;
ptr = mem + (vect * 4);
I286_IP = LOADINTELWORD(ptr + 0); // real mode!
I286_CS = LOADINTELWORD(ptr + 2); // real mode!
CS_BASE = I286_CS << 4;
I286_WORKCLOCK(20);
}
void i286c(void) {
UINT opcode;
if (I286_TRAP) {
do {
GET_PCBYTE(opcode);
i286op[opcode]();
if (I286_TRAP) {
i286c_interrupt(1);
}
dmap_i286();
} while(I286_REMCLOCK > 0);
}
else if (dmac.working) {
do {
GET_PCBYTE(opcode);
i286op[opcode]();
dmap_i286();
} while(I286_REMCLOCK > 0);
}
else {
do {
GET_PCBYTE(opcode);
i286op[opcode]();
} while(I286_REMCLOCK > 0);
}
}
void i286c_step(void) {
UINT opcode;
I286_OV = I286_FLAG & O_FLAG;
I286_FLAG &= ~(O_FLAG);
GET_PCBYTE(opcode);
i286op[opcode]();
I286_FLAG &= ~(O_FLAG);
if (I286_OV) {
I286_FLAG |= (O_FLAG);
}
dmap_i286();
}
// ---- test
#if defined(I286C_TEST)
BYTE BYTESZPF(UINT r) {
if (r & (~0xff)) {
TRACEOUT(("BYTESZPF bound error: %x", r));
}
return(iflags[r & 0xff]);
}
BYTE BYTESZPCF(UINT r) {
if (r & (~0x1ff)) {
TRACEOUT(("BYTESZPCF bound error: %x", r));
}
return(iflags[r & 0x1ff]);
}
BYTE WORDSZPF(UINT32 r) {
BYTE f1;
BYTE f2;
if (r & (~0xffff)) {
TRACEOUT(("WORDSZPF bound error: %x", r));
}
f1 = _szpflag16[r & 0xffff];
f2 = iflags[r & 0xff] & P_FLAG;
f2 += (r)?0:Z_FLAG;
f2 += (r >> 8) & S_FLAG;
if (f1 != f2) {
TRACEOUT(("word flag error: %.2x %.2x", f1, f2));
}
return(f1);
}
BYTE WORDSZPCF(UINT32 r) {
BYTE f1;
BYTE f2;
if ((r & 0xffff0000) && (!(r & 0x00010000))) {
TRACEOUT(("WORDSZPCF bound error: %x", r));
}
f1 = (r >> 16) & 1;
f1 += _szpflag16[LOW16(r)];
f2 = iflags[r & 0xff] & P_FLAG;
f2 += (LOW16(r))?0:Z_FLAG;
f2 += (r >> 8) & S_FLAG;
f2 += (r >> 16) & 1;
if (f1 != f2) {
TRACEOUT(("word flag error: %.2x %.2x", f1, f2));
}
return(f1);
}
#endif
RetroPC.NET-CVS <cvs@retropc.net>