mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
Rewrote the recompiler interrupt checking in assembly (and removed it for the new dynamic compiler because the requires uops are not present), brings performance back up, and also did a number of CPU-related clean-ups (mostly removal of dead variables and associated code).
This commit is contained in:
@@ -308,13 +308,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
extern int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
extern int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
extern int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
extern int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
|
||||
extern void (*codegen_timing_start)();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
enum
|
||||
{
|
||||
ACCREG_ins = 0,
|
||||
ACCREG_cycles = 1,
|
||||
ACCREG_cycles = 0,
|
||||
|
||||
ACCREG_COUNT
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ static struct
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_ins] = {0, (uintptr_t) &(ins)},
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)},
|
||||
};
|
||||
|
||||
@@ -22,37 +21,42 @@ void codegen_accumulate(int acc_reg, int delta)
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong(-delta);
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong(-delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
{
|
||||
if (acc_regs[c].count)
|
||||
{
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) acc_regs[c].dest_reg);
|
||||
addlong(acc_regs[c].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
addbyte(0x81); /*ADD $acc_regs[0].count,acc_regs[0].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) acc_regs[0].dest_reg);
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[c].count = 0;
|
||||
}
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
acc_regs[c].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ static struct
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_ins] = {0, (uintptr_t) &(ins)},
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)}
|
||||
};
|
||||
|
||||
@@ -22,35 +21,38 @@ void codegen_accumulate(int acc_reg, int delta)
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0d);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
{
|
||||
if (acc_regs[c].count)
|
||||
{
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) acc_regs[c].dest_reg);
|
||||
addlong(acc_regs[c].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
addbyte(0x81); /*ADD $acc_regs[0].count,acc_regs[0].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) acc_regs[0].dest_reg);
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[c].count = 0;
|
||||
}
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
acc_regs[c].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
CLEAR_BITS((uintptr_t)&pic_pending, 0xffffffff);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
||||
@@ -49,11 +49,6 @@ int block_current = 0;
|
||||
static int block_num;
|
||||
int block_pos;
|
||||
|
||||
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
uint32_t codegen_endpc;
|
||||
|
||||
int codegen_block_cycles;
|
||||
@@ -224,7 +219,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next)
|
||||
fatal("Broken 1\n");
|
||||
@@ -238,7 +232,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask2)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next_2)
|
||||
fatal("Broken 2\n");
|
||||
@@ -260,7 +253,6 @@ void codegen_block_init(uint32_t phys_addr)
|
||||
if (block->valid != 0)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_reuse++;
|
||||
}
|
||||
block_num = HASH(phys_addr);
|
||||
codeblock_hash[block_num] = &codeblock[block_current];
|
||||
@@ -393,7 +385,6 @@ void codegen_block_remove()
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
||||
delete_block(block);
|
||||
cpu_recomp_removed++;
|
||||
|
||||
recomp_page = -1;
|
||||
}
|
||||
@@ -1049,7 +1040,6 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
generate_call:
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||
|
||||
codegen_accumulate(ACCREG_ins, 1);
|
||||
codegen_accumulate(ACCREG_cycles, -codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
|
||||
@@ -1096,10 +1086,11 @@ generate_call:
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
|
||||
/* Check for interrupts. */
|
||||
call(block, (uintptr_t)int_check);
|
||||
|
||||
addbyte(0x85); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0xf6); /* test byte ptr[&pic_pending],1 */
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
addbyte(0x01);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4]));
|
||||
|
||||
@@ -1175,13 +1166,11 @@ generate_call:
|
||||
|
||||
block->ins++;
|
||||
|
||||
addbyte(0x85); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4]));
|
||||
|
||||
/* Check for interrupts. */
|
||||
call(block, (uintptr_t)int_check);
|
||||
addbyte(0x0a); /* or al,byte ptr[&pic_pending] */
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
|
||||
addbyte(0x85); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
#include "x86_flags.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
/*ex*/
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/pic.h>
|
||||
|
||||
#include "386_common.h"
|
||||
|
||||
@@ -88,11 +91,6 @@ int block_current = 0;
|
||||
static int block_num;
|
||||
int block_pos;
|
||||
|
||||
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
uint32_t codegen_endpc;
|
||||
|
||||
int codegen_block_cycles;
|
||||
@@ -1367,7 +1365,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next)
|
||||
fatal("Broken 1\n");
|
||||
@@ -1381,7 +1378,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask2)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next_2)
|
||||
fatal("Broken 2\n");
|
||||
@@ -1403,7 +1399,6 @@ void codegen_block_init(uint32_t phys_addr)
|
||||
if (block->valid != 0)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_reuse++;
|
||||
}
|
||||
block_num = HASH(phys_addr);
|
||||
codeblock_hash[block_num] = &codeblock[block_current];
|
||||
@@ -1512,7 +1507,6 @@ void codegen_block_remove()
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
||||
delete_block(block);
|
||||
cpu_recomp_removed++;
|
||||
|
||||
recomp_page = -1;
|
||||
}
|
||||
@@ -2016,7 +2010,6 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
generate_call:
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||
|
||||
codegen_accumulate(ACCREG_ins, 1);
|
||||
codegen_accumulate(ACCREG_cycles, -codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
|
||||
@@ -2063,11 +2056,10 @@ generate_call:
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
|
||||
/* Check for interrupts. */
|
||||
addbyte(0xE8); /*CALL*/
|
||||
addlong(((uint8_t *)int_check - (uint8_t *)(&block->data[block_pos + 4])));
|
||||
|
||||
addbyte(0x09); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0xf6); /* test byte ptr[&pic_pending],1 */
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
addbyte(0x01);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4]));
|
||||
|
||||
@@ -2154,14 +2146,10 @@ generate_call:
|
||||
|
||||
block->ins++;
|
||||
|
||||
addbyte(0x09); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4]));
|
||||
|
||||
/* Check for interrupts. */
|
||||
addbyte(0xE8); /*CALL*/
|
||||
addlong(((uint8_t *)int_check - (uint8_t *)(&block->data[block_pos + 4])));
|
||||
addbyte(0x0a); /* or al,byte ptr[&pic_pending] */
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
|
||||
addbyte(0x09); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
|
||||
@@ -918,11 +918,9 @@ void loadcscall(uint16_t seg)
|
||||
int type;
|
||||
uint16_t tempw;
|
||||
|
||||
int csout = output;
|
||||
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
|
||||
x86seg_log("Protected mode CS load! %04X\n", seg);
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf("loadcscall(): Protected mode selector is zero",0);
|
||||
@@ -956,7 +954,7 @@ void loadcscall(uint16_t seg)
|
||||
newpc=segdat[0];
|
||||
if (type&0x800) newpc|=segdat[3]<<16;
|
||||
|
||||
if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
|
||||
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*/
|
||||
@@ -1001,14 +999,16 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
if (csout) x86seg_log("Complete\n");
|
||||
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
cycles -= timing_call_pm;
|
||||
}
|
||||
else
|
||||
{
|
||||
type=segdat[2]&0xF00;
|
||||
if (csout) x86seg_log("Type %03X\n",type);
|
||||
x86seg_log("Type %03X\n",type);
|
||||
switch (type)
|
||||
{
|
||||
case 0x400: /*Call gate*/
|
||||
|
||||
@@ -599,7 +599,6 @@ generate_call:
|
||||
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||
|
||||
codegen_accumulate(ir, ACCREG_ins, 1);
|
||||
codegen_accumulate(ir, ACCREG_cycles, -codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
|
||||
@@ -696,9 +695,6 @@ generate_call:
|
||||
|
||||
block->ins++;
|
||||
|
||||
/* Check for interrupts. */
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, int_check);
|
||||
|
||||
if (block->ins >= MAX_INSTRUCTION_COUNT)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
@@ -759,8 +755,6 @@ generate_call:
|
||||
uop_MOV_IMM(ir, IREG_ssegs, op_ssegs);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat);
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, op);
|
||||
/* Check for interrupts. */
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, int_check);
|
||||
codegen_mark_code_present(block, cs+cpu_state.pc, 8);
|
||||
|
||||
last_op_32 = op_32;
|
||||
|
||||
@@ -341,15 +341,8 @@ void codegen_delete_random_block(int required_mem_block);
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
extern int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
extern int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
extern int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
extern int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
extern int cpu_reps, cpu_reps_latched;
|
||||
extern int cpu_notreps, cpu_notreps_latched;
|
||||
extern int cpu_reps;
|
||||
extern int cpu_notreps;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ static struct
|
||||
int dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_ins] = {0, IREG_ins},
|
||||
[ACCREG_cycles] = {0, IREG_cycles},
|
||||
[ACCREG_cycles] = {0, IREG_cycles}
|
||||
};
|
||||
|
||||
void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
|
||||
@@ -28,23 +27,14 @@ void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
|
||||
|
||||
void codegen_accumulate_flush(ir_data_t *ir)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
{
|
||||
if (acc_regs[c].count)
|
||||
{
|
||||
uop_ADD_IMM(ir, acc_regs[c].dest_reg, acc_regs[c].dest_reg, acc_regs[c].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[c].count = 0;
|
||||
}
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
acc_regs[c].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -37,11 +37,6 @@ int block_current = 0;
|
||||
static int block_num;
|
||||
int block_pos;
|
||||
|
||||
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
uint32_t codegen_endpc;
|
||||
|
||||
int codegen_block_cycles;
|
||||
@@ -479,7 +474,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (*block->dirty_mask & block->page_mask)
|
||||
{
|
||||
invalidate_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block_nr == next_block)
|
||||
fatal("Broken 1\n");
|
||||
@@ -496,7 +490,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (*block->dirty_mask2 & block->page_mask2)
|
||||
{
|
||||
invalidate_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block_nr == next_block)
|
||||
fatal("Broken 2\n");
|
||||
@@ -626,7 +619,6 @@ void codegen_block_remove()
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
||||
delete_block(block);
|
||||
cpu_recomp_removed++;
|
||||
|
||||
recomp_page = -1;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ struct
|
||||
|
||||
[IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT},
|
||||
|
||||
[IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER, REG_PERMANENT},
|
||||
[IREG_acycs] = {REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT},
|
||||
[IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT},
|
||||
|
||||
[IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT},
|
||||
@@ -180,8 +180,6 @@ struct
|
||||
|
||||
[IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE},
|
||||
[IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE},
|
||||
|
||||
[IREG_acycs] = {REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT}
|
||||
};
|
||||
|
||||
void codegen_reg_mark_as_required()
|
||||
|
||||
@@ -41,7 +41,7 @@ enum
|
||||
|
||||
IREG_rm_mod_reg = 18,
|
||||
|
||||
IREG_ins = 19,
|
||||
IREG_acycs = 19,
|
||||
IREG_cycles = 20,
|
||||
|
||||
IREG_CS_base = 21,
|
||||
@@ -133,9 +133,7 @@ enum
|
||||
IREG_GS_limit_high = 86,
|
||||
IREG_SS_limit_high = 87,
|
||||
|
||||
IREG_acycs = 88,
|
||||
|
||||
IREG_COUNT = 89,
|
||||
IREG_COUNT = 88,
|
||||
|
||||
IREG_INVALID = 255,
|
||||
|
||||
|
||||
@@ -908,11 +908,9 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
int type;
|
||||
uint16_t tempw;
|
||||
|
||||
int csout = output;
|
||||
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
|
||||
x86seg_log("Protected mode CS load! %04X\n", seg);
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
@@ -946,7 +944,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
newpc=segdat[0];
|
||||
if (type&0x800) newpc|=segdat[3]<<16;
|
||||
|
||||
if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
|
||||
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*/
|
||||
@@ -992,13 +990,15 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
oldcpl = CPL;
|
||||
if (csout) x86seg_log("Complete\n");
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
cycles -= timing_call_pm;
|
||||
}
|
||||
else
|
||||
{
|
||||
type=segdat[2]&0xF00;
|
||||
if (csout) x86seg_log("Type %03X\n",type);
|
||||
x86seg_log("Type %03X\n",type);
|
||||
switch (type)
|
||||
{
|
||||
case 0x400: /*Call gate*/
|
||||
|
||||
@@ -334,8 +334,6 @@ exec386(int cycs)
|
||||
}
|
||||
}
|
||||
|
||||
ins++;
|
||||
|
||||
if (timetolive) {
|
||||
timetolive--;
|
||||
if (!timetolive)
|
||||
|
||||
@@ -47,8 +47,6 @@ int nmi_enable = 1;
|
||||
|
||||
int cpl_override=0;
|
||||
|
||||
int fpucount=0;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t cpu_cur_status = 0;
|
||||
#else
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
|
||||
|
||||
int inrecomp = 0, cpu_block_end = 0;
|
||||
int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
@@ -127,7 +125,6 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
@@ -168,7 +165,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
|
||||
@@ -278,7 +274,9 @@ static uint64_t tsc_old = 0;
|
||||
|
||||
int acycs = 0;
|
||||
|
||||
void update_tsc(void)
|
||||
|
||||
void
|
||||
update_tsc(void)
|
||||
{
|
||||
int cycdiff;
|
||||
uint64_t delta;
|
||||
@@ -299,27 +297,10 @@ void update_tsc(void)
|
||||
|
||||
if (cycdiff > 0) {
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
timer_process_inline();
|
||||
}
|
||||
}
|
||||
|
||||
int int_check(void)
|
||||
{
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (trap)
|
||||
return 1;
|
||||
else if (smi_line)
|
||||
return 1;
|
||||
else if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void exec386_dynarec(int cycs)
|
||||
{
|
||||
int vector;
|
||||
@@ -406,8 +387,6 @@ void exec386_dynarec(int cycs)
|
||||
CPU_BLOCK_END();
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -561,7 +540,6 @@ void exec386_dynarec(int cycs)
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
#endif
|
||||
cpu_recomp_blocks++;
|
||||
}
|
||||
else if (valid_block && !cpu_state.abrt)
|
||||
{
|
||||
@@ -574,8 +552,6 @@ void exec386_dynarec(int cycs)
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
cpu_new_blocks++;
|
||||
|
||||
codegen_block_start_recompile(block);
|
||||
codegen_in_recompile = 1;
|
||||
@@ -644,7 +620,6 @@ void exec386_dynarec(int cycs)
|
||||
CPU_BLOCK_END();
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
CPU_BLOCK_END();
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
@@ -734,8 +709,6 @@ void exec386_dynarec(int cycs)
|
||||
CPU_BLOCK_END();
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
@@ -862,7 +835,7 @@ void exec386_dynarec(int cycs)
|
||||
|
||||
if (cycdiff > 0) {
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
timer_process_inline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
@@ -53,7 +52,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat);
|
||||
|
||||
@@ -58,13 +58,11 @@ static __inline void PUSH_W(uint16_t val)
|
||||
{
|
||||
writememw(ss, ESP - 2, val); if (cpu_state.abrt) return;
|
||||
ESP -= 2;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return;
|
||||
SP -= 2;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,13 +72,11 @@ static __inline void PUSH_L(uint32_t val)
|
||||
{
|
||||
writememl(ss, ESP - 4, val); if (cpu_state.abrt) return;
|
||||
ESP -= 4;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return;
|
||||
SP -= 4;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,13 +87,11 @@ static __inline uint16_t POP_W()
|
||||
{
|
||||
ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 2;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmemw(ss, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 2;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -109,13 +103,11 @@ static __inline uint32_t POP_L()
|
||||
{
|
||||
ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 4;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmeml(ss, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 4;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -127,13 +119,11 @@ static __inline uint16_t POP_W_seg(uint32_t seg)
|
||||
{
|
||||
ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 2;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmemw(seg, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 2;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -145,13 +135,11 @@ static __inline uint32_t POP_L_seg(uint32_t seg)
|
||||
{
|
||||
ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 4;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmeml(seg, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 4;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int cpu_type;
|
||||
const FPU *fpus;
|
||||
const FPU *fpus;
|
||||
int rspeed;
|
||||
double multi;
|
||||
uint32_t edx_reset;
|
||||
@@ -210,14 +210,11 @@ typedef union {
|
||||
} x86reg;
|
||||
|
||||
typedef struct {
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
uint8_t access;
|
||||
uint8_t ar_high;
|
||||
uint8_t access, ar_high;
|
||||
int8_t checked; /*Non-zero if selector is known to be valid*/
|
||||
uint16_t seg;
|
||||
uint32_t limit_low,
|
||||
limit_high;
|
||||
int checked; /*Non-zero if selector is known to be valid*/
|
||||
uint32_t base, limit,
|
||||
limit_low, limit_high;
|
||||
} x86seg;
|
||||
|
||||
typedef union {
|
||||
@@ -250,19 +247,24 @@ typedef struct {
|
||||
|
||||
uint8_t tag[8];
|
||||
|
||||
int8_t ssegs, ismmx,
|
||||
abrt, pad;
|
||||
|
||||
uint16_t npxs, npxc, flags, eflags,
|
||||
old_npxc, new_npxc;
|
||||
|
||||
uint16_t MM_w4[8];
|
||||
|
||||
int _cycles,
|
||||
flags_op, TOP;
|
||||
|
||||
uint32_t flags_res,
|
||||
flags_op1, flags_op2,
|
||||
pc, oldpc, eaaddr, op32;
|
||||
|
||||
cr0_t CR0;
|
||||
|
||||
x86seg *ea_seg;
|
||||
uint32_t eaaddr;
|
||||
|
||||
int flags_op;
|
||||
uint32_t flags_res;
|
||||
uint32_t flags_op1,
|
||||
flags_op2;
|
||||
|
||||
uint32_t pc;
|
||||
uint32_t oldpc;
|
||||
uint32_t op32;
|
||||
|
||||
int TOP;
|
||||
|
||||
union {
|
||||
struct {
|
||||
@@ -273,26 +275,10 @@ typedef struct {
|
||||
int32_t rm_mod_reg_data;
|
||||
} rm_data;
|
||||
|
||||
int8_t ssegs;
|
||||
int8_t ismmx;
|
||||
int8_t abrt;
|
||||
|
||||
int _cycles;
|
||||
int cpu_recomp_ins;
|
||||
|
||||
uint16_t npxs,
|
||||
npxc;
|
||||
|
||||
double ST[8];
|
||||
|
||||
uint16_t MM_w4[8];
|
||||
|
||||
MMX_REG MM[8];
|
||||
|
||||
uint16_t old_npxc,
|
||||
new_npxc;
|
||||
uint32_t last_ea;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint32_t old_fp_control, new_fp_control;
|
||||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
@@ -303,16 +289,8 @@ typedef struct {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
x86seg seg_cs,
|
||||
seg_ds,
|
||||
seg_es,
|
||||
seg_ss,
|
||||
seg_fs,
|
||||
seg_gs;
|
||||
|
||||
uint16_t flags, eflags;
|
||||
|
||||
cr0_t CR0;
|
||||
x86seg seg_cs, seg_ds, seg_es, seg_ss,
|
||||
seg_fs, seg_gs;
|
||||
} cpu_state_t;
|
||||
|
||||
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
|
||||
@@ -345,7 +323,7 @@ typedef struct {
|
||||
# endif
|
||||
#endif
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128)
|
||||
COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128)
|
||||
|
||||
#define cpu_state_offset(MEMBER) ((uint8_t)((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128))
|
||||
|
||||
@@ -425,19 +403,14 @@ extern uint32_t cpu_cur_status;
|
||||
extern uint64_t cpu_CR4_mask;
|
||||
extern uint64_t tsc;
|
||||
extern msr_t msr;
|
||||
extern cpu_state_t cpu_state;
|
||||
extern cpu_state_t cpu_state;
|
||||
extern uint8_t opcode;
|
||||
extern int insc;
|
||||
extern int fpucount;
|
||||
extern float mips,flops;
|
||||
extern int clockrate;
|
||||
extern int cgate16;
|
||||
extern int cpl_override;
|
||||
extern int CPUID;
|
||||
extern uint64_t xt_cpu_multi;
|
||||
extern uint64_t xt_cpu_multi;
|
||||
extern int isa_cycles;
|
||||
extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
|
||||
extern int ins,output;
|
||||
extern uint32_t pccache;
|
||||
extern uint8_t *pccache2;
|
||||
|
||||
@@ -503,7 +476,7 @@ extern int timing_misaligned;
|
||||
extern int in_sys, unmask_a20_in_smm;
|
||||
extern uint32_t old_rammask;
|
||||
|
||||
extern int acycs;
|
||||
extern int acycs, pic_pending;
|
||||
|
||||
extern uint16_t cpu_fast_off_count, cpu_fast_off_val;
|
||||
extern uint32_t cpu_fast_off_flags;
|
||||
@@ -601,6 +574,4 @@ extern const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int
|
||||
extern const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c);
|
||||
extern int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c);
|
||||
|
||||
extern int int_check();
|
||||
|
||||
#endif /*EMU_CPU_H*/
|
||||
|
||||
@@ -11,7 +11,7 @@ extern int x86_was_reset, trap;
|
||||
extern int codegen_flat_ss, codegen_flat_ds;
|
||||
extern int timetolive, keyboardtimer, trap;
|
||||
extern int optype, stack32;
|
||||
extern int oldcpl, cgate32, cpl_override, fpucount;
|
||||
extern int oldcpl, cgate32, cpl_override;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven, inttype;
|
||||
|
||||
|
||||
@@ -201,12 +201,10 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
|
||||
else { DEST_REG++; SRC_REG++; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
@@ -240,12 +238,10 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
|
||||
else { DEST_REG += 2; SRC_REG += 2; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
@@ -279,12 +275,10 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
|
||||
else { DEST_REG += 4; SRC_REG += 4; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
@@ -313,7 +307,6 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -343,7 +336,6 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -373,7 +365,6 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -404,7 +395,6 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -434,7 +424,6 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -464,7 +453,6 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -597,11 +585,9 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
@@ -631,11 +617,9 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
@@ -665,11 +649,9 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
|
||||
@@ -431,7 +431,6 @@ typedef union
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define FP_ENTER() { \
|
||||
fpucount++; \
|
||||
}
|
||||
#else
|
||||
#define FP_ENTER() do \
|
||||
@@ -441,7 +440,6 @@ typedef union
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
fpucount++; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2246,8 +2246,8 @@ kbd_read(uint16_t port, void *priv)
|
||||
ret &= ~0x04;
|
||||
}
|
||||
#ifdef USE_DYNAREC
|
||||
flip_flop = (flip_flop + 1) & 3;
|
||||
if (cpu_use_dynarec && (flip_flop == 3))
|
||||
flip_flop = (flip_flop + 1) & 0xf;
|
||||
if (cpu_use_dynarec && (flip_flop == 0xf))
|
||||
update_tsc();
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -1010,7 +1010,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x07: /* Recalibrate */
|
||||
case 0x0f: /* Seek */
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
if (fdc->flags & FDC_FLAG_PCJR)
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
else
|
||||
timer_set_delay_u64(&fdc->timer, 256 * TIMER_USEC);
|
||||
break;
|
||||
default:
|
||||
timer_set_delay_u64(&fdc->timer, 256 * TIMER_USEC);
|
||||
|
||||
@@ -9,7 +9,7 @@ typedef struct PIC {
|
||||
|
||||
|
||||
extern PIC pic, pic2;
|
||||
extern int pic_intpending;
|
||||
extern int pic_intpending, pic_pending;
|
||||
|
||||
|
||||
extern void pic_set_shadow(int sh);
|
||||
|
||||
@@ -225,4 +225,54 @@ extern void timer_advance_ex(pc_timer_t *timer, int start);
|
||||
extern void timer_on(pc_timer_t *timer, double period, int start);
|
||||
extern void timer_on_auto(pc_timer_t *timer, double period);
|
||||
|
||||
extern void timer_remove_head(void);
|
||||
|
||||
|
||||
extern pc_timer_t * timer_head;
|
||||
extern int timer_inited;
|
||||
|
||||
|
||||
__inline void
|
||||
timer_remove_head_inline(void)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
|
||||
if (timer_inited && timer_head) {
|
||||
timer = timer_head;
|
||||
timer_head = timer->next;
|
||||
if (timer_head) {
|
||||
timer_head->prev = NULL;
|
||||
timer->next->prev = NULL;
|
||||
}
|
||||
timer->next = timer->prev = NULL;
|
||||
timer->flags &= ~TIMER_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__inline void
|
||||
timer_process_inline(void)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
|
||||
if (!timer_inited || !timer_head)
|
||||
return;
|
||||
|
||||
while(1) {
|
||||
timer = timer_head;
|
||||
|
||||
if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc))
|
||||
break;
|
||||
|
||||
timer_remove_head_inline();
|
||||
|
||||
if (timer->flags & TIMER_SPLIT)
|
||||
timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */
|
||||
else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */
|
||||
timer->callback(timer->p);
|
||||
}
|
||||
|
||||
timer_target = timer_head->ts.ts32.integer;
|
||||
}
|
||||
|
||||
#endif /*_TIMER_H_*/
|
||||
|
||||
1
src/io.c
1
src/io.c
@@ -26,6 +26,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/m_amstrad.h>
|
||||
|
||||
|
||||
2
src/pc.c
2
src/pc.c
@@ -346,6 +346,8 @@ pc_init(int argc, wchar_t *argv[])
|
||||
plat_getcwd(usr_path, sizeof_w(usr_path)-1);
|
||||
memset(path, 0x00, sizeof(path));
|
||||
|
||||
pclog("sizeof(cpu_state_t) = %i\n", sizeof(cpu_state_t));
|
||||
|
||||
for (c=1; c<argc; c++) {
|
||||
if (argv[c][0] != L'-') break;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ int output;
|
||||
int intclear;
|
||||
int keywaiting = 0;
|
||||
int pic_intpending;
|
||||
int pic_pending;
|
||||
PIC pic, pic2;
|
||||
uint16_t pic_current;
|
||||
|
||||
@@ -82,6 +83,7 @@ pic_updatepending()
|
||||
pic_intpending |= temp_pending;
|
||||
}
|
||||
}
|
||||
pic_pending = !!((cpu_state.flags & I_FLAG) && pic_intpending);
|
||||
pic_log("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2);
|
||||
pic_log(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2));
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ uint32_t timer_target;
|
||||
|
||||
/*Enabled timers are stored in a linked list, with the first timer to expire at
|
||||
the head.*/
|
||||
static pc_timer_t *timer_head = NULL;
|
||||
pc_timer_t *timer_head = NULL;
|
||||
|
||||
/* Are we initialized? */
|
||||
static int timer_inited = 0;
|
||||
int timer_inited = 0;
|
||||
|
||||
|
||||
void
|
||||
@@ -99,7 +99,7 @@ timer_disable(pc_timer_t *timer)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
timer_remove_head(void)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
|
||||
Reference in New Issue
Block a user