diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 891606606..4b4e74d55 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -512,35 +512,54 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) return ret; } + static int read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf) { track_info_t ti; - int len = 4; - int c, d, first_track, last_track; + int i, len = 4; + int first_track, last_track; uint32_t temp; + cdrom_log("read_toc_normal(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf); + dev->ops->get_tracks(dev, &first_track, &last_track); - b[2] = first_track; - b[3] = last_track; + /* Byte 2 = Number of the first track */ + dev->ops->get_track_info(dev, 1, 0, &ti); + b[2] = ti.number; + cdrom_log(" b[2] = %02X\n", b[2]); - d = 0; - for (c = 0; c <= last_track; c++) { - dev->ops->get_track_info(dev, c + 1, 0, &ti); - if (ti.number >= start_track) { - d = c; - break; + /* Byte 3 = Number of the last track before the lead-out track */ + dev->ops->get_track_info(dev, last_track, 0, &ti); + b[3] = ti.number; + cdrom_log(" b[3] = %02X\n", b[2]); + + if (start_track == 0x00) + first_track = 0; + else { + first_track = -1; + for (i = 0; i <= last_track; i++) { + dev->ops->get_track_info(dev, i + 1, 0, &ti); + if (ti.number >= start_track) { + first_track = i; + break; + } } } + cdrom_log(" first_track = %i, last_track = %i\n", first_track, last_track); - if (start_track != 0xAA) { - dev->ops->get_track_info(dev, c + 1, 0, &ti); - b[2] = ti.number; + /* No suitable starting track, return with error. */ + if (first_track == -1) { +#ifdef ENABLE_CDROM_LOG + cdrom_log(" [ERROR] No suitable track found\n"); +#endif + return -1; } - for (c = d; c <= last_track; c++) { - dev->ops->get_track_info(dev, c + 1, 0, &ti); + for (i = first_track; i <= last_track; i++) { + cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); + dev->ops->get_track_info(dev, i + 1, 0, &ti); b[len++] = 0; /* reserved */ b[len++] = ti.attr; @@ -572,23 +591,27 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf) int len = 4; uint32_t temp; + cdrom_log("read_toc_session(%08X, %08X, %i)\n", dev, b, msf); + + /* Bytes 2 and 3 = Number of first and last sessions */ + b[2] = b[3] = 1; + dev->ops->get_track_info(dev, 1, 0, &ti); - if (ti.number == 0) - ti.number = 1; + cdrom_log(" tracks(0) = %02X, %02X, %i:%02i.%02i\n", ti.attr, ti.number, ti.m, ti.s, ti.f); - b[2] = b[3] = 1; b[len++] = 0; /* reserved */ b[len++] = ti.attr; b[len++] = ti.number; /* track number */ b[len++] = 0; /* reserved */ + if (msf) { b[len++] = 0; b[len++] = ti.m; b[len++] = ti.s; b[len++] = ti.f; } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; /* Do the - 150. */ + temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; b[len++] = temp >> 24; b[len++] = temp >> 16; b[len++] = temp >> 8; @@ -603,28 +626,31 @@ static int read_toc_raw(cdrom_t *dev, unsigned char *b) { track_info_t ti; + int i, len = 4; int first_track, last_track; - int track, len = 4; + + cdrom_log("read_toc_raw(%08X, %08X)\n", dev, b); dev->ops->get_tracks(dev, &first_track, &last_track); - b[2] = first_track; - b[3] = last_track; + /* Bytes 2 and 3 = Number of first and last sessions */ + b[2] = b[3] = 1; - for (track = first_track; track <= last_track; track++) { - dev->ops->get_track_info(dev, track, 0, &ti); + for (i = 0; i <= last_track; i++) { + dev->ops->get_track_info(dev, i + 1, 0, &ti); - b[len++] = track; - b[len++] = ti.attr; + cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); + + b[len++] = 1; /* Session number */ + b[len++] = ti.attr; /* Track ADR and Control */ + b[len++] = 0; /* TNO (always 0) */ + b[len++] = ti.number; /* Point (for track points - track number) */ + b[len++] = ti.m; /* M */ + b[len++] = ti.s; /* S */ + b[len++] = ti.f; /* F */ b[len++] = 0; b[len++] = 0; b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; } return len; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 802069978..4552ddc00 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -262,6 +262,7 @@ cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out) } +/* TODO: This never returns anything other than 1, should it even be an int? */ int cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out) { @@ -972,8 +973,7 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile) success = 1; } else { #ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG - cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", - command.c_str()); + cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", command); #endif success = 0; } diff --git a/src/codegen_new/x86_ops_shift.h b/src/codegen_new/x86_ops_shift.h deleted file mode 100644 index 106a5701a..000000000 --- a/src/codegen_new/x86_ops_shift.h +++ /dev/null @@ -1,607 +0,0 @@ -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ - } - -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ - } - -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ - } - -static int opC0_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; -} -static int opC0_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; -} -static int opC1_w_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; -} -static int opC1_w_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; -} -static int opC1_l_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; -} -static int opC1_l_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; -} - -static int opD0_a16(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; -} -static int opD0_a32(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; -} -static int opD1_w_a16(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; -} -static int opD1_w_a32(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; -} -static int opD1_l_a16(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; -} -static int opD1_l_a32(uint32_t fetchdat) -{ - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; -} - -static int opD2_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; -} -static int opD2_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint8_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; -} -static int opD3_w_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; -} -static int opD3_w_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint16_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; -} -static int opD3_l_a16(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; -} -static int opD3_l_a32(uint32_t fetchdat) -{ - int c; - int tempc; - uint32_t temp, temp2 = 0; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; -} - - -#define SHLD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ - if (count <= 16) tempw = templ >> (16 - count); \ - else tempw = (templ << count) >> 16; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } - -#define SHLD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ - templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } - - -#define SHRD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (tempw >> (count - 1)) & 1; \ - templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ - tempw = templ >> count; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } - -#define SHRD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (templ >> (count - 1)) & 1; \ - templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } - -#define opSHxD(operation) \ - static int op ## operation ## _i_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _CL_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _i_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } \ - static int op ## operation ## _CL_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } - -opSHxD(SHLD_w) -opSHxD(SHLD_l) -opSHxD(SHRD_w) -opSHxD(SHRD_l) diff --git a/src/codegen_new/x86seg.c b/src/codegen_new/x86seg.c deleted file mode 100644 index 29d1bfc97..000000000 --- a/src/codegen_new/x86seg.c +++ /dev/null @@ -1,2600 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x86 CPU segment emulation. - * - * - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include <86box/device.h> -#include <86box/timer.h> -#include <86box/machine.h> -#include <86box/mem.h> -#include <86box/nvr.h> -#include "x86.h" -#include "x86_flags.h" -#include "386_common.h" - - -extern FILE *stdlog; /* file to log output to */ - - -/*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ -#define CS_ACCESSED - -/*Controls whether the accessed bit in a descriptor is set when a data or stack - selector is loaded.*/ -#define SEL_ACCESSED -int stimes = 0; -int dtimes = 0; -int btimes = 0; - -uint32_t abrt_error; -int cgate16, cgate32; - -#define breaknullsegs 0 - -int intgatesize; - -void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); -void taskswitch386(uint16_t seg, uint16_t *segdat); - -void pmodeint(int num, int soft); -/*NOT PRESENT is INT 0B - GPF is INT 0D*/ - - -#ifdef ENABLE_X86SEG_LOG -int x86seg_do_log = ENABLE_X86SEG_LOG; - - -static void -x86seg_log(const char *fmt, ...) -{ - va_list ap; - - if (x86seg_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -#define x86seg_log(fmt, ...) -#endif - - -void x86abort(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - - nvr_save(); -#ifdef ENABLE_808X_LOG - dumpregs(1); -#endif - fflush(stdlog); - exit(-1); -} - -uint8_t opcode2; - -static void seg_reset(x86seg *s) -{ - s->access = (0 << 5) | 2 | 0x80; - s->ar_high = 0x10; - s->limit = 0xFFFF; - s->limit_low = 0; - s->limit_high = 0xffff; - if (s == &cpu_state.seg_cs) - { - /* TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below: - s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; */ - s->base = AT ? 0xF0000 : 0xFFFF0; - s->seg = AT ? 0xF000 : 0xFFFF; - } - else - { - s->base = 0; - s->seg = 0; - } -} - -void x86seg_reset() -{ - seg_reset(&cpu_state.seg_cs); - seg_reset(&cpu_state.seg_ds); - seg_reset(&cpu_state.seg_es); - seg_reset(&cpu_state.seg_fs); - seg_reset(&cpu_state.seg_gs); - seg_reset(&cpu_state.seg_ss); -} - -void x86_doabrt(int x86_abrt) -{ - cpu_state.pc = cpu_state.oldpc; - cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; - - if (msw & 1) - pmodeint(x86_abrt, 0); - else - { - uint32_t addr = (x86_abrt << 2) + idt.base; - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - return; - } - - if (cpu_state.abrt || x86_was_reset) return; - - if (intgatesize == 16) - { - if (stack32) - { - writememw(ss, ESP-2, abrt_error); - ESP-=2; - } - else - { - writememw(ss, ((SP-2)&0xFFFF), abrt_error); - SP-=2; - } - } - else - { - if (stack32) - { - writememl(ss, ESP-4, abrt_error); - ESP-=4; - } - else - { - writememl(ss, ((SP-4)&0xFFFF), abrt_error); - SP-=4; - } - } -} -void x86gpf(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_GPF; - abrt_error = error; -} -void x86ss(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_SS; - abrt_error = error; -} -void x86ts(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_TS; - abrt_error = error; -} -void x86np(char *s, uint16_t error) -{ - cpu_state.abrt = ABRT_NP; - abrt_error = error; -} - - -static void set_stack32(int s) -{ - stack32 = s; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - else - cpu_cur_status &= ~CPU_STATUS_STACK32; -} - -static void set_use32(int u) -{ - if (u) - { - use32 = 0x300; - cpu_cur_status |= CPU_STATUS_USE32; - } - else - { - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - } -} - -void do_seg_load(x86seg *s, uint16_t *segdat) -{ - s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); - if (segdat[3] & 0x80) - s->limit = (s->limit << 12) | 0xFFF; - s->base = segdat[1] | ((segdat[2] & 0xFF) << 16); - if (is386) - s->base |= ((segdat[3] >> 8) << 24); - s->access = segdat[2] >> 8; - s->ar_high = segdat[3] & 0xff; - - if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/ - { - s->limit_high = s->limit; - s->limit_low = 0; - } - else - { - s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; - } - - if (s == &cpu_state.seg_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &cpu_state.seg_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -static void do_seg_v86_init(x86seg *s) -{ - s->access = (3 << 5) | 2 | 0x80; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; - s->limit_high = 0xffff; -} - -static void check_seg_valid(x86seg *s) -{ - int dpl = (s->access >> 5) & 3; - int valid = 1; - - if (s->seg & 4) - { - if ((s->seg & ~7) >= ldt.limit) - { - valid = 0; - } - } - else - { - if ((s->seg & ~7) >= gdt.limit) - { - valid = 0; - } - } - - switch (s->access & 0x1f) - { - case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1A: case 0x1B: /*Readable non-conforming code*/ - if ((s->seg & 3) > dpl || (CPL) > dpl) - { - valid = 0; - break; - } - break; - - case 0x1E: case 0x1F: /*Readable conforming code*/ - break; - - default: - valid = 0; - break; - } - - if (!valid) - loadseg(0, s); -} - -int loadseg(uint16_t seg, x86seg *s) -{ - uint16_t segdat[4]; - uint32_t addr; - int dpl; - - if (msw&1 && !(cpu_state.eflags&VM_FLAG)) - { - if (!(seg&~3)) - { - if (s==&cpu_state.seg_ss) - { - x86ss(NULL,0); - return 1; - } - s->seg=0; - s->access = 0x80; - s->ar_high = 0x10; - s->base=-1; - if (s == &cpu_state.seg_ds) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - return 0; - } - addr=seg&~7; - if (seg&4) - { - if ((addr+7)>ldt.limit) - { - x86gpf("loadseg(): Bigger than LDT limit",seg&~3); - return 1; - } - addr+=ldt.base; - } - else - { - if ((addr+7)>gdt.limit) - { - x86gpf("loadseg(): Bigger than GDT limit",seg&~3); - return 1; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return 1; - dpl=(segdat[2]>>13)&3; - if (s==&cpu_state.seg_ss) - { - if (!(seg&~3)) - { - x86gpf("loadseg(): Zero stack segment",seg&~3); - return 1; - } - if ((seg&3)!=CPL) - { - x86gpf("loadseg(): Stack segment RPL != CPL",seg&~3); - return 1; - } - if (dpl!=CPL) - { - x86gpf("loadseg(): Stack segment DPL != CPL",seg&~3); - return 1; - } - switch ((segdat[2]>>8)&0x1F) - { - case 0x12: case 0x13: case 0x16: case 0x17: /*r/w*/ - break; - default: - x86gpf("loadseg(): Unknown stack segment type",seg&~3); - return 1; - } - if (!(segdat[2]&0x8000)) - { - x86ss(NULL,seg&~3); - return 1; - } - set_stack32((segdat[3] & 0x40) ? 1 : 0); - } - else if (s!=&cpu_state.seg_cs) - { - x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - x86seg_log("Seg type %03X\n",segdat[2]&0x1F00); - switch ((segdat[2]>>8)&0x1F) - { - case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1A: case 0x1B: /*Readable non-conforming code*/ - if ((seg&3)>dpl) - { - x86gpf("loadseg(): Normal segment RPL > DPL",seg&~3); - return 1; - } - if ((CPL)>dpl) - { - x86gpf("loadseg(): Normal segment DPL < CPL",seg&~3); - return 1; - } - break; - case 0x1E: case 0x1F: /*Readable conforming code*/ - break; - default: - x86gpf("loadseg(): Unknown normal segment type",seg&~3); - return 1; - } - } - - if (!(segdat[2] & 0x8000)) - { - x86np("Load data seg not present", seg & 0xfffc); - return 1; - } - s->seg = seg; - do_seg_load(s, segdat); - -#ifndef CS_ACCESSED - if (s != &_cs) - { -#endif -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif -#ifndef CS_ACCESSED - } -#endif - s->checked = 0; -#ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; -#endif - } - else - { - s->access = (3 << 5) | 2 | 0x80; - s->ar_high = 0x10; - s->base = seg << 4; - s->seg = seg; - s->checked = 1; -#ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; -#endif - if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) - set_stack32(0); - } - - if (s == &cpu_state.seg_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &cpu_state.seg_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } - - return cpu_state.abrt; -} - -#define DPL ((segdat[2]>>13)&3) -#define DPL2 ((segdat2[2]>>13)&3) -#define DPL3 ((segdat3[2]>>13)&3) - -void loadcs(uint16_t seg) -{ - uint16_t segdat[4]; - uint32_t addr; - x86seg_log("Load CS %04X\n",seg); - if (msw&1 && !(cpu_state.eflags&VM_FLAG)) - { - if (!(seg&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - if (segdat[2]&0x1000) /*Normal code segment*/ - { - if (!(segdat[2]&0x400)) /*Not conforming*/ - { - if ((seg&3)>CPL) - { - x86gpf(NULL,seg&~3); - return; - } - if (CPL != DPL) - { - x86gpf("loadcs(): CPL != DPL",seg&~3); - return; - } - } - if (CPL < DPL) - { - x86gpf("loadcs(): CPL < DPL",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x40); - CS=(seg&~3)|CPL; - do_seg_load(&cpu_state.seg_cs, segdat); - use32=(segdat[3]&0x40)?0x300:0; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - } - else /*System segment*/ - { - if (!(segdat[2]&0x8000)) - { - x86np("Load CS system seg not present\n", seg & 0xfffc); - return; - } - switch (segdat[2]&0xF00) - { - default: - x86gpf(NULL,seg&~3); - return; - } - } - } - else - { - cpu_state.seg_cs.base=seg<<4; - cpu_state.seg_cs.limit=0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS=seg & 0xFFFF; - if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; - else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - } -} - -void loadcsjmp(uint16_t seg, uint32_t old_pc) -{ - uint16_t segdat[4]; - uint32_t addr; - uint16_t type,seg2; - uint32_t newpc; - if (msw&1 && !(cpu_state.eflags&VM_FLAG)) - { - if (!(seg&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - x86seg_log("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); - if (segdat[2]&0x1000) /*Normal code segment*/ - { - if (!(segdat[2]&0x400)) /*Not conforming*/ - { - if ((seg&3)>CPL) - { - x86gpf("loadcsjmp(): segment PL > CPL",seg&~3); - return; - } - if (CPL != DPL) - { - x86gpf("loadcsjmp(): CPL != DPL",seg&~3); - return; - } - } - if (CPL < DPL) - { - x86gpf("loadcsjmp(): CPL < DPL",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP not present\n", seg & 0xfffc); - return; - } - set_use32(segdat[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - CS = (seg & ~3) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - cycles -= timing_jmp_pm; - } - else /*System segment*/ - { - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP system selector not present\n", seg & 0xfffc); - return; - } - type=segdat[2]&0xF00; - newpc=segdat[0]; - if (type&0x800) newpc|=segdat[3]<<16; - switch (type) - { - case 0x400: /*Call gate*/ - case 0xC00: - cgate32=(type&0x800); - cgate16=!cgate32; - cpu_state.oldpc = cpu_state.pc; - if ((DPL < CPL) || (DPL < (seg&3))) - { - x86gpf(NULL,seg&~3); - return; - } - if (DPL < CPL) - { - x86gpf("loadcsjmp(): ex DPL < CPL",seg&~3); - return; - } - if ((DPL < (seg&3))) - { - x86gpf("loadcsjmp(): ex (DPL < (seg&3))",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP call gate not present\n", seg & 0xfffc); - return; - } - seg2=segdat[1]; - - if (!(seg2&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg2&~7; - if (seg2&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - - if (DPL > CPL) - { - x86gpf("loadcsjmp(): ex DPL > CPL",seg2&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS JMP from call gate not present\n", seg2 & 0xfffc); - return; - } - - - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ - if (DPL > CPL) - { - x86gpf(NULL,seg2&~3); - return; - } - /*FALLTHROUGH*/ - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - CS=seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - break; - - default: - x86gpf(NULL,seg2&~3); - return; - } - cycles -= timing_jmp_pm_gate; - break; - - - case 0x100: /*286 Task gate*/ - case 0x900: /*386 Task gate*/ - cpu_state.pc = old_pc; - optype=JMP; - cpl_override=1; - taskswitch286(seg,segdat,segdat[2]&0x800); - cpu_state.flags &= ~NT_FLAG; - cpl_override=0; - return; - - default: - x86gpf(NULL,0); - return; - } - } - } - else - { - cpu_state.seg_cs.base=seg<<4; - cpu_state.seg_cs.limit=0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS=seg; - if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; - else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high = 0x10; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - cycles -= timing_jmp_rm; - } -} - -void PUSHW(uint16_t v) -{ - if (stack32) - { - writememw(ss,ESP-2,v); - if (cpu_state.abrt) return; - ESP-=2; - } - else - { - writememw(ss,((SP-2)&0xFFFF),v); - if (cpu_state.abrt) return; - SP-=2; - } -} -void PUSHL(uint32_t v) -{ - if (stack32) - { - writememl(ss,ESP-4,v); - if (cpu_state.abrt) return; - ESP-=4; - } - else - { - writememl(ss,((SP-4)&0xFFFF),v); - if (cpu_state.abrt) return; - SP-=4; - } -} -uint16_t POPW() -{ - uint16_t tempw; - if (stack32) - { - tempw=readmemw(ss,ESP); - if (cpu_state.abrt) return 0; - ESP+=2; - } - else - { - tempw=readmemw(ss,SP); - if (cpu_state.abrt) return 0; - SP+=2; - } - return tempw; -} -uint32_t POPL() -{ - uint32_t templ; - if (stack32) - { - templ=readmeml(ss,ESP); - if (cpu_state.abrt) return 0; - ESP+=4; - } - else - { - templ=readmeml(ss,SP); - if (cpu_state.abrt) return 0; - SP+=4; - } - return templ; -} - -void loadcscall(uint16_t seg, uint32_t old_pc) -{ - uint16_t seg2; - uint16_t segdat[4],segdat2[4],newss; - uint32_t addr,oldssbase=ss, oaddr; - uint32_t newpc; - int count; - uint32_t oldss,oldsp,newsp, oldsp2; - int type; - uint16_t tempw; - - if (msw&1 && !(cpu_state.eflags&VM_FLAG)) - { - x86seg_log("Protected mode CS load! %04X\n", seg); - if (!(seg&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - type=segdat[2]&0xF00; - newpc=segdat[0]; - if (type&0x800) newpc|=segdat[3]<<16; - - x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]); - if (segdat[2]&0x1000) - { - if (!(segdat[2]&0x400)) /*Not conforming*/ - { - if ((seg&3)>CPL) - { - x86gpf("loadcscall(): segment > CPL",seg&~3); - return; - } - if (CPL != DPL) - { - x86gpf(NULL,seg&~3); - return; - } - } - if (CPL < DPL) - { - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86np("Load CS call not present", seg & 0xfffc); - return; - } - set_use32(segdat[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - /*Conforming segments don't change CPL, so preserve existing CPL*/ - if (segdat[2]&0x400) - { - seg = (seg & ~3) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - } - else /*On non-conforming segments, set RPL = CPL*/ - seg = (seg & ~3) | CPL; - CS=seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; -#ifdef ENABLE_X86SEG_LOG - x86seg_log("Complete\n"); -#endif - cycles -= timing_call_pm; - } - else - { - type=segdat[2]&0xF00; - x86seg_log("Type %03X\n",type); - switch (type) - { - case 0x400: /*Call gate*/ - case 0xC00: /*386 Call gate*/ - x86seg_log("Callgate %08X\n", cpu_state.pc); - cgate32=(type&0x800); - cgate16=!cgate32; - count=segdat[2]&31; - if (DPL < CPL) - { - x86gpf("loadcscall(): ex DPL < CPL",seg&~3); - return; - } - if ((DPL < (seg&3))) - { - x86gpf("loadcscall(): ex (DPL < (seg&3))",seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86seg_log("Call gate not present %04X\n",seg); - x86np("Call gate not present\n", seg & 0xfffc); - return; - } - seg2=segdat[1]; - - x86seg_log("New address : %04X:%08X\n", seg2, newpc); - - if (!(seg2&~3)) - { - x86gpf(NULL,0); - return; - } - addr=seg2&~7; - if (seg2&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg2&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - - x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n",seg2,segdat[0],segdat[1],segdat[2]); - - if (DPL > CPL) - { - x86gpf("loadcscall(): ex DPL > CPL",seg2&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - x86seg_log("Call gate CS not present %04X\n",seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } - - - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ - if (DPL < CPL) - { - uint16_t oldcs = CS; - oaddr = addr; - /*Load new stack*/ - oldss=SS; - oldsp=oldsp2=ESP; - cpl_override=1; - if (tr.access&8) - { - addr = 4 + tr.base + (DPL * 8); - newss=readmemw(0,addr+4); - newsp=readmeml(0,addr); - } - else - { - addr = 2 + tr.base + (DPL * 4); - newss=readmemw(0,addr+2); - newsp=readmemw(0,addr); - } - cpl_override=0; - if (cpu_state.abrt) return; - x86seg_log("New stack %04X:%08X\n",newss,newsp); - if (!(newss&~3)) - { - x86ts(NULL,newss&~3); - return; - } - addr=newss&~7; - if (newss&4) - { - if ((addr+7)>ldt.limit) - { - x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit); - x86ts(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if ((addr+7)>gdt.limit) - { - x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit); - x86ts(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - x86seg_log("Read stack seg\n"); - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - x86seg_log("Read stack seg done!\n"); - if (((newss & 3) != DPL) || (DPL2 != DPL)) - { - x86ts(NULL,newss&~3); - return; - } - if ((segdat2[2]&0x1A00)!=0x1200) - { - x86ts(NULL,newss&~3); - return; - } - if (!(segdat2[2]&0x8000)) - { - x86ss("Call gate loading SS not present\n", newss & 0xfffc); - return; - } - if (!stack32) oldsp &= 0xFFFF; - SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - - do_seg_load(&cpu_state.seg_ss, segdat2); - - x86seg_log("Set access 1\n"); - -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - CS=seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; - - x86seg_log("Set access 2\n"); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - x86seg_log("Type %04X\n",type); - if (type==0xC00) - { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - if (count) - { - while (count) - { - count--; - PUSHL(readmeml(oldssbase,oldsp+(count*4))); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - } - } - } - else - { - x86seg_log("Stack %04X\n",SP); - PUSHW(oldss); - x86seg_log("Write SS to %04X:%04X\n",SS,SP); - PUSHW(oldsp2); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - x86seg_log("Write SP to %04X:%04X\n",SS,SP); - if (count) - { - while (count) - { - count--; - tempw=readmemw(oldssbase,(oldsp&0xFFFF)+(count*2)); - x86seg_log("PUSH %04X\n",tempw); - PUSHW(tempw); - if (cpu_state.abrt) - { - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - } - } - } - cycles -= timing_call_pm_gate_inner; - break; - } - else if (DPL > CPL) - { - x86gpf(NULL,seg2&~3); - return; - } - /*FALLTHROUGH*/ - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - CS=seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - cycles -= timing_call_pm_gate; - break; - - default: - x86gpf(NULL,seg2&~3); - return; - } - break; - - case 0x100: /*286 Task gate*/ - case 0x900: /*386 Task gate*/ - cpu_state.pc = old_pc; - cpl_override=1; - taskswitch286(seg,segdat,segdat[2]&0x800); - cpl_override=0; - break; - - default: - x86gpf(NULL,seg&~3); - return; - } - } - } - else - { - cpu_state.seg_cs.base=seg<<4; - cpu_state.seg_cs.limit=0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS=seg; - if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; - else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high = 0x10; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - } -} - -void pmoderetf(int is32, uint16_t off) -{ - uint32_t newpc; - uint32_t newsp; - uint32_t addr, oaddr; - uint16_t segdat[4],segdat2[4],seg,newss; - uint32_t oldsp=ESP; - x86seg_log("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,cpu_state.eflags); - if (is32) - { - newpc=POPL(); - seg=POPL(); if (cpu_state.abrt) return; - } - else - { - x86seg_log("PC read from %04X:%04X\n",SS,SP); - newpc=POPW(); - x86seg_log("CS read from %04X:%04X\n",SS,SP); - seg=POPW(); if (cpu_state.abrt) return; - } - x86seg_log("Return to %04X:%08X\n",seg,newpc); - if ((seg&3)=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; } - oaddr = addr; - - x86seg_log("CPL %i RPL %i %i\n",CPL,seg&3,is32); - - if (stack32) ESP+=off; - else SP+=off; - - if (CPL==(seg&3)) - { - x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if (CPL != DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if (CPL < DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - default: - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - ESP=oldsp; - x86np("RETF CS not present\n", seg & 0xfffc); - return; - } - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - cpu_state.pc=newpc; - if (segdat[2] & 0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); - - cycles -= timing_retf_pm; - } - else - { - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if ((seg&3) != DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL); - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if ((seg&3) < DPL) - { - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - x86seg_log("RETF conforming, %i %i\n",seg&3, DPL); - break; - default: - ESP=oldsp; - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - ESP=oldsp; - x86np("RETF CS not present\n", seg & 0xfffc); - return; - } - if (is32) - { - newsp=POPL(); - newss=POPL(); if (cpu_state.abrt) return; - } - else - { - x86seg_log("SP read from %04X:%04X\n",SS,SP); - newsp=POPW(); - x86seg_log("SS read from %04X:%04X\n",SS,SP); - newss=POPW(); if (cpu_state.abrt) return; - } - x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); - if (!(newss&~3)) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr=newss&~7; - if (newss&4) - { - if (addr>=ldt.limit) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; } - x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); - if ((newss & 3) != (seg & 3)) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - if ((segdat2[2]&0x1A00)!=0x1200) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - if (!(segdat2[2]&0x8000)) - { - ESP=oldsp; - x86np("RETF loading SS not present\n", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 3)) - { - ESP=oldsp; - x86gpf(NULL,newss&~3); - return; - } - SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); - -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - -#ifdef CS_ACCESSED - writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ -#endif - cpl_override = 0; -#endif - /*Conforming segments don't change CPL, so CPL = RPL*/ - if (segdat[2]&0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); - - cpu_state.pc=newpc; - CS=seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); - - if (stack32) ESP+=off; - else SP+=off; - - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_retf_pm_outer; - } -} - -void pmodeint(int num, int soft) -{ - uint16_t segdat[4],segdat2[4],segdat3[4]; - uint32_t addr, oaddr; - uint16_t newss; - uint32_t oldss,oldsp; - int type; - uint32_t newsp; - uint16_t seg = 0; - int new_cpl; - - if (cpu_state.eflags&VM_FLAG && IOPL!=3 && soft) - { - x86seg_log("V86 banned int\n"); - x86gpf(NULL,0); - return; - } - addr=(num<<3); - if (addr>=idt.limit) - { - if (num==8) - { - /*Triple fault - reset!*/ - softresetx86(); - cpu_set_edx(); - } - else if (num==0xD) - { - pmodeint(8,0); - } - else - { - x86gpf(NULL,(num*8)+2+((soft)?0:1)); - } - x86seg_log("addr >= IDT.limit\n"); - return; - } - addr+=idt.base; - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(2,addr); - segdat[2]=readmemw(4,addr); - segdat[3]=readmemw(6,addr); cpl_override=0; - if (cpu_state.abrt) { - x86seg_log("Abrt reading from %08X\n",addr); - return; - } - oaddr = addr; - - x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]); - if (!(segdat[2]&0x1F00)) - { - x86gpf(NULL,(num*8)+2); - return; - } - if (DPL=0x800)?32:16; - if (!(segdat[2]&0x8000)) - { - x86np("Int gate not present\n", (num << 3) | 2); - return; - } - seg=segdat[1]; - new_cpl = seg & 3; - - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - oaddr = addr; - - if (DPL2 > CPL) - { - x86gpf(NULL,seg&~3); - return; - } - switch (segdat2[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if (DPL2=ldt.limit) - { - x86ss(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86ss(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat3[0]=readmemw(0,addr); - segdat3[1]=readmemw(0,addr+2); - segdat3[2]=readmemw(0,addr+4); - segdat3[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - if (((newss & 3) != DPL2) || (DPL3 != DPL2)) - { - x86ss(NULL,newss&~3); - return; - } - if ((segdat3[2]&0x1A00)!=0x1200) - { - x86ss(NULL,newss&~3); - return; - } - if (!(segdat3[2]&0x8000)) - { - x86np("Int gate loading SS not present\n", newss & 0xfffc); - return; - } - SS=newss; - set_stack32((segdat3[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - do_seg_load(&cpu_state.seg_ss, segdat3); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat3[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - x86seg_log("New stack %04X:%08X\n",SS,ESP); - cpl_override=1; - if (type>=0x800) - { - if (cpu_state.eflags & VM_FLAG) - { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - PUSHL(ES); if (cpu_state.abrt) return; - loadseg(0,&cpu_state.seg_ds); - loadseg(0,&cpu_state.seg_es); - loadseg(0,&cpu_state.seg_fs); - loadseg(0,&cpu_state.seg_gs); - } - PUSHL(oldss); - PUSHL(oldsp); - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); if (cpu_state.abrt) return; - } - else - { - PUSHW(oldss); - PUSHW(oldsp); - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); if (cpu_state.abrt) return; - } - cpl_override=0; - cpu_state.seg_cs.access=0 | 0x80; - cycles -= timing_int_pm_outer - timing_int_pm; - break; - } - else if (DPL2!=CPL) - { - x86gpf(NULL,seg&~3); - return; - } - /*FALLTHROUGH*/ - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if (!(segdat2[2]&0x8000)) - { - x86np("Int gate CS not present\n", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && DPL20x800) - { - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); if (cpu_state.abrt) return; - } - else - { - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); if (cpu_state.abrt) return; - } - new_cpl = CS & 3; - break; - default: - x86gpf(NULL,seg&~3); - return; - } - do_seg_load(&cpu_state.seg_cs, segdat2); - CS = (seg & ~3) | new_cpl; - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); - else cpu_state.pc=segdat[0]; - set_use32(segdat2[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, oaddr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - - cpu_state.eflags &= ~VM_FLAG; - cpu_cur_status &= ~CPU_STATUS_V86; - if (!(type&0x100)) - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~(T_FLAG|NT_FLAG); - cycles -= timing_int_pm; - break; - - case 0x500: /*Task gate*/ - seg=segdat[1]; - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); - cpl_override=0; if (cpu_state.abrt) return; - if (!(segdat2[2]&0x8000)) - { - x86np("Int task gate not present\n", segdat[1] & 0xfffc); - return; - } - optype=OPTYPE_INT; - cpl_override=1; - taskswitch286(seg,segdat2,segdat2[2]&0x800); - cpl_override=0; - break; - - default: - x86gpf(NULL,seg&~3); - return; - } -} - -void pmodeiret(int is32) -{ - uint32_t newsp; - uint16_t newss; - uint32_t tempflags,flagmask; - uint32_t newpc; - uint16_t segdat[4],segdat2[4]; - uint16_t segs[4]; - uint16_t seg = 0; - uint32_t addr, oaddr; - uint32_t oldsp=ESP; - if (is386 && (cpu_state.eflags & VM_FLAG)) - { - if (IOPL!=3) - { - x86gpf(NULL,0); - return; - } - if (is32) - { - newpc=POPL(); - seg=POPL(); - tempflags=POPL(); if (cpu_state.abrt) return; - } - else - { - newpc=POPW(); - seg=POPW(); - tempflags=POPW(); if (cpu_state.abrt) return; - } - cpu_state.pc=newpc; - cpu_state.seg_cs.base=seg<<4; - cpu_state.seg_cs.limit=0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.access |= 0x80; - cpu_state.seg_cs.ar_high = 0x10; - CS=seg; - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2; - cycles -= timing_iret_rm; - return; - } - - if (cpu_state.flags & NT_FLAG) - { - seg=readmemw(tr.base,0); - addr=seg&~7; - if (seg&4) - { - x86seg_log("TS LDT %04X %04X IRET\n",seg,gdt.limit); - x86ts(NULL,seg&~3); - return; - } - else - { - if (addr>=gdt.limit) - { - x86ts(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); - taskswitch286(seg,segdat,segdat[2] & 0x800); - cpl_override=0; - return; - } - flagmask=0xFFFF; - if (CPL) flagmask&=~0x3000; - if (IOPL>16)&VM_FLAG)) - { - newsp=POPL(); - newss=POPL(); - segs[0]=POPL(); - segs[1]=POPL(); - segs[2]=POPL(); - segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } - cpu_state.eflags = tempflags>>16; - cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0],&cpu_state.seg_es); - do_seg_v86_init(&cpu_state.seg_es); - loadseg(segs[1],&cpu_state.seg_ds); - do_seg_v86_init(&cpu_state.seg_ds); - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2],&cpu_state.seg_fs); - do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3],&cpu_state.seg_gs); - do_seg_v86_init(&cpu_state.seg_gs); - - cpu_state.pc = newpc & 0xffff; - cpu_state.seg_cs.base=seg<<4; - cpu_state.seg_cs.limit=0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS=seg; - cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high = 0x10; - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - - ESP=newsp; - loadseg(newss,&cpu_state.seg_ss); - do_seg_v86_init(&cpu_state.seg_ss); - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - use32=0; - cpu_cur_status &= ~CPU_STATUS_USE32; - cpu_state.flags = (tempflags&0xFFD5)|2; - cycles -= timing_iret_v86; - return; - } - } - else - { - newpc=POPW(); - seg=POPW(); - tempflags=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; } - } - if (!(seg&~3)) - { - ESP = oldsp; - x86gpf(NULL,0); - return; - } - - addr=seg&~7; - if (seg&4) - { - if (addr>=ldt.limit) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - addr+=gdt.base; - } - if ((seg&3) < CPL) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - cpl_override=1; - segdat[0]=readmemw(0,addr); - segdat[1]=readmemw(0,addr+2); - segdat[2]=readmemw(0,addr+4); - segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } - - switch (segdat[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ - if ((seg&3) != DPL) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming code*/ - if ((seg&3) < DPL) - { - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - break; - default: - ESP = oldsp; - x86gpf(NULL,seg&~3); - return; - } - if (!(segdat[2]&0x8000)) - { - ESP = oldsp; - x86np("IRET CS not present\n", seg & 0xfffc); - return; - } - if ((seg&3) == CPL) - { - CS=seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3]&0x40); - -#ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; -#endif - cycles -= timing_iret_pm; - } - else /*Return to outer level*/ - { - oaddr = addr; - x86seg_log("Outer level\n"); - if (is32) - { - newsp=POPL(); - newss=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } - } - else - { - newsp=POPW(); - newss=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; } - } - - x86seg_log("IRET load stack %04X:%04X\n",newss,newsp); - - if (!(newss&~3)) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr=newss&~7; - if (newss&4) - { - if (addr>=ldt.limit) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - addr+=gdt.base; - } - cpl_override=1; - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } - if ((newss & 3) != (seg & 3)) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - if ((segdat2[2]&0x1A00)!=0x1200) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - if (DPL2 != (seg & 3)) - { - ESP = oldsp; - x86gpf(NULL,newss&~3); - return; - } - if (!(segdat2[2]&0x8000)) - { - ESP = oldsp; - x86np("IRET loading SS not present\n", newss & 0xfffc); - return; - } - SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) ESP=newsp; - else SP=newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); - -#ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr+4, segdat2[2] | 0x100); /*Set accessed bit*/ - -#ifdef CS_ACCESSED - writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ -#endif - cpl_override = 0; -#endif - /*Conforming segments don't change CPL, so CPL = RPL*/ - if (segdat[2]&0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); - - CS=seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); - - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_iret_pm_outer; - } - cpu_state.pc=newpc; - cpu_state.flags = (cpu_state.flags&~flagmask) | (tempflags&flagmask&0xFFD5)|2; - if (is32) cpu_state.eflags = tempflags>>16; -} - -void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) -{ - uint32_t base; - uint32_t limit; - uint32_t templ; - uint16_t tempw; - - uint32_t new_cr3=0; - uint16_t new_es,new_cs,new_ss,new_ds,new_fs,new_gs; - uint16_t new_ldt; - - uint32_t new_eax,new_ebx,new_ecx,new_edx,new_esp,new_ebp,new_esi,new_edi,new_pc,new_flags; - - uint32_t addr; - - uint16_t segdat2[4]; - - base=segdat[1]|((segdat[2]&0xFF)<<16); - limit=segdat[0]; - if(is386) - { - base |= (segdat[3]>>8)<<24; - limit |= (segdat[3]&0xF)<<16; - } - - if (is32) - { - if (limit < 103) - { - x86ts(NULL, seg); - return; - } - - if (optype==JMP || optype==CALL || optype==OPTYPE_INT) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); - if (cpu_state.abrt) return; - tempw|=0x200; - if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==IRET) cpu_state.flags&=~NT_FLAG; - - cpu_386_flags_rebuild(); - writememl(tr.base,0x1C,cr3); - writememl(tr.base,0x20,cpu_state.pc); - writememl(tr.base,0x24,cpu_state.flags | (cpu_state.eflags<<16)); - - writememl(tr.base,0x28,EAX); - writememl(tr.base,0x2C,ECX); - writememl(tr.base,0x30,EDX); - writememl(tr.base,0x34,EBX); - writememl(tr.base,0x38,ESP); - writememl(tr.base,0x3C,EBP); - writememl(tr.base,0x40,ESI); - writememl(tr.base,0x44,EDI); - - writememl(tr.base,0x48,ES); - writememl(tr.base,0x4C,CS); - writememl(tr.base,0x50,SS); - writememl(tr.base,0x54,DS); - writememl(tr.base,0x58,FS); - writememl(tr.base,0x5C,GS); - - if (optype==JMP || optype==IRET) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); - else tempw=readmemw(gdt.base,(tr.seg&~7)+4); - if (cpu_state.abrt) return; - tempw&=~0x200; - if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); - else writememw(gdt.base,(tr.seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==OPTYPE_INT || optype==CALL) - { - writememl(base,0,tr.seg); - if (cpu_state.abrt) - return; - } - - - new_cr3=readmeml(base,0x1C); - new_pc=readmeml(base,0x20); - new_flags=readmeml(base,0x24); - if (optype == OPTYPE_INT || optype == CALL) - new_flags |= NT_FLAG; - - new_eax=readmeml(base,0x28); - new_ecx=readmeml(base,0x2C); - new_edx=readmeml(base,0x30); - new_ebx=readmeml(base,0x34); - new_esp=readmeml(base,0x38); - new_ebp=readmeml(base,0x3C); - new_esi=readmeml(base,0x40); - new_edi=readmeml(base,0x44); - - new_es=readmemw(base,0x48); - new_cs=readmemw(base,0x4C); - new_ss=readmemw(base,0x50); - new_ds=readmemw(base,0x54); - new_fs=readmemw(base,0x58); - new_gs=readmemw(base,0x5C); - new_ldt=readmemw(base,0x60); - - cr0 |= 8; - - cr3=new_cr3; - flushmmucache(); - - cpu_state.pc=new_pc; - cpu_state.flags = new_flags; - cpu_state.eflags = new_flags>>16; - cpu_386_flags_extract(); - - ldt.seg=new_ldt; - templ=(ldt.seg&~7)+gdt.base; - ldt.limit=readmemw(0,templ); - if (readmemb(0,templ+6)&0x80) - { - ldt.limit<<=12; - ldt.limit|=0xFFF; - } - ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); - - if (cpu_state.eflags & VM_FLAG) - { - loadcs(new_cs); - set_use32(0); - cpu_cur_status |= CPU_STATUS_V86; - } - else - { - if (!(new_cs&~3)) - { - x86ts(NULL,0); - return; - } - addr=new_cs&~7; - if (new_cs&4) - { - if (addr>=ldt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=gdt.base; - } - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); - if (!(segdat2[2]&0x8000)) - { - x86np("TS loading CS not present\n", new_cs & 0xfffc); - return; - } - switch (segdat2[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if ((new_cs&3) != DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if ((new_cs&3) < DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - default: - x86ts(NULL,new_cs&~3); - return; - } - - CS=new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat2[3] & 0x40); - cpu_cur_status &= ~CPU_STATUS_V86; - } - - EAX=new_eax; - ECX=new_ecx; - EDX=new_edx; - EBX=new_ebx; - ESP=new_esp; - EBP=new_ebp; - ESI=new_esi; - EDI=new_edi; - - loadseg(new_es,&cpu_state.seg_es); - loadseg(new_ss,&cpu_state.seg_ss); - loadseg(new_ds,&cpu_state.seg_ds); - loadseg(new_fs,&cpu_state.seg_fs); - loadseg(new_gs,&cpu_state.seg_gs); - } - else - { - if (limit < 43) - { - x86ts(NULL, seg); - return; - } - - if (optype==JMP || optype==CALL || optype==OPTYPE_INT) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); - if (cpu_state.abrt) return; - tempw|=0x200; - if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; - - cpu_386_flags_rebuild(); - writememw(tr.base,0x0E,cpu_state.pc); - writememw(tr.base,0x10,cpu_state.flags); - - writememw(tr.base,0x12,AX); - writememw(tr.base,0x14,CX); - writememw(tr.base,0x16,DX); - writememw(tr.base,0x18,BX); - writememw(tr.base,0x1A,SP); - writememw(tr.base,0x1C,BP); - writememw(tr.base,0x1E,SI); - writememw(tr.base,0x20,DI); - - writememw(tr.base,0x22,ES); - writememw(tr.base,0x24,CS); - writememw(tr.base,0x26,SS); - writememw(tr.base,0x28,DS); - - if (optype==JMP || optype==IRET) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); - else tempw=readmemw(gdt.base,(tr.seg&~7)+4); - if (cpu_state.abrt) return; - tempw&=~0x200; - if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); - else writememw(gdt.base,(tr.seg&~7)+4,tempw); - } - if (cpu_state.abrt) return; - - if (optype==OPTYPE_INT || optype==CALL) - { - writememw(base,0,tr.seg); - if (cpu_state.abrt) - return; - } - - new_pc=readmemw(base,0x0E); - new_flags=readmemw(base,0x10); - if (optype == OPTYPE_INT || optype == CALL) - new_flags |= NT_FLAG; - - new_eax=readmemw(base,0x12); - new_ecx=readmemw(base,0x14); - new_edx=readmemw(base,0x16); - new_ebx=readmemw(base,0x18); - new_esp=readmemw(base,0x1A); - new_ebp=readmemw(base,0x1C); - new_esi=readmemw(base,0x1E); - new_edi=readmemw(base,0x20); - - new_es=readmemw(base,0x22); - new_cs=readmemw(base,0x24); - new_ss=readmemw(base,0x26); - new_ds=readmemw(base,0x28); - new_ldt=readmemw(base,0x2A); - - msw |= 8; - - cpu_state.pc=new_pc; - cpu_state.flags = new_flags; - cpu_386_flags_extract(); - - ldt.seg=new_ldt; - templ=(ldt.seg&~7)+gdt.base; - ldt.limit=readmemw(0,templ); - ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); - if (is386) - { - if (readmemb(0,templ+6)&0x80) - { - ldt.limit<<=12; - ldt.limit|=0xFFF; - } - ldt.base|=(readmemb(0,templ+7)<<24); - } - - if (!(new_cs&~3)) - { - x86ts(NULL,0); - return; - } - addr=new_cs&~7; - if (new_cs&4) - { - if (addr>=ldt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=ldt.base; - } - else - { - if (addr>=gdt.limit) - { - x86ts(NULL,new_cs&~3); - return; - } - addr+=gdt.base; - } - segdat2[0]=readmemw(0,addr); - segdat2[1]=readmemw(0,addr+2); - segdat2[2]=readmemw(0,addr+4); - segdat2[3]=readmemw(0,addr+6); - if (!(segdat2[2]&0x8000)) - { - x86np("TS loading CS not present\n", new_cs & 0xfffc); - return; - } - switch (segdat2[2]&0x1F00) - { - case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ - if ((new_cs&3) != DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ - if ((new_cs&3) < DPL2) - { - x86ts(NULL,new_cs&~3); - return; - } - break; - default: - x86ts(NULL,new_cs&~3); - return; - } - - CS=new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - set_use32(0); - - EAX=new_eax | 0xFFFF0000; - ECX=new_ecx | 0xFFFF0000; - EDX=new_edx | 0xFFFF0000; - EBX=new_ebx | 0xFFFF0000; - ESP=new_esp | 0xFFFF0000; - EBP=new_ebp | 0xFFFF0000; - ESI=new_esi | 0xFFFF0000; - EDI=new_edi | 0xFFFF0000; - - loadseg(new_es,&cpu_state.seg_es); - loadseg(new_ss,&cpu_state.seg_ss); - loadseg(new_ds,&cpu_state.seg_ds); - if (is386) - { - loadseg(0,&cpu_state.seg_fs); - loadseg(0,&cpu_state.seg_gs); - } - } - - tr.seg=seg; - tr.base=base; - tr.limit=limit; - tr.access=segdat[2]>>8; - tr.ar_high = 0x10; -} - diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 63ed7631a..e09d9b76e 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -74,9 +74,10 @@ smram_t temp_smram[2]; /* SMM feature masks */ #define SMM_IO_INSTRUCTION_RESTART (0x00010000) #define SMM_SMBASE_RELOCATION (0x00020000) +#define SMM_REVISION (0x20000000) /* TODO: Which CPU added SMBASE relocation? */ -#define SMM_REVISION_ID SMM_SMBASE_RELOCATION +#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) #define SMM_SAVE_STATE_MAP_SIZE 128 @@ -989,7 +990,7 @@ enter_smm(int in_hlt) uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supporter, do nothing. */ - if (!is_pentium && !is_k5 && !is_k6 && !is_p6) + if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6) return; x386_common_log("enter_smm(): smbase = %08X\n", smbase); @@ -1146,7 +1147,7 @@ leave_smm(void) uint32_t smram_state = smbase + 0x10000; /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ - if (!is_pentium && !is_k5 && !is_k6 && !is_p6) + if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6) return; memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 2cde6d9c5..f64f6ce8c 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -980,7 +980,7 @@ reset_common(int hard) smi_block = 0; if (hard) { - smbase = 0x00030000; + smbase = is_am486 ? 0x00060000 : 0x00030000; ppi_reset(); } in_sys = 0; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 122e0f732..ebb3fbfc4 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1726,6 +1726,7 @@ cpu_set(void) x87_timings = x87_timings_387; break; + case FPU_487SX: default: x87_timings = x87_timings_486; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index c63aacfc7..1d15bb9c6 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -27,6 +27,7 @@ enum { FPU_287, FPU_287XL, FPU_387, + FPU_487SX, FPU_INTERNAL }; diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index ca84055db..bb4251640 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -73,6 +73,12 @@ FPU fpus_80386[] = {"387", "387", FPU_387}, {NULL, NULL, 0} }; +FPU fpus_486sx[] = +{ + {"None", "none", FPU_NONE}, + {"487SX","487sx", FPU_487SX}, + {NULL, NULL, 0} +}; FPU fpus_internal[] = { {"Internal", "internal", FPU_INTERNAL}, @@ -259,12 +265,12 @@ CPU cpus_486DLC[] = { CPU cpus_i486S1[] = { /*i486*/ - {"i486SX/16", CPU_i486SX, fpus_none, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, - {"i486SX/20", CPU_i486SX, fpus_none, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, - {"i486SX/25", CPU_i486SX, fpus_none, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, - {"i486SX/33", CPU_i486SX, fpus_none, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, - {"i486SX2/50", CPU_i486SX2, fpus_none, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_none, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, + {"i486SX/16", CPU_i486SX, fpus_486sx, 16000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2}, + {"i486SX/20", CPU_i486SX, fpus_486sx, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/25", CPU_i486SX, fpus_486sx, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, + {"i486SX/33", CPU_i486SX, fpus_486sx, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, + {"i486SX2/50", CPU_i486SX2, fpus_486sx, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_486sx, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8}, {"i486DX/25", CPU_i486DX, fpus_internal, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, {"i486DX/33", CPU_i486DX, fpus_internal, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, {"i486DX/50", CPU_i486DX, fpus_internal, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6}, @@ -277,10 +283,10 @@ CPU cpus_i486S1[] = { }; CPU cpus_Am486S1[] = { /*Am486*/ - {"Am486SX/33", CPU_Am486SX, fpus_none, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486SX/40", CPU_Am486SX, fpus_none, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486SX2/50", CPU_Am486SX2, fpus_none, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX2, fpus_none, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486SX/33", CPU_Am486SX, fpus_486sx, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, fpus_486sx, 40000000, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, fpus_486sx, 50000000, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, fpus_486sx, 66666666, 2, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ {"Am486DX/33", CPU_Am486DX, fpus_internal, 33333333, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Am486DX/40", CPU_Am486DX, fpus_internal, 40000000, 1, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Am486DX2/50", CPU_Am486DX2, fpus_internal, 50000000, 2, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, @@ -290,9 +296,9 @@ CPU cpus_Am486S1[] = { }; CPU cpus_Cx486S1[] = { /*Cyrix 486*/ - {"Cx486S/25", CPU_Cx486S, fpus_none, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"Cx486S/33", CPU_Cx486S, fpus_none, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486S/40", CPU_Cx486S, fpus_none, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486S/25", CPU_Cx486S, fpus_486sx, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, fpus_486sx, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, fpus_486sx, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Cx486DX/33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Cx486DX/40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Cx486DX2/50", CPU_Cx486DX2, fpus_internal, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, @@ -303,12 +309,12 @@ CPU cpus_Cx486S1[] = { CPU cpus_i486[] = { /*i486/P24T*/ - {"i486SX/16", CPU_i486SX, fpus_none, 16000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2}, - {"i486SX/20", CPU_i486SX, fpus_none, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486SX/25", CPU_i486SX, fpus_none, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486SX/33", CPU_i486SX, fpus_none, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"i486SX2/50", CPU_i486SX2, fpus_none, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, - {"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_none, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8}, + {"i486SX/16", CPU_i486SX, fpus_486sx, 16000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2}, + {"i486SX/20", CPU_i486SX, fpus_486sx, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486SX/25", CPU_i486SX, fpus_486sx, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486SX/33", CPU_i486SX, fpus_486sx, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"i486SX2/50", CPU_i486SX2, fpus_486sx, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX2, fpus_486sx, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8}, {"i486DX/25", CPU_i486DX, fpus_internal, 25000000, 1.0, 0x404, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, {"i486DX/33", CPU_i486DX, fpus_internal, 33333333, 1.0, 0x414, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"i486DX/50", CPU_i486DX, fpus_internal, 50000000, 1.0, 0x411, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6}, @@ -326,10 +332,10 @@ CPU cpus_i486[] = { CPU cpus_Am486[] = { /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, fpus_none, 33333333, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486SX/40", CPU_Am486SX, fpus_none, 40000000, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486SX2/50", CPU_Am486SX2, fpus_none, 50000000, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX2, fpus_none, 66666666, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, + {"Am486SX/33", CPU_Am486SX, fpus_486sx, 33333333, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, fpus_486sx, 40000000, 1.0, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX2, fpus_486sx, 50000000, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX2, fpus_486sx, 66666666, 2.0, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, {"Am486DX/33", CPU_Am486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Am486DX/40", CPU_Am486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Am486DX2/50", CPU_Am486DX2, fpus_internal, 50000000, 2.0, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, @@ -347,9 +353,9 @@ CPU cpus_Am486[] = { CPU cpus_Cx486[] = { /*Cyrix 486*/ - {"Cx486S/25", CPU_Cx486S, fpus_none, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"Cx486S/33", CPU_Cx486S, fpus_none, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486S/40", CPU_Cx486S, fpus_none, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486S/25", CPU_Cx486S, fpus_486sx, 25000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, fpus_486sx, 33333333, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, fpus_486sx, 40000000, 1.0, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Cx486DX/33", CPU_Cx486DX, fpus_internal, 33333333, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, {"Cx486DX/40", CPU_Cx486DX, fpus_internal, 40000000, 1.0, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, {"Cx486DX2/50", CPU_Cx486DX2, fpus_internal, 50000000, 2.0, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, diff --git a/src/codegen/x86_ops_shift.h b/src/cpu/x86_ops_shift.h similarity index 63% rename from src/codegen/x86_ops_shift.h rename to src/cpu/x86_ops_shift.h index 5cf44943d..b2812d8a7 100644 --- a/src/codegen/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -1,3 +1,235 @@ +#ifdef USE_NEW_DYNAREC +#define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) \ + { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) \ + { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) \ + { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x20: case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t)temp >> c; \ + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + } \ + } + +#define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) \ + { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) \ + { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) \ + { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x20: case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t)temp >> c; \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + } \ + } + +#define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) \ + { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32-c)); \ + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROL32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32-c)); \ + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) \ + { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) \ + { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + break; \ + case 0x20: case 0x30: /*SHL l, c*/ \ + seteal(temp << c); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t)temp >> c; \ + seteal(temp); if (cpu_state.abrt) return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + break; \ + } \ + } +#else #define OP_SHIFT_b(c, ea32) \ { \ uint8_t temp_orig = temp; \ @@ -240,6 +472,7 @@ break; \ } \ } +#endif static int opC0_a16(uint32_t fetchdat) { @@ -564,7 +797,7 @@ static int opD3_l_a32(uint32_t fetchdat) if (cpu_mod != 3) \ SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = getbyte() & 31; \ - operation() \ + operation(); \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ @@ -578,7 +811,7 @@ static int opD3_l_a32(uint32_t fetchdat) if (cpu_mod != 3) \ SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = CL & 31; \ - operation() \ + operation(); \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ @@ -592,7 +825,7 @@ static int opD3_l_a32(uint32_t fetchdat) if (cpu_mod != 3) \ SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = getbyte() & 31; \ - operation() \ + operation(); \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ @@ -606,7 +839,7 @@ static int opD3_l_a32(uint32_t fetchdat) if (cpu_mod != 3) \ SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = CL & 31; \ - operation() \ + operation(); \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ diff --git a/src/codegen/x86seg.c b/src/cpu/x86seg.c similarity index 93% rename from src/codegen/x86seg.c rename to src/cpu/x86seg.c index 17d6f279b..d53ee8a83 100644 --- a/src/codegen/x86seg.c +++ b/src/cpu/x86seg.c @@ -36,6 +36,8 @@ #include "386_common.h" +extern FILE *stdlog; + /*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ #define CS_ACCESSED @@ -106,11 +108,9 @@ static void seg_reset(x86seg *s) s->limit = 0xFFFF; s->limit_low = 0; s->limit_high = 0xffff; - if(s == &cpu_state.seg_cs) + if (s == &cpu_state.seg_cs) { - // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; - // s->base = AT ? 0xF0000 : 0xFFFF0; s->seg = AT ? 0xF000 : 0xFFFF; } else @@ -118,7 +118,6 @@ static void seg_reset(x86seg *s) s->base = 0; s->seg = 0; } - } void x86seg_reset() @@ -133,7 +132,9 @@ void x86seg_reset() void x86_doabrt(int x86_abrt) { +#ifndef USE_NEW_DYNAREC CS = oldcs; +#endif cpu_state.pc = cpu_state.oldpc; cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; cpu_state.seg_cs.ar_high = 0x10; @@ -158,9 +159,11 @@ void x86_doabrt(int x86_abrt) SP-=6; } - cpu_state.flags&=~I_FLAG; - cpu_state.flags&=~T_FLAG; - oxpc=cpu_state.pc; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); return; @@ -249,7 +252,7 @@ void do_seg_load(x86seg *s, uint16_t *segdat) if (is386) s->base |= ((segdat[3] >> 8) << 24); s->access = segdat[2] >> 8; - s->ar_high = segdat[3] & 0xff; + s->ar_high = segdat[3] & 0xff; if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/ { @@ -331,7 +334,11 @@ static void check_seg_valid(x86seg *s) loadseg(0, s); } +#ifdef USE_NEW_DYNAREC +int loadseg(uint16_t seg, x86seg *s) +#else void loadseg(uint16_t seg, x86seg *s) +#endif { uint16_t segdat[4]; uint32_t addr; @@ -344,7 +351,11 @@ void loadseg(uint16_t seg, x86seg *s) if (s==&cpu_state.seg_ss) { x86ss(NULL,0); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } s->seg = 0; s->access = 0x80; @@ -352,32 +363,36 @@ void loadseg(uint16_t seg, x86seg *s) s->base=-1; if (s == &cpu_state.seg_ds) cpu_cur_status |= CPU_STATUS_NOTFLATDS; +#ifdef USE_NEW_DYNAREC + return 0; +#else return; +#endif } addr=seg&~7; if (seg&4) { -#if 0 - if (addr>=ldt.limit) -#else if ((addr+7)>ldt.limit) -#endif { x86gpf("loadseg(): Bigger than LDT limit",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } addr+=ldt.base; } else { -#if 0 - if (addr>=gdt.limit) -#else if ((addr+7)>gdt.limit) -#endif { x86gpf("loadseg(): Bigger than GDT limit",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } addr+=gdt.base; } @@ -385,24 +400,40 @@ void loadseg(uint16_t seg, x86seg *s) segdat[0]=readmemw(0,addr); segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); +#ifdef USE_NEW_DYNAREC + segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return 1; +#else segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; +#endif dpl=(segdat[2]>>13)&3; if (s==&cpu_state.seg_ss) { if (!(seg&~3)) { - x86gpf("loadseg(): Stack segment is zero",seg&~3); + x86gpf("loadseg(): Zero stack segment",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } if ((seg&3)!=CPL) { x86gpf("loadseg(): Stack segment RPL != CPL",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } if (dpl!=CPL) { x86gpf("loadseg(): Stack segment DPL != CPL",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } switch ((segdat[2]>>8)&0x1F) { @@ -410,12 +441,20 @@ void loadseg(uint16_t seg, x86seg *s) break; default: x86gpf("loadseg(): Unknown stack segment type",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } if (!(segdat[2]&0x8000)) { x86ss(NULL,seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } set_stack32((segdat[3] & 0x40) ? 1 : 0); } @@ -430,33 +469,49 @@ void loadseg(uint16_t seg, x86seg *s) case 0x1A: case 0x1B: /*Readable non-conforming code*/ if ((seg&3)>dpl) { - x86gpf("loadseg(): Normal segment is zero",seg&~3); + x86gpf("loadseg(): Normal segment RPL > DPL",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } if ((CPL)>dpl) { x86gpf("loadseg(): Normal segment DPL < CPL",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } break; case 0x1E: case 0x1F: /*Readable conforming code*/ break; default: x86gpf("loadseg(): Unknown normal segment type",seg&~3); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } } if (!(segdat[2] & 0x8000)) { x86np("Load data seg not present", seg & 0xfffc); +#ifdef USE_NEW_DYNAREC + return 1; +#else return; +#endif } s->seg = seg; do_seg_load(s, segdat); #ifndef CS_ACCESSED - if (s != &cpu_state.seg_cs) + if (s != &_cs) { #endif #ifdef SEL_ACCESSED @@ -506,6 +561,10 @@ void loadseg(uint16_t seg, x86seg *s) else cpu_cur_status |= CPU_STATUS_NOTFLATSS; } + +#ifdef USE_NEW_DYNAREC + return cpu_state.abrt; +#endif } #define DPL ((segdat[2]>>13)&3) @@ -521,7 +580,7 @@ void loadcs(uint16_t seg) { if (!(seg&~3)) { - x86gpf(NULL,0); + x86gpf("loadcs(): Protected mode selector is zero",0); return; } addr=seg&~7; @@ -578,7 +637,10 @@ void loadcs(uint16_t seg) do_seg_load(&cpu_state.seg_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif + #ifdef CS_ACCESSED cpl_override = 1; writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ @@ -589,7 +651,7 @@ void loadcs(uint16_t seg) { if (!(segdat[2]&0x8000)) { - x86np("Load CS system seg not present", seg & 0xfffc); + x86np("Load CS system seg not present\n", seg & 0xfffc); return; } switch (segdat[2]&0xF00) @@ -609,8 +671,11 @@ void loadcs(uint16_t seg) CS=seg & 0xFFFF; if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high = 0x10; + cpu_state.seg_cs.ar_high = 0x10; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif } } @@ -690,6 +755,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc) do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif cycles -= timing_jmp_pm; } else /*System segment*/ @@ -708,7 +776,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc) case 0xC00: cgate32=(type&0x800); cgate16=!cgate32; +#ifndef USE_NEW_DYNAREC oldcs=CS; +#endif cpu_state.oldpc = cpu_state.pc; if (DPL < CPL) { @@ -720,16 +790,6 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc) x86gpf("loadcsjmp(): Call gate DPL< RPL",seg&~3); return; } - if (DPL < CPL) - { - x86gpf("loadcsjmp(): ex DPL < CPL",seg&~3); - return; - } - if ((DPL < (seg&3))) - { - x86gpf("loadcsjmp(): ex (DPL < (seg&3))",seg&~3); - return; - } if (!(segdat[2]&0x8000)) { x86np("Load CS JMP call gate not present\n", seg & 0xfffc); @@ -792,7 +852,9 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc) CS=seg2; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -813,7 +875,7 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc) case 0x100: /*286 Task gate*/ case 0x900: /*386 Task gate*/ - cpu_state.pc=old_pc; + cpu_state.pc = old_pc; optype=JMP; cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); @@ -836,8 +898,11 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc) CS=seg; if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high = 0x10; + cpu_state.seg_cs.ar_high = 0x10; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif cycles -= timing_jmp_rm; } } @@ -907,7 +972,11 @@ uint32_t POPL() return templ; } +#ifdef USE_NEW_DYNAREC +void loadcscall(uint16_t seg, uint32_t old_pc) +#else void loadcscall(uint16_t seg) +#endif { uint16_t seg2; uint16_t segdat[4],segdat2[4],newss; @@ -917,7 +986,7 @@ void loadcscall(uint16_t seg) uint32_t oldss,oldsp,newsp, oldsp2; int type; uint16_t tempw; - + if (msw&1 && !(cpu_state.eflags&VM_FLAG)) { x86seg_log("Protected mode CS load! %04X\n", seg); @@ -999,7 +1068,9 @@ void loadcscall(uint16_t seg) CS=seg; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif #ifdef ENABLE_X86SEG_LOG x86seg_log("Complete\n"); #endif @@ -1013,10 +1084,12 @@ void loadcscall(uint16_t seg) { case 0x400: /*Call gate*/ case 0xC00: /*386 Call gate*/ - x86seg_log("Callgate %08X\n", cpu_state.pc); + x86seg_log("Callgate %08X\n", cpu_state.pc); cgate32=(type&0x800); cgate16=!cgate32; +#ifndef USE_NEW_DYNAREC oldcs=CS; +#endif count=segdat[2]&31; if (DPL < CPL) { @@ -1030,7 +1103,6 @@ void loadcscall(uint16_t seg) } if (!(segdat[2]&0x8000)) { - x86seg_log("Call gate not present %04X\n",seg); x86np("Call gate not present\n", seg & 0xfffc); return; } @@ -1082,12 +1154,14 @@ void loadcscall(uint16_t seg) return; } - switch (segdat[2]&0x1F00) { case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ if (DPL < CPL) { +#ifdef USE_NEW_DYNAREC + uint16_t oldcs = CS; +#endif oaddr = addr; /*Load new stack*/ oldss=SS; @@ -1116,11 +1190,7 @@ void loadcscall(uint16_t seg) addr=newss&~7; if (newss&4) { -#if 0 - if (addr>=ldt.limit) -#else if ((addr+7)>ldt.limit) -#endif { x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit); x86ts(NULL,newss&~3); @@ -1130,11 +1200,7 @@ void loadcscall(uint16_t seg) } else { -#if 0 - if (addr>=gdt.limit) -#else if ((addr+7)>gdt.limit) -#endif { x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit); x86ts(NULL,newss&~3); @@ -1143,12 +1209,12 @@ void loadcscall(uint16_t seg) addr+=gdt.base; } cpl_override=1; - x86seg_log("Read stack seg\n"); + x86seg_log("Read stack seg\n"); segdat2[0]=readmemw(0,addr); segdat2[1]=readmemw(0,addr+2); segdat2[2]=readmemw(0,addr+4); segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - x86seg_log("Read stack seg done!\n"); + x86seg_log("Read stack seg done!\n"); if (((newss & 3) != DPL) || (DPL2 != DPL)) { x86ts(NULL,newss&~3); @@ -1172,7 +1238,7 @@ void loadcscall(uint16_t seg) do_seg_load(&cpu_state.seg_ss, segdat2); - x86seg_log("Set access 1\n"); + x86seg_log("Set access 1\n"); #ifdef SEL_ACCESSED cpl_override = 1; @@ -1183,19 +1249,21 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3]&0x40); cpu_state.pc=newpc; - - x86seg_log("Set access 2\n"); + + x86seg_log("Set access 2\n"); #ifdef CS_ACCESSED cpl_override = 1; writememw(0, oaddr+4, segdat[2] | 0x100); /*Set accessed bit*/ cpl_override = 0; #endif - - x86seg_log("Type %04X\n",type); + + x86seg_log("Type %04X\n",type); if (type==0xC00) { PUSHL(oldss); @@ -1204,6 +1272,9 @@ void loadcscall(uint16_t seg) { SS = oldss; ESP = oldsp2; +#ifdef USE_NEW_DYNAREC + CS = oldcs; +#endif return; } if (count) @@ -1216,6 +1287,9 @@ void loadcscall(uint16_t seg) { SS = oldss; ESP = oldsp2; +#ifdef USE_NEW_DYNAREC + CS = oldcs; +#endif return; } } @@ -1231,21 +1305,27 @@ void loadcscall(uint16_t seg) { SS = oldss; ESP = oldsp2; +#ifdef USE_NEW_DYNAREC + CS = oldcs; +#endif return; } - x86seg_log("Write SP to %04X:%04X\n",SS,SP); + x86seg_log("Write SP to %04X:%04X\n",SS,SP); if (count) { while (count) { count--; tempw=readmemw(oldssbase,(oldsp&0xFFFF)+(count*2)); - x86seg_log("PUSH %04X\n",tempw); + x86seg_log("PUSH %04X\n",tempw); PUSHW(tempw); if (cpu_state.abrt) { SS = oldss; ESP = oldsp2; +#ifdef USE_NEW_DYNAREC + CS = oldcs; +#endif return; } } @@ -1264,6 +1344,9 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -1283,7 +1366,11 @@ void loadcscall(uint16_t seg) case 0x100: /*286 Task gate*/ case 0x900: /*386 Task gate*/ - cpu_state.pc=oxpc; +#ifdef USE_NEW_DYNAREC + cpu_state.pc = old_pc; +#else + cpu_state.pc = oxpc; +#endif cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); cpl_override=0; @@ -1304,8 +1391,11 @@ void loadcscall(uint16_t seg) CS=seg; if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high = 0x10; + cpu_state.seg_cs.ar_high = 0x10; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif } } @@ -1417,6 +1507,9 @@ void pmoderetf(int is32, uint16_t off) do_seg_load(&cpu_state.seg_cs, segdat); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3] & 0x40); cycles -= timing_retf_pm; @@ -1432,7 +1525,7 @@ void pmoderetf(int is32, uint16_t off) x86gpf("pmoderetf(): Non-conforming RPL != DPL",seg&~3); return; } - x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL); + x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL); break; case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if ((seg&3) < DPL) @@ -1441,7 +1534,7 @@ void pmoderetf(int is32, uint16_t off) x86gpf("pmoderetf(): Conforming RPL < DPL",seg&~3); return; } - x86seg_log("RETF conforming, %i %i\n",seg&3, DPL); + x86seg_log("RETF conforming, %i %i\n",seg&3, DPL); break; default: ESP=oldsp; @@ -1499,7 +1592,7 @@ void pmoderetf(int is32, uint16_t off) segdat2[1]=readmemw(0,addr+2); segdat2[2]=readmemw(0,addr+4); segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; } - x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); + x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); if ((newss & 3) != (seg & 3)) { ESP=oldsp; @@ -1539,14 +1632,17 @@ void pmoderetf(int is32, uint16_t off) #endif cpl_override = 0; #endif - /*Conforming segments don't change CPL, so CPL = RPL*/ - if (segdat[2]&0x400) - segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); + /*Conforming segments don't change CPL, so CPL = RPL*/ + if (segdat[2]&0x400) + segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); cpu_state.pc=newpc; CS=seg; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3] & 0x40); if (stack32) ESP+=off; @@ -1560,11 +1656,6 @@ void pmoderetf(int is32, uint16_t off) } } -void restore_stack() -{ - ss=oldss; cpu_state.seg_ss.limit=oldsslimit; -} - void pmodeint(int num, int soft) { uint16_t segdat[4],segdat2[4],segdat3[4]; @@ -1575,10 +1666,10 @@ void pmodeint(int num, int soft) uint32_t newsp; uint16_t seg = 0; int new_cpl; - + if (cpu_state.eflags&VM_FLAG && IOPL!=3 && soft) { - x86seg_log("V86 banned int\n"); + x86seg_log("V86 banned int\n"); x86gpf("pmodeint(): V86 banned int",0); return; } @@ -1589,7 +1680,7 @@ void pmodeint(int num, int soft) { /*Triple fault - reset!*/ softresetx86(); - cpu_set_edx(); + cpu_set_edx(); } else if (num==0xD) { @@ -1607,7 +1698,11 @@ void pmodeint(int num, int soft) segdat[0]=readmemw(0,addr); segdat[1]=readmemw(2,addr); segdat[2]=readmemw(4,addr); - segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* x86seg_log("Abrt reading from %08X\n",addr); */ return; } + segdat[3]=readmemw(6,addr); cpl_override=0; + if (cpu_state.abrt) { + x86seg_log("Abrt reading from %08X\n",addr); + return; + } oaddr = addr; x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]); @@ -1675,7 +1770,7 @@ void pmodeint(int num, int soft) x86np("Int gate CS not present\n", segdat[1] & 0xfffc); return; } - if ((cpu_state.eflags&VM_FLAG) && DPL2) + if ((cpu_state.eflags & VM_FLAG) && DPL2) { x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode",segdat[1]&0xFFFC); return; @@ -1770,7 +1865,7 @@ void pmodeint(int num, int soft) } PUSHL(oldss); PUSHL(oldsp); - PUSHL(cpu_state.flags|(cpu_state.eflags<<16)); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); PUSHL(CS); PUSHL(cpu_state.pc); if (cpu_state.abrt) return; } @@ -1806,7 +1901,7 @@ void pmodeint(int num, int soft) } if (type>0x800) { - PUSHL(cpu_state.flags|(cpu_state.eflags<<16)); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); PUSHL(CS); PUSHL(cpu_state.pc); if (cpu_state.abrt) return; } @@ -1826,6 +1921,9 @@ void pmodeint(int num, int soft) CS = (seg & ~3) | new_cpl; cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; set_use32(segdat2[3]&0x40); @@ -1836,13 +1934,11 @@ void pmodeint(int num, int soft) cpl_override = 0; #endif - cpu_state.eflags&=~VM_FLAG; + cpu_state.eflags &= ~VM_FLAG; cpu_cur_status &= ~CPU_STATUS_V86; if (!(type&0x100)) - { - cpu_state.flags&=~I_FLAG; - } - cpu_state.flags&=~(T_FLAG|NT_FLAG); + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~(T_FLAG|NT_FLAG); cycles -= timing_int_pm; break; @@ -1898,17 +1994,19 @@ void pmodeiret(int is32) uint32_t newpc; uint16_t segdat[4],segdat2[4]; uint16_t segs[4]; - uint16_t seg; + uint16_t seg = 0; uint32_t addr, oaddr; uint32_t oldsp=ESP; - if (is386 && (cpu_state.eflags&VM_FLAG)) + if (is386 && (cpu_state.eflags & VM_FLAG)) { if (IOPL!=3) { x86gpf(NULL,0); return; } - oxpc=cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif if (is32) { newpc=POPL(); @@ -1926,15 +2024,15 @@ void pmodeiret(int is32) cpu_state.seg_cs.limit=0xFFFF; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.access |= 0x80; - cpu_state.seg_cs.ar_high = 0x10; + cpu_state.seg_cs.access |= 0x80; + cpu_state.seg_cs.ar_high = 0x10; CS=seg; - cpu_state.flags=(cpu_state.flags&0x3000)|(tempflags&0xCFD5)|2; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2; cycles -= timing_iret_rm; return; } - if (cpu_state.flags&NT_FLAG) + if (cpu_state.flags & NT_FLAG) { seg=readmemw(tr.base,0); addr=seg&~7; @@ -1962,7 +2060,9 @@ void pmodeiret(int is32) cpl_override=0; return; } - oxpc=cpu_state.pc; +#ifndef USE_NEW_DYNAREC + oxpc=cpu_state.pc; +#endif flagmask=0xFFFF; if (CPL) flagmask&=~0x3000; if (IOPL>16; + cpu_state.eflags = tempflags>>16; cpu_cur_status |= CPU_STATUS_V86; loadseg(segs[0],&cpu_state.seg_es); do_seg_v86_init(&cpu_state.seg_es); @@ -1989,25 +2089,28 @@ void pmodeiret(int is32) loadseg(segs[2],&cpu_state.seg_fs); do_seg_v86_init(&cpu_state.seg_fs); loadseg(segs[3],&cpu_state.seg_gs); - do_seg_v86_init(&cpu_state.seg_gs); - - cpu_state.pc=newpc; + do_seg_v86_init(&cpu_state.seg_gs); + + cpu_state.pc = newpc & 0xffff; cpu_state.seg_cs.base=seg<<4; cpu_state.seg_cs.limit=0xFFFF; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffff; CS=seg; cpu_state.seg_cs.access=(3<<5) | 2 | 0x80; - cpu_state.seg_cs.ar_high=0x10; + cpu_state.seg_cs.ar_high = 0x10; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif + ESP=newsp; loadseg(newss,&cpu_state.seg_ss); do_seg_v86_init(&cpu_state.seg_ss); cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32=0; cpu_cur_status &= ~CPU_STATUS_USE32; - cpu_state.flags=(tempflags&0xFFD5)|2; + cpu_state.flags = (tempflags&0xFFD5)|2; cycles -= timing_iret_v86; return; } @@ -2057,7 +2160,7 @@ void pmodeiret(int is32) segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } - + switch (segdat[2]&0x1F00) { case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ @@ -2093,6 +2196,9 @@ void pmodeiret(int is32) do_seg_load(&cpu_state.seg_cs, segdat); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED @@ -2198,8 +2304,11 @@ void pmodeiret(int is32) do_seg_load(&cpu_state.seg_cs, segdat); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat[3] & 0x40); - + check_seg_valid(&cpu_state.seg_ds); check_seg_valid(&cpu_state.seg_es); check_seg_valid(&cpu_state.seg_fs); @@ -2207,8 +2316,8 @@ void pmodeiret(int is32) cycles -= timing_iret_pm_outer; } cpu_state.pc=newpc; - cpu_state.flags=(cpu_state.flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2; - if (is32) cpu_state.eflags=tempflags>>16; + cpu_state.flags = (cpu_state.flags&~flagmask) | (tempflags&flagmask&0xFFD5)|2; + if (is32) cpu_state.eflags = tempflags>>16; } void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) @@ -2260,7 +2369,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) cpu_386_flags_rebuild(); writememl(tr.base,0x1C,cr3); writememl(tr.base,0x20,cpu_state.pc); - writememl(tr.base,0x24,cpu_state.flags|(cpu_state.eflags<<16)); + writememl(tr.base,0x24,cpu_state.flags | (cpu_state.eflags<<16)); writememl(tr.base,0x28,EAX); writememl(tr.base,0x2C,ECX); @@ -2326,8 +2435,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) flushmmucache(); cpu_state.pc=new_pc; - cpu_state.flags=new_flags; - cpu_state.eflags=new_flags>>16; + cpu_state.flags = new_flags; + cpu_state.eflags = new_flags>>16; cpu_386_flags_extract(); ldt.seg=new_ldt; @@ -2405,6 +2514,9 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&cpu_state.seg_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(segdat2[3] & 0x40); cpu_cur_status &= ~CPU_STATUS_V86; } @@ -2443,7 +2555,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } if (cpu_state.abrt) return; - if (optype==IRET) cpu_state.flags&=~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; cpu_386_flags_rebuild(); writememw(tr.base,0x0E,cpu_state.pc); @@ -2504,7 +2617,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) msw |= 8; cpu_state.pc=new_pc; - cpu_state.flags=new_flags; + cpu_state.flags = new_flags; cpu_386_flags_extract(); ldt.seg=new_ldt; @@ -2578,6 +2691,9 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&cpu_state.seg_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); +#ifdef USE_NEW_DYNAREC + oldcpl = CPL; +#endif set_use32(0); EAX=new_eax | 0xFFFF0000; @@ -2603,5 +2719,5 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) tr.base=base; tr.limit=limit; tr.access=segdat[2]>>8; - tr.ar_high = segdat[3] & 0xff; + tr.ar_high = segdat[3] & 0xff; } diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 26a414f75..83decd4fd 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -11,8 +11,8 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ ST(0) += use_var; \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ - FP_TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ + FP_TAG_VALID; \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -24,7 +24,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -37,7 +37,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ x87_pop(); \ - CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -49,7 +49,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ FP_TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -61,7 +61,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ FP_TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -73,7 +73,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ FP_TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fmul ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -85,7 +85,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ FP_TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -97,7 +97,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ FP_TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } @@ -127,7 +127,7 @@ static int opFADD(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) + ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } static int opFADDr(uint32_t fetchdat) @@ -136,7 +136,7 @@ static int opFADDr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); FP_TAG_VALID_F; - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } static int opFADDP(uint32_t fetchdat) @@ -146,7 +146,7 @@ static int opFADDP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } @@ -157,7 +157,7 @@ static int opFCOM(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES(x87_timings.fcom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); return 0; } @@ -168,7 +168,7 @@ static int opFCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES(x87_timings.fcom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); return 0; } @@ -187,7 +187,7 @@ static int opFCOMPP(uint32_t fetchdat) x87_pop(); x87_pop(); - CLOCK_CYCLES(x87_timings.fcom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -199,7 +199,7 @@ static int opFUCOMPP(uint32_t fetchdat) cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); x87_pop(); x87_pop(); - CLOCK_CYCLES(x87_timings.fucom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); return 0; } @@ -211,7 +211,7 @@ static int opFCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(x87_timings.fcom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); return 0; } static int opFCOMIP(uint32_t fetchdat) @@ -223,7 +223,7 @@ static int opFCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES(x87_timings.fcom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); return 0; } #endif @@ -234,7 +234,7 @@ static int opFDIV(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(0), ST(0), ST(fetchdat & 7)); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fdiv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); return 0; } static int opFDIVr(uint32_t fetchdat) @@ -243,7 +243,7 @@ static int opFDIVr(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); FP_TAG_VALID_F; - CLOCK_CYCLES(x87_timings.fdiv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); return 0; } static int opFDIVP(uint32_t fetchdat) @@ -253,7 +253,7 @@ static int opFDIVP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(x87_timings.fdiv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); return 0; } @@ -263,7 +263,7 @@ static int opFDIVR(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(0), ST(fetchdat&7), ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fdiv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); return 0; } static int opFDIVRr(uint32_t fetchdat) @@ -272,7 +272,7 @@ static int opFDIVRr(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); FP_TAG_VALID_F; - CLOCK_CYCLES(x87_timings.fdiv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); return 0; } static int opFDIVRP(uint32_t fetchdat) @@ -282,7 +282,7 @@ static int opFDIVRP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(x87_timings.fdiv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); return 0; } @@ -292,7 +292,7 @@ static int opFMUL(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fmul); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); return 0; } static int opFMULr(uint32_t fetchdat) @@ -301,7 +301,7 @@ static int opFMULr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID_F; - CLOCK_CYCLES(x87_timings.fmul); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); return 0; } static int opFMULP(uint32_t fetchdat) @@ -311,7 +311,7 @@ static int opFMULP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(x87_timings.fmul); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); return 0; } @@ -321,7 +321,7 @@ static int opFSUB(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } static int opFSUBr(uint32_t fetchdat) @@ -330,7 +330,7 @@ static int opFSUBr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID_F; - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } static int opFSUBP(uint32_t fetchdat) @@ -340,7 +340,7 @@ static int opFSUBP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } @@ -350,7 +350,7 @@ static int opFSUBR(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } static int opFSUBRr(uint32_t fetchdat) @@ -359,7 +359,7 @@ static int opFSUBRr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID_F; - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } static int opFSUBRP(uint32_t fetchdat) @@ -369,7 +369,7 @@ static int opFSUBRP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES(x87_timings.fadd); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); return 0; } @@ -380,7 +380,7 @@ static int opFUCOM(uint32_t fetchdat) cpu_state.pc++; cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES(x87_timings.fucom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); return 0; } @@ -391,7 +391,7 @@ static int opFUCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES(x87_timings.fucom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); return 0; } @@ -403,7 +403,7 @@ static int opFUCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(x87_timings.fucom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); return 0; } static int opFUCOMIP(uint32_t fetchdat) @@ -415,7 +415,7 @@ static int opFUCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES(x87_timings.fucom); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); return 0; } #endif diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index 7f1cf4900..f742196ea 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -23,7 +23,7 @@ static int opFILDiw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); - CLOCK_CYCLES(x87_timings.fild_16); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -35,7 +35,7 @@ static int opFILDiw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); - CLOCK_CYCLES(x87_timings.fild_16); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); return 0; } #endif @@ -48,7 +48,7 @@ static int opFISTiw_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); - CLOCK_CYCLES(x87_timings.fist_16); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -60,7 +60,7 @@ static int opFISTiw_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); - CLOCK_CYCLES(x87_timings.fist_16); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); return cpu_state.abrt; } #endif @@ -74,7 +74,7 @@ static int opFISTPiw_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fist_16); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -87,7 +87,7 @@ static int opFISTPiw_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fist_16); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); return 0; } #endif @@ -103,7 +103,7 @@ static int opFILDiq_a16(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; FP_TAG_DEFAULT; - CLOCK_CYCLES(x87_timings.fild_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -118,7 +118,7 @@ static int opFILDiq_a32(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; FP_TAG_DEFAULT; - CLOCK_CYCLES(x87_timings.fild_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); return 0; } #endif @@ -147,7 +147,7 @@ static int FBSTP_a16(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fbstp); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -175,7 +175,7 @@ static int FBSTP_a32(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fbstp); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); return 0; } #endif @@ -192,7 +192,7 @@ static int FISTPiq_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fist_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -208,7 +208,7 @@ static int FISTPiq_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fist_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); return 0; } #endif @@ -221,7 +221,7 @@ static int opFILDil_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); - CLOCK_CYCLES(x87_timings.fild_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -233,7 +233,7 @@ static int opFILDil_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); - CLOCK_CYCLES(x87_timings.fild_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); return 0; } #endif @@ -246,7 +246,7 @@ static int opFISTil_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); - CLOCK_CYCLES(x87_timings.fist_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -258,7 +258,7 @@ static int opFISTil_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); - CLOCK_CYCLES(x87_timings.fist_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); return cpu_state.abrt; } #endif @@ -272,7 +272,7 @@ static int opFISTPil_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fist_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -285,7 +285,7 @@ static int opFISTPil_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fist_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); return 0; } #endif @@ -298,7 +298,7 @@ static int opFLDe_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); - CLOCK_CYCLES(x87_timings.fld_80); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -310,7 +310,7 @@ static int opFLDe_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); - CLOCK_CYCLES(x87_timings.fld_80); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); return 0; } #endif @@ -322,7 +322,7 @@ static int opFSTPe_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fld_80); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -333,7 +333,7 @@ static int opFSTPe_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fld_80); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); return 0; } #endif @@ -346,7 +346,7 @@ static int opFLDd_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); - CLOCK_CYCLES(x87_timings.fld_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -358,7 +358,7 @@ static int opFLDd_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); - CLOCK_CYCLES(x87_timings.fld_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); return 0; } #endif @@ -371,7 +371,7 @@ static int opFSTd_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES(x87_timings.fst_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -383,7 +383,7 @@ static int opFSTd_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES(x87_timings.fst_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); return cpu_state.abrt; } #endif @@ -397,7 +397,7 @@ static int opFSTPd_a16(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fst_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -410,7 +410,7 @@ static int opFSTPd_a32(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fst_64); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); return 0; } #endif @@ -423,7 +423,7 @@ static int opFLDs_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); - CLOCK_CYCLES(x87_timings.fld_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -435,7 +435,7 @@ static int opFLDs_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); - CLOCK_CYCLES(x87_timings.fld_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); return 0; } #endif @@ -448,7 +448,7 @@ static int opFSTs_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES(x87_timings.fst_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -460,7 +460,7 @@ static int opFSTs_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES(x87_timings.fst_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); return cpu_state.abrt; } #endif @@ -474,7 +474,7 @@ static int opFSTPs_a16(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fst_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -487,7 +487,7 @@ static int opFSTPs_a32(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.fst_32); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); return 0; } #endif diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index af7be0527..bd8b1a851 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -15,7 +15,7 @@ static int opFSTSW_AX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; AX = cpu_state.npxs; - CLOCK_CYCLES(x87_timings.fstcw_sw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); return 0; } #endif @@ -25,7 +25,7 @@ static int opFNOP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - CLOCK_CYCLES(x87_timings.fnop); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); return 0; } @@ -34,7 +34,7 @@ static int opFCLEX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= 0xff00; - CLOCK_CYCLES(x87_timings.fnop); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); return 0; } @@ -58,7 +58,7 @@ static int opFINIT(uint32_t fetchdat) #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES(x87_timings.finit); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); CPU_BLOCK_END(); return 0; } @@ -73,7 +73,7 @@ static int opFFREE(uint32_t fetchdat) #else cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; #endif - CLOCK_CYCLES(x87_timings.ffree); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); return 0; } @@ -83,7 +83,7 @@ static int opFFREEP(uint32_t fetchdat) cpu_state.pc++; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(x87_timings.ffree); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); return 0; } @@ -93,7 +93,7 @@ static int opFST(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES(x87_timings.fst); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); return 0; } @@ -104,7 +104,7 @@ static int opFSTP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; x87_pop(); - CLOCK_CYCLES(x87_timings.fst); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); return 0; } @@ -160,7 +160,7 @@ static int FSTOR() #endif cpu_state.ismmx = 1; - CLOCK_CYCLES(x87_timings.frstor); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); return cpu_state.abrt; } static int opFSTOR_a16(uint32_t fetchdat) @@ -330,7 +330,7 @@ static int FSAVE() cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES(x87_timings.fsave); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); return cpu_state.abrt; } static int opFSAVE_a16(uint32_t fetchdat) @@ -358,7 +358,7 @@ static int opFSTSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(x87_timings.fstcw_sw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -368,7 +368,7 @@ static int opFSTSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(x87_timings.fstcw_sw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #endif @@ -386,7 +386,7 @@ static int opFLD(uint32_t fetchdat) x87_push(ST(fetchdat&7)); cpu_state.tag[cpu_state.TOP&7] = old_tag; cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES(x87_timings.fld); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); return 0; } @@ -407,7 +407,7 @@ static int opFXCH(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - CLOCK_CYCLES(x87_timings.fxch); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); return 0; } @@ -417,7 +417,7 @@ static int opFCHS(uint32_t fetchdat) cpu_state.pc++; ST(0) = -ST(0); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fchs); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); return 0; } @@ -427,7 +427,7 @@ static int opFABS(uint32_t fetchdat) cpu_state.pc++; ST(0) = fabs(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fabs); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); return 0; } @@ -438,7 +438,7 @@ static int opFTST(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == 0.0) cpu_state.npxs |= C3; else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES(x87_timings.ftst); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); return 0; } @@ -455,7 +455,7 @@ static int opFXAM(uint32_t fetchdat) else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES(x87_timings.fxam); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); return 0; } @@ -464,7 +464,7 @@ static int opFLD1(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(1.0); - CLOCK_CYCLES(x87_timings.fld_z1); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); return 0; } @@ -473,7 +473,7 @@ static int opFLDL2T(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(3.3219280948873623); - CLOCK_CYCLES(x87_timings.fld_const); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); return 0; } @@ -482,7 +482,7 @@ static int opFLDL2E(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(1.4426950408889634); - CLOCK_CYCLES(x87_timings.fld_const); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); return 0; } @@ -491,7 +491,7 @@ static int opFLDPI(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(3.141592653589793); - CLOCK_CYCLES(x87_timings.fld_const); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); return 0; } @@ -500,7 +500,7 @@ static int opFLDEG2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(0.3010299956639812); - CLOCK_CYCLES(x87_timings.fld_const); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); return 0; } @@ -509,7 +509,7 @@ static int opFLDLN2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES(x87_timings.fld_const); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); return 0; } @@ -519,7 +519,7 @@ static int opFLDZ(uint32_t fetchdat) cpu_state.pc++; x87_push(0.0); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fld_z1); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); return 0; } @@ -529,7 +529,7 @@ static int opF2XM1(uint32_t fetchdat) cpu_state.pc++; ST(0) = pow(2.0, ST(0)) - 1.0; FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.f2xm1); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); return 0; } @@ -540,7 +540,7 @@ static int opFYL2X(uint32_t fetchdat) ST(1) = ST(1) * (log(ST(0)) / log(2.0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES(x87_timings.fyl2x); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); return 0; } @@ -551,7 +551,7 @@ static int opFYL2XP1(uint32_t fetchdat) ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES(x87_timings.fyl2xp1); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); return 0; } @@ -563,7 +563,7 @@ static int opFPTAN(uint32_t fetchdat) FP_TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fptan); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); return 0; } @@ -574,7 +574,7 @@ static int opFPATAN(uint32_t fetchdat) ST(1) = atan2(ST(1), ST(0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES(x87_timings.fpatan); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); return 0; } @@ -587,7 +587,7 @@ static int opFDECSTP(uint32_t fetchdat) #else cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - CLOCK_CYCLES(x87_timings.fincdecstp); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); return 0; } @@ -600,7 +600,7 @@ static int opFINCSTP(uint32_t fetchdat) #else cpu_state.TOP = (cpu_state.TOP + 1) & 7; #endif - CLOCK_CYCLES(x87_timings.fincdecstp); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); return 0; } @@ -616,7 +616,7 @@ static int opFPREM(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(x87_timings.fprem); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -632,7 +632,7 @@ static int opFPREM1(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(x87_timings.fprem1); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); return 0; } #endif @@ -643,7 +643,7 @@ static int opFSQRT(uint32_t fetchdat) cpu_state.pc++; ST(0) = sqrt(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fsqrt); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); return 0; } @@ -658,7 +658,7 @@ static int opFSINCOS(uint32_t fetchdat) FP_TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fsincos); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); return 0; } #endif @@ -669,7 +669,7 @@ static int opFRNDINT(uint32_t fetchdat) cpu_state.pc++; ST(0) = (double)x87_fround(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.frndint); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); return 0; } @@ -681,7 +681,7 @@ static int opFSCALE(uint32_t fetchdat) temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); FP_TAG_VALID; - CLOCK_CYCLES(x87_timings.fscale); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); return 0; } @@ -693,7 +693,7 @@ static int opFSIN(uint32_t fetchdat) ST(0) = sin(ST(0)); FP_TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fsin_cos); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); return 0; } @@ -704,7 +704,7 @@ static int opFCOS(uint32_t fetchdat) ST(0) = cos(ST(0)); FP_TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fsin_cos); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); return 0; } #endif @@ -732,7 +732,7 @@ static int FLDENV() cpu_state.TOP = (cpu_state.npxs >> 11) & 7; break; } - CLOCK_CYCLES(x87_timings.fldenv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); return cpu_state.abrt; } @@ -765,7 +765,7 @@ static int opFLDCW_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(x87_timings.fldcw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -779,7 +779,7 @@ static int opFLDCW_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(x87_timings.fldcw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); return 0; } #endif @@ -823,7 +823,7 @@ static int FSTENV() writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); break; } - CLOCK_CYCLES(x87_timings.fstenv); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); return cpu_state.abrt; } @@ -852,7 +852,7 @@ static int opFSTCW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(cpu_state.npxc); - CLOCK_CYCLES(x87_timings.fstcw_sw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -862,7 +862,7 @@ static int opFSTCW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(cpu_state.npxc); - CLOCK_CYCLES(x87_timings.fstcw_sw); + CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #endif diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index f8a7e96fa..bf0c975f4 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1534,9 +1534,15 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) return; } - if (toc_format < 3) + if (toc_format < 3) { len = cdrom_read_toc(dev->drv, dev->buffer, toc_format, cdb[6], msf, max_len); - else { + if (len == -1) { + /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ + scsi_cdrom_invalid_field(dev); + scsi_cdrom_buf_free(dev); + return; + } + } else { scsi_cdrom_invalid_field(dev); scsi_cdrom_buf_free(dev); return; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index b740f11f0..b077d2d12 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -673,7 +673,7 @@ ega_doblit(int y1, int y2, int wx, int wy, ega_t *ega) if (ys_temp < 32) ys_temp = 200; - if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { + if ((ega->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { /* Screen res has changed.. fix up, and let them know. */ xsize = xs_temp; ysize = ys_temp; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 0ab9b5b3f..9ea2a7bd3 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -127,8 +127,12 @@ ega_render_text_40(ega_t *ega) for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + + if (ega->crtc[0x17] & 0x80) { + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + } else + chr = attr = 0; if (attr & 8) charaddr = ega->charsetb + (chr * 128); else charaddr = ega->charseta + (chr * 128); @@ -190,8 +194,12 @@ ega_render_text_80(ega_t *ega) for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + + if (ega->crtc[0x17] & 0x80) { + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + } else + chr = attr = 0; if (attr & 8) charaddr = ega->charsetb + (chr * 128); else charaddr = ega->charseta + (chr * 128); @@ -274,14 +282,17 @@ ega_render_2bpp_lowres(ega_t *ega) ega->ma &= ega->vrammask; - p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; - p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]]; + if (ega->crtc[0x17] & 0x80) { + p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; + p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); p += 16; } @@ -333,14 +344,17 @@ ega_render_2bpp_highres(ega_t *ega) ega->ma &= ega->vrammask; - p[0] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; - p[1] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; - p[2] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; - p[3] = ega->pallook[ega->egapal[dat[0] & 3]]; - p[4] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; - p[5] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; - p[6] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; - p[7] = ega->pallook[ega->egapal[dat[1] & 3]]; + if (ega->crtc[0x17] & 0x80) { + p[0] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; + p[1] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; + p[2] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; + p[3] = ega->pallook[ega->egapal[dat[0] & 3]]; + p[4] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; + p[5] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; + p[6] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; + p[7] = ega->pallook[ega->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); p += 8; } @@ -402,18 +416,21 @@ ega_render_4bpp_lowres(ega_t *ega) ega->ma &= ega->vrammask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + if (ega->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); p += 16; } @@ -470,18 +487,21 @@ ega_render_4bpp_highres(ega_t *ega) } ega->ma &= ega->vrammask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + if (ega->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); p += 8; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index aedaf58a9..3bec9dd24 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1299,7 +1299,7 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) if (ys_temp < 32) ys_temp = 200; - if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { + if ((svga->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { /* Screen res has changed.. fix up, and let them know. */ xsize = xs_temp; ysize = ys_temp; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index c76bf2d72..00fa85ff9 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -120,8 +120,12 @@ svga_render_text_40(svga_t *svga) for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + + if (svga->crtc[0x17] & 0x80) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else + chr = attr = 0; if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -183,8 +187,12 @@ svga_render_text_80(svga_t *svga) for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + + if (svga->crtc[0x17] & 0x80) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else + chr = attr = 0; if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -248,7 +256,10 @@ svga_render_text_80_ksc5601(svga_t *svga) drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + if (svga->crtc[0x17] & 0x80) + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + else + attr = 0; if (drawcursor) { bg = svga->pallook[svga->egapal[attr & 15]]; @@ -391,14 +402,17 @@ svga_render_2bpp_lowres(svga_t *svga) svga->ma &= svga->vram_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + if (svga->crtc[0x17] & 0x80) { + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); p += 16; } @@ -454,14 +468,17 @@ svga_render_2bpp_highres(svga_t *svga) svga->ma &= svga->vram_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + if (svga->crtc[0x17] & 0x80) { + p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); p += 8; } @@ -521,18 +538,21 @@ svga_render_4bpp_lowres(svga_t *svga) } svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + if (svga->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 16 * sizeof(uint32_t)); p += 16; } @@ -595,18 +615,21 @@ svga_render_4bpp_highres(svga_t *svga) } svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + if (svga->crtc[0x17] & 0x80) { + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); p += 8; } @@ -632,12 +655,14 @@ svga_render_8bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); svga->ma += 4; p += 8; @@ -665,17 +690,20 @@ svga_render_8bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + } else + memset(p, 0x00, 8 * sizeof(uint32_t)); svga->ma += 8; p += 8; @@ -703,17 +731,18 @@ svga_render_15bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; + p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - - p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; - - p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -739,21 +768,24 @@ svga_render_15bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = video_15to32[dat & 0xffff]; + p[x + 3] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = video_15to32[dat & 0xffff]; + p[x + 5] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -779,17 +811,20 @@ svga_render_15bpp_mix_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -815,25 +850,28 @@ svga_render_15bpp_mix_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -859,13 +897,16 @@ svga_render_16bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -890,21 +931,24 @@ svga_render_16bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + if (svga->crtc[0x17] & 0x80) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = video_16to32[dat & 0xffff]; + p[x + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = video_16to32[dat & 0xffff]; + p[x + 5] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = video_16to32[dat & 0xffff]; + p[x + 7] = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -927,7 +971,10 @@ svga_render_24bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + if (svga->crtc[0x17] & 0x80) + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + else + fg = 0x00000000; svga->ma += 3; svga->ma &= svga->vram_display_mask; buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = @@ -955,17 +1002,20 @@ svga_render_24bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[x] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); + p[x + 1] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); + p[x + 2] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); + p[x + 3] = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); svga->ma += 12; } @@ -989,8 +1039,11 @@ svga_render_32bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 4; + if (svga->crtc[0x17] & 0x80) + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + else + fg = 0x00000000; + svga->ma += 4; svga->ma &= svga->vram_display_mask; buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; @@ -1017,7 +1070,10 @@ svga_render_32bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + if (svga->crtc[0x17] & 0x80) + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + else + dat = 0x00000000; p[x] = dat & 0xffffff; } svga->ma += 4; @@ -1044,7 +1100,10 @@ svga_render_ABGR8888_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + if (svga->crtc[0x17] & 0x80) + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + else + dat = 0x00000000; p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } svga->ma += 4; @@ -1071,7 +1130,10 @@ svga_render_RGBA8888_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + if (svga->crtc[0x17] & 0x80) + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + else + dat = 0x00000000; p[x] = dat >> 8; } svga->ma += 4; diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index b71595c58..11bb948b2 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -157,8 +157,8 @@ sdl_stretch(int *w, int *h, int *x, int *y) } dx = (hw - dw) / 2.0; dy = (hh - dh) / 2.0; - *w = (int) hw; - *h = (int) hh; + *w = (int) dw; + *h = (int) dh; *x = (int) dx; *y = (int) dy; break; diff --git a/src/win/win_settings.c b/src/win/win_settings.c index ebf20dbd3..32ebc3aee 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -584,6 +584,8 @@ win_settings_machine_recalc_fpu(HWND hdlg) EnableWindow(h, TRUE); else EnableWindow(h, FALSE); + + temp_fpu = fpu_get_type_from_index(temp_machine, temp_cpu_m, temp_cpu, SendMessage(h, CB_GETCURSEL, 0, 0)); }