File:  [RetroPC.NET] / np2 / i286c / i286c.c
Revision 1.1: download - view: text, annotated - select for diffs
Fri Oct 17 02:57:37 2003 JST (22 years ago) by yui
Branches: MAIN
CVS tags: HEAD
Initial revision

#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>