--- tme/ic/m68k/m68k-insns-auto.c 2018/04/24 16:39:00 1.1.1.2 +++ tme/ic/m68k/m68k-insns-auto.c 2018/04/24 16:40:20 1.1.1.3 @@ -1,5 +1,5 @@ /* automatically generated by m68k-insns-auto.sh, do not edit! */ -_TME_RCSID("$Id: m68k-insns-auto.c,v 1.1.1.2 2018/04/24 16:39:00 root Exp $"); +_TME_RCSID("$Id: m68k-insns-auto.c,v 1.1.1.3 2018/04/24 16:40:20 root Exp $"); #include "m68k-impl.h" @@ -635,13 +635,23 @@ TME_M68K_INSN(tme_m68k_asr8) if (count > 0) { if (63 > SHIFTMAX_INT8_T && count > 8) { - res = 0; + res = 0 - (res < 0); } +#ifdef SHIFTSIGNED_INT8_T res >>= (count - 1); +#else /* !SHIFTSIGNED_INT8_T */ + for (; --count > 0; ) { + res = (res & ~((tme_int8_t) 1)) / 2; + } +#endif /* !SHIFTSIGNED_INT8_T */ flags = (res & 1); flags *= TME_M68K_FLAG_C; flags |= (flags * TME_M68K_FLAG_X); +#ifdef SHIFTSIGNED_INT8_T res >>= 1; +#else /* !SHIFTSIGNED_INT8_T */ + res = (res & ~((tme_int8_t) 1)) / 2; +#endif /* !SHIFTSIGNED_INT8_T */ } /* store the result: */ @@ -996,11 +1006,38 @@ TME_M68K_INSN(tme_m68k_cas8) TME_M68K_INSN(tme_m68k_moves8) { int ireg; + unsigned int ea_reg; + unsigned int increment; + TME_M68K_INSN_PRIV; + TME_M68K_INSN_CANFAULT; ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4); + + /* we have to handle postincrement and predecrement ourselves: */ + if (!TME_M68K_SEQUENCE_RESTARTING) { + ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); + increment = TME_M68K_SIZE_8; + if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) { + increment = TME_M68K_SIZE_16; + } + switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) { + case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break; + case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break; + default: break; + } + } + if (TME_M68K_INSN_SPECOP & TME_BIT(11)) { - ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg << 2); + if (!TME_M68K_SEQUENCE_RESTARTING) { + ic->tme_m68k_ireg_memx8 = ic->tme_m68k_ireg_uint8(ireg << 2); + ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc; + } + tme_m68k_write_memx8(ic); } else { + if (!TME_M68K_SEQUENCE_RESTARTING) { + ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc; + } + tme_m68k_read_memx8(ic); if (ireg >= TME_M68K_IREG_A0) { ic->tme_m68k_ireg_uint32(ireg) = TME_EXT_S8_U32((tme_int8_t) ic->tme_m68k_ireg_memx8); @@ -1624,13 +1661,23 @@ TME_M68K_INSN(tme_m68k_asr16) if (count > 0) { if (63 > SHIFTMAX_INT16_T && count > 16) { - res = 0; + res = 0 - (res < 0); } +#ifdef SHIFTSIGNED_INT16_T res >>= (count - 1); +#else /* !SHIFTSIGNED_INT16_T */ + for (; --count > 0; ) { + res = (res & ~((tme_int16_t) 1)) / 2; + } +#endif /* !SHIFTSIGNED_INT16_T */ flags = (res & 1); flags *= TME_M68K_FLAG_C; flags |= (flags * TME_M68K_FLAG_X); +#ifdef SHIFTSIGNED_INT16_T res >>= 1; +#else /* !SHIFTSIGNED_INT16_T */ + res = (res & ~((tme_int16_t) 1)) / 2; +#endif /* !SHIFTSIGNED_INT16_T */ } /* store the result: */ @@ -2083,13 +2130,15 @@ TME_M68K_INSN(tme_m68k_chk16) { if (*((tme_int16_t *) _op0) < 0) { ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N; + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); } if (*((tme_int16_t *) _op0) > *((tme_int16_t *) _op1)) { ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N; + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); } TME_M68K_INSN_OK; } @@ -2157,7 +2206,7 @@ TME_M68K_INSN(tme_m68k_cas2_16) int ireg_dc, ireg_du; int do_write; tme_uint16_t specopx = ic->_tme_m68k_insn_specop; - tme_uint16_t specopy = ic->_tme_m68k_insn_specop2; + tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t); tme_uint32_t addrx; tme_uint32_t addry; @@ -2254,11 +2303,38 @@ TME_M68K_INSN(tme_m68k_cas2_16) TME_M68K_INSN(tme_m68k_moves16) { int ireg; + unsigned int ea_reg; + unsigned int increment; + TME_M68K_INSN_PRIV; + TME_M68K_INSN_CANFAULT; ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4); + + /* we have to handle postincrement and predecrement ourselves: */ + if (!TME_M68K_SEQUENCE_RESTARTING) { + ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); + increment = TME_M68K_SIZE_16; + if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) { + increment = TME_M68K_SIZE_16; + } + switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) { + case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break; + case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break; + default: break; + } + } + if (TME_M68K_INSN_SPECOP & TME_BIT(11)) { - ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1); + if (!TME_M68K_SEQUENCE_RESTARTING) { + ic->tme_m68k_ireg_memx16 = ic->tme_m68k_ireg_uint16(ireg << 1); + ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc; + } + tme_m68k_write_memx16(ic); } else { + if (!TME_M68K_SEQUENCE_RESTARTING) { + ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc; + } + tme_m68k_read_memx16(ic); if (ireg >= TME_M68K_IREG_A0) { ic->tme_m68k_ireg_uint32(ireg) = TME_EXT_S16_U32((tme_int16_t) ic->tme_m68k_ireg_memx16); @@ -2944,13 +3020,23 @@ TME_M68K_INSN(tme_m68k_asr32) if (count > 0) { if (63 > SHIFTMAX_INT32_T && count > 32) { - res = 0; + res = 0 - (res < 0); } +#ifdef SHIFTSIGNED_INT32_T res >>= (count - 1); +#else /* !SHIFTSIGNED_INT32_T */ + for (; --count > 0; ) { + res = (res & ~((tme_int32_t) 1)) / 2; + } +#endif /* !SHIFTSIGNED_INT32_T */ flags = (res & 1); flags *= TME_M68K_FLAG_C; flags |= (flags * TME_M68K_FLAG_X); +#ifdef SHIFTSIGNED_INT32_T res >>= 1; +#else /* !SHIFTSIGNED_INT32_T */ + res = (res & ~((tme_int32_t) 1)) / 2; +#endif /* !SHIFTSIGNED_INT32_T */ } /* store the result: */ @@ -3435,13 +3521,15 @@ TME_M68K_INSN(tme_m68k_chk32) { if (*((tme_int32_t *) _op0) < 0) { ic->tme_m68k_ireg_ccr |= TME_M68K_FLAG_N; + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); } if (*((tme_int32_t *) _op0) > *((tme_int32_t *) _op1)) { ic->tme_m68k_ireg_ccr &= ~TME_M68K_FLAG_N; + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(6)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_CHK)); } TME_M68K_INSN_OK; } @@ -3509,7 +3597,7 @@ TME_M68K_INSN(tme_m68k_cas2_32) int ireg_dc, ireg_du; int do_write; tme_uint16_t specopx = ic->_tme_m68k_insn_specop; - tme_uint16_t specopy = ic->_tme_m68k_insn_specop2; + tme_uint16_t specopy = TME_M68K_INSN_OP0(tme_uint16_t); tme_uint32_t addrx; tme_uint32_t addry; @@ -3606,11 +3694,38 @@ TME_M68K_INSN(tme_m68k_cas2_32) TME_M68K_INSN(tme_m68k_moves32) { int ireg; + unsigned int ea_reg; + unsigned int increment; + TME_M68K_INSN_PRIV; + TME_M68K_INSN_CANFAULT; ireg = TME_M68K_IREG_D0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_SPECOP, 12, 4); + + /* we have to handle postincrement and predecrement ourselves: */ + if (!TME_M68K_SEQUENCE_RESTARTING) { + ea_reg = TME_M68K_IREG_A0 + TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 0, 3); + increment = TME_M68K_SIZE_32; + if (increment == TME_M68K_SIZE_8 && ea_reg == TME_M68K_IREG_A7) { + increment = TME_M68K_SIZE_16; + } + switch (TME_FIELD_EXTRACTU(TME_M68K_INSN_OPCODE, 3, 3)) { + case 3: ic->tme_m68k_ireg_uint32(ea_reg) += increment; break; + case 4: ic->_tme_m68k_ea_address = (ic->tme_m68k_ireg_uint32(ea_reg) -= increment); break; + default: break; + } + } + if (TME_M68K_INSN_SPECOP & TME_BIT(11)) { - ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg); + if (!TME_M68K_SEQUENCE_RESTARTING) { + ic->tme_m68k_ireg_memx32 = ic->tme_m68k_ireg_uint32(ireg); + ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_dfc; + } + tme_m68k_write_memx32(ic); } else { + if (!TME_M68K_SEQUENCE_RESTARTING) { + ic->_tme_m68k_ea_function_code = ic->tme_m68k_ireg_sfc; + } + tme_m68k_read_memx32(ic); ic->tme_m68k_ireg_uint32(ireg) = ic->tme_m68k_ireg_memx32; } TME_M68K_INSN_OK; @@ -3624,6 +3739,10 @@ tme_m68k_read_memx8(struct tme_m68k *ic) tme_uint32_t linear_address = ic->_tme_m68k_ea_address; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -3669,6 +3788,10 @@ tme_m68k_read_mem8(struct tme_m68k *ic, tme_uint32_t linear_address = ic->_tme_m68k_ea_address; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -3714,6 +3837,10 @@ tme_m68k_write_memx8(struct tme_m68k *ic tme_uint32_t linear_address = ic->_tme_m68k_ea_address; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx8, TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -3759,6 +3886,10 @@ tme_m68k_write_mem8(struct tme_m68k *ic, tme_uint32_t linear_address = ic->_tme_m68k_ea_address; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem8(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint8(ireg), TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -3805,6 +3936,10 @@ tme_m68k_read_memx16(struct tme_m68k *ic tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -3859,6 +3994,10 @@ tme_m68k_read_mem16(struct tme_m68k *ic, tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -3914,6 +4053,10 @@ tme_m68k_fetch16(struct tme_m68k *ic, tm struct tme_m68k_tlb *tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb); unsigned int insn_buffer_off = TME_ALIGN(ic->_tme_m68k_insn_buffer_off, sizeof(tme_uint16_t)); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -3970,6 +4113,10 @@ tme_m68k_pop16(struct tme_m68k *ic, tme_ tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -4027,6 +4174,10 @@ tme_m68k_write_memx16(struct tme_m68k *i tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx16, TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -4081,6 +4232,10 @@ tme_m68k_write_mem16(struct tme_m68k *ic tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem16(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint16(ireg), TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -4135,6 +4290,10 @@ tme_m68k_push16(struct tme_m68k *ic, tme tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint16_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem16(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -4192,6 +4351,10 @@ tme_m68k_read_memx32(struct tme_m68k *ic tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -4275,6 +4438,10 @@ tme_m68k_read_mem32(struct tme_m68k *ic, tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -4359,6 +4526,10 @@ tme_m68k_fetch32(struct tme_m68k *ic, tm struct tme_m68k_tlb *tlb = TME_ATOMIC_READ(struct tme_m68k_tlb *, ic->_tme_m68k_itlb); unsigned int insn_buffer_off = TME_ALIGN(ic->_tme_m68k_insn_buffer_off, sizeof(tme_uint32_t)); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -4444,6 +4615,10 @@ tme_m68k_pop32(struct tme_m68k *ic, tme_ tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -4530,6 +4705,10 @@ tme_m68k_write_memx32(struct tme_m68k *i tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_memx32, TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -4610,6 +4789,10 @@ tme_m68k_write_mem32(struct tme_m68k *ic tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem32(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, ic->tme_m68k_ireg_uint32(ireg), TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -4690,6 +4873,10 @@ tme_m68k_push32(struct tme_m68k *ic, tme tme_uint32_t linear_address_last = linear_address_first + sizeof(tme_uint32_t) - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem32(ic, function_code, linear_address_first, value, TME_BUS_CYCLE_WRITE); tme_m68k_log(ic, 1000, TME_OK, @@ -4773,6 +4960,10 @@ tme_m68k_read_mem(struct tme_m68k *ic, t tme_uint32_t linear_address_last = linear_address_first + count - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* do the bus cycle(s) ourselves from emulator memory if we can. the emulator memory allocator and TLB filler must guarantee that all tme_m68k_tlb_emulator_off_read pointers be 32-bit @@ -4912,7 +5103,7 @@ tme_m68k_read(struct tme_m68k *ic, /* only byte transfers can be unaligned: */ if (resid > sizeof(tme_uint8_t) && (linear_address & 1)) { - exception = TME_M68K_EXCEPTION_GROUP0_AERR; + exception = TME_M68K_EXCEPTION_AERR; break; } @@ -4930,7 +5121,7 @@ tme_m68k_read(struct tme_m68k *ic, /* an instruction fetch must be aligned: */ if (flags & TME_M68K_BUS_CYCLE_FETCH) { if (linear_address & 1) { - exception = TME_M68K_EXCEPTION_GROUP0_AERR; + exception = TME_M68K_EXCEPTION_AERR; break; } assert(!(resid & 1)); @@ -4961,7 +5152,7 @@ tme_m68k_read(struct tme_m68k *ic, if (!TME_M68K_TLB_OK_FAST_READ(tlb, function_code, linear_address, linear_address) || (rmw_rwlock != NULL && rmw_rwlock != tlb->tme_m68k_tlb_bus_rwlock)) { - exception = TME_M68K_EXCEPTION_GROUP0_BERR; + exception = TME_M68K_EXCEPTION_BERR; break; } @@ -4995,11 +5186,20 @@ tme_m68k_read(struct tme_m68k *ic, cycle.tme_bus_cycle_address = physical_address; } + /* otherwise, if we didn't get a bus error, but some + synchronous event has happened: */ + else if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { + + /* after the currently executing instruction finishes, check + for external resets, halts, or interrupts: */ + ic->_tme_m68k_instruction_burst_remaining = 0; + } + /* otherwise, any other error might be a bus error: */ else if (err != TME_OK) { err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err); if (err != TME_OK) { - exception = TME_M68K_EXCEPTION_GROUP0_BERR; + exception = TME_M68K_EXCEPTION_BERR; break; } } @@ -5047,6 +5247,10 @@ tme_m68k_write_mem(struct tme_m68k *ic, tme_uint32_t linear_address_last = linear_address_first + count - 1; struct tme_m68k_tlb *tlb = TME_M68K_TLB_ENTRY(ic, function_code, linear_address_first); +#ifdef _TME_M68K_STATS + ic->tme_m68k_stats.tme_m68k_stats_memory_total++; +#endif /* _TME_M68K_STATS */ + /* log the value written: */ tme_m68k_verify_mem_any(ic, ic->_tme_m68k_ea_function_code, ic->_tme_m68k_ea_address, buffer, count, TME_BUS_CYCLE_WRITE); tme_m68k_log_start(ic, 1000, TME_OK) { @@ -5186,7 +5390,7 @@ tme_m68k_write(struct tme_m68k *ic, /* only byte transfers can be unaligned: */ if (resid > sizeof(tme_uint8_t) && (linear_address & 1)) { - exception = TME_M68K_EXCEPTION_GROUP0_AERR; + exception = TME_M68K_EXCEPTION_AERR; break; } @@ -5226,7 +5430,7 @@ tme_m68k_write(struct tme_m68k *ic, if (!TME_M68K_TLB_OK_FAST_WRITE(tlb, function_code, linear_address, linear_address) || (rmw_rwlock != NULL && rmw_rwlock != tlb->tme_m68k_tlb_bus_rwlock)) { - exception = TME_M68K_EXCEPTION_GROUP0_BERR; + exception = TME_M68K_EXCEPTION_BERR; break; } @@ -5260,11 +5464,20 @@ tme_m68k_write(struct tme_m68k *ic, cycle.tme_bus_cycle_address = physical_address; } + /* otherwise, if we didn't get a bus error, but some + synchronous event has happened: */ + else if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { + + /* after the currently executing instruction finishes, check + for external resets, halts, or interrupts: */ + ic->_tme_m68k_instruction_burst_remaining = 0; + } + /* otherwise, any other error might be a bus error: */ else if (err != TME_OK) { err = tme_bus_tlb_fault(&tlb->tme_m68k_tlb_bus_tlb, &cycle, err); if (err != TME_OK) { - exception = TME_M68K_EXCEPTION_GROUP0_BERR; + exception = TME_M68K_EXCEPTION_BERR; break; } } @@ -5606,8 +5819,9 @@ TME_M68K_INSN(tme_m68k_divu) dividend = (tme_uint32_t) ic->tme_m68k_ireg_uint32(ireg_dq); divisor = TME_M68K_INSN_OP1(tme_uint16_t); if (divisor == 0) { + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); } /* do the division: */ @@ -5693,8 +5907,9 @@ TME_M68K_INSN(tme_m68k_divul) dividend = (tme_uint64_t) ic->tme_m68k_ireg_uint32(ireg_dq); divisor = TME_M68K_INSN_OP1(tme_uint32_t); if (divisor == 0) { + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); } /* do the division: */ @@ -5759,8 +5974,9 @@ TME_M68K_INSN(tme_m68k_divs) dividend = (tme_int32_t) ic->tme_m68k_ireg_int32(ireg_dq); divisor = TME_M68K_INSN_OP1(tme_int16_t); if (divisor == 0) { + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); } /* do the division: */ @@ -5846,8 +6062,9 @@ TME_M68K_INSN(tme_m68k_divsl) dividend = (tme_int64_t) ic->tme_m68k_ireg_int32(ireg_dq); divisor = TME_M68K_INSN_OP1(tme_int32_t); if (divisor == 0) { + ic->tme_m68k_ireg_pc_last = ic->tme_m68k_ireg_pc; ic->tme_m68k_ireg_pc = ic->tme_m68k_ireg_pc_next; - TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_GROUP2(5)); + TME_M68K_INSN_EXCEPTION(TME_M68K_EXCEPTION_INST(TME_M68K_VECTOR_DIV0)); } /* do the division: */