X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=m68k_in.c;h=ec2614fb48e84a5c133defa5d21257ed65dcd189;hb=b038f1428406660c04d0313b87d91fa6df676afc;hp=cf0eb18184cedc38b2a4028b56baef45c8e73336;hpb=e2f86a9c1a5c7a039831289f730a01eb7140402b;p=pistorm diff --git a/m68k_in.c b/m68k_in.c index cf0eb18..ec2614f 100644 --- a/m68k_in.c +++ b/m68k_in.c @@ -283,7 +283,8 @@ M68KMAKE_OPCODE_HANDLER_HEADER #include "m68kcpu.h" extern void m68040_fpu_op0(void); extern void m68040_fpu_op1(void); -extern void m68881_mmu_ops(); +extern void m68851_mmu_ops(); +extern void m68881_ftrap(); /* ======================================================================== */ /* ========================= INSTRUCTION HANDLERS ========================= */ @@ -561,6 +562,7 @@ cpdbcc 32 . . 1111...001001... .......... . . U U . . . 4 cpgen 32 . . 1111...000...... .......... . . U U . . . 4 4 . unemulated cpscc 32 . . 1111...001...... .......... . . U U . . . 4 4 . unemulated cptrapcc 32 . . 1111...001111... .......... . . U U . . . 4 4 . unemulated +ftrapcc 32 . . 1111001001111... .......... . . U U . . . 4 4 . dbt 16 . . 0101000011001... .......... U U U U U 12 12 6 6 6 dbf 16 . . 0101000111001... .......... U U U U U 12 12 6 6 6 dbcc 16 . . 0101....11001... .......... U U U U U 12 12 6 6 6 @@ -769,7 +771,8 @@ pack 16 mm ay7 1000...101001111 .......... . . U U U . . 13 1 pack 16 mm axy7 1000111101001111 .......... . . U U U . . 13 13 13 pack 16 mm . 1000...101001... .......... . . U U U . . 13 13 13 pea 32 . . 0100100001...... A..DXWLdx. U U U U U 6 6 5 5 5 -pflush 32 . . 1111010100011000 .......... . . . . S . . . . 4 TODO: correct timing +pflusha 32 . . 1111010100011... .......... . . . . S . . . . 4 TODO: correct timing +pflushan 32 . . 1111010100010... .......... . . . . S . . . . 4 TODO: correct timing pmmu 32 . . 1111000......... .......... . . S S S . . 8 8 8 reset 0 . . 0100111001110000 .......... S S S S S 0 0 0 0 0 ror 8 s . 1110...000011... .......... U U U U U 6 6 8 8 8 @@ -915,7 +918,8 @@ M68KMAKE_OP(1111, 0, ., .) M68KMAKE_OP(040fpu0, 32, ., .) { - if(CPU_TYPE_IS_030_PLUS(CPU_TYPE)) +// printf("FPU 040fpu0 HAS_FPU=%d\n",!!HAS_FPU); + if(HAS_FPU) { m68040_fpu_op0(); return; @@ -926,7 +930,8 @@ M68KMAKE_OP(040fpu0, 32, ., .) M68KMAKE_OP(040fpu1, 32, ., .) { - if(CPU_TYPE_IS_030_PLUS(CPU_TYPE)) +// printf("FPU 040fpu1 HAS_FPU=%d\n",!!HAS_FPU); + if(HAS_FPU) { m68040_fpu_op1(); return; @@ -942,13 +947,14 @@ M68KMAKE_OP(abcd, 8, rr, .) uint src = DY; uint dst = *r_dst; uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ + uint corf = 0; if(res > 9) - res += 6; + corf = 6; res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; + FLAG_V = ~res; /* Undefined V behavior */ + res += corf; + FLAG_X = FLAG_C = (res > 0x9f) << 8; if(FLAG_C) res -= 0xa0; @@ -968,13 +974,14 @@ M68KMAKE_OP(abcd, 8, mm, ax7) uint ea = EA_A7_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ + uint corf = 0; if(res > 9) - res += 6; + corf = 6; res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; + FLAG_V = ~res; /* Undefined V behavior */ + res += corf; + FLAG_X = FLAG_C = (res > 0x9f) << 8; if(FLAG_C) res -= 0xa0; @@ -994,13 +1001,14 @@ M68KMAKE_OP(abcd, 8, mm, ay7) uint ea = EA_AX_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ + uint corf = 0; if(res > 9) - res += 6; + corf = 6; res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; + FLAG_V = ~res; /* Undefined V behavior */ + res += corf; + FLAG_X = FLAG_C = (res > 0x9f) << 8; if(FLAG_C) res -= 0xa0; @@ -1020,13 +1028,14 @@ M68KMAKE_OP(abcd, 8, mm, axy7) uint ea = EA_A7_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ + uint corf = 0; if(res > 9) - res += 6; + corf = 6; res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; + FLAG_V = ~res; /* Undefined V behavior */ + res += corf; + FLAG_X = FLAG_C = (res > 0x9f) << 8; if(FLAG_C) res -= 0xa0; @@ -1046,13 +1055,14 @@ M68KMAKE_OP(abcd, 8, mm, .) uint ea = EA_AX_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1(); - - FLAG_V = ~res; /* Undefined V behavior */ + uint corf = 0; if(res > 9) - res += 6; + corf = 6; res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst); - FLAG_X = FLAG_C = (res > 0x99) << 8; + FLAG_V = ~res; /* Undefined V behavior */ + res += corf; + FLAG_X = FLAG_C = (res > 0x9f) << 8; if(FLAG_C) res -= 0xa0; @@ -2503,7 +2513,7 @@ M68KMAKE_OP(bfchg, 32, ., .) if((width + offset) > 32) { - mask_byte = MASK_OUT_ABOVE_8(mask_base); + mask_byte = MASK_OUT_ABOVE_8(mask_base) << (8-offset); data_byte = m68ki_read_8(ea+4); FLAG_Z |= (data_byte & mask_byte); m68ki_write_8(ea+4, data_byte ^ mask_byte); @@ -2594,7 +2604,7 @@ M68KMAKE_OP(bfclr, 32, ., .) if((width + offset) > 32) { - mask_byte = MASK_OUT_ABOVE_8(mask_base); + mask_byte = MASK_OUT_ABOVE_8(mask_base) << (8-offset); data_byte = m68ki_read_8(ea+4); FLAG_Z |= (data_byte & mask_byte); m68ki_write_8(ea+4, data_byte & ~mask_byte); @@ -2655,17 +2665,20 @@ M68KMAKE_OP(bfexts, 32, ., .) if(BIT_5(word2)) width = REG_D[width&7]; - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; + if(BIT_B(word2)) { + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } } width = ((width-1) & 31) + 1; - data = m68ki_read_32(ea); + data = (offset+width) < 8 ? (m68ki_read_8(ea) << 24) : + (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea); data = MASK_OUT_ABOVE_32(data< 32) @@ -2834,7 +2850,7 @@ M68KMAKE_OP(bfffo, 32, ., .) } width = ((width-1) & 31) + 1; - data = m68ki_read_32(ea); + data = (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea); data = MASK_OUT_ABOVE_32(data< 32) @@ -2923,13 +2939,15 @@ M68KMAKE_OP(bfins, 32, ., .) if(BIT_5(word2)) width = REG_D[width&7]; - /* Offset is signed so we have to use ugly math =( */ - ea += offset / 8; - offset %= 8; - if(offset < 0) - { - offset += 8; - ea--; + if(BIT_B(word2)) { + /* Offset is signed so we have to use ugly math =( */ + ea += offset / 8; + offset %= 8; + if(offset < 0) + { + offset += 8; + ea--; + } } width = ((width-1) & 31) + 1; @@ -2941,11 +2959,18 @@ M68KMAKE_OP(bfins, 32, ., .) FLAG_Z = insert_base; insert_long = insert_base >> offset; - data_long = m68ki_read_32(ea); + data_long = (offset+width) < 8 ? (m68ki_read_8(ea) << 24) : + (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea); FLAG_V = VFLAG_CLEAR; FLAG_C = CFLAG_CLEAR; - m68ki_write_32(ea, (data_long & ~mask_long) | insert_long); + if((width + offset) < 8) { + m68ki_write_8(ea, ((data_long & ~mask_long) | insert_long) >> 24); + } else if((width + offset) < 16) { + m68ki_write_16(ea, ((data_long & ~mask_long) | insert_long) >> 16); + } else { + m68ki_write_32(ea, (data_long & ~mask_long) | insert_long); + } if((width + offset) > 32) { @@ -3141,6 +3166,7 @@ M68KMAKE_OP(bftst, 32, ., .) M68KMAKE_OP(bkpt, 0, ., .) { +// TODO: review this... if(CPU_TYPE_IS_010_PLUS(CPU_TYPE)) { m68ki_bkpt_ack(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE) ? REG_IR & 7 : 0); /* auto-disable (see m68kcpu.h) */ @@ -3153,8 +3179,9 @@ M68KMAKE_OP(bra, 8, ., .) { m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); +// TODO: review this... +// if(REG_PC == REG_PPC) +// USE_ALL_CYCLES(); } @@ -3164,8 +3191,9 @@ M68KMAKE_OP(bra, 16, ., .) REG_PC -= 2; m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_16(offset); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); +// TODO: review this... +// if(REG_PC == REG_PPC) +// USE_ALL_CYCLES(); } @@ -3177,16 +3205,19 @@ M68KMAKE_OP(bra, 32, ., .) REG_PC -= 4; m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_32(offset); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); +// TODO: review this... +// if(REG_PC == REG_PPC) +// USE_ALL_CYCLES(); return; } else { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); +// TODO: review this... + m68ki_exception_illegal(); +// m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ +// m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +// if(REG_PC == REG_PPC) +// USE_ALL_CYCLES(); } } @@ -3264,9 +3295,11 @@ M68KMAKE_OP(bsr, 32, ., .) } else { - m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - m68ki_push_32(REG_PC); - m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); +// TODO: review this... + m68ki_exception_illegal(); +// m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ +// m68ki_push_32(REG_PC); +// m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); } } @@ -3309,7 +3342,7 @@ M68KMAKE_OP(callm, 32, ., .) (void)ea; /* just to avoid an 'unused variable' warning */ M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); return; } m68ki_exception_illegal(); @@ -3580,17 +3613,25 @@ M68KMAKE_OP(chk2cmp2, 8, ., pcdi) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xff; + sint compare = REG_DA[(word2 >> 12) & 15]; + if(!BIT_F(word2)) + compare &= 0xff; + uint ea = EA_PCDI_8(); sint lower_bound = m68ki_read_pcrel_8(ea); sint upper_bound = m68ki_read_pcrel_8(ea + 1); - if(!BIT_F(word2)) - compare = (int32)(int8)compare; - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x80) { + lower_bound = (int32)(int8)lower_bound; + upper_bound = (int32)(int8)upper_bound; + + if(!BIT_F(word2)) + compare = (int32)(int8)compare; + } - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); @@ -3607,16 +3648,24 @@ M68KMAKE_OP(chk2cmp2, 8, ., pcix) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xff; + sint compare = REG_DA[(word2 >> 12) & 15]; + if(!BIT_F(word2)) + compare &= 0xff; + uint ea = EA_PCIX_8(); sint lower_bound = m68ki_read_pcrel_8(ea); sint upper_bound = m68ki_read_pcrel_8(ea + 1); - if(!BIT_F(word2)) - compare = (int32)(int8)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => ||, faster operation short circuits + if (lower_bound & 0x80) { + lower_bound = (int32)(int8)lower_bound; + upper_bound = (int32)(int8)upper_bound; + + if(!BIT_F(word2)) + compare = (int32)(int8)compare; + } - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); @@ -3632,17 +3681,25 @@ M68KMAKE_OP(chk2cmp2, 8, ., .) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xff; + sint compare = REG_DA[(word2 >> 12) & 15]; + if(!BIT_F(word2)) + compare &= 0xff; + uint ea = M68KMAKE_GET_EA_AY_8; sint lower_bound = (int8)m68ki_read_8(ea); sint upper_bound = (int8)m68ki_read_8(ea + 1); - if(!BIT_F(word2)) - compare = (int32)(int8)compare; - - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x80) { + lower_bound = (int32)(int8)lower_bound; + upper_bound = (int32)(int8)upper_bound; - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + if(!BIT_F(word2)) + compare = (int32)(int8)compare; + } + + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); @@ -3657,16 +3714,25 @@ M68KMAKE_OP(chk2cmp2, 16, ., pcdi) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; + sint compare = REG_DA[(word2 >> 12) & 15]; + if(!BIT_F(word2)) + compare &= 0xffff; + uint ea = EA_PCDI_16(); sint lower_bound = (int16)m68ki_read_pcrel_16(ea); sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2); - if(!BIT_F(word2)) - compare = (int32)(int16)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x8000) { + lower_bound = (int32)(int16)lower_bound; + upper_bound = (int32)(int16)upper_bound; - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + if(!BIT_F(word2)) + compare = (int32)(int16)compare; + } + + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); @@ -3681,16 +3747,25 @@ M68KMAKE_OP(chk2cmp2, 16, ., pcix) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; + sint compare = REG_DA[(word2 >> 12) & 15]; + if(!BIT_F(word2)) + compare &= 0xffff; + uint ea = EA_PCIX_16(); sint lower_bound = (int16)m68ki_read_pcrel_16(ea); sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2); - if(!BIT_F(word2)) - compare = (int32)(int16)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x8000) { + lower_bound = (int32)(int16)lower_bound; + upper_bound = (int32)(int16)upper_bound; + + if(!BIT_F(word2)) + compare = (int32)(int16)compare; + } - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); @@ -3705,16 +3780,25 @@ M68KMAKE_OP(chk2cmp2, 16, ., .) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]&0xffff; + sint compare = REG_DA[(word2 >> 12) & 15]; + if(!BIT_F(word2)) + compare &= 0xffff; + uint ea = M68KMAKE_GET_EA_AY_16; sint lower_bound = (int16)m68ki_read_16(ea); sint upper_bound = (int16)m68ki_read_16(ea + 2); - if(!BIT_F(word2)) - compare = (int32)(int16)compare; - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x8000) { + lower_bound = (int32)(int16)lower_bound; + upper_bound = (int32)(int16)upper_bound; + + if(!BIT_F(word2)) + compare = (int32)(int16)compare; + } - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); @@ -3728,16 +3812,22 @@ M68KMAKE_OP(chk2cmp2, 32, ., pcdi) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]; - uint ea = EA_PCDI_32(); - sint lower_bound = m68ki_read_pcrel_32(ea); - sint upper_bound = m68ki_read_pcrel_32(ea + 4); + uint32 word2 = OPER_I_16(); + sint64 compare = REG_DA[(word2 >> 12) & 15]; + uint32 ea = EA_PCDI_32(); + sint64 lower_bound = m68ki_read_pcrel_32(ea); + sint64 upper_bound = m68ki_read_pcrel_32(ea + 4); + + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x80000000) { + lower_bound = (int64)(int32)lower_bound; + upper_bound = (int64)(int32)upper_bound; + compare = (int64)(int32)compare; + } - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); return; @@ -3750,16 +3840,22 @@ M68KMAKE_OP(chk2cmp2, 32, ., pcix) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { - uint word2 = OPER_I_16(); - sint compare = REG_DA[(word2 >> 12) & 15]; - uint ea = EA_PCIX_32(); - sint lower_bound = m68ki_read_32(ea); - sint upper_bound = m68ki_read_32(ea + 4); + uint32 word2 = OPER_I_16(); + sint64 compare = REG_DA[(word2 >> 12) & 15]; + uint32 ea = EA_PCIX_32(); + sint64 lower_bound = m68ki_read_32(ea); + sint64 upper_bound = m68ki_read_32(ea + 4); + + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x80000000) { + lower_bound = (int64)(int32)lower_bound; + upper_bound = (int64)(int32)upper_bound; + compare = (int64)(int32)compare; + } - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); return; @@ -3772,17 +3868,22 @@ M68KMAKE_OP(chk2cmp2, 32, ., .) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { - uint word2 = OPER_I_16(); - // JFF changed the logic. chk2/cmp2 uses signed values, not unsigned - sint compare = REG_DA[(word2 >> 12) & 15]; - uint ea = M68KMAKE_GET_EA_AY_32; - sint lower_bound = m68ki_read_32(ea); - sint upper_bound = m68ki_read_32(ea + 4); + uint32 word2 = OPER_I_16(); + sint64 compare = REG_DA[(word2 >> 12) & 15]; + uint32 ea = M68KMAKE_GET_EA_AY_32; + sint64 lower_bound = m68ki_read_32(ea); + sint64 upper_bound = m68ki_read_32(ea + 4); + + // for signed compare, the arithmetically smaller value is the lower bound + if (lower_bound & 0x80000000) { + lower_bound = (int64)(int32)lower_bound; + upper_bound = (int64)(int32)upper_bound; + compare = (int64)(int32)compare; + } - FLAG_Z = !((upper_bound==compare) || (lower_bound==compare)); // JFF: | => || + FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET; + FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1; - FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8; - if(COND_CS() && BIT_B(word2)) m68ki_exception_trap(EXCEPTION_CHK); return; @@ -3804,7 +3905,11 @@ M68KMAKE_OP(clr, 8, ., d) M68KMAKE_OP(clr, 8, ., .) { - m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0); + uint32 ea = M68KMAKE_GET_EA_AY_8; + + if(CPU_TYPE_IS_000(CPU_TYPE)) + m68ki_read_8(ea); /* the 68000 does a dummy read, the value is discarded */ + m68ki_write_8(ea, 0); FLAG_N = NFLAG_CLEAR; FLAG_V = VFLAG_CLEAR; @@ -3826,7 +3931,11 @@ M68KMAKE_OP(clr, 16, ., d) M68KMAKE_OP(clr, 16, ., .) { - m68ki_write_16(M68KMAKE_GET_EA_AY_16, 0); + uint32 ea = M68KMAKE_GET_EA_AY_16; + + if(CPU_TYPE_IS_000(CPU_TYPE)) + m68ki_read_16(ea); /* the 68000 does a dummy read, the value is discarded */ + m68ki_write_16(ea, 0); FLAG_N = NFLAG_CLEAR; FLAG_V = VFLAG_CLEAR; @@ -3848,7 +3957,11 @@ M68KMAKE_OP(clr, 32, ., d) M68KMAKE_OP(clr, 32, ., .) { - m68ki_write_32(M68KMAKE_GET_EA_AY_32, 0); + uint32 ea = M68KMAKE_GET_EA_AY_32; + + if(CPU_TYPE_IS_000(CPU_TYPE)) + m68ki_read_32(ea); /* the 68000 does a dummy read, the value is discarded */ + m68ki_write_32(ea, 0); FLAG_N = NFLAG_CLEAR; FLAG_V = VFLAG_CLEAR; @@ -4310,7 +4423,7 @@ M68KMAKE_OP(cpbcc, 32, ., .) { M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); return; } m68ki_exception_1111(); @@ -4323,7 +4436,7 @@ M68KMAKE_OP(cpdbcc, 32, ., .) { M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); return; } m68ki_exception_1111(); @@ -4332,11 +4445,13 @@ M68KMAKE_OP(cpdbcc, 32, ., .) M68KMAKE_OP(cpgen, 32, ., .) { +// TODO: what's the condition? +// if(HAS_FPU || HAS_PMMU) if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); return; } m68ki_exception_1111(); @@ -4349,7 +4464,7 @@ M68KMAKE_OP(cpscc, 32, ., .) { M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); return; } m68ki_exception_1111(); @@ -4362,7 +4477,7 @@ M68KMAKE_OP(cptrapcc, 32, ., .) { M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); // JFF: unsupported, but at least if the trap doesn't occur, app should still work, so at least PC increase is correct REG_PC += 4; return; @@ -4370,6 +4485,15 @@ M68KMAKE_OP(cptrapcc, 32, ., .) m68ki_exception_1111(); } +M68KMAKE_OP(ftrapcc,32, ., .) +{ + if(HAS_FPU) + { + m68881_ftrap(); + } else { + m68ki_exception_1111(); + } +} M68KMAKE_OP(dbt, 16, ., .) { @@ -4431,12 +4555,12 @@ M68KMAKE_OP(divs, 16, ., d) if(src != 0) { + FLAG_C = CFLAG_CLEAR; if((uint32)*r_dst == 0x80000000 && src == -1) { FLAG_Z = 0; FLAG_N = NFLAG_CLEAR; FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; *r_dst = 0; return; } @@ -4449,7 +4573,6 @@ M68KMAKE_OP(divs, 16, ., d) FLAG_Z = quotient; FLAG_N = NFLAG_16(quotient); FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); return; } @@ -4469,12 +4592,12 @@ M68KMAKE_OP(divs, 16, ., .) if(src != 0) { + FLAG_C = CFLAG_CLEAR; if((uint32)*r_dst == 0x80000000 && src == -1) { FLAG_Z = 0; FLAG_N = NFLAG_CLEAR; FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; *r_dst = 0; return; } @@ -4487,7 +4610,6 @@ M68KMAKE_OP(divs, 16, ., .) FLAG_Z = quotient; FLAG_N = NFLAG_16(quotient); FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); return; } @@ -4505,6 +4627,7 @@ M68KMAKE_OP(divu, 16, ., d) if(src != 0) { + FLAG_C = CFLAG_CLEAR; uint quotient = *r_dst / src; uint remainder = *r_dst % src; @@ -4513,7 +4636,6 @@ M68KMAKE_OP(divu, 16, ., d) FLAG_Z = quotient; FLAG_N = NFLAG_16(quotient); FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); return; } @@ -4531,6 +4653,7 @@ M68KMAKE_OP(divu, 16, ., .) if(src != 0) { + FLAG_C = CFLAG_CLEAR; uint quotient = *r_dst / src; uint remainder = *r_dst % src; @@ -4539,7 +4662,6 @@ M68KMAKE_OP(divu, 16, ., .) FLAG_Z = quotient; FLAG_N = NFLAG_16(quotient); FLAG_V = VFLAG_CLEAR; - FLAG_C = CFLAG_CLEAR; *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16)); return; } @@ -5227,8 +5349,6 @@ M68KMAKE_OP(jmp, 32, ., .) { m68ki_jump(M68KMAKE_GET_EA_AY_32); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); } @@ -6809,7 +6929,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x003: /* TC */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_tc; return; } m68ki_exception_illegal(); @@ -6817,7 +6937,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x004: /* ITT0 */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_itt0; return; } m68ki_exception_illegal(); @@ -6825,7 +6945,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x005: /* ITT1 */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_itt1; return; } m68ki_exception_illegal(); @@ -6833,7 +6953,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x006: /* DTT0 */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_dtt0; return; } m68ki_exception_illegal(); @@ -6841,7 +6961,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x007: /* DTT1 */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_dtt1; return; } m68ki_exception_illegal(); @@ -6849,7 +6969,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x805: /* MMUSR */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_sr_040; return; } m68ki_exception_illegal(); @@ -6857,7 +6977,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x806: /* URP */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_urp_aptr; return; } m68ki_exception_illegal(); @@ -6865,7 +6985,7 @@ M68KMAKE_OP(movec, 32, cr, .) case 0x807: /* SRP */ if(CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_srp_aptr; return; } m68ki_exception_illegal(); @@ -6906,7 +7026,7 @@ M68KMAKE_OP(movec, 32, rc, .) /* 68030 can write all bits except 5-7, 040 can write all */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - REG_CACR = REG_DA[(word2 >> 12) & 15]; + REG_CACR = REG_DA[(word2 >> 12) & 15] & 0xfffffffe; // Old I cache bit not working on 040 } else if (CPU_TYPE_IS_030_PLUS(CPU_TYPE)) { @@ -6916,6 +7036,10 @@ M68KMAKE_OP(movec, 32, rc, .) { REG_CACR = REG_DA[(word2 >> 12) & 15] & 0x0f; } + + if (REG_CACR & (M68K_CACR_CI | M68K_CACR_CEI)) { + m68ki_ic_clear(); + } return; } m68ki_exception_illegal(); @@ -6964,7 +7088,16 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x003: /* TC */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_tc = REG_DA[(word2 >> 12) & 15]; + + if (m68ki_cpu.mmu_tc & 0x8000) + { + m68ki_cpu.pmmu_enabled = 1; + } + else + { + m68ki_cpu.pmmu_enabled = 0; + } return; } m68ki_exception_illegal(); @@ -6972,7 +7105,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x004: /* ITT0 */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_itt0 = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -6980,7 +7113,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x005: /* ITT1 */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_itt1 = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -6988,7 +7121,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x006: /* DTT0 */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_dtt0 = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -6996,7 +7129,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x007: /* DTT1 */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_dtt1 = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -7004,7 +7137,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x805: /* MMUSR */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_sr_040 = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -7012,7 +7145,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x806: /* URP */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_urp_aptr = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -7020,7 +7153,7 @@ M68KMAKE_OP(movec, 32, rc, .) case 0x807: /* SRP */ if (CPU_TYPE_IS_040_PLUS(CPU_TYPE)) { - /* TODO */ + m68ki_cpu.mmu_srp_aptr = REG_DA[(word2 >> 12) & 15]; return; } m68ki_exception_illegal(); @@ -7744,19 +7877,19 @@ M68KMAKE_OP(mull, 32, ., .) M68KMAKE_OP(nbcd, 8, ., d) { uint* r_dst = &DY; - uint dst = *r_dst; - uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + uint dst = MASK_OUT_ABOVE_8(*r_dst); + uint res = - dst - XFLAG_AS_1(); - if(res != 0x9a) + if(res != 0) { - FLAG_V = ~res; /* Undefined V behavior */ + FLAG_V = res; /* Undefined V behavior */ - if((res & 0x0f) == 0xa) - res = (res & 0xf0) + 0x10; + if(((res|dst) & 0x0f) == 0) + res = (res & 0xf0) + 6; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res + 0x9a); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ *r_dst = MASK_OUT_BELOW_8(*r_dst) | res; @@ -7778,18 +7911,18 @@ M68KMAKE_OP(nbcd, 8, ., .) { uint ea = M68KMAKE_GET_EA_AY_8; uint dst = m68ki_read_8(ea); - uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1()); + uint res = - dst - XFLAG_AS_1(); - if(res != 0x9a) + if(res != 0) { - FLAG_V = ~res; /* Undefined V behavior */ + FLAG_V = res; /* Undefined V behavior */ - if((res & 0x0f) == 0xa) - res = (res & 0xf0) + 0x10; + if(((res|dst) & 0x0f) == 0) + res = (res & 0xf0) + 6; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res + 0x9a); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ m68ki_write_8(ea, MASK_OUT_ABOVE_8(res)); @@ -8311,7 +8444,7 @@ M68KMAKE_OP(pack, 16, mm, ax7) ea_src = EA_AY_PD_8(); src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); - m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); + m68ki_write_8(EA_A7_PD_8(), ((src >> 8) & 0x000f) | ((src<<4) & 0x00f0)); return; } m68ki_exception_illegal(); @@ -8326,7 +8459,7 @@ M68KMAKE_OP(pack, 16, mm, ay7) uint ea_src = EA_A7_PD_8(); uint src = m68ki_read_8(ea_src); ea_src = EA_A7_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + src = (src | (m68ki_read_8(ea_src) << 8)) + OPER_I_16(); m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); return; @@ -8342,7 +8475,7 @@ M68KMAKE_OP(pack, 16, mm, axy7) uint ea_src = EA_A7_PD_8(); uint src = m68ki_read_8(ea_src); ea_src = EA_A7_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + src = (src | (m68ki_read_8(ea_src) << 8)) + OPER_I_16(); m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); return; @@ -8359,7 +8492,7 @@ M68KMAKE_OP(pack, 16, mm, .) uint ea_src = EA_AY_PD_8(); uint src = m68ki_read_8(ea_src); ea_src = EA_AY_PD_8(); - src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(); + src = (src | (m68ki_read_8(ea_src) << 8)) + OPER_I_16(); m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f)); return; @@ -8375,11 +8508,21 @@ M68KMAKE_OP(pea, 32, ., .) m68ki_push_32(ea); } -M68KMAKE_OP(pflush, 32, ., .) +M68KMAKE_OP(pflusha, 32, ., .) { - if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU)) + if (HAS_PMMU) + { + fprintf(stderr,"68040: unhandled PFLUSHA (ir=%04x)\n", REG_IR); + return; + } + m68ki_exception_1111(); +} + +M68KMAKE_OP(pflushan, 32, ., .) +{ + if (HAS_PMMU) { - fprintf(stderr,"68040: unhandled PFLUSH\n"); + fprintf(stderr,"68040: unhandled PFLUSHAN (ir=%04x)\n", REG_IR); return; } m68ki_exception_1111(); @@ -8389,7 +8532,7 @@ M68KMAKE_OP(pmmu, 32, ., .) { if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU)) { - m68881_mmu_ops(); + m68851_mmu_ops(); } else { @@ -9240,26 +9383,23 @@ M68KMAKE_OP(rte, 32, ., .) new_sr = m68ki_pull_16(); new_pc = m68ki_pull_32(); m68ki_fake_pull_16(); /* format word */ - m68ki_fake_pull_16(); /* special status word */ + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + m68ki_fake_pull_16(); /* special status */ m68ki_fake_pull_32(); /* fault address */ - m68ki_fake_pull_16(); /* unused/reserved */ - m68ki_fake_pull_16(); /* data output buffer */ - m68ki_fake_pull_16(); /* unused/reserved */ - m68ki_fake_pull_16(); /* data input buffer */ - m68ki_fake_pull_16(); /* unused/reserved */ - m68ki_fake_pull_16(); /* instruction input buffer */ - m68ki_fake_pull_32(); /* internal information, 16 words */ - m68ki_fake_pull_32(); /* (actually, we use 8 DWORDs) */ + m68ki_fake_pull_32(); /* reserved and data output buffer */ + m68ki_fake_pull_32(); /* reserved and data input buffer */ + m68ki_fake_pull_32(); /* reserved and instruction input buffer */ + m68ki_fake_pull_32(); /* 8 dwords of CPU specific undocumented data */ + m68ki_fake_pull_32(); m68ki_fake_pull_32(); m68ki_fake_pull_32(); m68ki_fake_pull_32(); m68ki_fake_pull_32(); m68ki_fake_pull_32(); m68ki_fake_pull_32(); - m68ki_jump(new_pc); - m68ki_set_sr(new_sr); - CPU_INSTR_MODE = INSTRUCTION_YES; - CPU_RUN_MODE = RUN_MODE_NORMAL; return; } CPU_INSTR_MODE = INSTRUCTION_YES; @@ -9294,6 +9434,84 @@ rte_loop: new_pc = m68ki_pull_32(); m68ki_fake_pull_16(); /* format word */ m68ki_fake_pull_32(); /* address */ + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + case 7: /* 68040 access error */ + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* $06: format word */ + m68ki_fake_pull_32(); /* $08: effective address */ + m68ki_fake_pull_16(); /* $0c: special status word */ + m68ki_fake_pull_16(); /* $0e: wb3s */ + m68ki_fake_pull_16(); /* $10: wb2s */ + m68ki_fake_pull_16(); /* $12: wb1s */ + m68ki_fake_pull_32(); /* $14: data fault address */ + m68ki_fake_pull_32(); /* $18: wb3a */ + m68ki_fake_pull_32(); /* $1c: wb3d */ + m68ki_fake_pull_32(); /* $20: wb2a */ + m68ki_fake_pull_32(); /* $24: wb2d */ + m68ki_fake_pull_32(); /* $28: wb1a */ + m68ki_fake_pull_32(); /* $2c: wb1d/pd0 */ + m68ki_fake_pull_32(); /* $30: pd1 */ + m68ki_fake_pull_32(); /* $34: pd2 */ + m68ki_fake_pull_32(); /* $38: pd3 */ + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + + case 0x0a: /* Bus Error at instruction boundary */ + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* $06: format word */ + m68ki_fake_pull_16(); /* $08: internal register */ + m68ki_fake_pull_16(); /* $0a: special status word */ + m68ki_fake_pull_16(); /* $0c: instruction pipe stage c */ + m68ki_fake_pull_16(); /* $0e: instruction pipe stage b */ + m68ki_fake_pull_32(); /* $10: data fault address */ + m68ki_fake_pull_32(); /* $14: internal registers */ + m68ki_fake_pull_32(); /* $18: data output buffer */ + m68ki_fake_pull_32(); /* $1c: internal registers */ + + m68ki_jump(new_pc); + m68ki_set_sr(new_sr); + CPU_INSTR_MODE = INSTRUCTION_YES; + CPU_RUN_MODE = RUN_MODE_NORMAL; + return; + + case 0x0b: /* Bus Error - Instruction Execution in Progress */ + new_sr = m68ki_pull_16(); + new_pc = m68ki_pull_32(); + m68ki_fake_pull_16(); /* $06: format word */ + m68ki_fake_pull_16(); /* $08: internal register */ + m68ki_fake_pull_16(); /* $0a: special status word */ + m68ki_fake_pull_16(); /* $0c: instruction pipe stage c */ + m68ki_fake_pull_16(); /* $0e: instruction pipe stage b */ + m68ki_fake_pull_32(); /* $10: data fault address */ + m68ki_fake_pull_32(); /* $14: internal registers */ + m68ki_fake_pull_32(); /* $18: data output buffer */ + m68ki_fake_pull_32(); /* $1c: internal registers */ + m68ki_fake_pull_32(); /* $20: */ + m68ki_fake_pull_32(); /* $24: stage B address */ + m68ki_fake_pull_32(); /* $28: */ + m68ki_fake_pull_32(); /* $2c: data input buffer */ + m68ki_fake_pull_32(); /* $30: */ + m68ki_fake_pull_16(); /* $34: */ + m68ki_fake_pull_16(); /* $36: version #, internal information */ + m68ki_fake_pull_32(); /* $38: */ + m68ki_fake_pull_32(); /* $3c: */ + m68ki_fake_pull_32(); /* $40: */ + m68ki_fake_pull_32(); /* $44: */ + m68ki_fake_pull_32(); /* $48: */ + m68ki_fake_pull_32(); /* $4c: */ + m68ki_fake_pull_32(); /* $50: */ + m68ki_fake_pull_32(); /* $54: */ + m68ki_fake_pull_32(); /* $58: */ + m68ki_jump(new_pc); m68ki_set_sr(new_sr); CPU_INSTR_MODE = INSTRUCTION_YES; @@ -9317,7 +9535,7 @@ M68KMAKE_OP(rtm, 32, ., .) m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n", m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR, - m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2)))); + m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE))); return; } m68ki_exception_illegal(); @@ -9345,19 +9563,23 @@ M68KMAKE_OP(sbcd, 8, rr, .) uint src = DY; uint dst = *r_dst; uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + uint corf = 0; - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; + if(res > 0xf) + corf = 6; res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) + FLAG_V = res; /* Undefined V behavior */ + if(res > 0xff) { res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + } else if(res < corf) + FLAG_X = FLAG_C = CFLAG_SET; + else + FLAG_N = FLAG_X = FLAG_C = 0; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res - corf); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ FLAG_N = NFLAG_8(res); /* Undefined N behavior */ FLAG_Z |= res; @@ -9371,19 +9593,23 @@ M68KMAKE_OP(sbcd, 8, mm, ax7) uint ea = EA_A7_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + uint corf = 0; - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; + if(res > 0xf) + corf = 6; res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) + FLAG_V = res; /* Undefined V behavior */ + if(res > 0xff) { res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + } else if(res < corf) + FLAG_X = FLAG_C = CFLAG_SET; + else + FLAG_N = FLAG_X = FLAG_C = 0; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res - corf); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ FLAG_N = NFLAG_8(res); /* Undefined N behavior */ FLAG_Z |= res; @@ -9397,19 +9623,23 @@ M68KMAKE_OP(sbcd, 8, mm, ay7) uint ea = EA_AX_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + uint corf = 0; - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; + if(res > 0xf) + corf = 6; res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) + FLAG_V = res; /* Undefined V behavior */ + if(res > 0xff) { res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + } else if(res < corf) + FLAG_X = FLAG_C = CFLAG_SET; + else + FLAG_N = FLAG_X = FLAG_C = 0; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res - corf); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ FLAG_N = NFLAG_8(res); /* Undefined N behavior */ FLAG_Z |= res; @@ -9423,19 +9653,23 @@ M68KMAKE_OP(sbcd, 8, mm, axy7) uint ea = EA_A7_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + uint corf = 0; - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; + if(res > 0xf) + corf = 6; res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) + FLAG_V = res; /* Undefined V behavior */ + if(res > 0xff) { res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + } else if(res < corf) + FLAG_X = FLAG_C = CFLAG_SET; + else + FLAG_N = FLAG_X = FLAG_C = 0; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res - corf); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ FLAG_N = NFLAG_8(res); /* Undefined N behavior */ FLAG_Z |= res; @@ -9449,19 +9683,23 @@ M68KMAKE_OP(sbcd, 8, mm, .) uint ea = EA_AX_PD_8(); uint dst = m68ki_read_8(ea); uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); + uint corf = 0; - FLAG_V = ~res; /* Undefined V behavior */ - - if(res > 9) - res -= 6; + if(res > 0xf) + corf = 6; res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src); - FLAG_X = FLAG_C = (res > 0x99) << 8; - if(FLAG_C) + FLAG_V = res; /* Undefined V behavior */ + if(res > 0xff) { res += 0xa0; + FLAG_X = FLAG_C = CFLAG_SET; + } else if(res < corf) + FLAG_X = FLAG_C = CFLAG_SET; + else + FLAG_N = FLAG_X = FLAG_C = 0; - res = MASK_OUT_ABOVE_8(res); + res = MASK_OUT_ABOVE_8(res - corf); - FLAG_V &= res; /* Undefined V behavior part II */ + FLAG_V &= ~res; /* Undefined V behavior part II */ FLAG_N = NFLAG_8(res); /* Undefined N behavior */ FLAG_Z |= res; @@ -10194,6 +10432,7 @@ M68KMAKE_OP(trapt, 16, ., .) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { + // TODO: review this... as mame is not using it... REG_PC += 2; // JFF else stackframe & return addresses are incorrect m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ return; @@ -10206,6 +10445,7 @@ M68KMAKE_OP(trapt, 32, ., .) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { + // TODO: review this... as mame is not using it... REG_PC += 4; // JFF else stackframe & return addresses are incorrect m68ki_exception_trap(EXCEPTION_TRAPV); /* HJB 990403 */ return; @@ -10262,6 +10502,7 @@ M68KMAKE_OP(trapcc, 16, ., .) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { + // TODO: review this... as mame is not using it... REG_PC += 2; /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */ if(M68KMAKE_CC) { @@ -10279,6 +10520,7 @@ M68KMAKE_OP(trapcc, 32, ., .) { if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) { + // TODO: review this... as mame is not using it... REG_PC += 4; /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */ if(M68KMAKE_CC) { @@ -10583,9 +10825,9 @@ M68KMAKE_OP(unpk, 16, mm, ax7) src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); ea_dst = EA_A7_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_A7_PD_8(); m68ki_write_8(ea_dst, src & 0xff); + ea_dst = EA_A7_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); return; } m68ki_exception_illegal(); @@ -10602,9 +10844,9 @@ M68KMAKE_OP(unpk, 16, mm, ay7) src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); ea_dst = EA_AX_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_AX_PD_8(); m68ki_write_8(ea_dst, src & 0xff); + ea_dst = EA_AX_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); return; } m68ki_exception_illegal(); @@ -10620,9 +10862,9 @@ M68KMAKE_OP(unpk, 16, mm, axy7) src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); ea_dst = EA_A7_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_A7_PD_8(); m68ki_write_8(ea_dst, src & 0xff); + ea_dst = EA_A7_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); return; } m68ki_exception_illegal(); @@ -10639,9 +10881,9 @@ M68KMAKE_OP(unpk, 16, mm, .) src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(); ea_dst = EA_AX_PD_8(); - m68ki_write_8(ea_dst, (src >> 8) & 0xff); - ea_dst = EA_AX_PD_8(); m68ki_write_8(ea_dst, src & 0xff); + ea_dst = EA_AX_PD_8(); + m68ki_write_8(ea_dst, (src >> 8) & 0xff); return; } m68ki_exception_illegal();