Merge branch 'master' into pc98x1

This commit is contained in:
TC1995
2024-08-29 20:51:41 +02:00
14 changed files with 215 additions and 77 deletions

View File

@@ -308,8 +308,7 @@ exec386_2386(int32_t cycs)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
cr0 ^= 0x80000000;
flushmmucache();
flushmmucache_pc();
}
if (cpu_end_block_after_ins)

View File

@@ -458,6 +458,7 @@ fastreadw_fetch(uint32_t a)
{
uint16_t ret;
cpu_old_paging = (cpu_flush_pending == 2);
if ((a & 0xFFF) > 0xFFE) {
ret = fastreadb(a);
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1))
@@ -469,6 +470,7 @@ fastreadw_fetch(uint32_t a)
ret = readmemwl_2386(a);
read_type = 4;
}
cpu_old_paging = 0;
return ret;
}
@@ -486,7 +488,9 @@ fastreadl_fetch(uint32_t a)
ret = 0;
else {
read_type = 1;
cpu_old_paging = (cpu_flush_pending == 2);
ret = readmemll_2386(a);
cpu_old_paging = 0;
read_type = 4;
}
@@ -563,35 +567,52 @@ fastreadl_fetch(uint32_t a)
}
#endif
#ifdef OPS_286_386
static __inline uint8_t
getbyte(void)
{
uint8_t ret;
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadb(cs + (cpu_state.pc - 1));
cpu_old_paging = 0;
return ret;
}
static __inline uint16_t
getword(void)
{
uint16_t ret;
cpu_state.pc += 2;
return fastreadw(cs + (cpu_state.pc - 2));
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadw(cs + (cpu_state.pc - 2));
cpu_old_paging = 0;
return ret;
}
static __inline uint32_t
getlong(void)
{
uint32_t ret;
cpu_state.pc += 4;
return fastreadl(cs + (cpu_state.pc - 4));
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadl(cs + (cpu_state.pc - 4));
cpu_old_paging = 0;
return ret;
}
static __inline uint64_t
getquad(void)
{
uint64_t ret;
cpu_state.pc += 8;
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
cpu_old_paging = 0;
return ret;
}
#ifdef OPS_286_386
static __inline uint8_t
geteab(void)
{
@@ -678,6 +699,34 @@ seteaq(uint64_t v)
# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v);
# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v);
#else
static __inline uint8_t
getbyte(void)
{
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
}
static __inline uint16_t
getword(void)
{
cpu_state.pc += 2;
return fastreadw(cs + (cpu_state.pc - 2));
}
static __inline uint32_t
getlong(void)
{
cpu_state.pc += 4;
return fastreadl(cs + (cpu_state.pc - 4));
}
static __inline uint64_t
getquad(void)
{
cpu_state.pc += 8;
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
}
static __inline uint8_t
geteab(void)
{

View File

@@ -937,8 +937,7 @@ exec386(int32_t cycs)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
cr0 ^= 0x80000000;
flushmmucache();
flushmmucache_pc();
}
#ifndef USE_NEW_DYNAREC

View File

@@ -183,6 +183,7 @@ int cpu_waitstates;
int cpu_cache_int_enabled;
int cpu_cache_ext_enabled;
int cpu_flush_pending;
int cpu_old_paging;
int cpu_isa_speed;
int cpu_pci_speed;
int cpu_isa_pci_div;

View File

@@ -618,6 +618,7 @@ extern int cpu_mem_prefetch_cycles;
extern int cpu_rom_prefetch_cycles;
extern int cpu_waitstates;
extern int cpu_flush_pending;
extern int cpu_old_paging;
extern int cpu_cache_int_enabled;
extern int cpu_cache_ext_enabled;
extern int cpu_isa_speed;

View File

@@ -326,6 +326,7 @@ reset_common(int hard)
codegen_reset();
#endif
cpu_flush_pending = 0;
cpu_old_paging = 0;
if (!hard)
flushmmucache();
x86_was_reset = 1;

View File

@@ -189,16 +189,15 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 || cpu_use_dynarec)
flushmmucache();
else
else {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
if (!is_p6 && !cpu_use_dynarec && ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000))
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
@@ -255,16 +254,15 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 || cpu_use_dynarec)
flushmmucache();
else
else {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
if (!is_p6 && !cpu_use_dynarec && ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000))
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))

View File

@@ -182,15 +182,14 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))
@@ -244,15 +243,14 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001)
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000)
cr0 = (cr0 & 0x80000000) | (cpu_state.regs[cpu_rm].l & 0x7fffffff);
else
cr0 = cpu_state.regs[cpu_rm].l;
cr0 = cpu_state.regs[cpu_rm].l;
if (cpu_16bitbus)
cr0 |= 0x10;
if (!(cr0 & 0x80000000))

View File

@@ -431,21 +431,12 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is386 && is32 && (cpu_mod == 3)) {
if (cpu_flush_pending) {
if (is486 || isibm486)
seteaw(cr0 ^ 0x80000000);
else if (is386 && !cpu_16bitbus)
seteaw((cr0 ^ 0x80000000) | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw((cr0 ^ 0x80000000) | 0x7FFFFFF0);
} else {
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
}
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
} else {
if (is486 || isibm486)
seteaw(msw);

View File

@@ -446,6 +446,7 @@ extern void mem_flush_write_page(uint32_t addr, uint32_t virt);
extern void mem_reset_page_blocks(void);
extern void flushmmucache(void);
extern void flushmmucache_pc(void);
extern void flushmmucache_nopc(void);
extern void mem_debug_check_addr(uint32_t addr, int write);

View File

@@ -225,6 +225,19 @@ flushmmucache(void)
#endif
}
void
flushmmucache_pc(void)
{
mmuflush++;
pccache = (uint32_t) 0xffffffff;
pccache2 = (uint8_t *) 0xffffffff;
#ifdef USE_DYNAREC
codegen_flush();
#endif
}
void
flushmmucache_nopc(void)
{

View File

@@ -278,6 +278,7 @@ readmembl_2386(uint32_t addr)
{
mem_mapping_t *map;
uint64_t a;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
@@ -287,7 +288,7 @@ readmembl_2386(uint32_t addr)
high_page = 0;
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_read_2386(addr);
addr64 = (uint32_t) a;
@@ -308,6 +309,7 @@ writemembl_2386(uint32_t addr, uint8_t val)
{
mem_mapping_t *map;
uint64_t a;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
mem_debug_check_addr(addr, 2);
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
@@ -317,7 +319,7 @@ writemembl_2386(uint32_t addr, uint8_t val)
high_page = 0;
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_write_2386(addr);
addr64 = (uint32_t) a;
@@ -336,12 +338,13 @@ uint8_t
readmembl_no_mmut_2386(uint32_t addr, uint32_t a64)
{
mem_mapping_t *map;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1);
mem_logical_addr = addr;
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return 0xff;
@@ -361,12 +364,13 @@ void
writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val)
{
mem_mapping_t *map;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1);
mem_logical_addr = addr;
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return;
@@ -384,6 +388,7 @@ readmemwl_2386(uint32_t addr)
{
mem_mapping_t *map;
uint64_t a;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
addr64a[0] = addr;
addr64a[1] = addr + 1;
@@ -399,7 +404,7 @@ readmemwl_2386(uint32_t addr)
if (!cpu_cyrix_alignment || (addr & 7) == 7)
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
for (uint8_t i = 0; i < 2; i++) {
a = mmutranslate_read_2386(addr + i);
addr64a[i] = (uint32_t) a;
@@ -414,7 +419,7 @@ readmemwl_2386(uint32_t addr)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_read_2386(addr);
addr64a[0] = (uint32_t) a;
@@ -442,6 +447,7 @@ writememwl_2386(uint32_t addr, uint16_t val)
{
mem_mapping_t *map;
uint64_t a;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
addr64a[0] = addr;
addr64a[1] = addr + 1;
@@ -457,7 +463,7 @@ writememwl_2386(uint32_t addr, uint16_t val)
if (!cpu_cyrix_alignment || (addr & 7) == 7)
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
for (uint8_t i = 0; i < 2; i++) {
/* Do not translate a page that has a valid lookup, as that is by definition valid
and the whole purpose of the lookup is to avoid repeat identical translations. */
@@ -479,7 +485,7 @@ writememwl_2386(uint32_t addr, uint16_t val)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_write_2386(addr);
addr64a[0] = (uint32_t) a;
@@ -508,6 +514,7 @@ uint16_t
readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64)
{
mem_mapping_t *map;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2);
@@ -517,7 +524,7 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64)
if (!cpu_cyrix_alignment || (addr & 7) == 7)
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return 0xffff;
}
@@ -527,7 +534,7 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return 0xffff;
@@ -552,6 +559,7 @@ void
writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val)
{
mem_mapping_t *map;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2);
@@ -561,7 +569,7 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val)
if (!cpu_cyrix_alignment || (addr & 7) == 7)
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffe) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return;
}
@@ -572,7 +580,7 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return;
@@ -600,6 +608,7 @@ readmemll_2386(uint32_t addr)
mem_mapping_t *map;
int i;
uint64_t a = 0x0000000000000000ULL;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
for (i = 0; i < 4; i++) {
addr64a[i] = (uint64_t) (addr + i);
@@ -615,7 +624,7 @@ readmemll_2386(uint32_t addr)
if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
for (i = 0; i < 4; i++) {
if (i == 0) {
a = mmutranslate_read_2386(addr + i);
@@ -644,7 +653,7 @@ readmemll_2386(uint32_t addr)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_read_2386(addr);
addr64a[0] = (uint32_t) a;
@@ -674,6 +683,7 @@ writememll_2386(uint32_t addr, uint32_t val)
mem_mapping_t *map;
int i;
uint64_t a = 0x0000000000000000ULL;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
for (i = 0; i < 4; i++) {
addr64a[i] = (uint64_t) (addr + i);
@@ -689,7 +699,7 @@ writememll_2386(uint32_t addr, uint32_t val)
if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
for (i = 0; i < 4; i++) {
/* Do not translate a page that has a valid lookup, as that is by definition valid
and the whole purpose of the lookup is to avoid repeat identical translations. */
@@ -723,7 +733,7 @@ writememll_2386(uint32_t addr, uint32_t val)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_write_2386(addr);
addr64a[0] = (uint32_t) a;
@@ -758,6 +768,7 @@ uint32_t
readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64)
{
mem_mapping_t *map;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4);
@@ -767,7 +778,7 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64)
if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return 0xffffffff;
}
@@ -777,7 +788,7 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return 0xffffffff;
@@ -804,6 +815,7 @@ void
writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val)
{
mem_mapping_t *map;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4);
@@ -813,7 +825,7 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val)
if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4))
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xffc) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return;
}
@@ -824,7 +836,7 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
if (cpu_state.abrt || high_page)
return;
@@ -858,6 +870,7 @@ readmemql_2386(uint32_t addr)
mem_mapping_t *map;
int i;
uint64_t a = 0x0000000000000000ULL;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
for (i = 0; i < 8; i++) {
addr64a[i] = (uint64_t) (addr + i);
@@ -872,7 +885,7 @@ readmemql_2386(uint32_t addr)
if (addr & 7) {
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xff8) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
for (i = 0; i < 8; i++) {
if (i == 0) {
a = mmutranslate_read_2386(addr + i);
@@ -901,7 +914,7 @@ readmemql_2386(uint32_t addr)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
a = mmutranslate_read_2386(addr);
addr64a[0] = (uint32_t) a;
@@ -924,6 +937,7 @@ writememql_2386(uint32_t addr, uint64_t val)
mem_mapping_t *map;
int i;
uint64_t a = 0x0000000000000000ULL;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
for (i = 0; i < 8; i++) {
addr64a[i] = (uint64_t) (addr + i);
@@ -938,7 +952,7 @@ writememql_2386(uint32_t addr, uint64_t val)
if (addr & 7) {
cycles -= timing_misaligned;
if ((addr & 0xfff) > 0xff8) {
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
for (i = 0; i < 8; i++) {
/* Do not translate a page that has a valid lookup, as that is by definition valid
and the whole purpose of the lookup is to avoid repeat identical translations. */
@@ -972,7 +986,7 @@ writememql_2386(uint32_t addr, uint64_t val)
}
}
if (cr0 >> 31) {
if (temp_cr0 >> 31) {
addr64a[0] = mmutranslate_write_2386(addr);
if (addr64a[0] > 0xffffffffULL)
return;
@@ -1013,13 +1027,14 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write)
int i;
uint32_t last_addr = addr + (num - 1);
uint64_t a = 0x0000000000000000ULL;
uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0;
mem_debug_check_addr(addr, write ? 2 : read_type);
for (i = 0; i < num; i++)
a64[i] = (uint64_t) addr;
if (!(cr0 >> 31))
if (!(temp_cr0 >> 31))
return;
for (i = 0; i < num; i++) {

View File

@@ -1546,7 +1546,7 @@ scsi_cdrom_insert(void *priv)
if (!dev)
return;
dev->unit_attention = 1;
dev->unit_attention = 0x11;
/* Turn off the medium changed status. */
dev->drv->cd_status &= ~CD_STATUS_MEDIUM_CHANGED;
scsi_cdrom_log("CD-ROM %i: Media insert\n", dev->id);
@@ -1598,6 +1598,13 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb)
ready = (dev->drv->cd_status != CD_STATUS_EMPTY) || (ext_medium_changed == -1);
/* Transition, pretend we're not ready for one check so that
Windows XP can recognize a medium change. */
if ((dev->unit_attention & 0xf0) == 0x10) {
ready = 0;
goto skip_ua_check;
}
skip_ready_check:
/* If the drive is not ready, there is no reason to keep the
UNIT ATTENTION condition present, as we only use it to mark
@@ -1624,6 +1631,7 @@ skip_ready_check:
}
}
skip_ua_check:
/* Unless the command is REQUEST SENSE, clear the sense. This will *NOT*
the UNIT ATTENTION condition if it's set. */
if (cdb[0] != GPCMD_REQUEST_SENSE)
@@ -1711,7 +1719,8 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt
buffer[2] = SENSE_ILLEGAL_REQUEST;
buffer[12] = ASC_AUDIO_PLAY_OPERATION;
buffer[13] = (dev->drv->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
} else if (dev->unit_attention && (scsi_cdrom_sense_key == 0)) {
} else if (dev->unit_attention && ((dev->unit_attention & 0xf0) != 0x10) &&
((scsi_cdrom_sense_key == 0) || (scsi_cdrom_sense_key == 2))) {
buffer[2] = SENSE_UNIT_ATTENTION;
buffer[12] = ASC_MEDIUM_MAY_HAVE_CHANGED;
buffer[13] = 0;
@@ -1719,6 +1728,9 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt
scsi_cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]);
if ((dev->unit_attention & 0xf0) == 0x10)
dev->unit_attention &= 0x0f;
if (buffer[2] == SENSE_UNIT_ATTENTION) {
/* If the last remaining sense is unit attention, clear
that condition. */
@@ -2338,7 +2350,9 @@ begin:
max_len = (cdb[7] << 8) | cdb[8];
/* only feature 0 is supported */
if ((cdb[2] != 0) || (cdb[3] > 2)) {
if ((feature > 3) && (feature != 0x010) &&
(feature != 0x1d) && (feature != 0x01e) &&
(feature != 0x01f) && (feature != 0x103)) {
scsi_cdrom_invalid_field(dev);
scsi_cdrom_buf_free(dev);
return;
@@ -2413,6 +2427,65 @@ begin:
alloc_length += 8;
b += 8;
}
if ((feature == 3) || ((cdb[1] & 3) < 2)) {
b[1] = 2;
b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */
b[3] = 4;
b[4] = 0x1d;
alloc_length += 8;
b += 8;
}
if ((feature == 0x10) || ((cdb[1] & 3) < 2)) {
b[1] = 0x10;
b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */
b[3] = 8;
b[6] = 8;
b[9] = 0x10;
alloc_length += 12;
b += 12;
}
if ((feature == 0x1d) || ((cdb[1] & 3) < 2)) {
b[1] = 0x1d;
b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */
b[3] = 0;
alloc_length += 4;
b += 4;
}
if ((feature == 0x1e) || ((cdb[1] & 3) < 2)) {
b[1] = 0x1e;
b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */
b[3] = 4;
b[4] = 0;
alloc_length += 8;
b += 8;
}
if ((feature == 0x1f) || ((cdb[1] & 3) < 2)) {
b[1] = 0x1f;
b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */
b[3] = 0;
alloc_length += 4;
b += 4;
}
if ((feature == 0x103) || ((cdb[1] & 3) < 2)) {
b[0] = 1;
b[1] = 3;
b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */
b[3] = 0;
b[4] = 7;
b[6] = 1;
alloc_length += 8;
b += 8;
}
dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff;
dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff;

View File

@@ -471,7 +471,8 @@ s3_virge_update_irqs(virge_t *virge) {
}
static void
s3_virge_out(uint16_t addr, uint8_t val, void *priv) {
s3_virge_out(uint16_t addr, uint8_t val, void *priv)
{
virge_t *virge = (virge_t *) priv;
svga_t * svga = &virge->svga;
uint8_t old;
@@ -483,7 +484,7 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) {
switch (addr) {
case 0x3c5:
if (svga->seqaddr >= 0x10) {
svga->seqregs[svga->seqaddr & 0x1f] = val;
svga->seqregs[svga->seqaddr] = val;
svga_recalctimings(svga);
return;
}
@@ -519,8 +520,6 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) {
return;
if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5))
return;
if (svga->crtcreg >= 0x80)
return;
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
@@ -707,7 +706,7 @@ s3_virge_in(uint16_t addr, void *priv) {
case 0x3c5:
if (svga->seqaddr >= 8)
ret = svga->seqregs[svga->seqaddr & 0x1f];
ret = svga->seqregs[svga->seqaddr];
else if (svga->seqaddr <= 4)
ret = svga_in(addr, svga);
else