diff options
Diffstat (limited to 'src/emu/cpu/i86/i86time.c')
-rw-r--r-- | src/emu/cpu/i86/i86time.c | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/src/emu/cpu/i86/i86time.c b/src/emu/cpu/i86/i86time.c new file mode 100644 index 00000000000..c9c1c808763 --- /dev/null +++ b/src/emu/cpu/i86/i86time.c @@ -0,0 +1,312 @@ +/**************************************************************************** +* real mode i286 emulator v1.4 by Fabrice Frances * +* (initial work based on David Hedley's pcemu) * +****************************************************************************/ + +struct i80x86_timing +{ + int id; + + UINT8 exception, iret; /* exception, IRET */ + UINT8 int3, int_imm, into_nt, into_t; /* INTs */ + UINT8 override; /* segment overrides */ + UINT8 flag_ops, lahf, sahf; /* flag operations */ + UINT8 aaa, aas, aam, aad; /* arithmetic adjusts */ + UINT8 daa, das; /* decimal adjusts */ + UINT8 cbw, cwd; /* sign extension */ + UINT8 hlt, load_ptr, lea, nop, wait, xlat; /* misc */ + + UINT8 jmp_short, jmp_near, jmp_far; /* direct JMPs */ + UINT8 jmp_r16, jmp_m16, jmp_m32; /* indirect JMPs */ + UINT8 call_near, call_far; /* direct CALLs */ + UINT8 call_r16, call_m16, call_m32; /* indirect CALLs */ + UINT8 ret_near, ret_far, ret_near_imm, ret_far_imm; /* returns */ + UINT8 jcc_nt, jcc_t, jcxz_nt, jcxz_t; /* conditional JMPs */ + UINT8 loop_nt, loop_t, loope_nt, loope_t; /* loops */ + + UINT8 in_imm8, in_imm16, in_dx8, in_dx16; /* port reads */ + UINT8 out_imm8, out_imm16, out_dx8, out_dx16; /* port writes */ + + UINT8 mov_rr8, mov_rm8, mov_mr8; /* move, 8-bit */ + UINT8 mov_ri8, mov_mi8; /* move, 8-bit immediate */ + UINT8 mov_rr16, mov_rm16, mov_mr16; /* move, 16-bit */ + UINT8 mov_ri16, mov_mi16; /* move, 16-bit immediate */ + UINT8 mov_am8, mov_am16, mov_ma8, mov_ma16; /* move, AL/AX memory */ + UINT8 mov_sr, mov_sm, mov_rs, mov_ms; /* move, segment registers */ + UINT8 xchg_rr8, xchg_rm8; /* exchange, 8-bit */ + UINT8 xchg_rr16, xchg_rm16, xchg_ar16; /* exchange, 16-bit */ + + UINT8 push_r16, push_m16, push_seg, pushf; /* pushes */ + UINT8 pop_r16, pop_m16, pop_seg, popf; /* pops */ + + UINT8 alu_rr8, alu_rm8, alu_mr8; /* ALU ops, 8-bit */ + UINT8 alu_ri8, alu_mi8, alu_mi8_ro; /* ALU ops, 8-bit immediate */ + UINT8 alu_rr16, alu_rm16, alu_mr16; /* ALU ops, 16-bit */ + UINT8 alu_ri16, alu_mi16, alu_mi16_ro; /* ALU ops, 16-bit immediate */ + UINT8 alu_r16i8, alu_m16i8, alu_m16i8_ro; /* ALU ops, 16-bit w/8-bit immediate */ + UINT8 mul_r8, mul_r16, mul_m8, mul_m16; /* MUL */ + UINT8 imul_r8, imul_r16, imul_m8, imul_m16; /* IMUL */ + UINT8 div_r8, div_r16, div_m8, div_m16; /* DIV */ + UINT8 idiv_r8, idiv_r16, idiv_m8, idiv_m16; /* IDIV */ + UINT8 incdec_r8, incdec_r16, incdec_m8, incdec_m16; /* INC/DEC */ + UINT8 negnot_r8, negnot_r16, negnot_m8, negnot_m16; /* NEG/NOT */ + + UINT8 rot_reg_1, rot_reg_base, rot_reg_bit; /* reg shift/rotate */ + UINT8 rot_m8_1, rot_m8_base, rot_m8_bit; /* m8 shift/rotate */ + UINT8 rot_m16_1, rot_m16_base, rot_m16_bit; /* m16 shift/rotate */ + + UINT8 cmps8, rep_cmps8_base, rep_cmps8_count; /* CMPS 8-bit */ + UINT8 cmps16, rep_cmps16_base, rep_cmps16_count; /* CMPS 16-bit */ + UINT8 scas8, rep_scas8_base, rep_scas8_count; /* SCAS 8-bit */ + UINT8 scas16, rep_scas16_base, rep_scas16_count; /* SCAS 16-bit */ + UINT8 lods8, rep_lods8_base, rep_lods8_count; /* LODS 8-bit */ + UINT8 lods16, rep_lods16_base, rep_lods16_count; /* LODS 16-bit */ + UINT8 stos8, rep_stos8_base, rep_stos8_count; /* STOS 8-bit */ + UINT8 stos16, rep_stos16_base, rep_stos16_count; /* STOS 16-bit */ + UINT8 movs8, rep_movs8_base, rep_movs8_count; /* MOVS 8-bit */ + UINT8 movs16, rep_movs16_base, rep_movs16_count; /* MOVS 16-bit */ + + void * check1; /* marker to make sure we line up */ + + UINT8 ins8, rep_ins8_base, rep_ins8_count; /* (80186) INS 8-bit */ + UINT8 ins16, rep_ins16_base, rep_ins16_count; /* (80186) INS 16-bit */ + UINT8 outs8, rep_outs8_base, rep_outs8_count; /* (80186) OUTS 8-bit */ + UINT8 outs16, rep_outs16_base, rep_outs16_count; /* (80186) OUTS 16-bit */ + UINT8 push_imm, pusha, popa; /* (80186) PUSH immediate, PUSHA/POPA */ + UINT8 imul_rri8, imul_rmi8; /* (80186) IMUL immediate 8-bit */ + UINT8 imul_rri16, imul_rmi16; /* (80186) IMUL immediate 16-bit */ + UINT8 enter0, enter1, enter_base, enter_count, leave; /* (80186) ENTER/LEAVE */ + UINT8 bound; /* (80186) BOUND */ + + void * check2; /* marker to make sure we line up */ +}; + + +/* these come from the 8088 timings in OPCODE.LST, but with the + penalty for 16-bit memory accesses removed wherever possible */ +static const struct i80x86_timing i8086_cycles = +{ + 8086, + + 51,32, /* exception, IRET */ + 2, 0, 4, 2, /* INTs */ + 2, /* segment overrides */ + 2, 4, 4, /* flag operations */ + 4, 4,83,60, /* arithmetic adjusts */ + 4, 4, /* decimal adjusts */ + 2, 5, /* sign extension */ + 2,24, 2, 2, 3,11, /* misc */ + + 15,15,15, /* direct JMPs */ + 11,18,24, /* indirect JMPs */ + 19,28, /* direct CALLs */ + 16,21,37, /* indirect CALLs */ + 20,32,24,31, /* returns */ + 4,16, 6,18, /* conditional JMPs */ + 5,17, 6,18, /* loops */ + + 10,14, 8,12, /* port reads */ + 10,14, 8,12, /* port writes */ + + 2, 8, 9, /* move, 8-bit */ + 4,10, /* move, 8-bit immediate */ + 2, 8, 9, /* move, 16-bit */ + 4,10, /* move, 16-bit immediate */ + 10,10,10,10, /* move, AL/AX memory */ + 2, 8, 2, 9, /* move, segment registers */ + 4,17, /* exchange, 8-bit */ + 4,17, 3, /* exchange, 16-bit */ + + 15,24,14,14, /* pushes */ + 12,25,12,12, /* pops */ + + 3, 9,16, /* ALU ops, 8-bit */ + 4,17,10, /* ALU ops, 8-bit immediate */ + 3, 9,16, /* ALU ops, 16-bit */ + 4,17,10, /* ALU ops, 16-bit immediate */ + 4,17,10, /* ALU ops, 16-bit w/8-bit immediate */ + 70,118,76,128, /* MUL */ + 80,128,86,138, /* IMUL */ + 80,144,86,154, /* DIV */ + 101,165,107,175,/* IDIV */ + 3, 2,15,15, /* INC/DEC */ + 3, 3,16,16, /* NEG/NOT */ + + 2, 8, 4, /* reg shift/rotate */ + 15,20, 4, /* m8 shift/rotate */ + 15,20, 4, /* m16 shift/rotate */ + + 22, 9,21, /* CMPS 8-bit */ + 22, 9,21, /* CMPS 16-bit */ + 15, 9,14, /* SCAS 8-bit */ + 15, 9,14, /* SCAS 16-bit */ + 12, 9,11, /* LODS 8-bit */ + 12, 9,11, /* LODS 16-bit */ + 11, 9,10, /* STOS 8-bit */ + 11, 9,10, /* STOS 16-bit */ + 18, 9,17, /* MOVS 8-bit */ + 18, 9,17, /* MOVS 16-bit */ + + (void *)-1 /* marker to make sure we line up */ +}; + + +/* these come from the Intel 80186 datasheet */ +static const struct i80x86_timing i80186_cycles = +{ + 80186, + + 45,28, /* exception, IRET */ + 0, 2, 4, 3, /* INTs */ + 2, /* segment overrides */ + 2, 2, 3, /* flag operations */ + 8, 7,19,15, /* arithmetic adjusts */ + 4, 4, /* decimal adjusts */ + 2, 4, /* sign extension */ + 2,18, 6, 2, 6,11, /* misc */ + + 14,14,14, /* direct JMPs */ + 11,17,26, /* indirect JMPs */ + 15,23, /* direct CALLs */ + 13,19,38, /* indirect CALLs */ + 16,22,18,25, /* returns */ + 4,13, 5,15, /* conditional JMPs */ + 6,16, 6,16, /* loops */ + + 10,10, 8, 8, /* port reads */ + 9, 9, 7, 7, /* port writes */ + + 2, 9,12, /* move, 8-bit */ + 3,12, /* move, 8-bit immediate */ + 2, 9,12, /* move, 16-bit */ + 4,13, /* move, 16-bit immediate */ + 8, 8, 9, 9, /* move, AL/AX memory */ + 2,11, 2,11, /* move, segment registers */ + 4,17, /* exchange, 8-bit */ + 4,17, 3, /* exchange, 16-bit */ + + 10,16, 9, 9, /* pushes */ + 10,20, 8, 8, /* pops */ + + 3,10,10, /* ALU ops, 8-bit */ + 4,16,10, /* ALU ops, 8-bit immediate */ + 3,10,10, /* ALU ops, 16-bit */ + 4,16,10, /* ALU ops, 16-bit immediate */ + 4,16,10, /* ALU ops, 16-bit w/8-bit immediate */ + 26,35,32,41, /* MUL */ + 25,34,31,40, /* IMUL */ + 29,38,35,44, /* DIV */ + 44,53,50,59, /* IDIV */ + 3, 3,15,15, /* INC/DEC */ + 3, 3,10,10, /* NEG/NOT */ + + 2, 5, 1, /* reg shift/rotate */ + 15,17, 1, /* m8 shift/rotate */ + 15,17, 1, /* m16 shift/rotate */ + + 22, 5,22, /* CMPS 8-bit */ + 22, 5,22, /* CMPS 16-bit */ + 15, 5,15, /* SCAS 8-bit */ + 15, 5,15, /* SCAS 16-bit */ + 12, 6,11, /* LODS 8-bit */ + 12, 6,11, /* LODS 16-bit */ + 10, 6, 9, /* STOS 8-bit */ + 10, 6, 9, /* STOS 16-bit */ + 14, 8, 8, /* MOVS 8-bit */ + 14, 8, 8, /* MOVS 16-bit */ + + (void *)-1, /* marker to make sure we line up */ + + 14, 8, 8, /* (80186) INS 8-bit */ + 14, 8, 8, /* (80186) INS 16-bit */ + 14, 8, 8, /* (80186) OUTS 8-bit */ + 14, 8, 8, /* (80186) OUTS 16-bit */ + 14,68,83, /* (80186) PUSH immediate, PUSHA/POPA */ + 22,29, /* (80186) IMUL immediate 8-bit */ + 25,32, /* (80186) IMUL immediate 16-bit */ + 15,25,4,16, 8, /* (80186) ENTER/LEAVE */ + 33, /* (80186) BOUND */ + + (void *)-1 /* marker to make sure we line up */ +}; + + +/* these come from the 80286 timings in OPCODE.LST */ +/* many of these numbers are suspect */ +static const struct i80x86_timing i80286_cycles = +{ + 80286, + + 23,17, /* exception, IRET */ + 0, 2, 3, 1, /* INTs */ + 2, /* segment overrides */ + 2, 2, 2, /* flag operations */ + 3, 3,16,14, /* arithmetic adjusts */ + 3, 3, /* decimal adjusts */ + 2, 2, /* sign extension */ + 2, 7, 3, 3, 3, 5, /* misc */ + + 7, 7,11, /* direct JMPs */ + 7,11,26, /* indirect JMPs */ + 7,13, /* direct CALLs */ + 7,11,29, /* indirect CALLs */ + 11,15,11,15, /* returns */ + 3, 7, 4, 8, /* conditional JMPs */ + 4, 8, 4, 8, /* loops */ + + 5, 5, 5, 5, /* port reads */ + 3, 3, 3, 3, /* port writes */ + + 2, 3, 3, /* move, 8-bit */ + 2, 3, /* move, 8-bit immediate */ + 2, 3, 3, /* move, 16-bit */ + 2, 3, /* move, 16-bit immediate */ + 5, 5, 3, 3, /* move, AL/AX memory */ + 2, 5, 2, 3, /* move, segment registers */ + 3, 5, /* exchange, 8-bit */ + 3, 5, 3, /* exchange, 16-bit */ + + 5, 5, 3, 3, /* pushes */ + 5, 5, 5, 5, /* pops */ + + 2, 7, 7, /* ALU ops, 8-bit */ + 3, 7, 7, /* ALU ops, 8-bit immediate */ + 2, 7, 7, /* ALU ops, 16-bit */ + 3, 7, 7, /* ALU ops, 16-bit immediate */ + 3, 7, 7, /* ALU ops, 16-bit w/8-bit immediate */ + 13,21,16,24, /* MUL */ + 13,21,16,24, /* IMUL */ + 14,22,17,25, /* DIV */ + 17,25,20,28, /* IDIV */ + 2, 2, 7, 7, /* INC/DEC */ + 2, 2, 7, 7, /* NEG/NOT */ + + 2, 5, 0, /* reg shift/rotate */ + 7, 8, 1, /* m8 shift/rotate */ + 7, 8, 1, /* m16 shift/rotate */ + + 13, 5,12, /* CMPS 8-bit */ + 13, 5,12, /* CMPS 16-bit */ + 9, 5, 8, /* SCAS 8-bit */ + 9, 5, 8, /* SCAS 16-bit */ + 5, 5, 4, /* LODS 8-bit */ + 5, 5, 4, /* LODS 16-bit */ + 4, 4, 3, /* STOS 8-bit */ + 4, 4, 3, /* STOS 16-bit */ + 5, 5, 4, /* MOVS 8-bit */ + 5, 5, 4, /* MOVS 16-bit */ + + (void *)-1, /* marker to make sure we line up */ + + 5, 5, 4, /* (80186) INS 8-bit */ + 5, 5, 4, /* (80186) INS 16-bit */ + 5, 5, 4, /* (80186) OUTS 8-bit */ + 5, 5, 4, /* (80186) OUTS 16-bit */ + 3,17,19, /* (80186) PUSH immediate, PUSHA/POPA */ + 21,24, /* (80186) IMUL immediate 8-bit */ + 21,24, /* (80186) IMUL immediate 16-bit */ + 11,15,12, 4, 5, /* (80186) ENTER/LEAVE */ + 13, /* (80186) BOUND */ + + (void *)-1 /* marker to make sure we line up */ +}; |