File:  [RetroPC.NET] / xmil / z80c / z80c_cb.c
Revision 1.1: download - view: text, annotated - select for diffs
Sun Aug 1 14:31:32 2004 JST (21 years, 3 months ago) by yui
Branches: MAIN
CVS tags: HEAD
initialize

//----------------------------------------------------------------------------
//
//  Z80C : Z80 Engine - GENERIC
//
//                                  Copyright by Studio Milmake 1999-2000,2004
//
//----------------------------------------------------------------------------


#include	"compiler.h"
#include	"z80core.h"
#include	"z80c.h"
#include	"x1_io.h"
#include	"z80c.mcr"


static BYTE CPUCALL _cb_rlc(BYTE v) {

	BYTE	ret;

	R_Z80F = v >> 7;
	ret = (v << 1) | R_Z80F;
	R_Z80F |= ZSPtable[ret];
	return(ret);
}

static BYTE CPUCALL _cb_rrc(BYTE v) {

	BYTE	ret;

	R_Z80F = v & 1;
	ret = (v >> 1) | (R_Z80F << 7);
	R_Z80F |= ZSPtable[ret];
	return(ret);
}

static BYTE CPUCALL _cb_rl(BYTE v) {

	BYTE	ret;

	ret = (v << 1) | (R_Z80F & 1);
	R_Z80F = ZSPtable[ret] | (v >> 7);
	return(ret);
}

static BYTE CPUCALL _cb_rr(BYTE v) {

	BYTE	ret;

	ret = (v >> 1) | (R_Z80F << 7);
	R_Z80F = ZSPtable[ret] | (v & 1);
	return(ret);
}

static BYTE CPUCALL _cb_sla(BYTE v) {

	BYTE	ret;

	ret = (v << 1);
	R_Z80F = ZSPtable[ret] | (v >> 7);
	return(ret);
}

static BYTE CPUCALL _cb_sra(BYTE v) {

	BYTE	ret;

	ret = (((char)v) / 2);
	R_Z80F = ZSPtable[ret] | (v & 1);
	return(ret);
}

static BYTE CPUCALL _cb_sll(BYTE v) {

	BYTE	ret;

	ret = (v << 1) | 1;
	R_Z80F = ZSPtable[ret] | (v >> 7);
	return(ret);
}

static BYTE CPUCALL _cb_srl(BYTE v) {

	BYTE	ret;

	ret = v >> 1;
	R_Z80F = ZSPtable[ret] | (v & 1);
	return(ret);
}


static BYTE (CPUCALL * rolsft_proc[8])(BYTE value) = {
		_cb_rlc,	_cb_rrc,	_cb_rl,		_cb_rr,
		_cb_sla,	_cb_sra,	_cb_sll,	_cb_srl};

static BYTE *cb_reg[8] = {
		&R_Z80B,	&R_Z80C,	&R_Z80D,	&R_Z80E,
		&R_Z80H,	&R_Z80L,	NULL,		&R_Z80A};


void z80c_cb(void) {

	BYTE	op;
	BYTE	*reg;
	BYTE	xhl;
	int		bit;

	R_Z80R++;
	GET_PC_BYTE(op);

	reg = cb_reg[op & 7];
	bit = (op >> 3) & 7;
	if (reg) {
		Z80_COUNT(8);
		switch(op & 0xc0) {
			case 0x00:
				*reg = rolsft_proc[bit](*reg);
				break;

			case 0x40:										// bit
				R_Z80F &= C_FLAG;
				if ((*reg) & (1 << bit)) {
					if (bit != 7) {
						R_Z80F |= H_FLAG;
					}
					else {
						R_Z80F |= (H_FLAG | S_FLAG);
					}
				}
				else {
					R_Z80F |= (H_FLAG | Z_FLAG);
				}
				break;

			case 0x80:										// reset
				(*reg) &= ~(1 << bit);
				break;

			case 0xc0:										// set
				(*reg) |= 1 << bit;
				break;
		}
	}
	else {
		xhl = Z80_RDMEM(R_Z80HL);
		switch(op & 0xc0) {
			case 0x00:
				Z80_COUNT(15);
				xhl = rolsft_proc[bit](xhl);
				break;

			case 0x40:										// bit
				Z80_COUNT(12);
				R_Z80F &= C_FLAG;
				if (xhl & (1 << bit)) {
					if (bit != 7) {
						R_Z80F |= H_FLAG;
					}
					else {
						R_Z80F |= (H_FLAG | S_FLAG);
					}
				}
				else {
					R_Z80F |= (H_FLAG | Z_FLAG);
				}
				return;

			case 0x80:										// reset
				Z80_COUNT(15);
				xhl &= ~(1 << bit);
				break;

			case 0xc0:										// set
				Z80_COUNT(15);
				xhl |= 1 << bit;
				break;
		}
		Z80_WRMEM(R_Z80HL, xhl);
	}
}

void z80c_ixcb(void) {

	BYTE	op;
	WORD	adrs;
	BYTE	xi;
	int		bit;

	R_Z80R++;
	adrs = __CBW(Z80_RDMEM(R_Z80PC++)) + R_Z80IX;
	xi = Z80_RDMEM(adrs);
	GET_PC_BYTE(op);
	bit = (op >> 3) & 7;
	switch(op & 0xc0) {
		case 0x00:
			Z80_COUNT(23);
			xi = rolsft_proc[bit](xi);
			break;

		case 0x40:										// bit
			Z80_COUNT(20);
			R_Z80F &= C_FLAG;
			if (xi & (1 << bit)) {
				if (bit != 7) {
					R_Z80F |= H_FLAG;
				}
				else {
					R_Z80F |= (H_FLAG | S_FLAG);
				}
			}
			else {
				R_Z80F |= (H_FLAG | Z_FLAG);
			}
			return;

		case 0x80:										// reset
			Z80_COUNT(23);
			xi &= ~(1 << bit);
			break;

		case 0xc0:										// set
			Z80_COUNT(23);
			xi |= 1 << bit;
			break;
	}
	Z80_WRMEM(adrs, xi);
}

void z80c_iycb(void) {

	BYTE	op;
	WORD	adrs;
	BYTE	xi;
	int		bit;

	R_Z80R++;
	adrs = __CBW(Z80_RDMEM(R_Z80PC++)) + R_Z80IY;
	xi = Z80_RDMEM(adrs);
	GET_PC_BYTE(op);
	bit = (op >> 3) & 7;
	switch(op & 0xc0) {
		case 0x00:
			Z80_COUNT(23);
			xi = rolsft_proc[bit](xi);
			break;

		case 0x40:										// bit
			Z80_COUNT(20);
			R_Z80F &= C_FLAG;
			if (xi & (1 << bit)) {
				if (bit != 7) {
					R_Z80F |= H_FLAG;
				}
				else {
					R_Z80F |= (H_FLAG | S_FLAG);
				}
			}
			else {
				R_Z80F |= (H_FLAG | Z_FLAG);
			}
			return;

		case 0x80:										// reset
			Z80_COUNT(23);
			xi &= ~(1 << bit);
			break;

		case 0xc0:										// set
			Z80_COUNT(23);
			xi |= 1 << bit;
			break;
	}
	Z80_WRMEM(adrs, xi);
}


RetroPC.NET-CVS <cvs@retropc.net>