File:  [RetroPC.NET] / np2 / i286c / i286c.c
Revision 1.3: download - view: text, annotated - select for diffs
Fri Oct 17 20:10:02 2003 JST (22 years ago) by yui
Branches: MAIN
CVS tags: HEAD
fix CPU (T.Yui)

#include	"compiler.h"
#include	"i286.h"
#include	"i286c.h"
#include	"memory.h"
#include	"pccore.h"
#include	"iocore.h"
#include	"dmap.h"
#include	"i286c.mcr"


	I286REG		i286reg;

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};


// ----

	UINT32	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 *)&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] = ((BYTE *)&I286_REG) + pos;
		reg16_b53[i] = ((UINT16 *)&I286_REG) + ((i >> 3) & 7);
		reg16_b20[i] = ((UINT16 *)&I286_REG) + (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(&i286reg, sizeof(i286reg));
	I286_CS = 0x1fc0;
	CS_BASE = 0x1fc00;
}

void i286_resetprefetch(void) {
}

void CPUCALL i286_intnum(UINT vect, UINT16 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) {

	UINT	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 = 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>