mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
i286 - enabling 287 emulation by trapping when needed [Carl]
idectrl - Clears error status on driver initialization [Carl]
This commit is contained in:
parent
6659e57a43
commit
5aa0cf528a
@ -212,8 +212,8 @@ static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
|
||||
UINT32 naddr, oaddr, ldtaddr;
|
||||
int i;
|
||||
logerror("This program uses TSSs, how rare. Expect a crash.\n");
|
||||
if (TBL(ntask)) TRAP(INVALID_TSS,IDXTBL(ntask));
|
||||
if ((naddr = i80286_selector_address(cpustate,ntask)) == -1) TRAP(INVALID_TSS,IDXTBL(ntask));
|
||||
if (TBL(ntask)) throw TRAP(INVALID_TSS,IDXTBL(ntask));
|
||||
if ((naddr = i80286_selector_address(cpustate,ntask)) == -1) throw TRAP(INVALID_TSS,IDXTBL(ntask));
|
||||
oaddr = i80286_selector_address(cpustate,cpustate->tr.sel);
|
||||
ndesc[0] = ReadWord(naddr);
|
||||
ndesc[1] = ReadWord(naddr+2);
|
||||
@ -222,7 +222,7 @@ static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
|
||||
r = RIGHTS(ndesc);
|
||||
if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE)) throw TRAP(GENERAL_PROTECTION_FAULT,IDXTBL(ntask));
|
||||
if (!PRES(r)) throw TRAP(SEG_NOT_PRESENT, IDXTBL(ntask));
|
||||
if (LIMIT(ndesc) < 44) TRAP(INVALID_TSS,IDXTBL(ntask));
|
||||
if (LIMIT(ndesc) < 44) throw TRAP(INVALID_TSS,IDXTBL(ntask));
|
||||
for (i = 0; i < 44; i+=2) ntss[i/2] = ReadWord(BASE(ndesc)+i);
|
||||
|
||||
cpustate->flags = CompressFlags();
|
||||
@ -271,23 +271,28 @@ static void i80286_switch_task(i80286_state *cpustate, UINT16 ntask, int type)
|
||||
cpustate->regs.w[SI] = ntss[TSS_SI];
|
||||
cpustate->regs.w[DI] = ntss[TSS_DI];
|
||||
|
||||
if (TBL(ntss[TSS_LDT])) TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
if ((ldtaddr = i80286_selector_address(cpustate,ntss[TSS_LDT])) == -1) TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
desc[0] = ReadWord(ldtaddr);
|
||||
desc[1] = ReadWord(ldtaddr+2);
|
||||
desc[2] = ReadWord(ldtaddr+4);
|
||||
r = RIGHTS(desc);
|
||||
if (SEGDESC(r) || (GATE(r) != LDTDESC)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
if (!PRES(r)) TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
if (TBL(ntss[TSS_LDT])) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
if (IDXTBL(ntss[TSS_LDT])) {
|
||||
if ((ldtaddr = i80286_selector_address(cpustate,ntss[TSS_LDT])) == -1) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
desc[0] = ReadWord(ldtaddr);
|
||||
desc[1] = ReadWord(ldtaddr+2);
|
||||
desc[2] = ReadWord(ldtaddr+4);
|
||||
r = RIGHTS(desc);
|
||||
if (SEGDESC(r) || (GATE(r) != LDTDESC)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
if (!PRES(r)) throw TRAP(INVALID_TSS,IDXTBL(ntss[TSS_LDT]));
|
||||
cpustate->ldtr.sel=ntss[TSS_LDT];
|
||||
cpustate->ldtr.limit=LIMIT(desc);
|
||||
cpustate->ldtr.base=BASE(desc);
|
||||
cpustate->ldtr.rights=RIGHTS(desc);
|
||||
} else {
|
||||
cpustate->ldtr.sel=0;
|
||||
cpustate->ldtr.limit=0;
|
||||
cpustate->ldtr.base=0;
|
||||
cpustate->ldtr.rights=0;
|
||||
}
|
||||
|
||||
if (type == CALL) cpustate->flags |= 0x4000;
|
||||
cpustate->msw |= 8;
|
||||
|
||||
cpustate->ldtr.sel=ntss[TSS_LDT]; // docs say nothing about whether a null ldt can be in a tss
|
||||
cpustate->ldtr.limit=LIMIT(desc);
|
||||
cpustate->ldtr.base=BASE(desc);
|
||||
cpustate->ldtr.rights=RIGHTS(desc);
|
||||
|
||||
i80286_data_descriptor_full(cpustate, SS, ntss[TSS_SS], RPL(ntss[TSS_CS]), TRAP(INVALID_TSS,IDXTBL(ntss[TSS_SS])));
|
||||
|
||||
cpustate->sregs[CS] = IDXTBL(cpustate->sregs[CS]) | RPL(ntss[TSS_CS]); // fixme
|
||||
@ -823,6 +828,23 @@ static void PREFIX286(_retf)(i8086_state *cpustate)
|
||||
ICOUNT -= timing.ret_far;
|
||||
}
|
||||
|
||||
static void PREFIX286(_escape)(i8086_state *cpustate) /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde */
|
||||
{
|
||||
if ((cpustate->msw&8) || (cpustate->msw&4)) throw TRAP(FPU_UNAVAILABLE,-1);
|
||||
unsigned ModRM = FETCH;
|
||||
ICOUNT -= timing.nop;
|
||||
GetRMByte(ModRM);
|
||||
}
|
||||
|
||||
static void PREFIX286(_escape_7)(i8086_state *cpustate) /* Opcode 0xdf */
|
||||
{
|
||||
if ((cpustate->msw&8) || (cpustate->msw&4)) throw TRAP(FPU_UNAVAILABLE,-1);
|
||||
unsigned ModRM = FETCH;
|
||||
ICOUNT -= timing.nop;
|
||||
GetRMByte(ModRM);
|
||||
if (ModRM == 0xe0) cpustate->regs.w[AX] = 0xffff; // FPU not present
|
||||
}
|
||||
|
||||
static void i80286_check_permission(i8086_state *cpustate, UINT8 check_seg, UINT16 offset, i80286_size size, i80286_operation operation)
|
||||
{
|
||||
int trap = 0;
|
||||
|
@ -5,9 +5,9 @@
|
||||
#define INTO_OVERFLOW 4
|
||||
#define BOUND_OVERRUN 5
|
||||
#define ILLEGAL_INSTRUCTION 6
|
||||
#define CPU_EXT_UNAVAILABLE 7
|
||||
#define FPU_UNAVAILABLE 7
|
||||
#define DOUBLE_FAULT 8
|
||||
#define CPU_EXT_SEG_OVERRUN 9
|
||||
#define FPU_SEG_OVERRUN 9
|
||||
#define INVALID_TSS 10
|
||||
#define SEG_NOT_PRESENT 11
|
||||
#define STACK_FAULT 12
|
||||
@ -22,6 +22,7 @@ static void i80286_code_descriptor(i80286_state *cpustate,UINT16 selector, UINT1
|
||||
static void i80286_data_descriptor(i80286_state *cpustate,int reg, UINT16 selector);
|
||||
static void PREFIX286(_0fpre)(i80286_state *cpustate);
|
||||
static void PREFIX286(_arpl)(i80286_state *cpustate);
|
||||
static void PREFIX286(_escape_7)(i8086_state *cpustate);
|
||||
static void i80286_pop_seg(i80286_state *cpustate,int reg);
|
||||
static void i80286_load_flags(i80286_state *cpustate, UINT16 flags, int cpl);
|
||||
|
||||
|
@ -1971,6 +1971,9 @@ static void PREFIX86(_call_far)(i8086_state *cpustate)
|
||||
|
||||
static void PREFIX86(_wait)(i8086_state *cpustate) /* Opcode 0x9b */
|
||||
{
|
||||
#ifdef I80286
|
||||
if ((cpustate->msw&0x0a) == 0x0a) throw TRAP(FPU_UNAVAILABLE,-1);
|
||||
#endif
|
||||
if (cpustate->test_state)
|
||||
{
|
||||
ICOUNT = 0;
|
||||
@ -2464,12 +2467,14 @@ static void PREFIX86(_xlat)(i8086_state *cpustate) /* Opcode 0xd7 */
|
||||
cpustate->regs.b[AL] = GetMemB(DS, dest);
|
||||
}
|
||||
|
||||
#ifndef I80286
|
||||
static void PREFIX86(_escape)(i8086_state *cpustate) /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
|
||||
{
|
||||
unsigned ModRM = FETCH;
|
||||
ICOUNT -= timing.nop;
|
||||
GetRMByte(ModRM);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PREFIX86(_loopne)(i8086_state *cpustate) /* Opcode 0xe0 */
|
||||
{
|
||||
|
@ -221,14 +221,14 @@ static void (*const PREFIX286(_instruction)[256])(i8086_state *cpustate) =
|
||||
PREFIX86(_aad), /* 0xd5 */
|
||||
PREFIX286(_invalid),
|
||||
PREFIX86(_xlat), /* 0xd7 */
|
||||
PREFIX86(_escape), /* 0xd8 */
|
||||
PREFIX86(_escape), /* 0xd9 */
|
||||
PREFIX86(_escape), /* 0xda */
|
||||
PREFIX86(_escape), /* 0xdb */
|
||||
PREFIX86(_escape), /* 0xdc */
|
||||
PREFIX86(_escape), /* 0xdd */
|
||||
PREFIX86(_escape), /* 0xde */
|
||||
PREFIX86(_escape), /* 0xdf */
|
||||
PREFIX286(_escape), /* 0xd8 */
|
||||
PREFIX286(_escape), /* 0xd9 */
|
||||
PREFIX286(_escape), /* 0xda */
|
||||
PREFIX286(_escape), /* 0xdb */
|
||||
PREFIX286(_escape), /* 0xdc */
|
||||
PREFIX286(_escape), /* 0xdd */
|
||||
PREFIX286(_escape), /* 0xde */
|
||||
PREFIX286(_escape_7), /* 0xdf */
|
||||
PREFIX86(_loopne), /* 0xe0 */
|
||||
PREFIX86(_loope), /* 0xe1 */
|
||||
PREFIX86(_loop), /* 0xe2 */
|
||||
@ -484,14 +484,14 @@ static void (*const PREFIX286(_instruction)[256])(i8086_state *cpustate) =
|
||||
case 0xd5: PREFIX86(_aad)(cpustate); break;\
|
||||
case 0xd6: PREFIX286(_invalid)(cpustate); break;\
|
||||
case 0xd7: PREFIX86(_xlat)(cpustate); break;\
|
||||
case 0xd8: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xd9: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xda: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xdb: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xdc: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xdd: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xde: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xdf: PREFIX86(_escape)(cpustate); break;\
|
||||
case 0xd8: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xd9: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xda: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xdb: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xdc: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xdd: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xde: PREFIX286(_escape)(cpustate); break;\
|
||||
case 0xdf: PREFIX286(_escape_7)(cpustate); break;\
|
||||
case 0xe0: PREFIX86(_loopne)(cpustate); break;\
|
||||
case 0xe1: PREFIX86(_loope)(cpustate); break;\
|
||||
case 0xe2: PREFIX86(_loop)(cpustate); break;\
|
||||
|
@ -1177,6 +1177,8 @@ static void handle_command(ide_state *ide, UINT8 command)
|
||||
|
||||
case IDE_COMMAND_SET_CONFIG:
|
||||
LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", ide->cur_head + 1, ide->sector_count));
|
||||
ide->status &= ~IDE_STATUS_ERROR;
|
||||
ide->error = IDE_ERROR_NONE;
|
||||
|
||||
ide->num_sectors = ide->sector_count;
|
||||
ide->num_heads = ide->cur_head + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user