From d6dedbdedf967d2bdcb8bff9001519a94f0e66cb Mon Sep 17 00:00:00 2001 From: Couriersud Date: Sun, 9 Nov 2008 20:38:33 +0000 Subject: [PATCH] Converted i8x41 to use pointers for state access Separated opcodes into i8x41ops.c --- .gitattributes | 1 + src/emu/cpu/i8x41/i8x41.c | 2420 ++++++++++------------------------ src/emu/cpu/i8x41/i8x41ops.c | 1085 +++++++++++++++ 3 files changed, 1772 insertions(+), 1734 deletions(-) create mode 100644 src/emu/cpu/i8x41/i8x41ops.c diff --git a/.gitattributes b/.gitattributes index 27981223bc2..2b4fab213a1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -171,6 +171,7 @@ src/emu/cpu/i86/v33intf.h svneol=native#text/plain src/emu/cpu/i8x41/8x41dasm.c svneol=native#text/plain src/emu/cpu/i8x41/i8x41.c svneol=native#text/plain src/emu/cpu/i8x41/i8x41.h svneol=native#text/plain +src/emu/cpu/i8x41/i8x41ops.c svneol=native#text/plain src/emu/cpu/i960/i960.c svneol=native#text/plain src/emu/cpu/i960/i960.h svneol=native#text/plain src/emu/cpu/i960/i960dis.c svneol=native#text/plain diff --git a/src/emu/cpu/i8x41/i8x41.c b/src/emu/cpu/i8x41/i8x41.c index a64b3428e5e..823c7a852ca 100644 --- a/src/emu/cpu/i8x41/i8x41.c +++ b/src/emu/cpu/i8x41/i8x41.c @@ -118,8 +118,8 @@ #include "deprecat.h" #include "i8x41.h" -typedef struct _upi41 I8X41; -struct _upi41 { +typedef struct _upi41_state_t upi41_state_t; +struct _upi41_state_t { UINT16 ppc; UINT16 pc; UINT8 timer; @@ -138,16 +138,15 @@ struct _upi41 { UINT8 ram_mask; cpu_irq_callback irq_callback; const device_config *device; + int icount; }; -static int i8x41_ICount; - -static I8X41 i8x41; +static void *token; #define RM(a) program_read_byte_8le(a) -#define IRAM_R(a) data_read_byte_8le((a) & i8x41.ram_mask) -#define IRAM_W(a,v) data_write_byte_8le((a) & i8x41.ram_mask, v) +#define IRAM_R(a) data_read_byte_8le((a) & upi41_state->ram_mask) +#define IRAM_W(a,v) data_write_byte_8le((a) & upi41_state->ram_mask, v) #define RP(a) io_read_byte_8le(a) #define WP(a,v) io_write_byte_8le(a,v) @@ -207,1110 +206,608 @@ static I8X41 i8x41; /* shorter names for the I8x41 structure elements */ -#define PPC i8x41.ppc -#define PC i8x41.pc -#define A i8x41.a -#define PSW i8x41.psw -#define DBBI i8x41.dbbi -#define DBBO i8x41.dbbo -#define STATE i8x41.state -#define ENABLE i8x41.enable -#define PRESCALER i8x41.prescaler -#define P1 i8x41.p1 -#define P2 i8x41.p2 -#define P2_HS i8x41.p2_hs /* Port 2 Hand Shaking */ -#define CONTROL i8x41.control +#define PPC upi41_state->ppc +#define PC upi41_state->pc +#define A upi41_state->a +#define PSW upi41_state->psw +#define DBBI upi41_state->dbbi +#define DBBO upi41_state->dbbo +#define STATE upi41_state->state +#define ENABLE upi41_state->enable +#define PRESCALER upi41_state->prescaler +#define P1 upi41_state->p1 +#define P2 upi41_state->p2 +#define P2_HS upi41_state->p2_hs /* Port 2 Hand Shaking */ +#define CONTROL upi41_state->control #define GETR(n) (IRAM_R(((PSW & BS) ? M_BANK1:M_BANK0)+(n))) #define SETR(n,v) (IRAM_W(((PSW & BS) ? M_BANK1:M_BANK0)+(n), (v))) -static void set_irq_line(int irqline, int state); +static void set_irq_line(upi41_state_t *upi41_state, int irqline, int state); /************************************************************************ * Shortcuts ************************************************************************/ -INLINE void PUSH_PC_TO_STACK(void) +INLINE void push_pc_to_stack(upi41_state_t *upi41_state) { IRAM_W( M_STACK + (PSW&SP) * 2 + 0, PC & 0xff); IRAM_W( M_STACK + (PSW&SP) * 2 + 1, ((PC >> 8) & 0x0f) | (PSW & 0xf0) ); PSW = (PSW & ~SP) | ((PSW + 1) & SP); } +#define PUSH_PC_TO_STACK() push_pc_to_stack(upi41_state) -/************************************************************************ - * Emulate the Instructions - ************************************************************************/ +/*********************************************************************** + * Opcodes + ***********************************************************************/ -/*********************************** - * illegal opcodes - ***********************************/ -INLINE void illegal(void) +#include "i8x41ops.c" + +/*********************************************************************** + * Execute a single opcode + ***********************************************************************/ + +INLINE void execute_op(upi41_state_t *upi41_state, UINT8 op) { - logerror("i8x41 #%d: illegal opcode at 0x%03x: %02x\n", cpu_getactivecpu(), PC, ROP(PC)); -} - -/*********************************** - * 0110 1rrr * ADD A,Rr - ***********************************/ -INLINE void add_r(int r) -{ - UINT8 res = A + GETR(r); - if( res < A ) PSW |= FC; - if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; - A = res; -} - -/*********************************** - * 0110 000r - * ADD A,@Rr - ***********************************/ -INLINE void add_rm(int r) -{ - UINT8 res = A + IRAM_R(GETR(r)); - if( res < A ) PSW |= FC; - if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; - A = res; -} - -/*********************************** - * 0000 0011 7654 3210 - * ADD A,#n - ***********************************/ -INLINE void add_i(void) -{ - UINT8 res = A + ROP_ARG(PC); - PC++; - if( res < A ) PSW |= FC; - if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; - A = res; -} - -/*********************************** - * 0111 1rrr - * ADDC A,Rr - ***********************************/ -INLINE void addc_r(int r) -{ - UINT8 res = A + GETR(r) + (PSW >> 7); - if( res <= A ) PSW |= FC; - if( (res & 0x0f) <= (A & 0x0f) ) PSW |= FA; - A = res; -} - -/*********************************** - * 0111 000r - * ADDC A,@Rr - ***********************************/ -INLINE void addc_rm(int r) -{ - UINT8 res = A + IRAM_R(GETR(r)) + (PSW >> 7); - if( res <= A ) PSW |= FC; - if( (res & 0x0f) <= (A & 0x0f) ) PSW |= FA; - A = res; -} - -/*********************************** - * 0001 0011 7654 3210 - * ADDC A,#n - ***********************************/ -INLINE void addc_i(void) -{ - UINT8 res = A + ROP_ARG(PC) + (PSW >> 7); - PC++; - if( res <= A ) PSW |= FC; - if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; - A = res; -} - -/*********************************** - * 0101 1rrr - * ANL A,Rr - ***********************************/ -INLINE void anl_r(int r) -{ - A = A & GETR(r); -} - -/*********************************** - * 0101 000r - * ANL A,@Rr - ***********************************/ -INLINE void anl_rm(int r) -{ - A = A & IRAM_R(GETR(r)); -} - -/*********************************** - * 0101 0011 7654 3210 - * ANL A,#n - ***********************************/ -INLINE void anl_i(void) -{ - A = A & ROP_ARG(PC); - PC++; -} - -/*********************************** - * 1001 10pp 7654 3210 - * ANL Pp,#n - ***********************************/ -INLINE void anl_p_i(int p) -{ - UINT8 val = ROP_ARG(PC); - PC++; - /* changed to latched port scheme */ - switch (p) + switch( op ) { - case 00: break; /* invalid port */ - case 01: P1 &= val; WP(p, P1); break; - case 02: P2 &= val; WP(p, (P2 & P2_HS) ); break; - case 03: break; /* invalid port */ - default: break; + /* opcode cycles bitmask */ + case 0x00: /* 1: 0000 0000 */ + nop(upi41_state, op); + break; + case 0x01: /* 1: 0000 0001 */ + illegal(upi41_state, op); + break; + case 0x02: /* 1: 0000 0010 */ + out_dbb_a(upi41_state, op); + break; + case 0x03: /* 2: 0000 0011 */ + add_i(upi41_state, op); + break; + case 0x04: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0x05: /* 1: 0000 0101 */ + en_i(upi41_state, op); + break; + case 0x06: /* 1: 0000 0110 */ + illegal(upi41_state, op); + break; + case 0x07: /* 1: 0000 0111 */ + dec_a(upi41_state, op); + break; + case 0x08: /* 2: 0000 10pp */ + case 0x09: /* 2: 0000 10pp */ + case 0x0a: /* 2: 0000 10pp */ + case 0x0b: /* 2: 0000 10pp */ + in_a_p(upi41_state, op & 3); + break; + case 0x0c: /* 2: 0000 11pp */ + case 0x0d: /* 2: 0000 11pp */ + case 0x0e: /* 2: 0000 11pp */ + case 0x0f: /* 2: 0000 11pp */ + movd_a_p(upi41_state, op & 3); + break; + case 0x10: /* 1: 0001 000r */ + inc_rm(upi41_state, 0); + break; + case 0x11: /* 1: 0001 000r */ + inc_rm(upi41_state, 1); + break; + case 0x12: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 0); + break; + case 0x13: /* 2: 0001 0011 */ + addc_i(upi41_state, op); + break; + case 0x14: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0x15: /* 1: 0001 0101 */ + dis_i(upi41_state, op); + break; + case 0x16: /* 2: 0001 0110 */ + jtf_i(upi41_state, op); + break; + case 0x17: /* 1: 0001 0111 */ + inc_a(upi41_state, op); + break; + case 0x18: /* 1: 0001 1rrr */ + case 0x19: /* 1: 0001 1rrr */ + case 0x1a: /* 1: 0001 1rrr */ + case 0x1b: /* 1: 0001 1rrr */ + case 0x1c: /* 1: 0001 1rrr */ + case 0x1d: /* 1: 0001 1rrr */ + case 0x1e: /* 1: 0001 1rrr */ + case 0x1f: /* 1: 0001 1rrr */ + inc_r(upi41_state, op & 7); + break; + case 0x20: /* 1: 0010 000r */ + xch_a_rm(upi41_state, 0); + break; + case 0x21: /* 1: 0010 000r */ + xch_a_rm(upi41_state, 1); + break; + case 0x22: /* 1: 0010 0010 */ + in_a_dbb(upi41_state, op); + break; + case 0x23: /* 2: 0010 0011 */ + mov_a_i(upi41_state, op); + break; + case 0x24: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0x25: /* 1: 0010 0101 */ + en_tcnti(upi41_state, op); + break; + case 0x26: /* 2: 0010 0110 */ + jnt0_i(upi41_state, op); + break; + case 0x27: /* 1: 0010 0111 */ + clr_a(upi41_state, op); + break; + case 0x28: /* 1: 0010 1rrr */ + case 0x29: /* 1: 0010 1rrr */ + case 0x2a: /* 1: 0010 1rrr */ + case 0x2b: /* 1: 0010 1rrr */ + case 0x2c: /* 1: 0010 1rrr */ + case 0x2d: /* 1: 0010 1rrr */ + case 0x2e: /* 1: 0010 1rrr */ + case 0x2f: /* 1: 0010 1rrr */ + xch_a_r(upi41_state, op & 7); + break; + case 0x30: /* 1: 0011 000r */ + xchd_a_rm(upi41_state, 0); + break; + case 0x31: /* 1: 0011 000r */ + xchd_a_rm(upi41_state, 1); + break; + case 0x32: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 1); + break; + case 0x33: /* 1: 0011 0101 */ + illegal(upi41_state, op); + break; + case 0x34: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0x35: /* 1: 0000 0101 */ + dis_tcnti(upi41_state, op); + break; + case 0x36: /* 2: 0011 0110 */ + jt0_i(upi41_state, op); + break; + case 0x37: /* 1: 0011 0111 */ + cpl_a(upi41_state, op); + break; + case 0x38: /* 2: 0011 10pp */ + case 0x39: /* 2: 0011 10pp */ + case 0x3a: /* 2: 0011 10pp */ + case 0x3b: /* 2: 0011 10pp */ + out_p_a(upi41_state, op & 3); + break; + case 0x3c: /* 2: 0011 11pp */ + case 0x3d: /* 2: 0011 11pp */ + case 0x3e: /* 2: 0011 11pp */ + case 0x3f: /* 2: 0011 11pp */ + movd_p_a(upi41_state, op & 3); + break; + case 0x40: /* 1: 0100 000r */ + orl_rm(upi41_state, 0); + break; + case 0x41: /* 1: 0100 000r */ + orl_rm(upi41_state, 1); + break; + case 0x42: /* 1: 0100 0010 */ + mov_a_t(upi41_state, op); + break; + case 0x43: /* 2: 0100 0011 */ + orl_i(upi41_state, op); + break; + case 0x44: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0x45: /* 1: 0100 0101 */ + strt_cnt(upi41_state, op); + break; + case 0x46: /* 2: 0100 0110 */ + jnt1_i(upi41_state, op); + break; + case 0x47: /* 1: 0100 0111 */ + swap_a(upi41_state, op); + break; + case 0x48: /* 1: 0100 1rrr */ + case 0x49: /* 1: 0100 1rrr */ + case 0x4a: /* 1: 0100 1rrr */ + case 0x4b: /* 1: 0100 1rrr */ + case 0x4c: /* 1: 0100 1rrr */ + case 0x4d: /* 1: 0100 1rrr */ + case 0x4e: /* 1: 0100 1rrr */ + case 0x4f: /* 1: 0100 1rrr */ + orl_r(upi41_state, op & 7); + break; + case 0x50: /* 1: 0101 000r */ + anl_rm(upi41_state, 0); + break; + case 0x51: /* 1: 0101 000r */ + anl_rm(upi41_state, 1); + break; + case 0x52: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 2); + break; + case 0x53: /* 2: 0101 0011 */ + anl_i(upi41_state, op); + break; + case 0x54: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0x55: /* 1: 0101 0101 */ + strt_t(upi41_state, op); + break; + case 0x56: /* 2: 0101 0110 */ + jt1_i(upi41_state, op); + break; + case 0x57: /* 1: 0101 0111 */ + da_a(upi41_state, op); + break; + case 0x58: /* 1: 0101 1rrr */ + case 0x59: /* 1: 0101 1rrr */ + case 0x5a: /* 1: 0101 1rrr */ + case 0x5b: /* 1: 0101 1rrr */ + case 0x5c: /* 1: 0101 1rrr */ + case 0x5d: /* 1: 0101 1rrr */ + case 0x5e: /* 1: 0101 1rrr */ + case 0x5f: /* 1: 0101 1rrr */ + anl_r(upi41_state, op & 7); + break; + case 0x60: /* 1: 0110 000r */ + add_rm(upi41_state, 0); + break; + case 0x61: /* 1: 0110 000r */ + add_rm(upi41_state, 1); + break; + case 0x62: /* 1: 0110 0010 */ + mov_t_a(upi41_state, op); + break; + case 0x63: /* 1: 0110 0011 */ + illegal(upi41_state, op); + break; + case 0x64: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0x65: /* 1: 0110 0101 */ + stop_tcnt(upi41_state, op); + break; + case 0x66: /* 1: 0110 0110 */ + illegal(upi41_state, op); + break; + case 0x67: /* 1: 0110 0111 */ + rrc_a(upi41_state, op); + break; + case 0x68: /* 1: 0110 1rrr */ + case 0x69: /* 1: 0110 1rrr */ + case 0x6a: /* 1: 0110 1rrr */ + case 0x6b: /* 1: 0110 1rrr */ + case 0x6c: /* 1: 0110 1rrr */ + case 0x6d: /* 1: 0110 1rrr */ + case 0x6e: /* 1: 0110 1rrr */ + case 0x6f: /* 1: 0110 1rrr */ + add_r(upi41_state, op & 7); + break; + case 0x70: /* 1: 0111 000r */ + addc_rm(upi41_state, 0); + break; + case 0x71: /* 1: 0111 000r */ + addc_rm(upi41_state, 1); + break; + case 0x72: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 3); + break; + case 0x73: /* 1: 0111 0011 */ + illegal(upi41_state, op); + break; + case 0x74: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0x75: /* 1: 0111 0101 */ + illegal(upi41_state, op); + break; + case 0x76: /* 2: 0111 0110 */ + jf1_i(upi41_state, op); + break; + case 0x77: /* 1: 0111 0111 */ + rr_a(upi41_state, op); + break; + case 0x78: /* 1: 0111 1rrr */ + case 0x79: /* 1: 0111 1rrr */ + case 0x7a: /* 1: 0111 1rrr */ + case 0x7b: /* 1: 0111 1rrr */ + case 0x7c: /* 1: 0111 1rrr */ + case 0x7d: /* 1: 0111 1rrr */ + case 0x7e: /* 1: 0111 1rrr */ + case 0x7f: /* 1: 0111 1rrr */ + addc_r(upi41_state, op & 7); + break; + case 0x80: /* 1: 1000 0000 */ + illegal(upi41_state, op); + break; + case 0x81: /* 1: 1000 0001 */ + illegal(upi41_state, op); + break; + case 0x82: /* 1: 1000 0010 */ + illegal(upi41_state, op); + break; + case 0x83: /* 2: 1000 0011 */ + ret(upi41_state, op); + break; + case 0x84: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0x85: /* 1: 1000 0101 */ + clr_f0(upi41_state, op); + break; + case 0x86: /* 2: 1000 0110 */ + jobf_i(upi41_state, op); + break; + case 0x87: /* 1: 1000 0111 */ + illegal(upi41_state, op); + break; + case 0x88: /* 2: 1000 10pp */ + case 0x89: /* 2: 1000 10pp */ + case 0x8a: /* 2: 1000 10pp */ + case 0x8b: /* 2: 1000 10pp */ + orl_p_i(upi41_state, op & 3); + break; + case 0x8c: /* 2: 1000 11pp */ + case 0x8d: /* 2: 1000 11pp */ + case 0x8e: /* 2: 1000 11pp */ + case 0x8f: /* 2: 1000 11pp */ + orld_p_a(upi41_state, op & 7); + break; + case 0x90: /* 1: 1001 0000 */ + mov_sts_a(upi41_state, op); + break; + case 0x91: /* 1: 1001 0001 */ + illegal(upi41_state, op); + break; + case 0x92: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 4); + break; + case 0x93: /* 2: 1001 0011 */ + retr(upi41_state, op); + break; + case 0x94: /* 1: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0x95: /* 1: 1001 0101 */ + cpl_f0(upi41_state, op); + break; + case 0x96: /* 2: 1001 0110 */ + jnz_i(upi41_state, op); + break; + case 0x97: /* 1: 1001 0111 */ + clr_c(upi41_state, op); + break; + case 0x98: /* 2: 1001 10pp , illegal port */ + case 0x99: /* 2: 1001 10pp */ + case 0x9a: /* 2: 1001 10pp */ + case 0x9b: /* 2: 1001 10pp , illegal port */ + anl_p_i(upi41_state, op & 3); + break; + case 0x9c: /* 2: 1001 11pp */ + case 0x9d: /* 2: 1001 11pp */ + case 0x9e: /* 2: 1001 11pp */ + case 0x9f: /* 2: 1001 11pp */ + anld_p_a(upi41_state, op & 7); + break; + case 0xa0: /* 1: 1010 000r */ + mov_rm_a(upi41_state, 0); + break; + case 0xa1: /* 1: 1010 000r */ + mov_rm_a(upi41_state, 1); + break; + case 0xa2: /* 1: 1010 0010 */ + illegal(upi41_state, op); + break; + case 0xa3: /* 2: 1010 0011 */ + movp_a_am(upi41_state, op); + break; + case 0xa4: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0xa5: /* 1: 1010 0101 */ + clr_f1(upi41_state, op); + break; + case 0xa6: /* 1: 1010 0110 */ + illegal(upi41_state, op); + break; + case 0xa7: /* 1: 1010 0111 */ + cpl_c(upi41_state, op); + break; + case 0xa8: /* 1: 1010 1rrr */ + case 0xa9: /* 1: 1010 1rrr */ + case 0xaa: /* 1: 1010 1rrr */ + case 0xab: /* 1: 1010 1rrr */ + case 0xac: /* 1: 1010 1rrr */ + case 0xad: /* 1: 1010 1rrr */ + case 0xae: /* 1: 1010 1rrr */ + case 0xaf: /* 1: 1010 1rrr */ + mov_r_a(upi41_state, op & 7); + break; + case 0xb0: /* 2: 1011 000r */ + mov_rm_i(upi41_state, 0); + break; + case 0xb1: /* 2: 1011 000r */ + mov_rm_i(upi41_state, 1); + break; + case 0xb2: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 5); + break; + case 0xb3: /* 2: 1011 0011 */ + jmpp_a(upi41_state, op); + break; + case 0xb4: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0xb5: /* 1: 1011 0101 */ + cpl_f1(upi41_state, op); + break; + case 0xb6: /* 2: 1011 0110 */ + jf0_i(upi41_state, op); + break; + case 0xb7: /* 1: 1011 0111 */ + illegal(upi41_state, op); + break; + case 0xb8: /* 2: 1011 1rrr */ + case 0xb9: /* 2: 1011 1rrr */ + case 0xba: /* 2: 1011 1rrr */ + case 0xbb: /* 2: 1011 1rrr */ + case 0xbc: /* 2: 1011 1rrr */ + case 0xbd: /* 2: 1011 1rrr */ + case 0xbe: /* 2: 1011 1rrr */ + case 0xbf: /* 2: 1011 1rrr */ + mov_r_i(upi41_state, op & 7); + break; + case 0xc0: /* 1: 1100 0000 */ + illegal(upi41_state, op); + break; + case 0xc1: /* 1: 1100 0001 */ + illegal(upi41_state, op); + break; + case 0xc2: /* 1: 1100 0010 */ + illegal(upi41_state, op); + break; + case 0xc3: /* 1: 1100 0011 */ + illegal(upi41_state, op); + break; + case 0xc4: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0xc5: /* 1: 1100 0101 */ + sel_rb0(upi41_state, op); + break; + case 0xc6: /* 2: 1100 0110 */ + jz_i(upi41_state, op); + break; + case 0xc7: /* 1: 1100 0111 */ + mov_a_psw(upi41_state, op); + break; + case 0xc8: /* 1: 1100 1rrr */ + case 0xc9: /* 1: 1100 1rrr */ + case 0xca: /* 1: 1100 1rrr */ + case 0xcb: /* 1: 1100 1rrr */ + case 0xcc: /* 1: 1100 1rrr */ + case 0xcd: /* 1: 1100 1rrr */ + case 0xcf: /* 1: 1100 1rrr */ + dec_r(upi41_state, op & 7); + break; + case 0xd0: /* 1: 1101 000r */ + xrl_rm(upi41_state, 0); + break; + case 0xd1: /* 1: 1101 000r */ + xrl_rm(upi41_state, 1); + break; + case 0xd2: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 6); + break; + case 0xd3: /* 1: 1101 0011 */ + xrl_i(upi41_state, op); + break; + case 0xd4: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0xd5: /* 1: 1101 0101 */ + sel_rb1(upi41_state, op); + break; + case 0xd6: /* 2: 1101 0110 */ + jnibf_i(upi41_state, op); + break; + case 0xd7: /* 1: 1101 0111 */ + mov_psw_a(upi41_state, op); + break; + case 0xd8: /* 1: 1101 1rrr */ + case 0xd9: /* 1: 1101 1rrr */ + case 0xda: /* 1: 1101 1rrr */ + case 0xdb: /* 1: 1101 1rrr */ + case 0xdc: /* 1: 1101 1rrr */ + case 0xdd: /* 1: 1101 1rrr */ + case 0xde: /* 1: 1101 1rrr */ + case 0xdf: /* 1: 1101 1rrr */ + xrl_r(upi41_state, op & 7); + break; + case 0xe0: /* 1: 1110 0000 */ + illegal(upi41_state, op); + break; + case 0xe1: /* 1: 1110 0001 */ + illegal(upi41_state, op); + break; + case 0xe2: /* 1: 1110 0010 */ + illegal(upi41_state, op); + break; + case 0xe3: /* 2: 1110 0011 */ + movp3_a_am(upi41_state, op); + break; + case 0xe4: /* 2: aaa0 0100 */ + jmp_i(upi41_state, op); + break; + case 0xe5: /* 1: 1110 0101 */ + en_dma(upi41_state, op); + break; + case 0xe6: /* 2: 1110 0110 */ + jnc_i(upi41_state, op); + break; + case 0xe7: /* 1: 1110 0111 */ + rl_a(upi41_state, op); + break; + case 0xe8: /* 2: 1110 1rrr */ + case 0xe9: /* 2: 1110 1rrr */ + case 0xea: /* 2: 1110 1rrr */ + case 0xeb: /* 2: 1110 1rrr */ + case 0xec: /* 2: 1110 1rrr */ + case 0xed: /* 2: 1110 1rrr */ + case 0xee: /* 2: 1110 1rrr */ + case 0xef: /* 2: 1110 1rrr */ + djnz_r_i(upi41_state, op & 7); + break; + case 0xf0: /* 1: 1111 000r */ + mov_a_rm(upi41_state, 0); + break; + case 0xf1: /* 1: 1111 000r */ + mov_a_rm(upi41_state, 1); + break; + case 0xf2: /* 2: bbb1 0010 */ + jbb_i(upi41_state, 7); + break; + case 0xf3: /* 1: 1111 0011 */ + illegal(upi41_state, op); + break; + case 0xf4: /* 2: aaa1 0100 */ + call_i(upi41_state, op); + break; + case 0xf5: /* 1: 1111 0101 */ + en_flags(upi41_state, op); + break; + case 0xf6: /* 2: 1111 0110 */ + jc_i(upi41_state, op); + break; + case 0xf7: /* 1: 1111 0111 */ + rlc_a(upi41_state, op); + break; + case 0xf8: /* 1: 1111 1rrr */ + case 0xf9: /* 1: 1111 1rrr */ + case 0xfa: /* 1: 1111 1rrr */ + case 0xfb: /* 1: 1111 1rrr */ + case 0xfc: /* 1: 1111 1rrr */ + case 0xfd: /* 1: 1111 1rrr */ + case 0xfe: /* 1: 1111 1rrr */ + case 0xff: /* 1: 1111 1rrr */ + mov_a_r(upi41_state, op & 7); + break; } } -/*********************************** - * 1001 11pp 7654 3210 - * ANLD Pp,A - ***********************************/ -INLINE void anld_p_a(int p) -{ - /* added proper expanded port setup */ - WP(2, (P2 & 0xf0) | 0x0c | p); /* AND mode */ - WP(I8X41_ps, 0); /* activate command strobe */ - WP(2, (A & 0x0f)); /* Expander to take care of AND function */ - WP(I8X41_ps, 1); /* release command strobe */ -} - -/*********************************** - * aaa1 0100 7654 3210 - * CALL addr - ***********************************/ -INLINE void call_i(int page) -{ - UINT8 adr = ROP_ARG(PC); - PC++; - PUSH_PC_TO_STACK(); - PC = page | adr; -} - -/*********************************** - * 0010 0111 - * CLR A - ***********************************/ -INLINE void clr_a(void) -{ - A = 0; -} - -/*********************************** - * 1001 0111 - * CLR C - ***********************************/ -INLINE void clr_c(void) -{ - PSW &= ~FC; -} - -/*********************************** - * 1000 0101 - * CLR F0 - ***********************************/ -INLINE void clr_f0(void) -{ - PSW &= ~Ff0; - STATE &= ~F0; -} - -/*********************************** - * 1010 0101 - * CLR F1 - ***********************************/ -INLINE void clr_f1(void) -{ - STATE &= ~F1; -} - -/*********************************** - * 0011 0111 - * CPL A - ***********************************/ -INLINE void cpl_a(void) -{ - A = ~A; -} - -/*********************************** - * 1010 0111 - * CPL C - ***********************************/ -INLINE void cpl_c(void) -{ - PSW ^= FC; -} - -/*********************************** - * 1001 0101 - * CPL F0 - ***********************************/ -INLINE void cpl_f0(void) -{ - PSW ^= Ff0; - STATE ^= F0; -} - -/*********************************** - * 1011 0101 - * CPL F1 - ***********************************/ -INLINE void cpl_f1(void) -{ - STATE ^= F1; -} - -/*********************************** - * 0101 0111 - * DA A - ***********************************/ -INLINE void da_a(void) -{ - UINT8 res = A + ((PSW & FA) || ((A & 0x0f) > 0x09)) ? 0x06 : 0x00; - if( (PSW & FC) || ((res & 0xf0) > 0x90) ) - res += 0x60; - if( res < A ) - PSW |= FC; - else - PSW &= ~FC; - A = res; -} - -/*********************************** - * 0000 0111 - * DEC A - ***********************************/ -INLINE void dec_a(void) -{ - A -= 1; -} - -/*********************************** - * 1100 1rrr - * DEC Rr - ***********************************/ -INLINE void dec_r(int r) -{ - SETR(r, GETR(r) - 1); -} - -/*********************************** - * 0001 0101 - * DIS I - ***********************************/ -INLINE void dis_i(void) -{ - ENABLE &= ~IBFI; /* disable input buffer full interrupt */ -} - -/*********************************** - * 0011 0101 - * DIS TCNTI - ***********************************/ -INLINE void dis_tcnti(void) -{ - ENABLE &= ~TCNTI; /* disable timer/counter interrupt */ -} - -/*********************************** - * 0111 1rrr 7654 3210 - * DJNZ Rr,addr - ***********************************/ -INLINE void djnz_r_i(int r) -{ - UINT8 adr = ROP_ARG(PC); - PC++; - SETR(r, GETR(r) - 1); - if( GETR(r) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1110 0101 - * EN DMA - ***********************************/ -INLINE void en_dma(void) -{ - ENABLE |= DMA; /* enable DMA handshake lines */ - P2_HS &= 0xbf; - WP(0x02, (P2 & P2_HS) ); -} - -/*********************************** - * 1111 0101 - * EN FLAGS - ***********************************/ -INLINE void en_flags(void) -{ - if( 0 == (ENABLE & FLAGS) ) - { - /* Configure upper lines on Port 2 for IRQ handshaking (P24 and P25) */ - - ENABLE |= FLAGS; - if( STATE & OBF ) P2_HS |= 0x10; - else P2_HS &= 0xef; - if( STATE & IBF ) P2_HS |= 0x20; - else P2_HS &= 0xdf; - WP(0x02, (P2 & P2_HS) ); - } -} - -/*********************************** - * 0000 0101 - * EN I - ***********************************/ -INLINE void en_i(void) -{ - if( 0 == (ENABLE & IBFI) ) - { - ENABLE |= IBFI; /* enable input buffer full interrupt */ - CONTROL &= ~IBFI_IGNR; - if( STATE & IBF ) /* already got data in the buffer? */ - set_irq_line(I8X41_INT_IBF, HOLD_LINE); - } -} - -/*********************************** - * 0010 0101 - * EN TCNTI - ***********************************/ -INLINE void en_tcnti(void) -{ - ENABLE |= TCNTI; /* enable timer/counter interrupt */ - CONTROL &= ~TIRQ_IGNR; -} - -/*********************************** - * 0010 0010 - * IN A,DBB - ***********************************/ -INLINE void in_a_dbb(void) -{ - if( i8x41.irq_callback ) - (*i8x41.irq_callback)(i8x41.device, I8X41_INT_IBF); - - STATE &= ~IBF; /* clear input buffer full flag */ - if( ENABLE & FLAGS ) - { - P2_HS &= 0xdf; - if( STATE & OBF ) P2_HS |= 0x10; - else P2_HS &= 0xef; - WP(0x02, (P2 & P2_HS) ); /* Clear the DBBI IRQ out on P25 */ - } - A = DBBI; -} - -/*********************************** - * 0000 10pp - * IN A,Pp - ***********************************/ -INLINE void in_a_p(int p) -{ - /* changed to latched port scheme */ - switch( p ) - { - case 00: break; /* invalid port */ - case 01: A = (RP(p) & P1); break; - case 02: A = (RP(p) & P2); break; - case 03: break; /* invalid port */ - default: break; - } -} - -/*********************************** - * 0001 0111 - * INC A - ***********************************/ -INLINE void inc_a(void) -{ - A += 1; -} - -/*********************************** - * 0001 1rrr - * INC Rr - ***********************************/ -INLINE void inc_r(int r) -{ - SETR(r, GETR(r) + 1); -} - -/*********************************** - * 0001 000r - * INC @ Rr - ***********************************/ -INLINE void inc_rm(int r) -{ - UINT16 addr = GETR(r); - IRAM_W( addr, IRAM_R(addr) + 1 ); -} - -/*********************************** - * bbb1 0010 - * JBb addr - ***********************************/ -INLINE void jbb_i(int bit) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( A & (1 << bit) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1111 0110 - * JC addr - ***********************************/ -INLINE void jc_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( PSW & FC ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1011 0110 - * JF0 addr - ***********************************/ -INLINE void jf0_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( STATE & F0 ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 0111 0110 - * JF1 addr - ***********************************/ -INLINE void jf1_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( STATE & F1 ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * aaa0 0100 - * JMP addr - ***********************************/ -INLINE void jmp_i(int page) -{ - /* err.. do we have 10 or 11 PC bits? - * CALL is said to use 0aa1 (4 pages) - * JMP is said to use aaa0 (8 pages) - */ - UINT8 adr = ROP_ARG(PC); - PC = page | adr; -} - -/*********************************** - * 1011 0011 - * JMP @ A - ***********************************/ -INLINE void jmpp_a(void) -{ - UINT16 adr = (PC & 0x700) | A; - PC = (PC & 0x700) | RM(adr); -} - -/*********************************** - * 1110 0110 - * JNC addr - ***********************************/ -INLINE void jnc_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( !(PSW & FC) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1101 0110 - * JNIBF addr - ***********************************/ -INLINE void jnibf_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( 0 == (STATE & IBF) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 0010 0110 - * JNT0 addr - ***********************************/ -INLINE void jnt0_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( 0 == RP(I8X41_t0) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 0100 0110 - * JNT1 addr - ***********************************/ -INLINE void jnt1_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( !(ENABLE & CNT) ) - { - UINT8 level = RP(I8X41_t1); - if( level ) CONTROL |= TEST1; - else CONTROL &= ~TEST1; - } - if( !(CONTROL & TEST1) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1001 0110 - * JNZ addr - ***********************************/ -INLINE void jnz_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( A ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1000 0110 - * JOBF addr - ***********************************/ -INLINE void jobf_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( STATE & OBF ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 0001 0110 - * JTF addr - ***********************************/ -INLINE void jtf_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( CONTROL & TOVF ) - PC = (PC & 0x700) | adr; - CONTROL &= ~TOVF; -} - -/*********************************** - * 0011 0110 - * JT0 addr - ***********************************/ -INLINE void jt0_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( RP(I8X41_t0) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 0101 0110 - * JT1 addr - ***********************************/ -INLINE void jt1_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( !(ENABLE & CNT) ) - { - UINT8 level = RP(I8X41_t1); - if( level ) CONTROL |= TEST1; - else CONTROL &= ~TEST1; - } - if( (CONTROL & TEST1) ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 1100 0110 - * JZ addr - ***********************************/ -INLINE void jz_i(void) -{ - UINT8 adr = ROP_ARG(PC); - PC += 1; - if( !A ) - PC = (PC & 0x700) | adr; -} - -/*********************************** - * 0010 0011 - * MOV A,#n - ***********************************/ -INLINE void mov_a_i(void) -{ - A = ROP(PC); - PC += 1; -} - -/*********************************** - * 1100 0111 - * MOV A,PSW - ***********************************/ -INLINE void mov_a_psw(void) -{ - A = PSW; -} - -/*********************************** - * 1111 1rrr - * MOV A,Rr - ***********************************/ -INLINE void mov_a_r(int r) -{ - A = GETR(r); -} - -/*********************************** - * 1111 000r - * MOV A,Rr - ***********************************/ -INLINE void mov_a_rm(int r) -{ - A = IRAM_R(GETR(r)); -} - -/*********************************** - * 0100 0010 - * MOV A,T - ***********************************/ -INLINE void mov_a_t(void) -{ - A = i8x41.timer; -} - -/*********************************** - * 1101 0111 - * MOV PSW,A - ***********************************/ -INLINE void mov_psw_a(void) -{ - PSW = A; -} - -/*********************************** - * 1010 1rrr - * MOV Rr,A - ***********************************/ -INLINE void mov_r_a(int r) -{ - SETR(r, A); -} - -/*********************************** - * 1011 1rrr - * MOV Rr,#n - ***********************************/ -INLINE void mov_r_i(int r) -{ - UINT8 val = ROP_ARG(PC); - PC += 1; - SETR(r, val); -} - -/*********************************** - * 1010 000r - * MOV @Rr,A - ***********************************/ -INLINE void mov_rm_a(int r) -{ - IRAM_W(GETR(r), A ); -} - -/*********************************** - * 1011 000r - * MOV @Rr,#n - ***********************************/ -INLINE void mov_rm_i(int r) -{ - UINT8 val = ROP_ARG(PC); - PC += 1; - IRAM_W(GETR(r), val ); -} - -/*********************************** - * 1001 0000 - * MOV STS,A - ***********************************/ -INLINE void mov_sts_a(void) -{ - STATE = (STATE & 0x0f) | (A & 0xf0); -} - -/*********************************** - * 0110 0010 - * MOV T,A - ***********************************/ -INLINE void mov_t_a(void) -{ - i8x41.timer = A; -} - -/*********************************** - * 0000 11pp - * MOVD A,Pp - ***********************************/ -INLINE void movd_a_p(int p) -{ - /* added proper expanded port setup */ - WP(2, (P2 & 0xf0) | 0x00 | p); /* READ mode */ - WP(I8X41_ps, 0); /* activate command strobe */ - A = RP(2) & 0xf; - WP(I8X41_ps, 1); /* release command strobe */ -} - -/*********************************** - * 0011 11pp - * MOVD Pp,A - ***********************************/ -INLINE void movd_p_a(int p) -{ - /* added proper expanded port setup */ - WP(2, (P2 & 0xf0) | 0x04 | p); /* WRITE mode */ - WP(I8X41_ps, 0); /* activate command strobe */ - WP(2, A & 0x0f); - WP(I8X41_ps, 1); /* release command strobe */ -} - -/*********************************** - * 1010 0011 - * MOVP A,@A - ***********************************/ -INLINE void movp_a_am(void) -{ - UINT16 addr = (PC & 0x700) | A; - A = RM(addr); -} - -/*********************************** - * 1110 0011 - * MOVP3 A,@A - ***********************************/ -INLINE void movp3_a_am(void) -{ - UINT16 addr = 0x300 | A; - A = RM(addr); -} - -/*********************************** - * 0000 0000 - * NOP - ***********************************/ -INLINE void nop(void) -{ -} - -/*********************************** - * 0100 1rrr - * ORL A,Rr - ***********************************/ -INLINE void orl_r(int r) -{ - A = A | GETR(r); -} - -/*********************************** - * 0100 000r - * ORL A,@Rr - ***********************************/ -INLINE void orl_rm(int r) -{ - A = A | IRAM_R(GETR(r)); -} - -/*********************************** - * 0100 0011 7654 3210 - * ORL A,#n - ***********************************/ -INLINE void orl_i(void) -{ - UINT8 val = ROP_ARG(PC); - PC++; - A = A | val; -} - -/*********************************** - * 1000 10pp 7654 3210 - * ORL Pp,#n - ***********************************/ -INLINE void orl_p_i(int p) -{ - UINT8 val = ROP_ARG(PC); - PC++; - /* changed to latched port scheme */ - switch (p) - { - case 00: break; /* invalid port */ - case 01: P1 |= val; WP(p, P1); break; - case 02: P2 |= val; WP(p, P2); break; - case 03: break; /* invalid port */ - default: break; - } -} - -/*********************************** - * 1000 11pp 7654 3210 - * ORLD Pp,A - ***********************************/ -INLINE void orld_p_a(int p) -{ - /* added proper expanded port setup */ - WP(2, (P2 & 0xf0) | 0x08 | p); /* OR mode */ - WP(I8X41_ps, 0); /* activate command strobe */ - WP(2, A & 0x0f); /* Expander to take care of OR function */ - WP(I8X41_ps, 1); /* release command strobe */ -} - -/*********************************** - * 0000 0010 - * OUT DBB,A - ***********************************/ -INLINE void out_dbb_a(void) -{ - DBBO = A; /* DBB output buffer */ - STATE |= OBF; /* assert the output buffer full flag */ - if( ENABLE & FLAGS ) - { - P2_HS |= 0x10; - if( STATE & IBF ) P2_HS |= 0x20; - else P2_HS &= 0xdf; - WP(0x02, (P2 & P2_HS) ); /* Assert the DBBO IRQ out on P24 */ - } -} - -/*********************************** - * 0011 10pp - * OUT Pp,A - ***********************************/ -INLINE void out_p_a(int p) -{ - /* changed to latched port scheme */ - switch (p) - { - case 00: break; /* invalid port */ - case 01: WP(p, A); P1 = A; break; - case 02: WP(p, A); P2 = A; break; - case 03: break; /* invalid port */ - default: break; - } -} - -/*********************************** - * 1000 0011 - * RET - ***********************************/ -INLINE void ret(void) -{ - UINT8 msb; - PSW = (PSW & ~SP) | ((PSW - 1) & SP); - msb = IRAM_R(M_STACK + (PSW&SP) * 2 + 1); - PC = IRAM_R(M_STACK + (PSW&SP) * 2 + 0); - PC |= (msb << 8) & 0x700; -} - -/*********************************** - * 1001 0011 - * RETR - ***********************************/ -INLINE void retr(void) -{ - UINT8 msb; - PSW = (PSW & ~SP) | ((PSW - 1) & SP); - msb = IRAM_R(M_STACK + (PSW&SP) * 2 + 1); - PC = IRAM_R(M_STACK + (PSW&SP) * 2 + 0); - PC |= (msb << 8) & 0x700; - PSW = (PSW & 0x0f) | (msb & 0xf0); - CONTROL &= ~IRQ_IGNR; -} - -/*********************************** - * 1110 0111 - * RL A - ***********************************/ -INLINE void rl_a(void) -{ - A = (A << 1) | (A >> 7); -} - -/*********************************** - * 1111 0111 - * RLC A - ***********************************/ -INLINE void rlc_a(void) -{ - UINT8 c = PSW >> 7; - PSW = (PSW & ~FC) | (A & FC); - A = (A << 1) | c; -} - -/*********************************** - * 0111 0111 - * RR A - ***********************************/ -INLINE void rr_a(void) -{ - A = (A >> 1) | (A << 7); -} - -/*********************************** - * 0110 0111 - * RRC A - ***********************************/ -INLINE void rrc_a(void) -{ - UINT8 c = PSW & 0x80; - PSW = (PSW & ~FC) | (A << 7); - A = (A >> 1) | c; -} - -/*********************************** - * 1100 0101 - * SEL RB0 - ***********************************/ -INLINE void sel_rb0(void) -{ - PSW &= ~BS; -} - -/*********************************** - * 1101 0101 - * SEL RB1 - ***********************************/ -INLINE void sel_rb1(void) -{ - PSW |= BS; -} - -/*********************************** - * 0110 0101 - * STOP TCNT - ***********************************/ -INLINE void stop_tcnt(void) -{ - ENABLE &= ~(T|CNT); -} - -/*********************************** - * 0100 0101 - * STRT CNT - ***********************************/ -INLINE void strt_cnt(void) -{ - ENABLE |= CNT; - ENABLE &= ~T; -} - -/*********************************** - * 0101 0101 - * STRT T - ***********************************/ -INLINE void strt_t(void) -{ - ENABLE |= T; - ENABLE &= ~CNT; -} - -/*********************************** - * 0100 0111 - * SWAP A - ***********************************/ -INLINE void swap_a(void) -{ - A = (A << 4) | (A >> 4); -} - -/*********************************** - * 0010 1rrr - * XCH A,Rr - ***********************************/ -INLINE void xch_a_r(int r) -{ - UINT8 tmp = GETR(r); - SETR(r, A); - A = tmp; -} - -/*********************************** - * 0010 000r - * XCH A,@Rr - ***********************************/ -INLINE void xch_a_rm(int r) -{ - UINT16 addr = GETR(r); - UINT8 tmp = IRAM_R(addr); - IRAM_W( addr, A ); - A = tmp; -} - -/*********************************** - * 0011 000r - * XCHD A,@Rr - ***********************************/ -INLINE void xchd_a_rm(int r) -{ - UINT16 addr = GETR(r); - UINT8 tmp = IRAM_R(addr); - IRAM_W( addr, (tmp & 0xf0) | (A & 0x0f) ); - A = (A & 0xf0) | (tmp & 0x0f); -} - -/*********************************** - * 1101 1rrr - * XRL A,Rr - ***********************************/ -INLINE void xrl_r(int r) -{ - A = A ^ GETR(r); -} - -/*********************************** - * 1101 000r - * XRL A,@Rr - ***********************************/ -INLINE void xrl_rm(int r) -{ - A = A ^ IRAM_R(GETR(r)); -} - -/*********************************** - * 1101 0011 7654 3210 - * XRL A,#n - ***********************************/ -INLINE void xrl_i(void) -{ - UINT8 val = ROP_ARG(PC); - PC++; - A = A ^ val; -} - - /*********************************************************************** * Cycle Timings ***********************************************************************/ @@ -1341,33 +838,39 @@ static const UINT8 i8x41_cycles[] = { static CPU_INIT( i8x41 ) { - i8x41.irq_callback = irqcallback; - i8x41.device = device; - i8x41.subtype = 8041; - i8x41.ram_mask = I8X41_intRAM_MASK; + upi41_state_t *upi41_state = device->token; + + token = device->token; + + upi41_state->irq_callback = irqcallback; + upi41_state->device = device; + upi41_state->subtype = 8041; + upi41_state->ram_mask = I8X41_intRAM_MASK; - state_save_register_item("i8x41", index, i8x41.ppc); - state_save_register_item("i8x41", index, i8x41.pc); - state_save_register_item("i8x41", index, i8x41.timer); - state_save_register_item("i8x41", index, i8x41.prescaler); - state_save_register_item("i8x41", index, i8x41.subtype); - state_save_register_item("i8x41", index, i8x41.a); - state_save_register_item("i8x41", index, i8x41.psw); - state_save_register_item("i8x41", index, i8x41.state); - state_save_register_item("i8x41", index, i8x41.enable); - state_save_register_item("i8x41", index, i8x41.control); - state_save_register_item("i8x41", index, i8x41.dbbi); - state_save_register_item("i8x41", index, i8x41.dbbo); - state_save_register_item("i8x41", index, i8x41.p1); - state_save_register_item("i8x41", index, i8x41.p2); - state_save_register_item("i8x41", index, i8x41.p2_hs); + state_save_register_item("i8x41", index, upi41_state->ppc); + state_save_register_item("i8x41", index, upi41_state->pc); + state_save_register_item("i8x41", index, upi41_state->timer); + state_save_register_item("i8x41", index, upi41_state->prescaler); + state_save_register_item("i8x41", index, upi41_state->subtype); + state_save_register_item("i8x41", index, upi41_state->a); + state_save_register_item("i8x41", index, upi41_state->psw); + state_save_register_item("i8x41", index, upi41_state->state); + state_save_register_item("i8x41", index, upi41_state->enable); + state_save_register_item("i8x41", index, upi41_state->control); + state_save_register_item("i8x41", index, upi41_state->dbbi); + state_save_register_item("i8x41", index, upi41_state->dbbo); + state_save_register_item("i8x41", index, upi41_state->p1); + state_save_register_item("i8x41", index, upi41_state->p2); + state_save_register_item("i8x41", index, upi41_state->p2_hs); } static CPU_INIT( i8042 ) { + upi41_state_t *upi41_state; CPU_INIT_CALL(i8x41); - i8x41.subtype = 8042; - i8x41.ram_mask = I8X42_intRAM_MASK; + upi41_state = token; + upi41_state->subtype = 8042; + upi41_state->ram_mask = I8X42_intRAM_MASK; } @@ -1378,14 +881,16 @@ static CPU_INIT( i8042 ) static CPU_RESET( i8x41 ) { - i8x41.ppc = 0; - i8x41.pc = 0; - i8x41.timer = 0; - i8x41.prescaler = 0; - i8x41.a = 0; - i8x41.psw = 0; - i8x41.state = 0; - i8x41.enable = 0; + upi41_state_t *upi41_state = device->token; + + upi41_state->ppc = 0; + upi41_state->pc = 0; + upi41_state->timer = 0; + upi41_state->prescaler = 0; + upi41_state->a = 0; + upi41_state->psw = 0; + upi41_state->state = 0; + upi41_state->enable = 0; ENABLE = IBFI | TCNTI; DBBI = 0xff; @@ -1413,9 +918,10 @@ static CPU_EXIT( i8x41 ) static CPU_EXECUTE( i8x41 ) { + upi41_state_t *upi41_state = device->token; int inst_cycles, T1_level; - i8x41_ICount = cycles; + upi41_state->icount = cycles; do { @@ -1426,564 +932,9 @@ static CPU_EXECUTE( i8x41 ) debugger_instruction_hook(Machine, PC); PC += 1; - i8x41_ICount -= i8x41_cycles[op]; - - switch( op ) - { - /* opcode cycles bitmask */ - case 0x00: /* 1: 0000 0000 */ - nop(); - break; - case 0x01: /* 1: 0000 0001 */ - illegal(); - break; - case 0x02: /* 1: 0000 0010 */ - out_dbb_a(); - break; - case 0x03: /* 2: 0000 0011 */ - add_i(); - break; - case 0x04: /* 2: aaa0 0100 */ - jmp_i(0x000); - break; - case 0x05: /* 1: 0000 0101 */ - en_i(); - break; - case 0x06: /* 1: 0000 0110 */ - illegal(); - break; - case 0x07: /* 1: 0000 0111 */ - dec_a(); - break; - case 0x08: /* 2: 0000 10pp */ - case 0x09: /* 2: 0000 10pp */ - case 0x0a: /* 2: 0000 10pp */ - case 0x0b: /* 2: 0000 10pp */ - in_a_p(op & 3); - break; - case 0x0c: /* 2: 0000 11pp */ - case 0x0d: /* 2: 0000 11pp */ - case 0x0e: /* 2: 0000 11pp */ - case 0x0f: /* 2: 0000 11pp */ - movd_a_p(op & 3); - break; - case 0x10: /* 1: 0001 000r */ - inc_rm(0); - break; - case 0x11: /* 1: 0001 000r */ - inc_rm(1); - break; - case 0x12: /* 2: bbb1 0010 */ - jbb_i(0); - break; - case 0x13: /* 2: 0001 0011 */ - addc_i(); - break; - case 0x14: /* 2: aaa1 0100 */ - call_i(0x000); - break; - case 0x15: /* 1: 0001 0101 */ - dis_i(); - break; - case 0x16: /* 2: 0001 0110 */ - jtf_i(); - break; - case 0x17: /* 1: 0001 0111 */ - inc_a(); - break; - case 0x18: /* 1: 0001 1rrr */ - case 0x19: /* 1: 0001 1rrr */ - case 0x1a: /* 1: 0001 1rrr */ - case 0x1b: /* 1: 0001 1rrr */ - case 0x1c: /* 1: 0001 1rrr */ - case 0x1d: /* 1: 0001 1rrr */ - case 0x1e: /* 1: 0001 1rrr */ - case 0x1f: /* 1: 0001 1rrr */ - inc_r(op & 7); - break; - case 0x20: /* 1: 0010 000r */ - xch_a_rm(0); - break; - case 0x21: /* 1: 0010 000r */ - xch_a_rm(1); - break; - case 0x22: /* 1: 0010 0010 */ - in_a_dbb(); - break; - case 0x23: /* 2: 0010 0011 */ - mov_a_i(); - break; - case 0x24: /* 2: aaa0 0100 */ - jmp_i(0x100); - break; - case 0x25: /* 1: 0010 0101 */ - en_tcnti(); - break; - case 0x26: /* 2: 0010 0110 */ - jnt0_i(); - break; - case 0x27: /* 1: 0010 0111 */ - clr_a(); - break; - case 0x28: /* 1: 0010 1rrr */ - case 0x29: /* 1: 0010 1rrr */ - case 0x2a: /* 1: 0010 1rrr */ - case 0x2b: /* 1: 0010 1rrr */ - case 0x2c: /* 1: 0010 1rrr */ - case 0x2d: /* 1: 0010 1rrr */ - case 0x2e: /* 1: 0010 1rrr */ - case 0x2f: /* 1: 0010 1rrr */ - xch_a_r(op & 7); - break; - case 0x30: /* 1: 0011 000r */ - xchd_a_rm(0); - break; - case 0x31: /* 1: 0011 000r */ - xchd_a_rm(1); - break; - case 0x32: /* 2: bbb1 0010 */ - jbb_i(1); - break; - case 0x33: /* 1: 0011 0101 */ - illegal(); - break; - case 0x34: /* 2: aaa1 0100 */ - call_i(0x100); - break; - case 0x35: /* 1: 0000 0101 */ - dis_tcnti(); - break; - case 0x36: /* 2: 0011 0110 */ - jt0_i(); - break; - case 0x37: /* 1: 0011 0111 */ - cpl_a(); - break; - case 0x38: /* 2: 0011 10pp */ - case 0x39: /* 2: 0011 10pp */ - case 0x3a: /* 2: 0011 10pp */ - case 0x3b: /* 2: 0011 10pp */ - out_p_a(op & 3); - break; - case 0x3c: /* 2: 0011 11pp */ - case 0x3d: /* 2: 0011 11pp */ - case 0x3e: /* 2: 0011 11pp */ - case 0x3f: /* 2: 0011 11pp */ - movd_p_a(op & 3); - break; - case 0x40: /* 1: 0100 000r */ - orl_rm(0); - break; - case 0x41: /* 1: 0100 000r */ - orl_rm(1); - break; - case 0x42: /* 1: 0100 0010 */ - mov_a_t(); - break; - case 0x43: /* 2: 0100 0011 */ - orl_i(); - break; - case 0x44: /* 2: aaa0 0100 */ - jmp_i(0x200); - break; - case 0x45: /* 1: 0100 0101 */ - strt_cnt(); - break; - case 0x46: /* 2: 0100 0110 */ - jnt1_i(); - break; - case 0x47: /* 1: 0100 0111 */ - swap_a(); - break; - case 0x48: /* 1: 0100 1rrr */ - case 0x49: /* 1: 0100 1rrr */ - case 0x4a: /* 1: 0100 1rrr */ - case 0x4b: /* 1: 0100 1rrr */ - case 0x4c: /* 1: 0100 1rrr */ - case 0x4d: /* 1: 0100 1rrr */ - case 0x4e: /* 1: 0100 1rrr */ - case 0x4f: /* 1: 0100 1rrr */ - orl_r(op & 7); - break; - case 0x50: /* 1: 0101 000r */ - anl_rm(0); - break; - case 0x51: /* 1: 0101 000r */ - anl_rm(1); - break; - case 0x52: /* 2: bbb1 0010 */ - jbb_i(2); - break; - case 0x53: /* 2: 0101 0011 */ - anl_i(); - break; - case 0x54: /* 2: aaa1 0100 */ - call_i(0x200); - break; - case 0x55: /* 1: 0101 0101 */ - strt_t(); - break; - case 0x56: /* 2: 0101 0110 */ - jt1_i(); - break; - case 0x57: /* 1: 0101 0111 */ - da_a(); - break; - case 0x58: /* 1: 0101 1rrr */ - case 0x59: /* 1: 0101 1rrr */ - case 0x5a: /* 1: 0101 1rrr */ - case 0x5b: /* 1: 0101 1rrr */ - case 0x5c: /* 1: 0101 1rrr */ - case 0x5d: /* 1: 0101 1rrr */ - case 0x5e: /* 1: 0101 1rrr */ - case 0x5f: /* 1: 0101 1rrr */ - anl_r(op & 7); - break; - case 0x60: /* 1: 0110 000r */ - add_rm(0); - break; - case 0x61: /* 1: 0110 000r */ - add_rm(1); - break; - case 0x62: /* 1: 0110 0010 */ - mov_t_a(); - break; - case 0x63: /* 1: 0110 0011 */ - illegal(); - break; - case 0x64: /* 2: aaa0 0100 */ - jmp_i(0x300); - break; - case 0x65: /* 1: 0110 0101 */ - stop_tcnt(); - break; - case 0x66: /* 1: 0110 0110 */ - illegal(); - break; - case 0x67: /* 1: 0110 0111 */ - rrc_a(); - break; - case 0x68: /* 1: 0110 1rrr */ - case 0x69: /* 1: 0110 1rrr */ - case 0x6a: /* 1: 0110 1rrr */ - case 0x6b: /* 1: 0110 1rrr */ - case 0x6c: /* 1: 0110 1rrr */ - case 0x6d: /* 1: 0110 1rrr */ - case 0x6e: /* 1: 0110 1rrr */ - case 0x6f: /* 1: 0110 1rrr */ - add_r(op & 7); - break; - case 0x70: /* 1: 0111 000r */ - addc_rm(0); - break; - case 0x71: /* 1: 0111 000r */ - addc_rm(1); - break; - case 0x72: /* 2: bbb1 0010 */ - jbb_i(3); - break; - case 0x73: /* 1: 0111 0011 */ - illegal(); - break; - case 0x74: /* 2: aaa1 0100 */ - call_i(0x300); - break; - case 0x75: /* 1: 0111 0101 */ - illegal(); - break; - case 0x76: /* 2: 0111 0110 */ - jf1_i(); - break; - case 0x77: /* 1: 0111 0111 */ - rr_a(); - break; - case 0x78: /* 1: 0111 1rrr */ - case 0x79: /* 1: 0111 1rrr */ - case 0x7a: /* 1: 0111 1rrr */ - case 0x7b: /* 1: 0111 1rrr */ - case 0x7c: /* 1: 0111 1rrr */ - case 0x7d: /* 1: 0111 1rrr */ - case 0x7e: /* 1: 0111 1rrr */ - case 0x7f: /* 1: 0111 1rrr */ - addc_r(op & 7); - break; - case 0x80: /* 1: 1000 0000 */ - illegal(); - break; - case 0x81: /* 1: 1000 0001 */ - illegal(); - break; - case 0x82: /* 1: 1000 0010 */ - illegal(); - break; - case 0x83: /* 2: 1000 0011 */ - ret(); - break; - case 0x84: /* 2: aaa0 0100 */ - jmp_i(0x400); - break; - case 0x85: /* 1: 1000 0101 */ - clr_f0(); - break; - case 0x86: /* 2: 1000 0110 */ - jobf_i(); - break; - case 0x87: /* 1: 1000 0111 */ - illegal(); - break; - case 0x88: /* 2: 1000 10pp */ - case 0x89: /* 2: 1000 10pp */ - case 0x8a: /* 2: 1000 10pp */ - case 0x8b: /* 2: 1000 10pp */ - orl_p_i(op & 3); - break; - case 0x8c: /* 2: 1000 11pp */ - case 0x8d: /* 2: 1000 11pp */ - case 0x8e: /* 2: 1000 11pp */ - case 0x8f: /* 2: 1000 11pp */ - orld_p_a(op & 7); - break; - case 0x90: /* 1: 1001 0000 */ - mov_sts_a(); - break; - case 0x91: /* 1: 1001 0001 */ - illegal(); - break; - case 0x92: /* 2: bbb1 0010 */ - jbb_i(4); - break; - case 0x93: /* 2: 1001 0011 */ - retr(); - break; - case 0x94: /* 1: aaa1 0100 */ - call_i(0x400); - break; - case 0x95: /* 1: 1001 0101 */ - cpl_f0(); - break; - case 0x96: /* 2: 1001 0110 */ - jnz_i(); - break; - case 0x97: /* 1: 1001 0111 */ - clr_c(); - break; - case 0x98: /* 2: 1001 10pp , illegal port */ - case 0x99: /* 2: 1001 10pp */ - case 0x9a: /* 2: 1001 10pp */ - case 0x9b: /* 2: 1001 10pp , illegal port */ - anl_p_i(op & 3); - break; - case 0x9c: /* 2: 1001 11pp */ - case 0x9d: /* 2: 1001 11pp */ - case 0x9e: /* 2: 1001 11pp */ - case 0x9f: /* 2: 1001 11pp */ - anld_p_a(op & 7); - break; - case 0xa0: /* 1: 1010 000r */ - mov_rm_a(0); - break; - case 0xa1: /* 1: 1010 000r */ - mov_rm_a(1); - break; - case 0xa2: /* 1: 1010 0010 */ - illegal(); - break; - case 0xa3: /* 2: 1010 0011 */ - movp_a_am(); - break; - case 0xa4: /* 2: aaa0 0100 */ - jmp_i(0x500); - break; - case 0xa5: /* 1: 1010 0101 */ - clr_f1(); - break; - case 0xa6: /* 1: 1010 0110 */ - illegal(); - break; - case 0xa7: /* 1: 1010 0111 */ - cpl_c(); - break; - case 0xa8: /* 1: 1010 1rrr */ - case 0xa9: /* 1: 1010 1rrr */ - case 0xaa: /* 1: 1010 1rrr */ - case 0xab: /* 1: 1010 1rrr */ - case 0xac: /* 1: 1010 1rrr */ - case 0xad: /* 1: 1010 1rrr */ - case 0xae: /* 1: 1010 1rrr */ - case 0xaf: /* 1: 1010 1rrr */ - mov_r_a(op & 7); - break; - case 0xb0: /* 2: 1011 000r */ - mov_rm_i(0); - break; - case 0xb1: /* 2: 1011 000r */ - mov_rm_i(1); - break; - case 0xb2: /* 2: bbb1 0010 */ - jbb_i(5); - break; - case 0xb3: /* 2: 1011 0011 */ - jmpp_a(); - break; - case 0xb4: /* 2: aaa1 0100 */ - call_i(0x500); - break; - case 0xb5: /* 1: 1011 0101 */ - cpl_f1(); - break; - case 0xb6: /* 2: 1011 0110 */ - jf0_i(); - break; - case 0xb7: /* 1: 1011 0111 */ - illegal(); - break; - case 0xb8: /* 2: 1011 1rrr */ - case 0xb9: /* 2: 1011 1rrr */ - case 0xba: /* 2: 1011 1rrr */ - case 0xbb: /* 2: 1011 1rrr */ - case 0xbc: /* 2: 1011 1rrr */ - case 0xbd: /* 2: 1011 1rrr */ - case 0xbe: /* 2: 1011 1rrr */ - case 0xbf: /* 2: 1011 1rrr */ - mov_r_i(op & 7); - break; - case 0xc0: /* 1: 1100 0000 */ - illegal(); - break; - case 0xc1: /* 1: 1100 0001 */ - illegal(); - break; - case 0xc2: /* 1: 1100 0010 */ - illegal(); - break; - case 0xc3: /* 1: 1100 0011 */ - illegal(); - break; - case 0xc4: /* 2: aaa0 0100 */ - jmp_i(0x600); - break; - case 0xc5: /* 1: 1100 0101 */ - sel_rb0(); - break; - case 0xc6: /* 2: 1100 0110 */ - jz_i(); - break; - case 0xc7: /* 1: 1100 0111 */ - mov_a_psw(); - break; - case 0xc8: /* 1: 1100 1rrr */ - case 0xc9: /* 1: 1100 1rrr */ - case 0xca: /* 1: 1100 1rrr */ - case 0xcb: /* 1: 1100 1rrr */ - case 0xcc: /* 1: 1100 1rrr */ - case 0xcd: /* 1: 1100 1rrr */ - case 0xcf: /* 1: 1100 1rrr */ - dec_r(op & 7); - break; - case 0xd0: /* 1: 1101 000r */ - xrl_rm(0); - break; - case 0xd1: /* 1: 1101 000r */ - xrl_rm(1); - break; - case 0xd2: /* 2: bbb1 0010 */ - jbb_i(6); - break; - case 0xd3: /* 1: 1101 0011 */ - xrl_i(); - break; - case 0xd4: /* 2: aaa1 0100 */ - call_i(0x600); - break; - case 0xd5: /* 1: 1101 0101 */ - sel_rb1(); - break; - case 0xd6: /* 2: 1101 0110 */ - jnibf_i(); - break; - case 0xd7: /* 1: 1101 0111 */ - mov_psw_a(); - break; - case 0xd8: /* 1: 1101 1rrr */ - case 0xd9: /* 1: 1101 1rrr */ - case 0xda: /* 1: 1101 1rrr */ - case 0xdb: /* 1: 1101 1rrr */ - case 0xdc: /* 1: 1101 1rrr */ - case 0xdd: /* 1: 1101 1rrr */ - case 0xde: /* 1: 1101 1rrr */ - case 0xdf: /* 1: 1101 1rrr */ - xrl_r(op & 7); - break; - case 0xe0: /* 1: 1110 0000 */ - illegal(); - break; - case 0xe1: /* 1: 1110 0001 */ - illegal(); - break; - case 0xe2: /* 1: 1110 0010 */ - illegal(); - break; - case 0xe3: /* 2: 1110 0011 */ - movp3_a_am(); - break; - case 0xe4: /* 2: aaa0 0100 */ - jmp_i(0x700); - break; - case 0xe5: /* 1: 1110 0101 */ - en_dma(); - break; - case 0xe6: /* 2: 1110 0110 */ - jnc_i(); - break; - case 0xe7: /* 1: 1110 0111 */ - rl_a(); - break; - case 0xe8: /* 2: 1110 1rrr */ - case 0xe9: /* 2: 1110 1rrr */ - case 0xea: /* 2: 1110 1rrr */ - case 0xeb: /* 2: 1110 1rrr */ - case 0xec: /* 2: 1110 1rrr */ - case 0xed: /* 2: 1110 1rrr */ - case 0xee: /* 2: 1110 1rrr */ - case 0xef: /* 2: 1110 1rrr */ - djnz_r_i(op & 7); - break; - case 0xf0: /* 1: 1111 000r */ - mov_a_rm(0); - break; - case 0xf1: /* 1: 1111 000r */ - mov_a_rm(1); - break; - case 0xf2: /* 2: bbb1 0010 */ - jbb_i(7); - break; - case 0xf3: /* 1: 1111 0011 */ - illegal(); - break; - case 0xf4: /* 2: aaa1 0100 */ - call_i(0x700); - break; - case 0xf5: /* 1: 1111 0101 */ - en_flags(); - break; - case 0xf6: /* 2: 1111 0110 */ - jc_i(); - break; - case 0xf7: /* 1: 1111 0111 */ - rlc_a(); - break; - case 0xf8: /* 1: 1111 1rrr */ - case 0xf9: /* 1: 1111 1rrr */ - case 0xfa: /* 1: 1111 1rrr */ - case 0xfb: /* 1: 1111 1rrr */ - case 0xfc: /* 1: 1111 1rrr */ - case 0xfd: /* 1: 1111 1rrr */ - case 0xfe: /* 1: 1111 1rrr */ - case 0xff: /* 1: 1111 1rrr */ - mov_a_r(op & 7); - break; - } + upi41_state->icount -= i8x41_cycles[op]; + execute_op(upi41_state, op); if( ENABLE & CNT ) { @@ -1993,8 +944,8 @@ static CPU_EXECUTE( i8x41 ) T1_level = RP(I8X41_t1); if( (CONTROL & TEST1) && (T1_level == 0) ) /* Negative Edge */ { - i8x41.timer++; - if (i8x41.timer == 0) + upi41_state->timer++; + if (upi41_state->timer == 0) { CONTROL |= TOVF; if( ENABLE & TCNTI ) @@ -2013,8 +964,8 @@ static CPU_EXECUTE( i8x41 ) if( PRESCALER >= 32 ) { PRESCALER -= 32; - i8x41.timer++; - if( i8x41.timer == 0 ) + upi41_state->timer++; + if( upi41_state->timer == 0 ) { CONTROL |= TOVF; if( ENABLE & TCNTI ) @@ -2033,7 +984,7 @@ static CPU_EXECUTE( i8x41 ) PC = V_IBF; CONTROL &= ~IBFI_PEND; CONTROL |= IBFI_IGNR; - i8x41_ICount -= 2; + upi41_state->icount -= 2; } } if( 0 == (CONTROL & TIRQ_IGNR) ) /* Should we ignore Timer interrupts ? */ @@ -2045,15 +996,15 @@ static CPU_EXECUTE( i8x41 ) CONTROL &= ~TIRQ_PEND; CONTROL |= IRQ_IGNR; if( ENABLE & T ) PRESCALER += 2; /* 2 states */ - i8x41_ICount -= 2; /* 2 states to take interrupt */ + upi41_state->icount -= 2; /* 2 states to take interrupt */ } } } - } while( i8x41_ICount > 0 ); + } while( upi41_state->icount > 0 ); - return cycles - i8x41_ICount; + return cycles - upi41_state->icount ; } @@ -2063,8 +1014,6 @@ static CPU_EXECUTE( i8x41 ) static CPU_GET_CONTEXT( i8x41 ) { - if( dst ) - memcpy(dst, &i8x41, sizeof(I8X41)); } @@ -2074,15 +1023,14 @@ static CPU_GET_CONTEXT( i8x41 ) static CPU_SET_CONTEXT( i8x41 ) { - if( src ) - memcpy(&i8x41, src, sizeof(I8X41)); + token = src; } /**************************************************************************** * Set IRQ line state ****************************************************************************/ -static void set_irq_line(int irqline, int state) +static void set_irq_line(upi41_state_t *upi41_state, int irqline, int state) { switch( irqline ) { @@ -2114,8 +1062,8 @@ static void set_irq_line(int irqline, int state) /* counting enabled? */ if( ENABLE & CNT ) { - i8x41.timer++; - if( i8x41.timer == 0 ) + upi41_state->timer++; + if( upi41_state->timer == 0 ) { CONTROL |= TOVF; CONTROL |= TIRQ_PEND; @@ -2155,11 +1103,13 @@ ADDRESS_MAP_END static CPU_SET_INFO( i8x41 ) { + upi41_state_t *upi41_state = token; + switch (state) { /* --- the following bits of info are set as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_STATE + I8X41_INT_IBF: set_irq_line(I8X41_INT_IBF, info->i); break; - case CPUINFO_INT_INPUT_STATE + I8X41_INT_TEST1: set_irq_line(I8X41_INT_TEST1, info->i); break; + case CPUINFO_INT_INPUT_STATE + I8X41_INT_IBF: set_irq_line(upi41_state, I8X41_INT_IBF, info->i); break; + case CPUINFO_INT_INPUT_STATE + I8X41_INT_TEST1: set_irq_line(upi41_state, I8X41_INT_TEST1, info->i); break; case CPUINFO_INT_PC: case CPUINFO_INT_REGISTER + I8X41_PC: PC = info->i & 0x7ff; break; @@ -2169,7 +1119,7 @@ static CPU_SET_INFO( i8x41 ) case CPUINFO_INT_REGISTER + I8X41_PSW: PSW = info->i; break; case CPUINFO_INT_REGISTER + I8X41_A: A = info->i; break; - case CPUINFO_INT_REGISTER + I8X41_T: i8x41.timer = info->i & 0x1fff; break; + case CPUINFO_INT_REGISTER + I8X41_T: upi41_state->timer = info->i & 0x1fff; break; case CPUINFO_INT_REGISTER + I8X41_R0: SETR(0, info->i); break; case CPUINFO_INT_REGISTER + I8X41_R1: SETR(1, info->i); break; case CPUINFO_INT_REGISTER + I8X41_R2: SETR(2, info->i); break; @@ -2181,7 +1131,7 @@ static CPU_SET_INFO( i8x41 ) case CPUINFO_INT_REGISTER + I8X41_DATA: DBBI = info->i; - if( i8x41.subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ + if( upi41_state->subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ DBBO = info->i; STATE &= ~F1; STATE |= IBF; @@ -2200,13 +1150,13 @@ static CPU_SET_INFO( i8x41 ) /* Same as I8X41_DATA, except this is used by the */ /* debugger and does not upset the flag states */ DBBI = info->i; - if( i8x41.subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ + if( upi41_state->subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ DBBO = info->i; break; case CPUINFO_INT_REGISTER + I8X41_CMND: DBBI = info->i; - if( i8x41.subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ + if( upi41_state->subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ DBBO = info->i; STATE |= F1; STATE |= IBF; @@ -2225,7 +1175,7 @@ static CPU_SET_INFO( i8x41 ) /* Same as I8X41_CMND, except this is used by the */ /* debugger and does not upset the flag states */ DBBI = info->i; - if( i8x41.subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ + if( upi41_state->subtype == 8041 ) /* plain 8041 had no split input/output DBB buffers */ DBBO = info->i; break; @@ -2245,10 +1195,12 @@ static CPU_SET_INFO( i8x41 ) CPU_GET_INFO( i8041 ) { + upi41_state_t *upi41_state = token; + switch (state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(i8x41); break; + case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(upi41_state_t); break; case CPUINFO_INT_INPUT_LINES: info->i = 2; break; case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break; @@ -2285,7 +1237,7 @@ CPU_GET_INFO( i8041 ) case CPUINFO_INT_REGISTER + I8X41_PSW: info->i = PSW; break; case CPUINFO_INT_REGISTER + I8X41_A: info->i = A; break; - case CPUINFO_INT_REGISTER + I8X41_T: info->i = i8x41.timer; break; + case CPUINFO_INT_REGISTER + I8X41_T: info->i = upi41_state->timer; break; case CPUINFO_INT_REGISTER + I8X41_R0: info->i = GETR(0); break; case CPUINFO_INT_REGISTER + I8X41_R1: info->i = GETR(1); break; case CPUINFO_INT_REGISTER + I8X41_R2: info->i = GETR(2); break; @@ -2319,54 +1271,54 @@ CPU_GET_INFO( i8041 ) break; /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(i8x41); break; + case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(i8x41); break; case CPUINFO_PTR_GET_CONTEXT: info->getcontext = CPU_GET_CONTEXT_NAME(i8x41); break; case CPUINFO_PTR_SET_CONTEXT: info->setcontext = CPU_SET_CONTEXT_NAME(i8x41); break; case CPUINFO_PTR_INIT: info->init = CPU_INIT_NAME(i8x41); break; - case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(i8x41); break; + case CPUINFO_PTR_RESET: info->reset = CPU_RESET_NAME(i8x41); break; case CPUINFO_PTR_EXIT: info->exit = CPU_EXIT_NAME(i8x41); break; - case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(i8x41); break; - case CPUINFO_PTR_BURN: info->burn = NULL; break; + case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(i8x41); break; + case CPUINFO_PTR_BURN: info->burn = NULL; break; case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(i8x41); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &i8x41_ICount; break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &upi41_state->icount ; break; /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "I8041"); break; - case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "UPI-41/42"); break; - case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "0.6"); break; - case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; + case CPUINFO_STR_NAME: strcpy(info->s, "I8041"); break; + case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "UPI-41/42"); break; + case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "0.6"); break; + case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Juergen Buchmueller, all rights reserved."); break; case CPUINFO_STR_FLAGS: sprintf(info->s, "%c%c%c%c%c%c%c%c", - i8x41.psw & 0x80 ? 'C':'.', - i8x41.psw & 0x40 ? 'A':'.', - i8x41.psw & 0x20 ? '0':'.', - i8x41.psw & 0x10 ? 'B':'.', - i8x41.psw & 0x08 ? '?':'.', - i8x41.psw & 0x04 ? 's':'.', - i8x41.psw & 0x02 ? 's':'.', - i8x41.psw & 0x01 ? 's':'.'); + upi41_state->psw & 0x80 ? 'C':'.', + upi41_state->psw & 0x40 ? 'A':'.', + upi41_state->psw & 0x20 ? '0':'.', + upi41_state->psw & 0x10 ? 'B':'.', + upi41_state->psw & 0x08 ? '?':'.', + upi41_state->psw & 0x04 ? 's':'.', + upi41_state->psw & 0x02 ? 's':'.', + upi41_state->psw & 0x01 ? 's':'.'); break; - case CPUINFO_STR_REGISTER + I8X41_PC: sprintf(info->s, "PC:%04X", i8x41.pc); break; - case CPUINFO_STR_REGISTER + I8X41_SP: sprintf(info->s, "S:%X", i8x41.psw & SP); break; - case CPUINFO_STR_REGISTER + I8X41_PSW: sprintf(info->s, "PSW:%02X", i8x41.psw); break; - case CPUINFO_STR_REGISTER + I8X41_A: sprintf(info->s, "A:%02X", i8x41.a); break; - case CPUINFO_STR_REGISTER + I8X41_T: sprintf(info->s, "T:%02X.%02X", i8x41.timer, (i8x41.prescaler & 0x1f) ); break; - case CPUINFO_STR_REGISTER + I8X41_R0: sprintf(info->s, "R0:%02X", GETR(0)); break; - case CPUINFO_STR_REGISTER + I8X41_R1: sprintf(info->s, "R1:%02X", GETR(1)); break; - case CPUINFO_STR_REGISTER + I8X41_R2: sprintf(info->s, "R2:%02X", GETR(2)); break; - case CPUINFO_STR_REGISTER + I8X41_R3: sprintf(info->s, "R3:%02X", GETR(3)); break; - case CPUINFO_STR_REGISTER + I8X41_R4: sprintf(info->s, "R4:%02X", GETR(4)); break; - case CPUINFO_STR_REGISTER + I8X41_R5: sprintf(info->s, "R5:%02X", GETR(5)); break; - case CPUINFO_STR_REGISTER + I8X41_R6: sprintf(info->s, "R6:%02X", GETR(6)); break; - case CPUINFO_STR_REGISTER + I8X41_R7: sprintf(info->s, "R7:%02X", GETR(7)); break; - case CPUINFO_STR_REGISTER + I8X41_P1: sprintf(info->s, "P1:%02X", i8x41.p1); break; - case CPUINFO_STR_REGISTER + I8X41_P2: sprintf(info->s, "P2:%02X", i8x41.p2); break; - case CPUINFO_STR_REGISTER + I8X41_DATA_DASM: sprintf(info->s, "DBBI:%02X", i8x41.dbbi); break; - case CPUINFO_STR_REGISTER + I8X41_CMND_DASM: sprintf(info->s, "DBBO:%02X", i8x41.dbbo); break; - case CPUINFO_STR_REGISTER + I8X41_STAT: sprintf(info->s, "STAT:%02X", i8x41.state); break; + case CPUINFO_STR_REGISTER + I8X41_PC: sprintf(info->s, "PC:%04X", upi41_state->pc); break; + case CPUINFO_STR_REGISTER + I8X41_SP: sprintf(info->s, "S:%X", upi41_state->psw & SP); break; + case CPUINFO_STR_REGISTER + I8X41_PSW: sprintf(info->s, "PSW:%02X", upi41_state->psw); break; + case CPUINFO_STR_REGISTER + I8X41_A: sprintf(info->s, "A:%02X", upi41_state->a); break; + case CPUINFO_STR_REGISTER + I8X41_T: sprintf(info->s, "T:%02X.%02X", upi41_state->timer, (upi41_state->prescaler & 0x1f) ); break; + case CPUINFO_STR_REGISTER + I8X41_R0: sprintf(info->s, "R0:%02X", GETR(0)); break; + case CPUINFO_STR_REGISTER + I8X41_R1: sprintf(info->s, "R1:%02X", GETR(1)); break; + case CPUINFO_STR_REGISTER + I8X41_R2: sprintf(info->s, "R2:%02X", GETR(2)); break; + case CPUINFO_STR_REGISTER + I8X41_R3: sprintf(info->s, "R3:%02X", GETR(3)); break; + case CPUINFO_STR_REGISTER + I8X41_R4: sprintf(info->s, "R4:%02X", GETR(4)); break; + case CPUINFO_STR_REGISTER + I8X41_R5: sprintf(info->s, "R5:%02X", GETR(5)); break; + case CPUINFO_STR_REGISTER + I8X41_R6: sprintf(info->s, "R6:%02X", GETR(6)); break; + case CPUINFO_STR_REGISTER + I8X41_R7: sprintf(info->s, "R7:%02X", GETR(7)); break; + case CPUINFO_STR_REGISTER + I8X41_P1: sprintf(info->s, "P1:%02X", upi41_state->p1); break; + case CPUINFO_STR_REGISTER + I8X41_P2: sprintf(info->s, "P2:%02X", upi41_state->p2); break; + case CPUINFO_STR_REGISTER + I8X41_DATA_DASM: sprintf(info->s, "DBBI:%02X", upi41_state->dbbi); break; + case CPUINFO_STR_REGISTER + I8X41_CMND_DASM: sprintf(info->s, "DBBO:%02X", upi41_state->dbbo); break; + case CPUINFO_STR_REGISTER + I8X41_STAT: sprintf(info->s, "STAT:%02X", upi41_state->state); break; } } diff --git a/src/emu/cpu/i8x41/i8x41ops.c b/src/emu/cpu/i8x41/i8x41ops.c new file mode 100644 index 00000000000..ee93f203502 --- /dev/null +++ b/src/emu/cpu/i8x41/i8x41ops.c @@ -0,0 +1,1085 @@ + +/************************************************************************ + * Emulate the Instructions + ************************************************************************/ + +#define OP_HANDLER( _name ) INLINE void _name (upi41_state_t *upi41_state, UINT8 r) + +/*********************************** + * illegal opcodes + ***********************************/ +OP_HANDLER( illegal ) +{ + logerror("i8x41 #%d: illegal opcode at 0x%03x: %02x\n", cpu_getactivecpu(), PC, ROP(PC)); +} + +/*********************************** + * 0110 1rrr * ADD A,Rr + ***********************************/ +OP_HANDLER( add_r ) +{ + UINT8 res = A + GETR(r); + if( res < A ) PSW |= FC; + if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; + A = res; +} + +/*********************************** + * 0110 000r + * ADD A,@Rr + ***********************************/ +OP_HANDLER( add_rm ) +{ + UINT8 res = A + IRAM_R(GETR(r)); + if( res < A ) PSW |= FC; + if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; + A = res; +} + +/*********************************** + * 0000 0011 7654 3210 + * ADD A,#n + ***********************************/ +OP_HANDLER( add_i ) +{ + UINT8 res = A + ROP_ARG(PC); + PC++; + if( res < A ) PSW |= FC; + if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; + A = res; +} + +/*********************************** + * 0111 1rrr + * ADDC A,Rr + ***********************************/ +OP_HANDLER( addc_r ) +{ + UINT8 res = A + GETR(r) + (PSW >> 7); + if( res <= A ) PSW |= FC; + if( (res & 0x0f) <= (A & 0x0f) ) PSW |= FA; + A = res; +} + +/*********************************** + * 0111 000r + * ADDC A,@Rr + ***********************************/ +OP_HANDLER( addc_rm ) +{ + UINT8 res = A + IRAM_R(GETR(r)) + (PSW >> 7); + if( res <= A ) PSW |= FC; + if( (res & 0x0f) <= (A & 0x0f) ) PSW |= FA; + A = res; +} + +/*********************************** + * 0001 0011 7654 3210 + * ADDC A,#n + ***********************************/ +OP_HANDLER( addc_i ) +{ + UINT8 res = A + ROP_ARG(PC) + (PSW >> 7); + PC++; + if( res <= A ) PSW |= FC; + if( (res & 0x0f) < (A & 0x0f) ) PSW |= FA; + A = res; +} + +/*********************************** + * 0101 1rrr + * ANL A,Rr + ***********************************/ +OP_HANDLER( anl_r ) +{ + A = A & GETR(r); +} + +/*********************************** + * 0101 000r + * ANL A,@Rr + ***********************************/ +OP_HANDLER( anl_rm ) +{ + A = A & IRAM_R(GETR(r)); +} + +/*********************************** + * 0101 0011 7654 3210 + * ANL A,#n + ***********************************/ +OP_HANDLER( anl_i ) +{ + A = A & ROP_ARG(PC); + PC++; +} + +/*********************************** + * 1001 10pp 7654 3210 + * ANL Pp,#n + ***********************************/ +OP_HANDLER( anl_p_i ) +{ + UINT8 p = r; + UINT8 val = ROP_ARG(PC); + PC++; + /* changed to latched port scheme */ + switch (p) + { + case 00: break; /* invalid port */ + case 01: P1 &= val; WP(p, P1); break; + case 02: P2 &= val; WP(p, (P2 & P2_HS) ); break; + case 03: break; /* invalid port */ + default: break; + } +} + +/*********************************** + * 1001 11pp 7654 3210 + * ANLD Pp,A + ***********************************/ +OP_HANDLER( anld_p_a ) +{ + UINT8 p = r; + /* added proper expanded port setup */ + WP(2, (P2 & 0xf0) | 0x0c | p); /* AND mode */ + WP(I8X41_ps, 0); /* activate command strobe */ + WP(2, (A & 0x0f)); /* Expander to take care of AND function */ + WP(I8X41_ps, 1); /* release command strobe */ +} + +/*********************************** + * aaa1 0100 7654 3210 + * CALL addr + ***********************************/ +OP_HANDLER( call_i ) +{ + UINT16 page = (r & 0xe0) << 3; + UINT8 adr = ROP_ARG(PC); + PC++; + PUSH_PC_TO_STACK(); + PC = page | adr; +} + +/*********************************** + * 0010 0111 + * CLR A + ***********************************/ +OP_HANDLER( clr_a ) +{ + A = 0; +} + +/*********************************** + * 1001 0111 + * CLR C + ***********************************/ +OP_HANDLER( clr_c ) +{ + PSW &= ~FC; +} + +/*********************************** + * 1000 0101 + * CLR F0 + ***********************************/ +OP_HANDLER( clr_f0 ) +{ + PSW &= ~Ff0; + STATE &= ~F0; +} + +/*********************************** + * 1010 0101 + * CLR F1 + ***********************************/ +OP_HANDLER( clr_f1 ) +{ + STATE &= ~F1; +} + +/*********************************** + * 0011 0111 + * CPL A + ***********************************/ +OP_HANDLER( cpl_a ) +{ + A = ~A; +} + +/*********************************** + * 1010 0111 + * CPL C + ***********************************/ +OP_HANDLER( cpl_c ) +{ + PSW ^= FC; +} + +/*********************************** + * 1001 0101 + * CPL F0 + ***********************************/ +OP_HANDLER( cpl_f0 ) +{ + PSW ^= Ff0; + STATE ^= F0; +} + +/*********************************** + * 1011 0101 + * CPL F1 + ***********************************/ +OP_HANDLER( cpl_f1 ) +{ + STATE ^= F1; +} + +/*********************************** + * 0101 0111 + * DA A + ***********************************/ +OP_HANDLER( da_a ) +{ + UINT8 res = A + ((PSW & FA) || ((A & 0x0f) > 0x09)) ? 0x06 : 0x00; + if( (PSW & FC) || ((res & 0xf0) > 0x90) ) + res += 0x60; + if( res < A ) + PSW |= FC; + else + PSW &= ~FC; + A = res; +} + +/*********************************** + * 0000 0111 + * DEC A + ***********************************/ +OP_HANDLER( dec_a ) +{ + A -= 1; +} + +/*********************************** + * 1100 1rrr + * DEC Rr + ***********************************/ +OP_HANDLER( dec_r ) +{ + SETR(r, GETR(r) - 1); +} + +/*********************************** + * 0001 0101 + * DIS I + ***********************************/ +OP_HANDLER( dis_i ) +{ + ENABLE &= ~IBFI; /* disable input buffer full interrupt */ +} + +/*********************************** + * 0011 0101 + * DIS TCNTI + ***********************************/ +OP_HANDLER( dis_tcnti ) +{ + ENABLE &= ~TCNTI; /* disable timer/counter interrupt */ +} + +/*********************************** + * 0111 1rrr 7654 3210 + * DJNZ Rr,addr + ***********************************/ +OP_HANDLER( djnz_r_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC++; + SETR(r, GETR(r) - 1); + if( GETR(r) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1110 0101 + * EN DMA + ***********************************/ +OP_HANDLER( en_dma ) +{ + ENABLE |= DMA; /* enable DMA handshake lines */ + P2_HS &= 0xbf; + WP(0x02, (P2 & P2_HS) ); +} + +/*********************************** + * 1111 0101 + * EN FLAGS + ***********************************/ +OP_HANDLER( en_flags ) +{ + if( 0 == (ENABLE & FLAGS) ) + { + /* Configure upper lines on Port 2 for IRQ handshaking (P24 and P25) */ + + ENABLE |= FLAGS; + if( STATE & OBF ) P2_HS |= 0x10; + else P2_HS &= 0xef; + if( STATE & IBF ) P2_HS |= 0x20; + else P2_HS &= 0xdf; + WP(0x02, (P2 & P2_HS) ); + } +} + +/*********************************** + * 0000 0101 + * EN I + ***********************************/ +OP_HANDLER( en_i ) +{ + if( 0 == (ENABLE & IBFI) ) + { + ENABLE |= IBFI; /* enable input buffer full interrupt */ + CONTROL &= ~IBFI_IGNR; + if( STATE & IBF ) /* already got data in the buffer? */ + set_irq_line(upi41_state, I8X41_INT_IBF, HOLD_LINE); + } +} + +/*********************************** + * 0010 0101 + * EN TCNTI + ***********************************/ +OP_HANDLER( en_tcnti ) +{ + ENABLE |= TCNTI; /* enable timer/counter interrupt */ + CONTROL &= ~TIRQ_IGNR; +} + +/*********************************** + * 0010 0010 + * IN A,DBB + ***********************************/ +OP_HANDLER( in_a_dbb ) +{ + if( upi41_state->irq_callback ) + (upi41_state->irq_callback)(upi41_state->device, I8X41_INT_IBF); + + STATE &= ~IBF; /* clear input buffer full flag */ + if( ENABLE & FLAGS ) + { + P2_HS &= 0xdf; + if( STATE & OBF ) P2_HS |= 0x10; + else P2_HS &= 0xef; + WP(0x02, (P2 & P2_HS) ); /* Clear the DBBI IRQ out on P25 */ + } + A = DBBI; +} + +/*********************************** + * 0000 10pp + * IN A,Pp + ***********************************/ +OP_HANDLER( in_a_p ) +{ + UINT8 p = r; + /* changed to latched port scheme */ + switch( p ) + { + case 00: break; /* invalid port */ + case 01: A = (RP(p) & P1); break; + case 02: A = (RP(p) & P2); break; + case 03: break; /* invalid port */ + default: break; + } +} + +/*********************************** + * 0001 0111 + * INC A + ***********************************/ +OP_HANDLER( inc_a ) +{ + A += 1; +} + +/*********************************** + * 0001 1rrr + * INC Rr + ***********************************/ +OP_HANDLER( inc_r ) +{ + SETR(r, GETR(r) + 1); +} + +/*********************************** + * 0001 000r + * INC @ Rr + ***********************************/ +OP_HANDLER( inc_rm ) +{ + UINT16 addr = GETR(r); + IRAM_W( addr, IRAM_R(addr) + 1 ); +} + +/*********************************** + * bbb1 0010 + * JBb addr + ***********************************/ +OP_HANDLER( jbb_i ) +{ + UINT8 bit = r; + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( A & (1 << bit) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1111 0110 + * JC addr + ***********************************/ +OP_HANDLER( jc_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( PSW & FC ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1011 0110 + * JF0 addr + ***********************************/ +OP_HANDLER( jf0_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( STATE & F0 ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 0111 0110 + * JF1 addr + ***********************************/ +OP_HANDLER( jf1_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( STATE & F1 ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * aaa0 0100 + * JMP addr + ***********************************/ +OP_HANDLER( jmp_i ) +{ + /* err.. do we have 10 or 11 PC bits? + * CALL is said to use 0aa1 (4 pages) + * JMP is said to use aaa0 (8 pages) + */ + UINT16 page = ((r & 0xe0) << 3); + UINT8 adr = ROP_ARG(PC); + PC = page | adr; +} + +/*********************************** + * 1011 0011 + * JMP @ A + ***********************************/ +OP_HANDLER( jmpp_a ) +{ + UINT16 adr = (PC & 0x700) | A; + PC = (PC & 0x700) | RM(adr); +} + +/*********************************** + * 1110 0110 + * JNC addr + ***********************************/ +OP_HANDLER( jnc_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( !(PSW & FC) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1101 0110 + * JNIBF addr + ***********************************/ +OP_HANDLER( jnibf_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( 0 == (STATE & IBF) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 0010 0110 + * JNT0 addr + ***********************************/ +OP_HANDLER( jnt0_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( 0 == RP(I8X41_t0) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 0100 0110 + * JNT1 addr + ***********************************/ +OP_HANDLER( jnt1_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( !(ENABLE & CNT) ) + { + UINT8 level = RP(I8X41_t1); + if( level ) CONTROL |= TEST1; + else CONTROL &= ~TEST1; + } + if( !(CONTROL & TEST1) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1001 0110 + * JNZ addr + ***********************************/ +OP_HANDLER( jnz_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( A ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1000 0110 + * JOBF addr + ***********************************/ +OP_HANDLER( jobf_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( STATE & OBF ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 0001 0110 + * JTF addr + ***********************************/ +OP_HANDLER( jtf_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( CONTROL & TOVF ) + PC = (PC & 0x700) | adr; + CONTROL &= ~TOVF; +} + +/*********************************** + * 0011 0110 + * JT0 addr + ***********************************/ +OP_HANDLER( jt0_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( RP(I8X41_t0) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 0101 0110 + * JT1 addr + ***********************************/ +OP_HANDLER( jt1_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( !(ENABLE & CNT) ) + { + UINT8 level = RP(I8X41_t1); + if( level ) CONTROL |= TEST1; + else CONTROL &= ~TEST1; + } + if( (CONTROL & TEST1) ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 1100 0110 + * JZ addr + ***********************************/ +OP_HANDLER( jz_i ) +{ + UINT8 adr = ROP_ARG(PC); + PC += 1; + if( !A ) + PC = (PC & 0x700) | adr; +} + +/*********************************** + * 0010 0011 + * MOV A,#n + ***********************************/ +OP_HANDLER( mov_a_i ) +{ + A = ROP(PC); + PC += 1; +} + +/*********************************** + * 1100 0111 + * MOV A,PSW + ***********************************/ +OP_HANDLER( mov_a_psw ) +{ + A = PSW; +} + +/*********************************** + * 1111 1rrr + * MOV A,Rr + ***********************************/ +OP_HANDLER( mov_a_r ) +{ + A = GETR(r); +} + +/*********************************** + * 1111 000r + * MOV A,Rr + ***********************************/ +OP_HANDLER( mov_a_rm ) +{ + A = IRAM_R(GETR(r)); +} + +/*********************************** + * 0100 0010 + * MOV A,T + ***********************************/ +OP_HANDLER( mov_a_t ) +{ + A = upi41_state->timer; +} + +/*********************************** + * 1101 0111 + * MOV PSW,A + ***********************************/ +OP_HANDLER( mov_psw_a ) +{ + PSW = A; +} + +/*********************************** + * 1010 1rrr + * MOV Rr,A + ***********************************/ +OP_HANDLER( mov_r_a ) +{ + SETR(r, A); +} + +/*********************************** + * 1011 1rrr + * MOV Rr,#n + ***********************************/ +OP_HANDLER( mov_r_i ) +{ + UINT8 val = ROP_ARG(PC); + PC += 1; + SETR(r, val); +} + +/*********************************** + * 1010 000r + * MOV @Rr,A + ***********************************/ +OP_HANDLER( mov_rm_a ) +{ + IRAM_W(GETR(r), A ); +} + +/*********************************** + * 1011 000r + * MOV @Rr,#n + ***********************************/ +OP_HANDLER( mov_rm_i ) +{ + UINT8 val = ROP_ARG(PC); + PC += 1; + IRAM_W(GETR(r), val ); +} + +/*********************************** + * 1001 0000 + * MOV STS,A + ***********************************/ +OP_HANDLER( mov_sts_a ) +{ + STATE = (STATE & 0x0f) | (A & 0xf0); +} + +/*********************************** + * 0110 0010 + * MOV T,A + ***********************************/ +OP_HANDLER( mov_t_a ) +{ + upi41_state->timer = A; +} + +/*********************************** + * 0000 11pp + * MOVD A,Pp + ***********************************/ +OP_HANDLER( movd_a_p ) +{ + UINT8 p = r; + /* added proper expanded port setup */ + WP(2, (P2 & 0xf0) | 0x00 | p); /* READ mode */ + WP(I8X41_ps, 0); /* activate command strobe */ + A = RP(2) & 0xf; + WP(I8X41_ps, 1); /* release command strobe */ +} + +/*********************************** + * 0011 11pp + * MOVD Pp,A + ***********************************/ +OP_HANDLER( movd_p_a ) +{ + UINT8 p = r; + /* added proper expanded port setup */ + WP(2, (P2 & 0xf0) | 0x04 | p); /* WRITE mode */ + WP(I8X41_ps, 0); /* activate command strobe */ + WP(2, A & 0x0f); + WP(I8X41_ps, 1); /* release command strobe */ +} + +/*********************************** + * 1010 0011 + * MOVP A,@A + ***********************************/ +OP_HANDLER( movp_a_am ) +{ + UINT16 addr = (PC & 0x700) | A; + A = RM(addr); +} + +/*********************************** + * 1110 0011 + * MOVP3 A,@A + ***********************************/ +OP_HANDLER( movp3_a_am ) +{ + UINT16 addr = 0x300 | A; + A = RM(addr); +} + +/*********************************** + * 0000 0000 + * NOP + ***********************************/ +OP_HANDLER( nop ) +{ +} + +/*********************************** + * 0100 1rrr + * ORL A,Rr + ***********************************/ +OP_HANDLER( orl_r ) +{ + A = A | GETR(r); +} + +/*********************************** + * 0100 000r + * ORL A,@Rr + ***********************************/ +OP_HANDLER( orl_rm ) +{ + A = A | IRAM_R(GETR(r)); +} + +/*********************************** + * 0100 0011 7654 3210 + * ORL A,#n + ***********************************/ +OP_HANDLER( orl_i ) +{ + UINT8 val = ROP_ARG(PC); + PC++; + A = A | val; +} + +/*********************************** + * 1000 10pp 7654 3210 + * ORL Pp,#n + ***********************************/ +OP_HANDLER( orl_p_i ) +{ + UINT8 p = r; + UINT8 val = ROP_ARG(PC); + PC++; + /* changed to latched port scheme */ + switch (p) + { + case 00: break; /* invalid port */ + case 01: P1 |= val; WP(p, P1); break; + case 02: P2 |= val; WP(p, P2); break; + case 03: break; /* invalid port */ + default: break; + } +} + +/*********************************** + * 1000 11pp 7654 3210 + * ORLD Pp,A + ***********************************/ +OP_HANDLER( orld_p_a ) +{ + UINT8 p = r; + /* added proper expanded port setup */ + WP(2, (P2 & 0xf0) | 0x08 | p); /* OR mode */ + WP(I8X41_ps, 0); /* activate command strobe */ + WP(2, A & 0x0f); /* Expander to take care of OR function */ + WP(I8X41_ps, 1); /* release command strobe */ +} + +/*********************************** + * 0000 0010 + * OUT DBB,A + ***********************************/ +OP_HANDLER( out_dbb_a ) +{ + DBBO = A; /* DBB output buffer */ + STATE |= OBF; /* assert the output buffer full flag */ + if( ENABLE & FLAGS ) + { + P2_HS |= 0x10; + if( STATE & IBF ) P2_HS |= 0x20; + else P2_HS &= 0xdf; + WP(0x02, (P2 & P2_HS) ); /* Assert the DBBO IRQ out on P24 */ + } +} + +/*********************************** + * 0011 10pp + * OUT Pp,A + ***********************************/ +OP_HANDLER( out_p_a ) +{ + UINT8 p = r; + /* changed to latched port scheme */ + switch (p) + { + case 00: break; /* invalid port */ + case 01: WP(p, A); P1 = A; break; + case 02: WP(p, A); P2 = A; break; + case 03: break; /* invalid port */ + default: break; + } +} + +/*********************************** + * 1000 0011 + * RET + ***********************************/ +OP_HANDLER( ret ) +{ + UINT8 msb; + PSW = (PSW & ~SP) | ((PSW - 1) & SP); + msb = IRAM_R(M_STACK + (PSW&SP) * 2 + 1); + PC = IRAM_R(M_STACK + (PSW&SP) * 2 + 0); + PC |= (msb << 8) & 0x700; +} + +/*********************************** + * 1001 0011 + * RETR + ***********************************/ +OP_HANDLER( retr ) +{ + UINT8 msb; + PSW = (PSW & ~SP) | ((PSW - 1) & SP); + msb = IRAM_R(M_STACK + (PSW&SP) * 2 + 1); + PC = IRAM_R(M_STACK + (PSW&SP) * 2 + 0); + PC |= (msb << 8) & 0x700; + PSW = (PSW & 0x0f) | (msb & 0xf0); + CONTROL &= ~IRQ_IGNR; +} + +/*********************************** + * 1110 0111 + * RL A + ***********************************/ +OP_HANDLER( rl_a ) +{ + A = (A << 1) | (A >> 7); +} + +/*********************************** + * 1111 0111 + * RLC A + ***********************************/ +OP_HANDLER( rlc_a ) +{ + UINT8 c = PSW >> 7; + PSW = (PSW & ~FC) | (A & FC); + A = (A << 1) | c; +} + +/*********************************** + * 0111 0111 + * RR A + ***********************************/ +OP_HANDLER( rr_a ) +{ + A = (A >> 1) | (A << 7); +} + +/*********************************** + * 0110 0111 + * RRC A + ***********************************/ +OP_HANDLER( rrc_a ) +{ + UINT8 c = PSW & 0x80; + PSW = (PSW & ~FC) | (A << 7); + A = (A >> 1) | c; +} + +/*********************************** + * 1100 0101 + * SEL RB0 + ***********************************/ +OP_HANDLER( sel_rb0 ) +{ + PSW &= ~BS; +} + +/*********************************** + * 1101 0101 + * SEL RB1 + ***********************************/ +OP_HANDLER( sel_rb1 ) +{ + PSW |= BS; +} + +/*********************************** + * 0110 0101 + * STOP TCNT + ***********************************/ +OP_HANDLER( stop_tcnt ) +{ + ENABLE &= ~(T|CNT); +} + +/*********************************** + * 0100 0101 + * STRT CNT + ***********************************/ +OP_HANDLER( strt_cnt ) +{ + ENABLE |= CNT; + ENABLE &= ~T; +} + +/*********************************** + * 0101 0101 + * STRT T + ***********************************/ +OP_HANDLER( strt_t ) +{ + ENABLE |= T; + ENABLE &= ~CNT; +} + +/*********************************** + * 0100 0111 + * SWAP A + ***********************************/ +OP_HANDLER( swap_a ) +{ + A = (A << 4) | (A >> 4); +} + +/*********************************** + * 0010 1rrr + * XCH A,Rr + ***********************************/ +OP_HANDLER( xch_a_r ) +{ + UINT8 tmp = GETR(r); + SETR(r, A); + A = tmp; +} + +/*********************************** + * 0010 000r + * XCH A,@Rr + ***********************************/ +OP_HANDLER( xch_a_rm ) +{ + UINT16 addr = GETR(r); + UINT8 tmp = IRAM_R(addr); + IRAM_W( addr, A ); + A = tmp; +} + +/*********************************** + * 0011 000r + * XCHD A,@Rr + ***********************************/ +OP_HANDLER( xchd_a_rm ) +{ + UINT16 addr = GETR(r); + UINT8 tmp = IRAM_R(addr); + IRAM_W( addr, (tmp & 0xf0) | (A & 0x0f) ); + A = (A & 0xf0) | (tmp & 0x0f); +} + +/*********************************** + * 1101 1rrr + * XRL A,Rr + ***********************************/ +OP_HANDLER( xrl_r ) +{ + A = A ^ GETR(r); +} + +/*********************************** + * 1101 000r + * XRL A,@Rr + ***********************************/ +OP_HANDLER( xrl_rm ) +{ + A = A ^ IRAM_R(GETR(r)); +} + +/*********************************** + * 1101 0011 7654 3210 + * XRL A,#n + ***********************************/ +OP_HANDLER( xrl_i ) +{ + UINT8 val = ROP_ARG(PC); + PC++; + A = A ^ val; +} +