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));
}