#include "compiler.h"
#include "i286.h"
#include "i286c.h"
#include "memory.h"
#include "pccore.h"
#include "iocore.h"
#include "dmap.h"
#include "i286c.mcr"
I286REGS i286r;
I286STAT i286s;
I286DTR GDTR;
I286DTR IDTR;
UINT16 MSW;
const BYTE iflags[256] = { // 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};
// ----
DWORD EA_FIX;
BYTE *reg8_b53[256];
BYTE *reg8_b20[256];
UINT16 *reg16_b53[256];
UINT16 *reg16_b20[256];
BYTE szpcflag[0x200];
BYTE szpflag_w[0x10000];
CALCEA c_calc_ea_dst[256];
CALCLEA c_calc_lea[192];
GETLEA c_get_ea[192];
static UINT32 ea_nop(void) {
return(0);
}
void i286_initialize(void) {
UINT i;
UINT bit;
BYTE f;
int pos;
for (i=0; i<0x100; i++) {
f = P_FLAG;
for (bit=0x80; bit; bit>>=1) {
if (i & bit) {
f ^= P_FLAG;
}
}
if (!(i & 0xff)) {
f |= Z_FLAG;
}
if (i & 0x80) {
f |= S_FLAG;
}
szpcflag[i+0x000] = f;
szpcflag[i+0x100] = f | C_FLAG;
}
for (i=0; i<0x100; i++) {
#if defined(BYTESEX_LITTLE)
pos = ((i & 0x20)?1:0);
#else
pos = ((i & 0x20)?0:1);
#endif
pos += ((i >> 3) & 3) * 2;
reg8_b53[i] = ((BYTE *)&i286r) + pos;
#if defined(BYTESEX_LITTLE)
pos = ((i & 0x4)?1:0);
#else
pos = ((i & 0x4)?0:1);
#endif
pos += (i & 3) * 2;
reg8_b20[i] = ((BYTE *)&i286r) + pos;
reg16_b53[i] = ((UINT16 *)&i286r) + ((i >> 3) & 7);
reg16_b20[i] = ((UINT16 *)&i286r) + (i & 7);
}
for (i=0; i<0xc0; i++) {
pos = ((i >> 3) & 0x18) + (i & 0x07);
c_calc_ea_dst[i] = i286c_ea_dst_tbl[pos];
c_calc_lea[i] = i286c_lea_tbl[pos];
c_get_ea[i] = i286c_ea_tbl[pos];
}
for (; i<0x100; i++) {
c_calc_ea_dst[i] = ea_nop;
}
for (i=0; i<0x10000; i++) {
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;
}
szpflag_w[i] = f;
}
}
void i286_reset(void) {
i286_initialize();
ZeroMemory(&i286r, sizeof(i286r));
ZeroMemory(&i286s, sizeof(i286s));
I286_CS = 0x1fc0;
CS_BASE = 0x1fc00;
ZeroMemory(&GDTR, sizeof(GDTR));
ZeroMemory(&IDTR, sizeof(IDTR));
MSW = 0;
}
void i286_resetprefetch(void) {
}
void CPUCALL i286_intnum(DWORD vect, WORD IP) {
const BYTE *ptr;
REGPUSH0(REAL_FLAGREG)
REGPUSH0(I286_CS)
REGPUSH0(IP)
I286_FLAG &= ~(T_FLAG | I_FLAG);
I286_TRAP = 0;
ptr = I286_MEM + (vect * 4);
I286_IP = LOADINTELWORD(ptr+0); // real mode!
I286_CS = LOADINTELWORD(ptr+2); // real mode!
CS_BASE = I286_CS << 4;
I286_CLOCK(20)
}
void CPUCALL i286_interrupt(BYTE vect) {
BYTE op;
const BYTE *ptr;
op = i286_memoryread(I286_IP + CS_BASE);
if (op == 0xf4) { // hlt
I286_IP++;
}
REGPUSH0(REAL_FLAGREG)
REGPUSH0(I286_CS)
REGPUSH0(I286_IP)
I286_FLAG &= ~(T_FLAG | I_FLAG);
I286_TRAP = 0;
ptr = I286_MEM + (vect * 4);
I286_IP = LOADINTELWORD(ptr+0); // real mode!
I286_CS = LOADINTELWORD(ptr+2); // real mode!
CS_BASE = (UINT32)I286_CS << 4;
I286_CLOCK(20)
}
void i286(void) {
UINT opcode;
if (I286_TRAP) {
do {
GET_PCBYTE(opcode);
i286op[opcode]();
if (I286_TRAP) {
i286_interrupt(1);
}
dmap_i286();
} while(nevent.remainclock > 0);
}
else if (dmac.working) {
do {
GET_PCBYTE(opcode);
i286op[opcode]();
dmap_i286();
} while(nevent.remainclock > 0);
}
else {
do {
GET_PCBYTE(opcode);
i286op[opcode]();
} while(nevent.remainclock > 0);
}
}
void i286_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();
}
RetroPC.NET-CVS <cvs@retropc.net>