RTL8029AS now works properly (patch from TheCollector1995 with some modifications by me);
SVGA emulation now has partial support for 12x24 text mode used by 48k HECON.SYS; LEA AX,DX now once again issues #UD on 286+ like it should; FF /7 is now correctly an alias of FF /6 on 8080x; Hard disk configuration dialog now uses Segoe UI 9pt font instead of MS Sans Serif 8pt; Removed excess logging from serial mouse and x86seg.c; Applied mainline PCem PIT MSW1 fix commit; IMG-based floppy emulation now takes GAP4 and post-sector delays into account; Comemnted out emulation of non-Overdrive Pentium II's.
This commit is contained in:
@@ -1018,6 +1018,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] =
|
|||||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
OpFn OP_TABLE(pentium2_0f)[1024] =
|
OpFn OP_TABLE(pentium2_0f)[1024] =
|
||||||
{
|
{
|
||||||
/*16-bit data, 16-bit addr*/
|
/*16-bit data, 16-bit addr*/
|
||||||
@@ -1108,6 +1109,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] =
|
|||||||
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
|
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
|
||||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
OpFn OP_TABLE(pentium2d_0f)[1024] =
|
OpFn OP_TABLE(pentium2d_0f)[1024] =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3404,6 +3404,7 @@ void execx86(int cycs)
|
|||||||
FETCHCLEAR();
|
FETCHCLEAR();
|
||||||
break;
|
break;
|
||||||
case 0x30: /*PUSH w*/
|
case 0x30: /*PUSH w*/
|
||||||
|
case 0x38: /*PUSH w alias, reported by reenigne*/
|
||||||
tempw=geteaw();
|
tempw=geteaw();
|
||||||
// if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]);
|
// if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]);
|
||||||
if (ssegs) ss=oldss;
|
if (ssegs) ss=oldss;
|
||||||
|
|||||||
14
src/cpu.c
14
src/cpu.c
@@ -524,6 +524,7 @@ CPU cpus_PentiumPro[] =
|
|||||||
{"", -1, 0, 0, 0}
|
{"", -1, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
CPU cpus_Pentium2[] =
|
CPU cpus_Pentium2[] =
|
||||||
{
|
{
|
||||||
/*Intel Pentium II Klamath*/
|
/*Intel Pentium II Klamath*/
|
||||||
@@ -548,6 +549,7 @@ CPU cpus_Pentium2D[] =
|
|||||||
{"Pentium II D 500", CPU_PENTIUM2D, 33, 500000000, 5, 50000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
{"Pentium II D 500", CPU_PENTIUM2D, 33, 500000000, 5, 50000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC},
|
||||||
{"", -1, 0, 0, 0}
|
{"", -1, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
void cpu_set_edx()
|
void cpu_set_edx()
|
||||||
{
|
{
|
||||||
@@ -1357,7 +1359,8 @@ void cpu_set()
|
|||||||
codegen_timing_set(&codegen_timing_686);
|
codegen_timing_set(&codegen_timing_686);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_PENTIUM2:
|
#if 0
|
||||||
|
case CPU_PENTIUM2:
|
||||||
x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f);
|
x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f);
|
||||||
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
|
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16;
|
||||||
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
|
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32;
|
||||||
@@ -1388,6 +1391,7 @@ void cpu_set()
|
|||||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
||||||
codegen_timing_set(&codegen_timing_686);
|
codegen_timing_set(&codegen_timing_686);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case CPU_PENTIUM2D:
|
case CPU_PENTIUM2D:
|
||||||
x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f);
|
x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f);
|
||||||
@@ -1778,7 +1782,7 @@ void cpu_CPUID()
|
|||||||
EAX = 0;
|
EAX = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_PENTIUM2:
|
/* case CPU_PENTIUM2:
|
||||||
if (!EAX)
|
if (!EAX)
|
||||||
{
|
{
|
||||||
EAX = 0x00000002;
|
EAX = 0x00000002;
|
||||||
@@ -1802,7 +1806,7 @@ void cpu_CPUID()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
EAX = 0;
|
EAX = 0;
|
||||||
break;
|
break; */
|
||||||
|
|
||||||
case CPU_PENTIUM2D:
|
case CPU_PENTIUM2D:
|
||||||
if (!EAX)
|
if (!EAX)
|
||||||
@@ -1926,7 +1930,7 @@ void cpu_RDMSR()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_PENTIUMPRO:
|
case CPU_PENTIUMPRO:
|
||||||
case CPU_PENTIUM2:
|
// case CPU_PENTIUM2:
|
||||||
case CPU_PENTIUM2D:
|
case CPU_PENTIUM2D:
|
||||||
EAX = EDX = 0;
|
EAX = EDX = 0;
|
||||||
// pclog("RDMSR, ECX=%08X\n", ECX);
|
// pclog("RDMSR, ECX=%08X\n", ECX);
|
||||||
@@ -2119,7 +2123,7 @@ void cpu_WRMSR()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_PENTIUMPRO:
|
case CPU_PENTIUMPRO:
|
||||||
case CPU_PENTIUM2:
|
// case CPU_PENTIUM2:
|
||||||
case CPU_PENTIUM2D:
|
case CPU_PENTIUM2D:
|
||||||
// pclog("WRMSR, ECX=%08X\n", ECX);
|
// pclog("WRMSR, ECX=%08X\n", ECX);
|
||||||
switch (ECX)
|
switch (ECX)
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ extern int cpu, cpu_manufacturer;
|
|||||||
|
|
||||||
/*686 class CPUs*/
|
/*686 class CPUs*/
|
||||||
#define CPU_PENTIUMPRO 25
|
#define CPU_PENTIUMPRO 25
|
||||||
|
/*
|
||||||
#define CPU_PENTIUM2 26
|
#define CPU_PENTIUM2 26
|
||||||
#define CPU_PENTIUM2D 27
|
#define CPU_PENTIUM2D 27 */
|
||||||
|
#define CPU_PENTIUM2D 26
|
||||||
|
|
||||||
#define MANU_INTEL 0
|
#define MANU_INTEL 0
|
||||||
#define MANU_AMD 1
|
#define MANU_AMD 1
|
||||||
|
|||||||
@@ -501,7 +501,7 @@ void disc_sector_poll()
|
|||||||
disc_sector_n[drive] != s->n ||
|
disc_sector_n[drive] != s->n ||
|
||||||
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
||||||
!fdd_can_read_medium(drive ^ fdd_swap) ||
|
!fdd_can_read_medium(drive ^ fdd_swap) ||
|
||||||
disc_intersector_delay[drive] || disc_track_delay[drive])
|
disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive])
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
@@ -529,7 +529,7 @@ void disc_sector_poll()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cur_byte[drive] || !index_count[drive] || fdc_get_bitcell_period() != get_bitcell_period(drive) ||
|
if (cur_byte[drive] || !index_count[drive] || fdc_get_bitcell_period() != get_bitcell_period(drive) ||
|
||||||
disc_intersector_delay[drive] || disc_track_delay[drive])
|
disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive])
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
@@ -561,7 +561,7 @@ void disc_sector_poll()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
||||||
disc_intersector_delay[drive] || disc_track_delay[drive])
|
disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive])
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
@@ -601,7 +601,7 @@ void disc_sector_poll()
|
|||||||
disc_sector_sector[drive] != s->r ||
|
disc_sector_sector[drive] != s->r ||
|
||||||
disc_sector_n[drive] != s->n ||
|
disc_sector_n[drive] != s->n ||
|
||||||
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
(fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
||||||
disc_intersector_delay[drive] || disc_track_delay[drive])
|
disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive])
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
@@ -636,7 +636,7 @@ void disc_sector_poll()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
if (cur_byte[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
||||||
disc_intersector_delay[drive] || disc_track_delay[drive])
|
disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive])
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
@@ -653,7 +653,7 @@ void disc_sector_poll()
|
|||||||
fdc_writeprotect();
|
fdc_writeprotect();
|
||||||
}
|
}
|
||||||
if (!index_count[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
if (!index_count[drive] || (fdc_get_bitcell_period() != get_bitcell_period(drive)) ||
|
||||||
disc_intersector_delay[drive] || disc_track_delay[drive])
|
disc_intersector_delay[drive] || disc_postdata_delay[drive] || disc_track_delay[drive] || disc_gap4_delay[drive])
|
||||||
{
|
{
|
||||||
advance_byte();
|
advance_byte();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ uint8_t keyboard_at_read(uint16_t port, void *priv)
|
|||||||
|
|
||||||
case 0x64:
|
case 0x64:
|
||||||
temp = (keyboard_at.status & 0xFB) | (mode & CCB_SYSTEM);
|
temp = (keyboard_at.status & 0xFB) | (mode & CCB_SYSTEM);
|
||||||
if (mode & CCB_IGNORELOCK) temp |= STAT_LOCK;
|
/* if (mode & CCB_IGNORELOCK) */ temp |= STAT_LOCK;
|
||||||
keyboard_at.status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/);
|
keyboard_at.status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,8 +156,10 @@ MODEL models[] =
|
|||||||
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_i430vx_init},
|
{"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_i430vx_init},
|
||||||
{"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_p55tvp4_init},
|
{"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 512, 1, at_p55tvp4_init},
|
||||||
{"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55va_init},
|
{"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, 1, 1, 256, 1, at_p55va_init},
|
||||||
{"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_i440fx_init},
|
{"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_i440fx_init},
|
||||||
{"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_kn97_init},
|
{"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, 1, 1, 1024, 1, at_kn97_init},
|
||||||
|
// {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_i440fx_init},
|
||||||
|
// {"Award KN97 (440FX PCI)",ROM_KN97, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, 1, 1, 1024, 1, at_kn97_init},
|
||||||
{"", -1, {"", 0, "", 0, "", 0}, 0,0,0, 0}
|
{"", -1, {"", 0, "", 0, "", 0}, 0,0,0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void mouse_serial_poll(int x, int y, int b)
|
|||||||
|
|
||||||
if (!(serial1.mctrl&0x10))
|
if (!(serial1.mctrl&0x10))
|
||||||
{
|
{
|
||||||
pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]);
|
// pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]);
|
||||||
serial_write_fifo(&serial1, mousedat[0]);
|
serial_write_fifo(&serial1, mousedat[0]);
|
||||||
serial_write_fifo(&serial1, mousedat[1]);
|
serial_write_fifo(&serial1, mousedat[1]);
|
||||||
serial_write_fifo(&serial1, mousedat[2]);
|
serial_write_fifo(&serial1, mousedat[2]);
|
||||||
|
|||||||
1648
src/ne2000.c
1648
src/ne2000.c
File diff suppressed because it is too large
Load Diff
12
src/pc.rc
12
src/pc.rc
@@ -123,13 +123,13 @@ BEGIN
|
|||||||
COMBOBOX IDC_COMBODRB,162,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBODRB,162,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||||
END
|
END
|
||||||
|
|
||||||
HdConfDlg DIALOGEX 0, 0, 210, 310+4*16
|
HdConfDlg DIALOGEX 0, 0, 210, 286+4*16
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Configure Hard Discs"
|
CAPTION "Configure Hard Discs"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 9, "Segoe UI"
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "OK",IDOK,31+12,290+64,50,14
|
DEFPUSHBUTTON "OK",IDOK,31+12,264+64,50,14
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,101+12,290+64,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,101+12,264+64,50,14
|
||||||
|
|
||||||
LTEXT "C:",IDC_STATIC,7,6,27,10
|
LTEXT "C:",IDC_STATIC,7,6,27,10
|
||||||
RADIOBUTTON "Hard drive", IDC_CHDD, 7+64, 6, 53, 12 , WS_TABSTOP
|
RADIOBUTTON "Hard drive", IDC_CHDD, 7+64, 6, 53, 12 , WS_TABSTOP
|
||||||
@@ -198,8 +198,8 @@ HdConfDlg DIALOGEX 0, 0, 210, 310+4*16
|
|||||||
LTEXT "G:",IDC_STATIC,7,222+64,27,10
|
LTEXT "G:",IDC_STATIC,7,222+64,27,10
|
||||||
RADIOBUTTON "CD-ROM", IDC_GCDROM, 7+128, 222+64, 53, 12 , WS_TABSTOP
|
RADIOBUTTON "CD-ROM", IDC_GCDROM, 7+128, 222+64, 53, 12 , WS_TABSTOP
|
||||||
|
|
||||||
LTEXT "H:",IDC_STATIC,7,262+64,27,10
|
LTEXT "H:",IDC_STATIC,7,238+64,27,10
|
||||||
RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+128, 262+64, 53, 12 , WS_TABSTOP
|
RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+128, 238+64, 53, 12 , WS_TABSTOP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
if (val&16) /*ICW1*/
|
if (val&16) /*ICW1*/
|
||||||
{
|
{
|
||||||
pic.mask=0xFF;
|
pic.mask=0;
|
||||||
pic.mask2=0;
|
pic.mask2=0;
|
||||||
pic.icw=1;
|
pic.icw=1;
|
||||||
pic.icw1=val;
|
pic.icw1=val;
|
||||||
@@ -222,7 +222,7 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
if (val&16) /*ICW1*/
|
if (val&16) /*ICW1*/
|
||||||
{
|
{
|
||||||
pic2.mask=0xFF;
|
pic2.mask=0;
|
||||||
pic2.mask2=0;
|
pic2.mask2=0;
|
||||||
pic2.icw=1;
|
pic2.icw=1;
|
||||||
pic2.icw1=val;
|
pic2.icw1=val;
|
||||||
|
|||||||
120
src/vid_svga.c
120
src/vid_svga.c
@@ -43,6 +43,19 @@ void svga_set_override(svga_t *svga, int val)
|
|||||||
svga->override = val;
|
svga->override = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef union pci_bar
|
||||||
|
{
|
||||||
|
uint16_t word;
|
||||||
|
uint8_t bytes[2];
|
||||||
|
} ichar;
|
||||||
|
|
||||||
|
ichar char12x24[65536][48];
|
||||||
|
uint8_t charedit_on = 0;
|
||||||
|
ichar charcode;
|
||||||
|
uint8_t charmode = 0;
|
||||||
|
uint8_t charptr = 0;
|
||||||
|
uint8_t charsettings = 0xEE;
|
||||||
|
|
||||||
void svga_out(uint16_t addr, uint8_t val, void *p)
|
void svga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
svga_t *svga = (svga_t *)p;
|
svga_t *svga = (svga_t *)p;
|
||||||
@@ -51,6 +64,40 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
|
|||||||
// printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
// printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,pc);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x32CB:
|
||||||
|
printf("Write 32CB: %04X\n", val);
|
||||||
|
charedit_on = (val & 0x10) ? 1 : 0;
|
||||||
|
charsettings = val;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x22CB:
|
||||||
|
printf("Write 22CB: %04X\n", val);
|
||||||
|
charmode = val;
|
||||||
|
charptr = 0;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x22CF:
|
||||||
|
printf("Write 22CF: %04X\n", val);
|
||||||
|
// if (!charedit_on) return;
|
||||||
|
switch(charmode)
|
||||||
|
{
|
||||||
|
case 1: case 2:
|
||||||
|
charcode.bytes[charmode - 1] = val;
|
||||||
|
return;
|
||||||
|
case 3: case 4: /* Character bitmaps */
|
||||||
|
char12x24[charcode.word][charptr].bytes[(charmode & 1) ^ 1] = val;
|
||||||
|
charptr++;
|
||||||
|
charptr %= 48;
|
||||||
|
return;
|
||||||
|
case 0xAA: default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0x22CA: case 0x22CE: case 0x32CA:
|
||||||
|
printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc);
|
||||||
|
return;
|
||||||
|
|
||||||
case 0x3C0:
|
case 0x3C0:
|
||||||
if (!svga->attrff)
|
if (!svga->attrff)
|
||||||
{
|
{
|
||||||
@@ -251,6 +298,41 @@ uint8_t svga_in(uint16_t addr, void *p)
|
|||||||
// if (addr!=0x3da) pclog("Read port %04X\n",addr);
|
// if (addr!=0x3da) pclog("Read port %04X\n",addr);
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x22CA:
|
||||||
|
pclog("Read port %04X\n", addr);
|
||||||
|
return 0xAA;
|
||||||
|
case 0x22CB:
|
||||||
|
pclog("Read port %04X\n", addr);
|
||||||
|
// return charmode;
|
||||||
|
return 0xF0 | (charmode & 0x1F);
|
||||||
|
case 0x22CE:
|
||||||
|
pclog("Read port %04X\n", addr);
|
||||||
|
return 0xCC;
|
||||||
|
case 0x22CF: /* Read character bitmap */
|
||||||
|
pclog("Read port %04X\n", addr);
|
||||||
|
// if (!charedit_on) return 0xFF;
|
||||||
|
switch(charmode)
|
||||||
|
{
|
||||||
|
case 1: case 2:
|
||||||
|
return charcode.bytes[charmode - 1];
|
||||||
|
case 3: case 4: /* Character bitmaps */
|
||||||
|
/* Mode 3 is low bytes, mode 4 is high bytes */
|
||||||
|
temp = char12x24[charcode.word][charptr].bytes[(charmode & 1) ^ 1];
|
||||||
|
charptr++;
|
||||||
|
charptr %= 48;
|
||||||
|
return temp;
|
||||||
|
case 0xAA: default:
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
case 0x32CA:
|
||||||
|
pclog("Read port %04X\n", addr);
|
||||||
|
return 0xEE;
|
||||||
|
case 0x32CB:
|
||||||
|
pclog("Read port %04X\n", addr);
|
||||||
|
return 0xEE;
|
||||||
|
return charsettings;
|
||||||
|
// return 0xEE | (charedit_on ? 0x10 : 0);
|
||||||
|
|
||||||
case 0x3C0:
|
case 0x3C0:
|
||||||
return svga->attraddr | svga->attr_palette_enable;
|
return svga->attraddr | svga->attr_palette_enable;
|
||||||
case 0x3C1:
|
case 0x3C1:
|
||||||
@@ -384,13 +466,29 @@ void svga_recalctimings(svga_t *svga)
|
|||||||
{
|
{
|
||||||
if (svga->seqregs[1] & 8) /*40 column*/
|
if (svga->seqregs[1] & 8) /*40 column*/
|
||||||
{
|
{
|
||||||
svga->render = svga_render_text_40;
|
if (svga->hdisp == 120)
|
||||||
svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
|
{
|
||||||
|
svga->render = svga_render_text_40_12;
|
||||||
|
svga->hdisp *= 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
svga->render = svga_render_text_40;
|
||||||
|
svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
svga->render = svga_render_text_80;
|
if (svga->hdisp == 120)
|
||||||
svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
|
{
|
||||||
|
svga->render = svga_render_text_80_12;
|
||||||
|
svga->hdisp *= 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
svga->render = svga_render_text_80;
|
||||||
|
svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svga->hdisp_old = svga->hdisp;
|
svga->hdisp_old = svga->hdisp;
|
||||||
}
|
}
|
||||||
@@ -805,6 +903,10 @@ int svga_init(svga_t *svga, void *p, int memsize,
|
|||||||
|
|
||||||
svga_pointer = svga;
|
svga_pointer = svga;
|
||||||
|
|
||||||
|
io_sethandler(0x22ca, 0x0002, svga_in, NULL, NULL, svga_out, NULL, NULL, svga);
|
||||||
|
io_sethandler(0x22ce, 0x0002, svga_in, NULL, NULL, svga_out, NULL, NULL, svga);
|
||||||
|
io_sethandler(0x32ca, 0x0002, svga_in, NULL, NULL, svga_out, NULL, NULL, svga);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,6 +1114,13 @@ void svga_write(uint32_t addr, uint8_t val, void *p)
|
|||||||
svga->gdcreg[8] = wm;
|
svga->gdcreg[8] = wm;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (svga->render == svga_render_text_80_12)
|
||||||
|
{
|
||||||
|
FILE *f = fopen("hecon.dmp", "wb");
|
||||||
|
fwrite(svga->vram, 1, svga->vram_limit, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t svga_read(uint32_t addr, void *p)
|
uint8_t svga_read(uint32_t addr, void *p)
|
||||||
@@ -1627,6 +1736,9 @@ void svga_add_status_info(char *s, int max_len, void *p)
|
|||||||
sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y);
|
sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y);
|
||||||
strncat(s, temps, max_len);
|
strncat(s, temps, max_len);
|
||||||
|
|
||||||
|
sprintf(temps, "SVGA horizontal display : %i\n", svga->hdisp);
|
||||||
|
strncat(s, temps, max_len);
|
||||||
|
|
||||||
sprintf(temps, "SVGA refresh rate : %i Hz (%s)\n\n", svga->frames, svga->interlace ? "i" : "p");
|
sprintf(temps, "SVGA refresh rate : %i Hz (%s)\n\n", svga->frames, svga->interlace ? "i" : "p");
|
||||||
svga->frames = 0;
|
svga->frames = 0;
|
||||||
strncat(s, temps, max_len);
|
strncat(s, temps, max_len);
|
||||||
|
|||||||
@@ -101,6 +101,61 @@ void svga_render_text_40(svga_t *svga)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void svga_render_text_40_12(svga_t *svga)
|
||||||
|
{
|
||||||
|
int y_add = (enable_overscan) ? 16 : 0;
|
||||||
|
int x_add = (enable_overscan) ? 12 : 0;
|
||||||
|
|
||||||
|
if (svga->firstline_draw == 2000)
|
||||||
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (svga->fullchange)
|
||||||
|
{
|
||||||
|
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add];
|
||||||
|
int x, xx;
|
||||||
|
int drawcursor;
|
||||||
|
uint8_t chr, attr;
|
||||||
|
uint16_t dat;
|
||||||
|
uint32_t charaddr;
|
||||||
|
int fg, bg;
|
||||||
|
int xinc = 24;
|
||||||
|
|
||||||
|
for (x = 0; x < svga->hdisp; x += xinc)
|
||||||
|
{
|
||||||
|
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||||
|
chr = svga->vram[svga->ma << 1];
|
||||||
|
attr = svga->vram[(svga->ma << 1) + 1];
|
||||||
|
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||||
|
else charaddr = svga->charseta + (chr * 128);
|
||||||
|
|
||||||
|
if (drawcursor)
|
||||||
|
{
|
||||||
|
bg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
|
fg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
|
bg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
|
if (attr & 0x80 && svga->attrregs[0x10] & 8)
|
||||||
|
{
|
||||||
|
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
|
||||||
|
if (svga->blink & 16)
|
||||||
|
fg = bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dat = *(uint16_t *) &(svga->vram[charaddr + (svga->sc << 2) - 1]);
|
||||||
|
for (xx = 0; xx < 24; xx += 2)
|
||||||
|
p[xx] = p[xx + 1] = (dat & (0x800 >> (xx >> 1))) ? fg : bg;
|
||||||
|
svga->ma += 4;
|
||||||
|
p += xinc;
|
||||||
|
}
|
||||||
|
svga->ma = svga_mask_addr(svga->ma, svga);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void svga_render_text_80(svga_t *svga)
|
void svga_render_text_80(svga_t *svga)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
@@ -168,6 +223,63 @@ void svga_render_text_80(svga_t *svga)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void svga_render_text_80_12(svga_t *svga)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int y_add = (enable_overscan) ? 16 : 0;
|
||||||
|
int x_add = (enable_overscan) ? 12 : 0;
|
||||||
|
|
||||||
|
if (svga->firstline_draw == 2000)
|
||||||
|
svga->firstline_draw = svga->displine;
|
||||||
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (svga->fullchange)
|
||||||
|
{
|
||||||
|
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add];
|
||||||
|
int x, xx;
|
||||||
|
int drawcursor;
|
||||||
|
uint8_t chr, attr;
|
||||||
|
uint16_t dat;
|
||||||
|
uint32_t charaddr;
|
||||||
|
int fg, bg;
|
||||||
|
int xinc = 12;
|
||||||
|
|
||||||
|
for (x = 0; x < svga->hdisp; x += xinc)
|
||||||
|
{
|
||||||
|
drawcursor = ((svga->ma == (svga->ca + 8)) && svga->con && svga->cursoron);
|
||||||
|
chr = svga->vram[svga->ma << 1];
|
||||||
|
attr = svga->vram[(svga->ma << 1) + 1];
|
||||||
|
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||||
|
else charaddr = svga->charseta + (chr * 128);
|
||||||
|
|
||||||
|
if (drawcursor)
|
||||||
|
{
|
||||||
|
bg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
|
fg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fg = svga->pallook[svga->egapal[attr & 15]];
|
||||||
|
bg = svga->pallook[svga->egapal[attr >> 4]];
|
||||||
|
if (attr & 0x80 && svga->attrregs[0x10] & 8)
|
||||||
|
{
|
||||||
|
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
|
||||||
|
if (svga->blink & 16)
|
||||||
|
fg = bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dat = svga->vram[charaddr + (svga->sc << 2)] << 4;
|
||||||
|
dat |= ((svga->vram[charaddr + (svga->sc << 2) + 1]) >> 4);
|
||||||
|
for (xx = 0; xx < 12; xx++)
|
||||||
|
p[xx] = (dat & (0x800 >> xx)) ? fg : bg;
|
||||||
|
svga->ma += 4;
|
||||||
|
p += xinc;
|
||||||
|
}
|
||||||
|
svga->ma = svga_mask_addr(svga->ma, svga);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void svga_render_2bpp_lowres(svga_t *svga)
|
void svga_render_2bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int changed_offset;
|
int changed_offset;
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ extern uint8_t edatlookup[4][4];
|
|||||||
|
|
||||||
void svga_render_blank(svga_t *svga);
|
void svga_render_blank(svga_t *svga);
|
||||||
void svga_render_text_40(svga_t *svga);
|
void svga_render_text_40(svga_t *svga);
|
||||||
|
void svga_render_text_40_12(svga_t *svga);
|
||||||
void svga_render_text_80(svga_t *svga);
|
void svga_render_text_80(svga_t *svga);
|
||||||
|
void svga_render_text_80_12(svga_t *svga);
|
||||||
|
|
||||||
void svga_render_2bpp_lowres(svga_t *svga);
|
void svga_render_2bpp_lowres(svga_t *svga);
|
||||||
void svga_render_2bpp_highres(svga_t *svga);
|
void svga_render_2bpp_highres(svga_t *svga);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ extern OpFn dynarec_ops_k6_0f[1024];
|
|||||||
|
|
||||||
extern OpFn dynarec_ops_c6x86mx_0f[1024];
|
extern OpFn dynarec_ops_c6x86mx_0f[1024];
|
||||||
extern OpFn dynarec_ops_pentiumpro_0f[1024];
|
extern OpFn dynarec_ops_pentiumpro_0f[1024];
|
||||||
extern OpFn dynarec_ops_pentium2_0f[1024];
|
// extern OpFn dynarec_ops_pentium2_0f[1024];
|
||||||
extern OpFn dynarec_ops_pentium2d_0f[1024];
|
extern OpFn dynarec_ops_pentium2d_0f[1024];
|
||||||
|
|
||||||
extern OpFn dynarec_ops_fpu_d8_a16[32];
|
extern OpFn dynarec_ops_fpu_d8_a16[32];
|
||||||
@@ -106,7 +106,7 @@ extern OpFn ops_k6_0f[1024];
|
|||||||
|
|
||||||
extern OpFn ops_c6x86mx_0f[1024];
|
extern OpFn ops_c6x86mx_0f[1024];
|
||||||
extern OpFn ops_pentiumpro_0f[1024];
|
extern OpFn ops_pentiumpro_0f[1024];
|
||||||
extern OpFn ops_pentium2_0f[1024];
|
// extern OpFn ops_pentium2_0f[1024];
|
||||||
extern OpFn ops_pentium2d_0f[1024];
|
extern OpFn ops_pentium2d_0f[1024];
|
||||||
|
|
||||||
extern OpFn ops_fpu_d8_a16[32];
|
extern OpFn ops_fpu_d8_a16[32];
|
||||||
|
|||||||
@@ -329,16 +329,16 @@ static int opMOV_a32_EAX(uint32_t fetchdat)
|
|||||||
static int opLEA_w_a16(uint32_t fetchdat)
|
static int opLEA_w_a16(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
// ILLEGAL_ON(mod == 3);
|
ILLEGAL_ON(mod == 3);
|
||||||
cpu_state.regs[reg].w = (mod == 3) ? (cpu_state.last_ea & 0xffff) : eaaddr;
|
cpu_state.regs[reg].w = eaaddr;
|
||||||
CLOCK_CYCLES(timing_rr);
|
CLOCK_CYCLES(timing_rr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int opLEA_w_a32(uint32_t fetchdat)
|
static int opLEA_w_a32(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
fetch_ea_32(fetchdat);
|
fetch_ea_32(fetchdat);
|
||||||
// ILLEGAL_ON(mod == 3);
|
ILLEGAL_ON(mod == 3);
|
||||||
cpu_state.regs[reg].w = (mod == 3) ? (cpu_state.last_ea & 0xffff) : eaaddr;
|
cpu_state.regs[reg].w = eaaddr;
|
||||||
CLOCK_CYCLES(timing_rr);
|
CLOCK_CYCLES(timing_rr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -346,16 +346,16 @@ static int opLEA_w_a32(uint32_t fetchdat)
|
|||||||
static int opLEA_l_a16(uint32_t fetchdat)
|
static int opLEA_l_a16(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
// ILLEGAL_ON(mod == 3);
|
ILLEGAL_ON(mod == 3);
|
||||||
cpu_state.regs[reg].l = ((mod == 3) ? cpu_state.last_ea : eaaddr) & 0xffff;
|
cpu_state.regs[reg].l = eaaddr & 0xffff;
|
||||||
CLOCK_CYCLES(timing_rr);
|
CLOCK_CYCLES(timing_rr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int opLEA_l_a32(uint32_t fetchdat)
|
static int opLEA_l_a32(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
fetch_ea_32(fetchdat);
|
fetch_ea_32(fetchdat);
|
||||||
// ILLEGAL_ON(mod == 3);
|
ILLEGAL_ON(mod == 3);
|
||||||
cpu_state.regs[reg].l = (mod == 3) ? cpu_state.last_ea : eaaddr;
|
cpu_state.regs[reg].l = eaaddr;
|
||||||
CLOCK_CYCLES(timing_rr);
|
CLOCK_CYCLES(timing_rr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
238
src/x86seg.c
238
src/x86seg.c
@@ -78,7 +78,7 @@ void x86_doabrt(int x86_abrt)
|
|||||||
|
|
||||||
/* if (CS == 0x3433 && cpu_state.pc == 0x000006B0)
|
/* if (CS == 0x3433 && cpu_state.pc == 0x000006B0)
|
||||||
{
|
{
|
||||||
pclog("Quit it\n");
|
// pclog("Quit it\n");
|
||||||
dumpregs();
|
dumpregs();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}*/
|
}*/
|
||||||
@@ -260,7 +260,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
{
|
{
|
||||||
if (s==&_ss)
|
if (s==&_ss)
|
||||||
{
|
{
|
||||||
pclog("SS selector = NULL!\n");
|
// pclog("SS selector = NULL!\n");
|
||||||
x86ss(NULL,0);
|
x86ss(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -281,7 +281,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n",seg,ldt.limit, opcode, opcode2, rmdat);
|
// pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n",seg,ldt.limit, opcode, opcode2, rmdat);
|
||||||
// dumppic();
|
// dumppic();
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
@@ -294,7 +294,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X 1\n",seg,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X 1\n",seg,gdt.limit);
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
x86gpf("loadseg(): Bigger than GDT limit",seg&~3);
|
x86gpf("loadseg(): Bigger than GDT limit",seg&~3);
|
||||||
@@ -312,13 +312,13 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
{
|
{
|
||||||
if (!(seg&~3))
|
if (!(seg&~3))
|
||||||
{
|
{
|
||||||
pclog("Load SS null selector\n");
|
// pclog("Load SS null selector\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((seg&3)!=CPL || dpl!=CPL)
|
if ((seg&3)!=CPL || dpl!=CPL)
|
||||||
{
|
{
|
||||||
pclog("Invalid SS permiss\n");
|
// pclog("Invalid SS permiss\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
// x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC);
|
// x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC);
|
||||||
return;
|
return;
|
||||||
@@ -328,14 +328,14 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
case 0x12: case 0x13: case 0x16: case 0x17: /*r/w*/
|
case 0x12: case 0x13: case 0x16: case 0x17: /*r/w*/
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("Invalid SS type\n");
|
// pclog("Invalid SS type\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
// x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC);
|
// x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Load SS not present!\n");
|
// pclog("Load SS not present!\n");
|
||||||
x86ss(NULL,seg&~3);
|
x86ss(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
// pclog("Load seg %04X %i %i %04X:%08X\n",seg,dpl,CS&3,CS,cpu_state.pc);
|
// pclog("Load seg %04X %i %i %04X:%08X\n",seg,dpl,CS&3,CS,cpu_state.pc);
|
||||||
if ((seg&3)>dpl || (CPL)>dpl)
|
if ((seg&3)>dpl || (CPL)>dpl)
|
||||||
{
|
{
|
||||||
pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]);
|
// pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
// x86abort("Data segment load - level too low!\n",seg&0xFFFC);
|
// x86abort("Data segment load - level too low!\n",seg&0xFFFC);
|
||||||
return;
|
return;
|
||||||
@@ -363,7 +363,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
case 0x1E: case 0x1F: /*Readable conforming code*/
|
case 0x1E: case 0x1F: /*Readable conforming code*/
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]);
|
// pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -418,7 +418,7 @@ void loadcs(uint16_t seg)
|
|||||||
// pclog("Load CS %04X\n",seg);
|
// pclog("Load CS %04X\n",seg);
|
||||||
if (!(seg&~3))
|
if (!(seg&~3))
|
||||||
{
|
{
|
||||||
pclog("Trying to load CS with NULL selector! lcs\n");
|
// pclog("Trying to load CS with NULL selector! lcs\n");
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
@@ -430,7 +430,7 @@ void loadcs(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit);
|
// pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -440,7 +440,7 @@ void loadcs(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -451,7 +451,7 @@ void loadcs(uint16_t seg)
|
|||||||
segdat[1]=readmemw(0,addr+2);
|
segdat[1]=readmemw(0,addr+2);
|
||||||
segdat[2]=readmemw(0,addr+4);
|
segdat[2]=readmemw(0,addr+4);
|
||||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (abrt) return;
|
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (abrt) return;
|
||||||
if (optype==JMP) pclog("Code seg - %04X - %04X %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2],segdat[3]);
|
// if (optype==JMP) pclog("Code seg - %04X - %04X %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||||
// if (!(segdat[2]&0x8000)) x86abort("Code segment not present!\n");
|
// if (!(segdat[2]&0x8000)) x86abort("Code segment not present!\n");
|
||||||
// if (output) pclog("Segdat2 %04X\n",segdat[2]);
|
// if (output) pclog("Segdat2 %04X\n",segdat[2]);
|
||||||
if (segdat[2]&0x1000) /*Normal code segment*/
|
if (segdat[2]&0x1000) /*Normal code segment*/
|
||||||
@@ -461,7 +461,7 @@ void loadcs(uint16_t seg)
|
|||||||
if ((seg&3)>CPL)
|
if ((seg&3)>CPL)
|
||||||
{
|
{
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
pclog("loadcs RPL > CPL %04X %04X %i %02X\n",segdat[2],seg,CPL,opcode);
|
// pclog("loadcs RPL > CPL %04X %04X %i %02X\n",segdat[2],seg,CPL,opcode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (CPL != DPL)
|
if (CPL != DPL)
|
||||||
@@ -505,7 +505,7 @@ void loadcs(uint16_t seg)
|
|||||||
switch (segdat[2]&0xF00)
|
switch (segdat[2]&0xF00)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
pclog("Bad CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg);
|
// pclog("Bad CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -539,7 +539,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
{
|
{
|
||||||
if (!(seg&~3))
|
if (!(seg&~3))
|
||||||
{
|
{
|
||||||
pclog("Trying to load CS with NULL selector! lcsjmp\n");
|
// pclog("Trying to load CS with NULL selector! lcsjmp\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -550,7 +550,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit);
|
// pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -560,7 +560,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -620,7 +620,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
// pclog("System CS\n");
|
// pclog("System CS\n");
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
x86np("Load CS JMP system selector not present\n", seg & 0xfffc);
|
// x86np("Load CS JMP system selector not present\n", seg & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
type=segdat[2]&0xF00;
|
type=segdat[2]&0xF00;
|
||||||
@@ -662,7 +662,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
|
|
||||||
if (!(seg2&~3))
|
if (!(seg2&~3))
|
||||||
{
|
{
|
||||||
pclog("Trying to load CS with NULL selector! lcsjmpcg\n");
|
// pclog("Trying to load CS with NULL selector! lcsjmpcg\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -673,7 +673,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X CSJ\n",seg2,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X CSJ\n",seg2,gdt.limit);
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -683,7 +683,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X CSJ\n",seg2,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X CSJ\n",seg2,gdt.limit);
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -712,7 +712,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
||||||
if (DPL > CPL)
|
if (DPL > CPL)
|
||||||
{
|
{
|
||||||
pclog("Call gate DPL > CPL");
|
// pclog("Call gate DPL > CPL");
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -731,7 +731,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("JMP Call gate bad segment type\n");
|
// pclog("JMP Call gate bad segment type\n");
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -752,7 +752,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("Bad JMP CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg);
|
// pclog("Bad JMP CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg);
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -865,7 +865,7 @@ void loadcscall(uint16_t seg)
|
|||||||
if (csout) pclog("Protected mode CS load! %04X\n",seg);
|
if (csout) pclog("Protected mode CS load! %04X\n",seg);
|
||||||
if (!(seg&~3))
|
if (!(seg&~3))
|
||||||
{
|
{
|
||||||
pclog("Trying to load CS with NULL selector! lcscall\n");
|
// pclog("Trying to load CS with NULL selector! lcscall\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -876,7 +876,7 @@ void loadcscall(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X CSC\n",seg,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X CSC\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -886,7 +886,7 @@ void loadcscall(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X CSC\n",seg,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X CSC\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -908,26 +908,26 @@ void loadcscall(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if ((seg&3)>CPL)
|
if ((seg&3)>CPL)
|
||||||
{
|
{
|
||||||
/* if (csout) */ pclog("Not conforming, RPL > CPL\n");
|
/* if (csout) */ // pclog("Not conforming, RPL > CPL\n");
|
||||||
x86gpf("loadcscall(): segment > CPL",seg&~3);
|
x86gpf("loadcscall(): segment > CPL",seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (CPL != DPL)
|
if (CPL != DPL)
|
||||||
{
|
{
|
||||||
/* if (csout) */ pclog("Not conforming, CPL != DPL (%i %i)\n",CPL,DPL);
|
/* if (csout) */ // pclog("Not conforming, CPL != DPL (%i %i)\n",CPL,DPL);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CPL < DPL)
|
if (CPL < DPL)
|
||||||
{
|
{
|
||||||
/* if (csout) */ pclog("CPL < DPL\n");
|
/* if (csout) */ // pclog("CPL < DPL\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
/* if (csout) */ pclog("Not present\n");
|
/* if (csout) */ // pclog("Not present\n");
|
||||||
x86np("Load CS call not present", seg & 0xfffc);
|
x86np("Load CS call not present", seg & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -998,7 +998,7 @@ void loadcscall(uint16_t seg)
|
|||||||
|
|
||||||
if (!(seg2&~3))
|
if (!(seg2&~3))
|
||||||
{
|
{
|
||||||
pclog("Trying to load CS with NULL selector! lcscallcg\n");
|
// pclog("Trying to load CS with NULL selector! lcscallcg\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -1009,7 +1009,7 @@ void loadcscall(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X CSC\n",seg2,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X CSC\n",seg2,gdt.limit);
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1019,7 +1019,7 @@ void loadcscall(uint16_t seg)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X CSC\n",seg2,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X CSC\n",seg2,gdt.limit);
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1073,7 +1073,7 @@ void loadcscall(uint16_t seg)
|
|||||||
if (output) pclog("New stack %04X:%08X\n",newss,newsp);
|
if (output) pclog("New stack %04X:%08X\n",newss,newsp);
|
||||||
if (!(newss&~3))
|
if (!(newss&~3))
|
||||||
{
|
{
|
||||||
pclog("Call gate loading null SS\n");
|
// pclog("Call gate loading null SS\n");
|
||||||
x86ts(NULL,newss&~3);
|
x86ts(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1107,7 @@ void loadcscall(uint16_t seg)
|
|||||||
if (output) pclog("Read stack seg done!\n");
|
if (output) pclog("Read stack seg done!\n");
|
||||||
if (((newss & 3) != DPL) || (DPL2 != DPL))
|
if (((newss & 3) != DPL) || (DPL2 != DPL))
|
||||||
{
|
{
|
||||||
pclog("Call gate loading SS with wrong permissions %04X %04X %i %i %04X %04X\n", newss, seg2, DPL, DPL2, segdat[2], segdat2[2]);
|
// pclog("Call gate loading SS with wrong permissions %04X %04X %i %i %04X %04X\n", newss, seg2, DPL, DPL2, segdat[2], segdat2[2]);
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
x86ts(NULL,newss&~3);
|
x86ts(NULL,newss&~3);
|
||||||
@@ -1115,13 +1115,13 @@ void loadcscall(uint16_t seg)
|
|||||||
}
|
}
|
||||||
if ((segdat2[2]&0x1A00)!=0x1200)
|
if ((segdat2[2]&0x1A00)!=0x1200)
|
||||||
{
|
{
|
||||||
pclog("Call gate loading SS wrong type\n");
|
// pclog("Call gate loading SS wrong type\n");
|
||||||
x86ts(NULL,newss&~3);
|
x86ts(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Call gate loading SS not present\n");
|
// pclog("Call gate loading SS not present\n");
|
||||||
x86np("Call gate loading SS not present\n", newss & 0xfffc);
|
x86np("Call gate loading SS not present\n", newss & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1162,7 +1162,7 @@ void loadcscall(uint16_t seg)
|
|||||||
PUSHL(oldsp2);
|
PUSHL(oldsp2);
|
||||||
if (abrt)
|
if (abrt)
|
||||||
{
|
{
|
||||||
pclog("ABRT PUSHL\n");
|
// pclog("ABRT PUSHL\n");
|
||||||
SS = oldss;
|
SS = oldss;
|
||||||
ESP = oldsp2;
|
ESP = oldsp2;
|
||||||
return;
|
return;
|
||||||
@@ -1176,7 +1176,7 @@ void loadcscall(uint16_t seg)
|
|||||||
PUSHL(readmeml(oldssbase,oldsp+(count*4)));
|
PUSHL(readmeml(oldssbase,oldsp+(count*4)));
|
||||||
if (abrt)
|
if (abrt)
|
||||||
{
|
{
|
||||||
pclog("ABRT COPYL\n");
|
// pclog("ABRT COPYL\n");
|
||||||
SS = oldss;
|
SS = oldss;
|
||||||
ESP = oldsp2;
|
ESP = oldsp2;
|
||||||
return;
|
return;
|
||||||
@@ -1195,7 +1195,7 @@ void loadcscall(uint16_t seg)
|
|||||||
PUSHW(oldsp2);
|
PUSHW(oldsp2);
|
||||||
if (abrt)
|
if (abrt)
|
||||||
{
|
{
|
||||||
pclog("ABRT PUSHW\n");
|
// pclog("ABRT PUSHW\n");
|
||||||
SS = oldss;
|
SS = oldss;
|
||||||
ESP = oldsp2;
|
ESP = oldsp2;
|
||||||
return;
|
return;
|
||||||
@@ -1213,7 +1213,7 @@ void loadcscall(uint16_t seg)
|
|||||||
PUSHW(tempw);
|
PUSHW(tempw);
|
||||||
if (abrt)
|
if (abrt)
|
||||||
{
|
{
|
||||||
pclog("ABRT COPYW\n");
|
// pclog("ABRT COPYW\n");
|
||||||
SS = oldss;
|
SS = oldss;
|
||||||
ESP = oldsp2;
|
ESP = oldsp2;
|
||||||
return;
|
return;
|
||||||
@@ -1230,7 +1230,7 @@ void loadcscall(uint16_t seg)
|
|||||||
}
|
}
|
||||||
else if (DPL > CPL)
|
else if (DPL > CPL)
|
||||||
{
|
{
|
||||||
pclog("Call gate DPL > CPL");
|
// pclog("Call gate DPL > CPL");
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1260,7 +1260,7 @@ void loadcscall(uint16_t seg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("Call gate bad segment type\n");
|
// pclog("Call gate bad segment type\n");
|
||||||
x86gpf(NULL,seg2&~3);
|
x86gpf(NULL,seg2&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1274,7 +1274,7 @@ void loadcscall(uint16_t seg)
|
|||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00);
|
// pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -1321,7 +1321,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
if (output) pclog("Return to %04X:%08X\n",seg,newpc);
|
if (output) pclog("Return to %04X:%08X\n",seg,newpc);
|
||||||
if ((seg&3)<CPL)
|
if ((seg&3)<CPL)
|
||||||
{
|
{
|
||||||
pclog("RETF RPL<CPL %04X %i %i %04X:%08X\n",seg,CPL,ins,CS,cpu_state.pc);
|
// pclog("RETF RPL<CPL %04X %i %i %04X:%08X\n",seg,CPL,ins,CS,cpu_state.pc);
|
||||||
// output=3;
|
// output=3;
|
||||||
// timetolive=100;
|
// timetolive=100;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -1332,7 +1332,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
}
|
}
|
||||||
if (!(seg&~3))
|
if (!(seg&~3))
|
||||||
{
|
{
|
||||||
pclog("Trying to load CS with NULL selector! retf\n");
|
// pclog("Trying to load CS with NULL selector! retf\n");
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
@@ -1343,7 +1343,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X RETF\n",seg,ldt.limit);
|
// pclog("Bigger than LDT limit %04X %04X RETF\n",seg,ldt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1353,7 +1353,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X RETF\n",seg,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X RETF\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
@@ -1381,7 +1381,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
||||||
if (CPL != DPL)
|
if (CPL != DPL)
|
||||||
{
|
{
|
||||||
pclog("RETF non-conforming CPL != DPL\n");
|
// pclog("RETF non-conforming CPL != DPL\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1390,20 +1390,20 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||||
if (CPL < DPL)
|
if (CPL < DPL)
|
||||||
{
|
{
|
||||||
pclog("RETF non-conforming CPL < DPL\n");
|
// pclog("RETF non-conforming CPL < DPL\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("RETF CS not code segment\n");
|
// pclog("RETF CS not code segment\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("RETF CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]);
|
// pclog("RETF CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]);
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86np("RETF CS not present\n", seg & 0xfffc);
|
x86np("RETF CS not present\n", seg & 0xfffc);
|
||||||
return;
|
return;
|
||||||
@@ -1434,7 +1434,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
||||||
if ((seg&3) != DPL)
|
if ((seg&3) != DPL)
|
||||||
{
|
{
|
||||||
pclog("RETF non-conforming RPL != DPL\n");
|
// pclog("RETF non-conforming RPL != DPL\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1444,7 +1444,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||||
if ((seg&3) < DPL)
|
if ((seg&3) < DPL)
|
||||||
{
|
{
|
||||||
pclog("RETF non-conforming RPL < DPL\n");
|
// pclog("RETF non-conforming RPL < DPL\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1452,14 +1452,14 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
if (output) pclog("RETF conforming, %i %i\n",seg&3, DPL);
|
if (output) pclog("RETF conforming, %i %i\n",seg&3, DPL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("RETF CS not code segment\n");
|
// pclog("RETF CS not code segment\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("RETF CS not present! %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]);
|
// pclog("RETF CS not present! %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]);
|
||||||
|
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86np("RETF CS not present\n", seg & 0xfffc);
|
x86np("RETF CS not present\n", seg & 0xfffc);
|
||||||
@@ -1482,7 +1482,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
if (output) pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base);
|
if (output) pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base);
|
||||||
if (!(newss&~3))
|
if (!(newss&~3))
|
||||||
{
|
{
|
||||||
pclog("RETF loading null SS\n");
|
// pclog("RETF loading null SS\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1492,7 +1492,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X RETF SS\n",newss,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X RETF SS\n",newss,gdt.limit);
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1503,7 +1503,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X RETF SS\n",newss,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X RETF SS\n",newss,gdt.limit);
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1519,7 +1519,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
// if (((newss & 3) != DPL) || (DPL2 != DPL))
|
// if (((newss & 3) != DPL) || (DPL2 != DPL))
|
||||||
if ((newss & 3) != (seg & 3))
|
if ((newss & 3) != (seg & 3))
|
||||||
{
|
{
|
||||||
pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg);
|
// pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg);
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
// output = 3;
|
// output = 3;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -1529,7 +1529,7 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
}
|
}
|
||||||
if ((segdat2[2]&0x1A00)!=0x1200)
|
if ((segdat2[2]&0x1A00)!=0x1200)
|
||||||
{
|
{
|
||||||
pclog("RETF loading SS wrong type\n");
|
// pclog("RETF loading SS wrong type\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
@@ -1538,14 +1538,14 @@ void pmoderetf(int is32, uint16_t off)
|
|||||||
}
|
}
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("RETF loading SS not present\n");
|
// pclog("RETF loading SS not present\n");
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86np("RETF loading SS not present\n", newss & 0xfffc);
|
x86np("RETF loading SS not present\n", newss & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DPL2 != (seg & 3))
|
if (DPL2 != (seg & 3))
|
||||||
{
|
{
|
||||||
pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg);
|
// pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg);
|
||||||
ESP=oldsp;
|
ESP=oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -1609,7 +1609,7 @@ void pmodeint(int num, int soft)
|
|||||||
if (eflags&VM_FLAG && IOPL!=3 && soft)
|
if (eflags&VM_FLAG && IOPL!=3 && soft)
|
||||||
{
|
{
|
||||||
if (output) pclog("V86 banned int\n");
|
if (output) pclog("V86 banned int\n");
|
||||||
pclog("V86 banned int!\n");
|
// pclog("V86 banned int!\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -1621,18 +1621,18 @@ void pmodeint(int num, int soft)
|
|||||||
if (num==8)
|
if (num==8)
|
||||||
{
|
{
|
||||||
/*Triple fault - reset!*/
|
/*Triple fault - reset!*/
|
||||||
pclog("Triple fault!\n");
|
// pclog("Triple fault!\n");
|
||||||
// output=1;
|
// output=1;
|
||||||
softresetx86();
|
softresetx86();
|
||||||
}
|
}
|
||||||
else if (num==0xD)
|
else if (num==0xD)
|
||||||
{
|
{
|
||||||
pclog("Double fault!\n");
|
// pclog("Double fault!\n");
|
||||||
pmodeint(8,0);
|
pmodeint(8,0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pclog("INT out of range\n");
|
// pclog("INT out of range\n");
|
||||||
x86gpf(NULL,(num*8)+2+(soft)?0:1);
|
x86gpf(NULL,(num*8)+2+(soft)?0:1);
|
||||||
}
|
}
|
||||||
if (output) pclog("addr >= IDT.limit\n");
|
if (output) pclog("addr >= IDT.limit\n");
|
||||||
@@ -1643,7 +1643,7 @@ void pmodeint(int num, int soft)
|
|||||||
segdat[0]=readmemw(0,addr);
|
segdat[0]=readmemw(0,addr);
|
||||||
segdat[1]=readmemw(2,addr);
|
segdat[1]=readmemw(2,addr);
|
||||||
segdat[2]=readmemw(4,addr);
|
segdat[2]=readmemw(4,addr);
|
||||||
segdat[3]=readmemw(6,addr); cpl_override=0; if (abrt) { pclog("Abrt reading from %08X\n",addr); return; }
|
segdat[3]=readmemw(6,addr); cpl_override=0; if (abrt) { /* pclog("Abrt reading from %08X\n",addr); */ return; }
|
||||||
oaddr = addr;
|
oaddr = addr;
|
||||||
|
|
||||||
if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
|
if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||||
@@ -1668,7 +1668,7 @@ void pmodeint(int num, int soft)
|
|||||||
// if (output) pclog("Int gate %04X %i oldpc %04X pc %04X\n",type,intgatesize,oldpc,cpu_state.pc);
|
// if (output) pclog("Int gate %04X %i oldpc %04X pc %04X\n",type,intgatesize,oldpc,cpu_state.pc);
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Int gate not present\n");
|
// pclog("Int gate not present\n");
|
||||||
x86np("Int gate not present\n", (num << 3) | 2);
|
x86np("Int gate not present\n", (num << 3) | 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1681,7 +1681,7 @@ void pmodeint(int num, int soft)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1691,7 +1691,7 @@ void pmodeint(int num, int soft)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins);
|
// pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1699,7 +1699,7 @@ void pmodeint(int num, int soft)
|
|||||||
}
|
}
|
||||||
/* if ((seg&3) < CPL)
|
/* if ((seg&3) < CPL)
|
||||||
{
|
{
|
||||||
pclog("INT to higher level\n");
|
// pclog("INT to higher level\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
@@ -1712,7 +1712,7 @@ void pmodeint(int num, int soft)
|
|||||||
|
|
||||||
if (DPL2 > CPL)
|
if (DPL2 > CPL)
|
||||||
{
|
{
|
||||||
pclog("INT to higher level 2\n");
|
// pclog("INT to higher level 2\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1725,13 +1725,13 @@ void pmodeint(int num, int soft)
|
|||||||
stack_changed=1;
|
stack_changed=1;
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Int gate CS not present\n");
|
// pclog("Int gate CS not present\n");
|
||||||
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((eflags&VM_FLAG) && DPL2)
|
if ((eflags&VM_FLAG) && DPL2)
|
||||||
{
|
{
|
||||||
pclog("V86 calling int gate, DPL != 0\n");
|
// pclog("V86 calling int gate, DPL != 0\n");
|
||||||
x86gpf(NULL,segdat[1]&0xFFFC);
|
x86gpf(NULL,segdat[1]&0xFFFC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1754,7 +1754,7 @@ void pmodeint(int num, int soft)
|
|||||||
cpl_override=0;
|
cpl_override=0;
|
||||||
if (!(newss&~3))
|
if (!(newss&~3))
|
||||||
{
|
{
|
||||||
pclog("Int gate loading null SS\n");
|
// pclog("Int gate loading null SS\n");
|
||||||
x86ss(NULL,newss&~3);
|
x86ss(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1763,7 +1763,7 @@ void pmodeint(int num, int soft)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n",newss,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n",newss,gdt.limit);
|
||||||
x86ss(NULL,newss&~3);
|
x86ss(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1773,7 +1773,7 @@ void pmodeint(int num, int soft)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit);
|
||||||
x86ss(NULL,newss&~3);
|
x86ss(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1786,19 +1786,19 @@ void pmodeint(int num, int soft)
|
|||||||
segdat3[3]=readmemw(0,addr+6); cpl_override=0; if (abrt) return;
|
segdat3[3]=readmemw(0,addr+6); cpl_override=0; if (abrt) return;
|
||||||
if (((newss & 3) != DPL2) || (DPL3 != DPL2))
|
if (((newss & 3) != DPL2) || (DPL3 != DPL2))
|
||||||
{
|
{
|
||||||
pclog("Int gate loading SS with wrong permissions\n");
|
// pclog("Int gate loading SS with wrong permissions\n");
|
||||||
x86ss(NULL,newss&~3);
|
x86ss(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((segdat3[2]&0x1A00)!=0x1200)
|
if ((segdat3[2]&0x1A00)!=0x1200)
|
||||||
{
|
{
|
||||||
pclog("Int gate loading SS wrong type\n");
|
// pclog("Int gate loading SS wrong type\n");
|
||||||
x86ss(NULL,newss&~3);
|
x86ss(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat3[2]&0x8000))
|
if (!(segdat3[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Int gate loading SS not present\n");
|
// pclog("Int gate loading SS not present\n");
|
||||||
x86np("Int gate loading SS not present\n", newss & 0xfffc);
|
x86np("Int gate loading SS not present\n", newss & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1859,20 +1859,20 @@ void pmodeint(int num, int soft)
|
|||||||
}
|
}
|
||||||
else if (DPL2!=CPL)
|
else if (DPL2!=CPL)
|
||||||
{
|
{
|
||||||
pclog("Non-conforming int gate DPL != CPL\n");
|
// pclog("Non-conforming int gate DPL != CPL\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Int gate CS not present\n");
|
// pclog("Int gate CS not present\n");
|
||||||
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((eflags & VM_FLAG) && DPL2<CPL)
|
if ((eflags & VM_FLAG) && DPL2<CPL)
|
||||||
{
|
{
|
||||||
pclog("Int gate V86 mode DPL2<CPL\n");
|
// pclog("Int gate V86 mode DPL2<CPL\n");
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1896,7 +1896,7 @@ void pmodeint(int num, int soft)
|
|||||||
new_cpl = CS & 3;
|
new_cpl = CS & 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("Int gate CS not code segment - %04X %04X %04X %04X\n",segdat2[0],segdat2[1],segdat2[2],segdat2[3]);
|
// pclog("Int gate CS not code segment - %04X %04X %04X %04X\n",segdat2[0],segdat2[1],segdat2[2],segdat2[3]);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1935,7 +1935,7 @@ void pmodeint(int num, int soft)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1945,7 +1945,7 @@ void pmodeint(int num, int soft)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins);
|
// pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1959,7 +1959,7 @@ void pmodeint(int num, int soft)
|
|||||||
cpl_override=0; if (abrt) return;
|
cpl_override=0; if (abrt) return;
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("Int task gate not present\n");
|
// pclog("Int task gate not present\n");
|
||||||
x86np("Int task gate not present\n", segdat[1] & 0xfffc);
|
x86np("Int task gate not present\n", segdat[1] & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1970,7 +1970,7 @@ void pmodeint(int num, int soft)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pclog("Bad int gate type %04X %04X %04X %04X %04X\n",segdat[2]&0x1F00,segdat[0],segdat[1],segdat[2],segdat[3]);
|
// pclog("Bad int gate type %04X %04X %04X %04X %04X\n",segdat[2]&0x1F00,segdat[0],segdat[1],segdat[2],segdat[3]);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1992,7 +1992,7 @@ void pmodeiret(int is32)
|
|||||||
// if (output) pclog("V86 IRET\n");
|
// if (output) pclog("V86 IRET\n");
|
||||||
if (IOPL!=3)
|
if (IOPL!=3)
|
||||||
{
|
{
|
||||||
pclog("V86 IRET! IOPL!=3\n");
|
// pclog("V86 IRET! IOPL!=3\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2034,7 +2034,7 @@ void pmodeiret(int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit);
|
// pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2044,7 +2044,7 @@ void pmodeiret(int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit);
|
// pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit);
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2129,7 +2129,7 @@ void pmodeiret(int is32)
|
|||||||
// pclog("Returned to %04X:%08X %04X %04X %i\n",seg,newpc,flags,tempflags, ins);
|
// pclog("Returned to %04X:%08X %04X %04X %i\n",seg,newpc,flags,tempflags, ins);
|
||||||
if (!(seg&~3))
|
if (!(seg&~3))
|
||||||
{
|
{
|
||||||
pclog("IRET CS=0\n");
|
// pclog("IRET CS=0\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
@@ -2143,7 +2143,7 @@ void pmodeiret(int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
@@ -2154,7 +2154,7 @@ void pmodeiret(int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
@@ -2163,7 +2163,7 @@ void pmodeiret(int is32)
|
|||||||
}
|
}
|
||||||
if ((seg&3) < CPL)
|
if ((seg&3) < CPL)
|
||||||
{
|
{
|
||||||
pclog("IRET to lower level\n");
|
// pclog("IRET to lower level\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
@@ -2180,7 +2180,7 @@ void pmodeiret(int is32)
|
|||||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/
|
||||||
if ((seg&3) != DPL)
|
if ((seg&3) != DPL)
|
||||||
{
|
{
|
||||||
pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]);
|
// pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
@@ -2191,14 +2191,14 @@ void pmodeiret(int is32)
|
|||||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming code*/
|
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming code*/
|
||||||
if ((seg&3) < DPL)
|
if ((seg&3) < DPL)
|
||||||
{
|
{
|
||||||
pclog("IRET C DPL\n");
|
// pclog("IRET C DPL\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("IRET CS != code seg\n");
|
// pclog("IRET CS != code seg\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,seg&~3);
|
x86gpf(NULL,seg&~3);
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
@@ -2207,7 +2207,7 @@ void pmodeiret(int is32)
|
|||||||
}
|
}
|
||||||
if (!(segdat[2]&0x8000))
|
if (!(segdat[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("IRET CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]);
|
// pclog("IRET CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86np("IRET CS not present\n", seg & 0xfffc);
|
x86np("IRET CS not present\n", seg & 0xfffc);
|
||||||
return;
|
return;
|
||||||
@@ -2248,7 +2248,7 @@ void pmodeiret(int is32)
|
|||||||
|
|
||||||
if (!(newss&~3))
|
if (!(newss&~3))
|
||||||
{
|
{
|
||||||
pclog("IRET loading null SS\n");
|
// pclog("IRET loading null SS\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -2258,7 +2258,7 @@ void pmodeiret(int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n",newss,gdt.limit);
|
// pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n",newss,gdt.limit);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -2269,7 +2269,7 @@ void pmodeiret(int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X PMODEIRET\n",newss,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X PMODEIRET\n",newss,gdt.limit);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
@@ -2285,7 +2285,7 @@ void pmodeiret(int is32)
|
|||||||
// if (((newss & 3) != DPL) || (DPL2 != DPL))
|
// if (((newss & 3) != DPL) || (DPL2 != DPL))
|
||||||
if ((newss & 3) != (seg & 3))
|
if ((newss & 3) != (seg & 3))
|
||||||
{
|
{
|
||||||
pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg);
|
// pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
// dumpregs();
|
// dumpregs();
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
@@ -2294,21 +2294,21 @@ void pmodeiret(int is32)
|
|||||||
}
|
}
|
||||||
if ((segdat2[2]&0x1A00)!=0x1200)
|
if ((segdat2[2]&0x1A00)!=0x1200)
|
||||||
{
|
{
|
||||||
pclog("IRET loading SS wrong type\n");
|
// pclog("IRET loading SS wrong type\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DPL2 != (seg & 3))
|
if (DPL2 != (seg & 3))
|
||||||
{
|
{
|
||||||
pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg);
|
// pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg);
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86gpf(NULL,newss&~3);
|
x86gpf(NULL,newss&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("IRET loading SS not present\n");
|
// pclog("IRET loading SS not present\n");
|
||||||
ESP = oldsp;
|
ESP = oldsp;
|
||||||
x86np("IRET loading SS not present\n", newss & 0xfffc);
|
x86np("IRET loading SS not present\n", newss & 0xfffc);
|
||||||
return;
|
return;
|
||||||
@@ -2483,14 +2483,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
|
|
||||||
if (eflags&VM_FLAG)
|
if (eflags&VM_FLAG)
|
||||||
{
|
{
|
||||||
pclog("Task switch V86!\n");
|
// pclog("Task switch V86!\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(new_cs&~3))
|
if (!(new_cs&~3))
|
||||||
{
|
{
|
||||||
pclog("TS loading null CS\n");
|
// pclog("TS loading null CS\n");
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2499,7 +2499,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=ldt.limit)
|
if (addr>=ldt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
// pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2509,7 +2509,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
{
|
{
|
||||||
if (addr>=gdt.limit)
|
if (addr>=gdt.limit)
|
||||||
{
|
{
|
||||||
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
// pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2521,7 +2521,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
segdat2[3]=readmemw(0,addr+6);
|
segdat2[3]=readmemw(0,addr+6);
|
||||||
if (!(segdat2[2]&0x8000))
|
if (!(segdat2[2]&0x8000))
|
||||||
{
|
{
|
||||||
pclog("TS loading CS not present\n");
|
// pclog("TS loading CS not present\n");
|
||||||
x86np("TS loading CS not present\n", new_cs & 0xfffc);
|
x86np("TS loading CS not present\n", new_cs & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2530,7 +2530,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
||||||
if ((new_cs&3) != DPL2)
|
if ((new_cs&3) != DPL2)
|
||||||
{
|
{
|
||||||
pclog("TS load CS non-conforming RPL != DPL");
|
// pclog("TS load CS non-conforming RPL != DPL");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86gpf(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2538,13 +2538,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||||
if ((new_cs&3) < DPL2)
|
if ((new_cs&3) < DPL2)
|
||||||
{
|
{
|
||||||
pclog("TS load CS non-conforming RPL < DPL");
|
// pclog("TS load CS non-conforming RPL < DPL");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86gpf(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pclog("TS load CS not code segment\n");
|
// pclog("TS load CS not code segment\n");
|
||||||
x86gpf(NULL,new_cs&~3);
|
x86gpf(NULL,new_cs&~3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2579,7 +2579,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pclog("16-bit TSS\n");
|
// pclog("16-bit TSS\n");
|
||||||
resetx86();
|
resetx86();
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user