diff --git a/.gitattributes b/.gitattributes index 45db586634a..dfb69732068 100644 --- a/.gitattributes +++ b/.gitattributes @@ -581,10 +581,6 @@ src/emu/cpu/upd7810/7810ops.c svneol=native#text/plain src/emu/cpu/upd7810/7810tbl.c svneol=native#text/plain src/emu/cpu/upd7810/upd7810.c svneol=native#text/plain src/emu/cpu/upd7810/upd7810.h svneol=native#text/plain -src/emu/cpu/v30mz/nec.h svneol=native#text/plain -src/emu/cpu/v30mz/necea.h svneol=native#text/plain -src/emu/cpu/v30mz/necinstr.h svneol=native#text/plain -src/emu/cpu/v30mz/necmodrm.h svneol=native#text/plain src/emu/cpu/v30mz/v30mz.c svneol=native#text/plain src/emu/cpu/v30mz/v30mz.h svneol=native#text/plain src/emu/cpu/v60/am.c svneol=native#text/plain diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index d43253d1353..036d7b06691 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -1298,11 +1298,7 @@ $(CPUOBJ)/nec/v25sfr.o: $(CPUSRC)/nec/v25sfr.c \ $(CPUSRC)/nec/v25priv.h $(CPUOBJ)/v30mz/v30mz.o: $(CPUSRC)/v30mz/v30mz.c \ - $(CPUSRC)/v30mz/v30mz.h \ - $(CPUSRC)/v30mz/necmodrm.h \ - $(CPUSRC)/v30mz/necinstr.h \ - $(CPUSRC)/v30mz/necea.h \ - $(CPUSRC)/v30mz/nec.h + $(CPUSRC)/v30mz/v30mz.h diff --git a/src/emu/cpu/v30mz/nec.h b/src/emu/cpu/v30mz/nec.h deleted file mode 100644 index a3e575b3413..00000000000 --- a/src/emu/cpu/v30mz/nec.h +++ /dev/null @@ -1,23 +0,0 @@ -/* ASG 971222 -- rewrote this interface */ -#ifndef __NECINTRF_H__ -#define __NECINTRF_H__ - - -typedef struct _nec_config nec_config; -struct _nec_config -{ - const UINT8* v25v35_decryptiontable; // internal decryption table -}; - -enum -{ - NEC_PC=0, - NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY, - NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS, - NEC_VECTOR, NEC_PENDING -}; - -/* Public functions */ -DECLARE_LEGACY_CPU_DEVICE(V30MZ, v30mz); - -#endif /* __NECINTRF_H__ */ diff --git a/src/emu/cpu/v30mz/necea.h b/src/emu/cpu/v30mz/necea.h deleted file mode 100644 index d55b5c75b0a..00000000000 --- a/src/emu/cpu/v30mz/necea.h +++ /dev/null @@ -1,56 +0,0 @@ - -static unsigned EA_000(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[BW]+cpustate->regs.w[IX]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_001(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[BW]+cpustate->regs.w[IY]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_002(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[BP]+cpustate->regs.w[IX]; cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_003(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[BP]+cpustate->regs.w[IY]; cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_004(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[IX]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_005(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[IY]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_006(v30mz_state *cpustate) { cpustate->eo=FETCH; cpustate->eo+=FETCH<<8; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_007(v30mz_state *cpustate) { cpustate->eo=cpustate->regs.w[BW]; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } - -static unsigned EA_100(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[BW]+cpustate->regs.w[IX]+(INT8)FETCH); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_101(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[BW]+cpustate->regs.w[IY]+(INT8)FETCH); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_102(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[BP]+cpustate->regs.w[IX]+(INT8)FETCH); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_103(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[BP]+cpustate->regs.w[IY]+(INT8)FETCH); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_104(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[IX]+(INT8)FETCH); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_105(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[IY]+(INT8)FETCH); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_106(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[BP]+(INT8)FETCH); cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_107(v30mz_state *cpustate) { cpustate->eo=(cpustate->regs.w[BW]+(INT8)FETCH); cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } - -static unsigned EA_200(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[BW]+cpustate->regs.w[IX]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_201(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[BW]+cpustate->regs.w[IY]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_202(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[BP]+cpustate->regs.w[IX]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_203(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[BP]+cpustate->regs.w[IY]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_204(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[IX]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_205(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[IY]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_206(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[BP]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(SS)+cpustate->eo; return cpustate->ea; } -static unsigned EA_207(v30mz_state *cpustate) { cpustate->e16=FETCH; cpustate->e16+=FETCH<<8; cpustate->eo=cpustate->regs.w[BW]+(INT16)cpustate->e16; cpustate->ea=DefaultBase(DS)+cpustate->eo; return cpustate->ea; } - -static unsigned (*const GetEA[192])(v30mz_state *cpustate)={ - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - EA_000, EA_001, EA_002, EA_003, EA_004, EA_005, EA_006, EA_007, - - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - EA_100, EA_101, EA_102, EA_103, EA_104, EA_105, EA_106, EA_107, - - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207, - EA_200, EA_201, EA_202, EA_203, EA_204, EA_205, EA_206, EA_207 -}; diff --git a/src/emu/cpu/v30mz/necinstr.h b/src/emu/cpu/v30mz/necinstr.h deleted file mode 100644 index 88708ab14b1..00000000000 --- a/src/emu/cpu/v30mz/necinstr.h +++ /dev/null @@ -1,507 +0,0 @@ -static void i_add_br8(v30mz_state *cpustate); -static void i_add_wr16(v30mz_state *cpustate); -static void i_add_r8b(v30mz_state *cpustate); -static void i_add_r16w(v30mz_state *cpustate); -static void i_add_ald8(v30mz_state *cpustate); -static void i_add_axd16(v30mz_state *cpustate); -static void i_push_es(v30mz_state *cpustate); -static void i_pop_es(v30mz_state *cpustate); -static void i_or_br8(v30mz_state *cpustate); -static void i_or_r8b(v30mz_state *cpustate); -static void i_or_wr16(v30mz_state *cpustate); -static void i_or_r16w(v30mz_state *cpustate); -static void i_or_ald8(v30mz_state *cpustate); -static void i_or_axd16(v30mz_state *cpustate); -static void i_push_cs(v30mz_state *cpustate); -static void i_pre_nec(v30mz_state *cpustate); -static void i_adc_br8(v30mz_state *cpustate); -static void i_adc_wr16(v30mz_state *cpustate); -static void i_adc_r8b(v30mz_state *cpustate); -static void i_adc_r16w(v30mz_state *cpustate); -static void i_adc_ald8(v30mz_state *cpustate); -static void i_adc_axd16(v30mz_state *cpustate); -static void i_push_ss(v30mz_state *cpustate); -static void i_pop_ss(v30mz_state *cpustate); -static void i_sbb_br8(v30mz_state *cpustate); -static void i_sbb_wr16(v30mz_state *cpustate); -static void i_sbb_r8b(v30mz_state *cpustate); -static void i_sbb_r16w(v30mz_state *cpustate); -static void i_sbb_ald8(v30mz_state *cpustate); -static void i_sbb_axd16(v30mz_state *cpustate); -static void i_push_ds(v30mz_state *cpustate); -static void i_pop_ds(v30mz_state *cpustate); -static void i_and_br8(v30mz_state *cpustate); -static void i_and_r8b(v30mz_state *cpustate); -static void i_and_wr16(v30mz_state *cpustate); -static void i_and_r16w(v30mz_state *cpustate); -static void i_and_ald8(v30mz_state *cpustate); -static void i_and_axd16(v30mz_state *cpustate); -static void i_es(v30mz_state *cpustate); -static void i_daa(v30mz_state *cpustate); -static void i_sub_br8(v30mz_state *cpustate); -static void i_sub_wr16(v30mz_state *cpustate); -static void i_sub_r8b(v30mz_state *cpustate); -static void i_sub_r16w(v30mz_state *cpustate); -static void i_sub_ald8(v30mz_state *cpustate); -static void i_sub_axd16(v30mz_state *cpustate); -static void i_cs(v30mz_state *cpustate); -static void i_das(v30mz_state *cpustate); -static void i_xor_br8(v30mz_state *cpustate); -static void i_xor_r8b(v30mz_state *cpustate); -static void i_xor_wr16(v30mz_state *cpustate); -static void i_xor_r16w(v30mz_state *cpustate); -static void i_xor_ald8(v30mz_state *cpustate); -static void i_xor_axd16(v30mz_state *cpustate); -static void i_ss(v30mz_state *cpustate); -static void i_aaa(v30mz_state *cpustate); -static void i_cmp_br8(v30mz_state *cpustate); -static void i_cmp_wr16(v30mz_state *cpustate); -static void i_cmp_r8b(v30mz_state *cpustate); -static void i_cmp_r16w(v30mz_state *cpustate); -static void i_cmp_ald8(v30mz_state *cpustate); -static void i_cmp_axd16(v30mz_state *cpustate); -static void i_ds(v30mz_state *cpustate); -static void i_aas(v30mz_state *cpustate); -static void i_inc_ax(v30mz_state *cpustate); -static void i_inc_cx(v30mz_state *cpustate); -static void i_inc_dx(v30mz_state *cpustate); -static void i_inc_bx(v30mz_state *cpustate); -static void i_inc_sp(v30mz_state *cpustate); -static void i_inc_bp(v30mz_state *cpustate); -static void i_inc_si(v30mz_state *cpustate); -static void i_inc_di(v30mz_state *cpustate); -static void i_dec_ax(v30mz_state *cpustate); -static void i_dec_cx(v30mz_state *cpustate); -static void i_dec_dx(v30mz_state *cpustate); -static void i_dec_bx(v30mz_state *cpustate); -static void i_dec_sp(v30mz_state *cpustate); -static void i_dec_bp(v30mz_state *cpustate); -static void i_dec_si(v30mz_state *cpustate); -static void i_dec_di(v30mz_state *cpustate); -static void i_push_ax(v30mz_state *cpustate); -static void i_push_cx(v30mz_state *cpustate); -static void i_push_dx(v30mz_state *cpustate); -static void i_push_bx(v30mz_state *cpustate); -static void i_push_sp(v30mz_state *cpustate); -static void i_push_bp(v30mz_state *cpustate); -static void i_push_si(v30mz_state *cpustate); -static void i_push_di(v30mz_state *cpustate); -static void i_pop_ax(v30mz_state *cpustate); -static void i_pop_cx(v30mz_state *cpustate); -static void i_pop_dx(v30mz_state *cpustate); -static void i_pop_bx(v30mz_state *cpustate); -static void i_pop_sp(v30mz_state *cpustate); -static void i_pop_bp(v30mz_state *cpustate); -static void i_pop_si(v30mz_state *cpustate); -static void i_pop_di(v30mz_state *cpustate); -static void i_pusha(v30mz_state *cpustate); -static void i_popa(v30mz_state *cpustate); -static void i_chkind(v30mz_state *cpustate); -static void i_repnc(v30mz_state *cpustate); -static void i_repc(v30mz_state *cpustate); -static void i_push_d16(v30mz_state *cpustate); -static void i_imul_d16(v30mz_state *cpustate); -static void i_push_d8(v30mz_state *cpustate); -static void i_imul_d8(v30mz_state *cpustate); -static void i_insb(v30mz_state *cpustate); -static void i_insw(v30mz_state *cpustate); -static void i_outsb(v30mz_state *cpustate); -static void i_outsw(v30mz_state *cpustate); -static void i_jo(v30mz_state *cpustate); -static void i_jno(v30mz_state *cpustate); -static void i_jc(v30mz_state *cpustate); -static void i_jnc(v30mz_state *cpustate); -static void i_jz(v30mz_state *cpustate); -static void i_jnz(v30mz_state *cpustate); -static void i_jce(v30mz_state *cpustate); -static void i_jnce(v30mz_state *cpustate); -static void i_js(v30mz_state *cpustate); -static void i_jns(v30mz_state *cpustate); -static void i_jp(v30mz_state *cpustate); -static void i_jnp(v30mz_state *cpustate); -static void i_jl(v30mz_state *cpustate); -static void i_jnl(v30mz_state *cpustate); -static void i_jle(v30mz_state *cpustate); -static void i_jnle(v30mz_state *cpustate); -static void i_80pre(v30mz_state *cpustate); -static void i_82pre(v30mz_state *cpustate); -static void i_81pre(v30mz_state *cpustate); -static void i_83pre(v30mz_state *cpustate); -static void i_test_br8(v30mz_state *cpustate); -static void i_test_wr16(v30mz_state *cpustate); -static void i_xchg_br8(v30mz_state *cpustate); -static void i_xchg_wr16(v30mz_state *cpustate); -static void i_mov_br8(v30mz_state *cpustate); -static void i_mov_r8b(v30mz_state *cpustate); -static void i_mov_wr16(v30mz_state *cpustate); -static void i_mov_r16w(v30mz_state *cpustate); -static void i_mov_wsreg(v30mz_state *cpustate); -static void i_lea(v30mz_state *cpustate); -static void i_mov_sregw(v30mz_state *cpustate); -static void i_invalid(v30mz_state *cpustate); -static void i_popw(v30mz_state *cpustate); -static void i_nop(v30mz_state *cpustate); -static void i_xchg_axcx(v30mz_state *cpustate); -static void i_xchg_axdx(v30mz_state *cpustate); -static void i_xchg_axbx(v30mz_state *cpustate); -static void i_xchg_axsp(v30mz_state *cpustate); -static void i_xchg_axbp(v30mz_state *cpustate); -static void i_xchg_axsi(v30mz_state *cpustate); -static void i_xchg_axdi(v30mz_state *cpustate); -static void i_cbw(v30mz_state *cpustate); -static void i_cwd(v30mz_state *cpustate); -static void i_call_far(v30mz_state *cpustate); -static void i_pushf(v30mz_state *cpustate); -static void i_popf(v30mz_state *cpustate); -static void i_sahf(v30mz_state *cpustate); -static void i_lahf(v30mz_state *cpustate); -static void i_mov_aldisp(v30mz_state *cpustate); -static void i_mov_axdisp(v30mz_state *cpustate); -static void i_mov_dispal(v30mz_state *cpustate); -static void i_mov_dispax(v30mz_state *cpustate); -static void i_movsb(v30mz_state *cpustate); -static void i_movsw(v30mz_state *cpustate); -static void i_cmpsb(v30mz_state *cpustate); -static void i_cmpsw(v30mz_state *cpustate); -static void i_test_ald8(v30mz_state *cpustate); -static void i_test_axd16(v30mz_state *cpustate); -static void i_stosb(v30mz_state *cpustate); -static void i_stosw(v30mz_state *cpustate); -static void i_lodsb(v30mz_state *cpustate); -static void i_lodsw(v30mz_state *cpustate); -static void i_scasb(v30mz_state *cpustate); -static void i_scasw(v30mz_state *cpustate); -static void i_mov_ald8(v30mz_state *cpustate); -static void i_mov_cld8(v30mz_state *cpustate); -static void i_mov_dld8(v30mz_state *cpustate); -static void i_mov_bld8(v30mz_state *cpustate); -static void i_mov_ahd8(v30mz_state *cpustate); -static void i_mov_chd8(v30mz_state *cpustate); -static void i_mov_dhd8(v30mz_state *cpustate); -static void i_mov_bhd8(v30mz_state *cpustate); -static void i_mov_axd16(v30mz_state *cpustate); -static void i_mov_cxd16(v30mz_state *cpustate); -static void i_mov_dxd16(v30mz_state *cpustate); -static void i_mov_bxd16(v30mz_state *cpustate); -static void i_mov_spd16(v30mz_state *cpustate); -static void i_mov_bpd16(v30mz_state *cpustate); -static void i_mov_sid16(v30mz_state *cpustate); -static void i_mov_did16(v30mz_state *cpustate); -static void i_rotshft_bd8(v30mz_state *cpustate); -static void i_rotshft_wd8(v30mz_state *cpustate); -static void i_ret_d16(v30mz_state *cpustate); -static void i_ret(v30mz_state *cpustate); -static void i_les_dw(v30mz_state *cpustate); -static void i_lds_dw(v30mz_state *cpustate); -static void i_mov_bd8(v30mz_state *cpustate); -static void i_mov_wd16(v30mz_state *cpustate); -static void i_enter(v30mz_state *cpustate); -static void i_leave(v30mz_state *cpustate); -static void i_retf_d16(v30mz_state *cpustate); -static void i_retf(v30mz_state *cpustate); -static void i_int3(v30mz_state *cpustate); -static void i_int(v30mz_state *cpustate); -static void i_into(v30mz_state *cpustate); -static void i_iret(v30mz_state *cpustate); -static void i_rotshft_b(v30mz_state *cpustate); -static void i_rotshft_w(v30mz_state *cpustate); -static void i_rotshft_bcl(v30mz_state *cpustate); -static void i_rotshft_wcl(v30mz_state *cpustate); -static void i_aam(v30mz_state *cpustate); -static void i_aad(v30mz_state *cpustate); -static void i_setalc(v30mz_state *cpustate); -static void i_trans(v30mz_state *cpustate); -static void i_fpo(v30mz_state *cpustate); -static void i_loopne(v30mz_state *cpustate); -static void i_loope(v30mz_state *cpustate); -static void i_loop(v30mz_state *cpustate); -static void i_jcxz(v30mz_state *cpustate); -static void i_inal(v30mz_state *cpustate); -static void i_inax(v30mz_state *cpustate); -static void i_outal(v30mz_state *cpustate); -static void i_outax(v30mz_state *cpustate); -static void i_call_d16(v30mz_state *cpustate); -static void i_jmp_d16(v30mz_state *cpustate); -static void i_jmp_far(v30mz_state *cpustate); -static void i_jmp_d8(v30mz_state *cpustate); -static void i_inaldx(v30mz_state *cpustate); -static void i_inaxdx(v30mz_state *cpustate); -static void i_outdxal(v30mz_state *cpustate); -static void i_outdxax(v30mz_state *cpustate); -static void i_lock(v30mz_state *cpustate); -static void i_repne(v30mz_state *cpustate); -static void i_repe(v30mz_state *cpustate); -static void i_hlt(v30mz_state *cpustate); -static void i_cmc(v30mz_state *cpustate); -static void i_f6pre(v30mz_state *cpustate); -static void i_f7pre(v30mz_state *cpustate); -static void i_clc(v30mz_state *cpustate); -static void i_stc(v30mz_state *cpustate); -static void i_di(v30mz_state *cpustate); -static void i_ei(v30mz_state *cpustate); -static void i_cld(v30mz_state *cpustate); -static void i_std(v30mz_state *cpustate); -static void i_fepre(v30mz_state *cpustate); -static void i_ffpre(v30mz_state *cpustate); - -static void i_wait(v30mz_state *cpustate); - -static void (*const nec_instruction[256])(v30mz_state *cpustate) = -{ - i_add_br8, /* 0x00 */ - i_add_wr16, /* 0x01 */ - i_add_r8b, /* 0x02 */ - i_add_r16w, /* 0x03 */ - i_add_ald8, /* 0x04 */ - i_add_axd16, /* 0x05 */ - i_push_es, /* 0x06 */ - i_pop_es, /* 0x07 */ - i_or_br8, /* 0x08 */ - i_or_wr16, /* 0x09 */ - i_or_r8b, /* 0x0a */ - i_or_r16w, /* 0x0b */ - i_or_ald8, /* 0x0c */ - i_or_axd16, /* 0x0d */ - i_push_cs, /* 0x0e */ - i_pre_nec /* 0x0f */, - i_adc_br8, /* 0x10 */ - i_adc_wr16, /* 0x11 */ - i_adc_r8b, /* 0x12 */ - i_adc_r16w, /* 0x13 */ - i_adc_ald8, /* 0x14 */ - i_adc_axd16, /* 0x15 */ - i_push_ss, /* 0x16 */ - i_pop_ss, /* 0x17 */ - i_sbb_br8, /* 0x18 */ - i_sbb_wr16, /* 0x19 */ - i_sbb_r8b, /* 0x1a */ - i_sbb_r16w, /* 0x1b */ - i_sbb_ald8, /* 0x1c */ - i_sbb_axd16, /* 0x1d */ - i_push_ds, /* 0x1e */ - i_pop_ds, /* 0x1f */ - i_and_br8, /* 0x20 */ - i_and_wr16, /* 0x21 */ - i_and_r8b, /* 0x22 */ - i_and_r16w, /* 0x23 */ - i_and_ald8, /* 0x24 */ - i_and_axd16, /* 0x25 */ - i_es, /* 0x26 */ - i_daa, /* 0x27 */ - i_sub_br8, /* 0x28 */ - i_sub_wr16, /* 0x29 */ - i_sub_r8b, /* 0x2a */ - i_sub_r16w, /* 0x2b */ - i_sub_ald8, /* 0x2c */ - i_sub_axd16, /* 0x2d */ - i_cs, /* 0x2e */ - i_das, /* 0x2f */ - i_xor_br8, /* 0x30 */ - i_xor_wr16, /* 0x31 */ - i_xor_r8b, /* 0x32 */ - i_xor_r16w, /* 0x33 */ - i_xor_ald8, /* 0x34 */ - i_xor_axd16, /* 0x35 */ - i_ss, /* 0x36 */ - i_aaa, /* 0x37 */ - i_cmp_br8, /* 0x38 */ - i_cmp_wr16, /* 0x39 */ - i_cmp_r8b, /* 0x3a */ - i_cmp_r16w, /* 0x3b */ - i_cmp_ald8, /* 0x3c */ - i_cmp_axd16, /* 0x3d */ - i_ds, /* 0x3e */ - i_aas, /* 0x3f */ - i_inc_ax, /* 0x40 */ - i_inc_cx, /* 0x41 */ - i_inc_dx, /* 0x42 */ - i_inc_bx, /* 0x43 */ - i_inc_sp, /* 0x44 */ - i_inc_bp, /* 0x45 */ - i_inc_si, /* 0x46 */ - i_inc_di, /* 0x47 */ - i_dec_ax, /* 0x48 */ - i_dec_cx, /* 0x49 */ - i_dec_dx, /* 0x4a */ - i_dec_bx, /* 0x4b */ - i_dec_sp, /* 0x4c */ - i_dec_bp, /* 0x4d */ - i_dec_si, /* 0x4e */ - i_dec_di, /* 0x4f */ - i_push_ax, /* 0x50 */ - i_push_cx, /* 0x51 */ - i_push_dx, /* 0x52 */ - i_push_bx, /* 0x53 */ - i_push_sp, /* 0x54 */ - i_push_bp, /* 0x55 */ - i_push_si, /* 0x56 */ - i_push_di, /* 0x57 */ - i_pop_ax, /* 0x58 */ - i_pop_cx, /* 0x59 */ - i_pop_dx, /* 0x5a */ - i_pop_bx, /* 0x5b */ - i_pop_sp, /* 0x5c */ - i_pop_bp, /* 0x5d */ - i_pop_si, /* 0x5e */ - i_pop_di, /* 0x5f */ - i_pusha, /* 0x60 */ - i_popa, /* 0x61 */ - i_chkind, /* 0x62 */ - i_invalid, /* 0x63 */ - i_repnc, /* 0x64 */ - i_repc, /* 0x65 */ - i_invalid, /* 0x66 */ - i_invalid, /* 0x67 */ - i_push_d16, /* 0x68 */ - i_imul_d16, /* 0x69 */ - i_push_d8, /* 0x6a */ - i_imul_d8, /* 0x6b */ - i_insb, /* 0x6c */ - i_insw, /* 0x6d */ - i_outsb, /* 0x6e */ - i_outsw, /* 0x6f */ - i_jo, /* 0x70 */ - i_jno, /* 0x71 */ - i_jc, /* 0x72 */ - i_jnc, /* 0x73 */ - i_jz, /* 0x74 */ - i_jnz, /* 0x75 */ - i_jce, /* 0x76 */ - i_jnce, /* 0x77 */ - i_js, /* 0x78 */ - i_jns, /* 0x79 */ - i_jp, /* 0x7a */ - i_jnp, /* 0x7b */ - i_jl, /* 0x7c */ - i_jnl, /* 0x7d */ - i_jle, /* 0x7e */ - i_jnle, /* 0x7f */ - i_80pre, /* 0x80 */ - i_81pre, /* 0x81 */ - i_82pre, /* 0x82 */ - i_83pre, /* 0x83 */ - i_test_br8, /* 0x84 */ - i_test_wr16, /* 0x85 */ - i_xchg_br8, /* 0x86 */ - i_xchg_wr16, /* 0x87 */ - i_mov_br8, /* 0x88 */ - i_mov_wr16, /* 0x89 */ - i_mov_r8b, /* 0x8a */ - i_mov_r16w, /* 0x8b */ - i_mov_wsreg, /* 0x8c */ - i_lea, /* 0x8d */ - i_mov_sregw, /* 0x8e */ - i_popw, /* 0x8f */ - i_nop, /* 0x90 */ - i_xchg_axcx, /* 0x91 */ - i_xchg_axdx, /* 0x92 */ - i_xchg_axbx, /* 0x93 */ - i_xchg_axsp, /* 0x94 */ - i_xchg_axbp, /* 0x95 */ - i_xchg_axsi, /* 0x97 */ - i_xchg_axdi, /* 0x97 */ - i_cbw, /* 0x98 */ - i_cwd, /* 0x99 */ - i_call_far, /* 0x9a */ - i_wait, /* 0x9b */ - i_pushf, /* 0x9c */ - i_popf, /* 0x9d */ - i_sahf, /* 0x9e */ - i_lahf, /* 0x9f */ - i_mov_aldisp, /* 0xa0 */ - i_mov_axdisp, /* 0xa1 */ - i_mov_dispal, /* 0xa2 */ - i_mov_dispax, /* 0xa3 */ - i_movsb, /* 0xa4 */ - i_movsw, /* 0xa5 */ - i_cmpsb, /* 0xa6 */ - i_cmpsw, /* 0xa7 */ - i_test_ald8, /* 0xa8 */ - i_test_axd16, /* 0xa9 */ - i_stosb, /* 0xaa */ - i_stosw, /* 0xab */ - i_lodsb, /* 0xac */ - i_lodsw, /* 0xad */ - i_scasb, /* 0xae */ - i_scasw, /* 0xaf */ - i_mov_ald8, /* 0xb0 */ - i_mov_cld8, /* 0xb1 */ - i_mov_dld8, /* 0xb2 */ - i_mov_bld8, /* 0xb3 */ - i_mov_ahd8, /* 0xb4 */ - i_mov_chd8, /* 0xb5 */ - i_mov_dhd8, /* 0xb6 */ - i_mov_bhd8, /* 0xb7 */ - i_mov_axd16, /* 0xb8 */ - i_mov_cxd16, /* 0xb9 */ - i_mov_dxd16, /* 0xba */ - i_mov_bxd16, /* 0xbb */ - i_mov_spd16, /* 0xbc */ - i_mov_bpd16, /* 0xbd */ - i_mov_sid16, /* 0xbe */ - i_mov_did16, /* 0xbf */ - i_rotshft_bd8, /* 0xc0 */ - i_rotshft_wd8, /* 0xc1 */ - i_ret_d16, /* 0xc2 */ - i_ret, /* 0xc3 */ - i_les_dw, /* 0xc4 */ - i_lds_dw, /* 0xc5 */ - i_mov_bd8, /* 0xc6 */ - i_mov_wd16, /* 0xc7 */ - i_enter, /* 0xc8 */ - i_leave, /* 0xc9 */ - i_retf_d16, /* 0xca */ - i_retf, /* 0xcb */ - i_int3, /* 0xcc */ - i_int, /* 0xcd */ - i_into, /* 0xce */ - i_iret, /* 0xcf */ - i_rotshft_b, /* 0xd0 */ - i_rotshft_w, /* 0xd1 */ - i_rotshft_bcl, /* 0xd2 */ - i_rotshft_wcl, /* 0xd3 */ - i_aam, /* 0xd4 */ - i_aad, /* 0xd5 */ - i_setalc, - i_trans, /* 0xd7 */ - i_fpo, /* 0xd8 */ - i_fpo, /* 0xd9 */ - i_fpo, /* 0xda */ - i_fpo, /* 0xdb */ - i_fpo, /* 0xdc */ - i_fpo, /* 0xdd */ - i_fpo, /* 0xde */ - i_fpo, /* 0xdf */ - i_loopne, /* 0xe0 */ - i_loope, /* 0xe1 */ - i_loop, /* 0xe2 */ - i_jcxz, /* 0xe3 */ - i_inal, /* 0xe4 */ - i_inax, /* 0xe5 */ - i_outal, /* 0xe6 */ - i_outax, /* 0xe7 */ - i_call_d16, /* 0xe8 */ - i_jmp_d16, /* 0xe9 */ - i_jmp_far, /* 0xea */ - i_jmp_d8, /* 0xeb */ - i_inaldx, /* 0xec */ - i_inaxdx, /* 0xed */ - i_outdxal, /* 0xee */ - i_outdxax, /* 0xef */ - i_lock, /* 0xf0 */ - i_invalid, /* 0xf1 */ - i_repne, /* 0xf2 */ - i_repe, /* 0xf3 */ - i_hlt, /* 0xf4 */ - i_cmc, /* 0xf5 */ - i_f6pre, /* 0xf6 */ - i_f7pre, /* 0xf7 */ - i_clc, /* 0xf8 */ - i_stc, /* 0xf9 */ - i_di, /* 0xfa */ - i_ei, /* 0xfb */ - i_cld, /* 0xfc */ - i_std, /* 0xfd */ - i_fepre, /* 0xfe */ - i_ffpre /* 0xff */ -}; diff --git a/src/emu/cpu/v30mz/necmodrm.h b/src/emu/cpu/v30mz/necmodrm.h deleted file mode 100644 index b7cedd6af13..00000000000 --- a/src/emu/cpu/v30mz/necmodrm.h +++ /dev/null @@ -1,104 +0,0 @@ -static struct { - struct { - WREGS w[256]; - BREGS b[256]; - } reg; - struct { - WREGS w[256]; - BREGS b[256]; - } RM; -} Mod_RM; - -#define RegWord(ModRM) cpustate->regs.w[Mod_RM.reg.w[ModRM]] -#define RegByte(ModRM) cpustate->regs.b[Mod_RM.reg.b[ModRM]] - -#define GetRMWord(ModRM) \ - ((ModRM) >= 0xc0 ? cpustate->regs.w[Mod_RM.RM.w[ModRM]] : ( (*GetEA[ModRM])(cpustate), ReadWord( cpustate->ea ) )) - -#define PutbackRMWord(ModRM,val) \ -{ \ - if (ModRM >= 0xc0) cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \ - else WriteWord(cpustate->ea,val); \ -} - -#define GetnextRMWord ReadWord((cpustate->ea&0xf0000)|((cpustate->ea+2)&0xffff)) - -#define PutRMWord(ModRM,val) \ -{ \ - if (ModRM >= 0xc0) \ - cpustate->regs.w[Mod_RM.RM.w[ModRM]]=val; \ - else { \ - (*GetEA[ModRM])(cpustate); \ - WriteWord( cpustate->ea ,val); \ - } \ -} - -#define PutImmRMWord(ModRM) \ -{ \ - UINT16 val; \ - if (ModRM >= 0xc0) \ - FETCHWORD(cpustate->regs.w[Mod_RM.RM.w[ModRM]]) \ - else { \ - (*GetEA[ModRM])(cpustate); \ - FETCHWORD(val) \ - WriteWord( cpustate->ea , val); \ - } \ -} - -#define GetRMByte(ModRM) \ - ((ModRM) >= 0xc0 ? cpustate->regs.b[Mod_RM.RM.b[ModRM]] : ReadByte( (*GetEA[ModRM])(cpustate) )) - -#define PutRMByte(ModRM,val) \ -{ \ - if (ModRM >= 0xc0) \ - cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \ - else \ - WriteByte( (*GetEA[ModRM])(cpustate) ,val); \ -} - -#define PutImmRMByte(ModRM) \ -{ \ - if (ModRM >= 0xc0) \ - cpustate->regs.b[Mod_RM.RM.b[ModRM]]=FETCH; \ - else { \ - (*GetEA[ModRM])(cpustate); \ - WriteByte( cpustate->ea , FETCH ); \ - } \ -} - -#define PutbackRMByte(ModRM,val) \ -{ \ - if (ModRM >= 0xc0) \ - cpustate->regs.b[Mod_RM.RM.b[ModRM]]=val; \ - else \ - WriteByte(cpustate->ea,val); \ -} - -#define DEF_br8 \ - UINT32 ModRM = FETCH,src,dst; \ - src = RegByte(ModRM); \ - dst = GetRMByte(ModRM) - -#define DEF_wr16 \ - UINT32 ModRM = FETCH,src,dst; \ - src = RegWord(ModRM); \ - dst = GetRMWord(ModRM) - -#define DEF_r8b \ - UINT32 ModRM = FETCH,src,dst; \ - dst = RegByte(ModRM); \ - src = GetRMByte(ModRM) - -#define DEF_r16w \ - UINT32 ModRM = FETCH,src,dst; \ - dst = RegWord(ModRM); \ - src = GetRMWord(ModRM) - -#define DEF_ald8 \ - UINT32 src = FETCH; \ - UINT32 dst = cpustate->regs.b[AL] - -#define DEF_axd16 \ - UINT32 src = FETCH; \ - UINT32 dst = cpustate->regs.w[AW]; \ - src += (FETCH << 8) diff --git a/src/emu/cpu/v30mz/v30mz.c b/src/emu/cpu/v30mz/v30mz.c index 9230f9c8e6c..2ef4b849b20 100644 --- a/src/emu/cpu/v30mz/v30mz.c +++ b/src/emu/cpu/v30mz/v30mz.c @@ -42,60 +42,42 @@ #include "emu.h" #include "debugger.h" - -#define PC(n) (((n)->sregs[CS]<<4)+(n)->ip) - - #include "v30mz.h" -#include "nec.h" -/* NEC registers */ -typedef union -{ /* eight general registers */ - UINT16 w[8]; /* viewed as 16 bits registers */ - UINT8 b[16]; /* or as 8 bit registers */ -} necbasicregs; -typedef struct _v30mz_state v30mz_state; -struct _v30mz_state -{ - necbasicregs regs; - UINT16 sregs[4]; +typedef enum { ES=0, CS, SS, DS } SREGS; +typedef enum { AW=0, CW, DW, BW, SP, BP, IX, IY } WREGS; - UINT16 ip; +#define NEC_NMI_INT_VECTOR 2 - INT32 SignVal; - UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */ - UINT8 TF, IF, DF, MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */ - UINT32 int_vector; - UINT32 pending_irq; - UINT32 nmi_state; - UINT32 irq_state; - UINT8 no_interrupt; +typedef enum { + AL = NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1), + AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0), + CL = NATIVE_ENDIAN_VALUE_LE_BE(0x2, 0x3), + CH = NATIVE_ENDIAN_VALUE_LE_BE(0x3, 0x2), + DL = NATIVE_ENDIAN_VALUE_LE_BE(0x4, 0x5), + DH = NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4), + BL = NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7), + BH = NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6), + SPL = NATIVE_ENDIAN_VALUE_LE_BE(0x8, 0x9), + SPH = NATIVE_ENDIAN_VALUE_LE_BE(0x9, 0x8), + BPL = NATIVE_ENDIAN_VALUE_LE_BE(0xa, 0xb), + BPH = NATIVE_ENDIAN_VALUE_LE_BE(0xb, 0xa), + IXL = NATIVE_ENDIAN_VALUE_LE_BE(0xc, 0xd), + IXH = NATIVE_ENDIAN_VALUE_LE_BE(0xd, 0xc), + IYL = NATIVE_ENDIAN_VALUE_LE_BE(0xe, 0xf), + IYH = NATIVE_ENDIAN_VALUE_LE_BE(0xf, 0xe) +} BREGS; - device_irq_acknowledge_callback irq_callback; - legacy_cpu_device *device; - address_space *program; - direct_read_data *direct; - address_space *io; - int icount; - UINT32 prefix_base; /* base address of the latest prefix segment */ - char seg_prefix; /* prefix segment indicator */ +#define CF (m_CarryVal!=0) +#define SF (m_SignVal<0) +#define ZF (m_ZeroVal==0) +#define PF m_parity_table[(UINT8)m_ParityVal] +#define AF (m_AuxVal!=0) +#define OF (m_OverVal!=0) +#define MD (m_MF!=0) - UINT32 ea; - UINT16 eo; - UINT16 e16; -}; - -extern int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, const nec_config *config); - -INLINE v30mz_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == V30MZ); - return (v30mz_state *)downcast(device)->token(); -} /***************************************************************************/ /* cpu state */ @@ -108,1046 +90,3636 @@ INLINE v30mz_state *get_safe_token(device_t *device) #define INT_IRQ 0x01 #define NMI_IRQ 0x02 -#include "necinstr.h" -#include "necea.h" -#include "necmodrm.h" - -static UINT8 parity_table[256]; - /***************************************************************************/ -static CPU_RESET( nec ) +const device_type V30MZ = &device_creator; + + +v30mz_cpu_device::v30mz_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : cpu_device(mconfig, V30MZ, "V30MZ", tag, owner, clock) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0) + , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0) { - v30mz_state *cpustate = get_safe_token(device); - unsigned int i,j,c; - static const BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH }; - device_irq_acknowledge_callback save_irqcallback; + static const BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH }; - save_irqcallback = cpustate->irq_callback; - memset( cpustate, 0, sizeof(*cpustate) ); - cpustate->irq_callback = save_irqcallback; - cpustate->device = device; - cpustate->program = device->space(AS_PROGRAM); - cpustate->direct = &cpustate->program->direct(); - cpustate->io = device->space(AS_IO); - - cpustate->sregs[CS] = 0xffff; - - for (i = 0;i < 256; i++) - { - for (j = i, c = 0; j > 0; j >>= 1) + /* Set up parity lookup table. */ + for (UINT16 i = 0;i < 256; i++) + { + UINT16 c = 0; + for (UINT16 j = i; j > 0; j >>= 1) + { if (j & 1) c++; - parity_table[i] = !(c & 1); - } + } + m_parity_table[i] = !(c & 1); + } - cpustate->ZeroVal = cpustate->ParityVal = 1; - SetMD(1); /* set the mode-flag = native mode */ + for (UINT16 i = 0; i < 256; i++) + { + m_Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3]; + m_Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ; + } - for (i = 0; i < 256; i++) - { - Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3]; - Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ; - } - - for (i = 0xc0; i < 0x100; i++) - { - Mod_RM.RM.w[i] = (WREGS)( i & 7 ); - Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7]; - } + for (UINT16 i = 0xc0; i < 0x100; i++) + { + m_Mod_RM.RM.w[i] = (WREGS)( i & 7 ); + m_Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7]; + } } -static CPU_EXIT( nec ) -{ +void v30mz_cpu_device::device_start() +{ + m_irq_callback = static_standard_irq_callback; + m_program = space(AS_PROGRAM); + m_direct = &m_program->direct(); + m_io = space(AS_IO); + + save_item(NAME(m_regs.w)); + save_item(NAME(m_sregs)); + save_item(NAME(m_ip)); + save_item(NAME(m_TF)); + save_item(NAME(m_IF)); + save_item(NAME(m_DF)); + save_item(NAME(m_MF)); + save_item(NAME(m_SignVal)); + save_item(NAME(m_int_vector)); + save_item(NAME(m_pending_irq)); + save_item(NAME(m_nmi_state)); + save_item(NAME(m_irq_state)); + save_item(NAME(m_AuxVal)); + save_item(NAME(m_OverVal)); + save_item(NAME(m_ZeroVal)); + save_item(NAME(m_CarryVal)); + save_item(NAME(m_ParityVal)); + save_item(NAME(m_seg_prefix)); + save_item(NAME(m_seg_prefix_next)); + + // Register state for debugger +// state_add( NEC_PC, "PC", m_PC ).callimport().callexport().formatstr("%04X"); + state_add( NEC_IP, "IP", m_ip ).callimport().callexport().formatstr("%04X"); + state_add( NEC_SP, "SP", m_regs.w[SP] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_AW, "AW", m_regs.w[AW] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_CW, "CW", m_regs.w[CS] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_DW, "DW", m_regs.w[DW] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_BW, "BW", m_regs.w[BW] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_BP, "BP", m_regs.w[BP] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_IX, "IX", m_regs.w[IX] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_IY, "IY", m_regs.w[IY] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_ES, "ES", m_sregs[ES] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_CS, "CS", m_sregs[CS] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_SS, "SS", m_sregs[SS] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_DS, "DS", m_sregs[DS] ).callimport().callexport().formatstr("%04X"); + state_add( NEC_VECTOR, "V", m_int_vector).callimport().callexport().formatstr("%02X"); + + state_add(STATE_GENPC, "curpc", m_pc).callimport().callexport().formatstr("%05X"); + state_add(STATE_GENFLAGS, "GENFLAGS", m_TF).callimport().callexport().formatstr("%16s").noshow(); + + m_icountptr = &m_icount; } -static void nec_interrupt(v30mz_state *cpustate,unsigned int_num) -{ - UINT32 dest_seg, dest_off; - i_pushf(cpustate); - cpustate->TF = cpustate->IF = 0; +void v30mz_cpu_device::state_string_export(const device_state_entry &entry, astring &string) +{ + switch (entry.index()) + { + case STATE_GENPC: + string.printf("%08X", pc() ); + break; + + case STATE_GENFLAGS: + { + UINT16 flags = CompressFlags(); + string.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + flags & 0x8000 ? 'M':'.', + flags & 0x4000 ? '?':'.', + flags & 0x2000 ? '?':'.', + flags & 0x1000 ? '?':'.', + flags & 0x0800 ? 'O':'.', + flags & 0x0400 ? 'D':'.', + flags & 0x0200 ? 'I':'.', + flags & 0x0100 ? 'T':'.', + flags & 0x0080 ? 'S':'.', + flags & 0x0040 ? 'Z':'.', + flags & 0x0020 ? '?':'.', + flags & 0x0010 ? 'A':'.', + flags & 0x0008 ? '?':'.', + flags & 0x0004 ? 'P':'.', + flags & 0x0002 ? 'N':'.', + flags & 0x0001 ? 'C':'.'); + } + break; + } +} + + +void v30mz_cpu_device::device_reset() +{ + m_ZeroVal = 1; + m_ParityVal = 1; + m_regs.w[AW] = 0; + m_regs.w[CW] = 0; + m_regs.w[DW] = 0; + m_regs.w[BW] = 0; + m_regs.w[SP] = 0; + m_regs.w[BP] = 0; + m_regs.w[IX] = 0; + m_regs.w[IY] = 0; + m_sregs[ES] = 0; + m_sregs[CS] = 0xffff; + m_sregs[SS] = 0; + m_sregs[DS] = 0; + m_ip = 0; + m_SignVal = 0; + m_AuxVal = 0; + m_OverVal = 0; + m_CarryVal = 0; + m_TF = 0; + m_IF = 0; + m_DF = 0; + m_MF = 1; + m_int_vector = 0; + m_pending_irq = 0; + m_nmi_state = 0; + m_irq_state = 0; + m_no_interrupt = 0; + m_fire_trap = 0; + m_prefix_base = 0; + m_seg_prefix = false; + m_seg_prefix_next = false; + m_ea = 0; + m_eo = 0; + m_e16 = 0; + m_modrm = 0; + m_dst = 0; + m_src = 0; +} + + +inline UINT32 v30mz_cpu_device::pc() +{ + m_pc = ( m_sregs[CS] << 4 ) + m_ip; + return m_pc; +} + + +inline UINT8 v30mz_cpu_device::read_byte(UINT32 addr) +{ + return m_program->read_byte(addr); +} + + +inline UINT16 v30mz_cpu_device::read_word(UINT32 addr) +{ + return m_program->read_byte(addr) | ( m_program->read_byte(addr+1) << 8 ); +} + + +inline void v30mz_cpu_device::write_byte(UINT32 addr, UINT8 data) +{ + m_program->write_byte(addr, data); +} + + +inline void v30mz_cpu_device::write_word(UINT32 addr, UINT16 data) +{ + m_program->write_byte( addr, data & 0xff ); + m_program->write_byte( addr + 1, data >> 8 ); +} + + +inline UINT8 v30mz_cpu_device::read_port(UINT16 port) +{ + return m_io->read_byte(port); +} + + +inline void v30mz_cpu_device::write_port(UINT16 port, UINT8 data) +{ + m_io->write_byte(port, data); +} + + +inline UINT8 v30mz_cpu_device::fetch_op() +{ + UINT8 data = m_direct->read_decrypted_byte( pc() ); + m_ip++; + return data; +} + + +inline UINT8 v30mz_cpu_device::fetch() +{ + UINT8 data = m_direct->read_raw_byte( pc() ); + m_ip++; + return data; +} + + +inline UINT16 v30mz_cpu_device::fetch_word() +{ + UINT16 data = fetch(); + data |= ( fetch() << 8 ); + return data; +} + + +inline UINT8 v30mz_cpu_device::repx_op() +{ + UINT8 next = fetch_op(); + bool seg_prefix = false; + int seg = 0; + + switch (next) + { + case 0x26: + seg_prefix = true; + seg = ES; + break; + case 0x2e: + seg_prefix = true; + seg = CS; + break; + case 0x36: + seg_prefix = true; + seg = SS; + break; + case 0x3e: + seg_prefix = true; + seg = DS; + break; + } + + if ( seg_prefix ) + { + m_seg_prefix = true; + m_seg_prefix_next = true; + m_prefix_base = m_sregs[seg] << 4; + next = fetch_op(); + CLK(2); + } + + return next; +} + + +inline void v30mz_cpu_device::CLK(UINT32 cycles) +{ + m_icount -= cycles; +} + + +inline void v30mz_cpu_device::CLKM(UINT32 cycles_reg, UINT32 cycles_mem) +{ + m_icount -= ( m_modrm >= 0xc0 ) ? cycles_reg : cycles_mem; +} + + +inline UINT32 v30mz_cpu_device::default_base(int seg) +{ + if ( m_seg_prefix && (seg==DS || seg==SS) ) + { + return m_prefix_base; + } + else + { + return m_sregs[seg] << 4; + } +} + + +inline UINT32 v30mz_cpu_device::get_ea() +{ + switch( m_modrm & 0xc7 ) + { + case 0x00: + m_eo = m_regs.w[BW] + m_regs.w[IX]; + m_ea = default_base(DS) + m_eo; + break; + case 0x01: + m_eo = m_regs.w[BW] + m_regs.w[IY]; + m_ea = default_base(DS) + m_eo; + break; + case 0x02: + m_eo = m_regs.w[BP] + m_regs.w[IX]; + m_ea = default_base(SS) + m_eo; + break; + case 0x03: + m_eo = m_regs.w[BP] + m_regs.w[IY]; + m_ea = default_base(SS) + m_eo; + break; + case 0x04: + m_eo = m_regs.w[IX]; + m_ea = default_base(DS) + m_eo; + break; + case 0x05: + m_eo = m_regs.w[IY]; + m_ea = default_base(DS) + m_eo; + break; + case 0x06: + m_eo = fetch_word(); + m_ea = default_base(DS) + m_eo; + break; + case 0x07: + m_eo = m_regs.w[BW]; + m_ea = default_base(DS) + m_eo; + break; + + case 0x40: + m_eo = m_regs.w[BW] + m_regs.w[IX] + (INT8)fetch(); + m_ea = default_base(DS) + m_eo; + break; + case 0x41: + m_eo = m_regs.w[BW] + m_regs.w[IY] + (INT8)fetch(); + m_ea = default_base(DS) + m_eo; + break; + case 0x42: + m_eo = m_regs.w[BP] + m_regs.w[IX] + (INT8)fetch(); + m_ea = default_base(SS) + m_eo; + break; + case 0x43: + m_eo = m_regs.w[BP] + m_regs.w[IY] + (INT8)fetch(); + m_ea = default_base(SS) + m_eo; + break; + case 0x44: + m_eo = m_regs.w[IX] + (INT8)fetch(); + m_ea = default_base(DS) + m_eo; + break; + case 0x45: + m_eo = m_regs.w[IY] + (INT8)fetch(); + m_ea = default_base(DS) + m_eo; + break; + case 0x46: + m_eo = m_regs.w[BP] + (INT8)fetch(); + m_ea = default_base(SS) + m_eo; + break; + case 0x47: + m_eo = m_regs.w[BW] + (INT8)fetch(); + m_ea = default_base(DS) + m_eo; + break; + + case 0x80: + m_e16 = fetch_word(); + m_eo = m_regs.w[BW] + m_regs.w[IX] + (INT16)m_e16; + m_ea = default_base(DS) + m_eo; + break; + case 0x81: + m_e16 = fetch_word(); + m_eo = m_regs.w[BW] + m_regs.w[IY] + (INT16)m_e16; + m_ea = default_base(DS) + m_eo; + break; + case 0x82: + m_e16 = fetch_word(); + m_eo = m_regs.w[BP] + m_regs.w[IX] + (INT16)m_e16; + m_ea = default_base(SS) + m_eo; + break; + case 0x83: + m_e16 = fetch_word(); + m_eo = m_regs.w[BP] + m_regs.w[IY] + (INT16)m_e16; + m_ea = default_base(SS) + m_eo; + break; + case 0x84: + m_e16 = fetch_word(); + m_eo = m_regs.w[IX] + (INT16)m_e16; + m_ea = default_base(DS) + m_eo; + break; + case 0x85: + m_e16 = fetch_word(); + m_eo = m_regs.w[IY] + (INT16)m_e16; + m_ea = default_base(DS) + m_eo; + break; + case 0x86: + m_e16 = fetch_word(); + m_eo = m_regs.w[BP] + (INT16)m_e16; + m_ea = default_base(SS) + m_eo; + break; + case 0x87: + m_e16 = fetch_word(); + m_eo = m_regs.w[BW] + (INT16)m_e16; + m_ea = default_base(DS) + m_eo; + break; + } + + return m_ea; +} + + +inline void v30mz_cpu_device::PutbackRMByte(UINT8 data) +{ + if ( m_modrm >= 0xc0 ) + { + m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = data; + } + else + { + write_byte( m_ea, data ); + } +} + + +inline void v30mz_cpu_device::PutbackRMWord(UINT16 data) +{ + if ( m_modrm >= 0xc0 ) + { + m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = data; + } + else + { + write_word( m_ea, data ); + } +} + +inline void v30mz_cpu_device::PutImmRMWord() +{ + if ( m_modrm >= 0xc0 ) + { + m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = fetch_word(); + } + else + { + write_word( get_ea(), fetch_word() ); + } +} + +inline void v30mz_cpu_device::PutRMWord(UINT16 val) +{ + if ( m_modrm >= 0xc0 ) + { + m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = val; + } + else + { + write_word( get_ea(), val ); + } +} + + +inline void v30mz_cpu_device::PutRMByte(UINT8 val) +{ + if ( m_modrm >= 0xc0 ) + { + m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = val; + } + else + { + write_byte( get_ea(), val ); + } +} + + +inline void v30mz_cpu_device::PutImmRMByte() +{ + if ( m_modrm >= 0xc0 ) + { + m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = fetch(); + } + else + { + write_byte( get_ea(), fetch() ); + } +} + + +inline void v30mz_cpu_device::DEF_br8() +{ + m_modrm = fetch(); + m_src = RegByte(); + m_dst = GetRMByte(); +} + + +inline void v30mz_cpu_device::DEF_wr16() +{ + m_modrm = fetch(); + m_src = RegWord(); + m_dst = GetRMWord(); +} + + +inline void v30mz_cpu_device::DEF_r8b() +{ + m_modrm = fetch(); + m_dst = RegByte(); + m_src = GetRMByte(); +} + + +inline void v30mz_cpu_device::DEF_r16w() +{ + m_modrm = fetch(); + m_dst = RegWord(); + m_src = GetRMWord(); +} + + +inline void v30mz_cpu_device::DEF_ald8() +{ + m_src = fetch(); + m_dst = m_regs.b[AL]; +} + + +inline void v30mz_cpu_device::DEF_axd16() +{ + m_src = fetch_word(); + m_dst = m_regs.w[AW]; +} + + + +inline void v30mz_cpu_device::RegByte(UINT8 data) +{ + m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ] = data; +} + + +inline void v30mz_cpu_device::RegWord(UINT16 data) +{ + m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ] = data; +} + + +inline UINT8 v30mz_cpu_device::RegByte() +{ + return m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ]; +} + + +inline UINT16 v30mz_cpu_device::RegWord() +{ + return m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ]; +} + + +inline UINT16 v30mz_cpu_device::GetRMWord() +{ + if ( m_modrm >= 0xc0 ) + { + return m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ]; + } + else + { + return read_word( get_ea() ); + } +} + + +inline UINT16 v30mz_cpu_device::GetnextRMWord() +{ + UINT32 addr = ( m_ea & 0xf0000 ) | ( ( m_ea + 2 ) & 0xffff ); + + return read_word( addr ); +} + + +inline UINT8 v30mz_cpu_device::GetRMByte() +{ + if ( m_modrm >= 0xc0 ) + { + return m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ]; + } + else + { + return read_byte( get_ea() ); + } +} + + +inline void v30mz_cpu_device::PutMemB(int seg, UINT16 offset, UINT8 data) +{ + write_byte( default_base( seg ) + offset, data); +} + + +inline void v30mz_cpu_device::PutMemW(int seg, UINT16 offset, UINT16 data) +{ + PutMemB( seg, offset, data & 0xff); + PutMemB( seg, offset+1, data >> 8); +} + + +inline UINT8 v30mz_cpu_device::GetMemB(int seg, UINT16 offset) +{ + return read_byte( default_base(seg) + offset ); +} + + +inline UINT16 v30mz_cpu_device::GetMemW(int seg, UINT16 offset) +{ + return GetMemB(seg, offset) | ( GetMemB(seg, offset + 1) << 8 ); +} + + +// Setting flags + +inline void v30mz_cpu_device::set_CFB(UINT32 x) +{ + m_CarryVal = x & 0x100; +} + +inline void v30mz_cpu_device::set_CFW(UINT32 x) +{ + m_CarryVal = x & 0x10000; +} + +inline void v30mz_cpu_device::set_AF(UINT32 x,UINT32 y,UINT32 z) +{ + m_AuxVal = (x ^ (y ^ z)) & 0x10; +} + +inline void v30mz_cpu_device::set_SF(UINT32 x) +{ + m_SignVal = x; +} + +inline void v30mz_cpu_device::set_ZF(UINT32 x) +{ + m_ZeroVal = x; +} + +inline void v30mz_cpu_device::set_PF(UINT32 x) +{ + m_ParityVal = x; +} + +inline void v30mz_cpu_device::set_SZPF_Byte(UINT32 x) +{ + m_SignVal = m_ZeroVal = m_ParityVal = (INT8)x; +} + +inline void v30mz_cpu_device::set_SZPF_Word(UINT32 x) +{ + m_SignVal = m_ZeroVal = m_ParityVal = (INT16)x; +} + +inline void v30mz_cpu_device::set_OFW_Add(UINT32 x,UINT32 y,UINT32 z) +{ + m_OverVal = (x ^ y) & (x ^ z) & 0x8000; +} + +inline void v30mz_cpu_device::set_OFB_Add(UINT32 x,UINT32 y,UINT32 z) +{ + m_OverVal = (x ^ y) & (x ^ z) & 0x80; +} + +inline void v30mz_cpu_device::set_OFW_Sub(UINT32 x,UINT32 y,UINT32 z) +{ + m_OverVal = (z ^ y) & (z ^ x) & 0x8000; +} + +inline void v30mz_cpu_device::set_OFB_Sub(UINT32 x,UINT32 y,UINT32 z) +{ + m_OverVal = (z ^ y) & (z ^ x) & 0x80; +} + + +inline UINT16 v30mz_cpu_device::CompressFlags() +{ + return (CF ? 1 : 0) + | (PF ? 4 : 0) + | (AF ? 0x10 : 0) + | (ZF ? 0x40 : 0) + | (SF ? 0x80 : 0) + | (m_TF << 8) + | (m_IF << 9) + | (m_DF << 10) + | (OF << 11) + | (MD << 15); +} + +inline void v30mz_cpu_device::ExpandFlags(UINT16 f) +{ + m_CarryVal = (f) & 1; + m_ParityVal = !((f) & 4); + m_AuxVal = (f) & 16; + m_ZeroVal = !((f) & 64); + m_SignVal = (f) & 128 ? -1 : 0; + m_TF = ((f) & 256) == 256; + m_IF = ((f) & 512) == 512; + m_DF = ((f) & 1024) == 1024; + m_OverVal = (f) & 2048; + m_MF = ((f) & 0x8000) == 0x8000; +} + +inline void v30mz_cpu_device::i_insb() +{ + PutMemB( ES, m_regs.w[IY], read_port( m_regs.w[DW] ) ); + m_regs.w[IY] += -2 * m_DF + 1; + CLK(6); +} + +inline void v30mz_cpu_device::i_insw() +{ + PutMemB( ES, m_regs.w[IY], read_port( m_regs.w[DW] ) ); + PutMemB( ES, (m_regs.w[IY] + 1) & 0xffff, read_port((m_regs.w[DW]+1)&0xffff)); + m_regs.w[IY] += -4 * m_DF + 2; + CLK(6); +} + +inline void v30mz_cpu_device::i_outsb() +{ + write_port( m_regs.w[DW], GetMemB( DS, m_regs.w[IX] ) ); + m_regs.w[IX] += -2 * m_DF + 1; + CLK(7); +} + +inline void v30mz_cpu_device::i_outsw() +{ + write_port( m_regs.w[DW], GetMemB( DS, m_regs.w[IX] ) ); + write_port( (m_regs.w[DW]+1)&0xffff, GetMemB( DS, (m_regs.w[IX]+1)&0xffff ) ); + m_regs.w[IX] += -4 * m_DF + 2; + CLK(7); +} + +inline void v30mz_cpu_device::i_movsb() +{ + UINT8 tmp = GetMemB( DS, m_regs.w[IX] ); + PutMemB( ES, m_regs.w[IY], tmp); + m_regs.w[IY] += -2 * m_DF + 1; + m_regs.w[IX] += -2 * m_DF + 1; + CLK(5); +} + +inline void v30mz_cpu_device::i_movsw() +{ + UINT16 tmp = GetMemW( DS, m_regs.w[IX] ); + PutMemW( ES, m_regs.w[IY], tmp ); + m_regs.w[IY] += -4 * m_DF + 2; + m_regs.w[IX] += -4 * m_DF + 2; + CLK(5); +} + +inline void v30mz_cpu_device::i_cmpsb() +{ + m_src = GetMemB( ES, m_regs.w[IY] ); + m_dst = GetMemB( DS, m_regs.w[IX] ); + SUBB(); + m_regs.w[IY] += -2 * m_DF + 1; + m_regs.w[IX] += -2 * m_DF + 1; + CLK(6); +} + +inline void v30mz_cpu_device::i_cmpsw() +{ + m_src = GetMemW( ES, m_regs.w[IY] ); + m_dst = GetMemW( DS, m_regs.w[IX] ); + SUBW(); + m_regs.w[IY] += -4 * m_DF + 2; + m_regs.w[IX] += -4 * m_DF + 2; + CLK(6); +} + +inline void v30mz_cpu_device::i_stosb() +{ + PutMemB( ES, m_regs.w[IY], m_regs.b[AL] ); + m_regs.w[IY] += -2 * m_DF + 1; + CLK(3); +} + +inline void v30mz_cpu_device::i_stosw() +{ + PutMemW( ES, m_regs.w[IY], m_regs.w[AW] ); + m_regs.w[IY] += -4 * m_DF + 2; + CLK(3); +} + +inline void v30mz_cpu_device::i_lodsb() +{ + m_regs.b[AL] = GetMemB( DS, m_regs.w[IX] ); + m_regs.w[IX] += -2 * m_DF + 1; + CLK(3); +} + +inline void v30mz_cpu_device::i_lodsw() +{ + m_regs.w[AW] = GetMemW( DS, m_regs.w[IX] ); + m_regs.w[IX] += -4 * m_DF + 2; + CLK(3); +} + +inline void v30mz_cpu_device::i_scasb() +{ + m_src = GetMemB( ES, m_regs.w[IY] ); + m_dst = m_regs.b[AL]; + SUBB(); + m_regs.w[IY] += -2 * m_DF + 1; + CLK(4); +} + +inline void v30mz_cpu_device::i_scasw() +{ + m_src = GetMemW( ES, m_regs.w[IY] ); + m_dst = m_regs.w[AW]; + SUBW(); + m_regs.w[IY] += -4 * m_DF + 2; + CLK(4); +} + + +inline void v30mz_cpu_device::i_popf() +{ + UINT32 tmp = POP(); + + ExpandFlags(tmp); + CLK(3); + if (m_TF) + { + m_fire_trap = 1; + } +} + + +inline void v30mz_cpu_device::ADDB() +{ + UINT32 res = m_dst + m_src; + + set_CFB(res); + set_OFB_Add(res,m_src,m_dst); + set_AF(res,m_src,m_dst); + set_SZPF_Byte(res); + m_dst = res & 0xff; +} + + +inline void v30mz_cpu_device::ADDW() +{ + UINT32 res = m_dst + m_src; + + set_CFW(res); + set_OFW_Add(res,m_src,m_dst); + set_AF(res,m_src,m_dst); + set_SZPF_Word(res); + m_dst = res & 0xffff; +} + + +inline void v30mz_cpu_device::SUBB() +{ + UINT32 res = m_dst - m_src; + + set_CFB(res); + set_OFB_Sub(res,m_src,m_dst); + set_AF(res,m_src,m_dst); + set_SZPF_Byte(res); + m_dst = res & 0xff; +} + + +inline void v30mz_cpu_device::SUBW() +{ + UINT32 res = m_dst - m_src; + + set_CFW(res); + set_OFW_Sub(res,m_src,m_dst); + set_AF(res,m_src,m_dst); + set_SZPF_Word(res); + m_dst = res & 0xffff; +} + + +inline void v30mz_cpu_device::ORB() +{ + m_dst |= m_src; + m_CarryVal = m_OverVal = m_AuxVal = 0; + set_SZPF_Byte(m_dst); +} + + +inline void v30mz_cpu_device::ORW() +{ + m_dst |= m_src; + m_CarryVal = m_OverVal = m_AuxVal = 0; + set_SZPF_Word(m_dst); +} + + +inline void v30mz_cpu_device::ANDB() +{ + m_dst &= m_src; + m_CarryVal = m_OverVal = m_AuxVal = 0; + set_SZPF_Byte(m_dst); +} + + +inline void v30mz_cpu_device::ANDW() +{ + m_dst &= m_src; + m_CarryVal = m_OverVal = m_AuxVal = 0; + set_SZPF_Word(m_dst); +} + + +inline void v30mz_cpu_device::XORB() +{ + m_dst ^= m_src; + m_CarryVal = m_OverVal = m_AuxVal = 0; + set_SZPF_Byte(m_dst); +} + + +inline void v30mz_cpu_device::XORW() +{ + m_dst ^= m_src; + m_CarryVal = m_OverVal = m_AuxVal = 0; + set_SZPF_Word(m_dst); +} + + +inline void v30mz_cpu_device::ROL_BYTE() +{ + m_CarryVal = m_dst & 0x80; + m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); +} + +inline void v30mz_cpu_device::ROL_WORD() +{ + m_CarryVal = m_dst & 0x8000; + m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); +} + +inline void v30mz_cpu_device::ROR_BYTE() +{ + m_CarryVal = m_dst & 0x1; + m_dst = (m_dst >> 1) | (CF ? 0x80 : 0x00); +} + +inline void v30mz_cpu_device::ROR_WORD() +{ + m_CarryVal = m_dst & 0x1; + m_dst = (m_dst >> 1) + (CF ? 0x8000 : 0x0000); +} + +inline void v30mz_cpu_device::ROLC_BYTE() +{ + m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); + set_CFB(m_dst); +} + +inline void v30mz_cpu_device::ROLC_WORD() +{ + m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); + set_CFW(m_dst); +} + +inline void v30mz_cpu_device::RORC_BYTE() +{ + m_dst |= ( CF ? 0x100 : 0x00); + m_CarryVal = m_dst & 0x01; + m_dst >>= 1; +} + +inline void v30mz_cpu_device::RORC_WORD() +{ + m_dst |= ( CF ? 0x10000 : 0); + m_CarryVal = m_dst & 0x01; + m_dst >>= 1; +} + +inline void v30mz_cpu_device::SHL_BYTE(UINT8 c) +{ + m_icount -= c; + m_dst <<= c; + set_CFB(m_dst); + set_SZPF_Byte(m_dst); + PutbackRMByte(m_dst); +} + +inline void v30mz_cpu_device::SHL_WORD(UINT8 c) +{ + m_icount -= c; + m_dst <<= c; + set_CFW(m_dst); + set_SZPF_Word(m_dst); + PutbackRMWord(m_dst); +} + +inline void v30mz_cpu_device::SHR_BYTE(UINT8 c) +{ + m_icount -= c; + m_dst >>= c-1; + m_CarryVal = m_dst & 0x1; + m_dst >>= 1; + set_SZPF_Byte(m_dst); + PutbackRMByte(m_dst); +} + +inline void v30mz_cpu_device::SHR_WORD(UINT8 c) +{ + m_icount -= c; + m_dst >>= c-1; + m_CarryVal = m_dst & 0x1; + m_dst >>= 1; + set_SZPF_Word(m_dst); + PutbackRMWord(m_dst); +} + +inline void v30mz_cpu_device::SHRA_BYTE(UINT8 c) +{ + m_icount -= c; + m_dst = ((INT8)m_dst) >> (c-1); + m_CarryVal = m_dst & 0x1; + m_dst = m_dst >> 1; + set_SZPF_Byte(m_dst); + PutbackRMByte(m_dst); +} + +inline void v30mz_cpu_device::SHRA_WORD(UINT8 c) +{ + m_icount -= c; + m_dst = ((INT16)m_dst) >> (c-1); + m_CarryVal = m_dst & 0x1; + m_dst = m_dst >> 1; + set_SZPF_Word(m_dst); + PutbackRMWord(m_dst); +} + + +inline void v30mz_cpu_device::XchgAWReg(UINT8 reg) +{ + UINT16 tmp = m_regs.w[reg]; + + m_regs.w[reg] = m_regs.w[AW]; + m_regs.w[AW] = tmp; +} + + +inline void v30mz_cpu_device::IncWordReg(UINT8 reg) +{ + UINT32 tmp = m_regs.w[reg]; + UINT32 tmp1 = tmp+1; + + m_OverVal = (tmp == 0x7fff); + set_AF(tmp1,tmp,1); + set_SZPF_Word(tmp1); + m_regs.w[reg] = tmp1; +} + + +inline void v30mz_cpu_device::DecWordReg(UINT8 reg) +{ + UINT32 tmp = m_regs.w[reg]; + UINT32 tmp1 = tmp-1; + + m_OverVal = (tmp == 0x8000); + set_AF(tmp1,tmp,1); + set_SZPF_Word(tmp1); + m_regs.w[reg] = tmp1; +} + + +inline void v30mz_cpu_device::PUSH(UINT16 data) +{ + m_regs.w[SP] -= 2; + write_word( ( m_sregs[SS] << 4 ) + m_regs.w[SP], data ); +} + + +inline UINT16 v30mz_cpu_device::POP() +{ + UINT16 data = read_word( ( m_sregs[SS] << 4 ) + m_regs.w[SP] ); + + m_regs.w[SP] += 2; + return data; +} + + +inline void v30mz_cpu_device::JMP(bool cond) +{ + int rel = (int)((INT8)fetch()); + + if (cond) + { + m_ip += rel; + CLK(9); + } + CLK(1); +} + + +inline void v30mz_cpu_device::ADJ4(INT8 param1,INT8 param2) +{ + if (AF || ((m_regs.b[AL] & 0xf) > 9)) + { + UINT16 tmp; + tmp = m_regs.b[AL] + param1; + m_regs.b[AL] = tmp; + m_AuxVal = 1; + m_CarryVal |= tmp & 0x100; + } + if (CF || (m_regs.b[AL]>0x9f)) + { + m_regs.b[AL] += param2; + m_CarryVal = 1; + } + set_SZPF_Byte(m_regs.b[AL]); +} + + +inline void v30mz_cpu_device::ADJB(INT8 param1, INT8 param2) +{ + if (AF || ((m_regs.b[AL] & 0xf) > 9)) + { + m_regs.b[AL] += param1; + m_regs.b[AH] += param2; + m_AuxVal = 1; + m_CarryVal = 1; + } + else + { + m_AuxVal = 0; + m_CarryVal = 0; + } + m_regs.b[AL] &= 0x0F; +} + + +void v30mz_cpu_device::interrupt(int int_num) +{ + PUSH( CompressFlags() ); + CLK(2); + m_TF = m_IF = 0; if (int_num == -1) { - int_num = (*cpustate->irq_callback)(cpustate->device, 0); + int_num = m_irq_callback(this, 0); - cpustate->irq_state = CLEAR_LINE; - cpustate->pending_irq &= ~INT_IRQ; + m_irq_state = CLEAR_LINE; + m_pending_irq &= ~INT_IRQ; } - dest_off = ReadWord(int_num*4); - dest_seg = ReadWord(int_num*4+2); + UINT16 dest_off = read_word( int_num * 4 + 0 ); + UINT16 dest_seg = read_word( int_num * 4 + 2 ); - PUSH(cpustate->sregs[CS]); - PUSH(cpustate->ip); - cpustate->ip = (UINT16)dest_off; - cpustate->sregs[CS] = (UINT16)dest_seg; + PUSH(m_sregs[CS]); + PUSH(m_ip); + m_ip = dest_off; + m_sregs[CS] = dest_seg; } -static void nec_trap(v30mz_state *cpustate) -{ - nec_instruction[FETCHOP](cpustate); - nec_interrupt(cpustate,1); -} -static void external_int(v30mz_state *cpustate) +void v30mz_cpu_device::execute_set_input( int inptnum, int state ) { - if( cpustate->pending_irq & NMI_IRQ ) + if (inptnum == INPUT_LINE_NMI) { - nec_interrupt(cpustate,NEC_NMI_INT_VECTOR); - cpustate->pending_irq &= ~NMI_IRQ; - } - else if( cpustate->pending_irq ) - { - /* the actual vector is retrieved after pushing flags */ - /* and clearing the IF */ - nec_interrupt(cpustate,(UINT32)-1); - } -} - -/****************************************************************************/ -/* OPCODES */ -/****************************************************************************/ - -#define OP(num,func_name) static void func_name(v30mz_state *cpustate) - -OP( 0x00, i_add_br8 ) { DEF_br8; ADDB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x01, i_add_wr16 ) { DEF_wr16; ADDW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x02, i_add_r8b ) { DEF_r8b; ADDB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x03, i_add_r16w ) { DEF_r16w; ADDW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x04, i_add_ald8 ) { DEF_ald8; ADDB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x05, i_add_axd16) { DEF_axd16; ADDW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x06, i_push_es ) { PUSH(cpustate->sregs[ES]); CLK(2); } -OP( 0x07, i_pop_es ) { POP(cpustate->sregs[ES]); CLK(3); } - -OP( 0x08, i_or_br8 ) { DEF_br8; ORB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x09, i_or_wr16 ) { DEF_wr16; ORW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x0a, i_or_r8b ) { DEF_r8b; ORB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x0b, i_or_r16w ) { DEF_r16w; ORW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x0e, i_push_cs ) { PUSH(cpustate->sregs[CS]); CLK(2); } -OP( 0x0f, i_pre_nec ) { UINT32 ModRM, tmp, tmp2; - switch (FETCH) { - case 0x10 : BITOP_BYTE; tmp2 = cpustate->regs.b[CL] & 0x7; cpustate->ZeroVal = (tmp & (1<CarryVal=cpustate->OverVal=0; break; /* Test */ - case 0x11 : BITOP_WORD; tmp2 = cpustate->regs.b[CL] & 0xf; cpustate->ZeroVal = (tmp & (1<CarryVal=cpustate->OverVal=0; break; /* Test */ - case 0x12 : BITOP_BYTE; tmp2 = cpustate->regs.b[CL] & 0x7; tmp &= ~(1<regs.b[CL] & 0xf; tmp &= ~(1<regs.b[CL] & 0x7; tmp |= (1<regs.b[CL] & 0xf; tmp |= (1<regs.b[CL] & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ - case 0x17 : BITOP_WORD; tmp2 = cpustate->regs.b[CL] & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ - - case 0x18 : BITOP_BYTE; tmp2 = (FETCH) & 0x7; cpustate->ZeroVal = (tmp & (1<CarryVal=cpustate->OverVal=0; break; /* Test */ - case 0x19 : BITOP_WORD; tmp2 = (FETCH) & 0xf; cpustate->ZeroVal = (tmp & (1<CarryVal=cpustate->OverVal=0; break; /* Test */ - case 0x1a : BITOP_BYTE; tmp2 = (FETCH) & 0x7; tmp &= ~(1<regs.b[AL] & 0xf; cpustate->regs.b[AL] = (cpustate->regs.b[AL] & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(9,15); break; - case 0x2a : ModRM = FETCH; tmp = GetRMByte(ModRM); tmp2 = (cpustate->regs.b[AL] & 0xf)<<4; cpustate->regs.b[AL] = (cpustate->regs.b[AL] & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(13,19); break; - case 0x31 : ModRM = FETCH; ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC(cpustate)); break; - case 0x33 : ModRM = FETCH; ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC(cpustate)); break; - case 0x92 : CLK(2); break; /* V25/35 FINT */ - case 0xe0 : ModRM = FETCH; ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC(cpustate)); break; - case 0xf0 : ModRM = FETCH; ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC(cpustate)); break; - case 0xff : ModRM = FETCH; ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC(cpustate)); break; - default: logerror("%06x: Unknown V20 instruction\n",PC(cpustate)); break; - } -} - -OP( 0x10, i_adc_br8 ) { DEF_br8; src+=CF; ADDB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x11, i_adc_wr16 ) { DEF_wr16; src+=CF; ADDW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x12, i_adc_r8b ) { DEF_r8b; src+=CF; ADDB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x13, i_adc_r16w ) { DEF_r16w; src+=CF; ADDW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x14, i_adc_ald8 ) { DEF_ald8; src+=CF; ADDB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x15, i_adc_axd16) { DEF_axd16; src+=CF; ADDW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x16, i_push_ss ) { PUSH(cpustate->sregs[SS]); CLK(2); } -OP( 0x17, i_pop_ss ) { POP(cpustate->sregs[SS]); CLK(3); cpustate->no_interrupt=1; } - -OP( 0x18, i_sbb_br8 ) { DEF_br8; src+=CF; SUBB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x19, i_sbb_wr16 ) { DEF_wr16; src+=CF; SUBW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x1a, i_sbb_r8b ) { DEF_r8b; src+=CF; SUBB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x1b, i_sbb_r16w ) { DEF_r16w; src+=CF; SUBW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x1c, i_sbb_ald8 ) { DEF_ald8; src+=CF; SUBB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x1d, i_sbb_axd16) { DEF_axd16; src+=CF; SUBW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x1e, i_push_ds ) { PUSH(cpustate->sregs[DS]); CLK(2); } -OP( 0x1f, i_pop_ds ) { POP(cpustate->sregs[DS]); CLK(3); } - -OP( 0x20, i_and_br8 ) { DEF_br8; ANDB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x21, i_and_wr16 ) { DEF_wr16; ANDW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x22, i_and_r8b ) { DEF_r8b; ANDB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x23, i_and_r16w ) { DEF_r16w; ANDW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x24, i_and_ald8 ) { DEF_ald8; ANDB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x25, i_and_axd16) { DEF_axd16; ANDW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x26, i_es ) { cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[ES]<<4; CLK(1); nec_instruction[FETCHOP](cpustate); cpustate->seg_prefix=FALSE; } -OP( 0x27, i_daa ) { ADJ4(6,0x60); CLK(10); } - -OP( 0x28, i_sub_br8 ) { DEF_br8; SUBB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x29, i_sub_wr16 ) { DEF_wr16; SUBW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x2a, i_sub_r8b ) { DEF_r8b; SUBB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x2b, i_sub_r16w ) { DEF_r16w; SUBW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x2c, i_sub_ald8 ) { DEF_ald8; SUBB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x2d, i_sub_axd16) { DEF_axd16; SUBW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x2e, i_cs ) { cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[CS]<<4; CLK(1); nec_instruction[FETCHOP](cpustate); cpustate->seg_prefix=FALSE; } -OP( 0x2f, i_das ) { ADJ4(-6,-0x60); CLK(10); } - -OP( 0x30, i_xor_br8 ) { DEF_br8; XORB; PutbackRMByte(ModRM,dst); CLKM(1,3); } -OP( 0x31, i_xor_wr16 ) { DEF_wr16; XORW; PutbackRMWord(ModRM,dst); CLKM(1,3);} -OP( 0x32, i_xor_r8b ) { DEF_r8b; XORB; RegByte(ModRM)=dst; CLKM(1,2); } -OP( 0x33, i_xor_r16w ) { DEF_r16w; XORW; RegWord(ModRM)=dst; CLKM(1,2); } -OP( 0x34, i_xor_ald8 ) { DEF_ald8; XORB; cpustate->regs.b[AL]=dst; CLK(1); } -OP( 0x35, i_xor_axd16) { DEF_axd16; XORW; cpustate->regs.w[AW]=dst; CLK(1); } -OP( 0x36, i_ss ) { cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[SS]<<4; CLK(1); nec_instruction[FETCHOP](cpustate); cpustate->seg_prefix=FALSE; } -OP( 0x37, i_aaa ) { ADJB(6, (cpustate->regs.b[AL] > 0xf9) ? 2 : 1); CLK(9); } - -OP( 0x38, i_cmp_br8 ) { DEF_br8; SUBB; CLKM(1,2); } -OP( 0x39, i_cmp_wr16 ) { DEF_wr16; SUBW; CLKM(1,2);} -OP( 0x3a, i_cmp_r8b ) { DEF_r8b; SUBB; CLKM(1,2); } -OP( 0x3b, i_cmp_r16w ) { DEF_r16w; SUBW; CLKM(1,2); } -OP( 0x3c, i_cmp_ald8 ) { DEF_ald8; SUBB; CLK(1); } -OP( 0x3d, i_cmp_axd16) { DEF_axd16; SUBW; CLK(1); } -OP( 0x3e, i_ds ) { cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[DS]<<4; CLK(1); nec_instruction[FETCHOP](cpustate); cpustate->seg_prefix=FALSE; } -OP( 0x3f, i_aas ) { ADJB(-6, (cpustate->regs.b[AL] < 6) ? -2 : -1); CLK(9); } - -OP( 0x40, i_inc_ax ) { IncWordReg(AW); CLK(1); } -OP( 0x41, i_inc_cx ) { IncWordReg(CW); CLK(1); } -OP( 0x42, i_inc_dx ) { IncWordReg(DW); CLK(1); } -OP( 0x43, i_inc_bx ) { IncWordReg(BW); CLK(1); } -OP( 0x44, i_inc_sp ) { IncWordReg(SP); CLK(1); } -OP( 0x45, i_inc_bp ) { IncWordReg(BP); CLK(1); } -OP( 0x46, i_inc_si ) { IncWordReg(IX); CLK(1); } -OP( 0x47, i_inc_di ) { IncWordReg(IY); CLK(1); } - -OP( 0x48, i_dec_ax ) { DecWordReg(AW); CLK(1); } -OP( 0x49, i_dec_cx ) { DecWordReg(CW); CLK(1); } -OP( 0x4a, i_dec_dx ) { DecWordReg(DW); CLK(1); } -OP( 0x4b, i_dec_bx ) { DecWordReg(BW); CLK(1); } -OP( 0x4c, i_dec_sp ) { DecWordReg(SP); CLK(1); } -OP( 0x4d, i_dec_bp ) { DecWordReg(BP); CLK(1); } -OP( 0x4e, i_dec_si ) { DecWordReg(IX); CLK(1); } -OP( 0x4f, i_dec_di ) { DecWordReg(IY); CLK(1); } - -OP( 0x50, i_push_ax ) { PUSH(cpustate->regs.w[AW]); CLK(1); } -OP( 0x51, i_push_cx ) { PUSH(cpustate->regs.w[CW]); CLK(1); } -OP( 0x52, i_push_dx ) { PUSH(cpustate->regs.w[DW]); CLK(1); } -OP( 0x53, i_push_bx ) { PUSH(cpustate->regs.w[BW]); CLK(1); } -OP( 0x54, i_push_sp ) { PUSH(cpustate->regs.w[SP]); CLK(1); } -OP( 0x55, i_push_bp ) { PUSH(cpustate->regs.w[BP]); CLK(1); } -OP( 0x56, i_push_si ) { PUSH(cpustate->regs.w[IX]); CLK(1); } -OP( 0x57, i_push_di ) { PUSH(cpustate->regs.w[IY]); CLK(1); } - -OP( 0x58, i_pop_ax ) { POP(cpustate->regs.w[AW]); CLK(1); } -OP( 0x59, i_pop_cx ) { POP(cpustate->regs.w[CW]); CLK(1); } -OP( 0x5a, i_pop_dx ) { POP(cpustate->regs.w[DW]); CLK(1); } -OP( 0x5b, i_pop_bx ) { POP(cpustate->regs.w[BW]); CLK(1); } -OP( 0x5c, i_pop_sp ) { POP(cpustate->regs.w[SP]); CLK(1); } -OP( 0x5d, i_pop_bp ) { POP(cpustate->regs.w[BP]); CLK(1); } -OP( 0x5e, i_pop_si ) { POP(cpustate->regs.w[IX]); CLK(1); } -OP( 0x5f, i_pop_di ) { POP(cpustate->regs.w[IY]); CLK(1); } - -OP( 0x60, i_pusha ) { - unsigned tmp=cpustate->regs.w[SP]; - PUSH(cpustate->regs.w[AW]); - PUSH(cpustate->regs.w[CW]); - PUSH(cpustate->regs.w[DW]); - PUSH(cpustate->regs.w[BW]); - PUSH(tmp); - PUSH(cpustate->regs.w[BP]); - PUSH(cpustate->regs.w[IX]); - PUSH(cpustate->regs.w[IY]); - CLK(9); -} -static unsigned nec_v30mz_popa_tmp; -OP( 0x61, i_popa ) { - POP(cpustate->regs.w[IY]); - POP(cpustate->regs.w[IX]); - POP(cpustate->regs.w[BP]); - POP(nec_v30mz_popa_tmp); - POP(cpustate->regs.w[BW]); - POP(cpustate->regs.w[DW]); - POP(cpustate->regs.w[CW]); - POP(cpustate->regs.w[AW]); - CLK(8); -} -OP( 0x62, i_chkind ) { - UINT32 low,high,tmp; - GetModRM; - low = GetRMWord(ModRM); - high= GetnextRMWord; - tmp= RegWord(ModRM); - if (tmphigh) { - nec_interrupt(cpustate,5); - CLK(20); - } else { - CLK(13); - } - logerror("%06x: bound %04x high %04x low %04x tmp\n",PC(cpustate),high,low,tmp); -} -OP( 0x64, i_repnc ) { UINT32 next = FETCHOP; UINT16 c = cpustate->regs.w[CW]; - switch(next) { /* Segments */ - case 0x26: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[ES]<<4; next = FETCHOP; CLK(2); break; - case 0x2e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[CS]<<4; next = FETCHOP; CLK(2); break; - case 0x36: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[SS]<<4; next = FETCHOP; CLK(2); break; - case 0x3e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[DS]<<4; next = FETCHOP; CLK(2); break; - } - - switch(next) { - case 0x6c: CLK(2); if (c) do { i_insb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0x6d: CLK(2); if (c) do { i_insw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0x6e: CLK(2); if (c) do { i_outsb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0x6f: CLK(2); if (c) do { i_outsw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xa4: CLK(2); if (c) do { i_movsb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xa5: CLK(2); if (c) do { i_movsw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xa6: CLK(2); if (c) do { i_cmpsb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xa7: CLK(2); if (c) do { i_cmpsw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xaa: CLK(2); if (c) do { i_stosb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xab: CLK(2); if (c) do { i_stosw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xac: CLK(2); if (c) do { i_lodsb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xad: CLK(2); if (c) do { i_lodsw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xae: CLK(2); if (c) do { i_scasb(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - case 0xaf: CLK(2); if (c) do { i_scasw(cpustate); c--; } while (c>0 && !CF); cpustate->regs.w[CW]=c; break; - default: logerror("%06x: REPNC invalid\n",PC(cpustate)); nec_instruction[next](cpustate); - } - cpustate->seg_prefix=FALSE; -} - -OP( 0x65, i_repc ) { UINT32 next = FETCHOP; UINT16 c = cpustate->regs.w[CW]; - switch(next) { /* Segments */ - case 0x26: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[ES]<<4; next = FETCHOP; CLK(2); break; - case 0x2e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[CS]<<4; next = FETCHOP; CLK(2); break; - case 0x36: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[SS]<<4; next = FETCHOP; CLK(2); break; - case 0x3e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[DS]<<4; next = FETCHOP; CLK(2); break; - } - - switch(next) { - case 0x6c: CLK(2); if (c) do { i_insb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0x6d: CLK(2); if (c) do { i_insw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0x6e: CLK(2); if (c) do { i_outsb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0x6f: CLK(2); if (c) do { i_outsw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xa4: CLK(2); if (c) do { i_movsb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xa5: CLK(2); if (c) do { i_movsw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xa6: CLK(2); if (c) do { i_cmpsb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xa7: CLK(2); if (c) do { i_cmpsw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xaa: CLK(2); if (c) do { i_stosb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xab: CLK(2); if (c) do { i_stosw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xac: CLK(2); if (c) do { i_lodsb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xad: CLK(2); if (c) do { i_lodsw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xae: CLK(2); if (c) do { i_scasb(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - case 0xaf: CLK(2); if (c) do { i_scasw(cpustate); c--; } while (c>0 && CF); cpustate->regs.w[CW]=c; break; - default: logerror("%06x: REPC invalid\n",PC(cpustate)); nec_instruction[next](cpustate); - } - cpustate->seg_prefix=FALSE; -} - -OP( 0x68, i_push_d16 ) { UINT32 tmp; FETCHWORD(tmp); PUSH(tmp); CLK(1); } -OP( 0x69, i_imul_d16 ) { UINT32 tmp; DEF_r16w; FETCHWORD(tmp); dst = (INT32)((INT16)src)*(INT32)((INT16)tmp); cpustate->CarryVal = cpustate->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(UINT16)dst; if (ModRM >= 0xc0) CLK(3) else CLK(4) } -OP( 0x6a, i_push_d8 ) { UINT32 tmp = (UINT16)((INT16)((INT8)FETCH)); PUSH(tmp); CLK(1); } -OP( 0x6b, i_imul_d8 ) { UINT32 src2; DEF_r16w; src2= (UINT16)((INT16)((INT8)FETCH)); dst = (INT32)((INT16)src)*(INT32)((INT16)src2); cpustate->CarryVal = cpustate->OverVal = (((INT32)dst) >> 15 != 0) && (((INT32)dst) >> 15 != -1); RegWord(ModRM)=(UINT16)dst; if (ModRM >= 0xc0) CLK(3) else CLK(4) } -OP( 0x6c, i_insb ) { PutMemB(ES,cpustate->regs.w[IY],read_port(cpustate->regs.w[DW])); cpustate->regs.w[IY]+= -2 * cpustate->DF + 1; CLK(6); } -OP( 0x6d, i_insw ) { PutMemB(ES,cpustate->regs.w[IY],read_port(cpustate->regs.w[DW])); PutMemB(ES,(cpustate->regs.w[IY]+1)&0xffff,read_port((cpustate->regs.w[DW]+1)&0xffff)); cpustate->regs.w[IY]+= -4 * cpustate->DF + 2; CLK(6); } -OP( 0x6e, i_outsb ) { write_port(cpustate->regs.w[DW],GetMemB(DS,cpustate->regs.w[IX])); cpustate->regs.w[IX]+= -2 * cpustate->DF + 1; CLK(7); } -OP( 0x6f, i_outsw ) { write_port(cpustate->regs.w[DW],GetMemB(DS,cpustate->regs.w[IX])); write_port((cpustate->regs.w[DW]+1)&0xffff,GetMemB(DS,(cpustate->regs.w[IX]+1)&0xffff)); cpustate->regs.w[IX]+= -4 * cpustate->DF + 2; CLK(7); } - -OP( 0x70, i_jo ) { JMP( OF); if ( OF) CLK(4) else CLK(1) } -OP( 0x71, i_jno ) { JMP(!OF); if (!OF) CLK(4) else CLK(1) } -OP( 0x72, i_jc ) { JMP( CF); if ( CF) CLK(4) else CLK(1) } -OP( 0x73, i_jnc ) { JMP(!CF); if (!CF) CLK(4) else CLK(1) } -OP( 0x74, i_jz ) { JMP( ZF); if ( ZF) CLK(4) else CLK(1) } -OP( 0x75, i_jnz ) { JMP(!ZF); if (!ZF) CLK(4) else CLK(1) } -OP( 0x76, i_jce ) { JMP(CF || ZF); if (CF || ZF) CLK(4) else CLK(1) } -OP( 0x77, i_jnce ) { JMP(!(CF || ZF)); if (!(CF || ZF)) CLK(4) else CLK(1) } -OP( 0x78, i_js ) { JMP( SF); if ( SF) CLK(4) else CLK(1) } -OP( 0x79, i_jns ) { JMP(!SF); if (!SF) CLK(4) else CLK(1) } -OP( 0x7a, i_jp ) { JMP( PF); if ( PF) CLK(4) else CLK(1) } -OP( 0x7b, i_jnp ) { JMP(!PF); if (!PF) CLK(4) else CLK(1) } -OP( 0x7c, i_jl ) { JMP((SF!=OF)&&(!ZF)); if ((SF!=OF)&&(!ZF)) CLK(4) else CLK(1) } -OP( 0x7d, i_jnl ) { JMP((ZF)||(SF==OF)); if ((ZF)||(SF==OF)) CLK(4) else CLK(1) } -OP( 0x7e, i_jle ) { JMP((ZF)||(SF!=OF)); if ((ZF)||(SF!=OF)) CLK(4) else CLK(1) } -OP( 0x7f, i_jnle ) { JMP((SF==OF)&&(!ZF)); if ((SF==OF)&&(!ZF)) CLK(4) else CLK(1) } - -OP( 0x80, i_80pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH; - if (ModRM >=0xc0 ) CLK(1) else if ((ModRM & 0x38)==0x38) CLK(2) else CLK(3) - switch (ModRM & 0x38) { - case 0x00: ADDB; PutbackRMByte(ModRM,dst); break; - case 0x08: ORB; PutbackRMByte(ModRM,dst); break; - case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break; - case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break; - case 0x20: ANDB; PutbackRMByte(ModRM,dst); break; - case 0x28: SUBB; PutbackRMByte(ModRM,dst); break; - case 0x30: XORB; PutbackRMByte(ModRM,dst); break; - case 0x38: SUBB; break; /* CMP */ - } -} - -OP( 0x81, i_81pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH; src+= (FETCH << 8); - if (ModRM >=0xc0 ) CLK(1) else if ((ModRM & 0x38)==0x38) CLK(2) else CLK(3) - switch (ModRM & 0x38) { - case 0x00: ADDW; PutbackRMWord(ModRM,dst); break; - case 0x08: ORW; PutbackRMWord(ModRM,dst); break; - case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break; - case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break; - case 0x20: ANDW; PutbackRMWord(ModRM,dst); break; - case 0x28: SUBW; PutbackRMWord(ModRM,dst); break; - case 0x30: XORW; PutbackRMWord(ModRM,dst); break; - case 0x38: SUBW; break; /* CMP */ - } -} - -OP( 0x82, i_82pre ) { UINT32 dst, src; GetModRM; dst = GetRMByte(ModRM); src = (UINT8)((INT8)FETCH); - if (ModRM >=0xc0 ) CLK(1) else if ((ModRM & 0x38)==0x38) CLK(2) else CLK(3) - switch (ModRM & 0x38) { - case 0x00: ADDB; PutbackRMByte(ModRM,dst); break; - case 0x08: ORB; PutbackRMByte(ModRM,dst); break; - case 0x10: src+=CF; ADDB; PutbackRMByte(ModRM,dst); break; - case 0x18: src+=CF; SUBB; PutbackRMByte(ModRM,dst); break; - case 0x20: ANDB; PutbackRMByte(ModRM,dst); break; - case 0x28: SUBB; PutbackRMByte(ModRM,dst); break; - case 0x30: XORB; PutbackRMByte(ModRM,dst); break; - case 0x38: SUBB; break; /* CMP */ - } -} - -OP( 0x83, i_83pre ) { UINT32 dst, src; GetModRM; dst = GetRMWord(ModRM); src = (UINT16)((INT16)((INT8)FETCH)); - if (ModRM >=0xc0 ) CLK(1) else if ((ModRM & 0x38)==0x38) CLK(2) else CLK(3) - switch (ModRM & 0x38) { - case 0x00: ADDW; PutbackRMWord(ModRM,dst); break; - case 0x08: ORW; PutbackRMWord(ModRM,dst); break; - case 0x10: src+=CF; ADDW; PutbackRMWord(ModRM,dst); break; - case 0x18: src+=CF; SUBW; PutbackRMWord(ModRM,dst); break; - case 0x20: ANDW; PutbackRMWord(ModRM,dst); break; - case 0x28: SUBW; PutbackRMWord(ModRM,dst); break; - case 0x30: XORW; PutbackRMWord(ModRM,dst); break; - case 0x38: SUBW; break; /* CMP */ - } -} - -OP( 0x84, i_test_br8 ) { DEF_br8; ANDB; CLKM(1,2); } -OP( 0x85, i_test_wr16 ) { DEF_wr16; ANDW; CLKM(1,2); } -OP( 0x86, i_xchg_br8 ) { DEF_br8; RegByte(ModRM)=dst; PutbackRMByte(ModRM,src); CLKM(3,5); } -OP( 0x87, i_xchg_wr16 ) { DEF_wr16; RegWord(ModRM)=dst; PutbackRMWord(ModRM,src); CLKM(3,5); } - -OP( 0x88, i_mov_br8 ) { UINT8 src; GetModRM; src = RegByte(ModRM); PutRMByte(ModRM,src); CLK(1); } -OP( 0x89, i_mov_wr16 ) { UINT16 src; GetModRM; src = RegWord(ModRM); PutRMWord(ModRM,src); CLK(1); } -OP( 0x8a, i_mov_r8b ) { UINT8 src; GetModRM; src = GetRMByte(ModRM); RegByte(ModRM)=src; CLK(1); } -OP( 0x8b, i_mov_r16w ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); RegWord(ModRM)=src; CLK(1); } -OP( 0x8c, i_mov_wsreg ) { GetModRM; PutRMWord(ModRM,cpustate->sregs[(ModRM & 0x38) >> 3]); CLKM(1,3); } -OP( 0x8d, i_lea ) { UINT16 ModRM = FETCH; (void)(*GetEA[ModRM])(cpustate); RegWord(ModRM)=cpustate->eo; CLK(1); } -OP( 0x8e, i_mov_sregw ) { UINT16 src; GetModRM; src = GetRMWord(ModRM); CLKM(2,3); - switch (ModRM & 0x38) { - case 0x00: cpustate->sregs[ES] = src; break; /* mov es,ew */ - case 0x08: cpustate->sregs[CS] = src; break; /* mov cs,ew */ - case 0x10: cpustate->sregs[SS] = src; break; /* mov ss,ew */ - case 0x18: cpustate->sregs[DS] = src; break; /* mov ds,ew */ - default: logerror("%06x: Mov Sreg - Invalid register\n",PC(cpustate)); - } - cpustate->no_interrupt=1; -} -OP( 0x8f, i_popw ) { UINT16 tmp; GetModRM; POP(tmp); PutRMWord(ModRM,tmp); CLKM(1,3); } -OP( 0x90, i_nop ) { CLK(1); - /* Cycle skip for idle loops (0: NOP 1: JMP 0) */ - if (cpustate->no_interrupt==0 && cpustate->icount>0 && (cpustate->pending_irq==0) && (PEEKOP((cpustate->sregs[CS]<<4)+cpustate->ip))==0xeb && (PEEK((cpustate->sregs[CS]<<4)+cpustate->ip+1))==0xfd) - cpustate->icount%=15; -} -OP( 0x91, i_xchg_axcx ) { XchgAWReg(CW); CLK(3); } -OP( 0x92, i_xchg_axdx ) { XchgAWReg(DW); CLK(3); } -OP( 0x93, i_xchg_axbx ) { XchgAWReg(BW); CLK(3); } -OP( 0x94, i_xchg_axsp ) { XchgAWReg(SP); CLK(3); } -OP( 0x95, i_xchg_axbp ) { XchgAWReg(BP); CLK(3); } -OP( 0x96, i_xchg_axsi ) { XchgAWReg(IX); CLK(3); } -OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); } - -OP( 0x98, i_cbw ) { cpustate->regs.b[AH] = (cpustate->regs.b[AL] & 0x80) ? 0xff : 0; CLK(1); } -OP( 0x99, i_cwd ) { cpustate->regs.w[DW] = (cpustate->regs.b[AH] & 0x80) ? 0xffff : 0; CLK(1); } -OP( 0x9a, i_call_far ) { UINT32 tmp, tmp2; FETCHWORD(tmp); FETCHWORD(tmp2); PUSH(cpustate->sregs[CS]); PUSH(cpustate->ip); cpustate->ip = (UINT16)tmp; cpustate->sregs[CS] = (UINT16)tmp2; CLK(10); } -OP( 0x9b, i_wait ) { logerror("%06x: Hardware POLL\n",PC(cpustate)); } -OP( 0x9c, i_pushf ) { PUSH( CompressFlags() ); CLK(2); } -OP( 0x9d, i_popf ) { UINT32 tmp; POP(tmp); ExpandFlags(tmp); CLK(3); if (cpustate->TF) nec_trap(cpustate); } -OP( 0x9e, i_sahf ) { UINT32 tmp = (CompressFlags() & 0xff00) | (cpustate->regs.b[AH] & 0xd5); ExpandFlags(tmp); CLK(4); } -OP( 0x9f, i_lahf ) { cpustate->regs.b[AH] = CompressFlags() & 0xff; CLK(2); } - -OP( 0xa0, i_mov_aldisp ) { UINT32 addr; FETCHWORD(addr); cpustate->regs.b[AL] = GetMemB(DS, addr); CLK(1); } -OP( 0xa1, i_mov_axdisp ) { UINT32 addr; FETCHWORD(addr); cpustate->regs.b[AL] = GetMemB(DS, addr); cpustate->regs.b[AH] = GetMemB(DS, (addr+1)&0xffff); CLK(1); } -OP( 0xa2, i_mov_dispal ) { UINT32 addr; FETCHWORD(addr); PutMemB(DS, addr, cpustate->regs.b[AL]); CLK(1); } -OP( 0xa3, i_mov_dispax ) { UINT32 addr; FETCHWORD(addr); PutMemB(DS, addr, cpustate->regs.b[AL]); PutMemB(DS, (addr+1)&0xffff, cpustate->regs.b[AH]); CLK(1); } -OP( 0xa4, i_movsb ) { UINT32 tmp = GetMemB(DS,cpustate->regs.w[IX]); PutMemB(ES,cpustate->regs.w[IY], tmp); cpustate->regs.w[IY] += -2 * cpustate->DF + 1; cpustate->regs.w[IX] += -2 * cpustate->DF + 1; CLK(5); } -OP( 0xa5, i_movsw ) { UINT32 tmp = GetMemW(DS,cpustate->regs.w[IX]); PutMemW(ES,cpustate->regs.w[IY], tmp); cpustate->regs.w[IY] += -4 * cpustate->DF + 2; cpustate->regs.w[IX] += -4 * cpustate->DF + 2; CLK(5); } -OP( 0xa6, i_cmpsb ) { UINT32 src = GetMemB(ES, cpustate->regs.w[IY]); UINT32 dst = GetMemB(DS, cpustate->regs.w[IX]); SUBB; cpustate->regs.w[IY] += -2 * cpustate->DF + 1; cpustate->regs.w[IX] += -2 * cpustate->DF + 1; CLK(6); } -OP( 0xa7, i_cmpsw ) { UINT32 src = GetMemW(ES, cpustate->regs.w[IY]); UINT32 dst = GetMemW(DS, cpustate->regs.w[IX]); SUBW; cpustate->regs.w[IY] += -4 * cpustate->DF + 2; cpustate->regs.w[IX] += -4 * cpustate->DF + 2; CLK(6); } - -OP( 0xa8, i_test_ald8 ) { DEF_ald8; ANDB; CLK(1); } -OP( 0xa9, i_test_axd16 ) { DEF_axd16; ANDW; CLK(1); } -OP( 0xaa, i_stosb ) { PutMemB(ES,cpustate->regs.w[IY],cpustate->regs.b[AL]); cpustate->regs.w[IY] += -2 * cpustate->DF + 1; CLK(3); } -OP( 0xab, i_stosw ) { PutMemW(ES,cpustate->regs.w[IY],cpustate->regs.w[AW]); cpustate->regs.w[IY] += -4 * cpustate->DF + 2; CLK(3); } -OP( 0xac, i_lodsb ) { cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[IX]); cpustate->regs.w[IX] += -2 * cpustate->DF + 1; CLK(3); } -OP( 0xad, i_lodsw ) { cpustate->regs.w[AW] = GetMemW(DS,cpustate->regs.w[IX]); cpustate->regs.w[IX] += -4 * cpustate->DF + 2; CLK(3); } -OP( 0xae, i_scasb ) { UINT32 src = GetMemB(ES, cpustate->regs.w[IY]); UINT32 dst = cpustate->regs.b[AL]; SUBB; cpustate->regs.w[IY] += -2 * cpustate->DF + 1; CLK(4); } -OP( 0xaf, i_scasw ) { UINT32 src = GetMemW(ES, cpustate->regs.w[IY]); UINT32 dst = cpustate->regs.w[AW]; SUBW; cpustate->regs.w[IY] += -4 * cpustate->DF + 2; CLK(4); } - -OP( 0xb0, i_mov_ald8 ) { cpustate->regs.b[AL] = FETCH; CLK(1); } -OP( 0xb1, i_mov_cld8 ) { cpustate->regs.b[CL] = FETCH; CLK(1); } -OP( 0xb2, i_mov_dld8 ) { cpustate->regs.b[DL] = FETCH; CLK(1); } -OP( 0xb3, i_mov_bld8 ) { cpustate->regs.b[BL] = FETCH; CLK(1); } -OP( 0xb4, i_mov_ahd8 ) { cpustate->regs.b[AH] = FETCH; CLK(1); } -OP( 0xb5, i_mov_chd8 ) { cpustate->regs.b[CH] = FETCH; CLK(1); } -OP( 0xb6, i_mov_dhd8 ) { cpustate->regs.b[DH] = FETCH; CLK(1); } -OP( 0xb7, i_mov_bhd8 ) { cpustate->regs.b[BH] = FETCH; CLK(1); } - -OP( 0xb8, i_mov_axd16 ) { cpustate->regs.b[AL] = FETCH; cpustate->regs.b[AH] = FETCH; CLK(1); } -OP( 0xb9, i_mov_cxd16 ) { cpustate->regs.b[CL] = FETCH; cpustate->regs.b[CH] = FETCH; CLK(1); } -OP( 0xba, i_mov_dxd16 ) { cpustate->regs.b[DL] = FETCH; cpustate->regs.b[DH] = FETCH; CLK(1); } -OP( 0xbb, i_mov_bxd16 ) { cpustate->regs.b[BL] = FETCH; cpustate->regs.b[BH] = FETCH; CLK(1); } -OP( 0xbc, i_mov_spd16 ) { cpustate->regs.b[SPL] = FETCH; cpustate->regs.b[SPH] = FETCH; CLK(1); } -OP( 0xbd, i_mov_bpd16 ) { cpustate->regs.b[BPL] = FETCH; cpustate->regs.b[BPH] = FETCH; CLK(1); } -OP( 0xbe, i_mov_sid16 ) { cpustate->regs.b[IXL] = FETCH; cpustate->regs.b[IXH] = FETCH; CLK(1); } -OP( 0xbf, i_mov_did16 ) { cpustate->regs.b[IYL] = FETCH; cpustate->regs.b[IYH] = FETCH; CLK(1); } - -OP( 0xc0, i_rotshft_bd8 ) { - UINT32 src, dst; UINT8 c; - GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src; - c=FETCH; - CLKM(3,5); - if (c) switch (ModRM & 0x38) { - case 0x00: do { ROL_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x08: do { ROR_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x10: do { ROLC_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x18: do { RORC_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x20: SHL_BYTE(c); break; - case 0x28: SHR_BYTE(c); break; - case 0x30: logerror("%06x: Undefined opcode 0xc0 0x30 (SHLA)\n",PC(cpustate)); break; - case 0x38: SHRA_BYTE(c); break; - } -} - -OP( 0xc1, i_rotshft_wd8 ) { - UINT32 src, dst; UINT8 c; - GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src; - c=FETCH; - CLKM(3,5); - if (c) switch (ModRM & 0x38) { - case 0x00: do { ROL_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x08: do { ROR_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x10: do { ROLC_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x18: do { RORC_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x20: SHL_WORD(c); break; - case 0x28: SHR_WORD(c); break; - case 0x30: logerror("%06x: Undefined opcode 0xc1 0x30 (SHLA)\n",PC(cpustate)); break; - case 0x38: SHRA_WORD(c); break; - } -} - -OP( 0xc2, i_ret_d16 ) { UINT32 count = FETCH; count += FETCH << 8; POP(cpustate->ip); cpustate->regs.w[SP]+=count; CLK(6); } -OP( 0xc3, i_ret ) { POP(cpustate->ip); CLK(6); } -OP( 0xc4, i_les_dw ) { GetModRM; UINT16 tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; cpustate->sregs[ES] = GetnextRMWord; CLK(6); } -OP( 0xc5, i_lds_dw ) { GetModRM; UINT16 tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; cpustate->sregs[DS] = GetnextRMWord; CLK(6); } -OP( 0xc6, i_mov_bd8 ) { GetModRM; PutImmRMByte(ModRM); CLK(1); } -OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); CLK(1); } - -OP( 0xc8, i_enter ) { - UINT32 nb = FETCH; - UINT32 i,level; - - CLK(8); - nb += FETCH << 8; - level = FETCH; - PUSH(cpustate->regs.w[BP]); - cpustate->regs.w[BP]=cpustate->regs.w[SP]; - cpustate->regs.w[SP] -= nb; - for (i=1;iregs.w[BP]-i*2)); - CLK(4); - } - if (level) { PUSH(cpustate->regs.w[BP]); if (level==1) CLK(2) else CLK(3) } -} -OP( 0xc9, i_leave ) { - cpustate->regs.w[SP]=cpustate->regs.w[BP]; - POP(cpustate->regs.w[BP]); - CLK(2); -} -OP( 0xca, i_retf_d16 ) { UINT32 count = FETCH; count += FETCH << 8; POP(cpustate->ip); POP(cpustate->sregs[CS]); cpustate->regs.w[SP]+=count; CLK(9); } -OP( 0xcb, i_retf ) { POP(cpustate->ip); POP(cpustate->sregs[CS]); CLK(8); } -OP( 0xcc, i_int3 ) { nec_interrupt(cpustate,3); CLK(9); } -OP( 0xcd, i_int ) { nec_interrupt(cpustate,FETCH); CLK(10); } -OP( 0xce, i_into ) { if (OF) { nec_interrupt(cpustate,4); CLK(13); } else CLK(6); } -OP( 0xcf, i_iret ) { POP(cpustate->ip); POP(cpustate->sregs[CS]); i_popf(cpustate); CLK(10); } - -OP( 0xd0, i_rotshft_b ) { - UINT32 src, dst; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src; - CLKM(1,3); - switch (ModRM & 0x38) { - case 0x00: ROL_BYTE; PutbackRMByte(ModRM,(UINT8)dst); cpustate->OverVal = (src^dst)&0x80; break; - case 0x08: ROR_BYTE; PutbackRMByte(ModRM,(UINT8)dst); cpustate->OverVal = (src^dst)&0x80; break; - case 0x10: ROLC_BYTE; PutbackRMByte(ModRM,(UINT8)dst); cpustate->OverVal = (src^dst)&0x80; break; - case 0x18: RORC_BYTE; PutbackRMByte(ModRM,(UINT8)dst); cpustate->OverVal = (src^dst)&0x80; break; - case 0x20: SHL_BYTE(1); cpustate->OverVal = (src^dst)&0x80; break; - case 0x28: SHR_BYTE(1); cpustate->OverVal = (src^dst)&0x80; break; - case 0x30: logerror("%06x: Undefined opcode 0xd0 0x30 (SHLA)\n",PC(cpustate)); break; - case 0x38: SHRA_BYTE(1); cpustate->OverVal = 0; break; - } -} - -OP( 0xd1, i_rotshft_w ) { - UINT32 src, dst; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src; - CLKM(1,3); - switch (ModRM & 0x38) { - case 0x00: ROL_WORD; PutbackRMWord(ModRM,(UINT16)dst); cpustate->OverVal = (src^dst)&0x8000; break; - case 0x08: ROR_WORD; PutbackRMWord(ModRM,(UINT16)dst); cpustate->OverVal = (src^dst)&0x8000; break; - case 0x10: ROLC_WORD; PutbackRMWord(ModRM,(UINT16)dst); cpustate->OverVal = (src^dst)&0x8000; break; - case 0x18: RORC_WORD; PutbackRMWord(ModRM,(UINT16)dst); cpustate->OverVal = (src^dst)&0x8000; break; - case 0x20: SHL_WORD(1); cpustate->OverVal = (src^dst)&0x8000; break; - case 0x28: SHR_WORD(1); cpustate->OverVal = (src^dst)&0x8000; break; - case 0x30: logerror("%06x: Undefined opcode 0xd1 0x30 (SHLA)\n",PC(cpustate)); break; - case 0x38: SHRA_WORD(1); cpustate->OverVal = 0; break; - } -} - -OP( 0xd2, i_rotshft_bcl ) { - UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMByte(ModRM); dst=src; - c=cpustate->regs.b[CL]; - CLKM(3,5); - if (c) switch (ModRM & 0x38) { - case 0x00: do { ROL_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x08: do { ROR_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x10: do { ROLC_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x18: do { RORC_BYTE; c--; } while (c>0); PutbackRMByte(ModRM,(UINT8)dst); break; - case 0x20: SHL_BYTE(c); break; - case 0x28: SHR_BYTE(c); break; - case 0x30: logerror("%06x: Undefined opcode 0xd2 0x30 (SHLA)\n",PC(cpustate)); break; - case 0x38: SHRA_BYTE(c); break; - } -} - -OP( 0xd3, i_rotshft_wcl ) { - UINT32 src, dst; UINT8 c; GetModRM; src = (UINT32)GetRMWord(ModRM); dst=src; - c=cpustate->regs.b[CL]; - CLKM(3,5); - if (c) switch (ModRM & 0x38) { - case 0x00: do { ROL_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x08: do { ROR_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x10: do { ROLC_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x18: do { RORC_WORD; c--; } while (c>0); PutbackRMWord(ModRM,(UINT16)dst); break; - case 0x20: SHL_WORD(c); break; - case 0x28: SHR_WORD(c); break; - case 0x30: logerror("%06x: Undefined opcode 0xd3 0x30 (SHLA)\n",PC(cpustate)); break; - case 0x38: SHRA_WORD(c); break; - } -} - -OP( 0xd4, i_aam ) { FETCH; cpustate->regs.b[AH] = cpustate->regs.b[AL] / 10; cpustate->regs.b[AL] %= 10; SetSZPF_Word(cpustate->regs.w[AW]); CLK(17); } -OP( 0xd5, i_aad ) { FETCH; cpustate->regs.b[AL] = cpustate->regs.b[AH] * 10 + cpustate->regs.b[AL]; cpustate->regs.b[AH] = 0; SetSZPF_Byte(cpustate->regs.b[AL]); CLK(5); } -OP( 0xd6, i_setalc ) { cpustate->regs.b[AL] = (CF)?0xff:0x00; CLK(3); logerror("%06x: Undefined opcode (SETALC)\n",PC(cpustate)); } -OP( 0xd7, i_trans ) { UINT32 dest = (cpustate->regs.w[BW]+cpustate->regs.b[AL])&0xffff; cpustate->regs.b[AL] = GetMemB(DS, dest); CLK(5); } -OP( 0xd8, i_fpo ) { GetModRM; CLK(1); logerror("%06x: Unimplemented floating point control %04x\n",PC(cpustate),ModRM); } - -OP( 0xe0, i_loopne ) { INT8 disp = (INT8)FETCH; cpustate->regs.w[CW]--; if (!ZF && cpustate->regs.w[CW]) { cpustate->ip = (UINT16)(cpustate->ip+disp); CLK(6); } else CLK(3); } -OP( 0xe1, i_loope ) { INT8 disp = (INT8)FETCH; cpustate->regs.w[CW]--; if ( ZF && cpustate->regs.w[CW]) { cpustate->ip = (UINT16)(cpustate->ip+disp); CLK(6); } else CLK(3); } -OP( 0xe2, i_loop ) { INT8 disp = (INT8)FETCH; cpustate->regs.w[CW]--; if (cpustate->regs.w[CW]) { cpustate->ip = (UINT16)(cpustate->ip+disp); CLK(5); } else CLK(2); } -OP( 0xe3, i_jcxz ) { INT8 disp = (INT8)FETCH; if (cpustate->regs.w[CW] == 0) { cpustate->ip = (UINT16)(cpustate->ip+disp); CLK(4); } else CLK(1); } -OP( 0xe4, i_inal ) { UINT8 port = FETCH; cpustate->regs.b[AL] = read_port(port); CLK(6); } -OP( 0xe5, i_inax ) { UINT8 port = FETCH; cpustate->regs.b[AL] = read_port(port); cpustate->regs.b[AH] = read_port(port+1); CLK(6); } -OP( 0xe6, i_outal ) { UINT8 port = FETCH; write_port(port, cpustate->regs.b[AL]); CLK(6); } -OP( 0xe7, i_outax ) { UINT8 port = FETCH; write_port(port, cpustate->regs.b[AL]); write_port(port+1, cpustate->regs.b[AH]); CLK(6); } - -OP( 0xe8, i_call_d16 ) { UINT32 tmp; FETCHWORD(tmp); PUSH(cpustate->ip); cpustate->ip = (UINT16)(cpustate->ip+(INT16)tmp); CLK(5); } -OP( 0xe9, i_jmp_d16 ) { UINT32 tmp; FETCHWORD(tmp); cpustate->ip = (UINT16)(cpustate->ip+(INT16)tmp); CLK(4); } -OP( 0xea, i_jmp_far ) { UINT32 tmp,tmp1; FETCHWORD(tmp); FETCHWORD(tmp1); cpustate->sregs[CS] = (UINT16)tmp1; cpustate->ip = (UINT16)tmp; CLK(7); } -OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((INT8)FETCH); CLK(4); - if (tmp==-2 && cpustate->no_interrupt==0 && (cpustate->pending_irq==0) && cpustate->icount>0) cpustate->icount%=12; /* cycle skip */ - cpustate->ip = (UINT16)(cpustate->ip+tmp); -} -OP( 0xec, i_inaldx ) { cpustate->regs.b[AL] = read_port(cpustate->regs.w[DW]); CLK(6);} -OP( 0xed, i_inaxdx ) { UINT32 port = cpustate->regs.w[DW]; cpustate->regs.b[AL] = read_port(port); cpustate->regs.b[AH] = read_port(port+1); CLK(6); } -OP( 0xee, i_outdxal ) { write_port(cpustate->regs.w[DW], cpustate->regs.b[AL]); CLK(6); } -OP( 0xef, i_outdxax ) { UINT32 port = cpustate->regs.w[DW]; write_port(port, cpustate->regs.b[AL]); write_port(port+1, cpustate->regs.b[AH]); CLK(6); } - -OP( 0xf0, i_lock ) { logerror("%06x: Warning - BUSLOCK\n",PC(cpustate)); cpustate->no_interrupt=1; CLK(1); } -OP( 0xf2, i_repne ) { UINT32 next = FETCHOP; UINT16 c = cpustate->regs.w[CW]; - switch(next) { /* Segments */ - case 0x26: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[ES]<<4; next = FETCHOP; CLK(2); break; - case 0x2e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[CS]<<4; next = FETCHOP; CLK(2); break; - case 0x36: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[SS]<<4; next = FETCHOP; CLK(2); break; - case 0x3e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[DS]<<4; next = FETCHOP; CLK(2); break; - } - - switch(next) { - case 0x6c: CLK(3); if (c) do { i_insb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0x6d: CLK(3); if (c) do { i_insw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0x6e: CLK(3); if (c) do { i_outsb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0x6f: CLK(3); if (c) do { i_outsw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xa4: CLK(3); if (c) do { i_movsb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xa5: CLK(3); if (c) do { i_movsw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xa6: CLK(3); if (c) do { i_cmpsb(cpustate); c--; } while (c>0 && ZF==0); cpustate->regs.w[CW]=c; break; - case 0xa7: CLK(3); if (c) do { i_cmpsw(cpustate); c--; } while (c>0 && ZF==0); cpustate->regs.w[CW]=c; break; - case 0xaa: CLK(3); if (c) do { i_stosb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xab: CLK(3); if (c) do { i_stosw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xac: CLK(3); if (c) do { i_lodsb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xad: CLK(3); if (c) do { i_lodsw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xae: CLK(3); if (c) do { i_scasb(cpustate); c--; } while (c>0 && ZF==0); cpustate->regs.w[CW]=c; break; - case 0xaf: CLK(3); if (c) do { i_scasw(cpustate); c--; } while (c>0 && ZF==0); cpustate->regs.w[CW]=c; break; - default: logerror("%06x: REPNE invalid\n",PC(cpustate)); nec_instruction[next](cpustate); - } - cpustate->seg_prefix=FALSE; -} -OP( 0xf3, i_repe ) { UINT32 next = FETCHOP; UINT16 c = cpustate->regs.w[CW]; - switch(next) { /* Segments */ - case 0x26: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[ES]<<4; next = FETCHOP; CLK(2); break; - case 0x2e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[CS]<<4; next = FETCHOP; CLK(2); break; - case 0x36: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[SS]<<4; next = FETCHOP; CLK(2); break; - case 0x3e: cpustate->seg_prefix=TRUE; cpustate->prefix_base=cpustate->sregs[DS]<<4; next = FETCHOP; CLK(2); break; - } - - switch(next) { - case 0x6c: CLK(3); if (c) do { i_insb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0x6d: CLK(3); if (c) do { i_insw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0x6e: CLK(3); if (c) do { i_outsb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0x6f: CLK(3); if (c) do { i_outsw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xa4: CLK(3); if (c) do { i_movsb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xa5: CLK(3); if (c) do { i_movsw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xa6: CLK(3); if (c) do { i_cmpsb(cpustate); c--; } while (c>0 && ZF==1); cpustate->regs.w[CW]=c; break; - case 0xa7: CLK(3); if (c) do { i_cmpsw(cpustate); c--; } while (c>0 && ZF==1); cpustate->regs.w[CW]=c; break; - case 0xaa: CLK(3); if (c) do { i_stosb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xab: CLK(3); if (c) do { i_stosw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xac: CLK(3); if (c) do { i_lodsb(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xad: CLK(3); if (c) do { i_lodsw(cpustate); c--; } while (c>0); cpustate->regs.w[CW]=c; break; - case 0xae: CLK(3); if (c) do { i_scasb(cpustate); c--; } while (c>0 && ZF==1); cpustate->regs.w[CW]=c; break; - case 0xaf: CLK(3); if (c) do { i_scasw(cpustate); c--; } while (c>0 && ZF==1); cpustate->regs.w[CW]=c; break; - default: logerror("%06x: REPE invalid\n",PC(cpustate)); nec_instruction[next](cpustate); - } - cpustate->seg_prefix=FALSE; -} -OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC(cpustate)); cpustate->icount=0; } -OP( 0xf5, i_cmc ) { cpustate->CarryVal = !CF; CLK(4); } -OP( 0xf6, i_f6pre ) { UINT32 tmp; UINT32 uresult,uresult2; INT32 result,result2; - GetModRM; tmp = GetRMByte(ModRM); - switch (ModRM & 0x38) { - case 0x00: tmp &= FETCH; cpustate->CarryVal = cpustate->OverVal = 0; SetSZPF_Byte(tmp); CLKM(1,2); break; /* TEST */ - case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC(cpustate)); break; - case 0x10: PutbackRMByte(ModRM,~tmp); CLKM(1,3); break; /* NOT */ - case 0x18: cpustate->CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); CLKM(1,3); break; /* NEG */ - case 0x20: uresult = cpustate->regs.b[AL]*tmp; cpustate->regs.w[AW]=(UINT16)uresult; cpustate->CarryVal=cpustate->OverVal=(cpustate->regs.b[AH]!=0); CLKM(3,4); break; /* MULU */ - case 0x28: result = (INT16)((INT8)cpustate->regs.b[AL])*(INT16)((INT8)tmp); cpustate->regs.w[AW]=(UINT16)result; cpustate->CarryVal=cpustate->OverVal=(cpustate->regs.b[AH]!=0); CLKM(3,4); break; /* MUL */ - case 0x30: if (tmp) { DIVUB; } else nec_interrupt(cpustate,0); CLKM(15,16); break; - case 0x38: if (tmp) { DIVB; } else nec_interrupt(cpustate,0); CLKM(17,18); break; - } -} - -OP( 0xf7, i_f7pre ) { UINT32 tmp,tmp2; UINT32 uresult,uresult2; INT32 result,result2; - GetModRM; tmp = GetRMWord(ModRM); - switch (ModRM & 0x38) { - case 0x00: FETCHWORD(tmp2); tmp &= tmp2; cpustate->CarryVal = cpustate->OverVal = 0; SetSZPF_Word(tmp); CLKM(1,2); break; /* TEST */ - case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC(cpustate)); break; - case 0x10: PutbackRMWord(ModRM,~tmp); CLKM(1,3); break; /* NOT */ - case 0x18: cpustate->CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); CLKM(1,3); break; /* NEG */ - case 0x20: uresult = cpustate->regs.w[AW]*tmp; cpustate->regs.w[AW]=uresult&0xffff; cpustate->regs.w[DW]=((UINT32)uresult)>>16; cpustate->CarryVal=cpustate->OverVal=(cpustate->regs.w[DW]!=0); CLKM(3,4); break; /* MULU */ - case 0x28: result = (INT32)((INT16)cpustate->regs.w[AW])*(INT32)((INT16)tmp); cpustate->regs.w[AW]=result&0xffff; cpustate->regs.w[DW]=result>>16; cpustate->CarryVal=cpustate->OverVal=(cpustate->regs.w[DW]!=0); CLKM(3,4); break; /* MUL */ - case 0x30: if (tmp) { DIVUW; } else nec_interrupt(cpustate,0); CLKM(23,24); break; - case 0x38: if (tmp) { DIVW; } else nec_interrupt(cpustate,0); CLKM(24,25); break; - } -} - -OP( 0xf8, i_clc ) { cpustate->CarryVal = 0; CLK(4); } -OP( 0xf9, i_stc ) { cpustate->CarryVal = 1; CLK(4); } -OP( 0xfa, i_di ) { SetIF(0); CLK(4); } -OP( 0xfb, i_ei ) { SetIF(1); CLK(4); } -OP( 0xfc, i_cld ) { SetDF(0); CLK(4); } -OP( 0xfd, i_std ) { SetDF(1); CLK(4); } -OP( 0xfe, i_fepre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMByte(ModRM); - switch(ModRM & 0x38) { - case 0x00: tmp1 = tmp+1; cpustate->OverVal = (tmp==0x7f); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(UINT8)tmp1); CLKM(1,3); break; /* INC */ - case 0x08: tmp1 = tmp-1; cpustate->OverVal = (tmp==0x80); SetAF(tmp1,tmp,1); SetSZPF_Byte(tmp1); PutbackRMByte(ModRM,(UINT8)tmp1); CLKM(1,3); break; /* DEC */ - default: logerror("%06x: FE Pre with unimplemented mod\n",PC(cpustate)); - } -} -OP( 0xff, i_ffpre ) { UINT32 tmp, tmp1; GetModRM; tmp=GetRMWord(ModRM); - switch(ModRM & 0x38) { - case 0x00: tmp1 = tmp+1; cpustate->OverVal = (tmp==0x7fff); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(UINT16)tmp1); CLKM(1,3); break; /* INC */ - case 0x08: tmp1 = tmp-1; cpustate->OverVal = (tmp==0x8000); SetAF(tmp1,tmp,1); SetSZPF_Word(tmp1); PutbackRMWord(ModRM,(UINT16)tmp1); CLKM(1,3); break; /* DEC */ - case 0x10: PUSH(cpustate->ip); cpustate->ip = (UINT16)tmp; CLKM(5,6); break; /* CALL */ - case 0x18: tmp1 = cpustate->sregs[CS]; cpustate->sregs[CS] = GetnextRMWord; PUSH(tmp1); PUSH(cpustate->ip); cpustate->ip = tmp; CLKM(5,12); break; /* CALL FAR */ - case 0x20: cpustate->ip = tmp; CLKM(4,5); break; /* JMP */ - case 0x28: cpustate->ip = tmp; cpustate->sregs[CS] = GetnextRMWord; CLK(10); break; /* JMP FAR */ - case 0x30: PUSH(tmp); CLK(1); break; - default: logerror("%06x: FF Pre with unimplemented mod\n",PC(cpustate)); - } -} - -static void i_invalid(v30mz_state *cpustate) -{ - cpustate->icount-=10; - logerror("%06x: Invalid Opcode\n",PC(cpustate)); -} - -/*****************************************************************************/ - -static void set_irq_line(v30mz_state *cpustate, int irqline, int state) -{ - if (irqline == INPUT_LINE_NMI) - { - if( cpustate->nmi_state == state ) return; - cpustate->nmi_state = state; + if ( m_nmi_state == state ) + { + return; + } + m_nmi_state = state; if (state != CLEAR_LINE) { - cpustate->pending_irq |= NMI_IRQ; + m_pending_irq |= NMI_IRQ; } } else { - cpustate->irq_state = state; + m_irq_state = state; if (state == CLEAR_LINE) { - // if (!cpustate->IF) NS010718 fix interrupt request loss - cpustate->pending_irq &= ~INT_IRQ; + m_pending_irq &= ~INT_IRQ; } else { - // if (cpustate->IF) NS010718 fix interrupt request loss - cpustate->pending_irq |= INT_IRQ; + m_pending_irq |= INT_IRQ; } } } -static CPU_DISASSEMBLE( nec ) + +offs_t v30mz_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { + extern int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, const nec_config *config); + return necv_dasm_one(buffer, pc, oprom, NULL); } -static void nec_init(legacy_cpu_device *device, device_irq_acknowledge_callback irqcallback, int type) + +void v30mz_cpu_device::execute_run() { - v30mz_state *cpustate = get_safe_token(device); - - device->save_item(NAME(cpustate->regs.w)); - device->save_item(NAME(cpustate->sregs)); - - device->save_item(NAME(cpustate->ip)); - device->save_item(NAME(cpustate->TF)); - device->save_item(NAME(cpustate->IF)); - device->save_item(NAME(cpustate->DF)); - device->save_item(NAME(cpustate->MF)); - device->save_item(NAME(cpustate->SignVal)); - device->save_item(NAME(cpustate->int_vector)); - device->save_item(NAME(cpustate->pending_irq)); - device->save_item(NAME(cpustate->nmi_state)); - device->save_item(NAME(cpustate->irq_state)); - device->save_item(NAME(cpustate->AuxVal)); - device->save_item(NAME(cpustate->OverVal)); - device->save_item(NAME(cpustate->ZeroVal)); - device->save_item(NAME(cpustate->CarryVal)); - device->save_item(NAME(cpustate->ParityVal)); - - cpustate->irq_callback = irqcallback; - cpustate->device = device; - cpustate->program = device->space(AS_PROGRAM); - cpustate->io = device->space(AS_IO); -} - -static CPU_INIT( v30mz ) { nec_init(device, irqcallback, 3); } -static CPU_EXECUTE( v30mz ) -{ - v30mz_state *cpustate = get_safe_token(device); - - while(cpustate->icount>0) { - /* Dispatch IRQ */ - if (cpustate->pending_irq && cpustate->no_interrupt==0) + while(m_icount > 0 ) + { + if ( m_seg_prefix_next ) { - if (cpustate->pending_irq & NMI_IRQ) - external_int(cpustate); - else if (cpustate->IF) - external_int(cpustate); + m_seg_prefix = true; + m_seg_prefix_next = false; + } + else + { + m_seg_prefix = false; + + /* Dispatch IRQ */ + if ( m_pending_irq && m_no_interrupt == 0 ) + { + if ( m_pending_irq & NMI_IRQ ) + { + interrupt(NEC_NMI_INT_VECTOR); + m_pending_irq &= ~NMI_IRQ; + } + else if ( m_IF ) + { + /* the actual vector is retrieved after pushing flags */ + /* and clearing the IF */ + interrupt(-1); + } + } + + /* No interrupt allowed between last instruction and this one */ + if ( m_no_interrupt ) + { + m_no_interrupt--; + } + + /* trap should allow one instruction to be executed */ + if ( m_fire_trap ) + { + if ( m_fire_trap >= 2 ) + { + interrupt(1); + m_fire_trap = 0; + } + else + { + m_fire_trap++; + } + } } - /* No interrupt allowed between last instruction and this one */ - if (cpustate->no_interrupt) - cpustate->no_interrupt--; + debugger_instruction_hook( this, pc() ); - debugger_instruction_hook(device, (cpustate->sregs[CS]<<4) + cpustate->ip); - nec_instruction[FETCHOP](cpustate); - } -} + UINT8 op = fetch_op(); + + switch(op) + { + case 0x00: // i_add_br8 + DEF_br8(); + ADDB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; + + case 0x01: // i_add_wr16 + DEF_wr16(); + ADDW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; + + case 0x02: // i_add_r8b + DEF_r8b(); + ADDB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x03: // i_add_r16w + DEF_r16w(); + ADDW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x04: // i_add_ald8 + DEF_ald8(); + ADDB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x05: // i_add_axd16 + DEF_axd16(); + ADDW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x06: // i_push_es + PUSH(m_sregs[ES]); + CLK(2); + break; + + case 0x07: // i_pop_es + m_sregs[ES] = POP(); + CLK(3); + break; + + case 0x08: // i_or_br8 + DEF_br8(); + ORB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; + + case 0x09: // i_or_wr16 + DEF_wr16(); + ORW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; + + case 0x0a: // i_or_r8b + DEF_r8b(); + ORB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x0b: // i_or_r16w + DEF_r16w(); + ORW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x0c: // i_or_ald8 + DEF_ald8(); + ORB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x0d: // i_or_axd16 + DEF_axd16(); + ORW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x0e: // i_push_cs + PUSH(m_sregs[CS]); + CLK(2); + break; + + case 0x0f: // i_pre_nec + { + UINT32 tmp, tmp2; + + switch ( fetch() ) + { + case 0x10: /* Test */ + m_modrm = fetch(); + tmp = GetRMByte(); + tmp2 = m_regs.b[CL] & 0x7; + m_ZeroVal = (tmp & (1<>4)*10 + (tmp&0xf); + int v2 = (tmp2>>4)*10 + (tmp2&0xf); + int result = v1 + v2 + m_CarryVal; + m_CarryVal = result > 99 ? 1 : 0; + result = result % 100; + v1 = ((result/10)<<4) | (result % 10); + PutMemB(ES, di,v1); + if (v1) + { + m_ZeroVal = 1; + } + si++; + di++; + } + } + break; + case 0x22: + { + int count = (m_regs.b[CL]+1)/2; + UINT16 di = m_regs.w[IY]; + UINT16 si = m_regs.w[IX]; + if (m_seg_prefix) + { + logerror("%s: %06x: Warning: seg_prefix defined for sub4s\n", tag(), pc()); + } + m_ZeroVal = m_CarryVal = 0; + for (int i=0; i>4)*10 + (tmp&0xf); + int v2 = (tmp2>>4)*10 + (tmp2&0xf); + if (v1 < (v2+m_CarryVal)) + { + v1+=100; + result = v1-(v2+m_CarryVal); + m_CarryVal = 1; + } + else + { + result = v1-(v2+m_CarryVal); + m_CarryVal = 0; + } + v1 = ((result/10)<<4) | (result % 10); + PutMemB(ES, di,v1); + if (v1) + { + m_ZeroVal = 1; + } + si++; + di++; + } + } + break; + case 0x26: + { + int count = (m_regs.b[CL]+1)/2; + UINT16 di = m_regs.w[IY]; + UINT16 si = m_regs.w[IX]; + if (m_seg_prefix) + { + logerror("%s: %06x: Warning: seg_prefix defined for cmp4s\n", tag(), pc()); + } + m_ZeroVal = m_CarryVal = 0; + for (int i=0; i>4)*10 + (tmp&0xf); + int v2 = (tmp2>>4)*10 + (tmp2&0xf); + if (v1 < (v2+m_CarryVal)) + { + v1+=100; + result = v1-(v2+m_CarryVal); + m_CarryVal = 1; + } + else + { + result = v1-(v2+m_CarryVal); + m_CarryVal = 0; + } + v1 = ((result/10)<<4) | (result % 10); + if (v1) + { + m_ZeroVal = 1; + } + si++; + di++; + } + } + break; + case 0x28: + m_modrm = fetch(); + tmp = GetRMByte(); + tmp <<= 4; + tmp |= m_regs.b[AL] & 0xf; + m_regs.b[AL] = (m_regs.b[AL] & 0xf0) | ((tmp>>8)&0xf); + tmp &= 0xff; + PutbackRMByte(tmp); + CLKM(9,15); + break; + case 0x2a: + m_modrm = fetch(); + tmp = GetRMByte(); + tmp2 = (m_regs.b[AL] & 0xf)<<4; + m_regs.b[AL] = (m_regs.b[AL] & 0xf0) | (tmp&0xf); + tmp = tmp2 | (tmp>>4); + PutbackRMByte(tmp); + CLKM(13,19); + break; + case 0x31: + m_modrm = fetch(); m_modrm = 0; logerror("%s: %06x: Unimplemented bitfield INS\n", tag(), pc()); break; + case 0x33: + m_modrm = fetch(); m_modrm = 0; logerror("%s: %06x: Unimplemented bitfield EXT\n", tag(), pc()); break; + case 0x92: /* V25/35 FINT */ + CLK(2); + break; + case 0xe0: + m_modrm = fetch(); + m_modrm = 0; + logerror("%s: %06x: V33 unimplemented BRKXA (break to expansion address)\n", tag(), pc()); + break; + case 0xf0: + m_modrm = fetch(); + m_modrm = 0; + logerror("%s: %06x: V33 unimplemented RETXA (return from expansion address)\n", tag(), pc()); + break; + case 0xff: + m_modrm = fetch(); + m_modrm = 0; + logerror("%s: %06x: unimplemented BRKEM (break to 8080 emulation mode)\n", tag(), pc()); + break; + default: + logerror("%s: %06x: Unknown V20 instruction\n", tag(), pc()); + break; + } + } + break; -/************************************************************************** - * Generic set_info - **************************************************************************/ + case 0x10: // i_adc_br8 + DEF_br8(); + m_src += CF ? 1 : 0; + ADDB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; -static CPU_SET_INFO( nec ) -{ - v30mz_state *cpustate = get_safe_token(device); - switch (state) - { - /* --- the following bits of info are set as 64-bit signed integers --- */ - case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(cpustate, 0, info->i); break; - case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break; + case 0x11: // i_adc_wr16 + DEF_wr16(); + m_src += CF ? 1 : 0; + ADDW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; - case CPUINFO_INT_PC: - case CPUINFO_INT_REGISTER + NEC_PC: - if( info->i - (cpustate->sregs[CS]<<4) < 0x10000 ) - { - cpustate->ip = info->i - (cpustate->sregs[CS]<<4); - } - else - { - cpustate->sregs[CS] = info->i >> 4; - cpustate->ip = info->i & 0x0000f; - } + case 0x12: // i_adc_r8b + DEF_r8b(); + m_src += CF ? 1 : 0; + ADDB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x13: // i_adc_r16w + DEF_r16w(); + m_src += CF ? 1 : 0; + ADDW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x14: // i_adc_ald8 + DEF_ald8(); + m_src += CF ? 1 : 0; + ADDB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x15: // i_adc_axd16 + DEF_axd16(); + m_src += CF ? 1 : 0; + ADDW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x16: // i_push_ss + PUSH(m_sregs[SS]); + CLK(2); + break; + + case 0x17: // i_pop_ss + m_sregs[SS] = POP(); + CLK(3); + m_no_interrupt = 1; + break; + + + case 0x18: // i_sbb_br8 + DEF_br8(); + m_src += CF ? 1 : 0; + SUBB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; + + case 0x19: // i_sbb_wr16 + DEF_wr16(); + m_src += CF ? 1 : 0; + SUBW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; + + case 0x1a: // i_sbb_r8b + DEF_r8b(); + m_src += CF ? 1 : 0; + SUBB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x1b: // i_sbb_r16w + DEF_r16w(); + m_src += CF ? 1 : 0; + SUBW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x1c: // i_sbb_ald8 + DEF_ald8(); + m_src += CF ? 1 : 0; + SUBB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x1d: // i_sbb_axd16 + DEF_axd16(); + m_src += CF ? 1 : 0; + SUBW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x1e: // i_push_ds + PUSH(m_sregs[DS]); + CLK(2); + break; + + case 0x1f: // i_pop_ds + m_sregs[DS] = POP(); + CLK(3); + break; + + + case 0x20: // i_and_br8 + DEF_br8(); + ANDB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; + + case 0x21: // i_and_wr16 + DEF_wr16(); + ANDW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; + + case 0x22: // i_and_r8b + DEF_r8b(); + ANDB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x23: // i_and_r16w + DEF_r16w(); + ANDW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x24: // i_and_ald8 + DEF_ald8(); + ANDB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x25: // i_and_axd16 + DEF_axd16(); + ANDW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x26: // i_es + m_seg_prefix_next = true; + m_prefix_base = m_sregs[ES]<<4; + CLK(1); + break; + + case 0x27: // i_daa + ADJ4(6,0x60); + CLK(10); + break; + + + case 0x28: // i_sub_br8 + DEF_br8(); + SUBB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; + + case 0x29: // i_sub_wr16 + DEF_wr16(); + SUBW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; + + case 0x2a: // i_sub_r8b + DEF_r8b(); + SUBB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x2b: // i_sub_r16w + DEF_r16w(); + SUBW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x2c: // i_sub_ald8 + DEF_ald8(); + SUBB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x2d: // i_sub_axd16 + DEF_axd16(); + SUBW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x2e: // i_cs + m_seg_prefix_next = true; + m_prefix_base = m_sregs[CS]<<4; + CLK(1); + break; + + case 0x2f: // i_das + ADJ4(-6,-0x60); + CLK(10); + break; + + + case 0x30: // i_xor_br8 + DEF_br8(); + XORB(); + PutbackRMByte(m_dst); + CLKM(1,3); + break; + + case 0x31: // i_xor_wr16 + DEF_wr16(); + XORW(); + PutbackRMWord(m_dst); + CLKM(1,3); + break; + + case 0x32: // i_xor_r8b + DEF_r8b(); + XORB(); + RegByte(m_dst); + CLKM(1,2); + break; + + case 0x33: // i_xor_r16w + DEF_r16w(); + XORW(); + RegWord(m_dst); + CLKM(1,2); + break; + + case 0x34: // i_xor_ald8 + DEF_ald8(); + XORB(); + m_regs.b[AL] = m_dst; + CLK(1); + break; + + case 0x35: // i_xor_axd16 + DEF_axd16(); + XORW(); + m_regs.w[AW] = m_dst; + CLK(1); + break; + + case 0x36: // i_ss + m_seg_prefix_next = true; + m_prefix_base = m_sregs[SS]<<4; + CLK(1); + break; + + case 0x37: // i_aaa + ADJB(6, (m_regs.b[AL] > 0xf9) ? 2 : 1); + CLK(9); + break; + + + case 0x38: // i_cmp_br8 + DEF_br8(); + SUBB(); + CLKM(1,2); + break; + + case 0x39: // i_cmp_wr16 + DEF_wr16(); + SUBW(); + CLKM(1,2); + break; + + case 0x3a: // i_cmp_r8b + DEF_r8b(); + SUBB(); + CLKM(1,2); + break; + + case 0x3b: // i_cmp_r16w + DEF_r16w(); + SUBW(); + CLKM(1,2); + break; + + case 0x3c: // i_cmp_ald8 + DEF_ald8(); + SUBB(); + CLK(1); + break; + + case 0x3d: // i_cmp_axd16 + DEF_axd16(); + SUBW(); + CLK(1); + break; + + case 0x3e: // i_ds + m_seg_prefix_next = true; + m_prefix_base = m_sregs[DS]<<4; + CLK(1); + break; + + case 0x3f: // i_aas + ADJB(-6, (m_regs.b[AL] < 6) ? -2 : -1); + CLK(9); + break; + + + case 0x40: // i_inc_ax + IncWordReg(AW); + CLK(1); + break; + + case 0x41: // i_inc_cx + IncWordReg(CW); + CLK(1); + break; + + case 0x42: // i_inc_dx + IncWordReg(DW); + CLK(1); + break; + + case 0x43: // i_inc_bx + IncWordReg(BW); + CLK(1); + break; + + case 0x44: // i_inc_sp + IncWordReg(SP); + CLK(1); + break; + + case 0x45: // i_inc_bp + IncWordReg(BP); + CLK(1); + break; + + case 0x46: // i_inc_si + IncWordReg(IX); + CLK(1); + break; + + case 0x47: // i_inc_di + IncWordReg(IY); + CLK(1); + break; + + + case 0x48: // i_dec_ax + DecWordReg(AW); + CLK(1); + break; + + case 0x49: // i_dec_cx + DecWordReg(CW); + CLK(1); + break; + + case 0x4a: // i_dec_dx + DecWordReg(DW); + CLK(1); + break; + + case 0x4b: // i_dec_bx + DecWordReg(BW); + CLK(1); + break; + + case 0x4c: // i_dec_sp + DecWordReg(SP); + CLK(1); + break; + + case 0x4d: // i_dec_bp + DecWordReg(BP); + CLK(1); + break; + + case 0x4e: // i_dec_si + DecWordReg(IX); + CLK(1); + break; + + case 0x4f: // i_dec_di + DecWordReg(IY); + CLK(1); + break; + + + case 0x50: // i_push_ax + PUSH(m_regs.w[AW]); + CLK(1); + break; + + case 0x51: // i_push_cx + PUSH(m_regs.w[CW]); + CLK(1); + break; + + case 0x52: // i_push_dx + PUSH(m_regs.w[DW]); + CLK(1); + break; + + case 0x53: // i_push_bx + PUSH(m_regs.w[BW]); + CLK(1); + break; + + case 0x54: // i_push_sp + PUSH(m_regs.w[SP]); + CLK(1); + break; + + case 0x55: // i_push_bp + PUSH(m_regs.w[BP]); + CLK(1); + break; + + case 0x56: // i_push_si + PUSH(m_regs.w[IX]); + CLK(1); + break; + + case 0x57: // i_push_di + PUSH(m_regs.w[IY]); + CLK(1); + break; + + + case 0x58: // i_pop_ax + m_regs.w[AW] = POP(); + CLK(1); + break; + + case 0x59: // i_pop_cx + m_regs.w[CW] = POP(); + CLK(1); + break; + + case 0x5a: // i_pop_dx + m_regs.w[DW] = POP(); + CLK(1); + break; + + case 0x5b: // i_pop_bx + m_regs.w[BW] = POP(); + CLK(1); + break; + + case 0x5c: // i_pop_sp + m_regs.w[SP] = POP(); + CLK(1); + break; + + case 0x5d: // i_pop_bp + m_regs.w[BP] = POP(); + CLK(1); + break; + + case 0x5e: // i_pop_si + m_regs.w[IX] = POP(); + CLK(1); + break; + + case 0x5f: // i_pop_di + m_regs.w[IY] = POP(); + CLK(1); + break; + + + case 0x60: // i_pusha + { + UINT32 tmp = m_regs.w[SP]; + + PUSH(m_regs.w[AW]); + PUSH(m_regs.w[CW]); + PUSH(m_regs.w[DW]); + PUSH(m_regs.w[BW]); + PUSH(tmp); + PUSH(m_regs.w[BP]); + PUSH(m_regs.w[IX]); + PUSH(m_regs.w[IY]); + CLK(9); + } + break; + + case 0x61: // i_popa + m_regs.w[IY] = POP(); + m_regs.w[IX] = POP(); + m_regs.w[BP] = POP(); + POP(); + m_regs.w[BW] = POP(); + m_regs.w[DW] = POP(); + m_regs.w[CW] = POP(); + m_regs.w[AW] = POP(); + CLK(8); + break; + + case 0x62: // i_chkind + { + UINT32 low,high,tmp; + m_modrm = fetch(); + low = GetRMWord(); + high = GetnextRMWord(); + tmp = RegWord(); + if (tmphigh) + { + interrupt(5); + CLK(20); + } + else + { + CLK(13); + } + logerror("%s: %06x: bound %04x high %04x low %04x tmp\n", tag(), pc(), high, low, tmp); + } + break; + + case 0x64: // i_repnc + { + UINT8 next = repx_op(); + UINT16 c = m_regs.w[CW]; + + switch (next) + { + case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + default: + logerror("%s: %06x: REPNC invalid\n", tag(), pc() ); + // Decrement IP so the normal instruction will be executed next + m_ip--; + break; + } + } + break; + + + case 0x65: // i_repc + { + UINT8 next = repx_op(); + UINT16 c = m_regs.w[CW]; + + switch (next) + { + case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + default: + logerror("%s: %06x: REPC invalid\n", tag(), pc()); + // Decrement IP so the normal instruction will be executed next + m_ip--; + break; + } + } + break; + + + case 0x68: // i_push_d16 + PUSH( fetch_word() ); + CLK(1); + break; + + case 0x69: // i_imul_d16 + { + UINT32 tmp; + DEF_r16w(); + tmp = fetch_word(); + m_dst = (INT32)((INT16)m_src)*(INT32)((INT16)tmp); + m_CarryVal = m_OverVal = (((INT32)m_dst) >> 15 != 0) && (((INT32)m_dst) >> 15 != -1); + RegWord(m_dst); + CLKM(3,4); + } + break; + + case 0x6a: // i_push_d8 + PUSH( (UINT16)((INT16)((INT8)fetch())) ); + CLK(1); + break; + + case 0x6b: // i_imul_d8 + { + UINT32 src2; + DEF_r16w(); + src2= (UINT16)((INT16)((INT8)fetch())); + m_dst = (INT32)((INT16)m_src)*(INT32)((INT16)src2); + m_CarryVal = m_OverVal = (((INT32)m_dst) >> 15 != 0) && (((INT32)m_dst) >> 15 != -1); + RegWord(m_dst); + CLKM(3,4); + } + break; + + case 0x6c: // i_insb + i_insb(); + break; + + case 0x6d: // i_insw + i_insw(); + break; + + case 0x6e: // i_outsb + i_outsb(); + break; + + case 0x6f: // i_outsw + i_outsw(); + break; + + + case 0x70: // i_jo + JMP( OF); + break; + + case 0x71: // i_jno + JMP(!OF); + break; + + case 0x72: // i_jc + JMP( CF); + break; + + case 0x73: // i_jnc + JMP(!CF); + break; + + case 0x74: // i_jz + JMP( ZF); + break; + + case 0x75: // i_jnz + JMP(!ZF); + break; + + case 0x76: // i_jce + JMP(CF || ZF); + break; + + case 0x77: // i_jnce + JMP(!(CF || ZF)); + break; + + case 0x78: // i_js + JMP( SF); + break; + + case 0x79: // i_jns + JMP(!SF); + break; + + case 0x7a: // i_jp + JMP( PF); + break; + + case 0x7b: // i_jnp + JMP(!PF); + break; + + case 0x7c: // i_jl + JMP((SF!=OF)&&(!ZF)); + break; + + case 0x7d: // i_jnl + JMP((ZF)||(SF==OF)); + break; + + case 0x7e: // i_jle + JMP((ZF)||(SF!=OF)); + break; + + case 0x7f: // i_jnle + JMP((SF==OF)&&(!ZF)); + break; + + + case 0x80: // i_80pre + m_modrm = fetch(); + m_dst = GetRMByte(); + m_src = fetch(); + if (m_modrm >=0xc0 ) { CLK(1); } + else if ((m_modrm & 0x38)==0x38) { CLK(2); } + else { CLK(3); } + switch (m_modrm & 0x38) + { + case 0x00: ADDB(); PutbackRMByte(m_dst); break; + case 0x08: ORB(); PutbackRMByte(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; ADDB(); PutbackRMByte(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; SUBB(); PutbackRMByte(m_dst); break; + case 0x20: ANDB(); PutbackRMByte(m_dst); break; + case 0x28: SUBB(); PutbackRMByte(m_dst); break; + case 0x30: XORB(); PutbackRMByte(m_dst); break; + case 0x38: SUBB(); break; /* CMP */ + } + break; + + + case 0x81: // i_81pre + m_modrm = fetch(); + m_dst = GetRMWord(); + m_src = fetch_word(); + if (m_modrm >=0xc0 ) { CLK(1); } + else if ((m_modrm & 0x38)==0x38) { CLK(2); } + else { CLK(3); } + switch (m_modrm & 0x38) + { + case 0x00: ADDW(); PutbackRMWord(m_dst); break; + case 0x08: ORW(); PutbackRMWord(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; ADDW(); PutbackRMWord(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; SUBW(); PutbackRMWord(m_dst); break; + case 0x20: ANDW(); PutbackRMWord(m_dst); break; + case 0x28: SUBW(); PutbackRMWord(m_dst); break; + case 0x30: XORW(); PutbackRMWord(m_dst); break; + case 0x38: SUBW(); break; /* CMP */ + } + break; + + + case 0x82: // i_82pre + m_modrm = fetch(); + m_dst = GetRMByte(); + m_src = (INT8)fetch(); + if (m_modrm >=0xc0 ) { CLK(1); } + else if ((m_modrm & 0x38)==0x38) { CLK(2); } + else { CLK(3); } + switch (m_modrm & 0x38) + { + case 0x00: ADDB(); PutbackRMByte(m_dst); break; + case 0x08: ORB(); PutbackRMByte(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; ADDB(); PutbackRMByte(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; SUBB(); PutbackRMByte(m_dst); break; + case 0x20: ANDB(); PutbackRMByte(m_dst); break; + case 0x28: SUBB(); PutbackRMByte(m_dst); break; + case 0x30: XORB(); PutbackRMByte(m_dst); break; + case 0x38: SUBB(); break; /* CMP */ + } + break; + + + case 0x83: // i_83pre + m_modrm = fetch(); + m_dst = GetRMWord(); + m_src = ((INT16)((INT8)fetch())); + if ( m_modrm >= 0xc0 ) { CLK(1); } + else if (( m_modrm & 0x38 ) == 0x38) { CLK(2); } + else { CLK(3); } + switch (m_modrm & 0x38) + { + case 0x00: ADDW(); PutbackRMWord(m_dst); break; + case 0x08: ORW(); PutbackRMWord(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; ADDW(); PutbackRMWord(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; SUBW(); PutbackRMWord(m_dst); break; + case 0x20: ANDW(); PutbackRMWord(m_dst); break; + case 0x28: SUBW(); PutbackRMWord(m_dst); break; + case 0x30: XORW(); PutbackRMWord(m_dst); break; + case 0x38: SUBW(); break; /* CMP */ + } + break; + + + case 0x84: // i_test_br8 + DEF_br8(); + ANDB(); + CLKM(1,2); + break; + + case 0x85: // i_test_wr16 + DEF_wr16(); + ANDW(); + CLKM(1,2); + break; + + case 0x86: // i_xchg_br8 + DEF_br8(); + RegByte(m_dst); + PutbackRMByte(m_src); + CLKM(3,5); + break; + + case 0x87: // i_xchg_wr16 + DEF_wr16(); + RegWord(m_dst); + PutbackRMWord(m_src); + CLKM(3,5); + break; + + + case 0x88: // i_mov_br8 + m_modrm = fetch(); + m_src = RegByte(); + PutRMByte(m_src); + CLK(1); + break; + + case 0x89: // i_mov_wr16 + m_modrm = fetch(); + m_src = RegWord(); + PutRMWord(m_src); + CLK(1); + break; + + case 0x8a: // i_mov_r8b + m_modrm = fetch(); + m_src = GetRMByte(); + RegByte(m_src); + CLK(1); + break; + + case 0x8b: // i_mov_r16w + m_modrm = fetch(); + m_src = GetRMWord(); + RegWord(m_src); + CLK(1); + break; + + case 0x8c: // i_mov_wsreg + m_modrm = fetch(); + PutRMWord(m_sregs[(m_modrm & 0x38) >> 3]); + CLKM(1,3); + break; + + case 0x8d: // i_lea + m_modrm = fetch(); + get_ea(); + RegWord(m_eo); + CLK(1); + break; + + case 0x8e: // i_mov_sregw + m_modrm = fetch(); + m_src = GetRMWord(); + CLKM(2,3); + switch (m_modrm & 0x38) + { + case 0x00: /* mov es,ew */ + m_sregs[ES] = m_src; + break; + case 0x08: /* mov cs,ew */ + m_sregs[CS] = m_src; + break; + case 0x10: /* mov ss,ew */ + m_sregs[SS] = m_src; + break; + case 0x18: /* mov ds,ew */ + m_sregs[DS] = m_src; + break; + default: + logerror("%s: %06x: Mov Sreg - Invalid register\n", tag(), pc()); + } + m_no_interrupt = 1; + break; + + case 0x8f: // i_popw + m_modrm = fetch(); + PutRMWord( POP() ); + CLKM(1,3); + break; + + case 0x90: // i_nop + CLK(1); + break; + + case 0x91: // i_xchg_axcx + XchgAWReg(CW); + CLK(3); + break; + + case 0x92: // i_xchg_axdx + XchgAWReg(DW); + CLK(3); + break; + + case 0x93: // i_xchg_axbx + XchgAWReg(BW); + CLK(3); + break; + + case 0x94: // i_xchg_axsp + XchgAWReg(SP); + CLK(3); + break; + + case 0x95: // i_xchg_axbp + XchgAWReg(BP); + CLK(3); + break; + + case 0x96: // i_xchg_axsi + XchgAWReg(IX); + CLK(3); + break; + + case 0x97: // i_xchg_axdi + XchgAWReg(IY); + CLK(3); + break; + + + case 0x98: // i_cbw + m_regs.b[AH] = (m_regs.b[AL] & 0x80) ? 0xff : 0; + CLK(1); + break; + + case 0x99: // i_cwd + m_regs.w[DW] = (m_regs.b[AH] & 0x80) ? 0xffff : 0; + CLK(1); + break; + + case 0x9a: // i_call_far + { + UINT16 tmp = fetch_word(); + UINT16 tmp2 = fetch_word(); + PUSH(m_sregs[CS]); + PUSH(m_ip); + m_ip = tmp; + m_sregs[CS] = tmp2; + CLK(10); + } + break; + + case 0x9b: // i_wait + logerror("%s: %06x: Hardware POLL\n", tag(), pc()); + break; + + case 0x9c: // i_pushf + PUSH( CompressFlags() ); + CLK(2); + break; + + case 0x9d: // i_popf + i_popf(); + break; + + case 0x9e: // i_sahf + { + UINT32 tmp = (CompressFlags() & 0xff00) | (m_regs.b[AH] & 0xd5); + ExpandFlags(tmp); + CLK(4); + } + break; + + case 0x9f: // i_lahf + m_regs.b[AH] = CompressFlags(); + CLK(2); + break; + + + case 0xa0: // i_mov_aldisp + { + UINT32 addr = fetch_word(); + m_regs.b[AL] = GetMemB(DS, addr); + CLK(1); + } + break; + + case 0xa1: // i_mov_axdisp + { + UINT32 addr = fetch_word(); + m_regs.b[AL] = GetMemB(DS, addr); + m_regs.b[AH] = GetMemB(DS, addr+1); + CLK(1); + } + break; + + case 0xa2: // i_mov_dispal + { + UINT32 addr = fetch_word(); + PutMemB(DS, addr, m_regs.b[AL]); + CLK(1); + } + break; + + case 0xa3: // i_mov_dispax + { + UINT32 addr = fetch_word(); + PutMemB(DS, addr, m_regs.b[AL]); + PutMemB(DS, addr+1, m_regs.b[AH]); + CLK(1); + } + break; + + case 0xa4: // i_movsb + i_movsb(); + break; + + case 0xa5: // i_movsw + i_movsw(); + break; + + case 0xa6: // i_cmpsb + i_cmpsb(); + break; + + case 0xa7: // i_cmpsw + i_cmpsw(); + break; + + + case 0xa8: // i_test_ald8 + DEF_ald8(); + ANDB(); + CLK(1); + break; + + case 0xa9: // i_test_axd16 + DEF_axd16(); + ANDW(); + CLK(1); + break; + + case 0xaa: // i_stosb + i_stosb(); + break; + + case 0xab: // i_stosw + i_stosw(); + break; + + case 0xac: // i_lodsb + i_lodsb(); + break; + + case 0xad: // i_lodsw + i_lodsw(); + break; + + case 0xae: // i_scasb + i_scasb(); + break; + + case 0xaf: // i_scasw + i_scasw(); + break; + + + case 0xb0: // i_mov_ald8 + m_regs.b[AL] = fetch(); + CLK(1); + break; + + case 0xb1: // i_mov_cld8 + m_regs.b[CL] = fetch(); + CLK(1); + break; + + case 0xb2: // i_mov_dld8 + m_regs.b[DL] = fetch(); + CLK(1); + break; + + case 0xb3: // i_mov_bld8 + m_regs.b[BL] = fetch(); + CLK(1); + break; + + case 0xb4: // i_mov_ahd8 + m_regs.b[AH] = fetch(); + CLK(1); + break; + + case 0xb5: // i_mov_chd8 + m_regs.b[CH] = fetch(); + CLK(1); + break; + + case 0xb6: // i_mov_dhd8 + m_regs.b[DH] = fetch(); + CLK(1); + break; + + case 0xb7: // i_mov_bhd8 + m_regs.b[BH] = fetch(); + CLK(1); + break; + + + case 0xb8: // i_mov_axd16 + m_regs.b[AL] = fetch(); + m_regs.b[AH] = fetch(); + CLK(1); + break; + + case 0xb9: // i_mov_cxd16 + m_regs.b[CL] = fetch(); + m_regs.b[CH] = fetch(); + CLK(1); + break; + + case 0xba: // i_mov_dxd16 + m_regs.b[DL] = fetch(); + m_regs.b[DH] = fetch(); + CLK(1); + break; + + case 0xbb: // i_mov_bxd16 + m_regs.b[BL] = fetch(); + m_regs.b[BH] = fetch(); + CLK(1); + break; + + case 0xbc: // i_mov_spd16 + m_regs.b[SPL] = fetch(); + m_regs.b[SPH] = fetch(); + CLK(1); + break; + + case 0xbd: // i_mov_bpd16 + m_regs.b[BPL] = fetch(); + m_regs.b[BPH] = fetch(); + CLK(1); + break; + + case 0xbe: // i_mov_sid16 + m_regs.b[IXL] = fetch(); + m_regs.b[IXH] = fetch(); + CLK(1); + break; + + case 0xbf: // i_mov_did16 + m_regs.b[IYL] = fetch(); + m_regs.b[IYH] = fetch(); + CLK(1); + break; + + + case 0xc0: // i_rotshft_bd8 + { + UINT8 c; + m_modrm = fetch(); + m_src = GetRMByte(); + m_dst = m_src; + c = fetch(); + CLKM(3,5); + if (c) + { + switch ( m_modrm & 0x38 ) + { + case 0x00: do { ROL_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x08: do { ROR_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x20: SHL_BYTE(c); break; + case 0x28: SHR_BYTE(c); break; + case 0x30: logerror("%s: %06x: Undefined opcode 0xc0 0x30 (SHLA)\n", tag(), pc()); break; + case 0x38: SHRA_BYTE(c); break; + } + } + } + break; + + case 0xc1: // i_rotshft_wd8 + { + UINT8 c; + m_modrm = fetch(); + m_src = GetRMWord(); + m_dst = m_src; + c = fetch(); + CLKM(3,5); + if (c) + { + switch ( m_modrm & 0x38 ) + { + case 0x00: do { ROL_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x08: do { ROR_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x20: SHL_WORD(c); break; + case 0x28: SHR_WORD(c); break; + case 0x30: logerror("%s: %06x: Undefined opcode 0xc1 0x30 (SHLA)\n", tag(), pc()); break; + case 0x38: SHRA_WORD(c); break; + } + } + } + break; + + + case 0xc2: // i_ret_d16 + { + UINT32 count = fetch_word(); + m_ip = POP(); + m_regs.w[SP] += count; + CLK(6); + } + break; + + case 0xc3: // i_ret + m_ip = POP(); + CLK(6); + break; + + case 0xc4: // i_les_dw + m_modrm = fetch(); + RegWord( GetRMWord() ); + m_sregs[ES] = GetnextRMWord(); + CLK(6); + break; + + case 0xc5: // i_lds_dw + m_modrm = fetch(); + RegWord( GetRMWord() ); + m_sregs[DS] = GetnextRMWord(); + CLK(6); + break; + + case 0xc6: // i_mov_bd8 + m_modrm = fetch(); + PutImmRMByte(); + CLK(1); + break; + + case 0xc7: // i_mov_wd16 + m_modrm = fetch(); + PutImmRMWord(); + CLK(1); + break; + + + case 0xc8: // i_enter + { + UINT16 nb = fetch(); + UINT32 level; + + CLK(8); + nb |= fetch() << 8; + level = fetch(); + PUSH(m_regs.w[BP]); + m_regs.w[BP] = m_regs.w[SP]; + m_regs.w[SP] -= nb; + for (int i=1; i0); PutbackRMByte(m_dst); break; + case 0x08: do { ROR_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; + case 0x20: SHL_BYTE(c); break; + case 0x28: SHR_BYTE(c); break; + case 0x30: logerror("%s: %06x: Undefined opcode 0xd2 0x30 (SHLA)\n", tag(), pc()); break; + case 0x38: SHRA_BYTE(c); break; + } + } + } + break; + + case 0xd3: // i_rotshft_wcl + { + UINT8 c; + + m_modrm = fetch(); + m_src = GetRMWord(); + m_dst = m_src; + c = m_regs.b[CL]; + CLKM(3,5); + if (c) + { + switch ( m_modrm & 0x38 ) + { + case 0x00: do { ROL_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x08: do { ROR_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; + case 0x20: SHL_WORD(c); break; + case 0x28: SHR_WORD(c); break; + case 0x30: logerror("%s: %06x: Undefined opcode 0xd3 0x30 (SHLA)\n", tag(), pc()); break; + case 0x38: SHRA_WORD(c); break; + } + } + } + break; + + case 0xd4: // i_aam + fetch(); + m_regs.b[AH] = m_regs.b[AL] / 10; + m_regs.b[AL] %= 10; + set_SZPF_Word(m_regs.w[AW]); + CLK(17); + break; + + case 0xd5: // i_aad + fetch(); + m_regs.b[AL] = m_regs.b[AH] * 10 + m_regs.b[AL]; + m_regs.b[AH] = 0; + set_SZPF_Byte(m_regs.b[AL]); + CLK(5); + break; + + case 0xd6: // i_setalc + m_regs.b[AL] = (CF) ? 0xff : 0x00; + CLK(3); + logerror("%s: %06x: Undefined opcode (SETALC)\n", tag(), pc() ); + break; + + case 0xd7: // i_trans + m_regs.b[AL] = GetMemB( DS, m_regs.w[BW] + m_regs.b[AL] ); + CLK(5); + break; + + case 0xd8: // i_fpo + m_modrm = fetch(); + CLK(1); + logerror("%s: %06x: Unimplemented floating point control %04x\n", tag(), pc(), m_modrm); + break; + + + case 0xe0: // i_loopne + { + INT8 disp = (INT8)fetch(); + + m_regs.w[CW]--; + if (!ZF && m_regs.w[CW]) + { + m_ip = m_ip + disp; + CLK(3); + } + CLK(3); + } + break; + + case 0xe1: // i_loope + { + INT8 disp = (INT8)fetch(); + + m_regs.w[CW]--; + if (ZF && m_regs.w[CW]) + { + m_ip = m_ip + disp; + CLK(3); + } + CLK(3); + } + break; + + case 0xe2: // i_loop + { + INT8 disp = (INT8)fetch(); + + m_regs.w[CW]--; + if (m_regs.w[CW]) + { + m_ip = m_ip + disp; + CLK(3); + } + CLK(2); + } + break; + + case 0xe3: // i_jcxz + { + INT8 disp = (INT8)fetch(); + + if (m_regs.w[CW] == 0) + { + m_ip = m_ip + disp; + CLK(3); + } + CLK(1); + } + break; + + case 0xe4: // i_inal + m_regs.b[AL] = read_port( fetch() ); + CLK(6); + break; + + case 0xe5: // i_inax + { + UINT8 port = fetch(); + + m_regs.b[AL] = read_port(port); + m_regs.b[AH] = read_port(port+1); + CLK(6); + } + break; + + case 0xe6: // i_outal + write_port( fetch(), m_regs.b[AL]); + CLK(6); + break; + + case 0xe7: // i_outax + { + UINT8 port = fetch(); + + write_port(port, m_regs.b[AL]); + write_port(port+1, m_regs.b[AH]); + CLK(6); + } + break; + + + case 0xe8: // i_call_d16 + { + INT16 tmp = (INT16)fetch_word(); + + PUSH(m_ip); + m_ip = m_ip + tmp; + CLK(5); + } + break; + + case 0xe9: // i_jmp_d16 + { + INT16 offset = (INT16)fetch_word(); + m_ip += offset; + CLK(4); + } + break; + + case 0xea: // i_jmp_far + { + UINT16 tmp = fetch_word(); + UINT16 tmp1 = fetch_word(); + + m_sregs[CS] = tmp1; + m_ip = tmp; + CLK(7); + } + break; + + case 0xeb: // i_jmp_d8 + { + int tmp = (int)((INT8)fetch()); + + CLK(4); + if (tmp==-2 && m_no_interrupt==0 && (m_pending_irq==0) && m_icount>0) + { + m_icount%=12; /* cycle skip */ + } + m_ip = (UINT16)(m_ip+tmp); + } + break; + + case 0xec: // i_inaldx + m_regs.b[AL] = read_port(m_regs.w[DW]); + CLK(6); + break; + + case 0xed: // i_inaxdx + { + UINT32 port = m_regs.w[DW]; + + m_regs.b[AL] = read_port(port); + m_regs.b[AH] = read_port(port+1); + CLK(6); + } + break; + + case 0xee: // i_outdxal + write_port(m_regs.w[DW], m_regs.b[AL]); + CLK(6); + break; + + case 0xef: // i_outdxax + { + UINT32 port = m_regs.w[DW]; + + write_port(port, m_regs.b[AL]); + write_port(port+1, m_regs.b[AH]); + CLK(6); + } + break; + + + case 0xf0: // i_lock + logerror("%s: %06x: Warning - BUSLOCK\n", tag(), pc()); + m_no_interrupt = 1; + CLK(1); + break; + + case 0xf2: // i_repne + { + UINT8 next = repx_op(); + UINT16 c = m_regs.w[CW]; + + switch (next) + { + case 0x6c: CLK(3); if (c) do { i_insb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: CLK(3); if (c) do { i_insw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: CLK(3); if (c) do { i_outsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: CLK(3); if (c) do { i_outsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: CLK(3); if (c) do { i_movsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: CLK(3); if (c) do { i_movsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: CLK(3); if (c) do { i_cmpsb(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: CLK(3); if (c) do { i_cmpsw(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: CLK(3); if (c) do { i_stosb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: CLK(3); if (c) do { i_stosw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: CLK(3); if (c) do { i_lodsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: CLK(3); if (c) do { i_lodsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: CLK(3); if (c) do { i_scasb(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: CLK(3); if (c) do { i_scasw(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + default: + logerror("%s: %06x: REPNE invalid\n", tag(), pc()); + // Decrement IP so the normal instruction will be executed next + m_ip--; + break; + } + } + break; + + case 0xf3: // i_repe + { + UINT8 next = repx_op(); + UINT16 c = m_regs.w[CW]; + + switch (next) + { + case 0x6c: CLK(3); if (c) do { i_insb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: CLK(3); if (c) do { i_insw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: CLK(3); if (c) do { i_outsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: CLK(3); if (c) do { i_outsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: CLK(3); if (c) do { i_movsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: CLK(3); if (c) do { i_movsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: CLK(3); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: CLK(3); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: CLK(3); if (c) do { i_stosb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: CLK(3); if (c) do { i_stosw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: CLK(3); if (c) do { i_lodsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: CLK(3); if (c) do { i_lodsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: CLK(3); if (c) do { i_scasb(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: CLK(3); if (c) do { i_scasw(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + default: + logerror("%s: %06x: REPE invalid\n", tag(), pc()); + // Decrement IP so the normal instruction will be executed next + m_ip--; + break; + } + } + break; + + case 0xf4: // i_hlt + logerror("%s: %06x: HALT\n", tag(), pc()); + m_icount = 0; + break; + + case 0xf5: // i_cmc + m_CarryVal ^= 1; + CLK(4); + break; + + case 0xf6: // i_f6pre + { + UINT32 tmp; + UINT32 uresult,uresult2; + INT32 result,result2; + + m_modrm = fetch(); + tmp = GetRMByte(); + switch ( m_modrm & 0x38 ) + { + case 0x00: /* TEST */ + tmp &= fetch(); + m_CarryVal = m_OverVal = 0; + set_SZPF_Byte(tmp); + CLKM(1,2); + break; + case 0x08: + logerror("%s: %06x: Undefined opcode 0xf6 0x08\n", tag(), pc()); + break; + case 0x10: /* NOT */ + PutbackRMByte(~tmp); + CLKM(1,3); + break; + case 0x18: /* NEG */ + m_CarryVal = (tmp!=0) ? 1 : 0; + tmp = (~tmp)+1; + set_SZPF_Byte(tmp); + PutbackRMByte(tmp&0xff); + CLKM(1,3); + break; + case 0x20: /* MULU */ + uresult = m_regs.b[AL] * tmp; + m_regs.w[AW] = (UINT16)uresult; + m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0; + CLKM(3,4); + break; + case 0x28: /* MUL */ + result = (INT16)((INT8)m_regs.b[AL])*(INT16)((INT8)tmp); + m_regs.w[AW] = (UINT16)result; + m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0; + CLKM(3,4); + break; + case 0x30: /* DIVU */ + if (tmp) + { + uresult = m_regs.w[AW]; + uresult2 = uresult % tmp; + if ((uresult /= tmp) > 0xff) + { + interrupt(0); + } + else + { + m_regs.b[AL] = uresult; + m_regs.b[AH] = uresult2; + } + } + else + { + interrupt(0); + } + CLKM(15,16); + break; + case 0x38: /* DIV */ + if (tmp) + { + result = (INT16)m_regs.w[AW]; + result2 = result % (INT16)((INT8)tmp); + if ((result /= (INT16)((INT8)tmp)) > 0xff) + { + interrupt(0); + } + else + { + m_regs.b[AL] = result; + m_regs.b[AH] = result2; + } + } + else + { + interrupt(0); + } + CLKM(17,18); + break; + } + } + break; + + + case 0xf7: // i_f7pre + { + UINT32 tmp,tmp2; + UINT32 uresult,uresult2; + INT32 result,result2; + + m_modrm = fetch(); + tmp = GetRMWord(); + switch ( m_modrm & 0x38 ) + { + case 0x00: /* TEST */ + tmp2 = fetch_word(); + tmp &= tmp2; + m_CarryVal = m_OverVal = 0; + set_SZPF_Word(tmp); + CLKM(1,2); + break; + case 0x08: + logerror("%s: %06x: Undefined opcode 0xf7 0x08\n", tag(), pc()); + break; + case 0x10: /* NOT */ + PutbackRMWord(~tmp); + CLKM(1,3); + break; + case 0x18: /* NEG */ + m_CarryVal = (tmp!=0) ? 1 : 0; + tmp = (~tmp) + 1; + set_SZPF_Word(tmp); + PutbackRMWord(tmp); + CLKM(1,3); + break; + case 0x20: /* MULU */ + uresult = m_regs.w[AW]*tmp; + m_regs.w[AW] = uresult & 0xffff; + m_regs.w[DW] = ((UINT32)uresult)>>16; + m_CarryVal = m_OverVal = (m_regs.w[DW] != 0) ? 1 : 0; + CLKM(3,4); + break; + case 0x28: /* MUL */ + result = (INT32)((INT16)m_regs.w[AW]) * (INT32)((INT16)tmp); + m_regs.w[AW] = result & 0xffff; + m_regs.w[DW] = result >> 16; + m_CarryVal = m_OverVal = (m_regs.w[DW] != 0) ? 1 : 0; + CLKM(3,4); + break; + case 0x30: /* DIVU */ + if (tmp) + { + uresult = (((UINT32)m_regs.w[DW]) << 16) | m_regs.w[AW]; + uresult2 = uresult % tmp; + if ((uresult /= tmp) > 0xffff) + { + interrupt(0); + } + else + { + m_regs.w[AW] = uresult; + m_regs.w[DW] = uresult2; + } + } + else + { + interrupt(0); + } + CLKM(23,24); + break; + case 0x38: /* DIV */ + if (tmp) + { + result = ((UINT32)m_regs.w[DW] << 16) + m_regs.w[AW]; + result2 = result % (INT32)((INT16)tmp); + if ((result /= (INT32)((INT16)tmp)) > 0xffff) + { + interrupt(0); + } + else + { + m_regs.w[AW] = result; + m_regs.w[DW] = result2; + } + } + else + { + interrupt(0); + } + CLKM(24,25); + break; + } + } + break; + + + case 0xf8: // i_clc + m_CarryVal = 0; + CLK(4); + break; + + case 0xf9: // i_stc + m_CarryVal = 1; + CLK(4); + break; + + case 0xfa: // i_di + m_IF = 0; + CLK(4); + break; + + case 0xfb: // i_ei + m_IF = 1; + CLK(4); + break; + + case 0xfc: // i_cld + m_DF = 0; + CLK(4); + break; + + case 0xfd: // i_std + m_DF = 1; + CLK(4); + break; + + case 0xfe: // i_fepre + { + UINT32 tmp, tmp1; + m_modrm = fetch(); + tmp = GetRMByte(); + switch ( m_modrm & 0x38 ) + { + case 0x00: /* INC */ + tmp1 = tmp+1; + m_OverVal = (tmp==0x7f); + set_AF(tmp1,tmp,1); + set_SZPF_Byte(tmp1); + PutbackRMByte(tmp1); + CLKM(1,3); + break; + case 0x08: /* DEC */ + tmp1 = tmp-1; + m_OverVal = (tmp==0x80); + set_AF(tmp1,tmp,1); + set_SZPF_Byte(tmp1); + PutbackRMByte(tmp1); + CLKM(1,3); + break; + default: + logerror("%s: %06x: FE Pre with unimplemented mod\n", tag(), pc()); + break; + } + } + break; + + case 0xff: // i_ffpre + { + UINT32 tmp, tmp1; + m_modrm = fetch(); + tmp = GetRMWord(); + switch ( m_modrm & 0x38 ) + { + case 0x00: /* INC */ + tmp1 = tmp+1; + m_OverVal = (tmp==0x7fff); + set_AF(tmp1,tmp,1); + set_SZPF_Word(tmp1); + PutbackRMWord(tmp1); + CLKM(1,3); + break; + case 0x08: /* DEC */ + tmp1 = tmp-1; + m_OverVal = (tmp==0x8000); + set_AF(tmp1,tmp,1); + set_SZPF_Word(tmp1); + PutbackRMWord(tmp1); + CLKM(1,3); + break; + case 0x10: /* CALL */ + PUSH(m_ip); + m_ip = tmp; + CLKM(5,6); + break; + case 0x18: /* CALL FAR */ + tmp1 = m_sregs[CS]; + m_sregs[CS] = GetnextRMWord(); + PUSH(tmp1); + PUSH(m_ip); + m_ip = tmp; + CLKM(5,12); + break; + case 0x20: /* JMP */ + m_ip = tmp; + CLKM(4,5); + break; + case 0x28: /* JMP FAR */ + m_ip = tmp; + m_sregs[CS] = GetnextRMWord(); + CLK(10); + break; + case 0x30: + PUSH(tmp); + CLK(1); + break; + default: + logerror("%s: %06x: FF Pre with unimplemented mod\n", tag(), pc()); + break; + } + } + break; + + default: + m_icount -= 10; + logerror("%s: %06x: Invalid Opcode %02x\n", tag(), pc(), op); break; - case CPUINFO_INT_REGISTER + NEC_IP: cpustate->ip = info->i; break; - case CPUINFO_INT_SP: - if( info->i - (cpustate->sregs[SS]<<4) < 0x10000 ) - { - cpustate->regs.w[SP] = info->i - (cpustate->sregs[SS]<<4); - } - else - { - cpustate->sregs[SS] = info->i >> 4; - cpustate->regs.w[SP] = info->i & 0x0000f; - } - break; - case CPUINFO_INT_REGISTER + NEC_SP: cpustate->regs.w[SP] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_FLAGS: ExpandFlags(info->i); break; - case CPUINFO_INT_REGISTER + NEC_AW: cpustate->regs.w[AW] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_CW: cpustate->regs.w[CW] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_DW: cpustate->regs.w[DW] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_BW: cpustate->regs.w[BW] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_BP: cpustate->regs.w[BP] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_IX: cpustate->regs.w[IX] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_IY: cpustate->regs.w[IY] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_ES: cpustate->sregs[ES] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_CS: cpustate->sregs[CS] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_SS: cpustate->sregs[SS] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_DS: cpustate->sregs[DS] = info->i; break; - case CPUINFO_INT_REGISTER + NEC_VECTOR: cpustate->int_vector = info->i; break; + + } } } - - -/************************************************************************** - * Generic get_info - **************************************************************************/ - -CPU_GET_INFO( v30mz ) -{ - v30mz_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; - int flags; - - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(v30mz_state); break; - case CPUINFO_INT_INPUT_LINES: info->i = 1; break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break; - case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break; - case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; - case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; - case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 6; break; - case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; - case CPUINFO_INT_MAX_CYCLES: info->i = 80; break; - - case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; - case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20; break; - case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; - case DEVINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; - case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; - case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; - case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break; - case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 16; break; - case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; - - case CPUINFO_INT_INPUT_STATE + 0: info->i = (cpustate->pending_irq & INT_IRQ) ? ASSERT_LINE : CLEAR_LINE; break; - case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = cpustate->nmi_state; break; - - case CPUINFO_INT_PREVIOUSPC: /* not supported */ break; - - case CPUINFO_INT_PC: - case CPUINFO_INT_REGISTER + NEC_PC: info->i = ((cpustate->sregs[CS]<<4) + cpustate->ip); break; - case CPUINFO_INT_REGISTER + NEC_IP: info->i = cpustate->ip; break; - case CPUINFO_INT_SP: info->i = (cpustate->sregs[SS]<<4) + cpustate->regs.w[SP]; break; - case CPUINFO_INT_REGISTER + NEC_SP: info->i = cpustate->regs.w[SP]; break; - case CPUINFO_INT_REGISTER + NEC_FLAGS: info->i = CompressFlags(); break; - case CPUINFO_INT_REGISTER + NEC_AW: info->i = cpustate->regs.w[AW]; break; - case CPUINFO_INT_REGISTER + NEC_CW: info->i = cpustate->regs.w[CW]; break; - case CPUINFO_INT_REGISTER + NEC_DW: info->i = cpustate->regs.w[DW]; break; - case CPUINFO_INT_REGISTER + NEC_BW: info->i = cpustate->regs.w[BW]; break; - case CPUINFO_INT_REGISTER + NEC_BP: info->i = cpustate->regs.w[BP]; break; - case CPUINFO_INT_REGISTER + NEC_IX: info->i = cpustate->regs.w[IX]; break; - case CPUINFO_INT_REGISTER + NEC_IY: info->i = cpustate->regs.w[IY]; break; - case CPUINFO_INT_REGISTER + NEC_ES: info->i = cpustate->sregs[ES]; break; - case CPUINFO_INT_REGISTER + NEC_CS: info->i = cpustate->sregs[CS]; break; - case CPUINFO_INT_REGISTER + NEC_SS: info->i = cpustate->sregs[SS]; break; - case CPUINFO_INT_REGISTER + NEC_DS: info->i = cpustate->sregs[DS]; break; - case CPUINFO_INT_REGISTER + NEC_VECTOR: info->i = cpustate->int_vector; break; - case CPUINFO_INT_REGISTER + NEC_PENDING: info->i = cpustate->pending_irq; break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(nec); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(nec); break; - case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(nec); break; - case CPUINFO_FCT_BURN: info->burn = NULL; break; - case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(nec); break; - case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case DEVINFO_STR_FAMILY: strcpy(info->s, "NEC V-Series"); break; - case DEVINFO_STR_VERSION: strcpy(info->s, "1.5"); break; - case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case DEVINFO_STR_CREDITS: strcpy(info->s, "NEC emulator v1.5 by Bryan McPhail"); break; - - case CPUINFO_STR_FLAGS: - flags = CompressFlags(); - sprintf(info->s, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", - flags & 0x8000 ? 'M':'.', - flags & 0x4000 ? '?':'.', - flags & 0x2000 ? '?':'.', - flags & 0x1000 ? '?':'.', - flags & 0x0800 ? 'O':'.', - flags & 0x0400 ? 'D':'.', - flags & 0x0200 ? 'I':'.', - flags & 0x0100 ? 'T':'.', - flags & 0x0080 ? 'S':'.', - flags & 0x0040 ? 'Z':'.', - flags & 0x0020 ? '?':'.', - flags & 0x0010 ? 'A':'.', - flags & 0x0008 ? '?':'.', - flags & 0x0004 ? 'P':'.', - flags & 0x0002 ? 'N':'.', - flags & 0x0001 ? 'C':'.'); - break; - - case CPUINFO_STR_REGISTER + NEC_PC: sprintf(info->s, "PC:%04X", (cpustate->sregs[CS]<<4) + cpustate->ip); break; - case CPUINFO_STR_REGISTER + NEC_IP: sprintf(info->s, "IP:%04X", cpustate->ip); break; - case CPUINFO_STR_REGISTER + NEC_SP: sprintf(info->s, "SP:%04X", cpustate->regs.w[SP]); break; - case CPUINFO_STR_REGISTER + NEC_FLAGS: sprintf(info->s, "F:%04X", CompressFlags()); break; - case CPUINFO_STR_REGISTER + NEC_AW: sprintf(info->s, "AW:%04X", cpustate->regs.w[AW]); break; - case CPUINFO_STR_REGISTER + NEC_CW: sprintf(info->s, "CW:%04X", cpustate->regs.w[CW]); break; - case CPUINFO_STR_REGISTER + NEC_DW: sprintf(info->s, "DW:%04X", cpustate->regs.w[DW]); break; - case CPUINFO_STR_REGISTER + NEC_BW: sprintf(info->s, "BW:%04X", cpustate->regs.w[BW]); break; - case CPUINFO_STR_REGISTER + NEC_BP: sprintf(info->s, "BP:%04X", cpustate->regs.w[BP]); break; - case CPUINFO_STR_REGISTER + NEC_IX: sprintf(info->s, "IX:%04X", cpustate->regs.w[IX]); break; - case CPUINFO_STR_REGISTER + NEC_IY: sprintf(info->s, "IY:%04X", cpustate->regs.w[IY]); break; - case CPUINFO_STR_REGISTER + NEC_ES: sprintf(info->s, "ES:%04X", cpustate->sregs[ES]); break; - case CPUINFO_STR_REGISTER + NEC_CS: sprintf(info->s, "CS:%04X", cpustate->sregs[CS]); break; - case CPUINFO_STR_REGISTER + NEC_SS: sprintf(info->s, "SS:%04X", cpustate->sregs[SS]); break; - case CPUINFO_STR_REGISTER + NEC_DS: sprintf(info->s, "DS:%04X", cpustate->sregs[DS]); break; - case CPUINFO_STR_REGISTER + NEC_VECTOR: sprintf(info->s, "V:%02X", cpustate->int_vector); break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(v30mz); - break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(v30mz); - break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case DEVINFO_STR_NAME: strcpy(info->s, "V30MZ"); - break; - } -} - -DEFINE_LEGACY_CPU_DEVICE(V30MZ, v30mz); diff --git a/src/emu/cpu/v30mz/v30mz.h b/src/emu/cpu/v30mz/v30mz.h index 2a6c2e43902..cab02c1dab5 100644 --- a/src/emu/cpu/v30mz/v30mz.h +++ b/src/emu/cpu/v30mz/v30mz.h @@ -1,358 +1,226 @@ -typedef enum { ES, CS, SS, DS } SREGS; -typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS; - -#define NEC_NMI_INT_VECTOR 2 - -typedef enum { - AL = NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1), - AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0), - CL = NATIVE_ENDIAN_VALUE_LE_BE(0x2, 0x3), - CH = NATIVE_ENDIAN_VALUE_LE_BE(0x3, 0x2), - DL = NATIVE_ENDIAN_VALUE_LE_BE(0x4, 0x5), - DH = NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4), - BL = NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7), - BH = NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6), - SPL = NATIVE_ENDIAN_VALUE_LE_BE(0x8, 0x9), - SPH = NATIVE_ENDIAN_VALUE_LE_BE(0x9, 0x8), - BPL = NATIVE_ENDIAN_VALUE_LE_BE(0xa, 0xb), - BPH = NATIVE_ENDIAN_VALUE_LE_BE(0xb, 0xa), - IXL = NATIVE_ENDIAN_VALUE_LE_BE(0xc, 0xd), - IXH = NATIVE_ENDIAN_VALUE_LE_BE(0xd, 0xc), - IYL = NATIVE_ENDIAN_VALUE_LE_BE(0xe, 0xf), - IYH = NATIVE_ENDIAN_VALUE_LE_BE(0xf, 0xe) -} BREGS; +#ifndef __V30MZ_H__ +#define __V30MZ_H__ -/* parameter x = result, y = source 1, z = source 2 */ +typedef struct _nec_config nec_config; +struct _nec_config +{ + const UINT8* v25v35_decryptiontable; // internal decryption table +}; -#define SetTF(x) (cpustate->TF = (x)) -#define SetIF(x) (cpustate->IF = (x)) -#define SetDF(x) (cpustate->DF = (x)) -#define SetMD(x) (cpustate->MF = (x)) /* OB [19.07.99] Mode Flag V30 */ - -#define SetCFB(x) (cpustate->CarryVal = (x) & 0x100) -#define SetCFW(x) (cpustate->CarryVal = (x) & 0x10000) -#define SetAF(x,y,z) (cpustate->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10) -#define SetSF(x) (cpustate->SignVal = (x)) -#define SetZF(x) (cpustate->ZeroVal = (x)) -#define SetPF(x) (cpustate->ParityVal = (x)) - -#define SetSZPF_Byte(x) (cpustate->SignVal=cpustate->ZeroVal=cpustate->ParityVal=(INT8)(x)) -#define SetSZPF_Word(x) (cpustate->SignVal=cpustate->ZeroVal=cpustate->ParityVal=(INT16)(x)) - -#define SetOFW_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000) -#define SetOFB_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80) -#define SetOFW_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000) -#define SetOFB_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80) - -#define ADDB { UINT32 res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(UINT8)res; } -#define ADDW { UINT32 res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(UINT16)res; } - -#define SUBB { UINT32 res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(UINT8)res; } -#define SUBW { UINT32 res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(UINT16)res; } - -#define ORB dst|=src; cpustate->CarryVal=cpustate->OverVal=cpustate->AuxVal=0; SetSZPF_Byte(dst) -#define ORW dst|=src; cpustate->CarryVal=cpustate->OverVal=cpustate->AuxVal=0; SetSZPF_Word(dst) - -#define ANDB dst&=src; cpustate->CarryVal=cpustate->OverVal=cpustate->AuxVal=0; SetSZPF_Byte(dst) -#define ANDW dst&=src; cpustate->CarryVal=cpustate->OverVal=cpustate->AuxVal=0; SetSZPF_Word(dst) - -#define XORB dst^=src; cpustate->CarryVal=cpustate->OverVal=cpustate->AuxVal=0; SetSZPF_Byte(dst) -#define XORW dst^=src; cpustate->CarryVal=cpustate->OverVal=cpustate->AuxVal=0; SetSZPF_Word(dst) - -#define CF (cpustate->CarryVal!=0) -#define SF (cpustate->SignVal<0) -#define ZF (cpustate->ZeroVal==0) -#define PF parity_table[(UINT8)cpustate->ParityVal] -#define AF (cpustate->AuxVal!=0) -#define OF (cpustate->OverVal!=0) -#define MD (cpustate->MF!=0) - -/************************************************************************/ - -#define SegBase(Seg) (cpustate->sregs[Seg] << 4) - -#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg==DS || Seg==SS)) ? cpustate->prefix_base : cpustate->sregs[Seg] << 4) - -#define GetMemB(Seg,Off) ((UINT8)cpustate->program->read_byte((DefaultBase(Seg)+(Off)))) -#define GetMemW(Seg,Off) ((UINT16) cpustate->program->read_byte((DefaultBase(Seg)+(Off))) + (cpustate->program->read_byte((DefaultBase(Seg)+((Off)+1)))<<8) ) - -#define PutMemB(Seg,Off,x) { cpustate->program->write_byte((DefaultBase(Seg)+(Off)),(x)); } -#define PutMemW(Seg,Off,x) { PutMemB(Seg,Off,(x)&0xff); PutMemB(Seg,(Off)+1,(UINT8)((x)>>8)); } - -/* Todo: Remove these later - plus readword could overflow */ -#define ReadByte(ea) ((UINT8)cpustate->program->read_byte((ea))) -#define ReadWord(ea) (cpustate->program->read_byte((ea))+(cpustate->program->read_byte(((ea)+1))<<8)) -#define WriteByte(ea,val) { cpustate->program->write_byte((ea),val); } -#define WriteWord(ea,val) { cpustate->program->write_byte((ea),(UINT8)(val)); cpustate->program->write_byte(((ea)+1),(val)>>8); } - -#define read_port(port) cpustate->io->read_byte(port) -#define write_port(port,val) cpustate->io->write_byte(port,val) - -#define FETCH (cpustate->direct->read_raw_byte((cpustate->sregs[CS]<<4)+cpustate->ip++)) -#define FETCHOP (cpustate->direct->read_decrypted_byte((cpustate->sregs[CS]<<4)+cpustate->ip++)) -#define FETCHWORD(var) { var=cpustate->direct->read_raw_byte((((cpustate->sregs[CS]<<4)+cpustate->ip)))+(cpustate->direct->read_raw_byte((((cpustate->sregs[CS]<<4)+cpustate->ip+1)))<<8); cpustate->ip+=2; } -#define PUSH(val) { cpustate->regs.w[SP]-=2; WriteWord((((cpustate->sregs[SS]<<4)+cpustate->regs.w[SP])),val); } -#define POP(var) { var = ReadWord((((cpustate->sregs[SS]<<4)+cpustate->regs.w[SP]))); cpustate->regs.w[SP]+=2; } -#define PEEK(addr) ((UINT8)cpustate->direct->read_raw_byte(addr)) -#define PEEKOP(addr) ((UINT8)cpustate->direct->read_decrypted_byte(addr)) - -#define GetModRM UINT32 ModRM=cpustate->direct->read_raw_byte((cpustate->sregs[CS]<<4)+cpustate->ip++) - -/* Cycle count macros: - CLK - cycle count is the same on all processors - CLKS - cycle count differs between processors, list all counts - CLKW - cycle count for word read/write differs for odd/even source/destination address - CLKM - cycle count for reg/mem instructions - CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses +enum +{ + NEC_PC=0, + NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY, + NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS, + NEC_VECTOR, NEC_PENDING +}; - Prefetch & buswait time is not emulated. - Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated. -*/ +///////////////////////////////////////////////////////////////// -#define CLK(v30mz) { cpustate->icount-=v30mz; } -#define CLKM(v30mz,v30mzm) { cpustate->icount-=( ModRM >=0xc0 )?v30mz:v30mzm; } +extern const device_type V30MZ; -/************************************************************************/ -#define CompressFlags() (UINT16)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \ - | (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) \ - | (cpustate->DF << 10) | (OF << 11)| (MD << 15)) +class v30mz_cpu_device : public cpu_device +{ +public: + // construction/destruction + v30mz_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); -#define ExpandFlags(f) \ -{ \ - cpustate->CarryVal = (f) & 1; \ - cpustate->ParityVal = !((f) & 4); \ - cpustate->AuxVal = (f) & 16; \ - cpustate->ZeroVal = !((f) & 64); \ - cpustate->SignVal = (f) & 128 ? -1 : 0; \ - cpustate->TF = ((f) & 256) == 256; \ - cpustate->IF = ((f) & 512) == 512; \ - cpustate->DF = ((f) & 1024) == 1024; \ - cpustate->OverVal = (f) & 2048; \ - cpustate->MF = ((f) & 0x8000) == 0x8000; \ -} +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); -#define IncWordReg(Reg) \ - unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \ - unsigned tmp1 = tmp+1; \ - cpustate->OverVal = (tmp == 0x7fff); \ - SetAF(tmp1,tmp,1); \ - SetSZPF_Word(tmp1); \ - cpustate->regs.w[Reg]=tmp1 + // device_execute_interface overrides + virtual UINT32 execute_min_cycles() const { return 1; } + virtual UINT32 execute_max_cycles() const { return 80; } + virtual UINT32 execute_input_lines() const { return 1; } + virtual void execute_run(); + virtual void execute_set_input(int inputnum, int state); -#define DecWordReg(Reg) \ - unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \ - unsigned tmp1 = tmp-1; \ - cpustate->OverVal = (tmp == 0x8000); \ - SetAF(tmp1,tmp,1); \ - SetSZPF_Word(tmp1); \ - cpustate->regs.w[Reg]=tmp1 + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : NULL ); } -#define JMP(flag) \ - int tmp = (int)((INT8)FETCH); \ - if (flag) \ - { \ - cpustate->ip = (UINT16)(cpustate->ip+tmp); \ - cpustate->icount-=10; \ - return; \ - } + // device_state_interface overrides + void state_string_export(const device_state_entry &entry, astring &string); -#define ADJ4(param1,param2) \ - if (AF || ((cpustate->regs.b[AL] & 0xf) > 9)) \ - { \ - UINT16 tmp; \ - tmp = cpustate->regs.b[AL] + param1; \ - cpustate->regs.b[AL] = tmp; \ - cpustate->AuxVal = 1; \ - cpustate->CarryVal |= tmp & 0x100; \ - } \ - if (CF || (cpustate->regs.b[AL]>0x9f)) \ - { \ - cpustate->regs.b[AL] += param2; \ - cpustate->CarryVal = 1; \ - } \ - SetSZPF_Byte(cpustate->regs.b[AL]) + // device_disasm_interface overrides + virtual UINT32 disasm_min_opcode_bytes() const { return 1; } + virtual UINT32 disasm_max_opcode_bytes() const { return 6; } + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); -#define ADJB(param1,param2) \ - if (AF || ((cpustate->regs.b[AL] & 0xf) > 9)) \ - { \ - cpustate->regs.b[AL] += param1; \ - cpustate->regs.b[AH] += param2; \ - cpustate->AuxVal = 1; \ - cpustate->CarryVal = 1; \ - } \ - else \ - { \ - cpustate->AuxVal = 0; \ - cpustate->CarryVal = 0; \ - } \ - cpustate->regs.b[AL] &= 0x0F + void interrupt(int int_num); -#define BITOP_BYTE \ - ModRM = FETCH; \ - if (ModRM >= 0xc0) { \ - tmp=cpustate->regs.b[Mod_RM.RM.b[ModRM]]; \ - } \ - else { \ - (*GetEA[ModRM])(cpustate); \ - tmp=ReadByte(cpustate->ea); \ - } + inline UINT32 pc(); + // Accessing memory and io + inline UINT8 read_byte(UINT32 addr); + inline UINT16 read_word(UINT32 addr); + inline void write_byte(UINT32 addr, UINT8 data); + inline void write_word(UINT32 addr, UINT16 data); + inline UINT8 read_port(UINT16 port); + inline void write_port(UINT16 port, UINT8 data); -#define BITOP_WORD \ - ModRM = FETCH; \ - if (ModRM >= 0xc0) { \ - tmp=cpustate->regs.w[Mod_RM.RM.w[ModRM]]; \ - } \ - else { \ - (*GetEA[ModRM])(cpustate); \ - tmp=ReadWord(cpustate->ea); \ - } + // Executing instructions + inline UINT8 fetch_op(); + inline UINT8 fetch(); + inline UINT16 fetch_word(); + inline UINT8 repx_op(); -#define BIT_NOT \ - if (tmp & (1<regs.w[Reg]; \ - cpustate->regs.w[Reg] = cpustate->regs.w[AW]; \ - cpustate->regs.w[AW] = tmp + // Memory handling while executing instructions + inline UINT32 default_base(int seg); + inline UINT32 get_ea(); + inline void PutbackRMByte(UINT8 data); + inline void PutbackRMWord(UINT16 data); + inline void RegByte(UINT8 data); + inline void RegWord(UINT16 data); + inline UINT8 RegByte(); + inline UINT16 RegWord(); + inline UINT16 GetRMWord(); + inline UINT16 GetnextRMWord(); + inline UINT8 GetRMByte(); + inline void PutMemB(int seg, UINT16 offset, UINT8 data); + inline void PutMemW(int seg, UINT16 offset, UINT16 data); + inline UINT8 GetMemB(int seg, UINT16 offset); + inline UINT16 GetMemW(int seg, UINT16 offset); + inline void PutImmRMWord(); + inline void PutRMWord(UINT16 val); + inline void PutRMByte(UINT8 val); + inline void PutImmRMByte(); + inline void DEF_br8(); + inline void DEF_wr16(); + inline void DEF_r8b(); + inline void DEF_r16w(); + inline void DEF_ald8(); + inline void DEF_axd16(); -#define ROL_BYTE cpustate->CarryVal = dst & 0x80; dst = (dst << 1)+CF -#define ROL_WORD cpustate->CarryVal = dst & 0x8000; dst = (dst << 1)+CF -#define ROR_BYTE cpustate->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7) -#define ROR_WORD cpustate->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15) -#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst) -#define ROLC_WORD dst = (dst << 1) + CF; SetCFW(dst) -#define RORC_BYTE dst = (CF<<8)+dst; cpustate->CarryVal = dst & 0x01; dst >>= 1 -#define RORC_WORD dst = (CF<<16)+dst; cpustate->CarryVal = dst & 0x01; dst >>= 1 -#define SHL_BYTE(c) cpustate->icount-=c; dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(UINT8)dst) -#define SHL_WORD(c) cpustate->icount-=c; dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(UINT16)dst) -#define SHR_BYTE(c) cpustate->icount-=c; dst >>= c-1; cpustate->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(UINT8)dst) -#define SHR_WORD(c) cpustate->icount-=c; dst >>= c-1; cpustate->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(UINT16)dst) -#define SHRA_BYTE(c) cpustate->icount-=c; dst = ((INT8)dst) >> (c-1); cpustate->CarryVal = dst & 0x1; dst = ((INT8)((UINT8)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(UINT8)dst) -#define SHRA_WORD(c) cpustate->icount-=c; dst = ((INT16)dst) >> (c-1); cpustate->CarryVal = dst & 0x1; dst = ((INT16)((UINT16)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(UINT16)dst) + // Flags + inline void set_CFB(UINT32 x); + inline void set_CFW(UINT32 x); + inline void set_AF(UINT32 x,UINT32 y,UINT32 z); + inline void set_SF(UINT32 x); + inline void set_ZF(UINT32 x); + inline void set_PF(UINT32 x); + inline void set_SZPF_Byte(UINT32 x); + inline void set_SZPF_Word(UINT32 x); + inline void set_OFW_Add(UINT32 x,UINT32 y,UINT32 z); + inline void set_OFB_Add(UINT32 x,UINT32 y,UINT32 z); + inline void set_OFW_Sub(UINT32 x,UINT32 y,UINT32 z); + inline void set_OFB_Sub(UINT32 x,UINT32 y,UINT32 z); + inline UINT16 CompressFlags(); + inline void ExpandFlags(UINT16 f); -#define DIVUB \ - uresult = cpustate->regs.w[AW]; \ - uresult2 = uresult % tmp; \ - if ((uresult /= tmp) > 0xff) { \ - nec_interrupt(cpustate,0); break; \ - } else { \ - cpustate->regs.b[AL] = uresult; \ - cpustate->regs.b[AH] = uresult2; \ - } + // rep instructions + inline void i_insb(); + inline void i_insw(); + inline void i_outsb(); + inline void i_outsw(); + inline void i_movsb(); + inline void i_movsw(); + inline void i_cmpsb(); + inline void i_cmpsw(); + inline void i_stosb(); + inline void i_stosw(); + inline void i_lodsb(); + inline void i_lodsw(); + inline void i_scasb(); + inline void i_scasw(); + inline void i_popf(); -#define DIVB \ - result = (INT16)cpustate->regs.w[AW]; \ - result2 = result % (INT16)((INT8)tmp); \ - if ((result /= (INT16)((INT8)tmp)) > 0xff) { \ - nec_interrupt(cpustate,0); break; \ - } else { \ - cpustate->regs.b[AL] = result; \ - cpustate->regs.b[AH] = result2; \ - } + // sub implementations + inline void ADDB(); + inline void ADDW(); + inline void SUBB(); + inline void SUBW(); + inline void ORB(); + inline void ORW(); + inline void ANDB(); + inline void ANDW(); + inline void XORB(); + inline void XORW(); + inline void ROL_BYTE(); + inline void ROL_WORD(); + inline void ROR_BYTE(); + inline void ROR_WORD(); + inline void ROLC_BYTE(); + inline void ROLC_WORD(); + inline void RORC_BYTE(); + inline void RORC_WORD(); + inline void SHL_BYTE(UINT8 c); + inline void SHL_WORD(UINT8 c); + inline void SHR_BYTE(UINT8 c); + inline void SHR_WORD(UINT8 c); + inline void SHRA_BYTE(UINT8 c); + inline void SHRA_WORD(UINT8 c); + inline void XchgAWReg(UINT8 reg); + inline void IncWordReg(UINT8 reg); + inline void DecWordReg(UINT8 reg); + inline void PUSH(UINT16 data); + inline UINT16 POP(); + inline void JMP(bool cond); + inline void ADJ4(INT8 param1, INT8 param2); + inline void ADJB(INT8 param1, INT8 param2); -#define DIVUW \ - uresult = (((UINT32)cpustate->regs.w[DW]) << 16) | cpustate->regs.w[AW];\ - uresult2 = uresult % tmp; \ - if ((uresult /= tmp) > 0xffff) { \ - nec_interrupt(cpustate,0); break; \ - } else { \ - cpustate->regs.w[AW]=uresult; \ - cpustate->regs.w[DW]=uresult2; \ - } +protected: + address_space_config m_program_config; + address_space_config m_io_config; -#define DIVW \ - result = ((UINT32)cpustate->regs.w[DW] << 16) + cpustate->regs.w[AW]; \ - result2 = result % (INT32)((INT16)tmp); \ - if ((result /= (INT32)((INT16)tmp)) > 0xffff) { \ - nec_interrupt(cpustate,0); break; \ - } else { \ - cpustate->regs.w[AW]=result; \ - cpustate->regs.w[DW]=result2; \ - } + union + { /* eight general registers */ + UINT16 w[8]; /* viewed as 16 bits registers */ + UINT8 b[16]; /* or as 8 bit registers */ + } m_regs; + UINT16 m_sregs[4]; -#define ADD4S { \ - int i,v1,v2,result; \ - int count = (cpustate->regs.b[CL]+1)/2; \ - unsigned di = cpustate->regs.w[IY]; \ - unsigned si = cpustate->regs.w[IX]; \ - if (cpustate->seg_prefix) logerror("%06x: Warning: seg_prefix defined for add4s\n",PC(cpustate)); \ - cpustate->ZeroVal = cpustate->CarryVal = 0; \ - for (i=0;iicount-=19; \ - tmp = GetMemB(DS, si); \ - tmp2 = GetMemB(ES, di); \ - v1 = (tmp>>4)*10 + (tmp&0xf); \ - v2 = (tmp2>>4)*10 + (tmp2&0xf); \ - result = v1+v2+cpustate->CarryVal; \ - cpustate->CarryVal = result > 99 ? 1 : 0; \ - result = result % 100; \ - v1 = ((result/10)<<4) | (result % 10); \ - PutMemB(ES, di,v1); \ - if (v1) cpustate->ZeroVal = 1; \ - si++; \ - di++; \ - } \ -} + UINT16 m_ip; -#define SUB4S { \ - int count = (cpustate->regs.b[CL]+1)/2; \ - int i,v1,v2,result; \ - unsigned di = cpustate->regs.w[IY]; \ - unsigned si = cpustate->regs.w[IX]; \ - if (cpustate->seg_prefix) logerror("%06x: Warning: seg_prefix defined for sub4s\n",PC(cpustate)); \ - cpustate->ZeroVal = cpustate->CarryVal = 0; \ - for (i=0;iicount-=19; \ - tmp = GetMemB(ES, di); \ - tmp2 = GetMemB(DS, si); \ - v1 = (tmp>>4)*10 + (tmp&0xf); \ - v2 = (tmp2>>4)*10 + (tmp2&0xf); \ - if (v1 < (v2+cpustate->CarryVal)) { \ - v1+=100; \ - result = v1-(v2+cpustate->CarryVal); \ - cpustate->CarryVal = 1; \ - } else { \ - result = v1-(v2+cpustate->CarryVal); \ - cpustate->CarryVal = 0; \ - } \ - v1 = ((result/10)<<4) | (result % 10); \ - PutMemB(ES, di,v1); \ - if (v1) cpustate->ZeroVal = 1; \ - si++; \ - di++; \ - } \ -} + INT32 m_SignVal; + UINT32 m_AuxVal, m_OverVal, m_ZeroVal, m_CarryVal, m_ParityVal; /* 0 or non-0 valued flags */ + UINT8 m_TF, m_IF, m_DF, m_MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */ + UINT32 m_int_vector; + UINT32 m_pending_irq; + UINT32 m_nmi_state; + UINT32 m_irq_state; + UINT8 m_no_interrupt; + UINT8 m_fire_trap; -#define CMP4S { \ - int count = (cpustate->regs.b[CL]+1)/2; \ - int i,v1,v2,result; \ - unsigned di = cpustate->regs.w[IY]; \ - unsigned si = cpustate->regs.w[IX]; \ - if (cpustate->seg_prefix) logerror("%06x: Warning: seg_prefix defined for cmp4s\n",PC(cpustate)); \ - cpustate->ZeroVal = cpustate->CarryVal = 0; \ - for (i=0;iicount-=19; \ - tmp = GetMemB(ES, di); \ - tmp2 = GetMemB(DS, si); \ - v1 = (tmp>>4)*10 + (tmp&0xf); \ - v2 = (tmp2>>4)*10 + (tmp2&0xf); \ - if (v1 < (v2+cpustate->CarryVal)) { \ - v1+=100; \ - result = v1-(v2+cpustate->CarryVal); \ - cpustate->CarryVal = 1; \ - } else { \ - result = v1-(v2+cpustate->CarryVal); \ - cpustate->CarryVal = 0; \ - } \ - v1 = ((result/10)<<4) | (result % 10); \ - if (v1) cpustate->ZeroVal = 1; \ - si++; \ - di++; \ - } \ -} + device_irq_acknowledge_callback m_irq_callback; + address_space *m_program; + direct_read_data *m_direct; + address_space *m_io; + int m_icount; + + UINT32 m_prefix_base; /* base address of the latest prefix segment */ + bool m_seg_prefix; /* prefix segment indicator */ + bool m_seg_prefix_next; /* prefix segment for next instruction */ + + UINT32 m_ea; + UINT16 m_eo; + UINT16 m_e16; + + // Used during execution of instructions + UINT8 m_modrm; + UINT32 m_dst; + UINT32 m_src; + UINT32 m_pc; + + // Lookup tables + UINT8 m_parity_table[256]; + struct { + struct { + int w[256]; + int b[256]; + } reg; + struct { + int w[256]; + int b[256]; + } RM; + } m_Mod_RM; +}; + + +#endif /* __V30MZ_H__ */