diff --git a/src/cpu/386.c b/src/cpu/386.c index f89a8dc968..295f94056e 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -311,12 +311,12 @@ exec386_2386(int32_t cycs) } } else if (trap) { flags_rebuild(); + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; #ifndef USE_NEW_DYNAREC oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index e4caa8a1bd..e132c0300d 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -268,6 +268,12 @@ exec386_dynarec_int(void) cpu_block_end = 0; x86_was_reset = 0; + if (trap == 2) { + /* Handle the T bit in the new TSS first. */ + CPU_BLOCK_END(); + goto block_ended; + } + while (!cpu_block_end) { # ifndef USE_NEW_DYNAREC oldcs = CS; @@ -321,13 +327,14 @@ exec386_dynarec_int(void) CPU_BLOCK_END(); } +block_ended: if (!cpu_state.abrt && trap) { + dr[6] |= (trap == 2) ? 0x8000 : 0x4000; trap = 0; # ifndef USE_NEW_DYNAREC oldcs = CS; # endif cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; x86_int(1); } @@ -542,7 +549,7 @@ exec386_dynarec_dyn(void) # endif CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) + if ((cpu_state.flags & T_FLAG) || (trap == 2)) CPU_BLOCK_END(); if (smi_line) CPU_BLOCK_END(); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 96061d3fa7..feaad59135 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -78,6 +78,10 @@ x86seg_log(const char *fmt, ...) # define x86seg_log(fmt, ...) #endif +#ifdef USE_DYNAREC +extern int cpu_block_end; +#endif + void #ifdef OPS_286_386 x86_doabrt_2386(int x86_abrt) @@ -2088,6 +2092,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) uint32_t new_edi; uint32_t new_pc; uint32_t new_flags; + uint32_t t_bit; uint32_t addr; uint32_t *segdat232 = (uint32_t *) segdat2; const x86seg *dt; @@ -2189,6 +2194,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) new_fs = readmemw(base, 0x58); new_gs = readmemw(base, 0x5C); new_ldt = readmemw(base, 0x60); + t_bit = readmemb(base, 0x64) & 1; cr0 |= 8; @@ -2279,6 +2285,13 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) op_loadseg(new_ds, &cpu_state.seg_ds); op_loadseg(new_fs, &cpu_state.seg_fs); op_loadseg(new_gs, &cpu_state.seg_gs); + + if (t_bit) { + trap = 2; +#ifdef USE_DYNAREC + cpu_block_end = 1; +#endif + } } else { if (limit < 43) { x86ts(NULL, seg);