if (gb->pcemobject) {
gb->pcemdev->close(gb->pcemobject);
gb->pcemobject = NULL;
+ gb->pcemobject2 = NULL;
}
}
if (gb->vram && gb->gfxmem_bank->baseaddr) {
flags_rebuild();
// pclog("Abort\n");
// if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt);
- tempi = cpu_state.abrt;
+ tempi = cpu_state.abrt & ABRT_MASK;
cpu_state.abrt = 0;
x86_doabrt(tempi);
if (cpu_state.abrt)
}
}
}
- ins_cycles -= cycles;
- tsc += ins_cycles;
-
- cycdiff=oldcyc-cycles;
- if (trap)
+ if (cpu_state.smi_pending)
+ {
+ cpu_state.smi_pending = 0;
+ x86_smi_enter();
+ }
+ else if (trap)
{
flags_rebuild();
// oldpc=pc;
ins++;
insc++;
+ ins_cycles -= cycles;
+ tsc += ins_cycles;
+
+ cycdiff=oldcyc-cycles;
+
if (timetolive)
{
timetolive--;
uint32_t cr2, cr3, cr4;
uint32_t dr[8];
+uint16_t sysenter_cs;
+uint32_t sysenter_eip, sysenter_esp;
+
uint32_t use32;
int stack32;
int optype;
if (cpu_state.abrt) return 1; \
if (tempi) \
{ \
- x86gpf(NULL,0); \
+ if (cpu_state.eflags & VM_FLAG) \
+ x86gpf_expected(NULL,0); \
+ else \
+ x86gpf(NULL,0); \
return 1; \
} \
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
+#if defined(__APPLE__) && defined(__aarch64__)
+#include <pthread.h>
+#endif
#include "ibm.h"
#include "x86.h"
#include "x86_ops.h"
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
//#define CACHE_ON() 0
-static int cycles_main = 0;
-void exec386_dynarec(int cycs)
+int cpu_end_block_after_ins = 0;
+
+
+static inline void exec_interpreter(void)
{
- uint8_t temp;
- uint32_t addr;
- int tempi;
- int cycdiff;
- int oldcyc;
- int cyc_period = cycs / 2000; /*5us*/
+ cpu_block_end = 0;
+ x86_was_reset = 0;
+// if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, DX, SI, DI, SP);
+ while (!cpu_block_end)
+ {
+ cpu_state.oldpc = cpu_state.pc;
+ cpu_state.op32 = use32;
- cycles_main += cycs;
- while (cycles_main > 0)
+ cpu_state.ea_seg = &cpu_state.seg_ds;
+ cpu_state.ssegs = 0;
+
+ fetchdat = fastreadl(cs + cpu_state.pc);
+
+ if (!cpu_state.abrt)
+ {
+ uint8_t opcode = fetchdat & 0xFF;
+ fetchdat >>= 8;
+ trap = cpu_state.flags & T_FLAG;
+
+// if (output == 3)
+// pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], ram[0x8f140]);
+
+ cpu_state.pc++;
+ x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
+ }
+
+ if (((cs + cpu_state.pc) >> 12) != pccache)
+ CPU_BLOCK_END();
+
+ if (cpu_state.abrt)
+ CPU_BLOCK_END();
+ if (cpu_state.smi_pending)
+ CPU_BLOCK_END();
+ if (trap)
+ CPU_BLOCK_END();
+ if (nmi && nmi_enable && nmi_mask)
+ CPU_BLOCK_END();
+ if (cpu_end_block_after_ins)
+ {
+ cpu_end_block_after_ins--;
+ if (!cpu_end_block_after_ins)
+ CPU_BLOCK_END();
+ }
+
+ ins++;
+ insc++;
+ }
+
+ if (trap)
{
- int cycles_start;
-
- cycles += cyc_period;
- cycles_start = cycles;
+ trap = 0;
+ cpu_state.oldpc = cpu_state.pc;
+ x86_int(1);
+ }
- while (cycles>0)
+ cpu_end_block_after_ins = 0;
+}
+
+static inline void exec_recompiler(void)
+{
+ uint32_t phys_addr = get_phys(cs+cpu_state.pc);
+ int hash = HASH(phys_addr);
+ codeblock_t *block = &codeblock[codeblock_hash[hash]];
+ int valid_block = 0;
+
+ if (!cpu_state.abrt)
+ {
+ page_t *page = &pages[phys_addr >> 12];
+
+ /*Block must match current CS, PC, code segment size,
+ and physical address. The physical address check will
+ also catch any page faults at this stage*/
+ valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
+ (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
+ ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
+ if (!valid_block)
{
- oldcyc=cycles;
-// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP);
- if (!CACHE_ON()) /*Interpret block*/
+ uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
+ int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
+ uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f);
+
+ if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))
{
- cpu_block_end = 0;
- x86_was_reset = 0;
-// if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, DX, SI, DI, SP);
- while (!cpu_block_end)
+ /*Walk page tree to see if we find the correct block*/
+ codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
+ if (new_block)
{
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
+ valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
+ (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
+ ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
+ if (valid_block)
+ {
+ block = new_block;
+ codeblock_hash[hash] = get_block_nr(block);
+ }
+ }
+ }
+ }
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
+ if (valid_block && (block->page_mask & *block->dirty_mask))
+ {
+ codegen_check_flush(page, page->dirty_mask, phys_addr);
+ if (block->pc == BLOCK_PC_INVALID)
+ valid_block = 0;
+ else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
+ block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
+ }
+ if (valid_block && block->page_mask2)
+ {
+ /*We don't want the second page to cause a page
+ fault at this stage - that would break any
+ code crossing a page boundary where the first
+ page is present but the second isn't. Instead
+ allow the first page to be interpreted and for
+ the page fault to occur when the page boundary
+ is actually crossed.*/
+ uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400));
+ page_t *page_2 = &pages[phys_addr_2 >> 12];
+ if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
+ valid_block = 0;
+ else if (block->page_mask2 & *block->dirty_mask2)
+ {
+ codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2);
+ if (block->pc == BLOCK_PC_INVALID)
+ valid_block = 0;
+ else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
+ block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
+ }
+ }
+ if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST))
+ {
+ block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
+ if (block->flags & CODEBLOCK_BYTE_MASK)
+ block->flags |= CODEBLOCK_NO_IMMEDIATES;
+ else
+ block->flags |= CODEBLOCK_BYTE_MASK;
+ }
+ if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7))
+ {
+ /*FPU top-of-stack does not match the value this block was compiled
+ with, re-compile using dynamic top-of-stack*/
+ block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED);
+ }
+ }
- if (!cpu_state.abrt)
- {
- uint8_t opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
- trap = cpu_state.flags & T_FLAG;
+ if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED))
+ {
+ void (*code)() = (void(*)(void)) & block->data[BLOCK_START];
-// if (output == 3)
-// pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], ram[0x8f140]);
+// if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc);
- cpu_state.pc++;
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
- }
+ inrecomp=1;
+ code();
+ inrecomp=0;
- if (((cs + cpu_state.pc) >> 12) != pccache)
- CPU_BLOCK_END();
+ cpu_recomp_blocks++;
+ }
+ else if (valid_block && !cpu_state.abrt)
+ {
+ uint32_t start_pc = cs+cpu_state.pc;
+ const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
- if (cpu_state.abrt)
- CPU_BLOCK_END();
- if (trap)
- CPU_BLOCK_END();
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- ins++;
- insc++;
- }
+ cpu_block_end = 0;
+ x86_was_reset = 0;
+
+ cpu_new_blocks++;
+
+#if defined(__APPLE__) && defined(__aarch64__)
+ pthread_jit_write_protect_np(0);
+#endif
+ codegen_block_start_recompile(block);
+ codegen_in_recompile = 1;
+
+// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]);
+ while (!cpu_block_end)
+ {
+ cpu_state.oldpc = cpu_state.pc;
+ cpu_state.op32 = use32;
+
+ cpu_state.ea_seg = &cpu_state.seg_ds;
+ cpu_state.ssegs = 0;
+
+ fetchdat = fastreadl(cs + cpu_state.pc);
+
+ if (!cpu_state.abrt)
+ {
+ uint8_t opcode = fetchdat & 0xFF;
+ fetchdat >>= 8;
+
+// if (output == 3)
+// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache);
+
+ cpu_state.pc++;
+
+ codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
+
+ x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
+
+ if (x86_was_reset)
+ break;
}
- else
+
+ /*Cap source code at 4000 bytes per block; this
+ will prevent any block from spanning more than
+ 2 pages. In practice this limit will never be
+ hit, as host block size is only 2kB*/
+ if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
+ CPU_BLOCK_END();
+ if (cpu_state.flags & T_FLAG)
+ CPU_BLOCK_END();
+ if (cpu_state.smi_pending)
+ CPU_BLOCK_END();
+ if (nmi && nmi_enable && nmi_mask)
+ CPU_BLOCK_END();
+
+ if (cpu_end_block_after_ins)
{
- uint32_t phys_addr = get_phys(cs+cpu_state.pc);
- int hash = HASH(phys_addr);
- codeblock_t *block = &codeblock[codeblock_hash[hash]];
- int valid_block = 0;
+ cpu_end_block_after_ins--;
+ if (!cpu_end_block_after_ins)
+ CPU_BLOCK_END();
+ }
- if (!cpu_state.abrt)
- {
- page_t *page = &pages[phys_addr >> 12];
-
- /*Block must match current CS, PC, code segment size,
- and physical address. The physical address check will
- also catch any page faults at this stage*/
- valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
- (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (!valid_block)
- {
- uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
- int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
- uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f);
-
- if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))
- {
- /*Walk page tree to see if we find the correct block*/
- codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
- if (new_block)
- {
- valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
- (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
- ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
- if (valid_block)
- {
- block = new_block;
- codeblock_hash[hash] = get_block_nr(block);
- }
- }
- }
- }
+ if (cpu_state.abrt)
+ {
+ if (!(cpu_state.abrt & ABRT_EXPECTED))
+ codegen_block_remove();
+ CPU_BLOCK_END();
+ }
- if (valid_block && (block->page_mask & *block->dirty_mask))
- {
- codegen_check_flush(page, page->dirty_mask, phys_addr);
- if (block->pc == BLOCK_PC_INVALID)
- valid_block = 0;
- else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
- block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
- }
- if (valid_block && block->page_mask2)
- {
- /*We don't want the second page to cause a page
- fault at this stage - that would break any
- code crossing a page boundary where the first
- page is present but the second isn't. Instead
- allow the first page to be interpreted and for
- the page fault to occur when the page boundary
- is actually crossed.*/
- uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400));
- page_t *page_2 = &pages[phys_addr_2 >> 12];
- if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
- valid_block = 0;
- else if (block->page_mask2 & *block->dirty_mask2)
- {
- codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2);
- if (block->pc == BLOCK_PC_INVALID)
- valid_block = 0;
- else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
- block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
- }
- }
- if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST))
- {
- block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
- if (block->flags & CODEBLOCK_BYTE_MASK)
- block->flags |= CODEBLOCK_NO_IMMEDIATES;
- else
- block->flags |= CODEBLOCK_BYTE_MASK;
- }
- if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7))
- {
- /*FPU top-of-stack does not match the value this block was compiled
- with, re-compile using dynamic top-of-stack*/
- block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED);
- }
- }
+ ins++;
+ insc++;
+ }
+ cpu_end_block_after_ins = 0;
- if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED))
- {
- void (*code)() = (void(*)(void))&block->data[BLOCK_START];
+ if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset)
+ codegen_block_end_recompile(block);
-// if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc);
+ if (x86_was_reset)
+ codegen_reset();
- inrecomp=1;
- code();
- inrecomp=0;
+ codegen_in_recompile = 0;
+#if defined(__APPLE__) && defined(__aarch64__)
+ pthread_jit_write_protect_np(1);
+#endif
+ }
+ else if (!cpu_state.abrt)
+ {
+ /*Mark block but do not recompile*/
+ uint32_t start_pc = cs+cpu_state.pc;
+ const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
- cpu_recomp_blocks++;
- }
- else if (valid_block && !cpu_state.abrt)
- {
- uint32_t start_pc = cs+cpu_state.pc;
- const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
-
- cpu_block_end = 0;
- x86_was_reset = 0;
-
- cpu_new_blocks++;
-
- codegen_block_start_recompile(block);
- codegen_in_recompile = 1;
-
-// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]);
- while (!cpu_block_end)
- {
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
+ cpu_block_end = 0;
+ x86_was_reset = 0;
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- uint8_t opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
-
- trap = cpu_state.flags & T_FLAG;
-
-// if (output == 3)
-// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache);
-
- cpu_state.pc++;
-
- codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
- if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- insc++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end_recompile(block);
-
- if (x86_was_reset)
- codegen_reset();
-
- codegen_in_recompile = 0;
- }
- else if (!cpu_state.abrt)
- {
- /*Mark block but do not recompile*/
- uint32_t start_pc = cs+cpu_state.pc;
- const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
+ codegen_block_init(phys_addr);
- cpu_block_end = 0;
- x86_was_reset = 0;
+// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]);
+ while (!cpu_block_end)
+ {
+ cpu_state.oldpc = cpu_state.pc;
+ cpu_state.op32 = use32;
- codegen_block_init(phys_addr);
+ cpu_state.ea_seg = &cpu_state.seg_ds;
+ cpu_state.ssegs = 0;
-// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]);
- while (!cpu_block_end)
- {
- cpu_state.oldpc = cpu_state.pc;
- cpu_state.op32 = use32;
+ codegen_endpc = (cs + cpu_state.pc) + 8;
+ fetchdat = fastreadl(cs + cpu_state.pc);
- cpu_state.ea_seg = &cpu_state.seg_ds;
- cpu_state.ssegs = 0;
-
- codegen_endpc = (cs + cpu_state.pc) + 8;
- fetchdat = fastreadl(cs + cpu_state.pc);
-
- if (!cpu_state.abrt)
- {
- uint8_t opcode = fetchdat & 0xFF;
- fetchdat >>= 8;
-
- trap = cpu_state.flags & T_FLAG;
-
-// if (output == 3)
-// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache);
-
- cpu_state.pc++;
-
- x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
-
- if (x86_was_reset)
- break;
- }
-
- /*Cap source code at 4000 bytes per block; this
- will prevent any block from spanning more than
- 2 pages. In practice this limit will never be
- hit, as host block size is only 2kB*/
- if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
- CPU_BLOCK_END();
-
- if (trap)
- CPU_BLOCK_END();
-
- if (nmi && nmi_enable && nmi_mask)
- CPU_BLOCK_END();
-
- if (cpu_state.abrt)
- {
- codegen_block_remove();
- CPU_BLOCK_END();
- }
-
- ins++;
- insc++;
- }
-
- if (!cpu_state.abrt && !x86_was_reset)
- codegen_block_end();
-
- if (x86_was_reset)
- codegen_reset();
- }
- else
- cpu_state.oldpc = cpu_state.pc;
+ if (!cpu_state.abrt)
+ {
+ uint8_t opcode = fetchdat & 0xFF;
+ fetchdat >>= 8;
+// if (output == 3)
+// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache);
+
+ cpu_state.pc++;
+
+ x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
+
+ if (x86_was_reset)
+ break;
}
- cycdiff=oldcyc-cycles;
- tsc += cycdiff;
+ /*Cap source code at 4000 bytes per block; this
+ will prevent any block from spanning more than
+ 2 pages. In practice this limit will never be
+ hit, as host block size is only 2kB*/
+ if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
+ CPU_BLOCK_END();
+ if (cpu_state.flags & T_FLAG)
+ CPU_BLOCK_END();
+ if (cpu_state.smi_pending)
+ CPU_BLOCK_END();
+ if (nmi && nmi_enable && nmi_mask)
+ CPU_BLOCK_END();
+
+ if (cpu_end_block_after_ins)
+ {
+ cpu_end_block_after_ins--;
+ if (!cpu_end_block_after_ins)
+ CPU_BLOCK_END();
+ }
+
+ if (cpu_state.abrt)
+ {
+ if (!(cpu_state.abrt & ABRT_EXPECTED))
+ codegen_block_remove();
+ CPU_BLOCK_END();
+ }
+
+ ins++;
+ insc++;
+ }
+ cpu_end_block_after_ins = 0;
+
+// if (!cpu_state.abrt && !x86_was_reset)
+ if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset)
+ codegen_block_end();
+
+ if (x86_was_reset)
+ codegen_reset();
+ }
+ else
+ cpu_state.oldpc = cpu_state.pc;
+
+}
+
+
+int cycles_main = 0;
+void exec386_dynarec(int cycs)
+{
+ uint8_t temp;
+ int tempi;
+ int cycdiff;
+ int oldcyc;
+ int cyc_period = cycs / 2000; /*5us*/
+
+ cycles_main += cycs;
+ while (cycles_main > 0)
+ {
+ int cycles_start;
+
+ cycles += cyc_period;
+ cycles_start = cycles;
+
+ while (cycles>0)
+ {
+ oldcyc=cycles;
+// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP);
+ if (!CACHE_ON()) /*Interpret block*/
+ exec_interpreter();
+ else
+ exec_recompiler();
if (cpu_state.abrt)
{
flags_rebuild();
- tempi = cpu_state.abrt;
+ tempi = cpu_state.abrt & ABRT_MASK;
cpu_state.abrt = 0;
x86_doabrt(tempi);
if (cpu_state.abrt)
}
}
- if (trap)
+ if (cpu_state.smi_pending)
{
- trap = 0;
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(1,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr = (1 << 2) + idt.base;
- cpu_state.flags &= ~I_FLAG;
- cpu_state.flags &= ~T_FLAG;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
+ cpu_state.smi_pending = 0;
+ x86_smi_enter();
}
else if (nmi && nmi_enable && nmi_mask)
{
temp=picinterrupt();
if (temp!=0xFF)
{
+ cpu_state.oldpc = cpu_state.pc;
+ x86_int(temp);
// pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc);
- CPU_BLOCK_END();
- flags_rebuild();
- if (msw&1)
- {
- pmodeint(temp,0);
- }
- else
- {
- writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
- writememw(ss,(SP-4)&0xFFFF,CS);
- writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
- SP-=6;
- addr=temp<<2;
- cpu_state.flags &= ~I_FLAG;
- cpu_state.flags &= ~T_FLAG;
- cpu_state.pc=readmemw(0,addr);
- loadcs(readmemw(0,addr+2));
- }
}
}
+
+ cycdiff=oldcyc-cycles;
+ tsc += cycdiff;
}
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
#include "x86_ops_bit.h"
#include "x86_ops_bitscan.h"
#include "x86_ops_call.h"
+#include "x86_ops_cyrix.h"
#include "x86_ops_flag.h"
#include "x86_ops_fpu.h"
#include "x86_ops_inc_dec.h"
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
+
+/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+};
+
+OpFn OP_TABLE(c6x86_0f)[1024] =
+{
+ /*16-bit data, 16-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL,
+
+/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
+/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
+
+/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+
+ /*32-bit data, 16-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL,
+
+/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
+/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
+
+/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+
+ /*16-bit data, 32-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, ILLEGAL,
+
+/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
+/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
+
+/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+
+ /*32-bit data, 32-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, ILLEGAL,
+
+/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
+/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
-OpFn OP_TABLE(pentiummmx_0f)[1024] =
+OpFn OP_TABLE(pentiummmx_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
-/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
-/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
-/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
-/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
-/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
-/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32,
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
-/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32,
+
+/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
+/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
+
+/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_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,
+};
+
+OpFn OP_TABLE(pentiumpro_0f)[1024] =
+{
+ /*16-bit data, 16-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16,
+/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
+/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
+
+/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+
+ /*32-bit data, 16-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16,
+/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
+/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
+
+/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+
+ /*16-bit data, 32-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32,
+/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
+/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
+
+/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+
+ /*32-bit data, 32-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32,
+/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
+/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
+
+/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*e0*/ 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,
+};
+
+OpFn OP_TABLE(pentium2_0f)[1024] =
+{
+ /*16-bit data, 16-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16,
+/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
+
+/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
+/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
+/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
+
+/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16,
+/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16,
+/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL,
+
+ /*32-bit data, 16-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16,
+/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
+
+/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
+/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
+/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
+
+/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16,
+/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16,
+/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL,
+
+ /*16-bit data, 32-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32,
+/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+
+/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32,
+/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
+/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32,
+
+/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
+/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
+/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
+/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
+
+/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
+/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_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,
+
+ /*32-bit data, 32-bit addr*/
+/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
+/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32,
+/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
+/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
-/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
+/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
/*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,
};
-OpFn OP_TABLE(286)[1024] =
+OpFn OP_TABLE(286)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
putc(readmembl(c+0x80000000),f);
}
fclose(f);
- pclog("Dumping done\n");
+ pclog("Dumping done\n");
/* f=fopen("rram6.dmp","wb");
for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f);
fclose(f);*/
{
printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
printf("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4);
+ pclog("SMBASE=%08x\n", cpu_state.smbase);
}
printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
for (c=0;c<1024*1024;c++)
x86seg_reset();
codegen_reset();
x86_was_reset = 1;
+ cpu_state.smbase = 0x30000;
}
void softresetx86()
extern codegen_timing_t codegen_timing_486;
extern codegen_timing_t codegen_timing_winchip;
extern codegen_timing_t codegen_timing_winchip2;
+extern codegen_timing_t codegen_timing_cyrixiii;
extern codegen_timing_t codegen_timing_k6;
+extern codegen_timing_t codegen_timing_p6;
void codegen_timing_set(codegen_timing_t *timing);
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_MAX 0x3c0
+
+#define CODEGEN_BACKEND_HAS_MOV_IMM
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_MAX 0x3c0
+
+#define CODEGEN_BACKEND_HAS_MOV_IMM
CPUID_TSC = (1 << 4),
CPUID_MSR = (1 << 5),
CPUID_CMPXCHG8B = (1 << 8),
+ CPUID_SEP = (1 << 11),
CPUID_CMOV = (1 << 15),
CPUID_MMX = (1 << 23)
};
timing_misaligned = 0;
cpu_cyrix_alignment = 0;
+ cpu_CR4_mask = 0;
switch (cpu_s->cpu_type)
{
break;
case CPU_Cx6x86:
- x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
+ x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f);
timing_rr = 1; /*register dest - register src*/
timing_rm = 1; /*register dest - memory src*/
timing_mr = 2; /*memory dest - register src*/
codegen_timing_set(&codegen_timing_k6);
break;
+ case CPU_PENTIUMPRO:
+ x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f);
+ 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_db_a16 = dynarec_ops_fpu_686_db_a16;
+ x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
+ x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
+ x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
+ x86_opcodes_da_a16 = ops_fpu_686_da_a16;
+ x86_opcodes_da_a32 = ops_fpu_686_da_a32;
+ x86_opcodes_db_a16 = ops_fpu_686_db_a16;
+ x86_opcodes_db_a32 = ops_fpu_686_db_a32;
+ x86_opcodes_df_a16 = ops_fpu_686_df_a16;
+ x86_opcodes_df_a32 = ops_fpu_686_df_a32;
+ timing_rr = 1; /*register dest - register src*/
+ timing_rm = 2; /*register dest - memory src*/
+ timing_mr = 3; /*memory dest - register src*/
+ timing_mm = 3;
+ timing_rml = 2; /*register dest - memory src long*/
+ timing_mrl = 3; /*memory dest - register src long*/
+ timing_mml = 3;
+ timing_bt = 0; /*branch taken*/
+ timing_bnt = 2; /*branch not taken*/
+ timing_int = 6;
+ timing_int_rm = 11;
+ timing_int_v86 = 54;
+ timing_int_pm = 25;
+ timing_int_pm_outer = 42;
+ timing_iret_rm = 7;
+ timing_iret_v86 = 27; /*unknown*/
+ timing_iret_pm = 10;
+ timing_iret_pm_outer = 27;
+ timing_call_rm = 4;
+ timing_call_pm = 4;
+ timing_call_pm_gate = 22;
+ timing_call_pm_gate_inner = 44;
+ timing_retf_rm = 4;
+ timing_retf_pm = 4;
+ timing_retf_pm_outer = 23;
+ timing_jmp_rm = 3;
+ timing_jmp_pm = 3;
+ timing_jmp_pm_gate = 18;
+ timing_misaligned = 3;
+ cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_SYSCALL;
+ msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
+ cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
+ codegen_timing_set(&codegen_timing_p6);
+ break;
+
+ case CPU_PENTIUM_2:
+ case CPU_CELERON:
+ case CPU_CELERON_A:
+ 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_a32 = dynarec_ops_fpu_686_da_a32;
+ x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16;
+ x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32;
+ x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
+ x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
+ x86_opcodes_da_a16 = ops_fpu_686_da_a16;
+ x86_opcodes_da_a32 = ops_fpu_686_da_a32;
+ x86_opcodes_db_a16 = ops_fpu_686_db_a16;
+ x86_opcodes_db_a32 = ops_fpu_686_db_a32;
+ x86_opcodes_df_a16 = ops_fpu_686_df_a16;
+ x86_opcodes_df_a32 = ops_fpu_686_df_a32;
+ timing_rr = 1; /*register dest - register src*/
+ timing_rm = 2; /*register dest - memory src*/
+ timing_mr = 3; /*memory dest - register src*/
+ timing_mm = 3;
+ timing_rml = 2; /*register dest - memory src long*/
+ timing_mrl = 3; /*memory dest - register src long*/
+ timing_mml = 3;
+ timing_bt = 0; /*branch taken*/
+ timing_bnt = 2; /*branch not taken*/
+ timing_int = 6;
+ timing_int_rm = 11;
+ timing_int_v86 = 54;
+ timing_int_pm = 25;
+ timing_int_pm_outer = 42;
+ timing_iret_rm = 7;
+ timing_iret_v86 = 27; /*unknown*/
+ timing_iret_pm = 10;
+ timing_iret_pm_outer = 27;
+ timing_call_rm = 4;
+ timing_call_pm = 4;
+ timing_call_pm_gate = 22;
+ timing_call_pm_gate_inner = 44;
+ timing_retf_rm = 4;
+ timing_retf_pm = 4;
+ timing_retf_pm_outer = 23;
+ timing_jmp_rm = 3;
+ timing_jmp_pm = 3;
+ timing_jmp_pm_gate = 18;
+ timing_misaligned = 3;
+ cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX | CPU_FEATURE_SYSCALL;
+ msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
+ cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
+ codegen_timing_set(&codegen_timing_p6);
+ break;
+
+ case CPU_CYRIX_III:
+ x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f);
+ timing_rr = 1; /*register dest - register src*/
+ timing_rm = 1; /*register dest - memory src*/
+ timing_mr = 1; /*memory dest - register src*/
+ timing_mm = 1;
+ timing_rml = 1; /*register dest - memory src long*/
+ timing_mrl = 1; /*memory dest - register src long*/
+ timing_mml = 1;
+ timing_bt = 1; /*branch taken*/
+ timing_bnt = 1; /*branch not taken*/
+ cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW;
+ msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21);
+ cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
+ /*unknown*/
+ timing_int_rm = 26;
+ timing_int_v86 = 82;
+ timing_int_pm = 44;
+ timing_int_pm_outer = 71;
+ timing_iret_rm = 7;
+ timing_iret_v86 = 26;
+ timing_iret_pm = 10;
+ timing_iret_pm_outer = 26;
+ timing_call_rm = 4;
+ timing_call_pm = 15;
+ timing_call_pm_gate = 26;
+ timing_call_pm_gate_inner = 35;
+ timing_retf_rm = 4;
+ timing_retf_pm = 7;
+ timing_retf_pm_outer = 23;
+ timing_jmp_rm = 5;
+ timing_jmp_pm = 7;
+ timing_jmp_pm_gate = 17;
+ timing_misaligned = 2;
+ cpu_cyrix_alignment = 1;
+ codegen_timing_set(&codegen_timing_cyrixiii);
+ break;
+
#endif
default:
break;
}
break;
+
+ case CPU_PENTIUMPRO:
+ if (!EAX)
+ {
+ EAX = 0x00000002;
+ EBX = 0x756e6547;
+ EDX = 0x49656e69;
+ ECX = 0x6c65746e;
+ }
+ else if (EAX == 1)
+ {
+ EAX = CPUID;
+ EBX = ECX = 0;
+ EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_SEP;
+ }
+ else if (EAX == 2)
+ {
+ EAX = 0x03020101;
+ EBX = 0;
+ ECX = 0;
+ EDX = 0x06040a42;
+ }
+ else
+ EAX = EBX = ECX = EDX = 0;
+ break;
+
+ case CPU_PENTIUM_2:
+ case CPU_CELERON:
+ case CPU_CELERON_A:
+ if (!EAX)
+ {
+ EAX = 0x00000002;
+ EBX = 0x756e6547;
+ EDX = 0x49656e69;
+ ECX = 0x6c65746e;
+ }
+ else if (EAX == 1)
+ {
+ EAX = CPUID;
+ EBX = ECX = 0;
+ EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX | CPUID_SEP;
+ }
+ else if (EAX == 2)
+ {
+ EAX = 0x03020101;
+ EBX = 0;
+ ECX = 0;
+ if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUM_2)
+ EDX = 0x08040c43; /*512kb L2 cache*/
+ else if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_CELERON)
+ EDX = 0x08040c40; /*No L2 cache*/
+ else
+ EDX = 0x08040c41; /*128kb L2 cache*/
+ }
+ else
+ EAX = EBX = ECX = EDX = 0;
+ break;
+
+ case CPU_CYRIX_III:
+ switch (EAX)
+ {
+ case 0:
+ EAX = 1;
+ EBX = 0x746e6543; /*CentaurHauls*/
+ ECX = 0x736c7561;
+ EDX = 0x48727561;
+ break;
+ case 1:
+ EAX = models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
+ EBX = ECX = 0;
+ EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
+ if (cpu_has_feature(CPU_FEATURE_CX8))
+ EDX |= CPUID_CMPXCHG8B;
+ if (msr.fcr & (1 << 9))
+ EDX |= CPUID_MMX;
+ break;
+ case 0x80000000:
+ EAX = 0x80000006;
+ break;
+ case 0x80000001:
+ EAX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset;
+ EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
+ if (cpu_has_feature(CPU_FEATURE_CX8))
+ EDX |= CPUID_CMPXCHG8B;
+ if (msr.fcr & (1 << 9))
+ EDX |= CPUID_MMX;
+ if (cpu_has_feature(CPU_FEATURE_3DNOW))
+ EDX |= CPUID_3DNOW;
+ break;
+
+ case 0x80000002: /*Processor name string*/
+ if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670)
+ {
+ EAX = 0x20414956; /*VIA Samuel 2*/
+ EBX = 0x756d6153;
+ ECX = 0x32206c65;
+ EDX = 0x00000000;
+ }
+ else
+ {
+ EAX = 0x20414956; /*VIA SamuelM*/
+ EBX = 0x756d6153;
+ ECX = 0x004d6c65;
+ EDX = 0x00000000;
+ }
+ break;
+
+ case 0x80000005: /*Cache information*/
+ EBX = 0x08800880; /*TLBs*/
+ ECX = 0x40040120; /*L1 data cache*/
+ EDX = 0x40020120; /*L1 instruction cache*/
+ break;
+
+ case 0x80000006: /*L2 Cache information*/
+ if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670)
+ ECX = 0x40040120; /*L2 cache*/
+ else
+ ECX = 0;
+ EAX = EBX = EDX = 0;
+ break;
+
+ default:
+ EAX = EBX = ECX = EDX = 0;
+ break;
+ }
+ break;
}
}
{
case CPU_WINCHIP:
case CPU_WINCHIP2:
+ case CPU_CYRIX_III:
EAX = EDX = 0;
switch (ECX)
{
break;
}
break;
+ case CPU_PENTIUMPRO:
+ case CPU_PENTIUM_2:
+ case CPU_CELERON:
+ case CPU_CELERON_A:
+ EAX = EDX = 0;
+ switch (ECX)
+ {
+ case 0x10:
+ EAX = tsc & 0xffffffff;
+ EDX = tsc >> 32;
+ break;
+
+ case 0x174:
+ EAX = sysenter_cs;
+ EDX = 0;
+ break;
+ case 0x175:
+ EAX = sysenter_esp;
+ EDX = 0;
+ break;
+ case 0x176:
+ EAX = sysenter_eip;
+ EDX = 0;
+ break;
+ }
+ break;
}
}
{
case CPU_WINCHIP:
case CPU_WINCHIP2:
+ case CPU_CYRIX_III:
switch (ECX)
{
case 0x02:
break;
}
break;
+ case CPU_PENTIUMPRO:
+ case CPU_PENTIUM_2:
+ case CPU_CELERON:
+ case CPU_CELERON_A:
+ switch (ECX)
+ {
+ case 0x10:
+ tsc = EAX | ((uint64_t)EDX << 32);
+ break;
+
+ case 0x174:
+ sysenter_cs = EAX & 0xffff;
+ break;
+ case 0x175:
+ sysenter_esp = EAX;
+ break;
+ case 0x176:
+ sysenter_eip = EAX;
+ break;
+ }
+ break;
}
}
static int cyrix_addr;
+#define CCR1_USE_SMI (1 << 1)
+#define CCR1_SMAC (1 << 2)
+#define CCR1_SM3 (1 << 7)
+
+#define CCR3_SMI_LOCK (1 << 0)
+#define CCR3_NMI_EN (1 << 1)
+
void cyrix_write(uint16_t addr, uint8_t val, void *priv)
{
if (!(addr & 1))
ccr0 = val;
break;
case 0xc1: /*CCR1*/
+ if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM))
+ val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3));
ccr1 = val;
break;
case 0xc2: /*CCR2*/
ccr2 = val;
break;
case 0xc3: /*CCR3*/
+ if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM))
+ val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK;
ccr3 = val;
break;
+ case 0xcd:
+ if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM))
+ {
+ cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24);
+ cyrix.smhr &= ~SMHR_VALID;
+ }
+ break;
+ case 0xce:
+ if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM))
+ {
+ cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16);
+ cyrix.smhr &= ~SMHR_VALID;
+ }
+ break;
+ case 0xcf:
+ if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM))
+ {
+ cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8);
+ if ((val & 0xf) == 0xf)
+ cyrix.arr[3].size = 1ull << 32; /*4 GB*/
+ else if (val & 0xf)
+ cyrix.arr[3].size = 2048 << (val & 0xf);
+ else
+ cyrix.arr[3].size = 0; /*Disabled*/
+ cyrix.smhr &= ~SMHR_VALID;
+ }
+ break;
+
case 0xe8: /*CCR4*/
if ((ccr3 & 0xf0) == 0x10)
{
case 0xfe: return models[model].cpu[cpu_manufacturer].cpus[cpu].cyrix_id & 0xff;
case 0xff: return models[model].cpu[cpu_manufacturer].cpus[cpu].cyrix_id >> 8;
}
- if ((cyrix_addr & ~0xf0) == 0xc0) return 0xff;
if (cyrix_addr == 0x20 && models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_Cx5x86) return 0xff;
}
return 0xff;
}
}
+int cpu_get_turbo()
+{
+ return cpu_turbo;
+}
+
int cpu_get_speed()
{
if (cpu_turbo)
return cpu_turbo_speed;
return cpu_nonturbo_speed;
}
+
+void cpu_set_nonturbo_divider(int divider)
+{
+ if (divider < 2)
+ cpu_set_turbo(1);
+ else
+ {
+ cpu_nonturbo_speed = cpu_turbo_speed / divider;
+ cpu_set_turbo(0);
+ }
+}
#define CPU_K6_3 25
#define CPU_K6_2P 26
#define CPU_K6_3P 27
+#define CPU_PENTIUMPRO 28
+#define CPU_PENTIUM_2 29
+#define CPU_CELERON 30
+#define CPU_CELERON_A 31
+#define CPU_CYRIX_III 32
#define MANU_INTEL 0
#define MANU_AMD 1
#define MANU_CYRIX 2
#define MANU_IDT 3
+#define MANU_VIA 4
extern int timing_rr;
extern int timing_mr, timing_mrl;
int atclk_div;
} CPU;
+extern CPU *cpu_s;
+
extern CPU cpus_8088[];
extern CPU cpus_8086[];
extern CPU cpus_286[];
extern CPU cpus_6x86_SS7[];
extern CPU cpus_K6_S7[];
extern CPU cpus_K6_SS7[];
+extern CPU cpus_PentiumPro[];
+extern CPU cpus_Slot1_100MHz[];
+extern CPU cpus_VIA_100MHz[];
extern CPU cpus_pcjr[];
extern CPU cpus_europc[];
/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/
extern int cpu_cyrix_alignment;
-#define CPU_FEATURE_RDTSC (1 << 0)
-#define CPU_FEATURE_MSR (1 << 1)
-#define CPU_FEATURE_MMX (1 << 2)
-#define CPU_FEATURE_CR4 (1 << 3)
-#define CPU_FEATURE_VME (1 << 4)
-#define CPU_FEATURE_CX8 (1 << 5)
-#define CPU_FEATURE_3DNOW (1 << 6)
+#define CPU_FEATURE_RDTSC (1 << 0)
+#define CPU_FEATURE_MSR (1 << 1)
+#define CPU_FEATURE_MMX (1 << 2)
+#define CPU_FEATURE_CR4 (1 << 3)
+#define CPU_FEATURE_VME (1 << 4)
+#define CPU_FEATURE_CX8 (1 << 5)
+#define CPU_FEATURE_3DNOW (1 << 6)
+#define CPU_FEATURE_SYSCALL (1 << 7)
extern uint32_t cpu_features;
static inline int cpu_has_feature(int feature)
extern int isa_cycles;
#define ISA_CYCLES(x) (x * isa_cycles)
+#define CPU_CLOCK_DIVIDER_MAX 16384
void cpu_update_waitstates();
void cpu_set();
void cpu_set_edx();
void cpu_set_turbo(int turbo);
+int cpu_get_turbo();
+void cpu_set_nonturbo_divider(int divider);
int cpu_get_speed();
extern int has_vlb;
--- /dev/null
+#include "device.h"
+
+void upc_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p);
+
+extern device_t f82c710_upc_device;
+
--- /dev/null
+void i440bx_init();
+void i440bx_reset();
ROM_PC200,
ROM_PC1640,
ROM_PC2086,
- ROM_PC3086,
+ ROM_PC3086,
ROM_AMIXT, /*XT Clone with AMI BIOS*/
ROM_LTXT,
ROM_LXT3,
ROM_MEGAPC,
ROM_AMA932J,
ROM_AMI386SX,
+ ROM_SPC6000A,
+ ROM_SPC6033P,
ROM_AMI486,
ROM_WIN486,
ROM_PCI486,
ROM_LEDGE_MODELM,
ROM_HYUNDAI_SUPER286TR,
ROM_ITAUTEC_INFOWAYM,
+ ROM_DESKPRO,
+ ROM_VS440FX,
+ ROM_GA686BX,
+ ROM_PC5086,
ROM_MAX
};
GFX_EGA, /*Using IBM EGA BIOS*/
GFX_TVGA, /*Using Trident TVGA8900D BIOS*/
GFX_ET4000, /*Tseng ET4000*/
+ GFX_KASAN16VGA, /*Kasan Hangulmadang-16 (Tseng ET4000AX)*/
GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/
GFX_ET4000W32, /*Tseng ET4000/W32p (Diamond Stealth 32)*/
GFX_BAHAMAS64, /*S3 Vision864 (Paradise Bahamas 64)*/
GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/
GFX_VIRGE, /*S3 Virge*/
GFX_TGUI9440, /*Trident TGUI9440*/
- GFX_VGA, /*IBM VGA*/
+ GFX_VGA, /*IBM VGA*/
GFX_VGAEDGE16, /*ATI VGA Edge-16 (18800-1)*/
GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/
GFX_VGACHARGER, /*ATI VGA Charger (28800-5)*/
GFX_VIRGEDX, /*S3 Virge/DX*/
GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/
GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/
- GFX_INCOLOR, /* Hercules InColor */
+ GFX_INCOLOR, /* Hercules InColor */
GFX_COLORPLUS, /* Plantronics ColorPlus */
GFX_WY700, /* Wyse 700 */
GFX_GENIUS, /* MDSI Genius */
GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/
GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/
GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/
+ GFX_TVGA9000B, /*Trident TVGA9000B*/
+ GFX_BANSHEE, /*Voodoo Banshee - reference PCI board with SGRAM*/
+ GFX_CL_BANSHEE, /*Creative Labs Voodoo Blaster Banshee PCI - with SDRAM*/
+ GFX_VOODOO_3_2000, /*Voodoo 3 2000*/
+ GFX_VOODOO_3_3000, /*Voodoo 3 3000*/
GFX_MAX
};
#define MIN(a, b) ((a) < (b) ? (a) : (b))
void ide_padstr(char *str, const char *src, int len);
+
+void stop_emulation_now(void);
keyboard_at.output_port = val;
break;
+ case 0xd2: /*Write to keyboard output buffer*/
+ keyboard_at_adddata(val);
+ break;
+
case 0xd3: /*Write to mouse output buffer*/
#ifdef UAE
if (ps2_mouse_supported)
keyboard_at.want60 = 1;
break;
+ case 0xba:
+ if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM)
+ keyboard_at_adddata(0);
+ break;
+
/* T3100e commands not implemented:
* 0xB7: Emulate PS/2 keyboard
* 0xB8: Emulate AT keyboard */
break;
case 0xca: /*AMI - read keyboard mode*/
- keyboard_at_adddata(0x00); /*ISA mode*/
+ if (romset == ROM_GA686BX) /*TODO*/
+ keyboard_at_adddata(0x01); /*PS2 mode*/
+ else
+ keyboard_at_adddata(0x00); /*ISA mode*/
break;
case 0xcb: /*AMI - set keyboard mode*/
keyboard_at_adddata(0x00);
break;
- case 0xe8: /* Super-286TR: turbo ON */
- // TODO: 0xe8 is always followed by 0xba
- // TODO: I don't know where to call cpu_set_turbo(1) to avoid slow POST after ctrl-alt-del when on low speed (if this is the real behavior!)
- if (romset == ROM_HYUNDAI_SUPER286TR)
- cpu_set_turbo(1); // 12 MHz
- break;
-
- case 0xe9: /* Super-286TR: turbo OFF */
- if (romset == ROM_HYUNDAI_SUPER286TR)
- cpu_set_turbo(0); // 8 MHz
- break;
+ // AWARD BIOS: called after turbo ON/OFF in the
+ // Hyundai Super-286TR and probably other AWARD 286
+ // bioses. Related to the Turbo LEDs. Exact function
+ // can't be confirmed because the system in question
+ // has no such leds.
+ //case 0xe8: /* Turbo ON, always followed by 0xba */
+ //case 0xe9: /* Turbo OFF */
+ //break;
case 0xef: /*??? - sent by AMI486*/
break;
void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p);
void keyboard_at_adddata_mouse(uint8_t val);
+extern uint8_t mouse_queue[16];
extern int mouse_queue_start, mouse_queue_end;
extern int mouse_scan;
mem_mapping_t ram_mid_mapping;
mem_mapping_t ram_remapped_mapping;
mem_mapping_t bios_mapping[8];
-mem_mapping_t bios_high_mapping[8];
+mem_mapping_t bios_high_mapping[9];
static mem_mapping_t romext_mapping;
static uint8_t ff_array[0x1000];
uint32_t mem_logical_addr;
+void (*smram_enable)(void);
+void (*smram_disable)(void);
+
int mmuflush=0;
int mmu_perm=4;
{
if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb()))
{
- mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x20000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x24000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x28000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x2c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
}
- mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
-
- mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0);
- mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x30000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x34000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x38000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x3c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0);
+
+ mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x20000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x24000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x28000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x2c000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x30000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x34000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x38000 & biosmask), MEM_MAPPING_ROM, 0);
+ mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x3c000 & biosmask), MEM_MAPPING_ROM, 0);
+ if (biosmask == 0x3ffff)
+ mem_mapping_add(&bios_high_mapping[8], (AT && cpu_16bitbus) ? 0xfc0000 : 0xfffc0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0);
}
int mem_a20_key = 0, mem_a20_alt = 0;
memset(_mem_state, 0, sizeof(_mem_state));
mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
- mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+ if (romset == ROM_XI8088)
+ {
+ // Xi 8088 UMBs are selected by DIP Switches
+ mem_set_mem_state(0x0a0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+ mem_set_mem_state(0x0c0000, 0x08000, model_get_config_int("umb_c0000h_c7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
+ mem_set_mem_state(0x0c8000, 0x08000, model_get_config_int("umb_c8000h_cffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
+ mem_set_mem_state(0x0d0000, 0x08000, model_get_config_int("umb_d0000h_d7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
+ mem_set_mem_state(0x0d8000, 0x08000, model_get_config_int("umb_d8000h_dffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
+ mem_set_mem_state(0x0e0000, 0x08000, model_get_config_int("umb_e0000h_e7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
+ mem_set_mem_state(0x0e8000, 0x08000, model_get_config_int("umb_e8000h_effff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
+ mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+ }
+ else
+ {
+ mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+ }
mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL);
if (mem_size > 1024)
mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
}
}
- if (mem_size > 768)
- mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
+ if (mem_size > 768) // 640k - 768k is graphics RAM
+ mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
if (romset == ROM_IBMPS1_2011)
mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL);
FILE *romfopen(char *fn, char *mode);
extern mem_mapping_t bios_mapping[8];
-extern mem_mapping_t bios_high_mapping[8];
+extern mem_mapping_t bios_high_mapping[9];
extern mem_mapping_t ram_high_mapping;
extern mem_mapping_t ram_remapped_mapping;
int loadbios();
extern int purgeable_page_count;
+
+extern void (*smram_enable)(void);
+extern void (*smram_disable)(void);
#endif
#include "mouse.h"
#include "mouse_ps2.h"
#include "plat-mouse.h"
+#include "x86.h"
+#include "f82c710_upc.h"
int mouse_scan = 0;
{
mouse_ps2_t *mouse = (mouse_ps2_t *)p;
uint8_t packet[3] = {0x08, 0, 0};
-
+
if (!x && !y && !z && b == mouse->b)
return;
mouse->flags = 0;
mouse->mode = MOUSE_STREAM;
- keyboard_at_set_mouse(mouse_ps2_write, mouse);
-
+ if(romset == ROM_PC5086)
+ upc_set_mouse(mouse_ps2_write, mouse);
+ else
+ keyboard_at_set_mouse(mouse_ps2_write, mouse);
+
return mouse;
}
case ROM_PC200: f = nvrfopen("pc200.nvr", "rb"); break;
case ROM_PC2086: f = nvrfopen("pc2086.nvr", "rb"); break;
case ROM_PC3086: f = nvrfopen("pc3086.nvr", "rb"); break;
+ case ROM_PC5086: f = nvrfopen("pc5086.nvr", "rb"); break;
case ROM_PPC512: f = nvrfopen("ppc512.nvr", "rb"); break;
case ROM_IBMAT: f = nvrfopen("at.nvr", "rb"); break;
case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "rb"); break;
case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break;
case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); nvrmask = 127; break;
case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "rb"); nvrmask = 127; break;
+ case ROM_SPC6000A: f = nvrfopen("spc6000a.nvr", "rb"); nvrmask = 127; break;
+ case ROM_SPC6033P: f = nvrfopen("spc6033p.nvr", "rb"); nvrmask = 127; break;
case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); nvrmask = 127; break;
case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); nvrmask = 127; break;
case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); break;
case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break;
case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break;
case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); nvrmask = 127; break;
+ case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "rb"); nvrmask = 127; break;
+ case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "rb"); nvrmask = 127; break;
default: return;
}
case ROM_PC200: f = nvrfopen("pc200.nvr", "wb"); break;
case ROM_PC2086: f = nvrfopen("pc2086.nvr", "wb"); break;
case ROM_PC3086: f = nvrfopen("pc3086.nvr", "wb"); break;
+ case ROM_PC5086: f = nvrfopen("pc5086.nvr", "wb"); break;
case ROM_PPC512: f = nvrfopen("ppc512.nvr", "wb"); break;
case ROM_IBMAT: f = nvrfopen("at.nvr", "wb"); break;
case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "wb"); break;
case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break;
case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); break;
case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "wb"); break;
+ case ROM_SPC6000A: f = nvrfopen("spc6000a.nvr", "wb"); break;
+ case ROM_SPC6033P: f = nvrfopen("spc6033p.nvr", "wb"); break;
case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); break;
case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); break;
case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); break;
extern char nvr_path[512];
extern char logs_path[512];
extern char screenshots_path[512];
+extern char nvr_default_path[512];
void get_pcem_path(char *s, int size);
+void get_pcem_base_path(char *s, int size);
char get_path_separator();
void paths_init();
int dir_exists(char* path);
return;
uae_u16 w = pcem_linear_read_w(offset, pcem_mapping_linear_priv);
pcem_linear_write_w(offset, w, pcem_mapping_linear_priv);
-}
\ No newline at end of file
+}
+
+int model_get_config_int(const char *s)
+{
+ return 0;
+}
+char *model_get_config_string(const char *s)
+{
+ return NULL;
+}
+void upc_set_mouse(void (*mouse_write)(uint8_t, void*), void *p)
+{
+}
void pic_updatepending()
{
- if ((pic2.pend&~pic2.mask)&~pic2.mask2)
- pic.pend |= (1 << 2);
+ if (AT || romset == ROM_XI8088)
+ {
+ if ((pic2.pend&~pic2.mask)&~pic2.mask2)
+ pic.pend |= (1 << 2);
+ else
+ pic.pend &= ~(1 << 2);
+ pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
+ if (!((pic.mask | pic.mask2) & (1 << 2)))
+ pic_intpending |= ((pic2.pend&~pic2.mask)&~pic2.mask2);
+ }
else
- pic.pend &= ~(1 << 2);
- pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
- if (!((pic.mask | pic.mask2) & (1 << 2)))
- pic_intpending |= ((pic2.pend&~pic2.mask)&~pic2.mask2);
+ pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
+
/* pclog("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2);
pclog(" %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));*/
}
pic.ins&=~(1<<c);
pic_update_mask(&pic.mask2, pic.ins);
- if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
+ if ((AT || romset == ROM_XI8088) && c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
pic.pend |= (1 << 2);
pic_updatepending();
if ((AT || romset == ROM_XI8088) && num == (1 << 2))
num = 1 << 9;
// pclog("picint : %04X\n", num);
-// if (num == 0x10) pclog("PICINT 10\n");
- if (num>0xFF)
+ if ((AT || romset == ROM_XI8088) && num>0xFF)
{
pic2.pend|=(num>>8);
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
pic.pend |= (1 << 2);
}
- else
+ else if (num <= 0xff)
{
pic.pend|=num;
}
// pclog("INTC %04X %i\n", num, c);
pic_current[c]=0;
- if (num > 0xff)
+ if ((AT || romset == ROM_XI8088) && num > 0xff)
{
pic2.pend &= ~(num >> 8);
if (!((pic2.pend&~pic2.mask)&~pic2.mask2))
pic.pend &= ~(1 << 2);
}
- else
+ else if(num <= 0xff)
{
pic.pend&=~num;
}
{
uint8_t temp=pic.pend&~pic.mask;
int c;
- for (c = 0; c < 2; c++)
- {
- if (temp & (1 << c))
- {
- if (!(pic.level_sensitive & (1 << c)))
- pic.pend &= ~(1 << c);
- pic.ins |= (1 << c);
- pic_update_mask(&pic.mask2, pic.ins);
-
- pic_updatepending();
- if (!c)
- pit_set_gate(&pit2, 0, 0);
-
- if (pic.icw4 & 0x02)
- pic_autoeoi();
-
- return c+pic.vector;
- }
- }
- if (temp & (1 << 2))
+ for (c = 0; c < 8; c++)
{
- uint8_t temp2 = pic2.pend & ~pic2.mask;
- for (c = 0; c < 8; c++)
+ if ((AT || romset == ROM_XI8088) && (temp & (1 << 2)))
{
- if (temp2 & (1 << c))
+ uint8_t temp2 = pic2.pend & ~pic2.mask;
+ for (c = 0; c < 8; c++)
{
- if (!(pic2.level_sensitive & (1 << c)))
- pic2.pend &= ~(1 << c);
- pic2.ins |= (1 << c);
- pic_update_mask(&pic2.mask2, pic2.ins);
+ if (temp2 & (1 << c))
+ {
+ if (!(pic2.level_sensitive & (1 << c)))
+ pic2.pend &= ~(1 << c);
+ pic2.ins |= (1 << c);
+ pic_update_mask(&pic2.mask2, pic2.ins);
- if (!(pic2.level_sensitive & (1 << c)))
- pic.pend &= ~(1 << c);
- pic.ins |= (1 << 2); /*Cascade IRQ*/
- pic_update_mask(&pic.mask2, pic.ins);
+ if (!(pic2.level_sensitive & (1 << c)))
+ pic.pend &= ~(1 << c);
+ pic.ins |= (1 << 2); /*Cascade IRQ*/
+ pic_update_mask(&pic.mask2, pic.ins);
- pic_updatepending();
+ pic_updatepending();
- if (pic2.icw4 & 0x02)
- pic2_autoeoi();
+ if (pic2.icw4 & 0x02)
+ pic2_autoeoi();
- return c+pic2.vector;
+ return c+pic2.vector;
+ }
}
}
- }
- for (c = 3; c < 8; c++)
- {
- if (temp & (1 << c))
+ else if (temp & (1 << c))
{
if (!(pic.level_sensitive & (1 << c)))
pic.pend &= ~(1 << c);
if (pic.icw4 & 0x02)
pic_autoeoi();
-
return c+pic.vector;
}
}
serial1.irq = irq;
serial1.addr = addr;
}
+void serial1_set_has_fifo(int has_fifo)
+{
+ serial1.has_fifo = has_fifo;
+}
void serial1_remove()
{
io_removehandler(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1);
serial2.irq = irq;
serial2.addr = addr;
}
+void serial2_set_has_fifo(int has_fifo)
+{
+ serial2.has_fifo = has_fifo;
+}
void serial2_remove()
{
io_removehandler(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2);
void serial2_init(uint16_t addr, int irq, int has_fifo);
void serial1_set(uint16_t addr, int irq);
void serial2_set(uint16_t addr, int irq);
+void serial1_set_has_fifo(int has_fifo);
+void serial2_set_has_fifo(int has_fifo);
void serial1_remove();
void serial2_remove();
void serial_reset();
/*Cirrus Logic CL-GD5429 emulation*/
+//SR7.0 = "true packed-pixel memory addressing"
#include <stdlib.h>
#include "ibm.h"
#include "cpu.h"
int vidsys_ena;
} gd5429_t;
-#define GRB_X8_ADDRESSING (1 << 1)
-#define GRB_WRITEMODE_EXT (1 << 2)
-#define GRB_8B_LATCHES (1 << 3)
+#define GRB_X8_ADDRESSING (1 << 1)
+#define GRB_WRITEMODE_EXT (1 << 2)
+#define GRB_8B_LATCHES (1 << 3)
+#define GRB_ENHANCED_16BIT (1 << 4)
static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p);
static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p);
break;
case 0x07:
- if (gd5429->type >= CL_TYPE_GD5429)
+ if (gd5429->type >= CL_TYPE_GD5429) {
svga->set_reset_disabled = svga->seqregs[7] & 1;
+ }
+ svga->packed_chain4 = svga->seqregs[7] & 1;
+ svga_recalctimings(svga);
case 0x0f:
case 0x17:
//UAE
if (!(svga->gdcreg[6] & 1))
svga->fullchange = 2;
- if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
+ if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT)
+ addr <<= 4;
+ else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
addr <<= 3;
- else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4))
+ else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4))
{
writemask2 = 1 << (addr & 3);
addr &= ~3;
}
+ else if (svga->chain4)
+ {
+ writemask2 = 1 << (addr & 3);
+ addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
+ }
else if (svga->chain2_write)
{
writemask2 &= ~0xa;
{
addr <<= 2;
}
-
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return;
addr &= svga->vram_mask;
// if (svga_output) pclog("%08X\n", addr);
-
svga->changedvram[addr >> 12] = changeframecount;
switch (svga->writemode)
{
case 4:
- if (svga->gdcreg[0xb] & 0x10)
+ if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT)
{
// pclog("Writemode 4 : %X ", addr);
- addr <<= 2;
svga->changedvram[addr >> 12] = changeframecount;
// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]);
if (val & svga->seqregs[2] & 0x80)
break;
case 5:
- if (svga->gdcreg[0xb] & 0x10)
+ if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT)
{
// pclog("Writemode 5 : %X ", addr);
- addr <<= 2;
svga->changedvram[addr >> 12] = changeframecount;
// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]);
if (svga->seqregs[2] & 0x80)
egareads++;
#endif
- if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
+ if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT)
+ latch_addr = (addr << 4) & svga->decode_mask;
+ else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
latch_addr = (addr << 3) & svga->decode_mask;
else
latch_addr = (addr << 2) & svga->decode_mask;
- if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
+ if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT)
+ addr <<= 4;
+ else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
addr <<= 3;
- else if (svga->chain4 || svga->fb_only)
+ else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
{
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
return svga->vram[addr & svga->vram_mask];
}
+ else if (svga->chain4)
+ {
+ readplane = addr & 3;
+ addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
+ }
else if (svga->chain2_read)
{
readplane = (readplane & 2) | (addr & 1);
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
- if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48)
- return;
+ if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && svga->crtcreg != 0x39 && (svga->crtc[0x38] & 0xcc) != 0x48)
+ {
+ if (!((svga->crtc[0x39] & 0xe0) == 0xa0 && svga->crtcreg >= 0x40 && svga->crtcreg <= 0x6d))
+ return;
+ }
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
switch (svga->crtcreg)
case 0x31:
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
+ svga->force_dword_mode = val & 0x08;
break;
case 0x32:
svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask;
}
}
-#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
- else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
- else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \
+/*Remap address for chain-4/doubleword style layout*/
+static inline uint32_t dword_remap(uint32_t in_addr)
+{
+ return in_addr;
+}
+static inline uint32_t dword_remap_w(uint32_t in_addr)
+{
+ return in_addr;
+}
+static inline uint32_t dword_remap_l(uint32_t in_addr)
+{
+ return in_addr;
+}
+
+#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \
+ else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \
+ else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; \
if (vram_mask) \
dat = ((dat & rd_mask) == rd_mask);
-#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
- else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
- else dat = vram_l[(addr) & (s3->vram_mask >> 2)];
+#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \
+ else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \
+ else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)];
#define MIX { \
uint32_t old_dest_dat = dest_dat; \
#define WRITE(addr) if (s3->bpp == 0) \
{ \
- svga->vram[(addr) & s3->vram_mask] = dest_dat; \
- svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \
+ svga->vram[dword_remap(addr) & s3->vram_mask] = dest_dat; \
+ svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \
} \
else if (s3->bpp == 1) \
{ \
- vram_w[(addr) & (s3->vram_mask >> 1)] = dest_dat; \
- svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
+ vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dest_dat; \
+ svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
} \
else \
{ \
- vram_l[(addr) & (s3->vram_mask >> 2)] = dest_dat; \
- svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
+ vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dest_dat; \
+ svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
}
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3)
// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
for (x = 0; x < 64; x += 16)
{
- dat[0] = (svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_display_mask];
- dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_display_mask];
+ uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr);
+
+ dat[0] = (svga->vram[remapped_addr] << 8) | svga->vram[remapped_addr + 1];
+ dat[1] = (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3];
for (xx = 0; xx < 16; xx++)
{
if (offset >= svga->hwcursor_latch.x)
io_removehandlerx(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
io_removehandlerx(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
io_removehandlerx(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
- io_removehandlerx(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
+ io_removehandlerx(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
+ io_removehandlerx(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3);
io_removehandlerx(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3);
}
int virge_busy;
uint8_t subsys_stat, subsys_cntl;
+
+ uint8_t serialport;
+
uint32_t advfunc;
int vblank_irq;
} virge_t;
#define INT_3DF_EMP (1 << 6)
#define INT_MASK 0xff
+#define SERIAL_PORT_SCW (1 << 0)
+#define SERIAL_PORT_SDW (1 << 1)
+#define SERIAL_PORT_SCR (1 << 2)
+#define SERIAL_PORT_SDR (1 << 3)
+
static int virge_vga_vsync_enabled(virge_t *virge)
{
if ((virge->svga.crtc[0x32] & 0x10) && !(virge->svga.crtc[0x11] & 0x20) && virge->vblank_irq > 0)
}
else
mem_mapping_set_addrx(&virge->linear_mapping, virge->linear_base, virge->linear_size);
- if (svga->fb_only >= 0)
- svga->fb_only = 1;
+ svga->fb_only = 1;
}
else
{
mem_mapping_disablex(&virge->linear_mapping);
- if (svga->fb_only >= 0)
- svga->fb_only = 0;
+ svga->fb_only = 0;
}
pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
return s3_virge_in(addr & 0x3ff, p);
+
+#if 0
+ case 0xff20: case 0xff21:
+ ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR);
+ if ((virge->serialport & SERIAL_PORT_SCW) && ddc_read_clock())
+ ret |= SERIAL_PORT_SCR;
+ if ((virge->serialport & SERIAL_PORT_SDW) && ddc_read_data())
+ ret |= SERIAL_PORT_SDR;
+ return ret;
+#endif
}
return 0xff;
}
if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000)
{
if (virge->s3d.cmd_set & CMD_SET_MS)
- ((val >> 8) | (val << 8)) << 16;
+ val = ((val >> 8) | (val << 8)) << 16;
// if ((virge->svga.crtc[0x54] & 3) == 1)
// ((val >> 8) | (val << 8)) << 16;
s3_virge_bitblt(virge, 16, val);
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
s3_virge_out(addr & 0x3ff, val, p);
break;
- }
-
+ case 0xff20:
+ virge->serialport = val;
+ //ddc_i2c_change((val & SERIAL_PORT_SCW) ? 1 : 0, (val & SERIAL_PORT_SDW) ? 1 : 0);
+ break;
+ }
}
static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
{
{
s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD);
}
- else
+ else switch (addr & 0xfffe)
{
+ default:
s3_virge_mmio_write(addr, val, p);
s3_virge_mmio_write(addr + 1, val >> 8, p);
+ break;
+
+ case 0xff20:
+ s3_virge_mmio_write(addr, val, p);
+ break;
}
}
static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
// s3_virge_triangle(virge);
break;
+
+ case 0xff20:
+ s3_virge_mmio_write(addr, val, p);
+ break;
}
}
virge->fifo_not_full_event = thread_create_event();
virge->fifo_thread = thread_create(fifo_thread, virge);
+ //ddc_init();
+
+ //TODO ViRGE does not use packed chain4
+ virge->svga.packed_chain4 = 1;
return virge;
}
virge->svga.crtc[0x6c] = 0x01;
- virge->svga.fb_only = -1;
-
virge->is_375 = 1;
virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
virge->wake_fifo_thread = thread_create_event();
virge->fifo_not_full_event = thread_create_event();
virge->fifo_thread = thread_create(fifo_thread, virge);
-
+
+ //ddc_init();
+
+ //TODO ViRGE does not use packed chain4
+ virge->svga.packed_chain4 = 1;
+
return virge;
}
{
return svga_pri;
}
-
void svga_set_override(svga_t *svga, int val)
{
if (svga->override && !val)
case 4:
svga->chain2_write = !(val & 4);
svga->chain4 = val & 8;
- svga->fast = ((svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4) || svga->fb_only < 0;
+ svga->fast = ((svga->gdcreg[8] == 0xff || svga->gdcreg[8] == 0) && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) &&
+ ((svga->chain4 && svga->packed_chain4) || svga->fb_only);
break;
}
break;
case 7: svga->colournocare=val; break;
}
svga->gdcreg[svga->gdcaddr & 15] = val;
- svga->fast = ((svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4) || svga->fb_only < 0;;
+ svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) &&
+ ((svga->chain4 && svga->packed_chain4) || svga->fb_only);
if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1))
svga_recalctimings(svga);
break;
if (svga->dispofftime < TIMER_USEC)
svga->dispofftime = TIMER_USEC;
-// pclog("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock);
-// pclog("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart);
-// pclog("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]);
+ svga_recalc_remap_func(svga);
+/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock);
+ printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart);
+ printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]);
-// pclog("svga->render %08X\n", svga->render);
+ pclog("svga->render %08X\n", svga->render);*/
}
extern int cyc_total;
svga->hwcursor_draw = hwcursor_draw;
svga->overlay_draw = overlay_draw;
svga->hwcursor.ysize = 64;
+ svga->ksc5601_english_font_type = 0;
svga_recalctimings(svga);
mem_mapping_addx(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga);
addr += svga->write_bank;
if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
- if (svga->chain4 || svga->fb_only)
+ if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
{
writemask2=1<<(addr&3);
addr&=~3;
}
+ else if (svga->chain4)
+ {
+ writemask2 = 1 << (addr & 3);
+ addr &= ~3;
+ addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
+ }
else if (svga->chain2_write)
{
writemask2 &= ~0xa;
// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
// pclog("%i\n", svga->readmode);
- if (svga->chain4 || svga->fb_only)
+ if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
{
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
svga->ld = svga->vram[latch_addr | 0x3];
return svga->vram[addr & svga->vram_mask];
}
+ else if (svga->chain4)
+ {
+ readplane = addr & 3;
+ addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
+ }
else if (svga->chain2_read)
{
readplane = (readplane & 2) | (addr & 1);
if (!(svga->gdcreg[6] & 1))
svga->fullchange = 2;
- if (svga->chain4 || svga->fb_only)
+ if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
{
writemask2=1<<(addr&3);
addr&=~3;
}
+ else if (svga->chain4)
+ {
+ writemask2 = 1 << (addr & 3);
+ addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
+ }
else if (svga->chain2_write)
{
writemask2 &= ~0xa;
egareads++;
#endif
- if (svga->chain4 || svga->fb_only)
+ if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
{
addr &= svga->decode_mask;
if (addr >= svga->vram_max)
return 0xff;
return svga->vram[addr & svga->vram_mask];
}
+ else if (svga->chain4)
+ {
+ readplane = addr & 3;
+ addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
+ }
else if (svga->chain2_read)
{
readplane = (readplane & 2) | (addr & 1);
svga_t *svga = (svga_t *)p;
char temps[128];
- if (svga->chain4) strcpy(temps, "SVGA chained ");
- else strcpy(temps, "SVGA unchained ");
+ if (svga->chain4) strcpy(temps, "SVGA chained (possibly mode 13h) ");
+ else strcpy(temps, "SVGA unchained (possibly mode-X) ");
strncat(s, temps, max_len);
if (!svga->video_bpp) strcpy(temps, "SVGA in text mode ");
void *p;
uint8_t ksc5601_sbyte_mask;
-
+ uint8_t ksc5601_udc_area_msb[2];
+ int ksc5601_swap_mode;
+ uint16_t ksc5601_english_font_type;
+
int vertical_linedbl;
int horizontal_linedbl;
/*Used to implement CRTC[0x17] bit 2 hsync divisor*/
int hsync_divisor;
+ /*Tseng-style chain4 mode - CRTC dword mode is the same as byte mode, chain4
+ addresses are shifted to match*/
+ int packed_chain4;
+
+ /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/
+ int force_dword_mode;
+
+ int remap_required;
+ uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr);
+
bool swaprb;
} svga_t;
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
+#include "vid_svga_render_remap.h"
-void svga_render_null(svga_t* svga)
+void svga_render_null(svga_t *svga)
{
- if (svga->firstline_draw == 4000)
- svga->firstline_draw = svga->displine;
- svga->lastline_draw = svga->displine;
+ if (svga->firstline_draw == 4000)
+ svga->firstline_draw = svga->displine;
+ svga->lastline_draw = svga->displine;
}
void svga_render_blank(svga_t *svga)
for (x = 0; x < svga->hdisp; x += xinc)
{
+ uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
+
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
- chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
- attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
+ chr = svga->vram[addr];
+ attr = svga->vram[addr+1];
+
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);
for (x = 0; x < svga->hdisp; x += xinc)
{
+ uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
+
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
- chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
- attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
+ chr = svga->vram[addr];
+ attr = svga->vram[addr+1];
+
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);
for (x = 0; x < svga->hdisp; x += xinc)
{
+ uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
+
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
- chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
- nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask];
- attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
+ chr = svga->vram[addr];
+ nextchr = svga->vram[addr + 8];
+ attr = svga->vram[addr + 1];
if (drawcursor)
{
if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80))
{
- if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
- dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc];
+ if((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff))
+ dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc];
else if(nextchr & 0x80)
+ {
+ if(svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff))
+ {
+ if(chr >= 0x80 && chr < 0x99) chr += 0x30;
+ else if(chr >= 0xB0 && chr < 0xC9) chr -= 0x30;
+ }
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc];
+ }
else
dat = 0xFF;
}
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);
- dat = svga->vram[charaddr + (svga->sc << 2)];
+ if ((svga->ksc5601_english_font_type >> 8) == 1) dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)][((chr & 1) << 4) | svga->sc];
+ else dat = svga->vram[charaddr + (svga->sc << 2)];
}
if (svga->seqregs[1] & 1)
{
}
}
- if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
- dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16];
+ if((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff))
+ dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16];
else if(nextchr & 0x80)
+ {
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16];
+ }
else
dat = 0xFF;
if (svga->seqregs[1] & 1)
void svga_render_2bpp_lowres(svga_t *svga)
{
- int changed_offset;
-
- changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
- if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = ((8 - svga->scrollcache) << 1) + 16;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x += 16)
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 16)
{
+ uint32_t addr = svga->remap_func(svga, svga->ma);
uint8_t dat[2];
- dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000];
- dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1];
+ dat[0] = svga->vram[addr];
+ dat[1] = svga->vram[addr + 1];
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
void svga_render_2bpp_highres(svga_t *svga)
{
- int changed_offset;
-
- changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
-
- if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - svga->scrollcache) + 24;
for (x = 0; x <= svga->hdisp; x += 8)
{
+ uint32_t addr = svga->remap_func(svga, svga->ma);
uint8_t dat[2];
- dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000];
- dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1];
+ dat[0] = svga->vram[addr];
+ dat[1] = svga->vram[addr + 1];
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
- p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
- p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
- p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
- p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
- p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
- p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
- p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
- p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
-
- p += 8;
+ *p++ = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
+ *p++ = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
+ *p++ = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
+ *p++ = svga->pallook[svga->egapal[dat[0] & 3]];
+ *p++ = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
+ *p++ = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
+ *p++ = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
+ *p++ = svga->pallook[svga->egapal[dat[1] & 3]];
}
}
}
void svga_render_4bpp_lowres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = ((8 - svga->scrollcache) << 1) + 16;
{
uint8_t edat[4];
uint8_t dat;
+ uint32_t addr = svga->remap_func(svga, svga->ma);
- *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
+ *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
void svga_render_4bpp_highres(svga_t *svga)
{
- int changed_offset;
-
- changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
-
- if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - svga->scrollcache) + 24;
{
uint8_t edat[4];
uint8_t dat;
+ uint32_t addr = svga->remap_func(svga, svga->ma);
- *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]);
+ *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
- p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
- p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
- p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
- p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
- p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
-
- p += 8;
+ *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
+ *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
}
}
}
void svga_render_8bpp_lowres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 8)
+ if (!svga->remap_required)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
-
- p[0] = p[1] = svga->pallook[dat & 0xff];
- p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff];
- p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff];
- p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff];
-
- svga->ma += 4;
- p += 8;
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 8)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+
+ p[0] = p[1] = svga->pallook[dat & 0xff];
+ p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff];
+ p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff];
+ p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff];
+
+ svga->ma += 4;
+ p += 8;
+ }
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 8)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ p[0] = p[1] = svga->pallook[dat & 0xff];
+ p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff];
+ p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff];
+ p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff];
+
+ svga->ma += 4;
+ p += 8;
+ }
}
svga->ma &= svga->vram_display_mask;
}
void svga_render_8bpp_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
- if (svga->firstline_draw == 4000)
+ if (svga->firstline_draw == 4000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x += 8)
+ if (!svga->remap_required)
+ {
+ for (x = 0; x <= svga->hdisp; x += 8)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ *p++ = svga->pallook[dat & 0xff];
+ *p++ = svga->pallook[(dat >> 8) & 0xff];
+ *p++ = svga->pallook[(dat >> 16) & 0xff];
+ *p++ = svga->pallook[(dat >> 24) & 0xff];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma+4) & svga->vram_display_mask]);
+ *p++ = svga->pallook[dat & 0xff];
+ *p++ = svga->pallook[(dat >> 8) & 0xff];
+ *p++ = svga->pallook[(dat >> 16) & 0xff];
+ *p++ = svga->pallook[(dat >> 24) & 0xff];
+
+ svga->ma += 8;
+ }
+ }
+ else
{
- uint32_t dat;
- dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
- p[0] = svga->pallook[dat & 0xff];
- p[1] = svga->pallook[(dat >> 8) & 0xff];
- p[2] = svga->pallook[(dat >> 16) & 0xff];
- p[3] = svga->pallook[(dat >> 24) & 0xff];
-
- dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
- p[4] = svga->pallook[dat & 0xff];
- p[5] = svga->pallook[(dat >> 8) & 0xff];
- p[6] = svga->pallook[(dat >> 16) & 0xff];
- p[7] = svga->pallook[(dat >> 24) & 0xff];
+ for (x = 0; x <= svga->hdisp; x += 4)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ svga->ma += 4;
- svga->ma += 8;
- p += 8;
+ *p++ = svga->pallook[dat & 0xff];
+ *p++ = svga->pallook[(dat >> 8) & 0xff];
+ *p++ = svga->pallook[(dat >> 16) & 0xff];
+ *p++ = svga->pallook[(dat >> 24) & 0xff];
+ }
}
+
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_15bpp_lowres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 4)
+ if (!svga->remap_required)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + x) & svga->vram_display_mask]);
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 4)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
- p[x] = p[x + 1] = video_15to32[dat & 0xffff];
- p[x + 2] = p[x + 3] = video_15to32[dat >> 16];
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+ }
+ svga->ma += x << 1;
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 2)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ svga->ma += 4;
+ }
}
- svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_15bpp_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x += 8)
+ if (!svga->remap_required)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
- p[x] = video_15to32[dat & 0xffff];
- p[x + 1] = video_15to32[dat >> 16];
+ for (x = 0; x <= svga->hdisp; x += 8)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
- p[x + 2] = video_15to32[dat & 0xffff];
- p[x + 3] = video_15to32[dat >> 16];
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
- p[x + 4] = video_15to32[dat & 0xffff];
- p[x + 5] = video_15to32[dat >> 16];
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+ }
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
- p[x + 6] = video_15to32[dat & 0xffff];
- p[x + 7] = video_15to32[dat >> 16];
+ svga->ma += x << 1;
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp; x += 2)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_15to32[dat & 0xffff];
+ *p++ = video_15to32[dat >> 16];
+
+ svga->ma += 4;
+ }
}
- svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_16bpp_lowres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - (svga->scrollcache & 6)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 4)
+ if (!svga->remap_required)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + x) & svga->vram_display_mask]);
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 4)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
- p[x] = p[x + 1] = video_16to32[dat & 0xffff];
- p[x + 2] = p[x + 3] = video_16to32[dat >> 16];
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+ }
+ svga->ma += x << 1;
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 2)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ svga->ma += 4;
+ }
}
- svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_16bpp_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x += 8)
+ if (!svga->remap_required)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
- p[x] = video_16to32[dat & 0xffff];
- p[x + 1] = video_16to32[dat >> 16];
-
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
- p[x + 2] = video_16to32[dat & 0xffff];
- p[x + 3] = video_16to32[dat >> 16];
+ for (x = 0; x <= svga->hdisp; x += 8)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
- p[x + 4] = video_16to32[dat & 0xffff];
- p[x + 5] = video_16to32[dat >> 16];
+ dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+ }
- dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
- p[x + 6] = video_16to32[dat & 0xffff];
- p[x + 7] = video_16to32[dat >> 16];
+ svga->ma += x << 1;
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp; x += 2)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = video_16to32[dat & 0xffff];
+ *p++ = video_16to32[dat >> 16];
+
+ svga->ma += 4;
+ }
}
- svga->ma += x << 1;
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_24bpp_lowres(svga_t *svga)
{
- int x, offset;
- uint32_t fg;
-
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
+ int x;
+ int offset = (8 - (svga->scrollcache & 6)) + 24;
+ uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
+
if (svga->firstline_draw == 4000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- offset = (8 - (svga->scrollcache & 6)) + 24;
-
- if (svga->swaprb) {
- for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++) {
- fg = svga->vram[svga->ma + 2] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 0] << 16);
- svga->ma += 3;
- svga->ma &= svga->vram_display_mask;
- ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
- }
- } else {
- for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
- {
- fg = svga->vram[svga->ma] | (svga->vram[(svga->ma + 1) & svga->vram_display_mask] << 8) | (svga->vram[(svga->ma + 2) & svga->vram_display_mask] << 16);
- svga->ma += 3;
- svga->ma &= svga->vram_display_mask;
- ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
- }
+ if (!svga->remap_required)
+ {
+ if (svga->swaprb) {
+
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
+ {
+ uint32_t fg = svga->vram[svga->ma + 2] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 0] << 16);
+ svga->ma += 3;
+ svga->ma &= svga->vram_display_mask;
+ p[0] = p[1] = fg;
+
+ svga->ma += 12;
+ p += 8;
+ }
+
+ } else {
+
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
+ {
+ uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
+ uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
+
+ p[0] = p[1] = dat0 & 0xffffff;
+ p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ p[6] = p[7] = dat2 >> 8;
+
+ svga->ma += 12;
+ p += 8;
+ }
+ }
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x += 4)
+ {
+ uint32_t dat0, dat1, dat2;
+ uint32_t addr;
+
+ addr = svga->remap_func(svga, svga->ma);
+ dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 4);
+ dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 8);
+ dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ p[0] = p[1] = dat0 & 0xffffff;
+ p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ p[6] = p[7] = dat2 >> 8;
+
+ svga->ma += 12;
+ p += 8;
+ }
}
}
}
void svga_render_24bpp_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- if (svga->swaprb) {
- uint32_t dat;
- for (x = 0; x <= svga->hdisp; x++)
- {
- dat = svga->vram[(svga->ma + 2) &svga->vram_display_mask] | (svga->vram[(svga->ma + 1) & svga->vram_display_mask] << 8) | (svga->vram[svga->ma + 0] << 16);
- p[x] = dat;
- svga->ma += 3;
- svga->ma &= svga->vram_display_mask;
- }
- } else {
- if ((svga->ma & svga->vram_display_mask) + svga->hdisp * 3 + 3 > svga->vram_display_mask) {
- for (x = 0; x <= svga->hdisp; x++) {
- uint32_t dat = (svga->vram[(svga->ma + 0) & svga->vram_display_mask] << 0) |
- (svga->vram[(svga->ma + 1) & svga->vram_display_mask] << 8) |
- (svga->vram[(svga->ma + 2) & svga->vram_display_mask] << 16);
- p[x] = dat;
- svga->ma += 3;
- }
- } else {
- for (x = 0; x <= svga->hdisp; x += 4) {
- uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
- p[x] = dat & 0xffffff;
-
- dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]);
- p[x + 1] = dat & 0xffffff;
-
- dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]);
- p[x + 2] = dat & 0xffffff;
+ if (!svga->remap_required)
+ {
+ for (x = 0; x <= svga->hdisp; x += 4)
+ {
+ uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
+ uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
+ uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
- dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]);
- p[x + 3] = dat & 0xffffff;
+ *p++ = dat0 & 0xffffff;
+ *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ *p++ = dat2 >> 8;
- svga->ma += 12;
+ svga->ma += 12;
+ }
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp; x += 4)
+ {
+ uint32_t dat0, dat1, dat2;
+ uint32_t addr;
+
+ addr = svga->remap_func(svga, svga->ma);
+ dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 4);
+ dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ addr = svga->remap_func(svga, svga->ma + 8);
+ dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+
+ *p++ = dat0 & 0xffffff;
+ *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
+ *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
+ *p++ = dat2 >> 8;
+
+ svga->ma += 12;
}
- }
}
svga->ma &= svga->vram_display_mask;
}
void svga_render_32bpp_lowres(svga_t *svga)
{
- int x, offset;
- uint32_t fg;
-
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
+ int x;
+ int offset = (8 - (svga->scrollcache & 6)) + 24;
+ uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
+
if (svga->firstline_draw == 4000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- offset = (8 - (svga->scrollcache & 6)) + 24;
-
- for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
+ if (!svga->remap_required)
{
- fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
- svga->ma += 4;
- svga->ma &= svga->vram_display_mask;
- ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ *p++ = dat & 0xffffff;
+ *p++ = dat & 0xffffff;
+ }
+ svga->ma += x * 4;
+ }
+ else
+ {
+ for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr]);
+ *p++ = dat & 0xffffff;
+ *p++ = dat & 0xffffff;
+ svga->ma += 4;
+ }
}
+ svga->ma &= svga->vram_display_mask;
}
}
91%*/
void svga_render_32bpp_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x++)
+ if (!svga->remap_required)
+ {
+ for (x = 0; x <= svga->hdisp; x++)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ *p++ = dat & 0xffffff;
+ }
+ svga->ma += x * 4;
+ }
+ else
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
- p[x] = dat & 0xffffff;
+ for (x = 0; x <= svga->hdisp; x++)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ *p++ = dat & 0xffffff;
+ svga->ma += 4;
+ }
}
- svga->ma += 4;
+
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_ABGR8888_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
-
- if (svga->firstline_draw == 4000)
+
+ if (svga->firstline_draw == 4000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x++)
+ if (!svga->remap_required)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
- p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
+ for (x = 0; x <= svga->hdisp; x++)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
+ }
+ svga->ma += x * 4;
}
- svga->ma += 4;
+ else
+ {
+ for (x = 0; x <= svga->hdisp; x++)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
+ svga->ma += 4;
+ }
+ }
+
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_RGBA8888_highres(svga_t *svga)
{
- if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
+ uint32_t changed_addr = svga->remap_func(svga, svga->ma);
+
+ if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
{
int x;
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
-
- if (svga->firstline_draw == 4000)
+
+ if (svga->firstline_draw == 4000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
- for (x = 0; x <= svga->hdisp; x++)
+ if (!svga->remap_required)
+ {
+ for (x = 0; x <= svga->hdisp; x++)
+ {
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ *p++ = dat >> 8;
+ }
+ svga->ma += x * 4;
+ }
+ else
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
- p[x] = dat >> 8;
+ for (x = 0; x <= svga->hdisp; x++)
+ {
+ uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
+ *p++ = dat >> 8;
+ svga->ma += 4;
+ }
}
- svga->ma += 4;
+
svga->ma &= svga->vram_display_mask;
}
}
extern uint8_t edatlookup[4][4];
-void svga_render_null(svga_t* svga);
+void svga_recalc_remap_func(svga_t *svga);
+
+void svga_render_null(svga_t *svga);
void svga_render_blank(svga_t *svga);
void svga_render_text_40(svga_t *svga);
void svga_render_text_80(svga_t *svga);
--- /dev/null
+/*Variables :
+ byte/word/doubleword mode
+ word has MA13/MA15->MA0
+ ET4000 treats doubleword as byte
+ row 0 -> MA13
+ row 1 -> MA14
+*/
+
+//S3 - enhanced mode mappings CR31.3 can force doubleword mode
+//Cirrus Logic handles SVGA writes seperately
+//S3, CL, TGUI blitters need checking
+
+//CL, S3, Mach64, ET4000, Banshee, TGUI all okay
+//Still to check - ViRGE, HT216
+#define VAR_BYTE_MODE (0 << 0)
+#define VAR_WORD_MODE_MA13 (1 << 0)
+#define VAR_WORD_MODE_MA15 (2 << 0)
+#define VAR_DWORD_MODE (3 << 0)
+#define VAR_MODE_MASK (3 << 0)
+#define VAR_ROW0_MA13 (1 << 2)
+#define VAR_ROW1_MA14 (1 << 3)
+
+#define ADDRESS_REMAP_FUNC(nr) \
+ static uint32_t address_remap_func_ ## nr(svga_t *svga, uint32_t in_addr) \
+ { \
+ uint32_t out_addr; \
+ \
+ switch (nr & VAR_MODE_MASK) \
+ { \
+ case VAR_BYTE_MODE: \
+ out_addr = in_addr; \
+ break; \
+ \
+ case VAR_WORD_MODE_MA13: \
+ out_addr = ((in_addr << 1) & 0x1fff8) | \
+ ((in_addr >> 13) & 0x4) | \
+ (in_addr & ~0x1ffff); \
+ break; \
+ \
+ case VAR_WORD_MODE_MA15: \
+ out_addr = ((in_addr << 1) & 0x1fff8) | \
+ ((in_addr >> 15) & 0x4) | \
+ (in_addr & ~0x1ffff); \
+ break; \
+ \
+ case VAR_DWORD_MODE: \
+ out_addr = ((in_addr << 2) & 0x3fff0) | \
+ ((in_addr >> 14) & 0xc) | \
+ (in_addr & ~0x3ffff); \
+ break; \
+ } \
+ \
+ if (nr & VAR_ROW0_MA13) \
+ out_addr = (out_addr & ~(1 << (13+2))) | \
+ ((svga->sc & 1) ? (1 << (13+2)) : 0); \
+ if (nr & VAR_ROW1_MA14) \
+ out_addr = (out_addr & ~(1 << (14+2))) | \
+ ((svga->sc & 2) ? (1 << (14+2)) : 0); \
+ \
+ return out_addr; \
+ }
+
+ADDRESS_REMAP_FUNC(0)
+ADDRESS_REMAP_FUNC(1)
+ADDRESS_REMAP_FUNC(2)
+ADDRESS_REMAP_FUNC(3)
+ADDRESS_REMAP_FUNC(4)
+ADDRESS_REMAP_FUNC(5)
+ADDRESS_REMAP_FUNC(6)
+ADDRESS_REMAP_FUNC(7)
+ADDRESS_REMAP_FUNC(8)
+ADDRESS_REMAP_FUNC(9)
+ADDRESS_REMAP_FUNC(10)
+ADDRESS_REMAP_FUNC(11)
+ADDRESS_REMAP_FUNC(12)
+ADDRESS_REMAP_FUNC(13)
+ADDRESS_REMAP_FUNC(14)
+ADDRESS_REMAP_FUNC(15)
+
+static uint32_t (*address_remap_funcs[16])(svga_t *svga, uint32_t in_addr) =
+{
+ address_remap_func_0,
+ address_remap_func_1,
+ address_remap_func_2,
+ address_remap_func_3,
+ address_remap_func_4,
+ address_remap_func_5,
+ address_remap_func_6,
+ address_remap_func_7,
+ address_remap_func_8,
+ address_remap_func_9,
+ address_remap_func_10,
+ address_remap_func_11,
+ address_remap_func_12,
+ address_remap_func_13,
+ address_remap_func_14,
+ address_remap_func_15
+};
+
+void svga_recalc_remap_func(svga_t *svga)
+{
+ int func_nr;
+
+ if (svga->fb_only)
+ func_nr = 0;
+ else
+ {
+ if (svga->force_dword_mode)
+ func_nr = VAR_DWORD_MODE;
+ else if (svga->crtc[0x14] & (1 << 6))
+ func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE;
+ else if (svga->crtc[0x17] & (1 << 6))
+ func_nr = VAR_BYTE_MODE;
+ else if (svga->crtc[0x17] & (1 << 5))
+ func_nr = VAR_WORD_MODE_MA15;
+ else
+ func_nr = VAR_WORD_MODE_MA13;
+
+ if (!(svga->crtc[0x17] & (1 << 0)))
+ func_nr |= VAR_ROW0_MA13;
+ if (!(svga->crtc[0x17] & (1 << 1)))
+ func_nr |= VAR_ROW1_MA14;
+ }
+
+// pclog("svga_recalc_remap_func: fb_only=%i chain4=%i packed_chain4=%i crtc[14]=%02x crtc[17]=%02x func_nr=%i\n",
+// svga->fb_only, svga->chain4, svga->packed_chain4, svga->crtc[0x14], svga->crtc[0x17], func_nr);
+ svga->remap_required = (func_nr != 0);
+ svga->remap_func = address_remap_funcs[func_nr];
+}
memset(voodoo, 0, sizeof(voodoo_t));
voodoo->bilinear_enabled = device_get_config_int("bilinear");
+ voodoo->dithersub_enabled = device_get_config_int("dithersub");
voodoo->scrfilter = device_get_config_int("dacfilter");
voodoo->texture_size = device_get_config_int("texture_memory");
voodoo->texture_mask = (voodoo->texture_size << 20) - 1;
memset(voodoo, 0, sizeof(voodoo_t));
voodoo->bilinear_enabled = device_get_config_int("bilinear");
+ voodoo->dithersub_enabled = device_get_config_int("dithersub");
voodoo->scrfilter = device_get_config_int("dacfilter");
voodoo->render_threads = device_get_config_int("render_threads");
+
voodoo->odd_even_mask = voodoo->render_threads - 1;
#ifndef NO_CODEGEN
voodoo->use_recompiler = device_get_config_int("recompiler");
.type = CONFIG_BINARY,
.default_int = 1
},
+ {
+ .name = "dithersub",
+ .description = "Dither subtraction",
+ .type = CONFIG_BINARY,
+ .default_int = 1
+ },
{
.name = "dacfilter",
.description = "Screen Filter",
{
TYPE_BANSHEE = 0,
TYPE_V3_2000,
- TYPE_V3_3000,
- TYPE_V5_5500
+ TYPE_V3_3000
};
typedef struct banshee_t
#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12)
-#define VIDPROCCFG_VIDPROCON (1 << 0)
+#define VIDPROCCFG_VIDPROC_ENABLE (1 << 0)
#define VIDPROCCFG_CURSOR_MODE (1 << 1)
#define VIDPROCCFG_INTERLACE (1 << 3)
#define VIDPROCCFG_HALF_MODE (1 << 4)
#define VIDSERIAL_I2C_SCK_R (1 << 26)
#define VIDSERIAL_I2C_SDA_R (1 << 27)
+#define MISCINIT0_Y_ORIGIN_SWAP_SHIFT (18)
+#define MISCINIT0_Y_ORIGIN_SWAP_MASK (0xfff << MISCINIT0_Y_ORIGIN_SWAP_SHIFT)
+
static int banshee_vga_vsync_enabled(banshee_t *banshee)
{
if (!(banshee->svga.crtc[0x11] & 0x20) && (banshee->svga.crtc[0x11] & 0x10) && ((banshee->pciInit0 >> 18) & 1) != 0)
svga->interlace = 0;
// if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT)
- if (banshee->vidProcCfg & VIDPROCCFG_VIDPROCON)
+ if (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE)
{
// this is some VGA-only feature? G-REX driver sets it and still expects normal 640x480 display.
svga->lowres = 0;
svga->video_res_override = 0;
}
+ svga->fb_only = (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE);
+
svga->horizontal_linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
if (((svga->miscout >> 2) & 3) == 3)
case Video_vidProcCfg:
banshee->vidProcCfg = val;
- //pclog("vidProcCfg=%08x\n", val);
+// pclog("vidProcCfg=%08x\n", val);
banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT;
svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA;
svga->fullchange = changeframecount;
case 0x00: ret = 0x1a; break; /*3DFX*/
case 0x01: ret = 0x12; break;
- case 0x02: ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : (banshee->type == TYPE_V5_5500 ? 0x09 : 0x05); break;
+ case 0x02: ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; break;
case 0x03: ret = 0x00; break;
case 0x04: ret = banshee->pci_regs[0x04] & 0x27; break;
{
banshee_t *banshee = (banshee_t *)p;
// svga_t *svga = &banshee->svga;
- uint32_t basemask = banshee->type == TYPE_V5_5500 ? 0xfc : 0xfe;
+ uint32_t basemask = 0xfe;
if (func)
return;
.type = CONFIG_BINARY,
.default_int = 1
},
+ {
+ .name = "dithersub",
+ .description = "Dither subtraction",
+ .type = CONFIG_BINARY,
+ .default_int = 1
+ },
{
.name = "dacfilter",
.description = "Screen Filter",
.type = CONFIG_BINARY,
.default_int = 1
},
+ {
+ .name = "dithersub",
+ .description = "Dither subtraction",
+ .type = CONFIG_BINARY,
+ .default_int = 1
+ },
{
.name = "dacfilter",
.description = "Screen Filter",
banshee->pci_regs[0x2e] = 0x3a;
banshee->pci_regs[0x2f] = 0x00;
break;
-
- case TYPE_V5_5500:
- banshee->pci_regs[0x2c] = 0x1a;
- banshee->pci_regs[0x2d] = 0x12;
- banshee->pci_regs[0x2e] = 0x09;
- banshee->pci_regs[0x2f] = 0x00;
- break;
-
}
banshee->svga.vblank_start = banshee_vblank_start;
}
static void *v3_3000_init()
{
- return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3);
-}
-static void *v5_5500_init()
-{
- return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V5_5500, VOODOO_3);
+ return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3);
}
static int banshee_available()
banshee_add_status_info,
banshee_sdram_config
};
-
-device_t voodoo_5_5500_device =
-{
- "Voodoo 5 5500 PCI",
- DEVICE_PCI,
- v5_5500_init,
- banshee_close,
- v3_3000_available,
- banshee_speed_changed,
- banshee_force_redraw,
- banshee_add_status_info,
- banshee_sdram_config
-};
extern device_t creative_voodoo_banshee_device;
extern device_t voodoo_3_2000_device;
extern device_t voodoo_3_3000_device;
-extern device_t voodoo_5_5500_device;
void banshee_set_overlay_addr(void *p, uint32_t addr);
if (params->fbzMode & (1 << 17))
{
- high_y = voodoo->v_disp - params->clipLowY;
- low_y = voodoo->v_disp - params->clipHighY;
+ int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap+1) : voodoo->v_disp;
+
+ high_y = y_origin - params->clipLowY;
+ low_y = y_origin - params->clipHighY;
}
else
{
int swap_pending;
int bilinear_enabled;
+ int dithersub_enabled;
int fb_size;
uint32_t fb_mask;
uint32_t tile_base, tile_stride;
int tile_stride_shift, tile_x, tile_x_real;
+ int y_origin_swap;
+
int read_time, write_time, burst_time;
pc_timer_t wake_timer;
},
};
+
+
+/* Dither subtraction */
+
+static const uint8_t dithersub_rb[256][4][4] =
+{
+ {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ },
+ {
+ {9, 5, 8, 4},
+ {3, 7, 2, 6},
+ {7, 3, 8, 4},
+ {1, 5, 2, 6},
+ },
+ {
+ {10, 6, 9, 5},
+ {4, 8, 3, 7},
+ {8, 4, 9, 5},
+ {2, 6, 3, 7},
+ },
+ {
+ {11, 7, 10, 6},
+ {5, 9, 4, 8},
+ {9, 5, 10, 6},
+ {3, 7, 4, 8},
+ },
+ {
+ {12, 8, 11, 7},
+ {6, 10, 5, 9},
+ {10, 6, 11, 7},
+ {4, 8, 5, 9},
+ },
+ {
+ {13, 9, 12, 8},
+ {7, 11, 6, 10},
+ {11, 7, 12, 8},
+ {5, 9, 6, 10},
+ },
+ {
+ {14, 10, 13, 9},
+ {8, 12, 7, 11},
+ {12, 8, 13, 9},
+ {6, 10, 7, 11},
+ },
+ {
+ {15, 11, 14, 10},
+ {9, 13, 8, 12},
+ {13, 9, 14, 10},
+ {7, 11, 8, 12},
+ },
+ {
+ {16, 12, 15, 11},
+ {10, 14, 9, 13},
+ {14, 10, 15, 11},
+ {8, 12, 9, 13},
+ },
+ {
+ {17, 13, 16, 12},
+ {11, 15, 10, 14},
+ {15, 11, 16, 12},
+ {9, 13, 10, 14},
+ },
+ {
+ {18, 14, 17, 13},
+ {12, 16, 11, 15},
+ {16, 12, 17, 13},
+ {10, 14, 11, 15},
+ },
+ {
+ {19, 15, 18, 14},
+ {13, 17, 12, 16},
+ {17, 13, 18, 14},
+ {11, 15, 12, 16},
+ },
+ {
+ {20, 16, 19, 15},
+ {14, 18, 13, 17},
+ {18, 14, 19, 15},
+ {12, 16, 13, 17},
+ },
+ {
+ {21, 17, 20, 16},
+ {15, 19, 14, 18},
+ {19, 15, 20, 16},
+ {13, 17, 14, 18},
+ },
+ {
+ {22, 18, 21, 17},
+ {16, 20, 15, 19},
+ {20, 16, 21, 17},
+ {14, 18, 15, 19},
+ },
+ {
+ {23, 19, 22, 18},
+ {17, 21, 16, 20},
+ {21, 17, 22, 18},
+ {15, 19, 16, 20},
+ },
+ {
+ {24, 20, 23, 19},
+ {18, 22, 17, 21},
+ {22, 18, 23, 19},
+ {16, 20, 17, 21},
+ },
+ {
+ {25, 21, 24, 20},
+ {19, 23, 18, 22},
+ {23, 19, 24, 20},
+ {17, 21, 18, 22},
+ },
+ {
+ {26, 22, 25, 21},
+ {20, 24, 19, 23},
+ {24, 20, 25, 21},
+ {18, 22, 19, 23},
+ },
+ {
+ {27, 23, 26, 22},
+ {21, 25, 20, 24},
+ {25, 21, 26, 22},
+ {19, 23, 20, 24},
+ },
+ {
+ {28, 24, 27, 23},
+ {22, 26, 21, 25},
+ {26, 22, 27, 23},
+ {20, 24, 21, 25},
+ },
+ {
+ {29, 25, 28, 24},
+ {23, 27, 22, 26},
+ {27, 23, 28, 24},
+ {21, 25, 22, 26},
+ },
+ {
+ {30, 26, 29, 25},
+ {24, 28, 23, 27},
+ {28, 24, 29, 25},
+ {22, 26, 23, 27},
+ },
+ {
+ {31, 27, 30, 26},
+ {25, 29, 24, 28},
+ {29, 25, 30, 26},
+ {23, 27, 24, 28},
+ },
+ {
+ {32, 28, 31, 27},
+ {26, 30, 25, 29},
+ {30, 26, 31, 27},
+ {24, 28, 25, 29},
+ },
+ {
+ {33, 29, 32, 28},
+ {27, 31, 26, 30},
+ {31, 27, 32, 28},
+ {25, 29, 26, 30},
+ },
+ {
+ {34, 30, 33, 29},
+ {28, 32, 27, 31},
+ {32, 28, 33, 29},
+ {26, 30, 27, 31},
+ },
+ {
+ {35, 31, 34, 30},
+ {29, 33, 28, 32},
+ {33, 29, 34, 30},
+ {27, 31, 28, 32},
+ },
+ {
+ {36, 32, 35, 31},
+ {30, 34, 29, 33},
+ {34, 30, 35, 31},
+ {28, 32, 29, 33},
+ },
+ {
+ {37, 33, 36, 32},
+ {31, 35, 30, 34},
+ {35, 31, 36, 32},
+ {29, 33, 30, 34},
+ },
+ {
+ {38, 34, 37, 33},
+ {32, 36, 31, 35},
+ {36, 32, 37, 33},
+ {30, 34, 31, 35},
+ },
+ {
+ {39, 35, 38, 34},
+ {33, 37, 32, 36},
+ {37, 33, 38, 34},
+ {31, 35, 32, 36},
+ },
+ {
+ {40, 36, 39, 35},
+ {34, 38, 33, 37},
+ {38, 34, 39, 35},
+ {32, 36, 33, 37},
+ },
+ {
+ {41, 37, 40, 36},
+ {35, 39, 34, 38},
+ {39, 35, 40, 36},
+ {33, 37, 34, 38},
+ },
+ {
+ {42, 38, 41, 37},
+ {36, 40, 35, 39},
+ {40, 36, 41, 37},
+ {34, 38, 35, 39},
+ },
+ {
+ {43, 39, 42, 38},
+ {37, 41, 36, 40},
+ {41, 37, 42, 38},
+ {35, 39, 36, 40},
+ },
+ {
+ {44, 40, 43, 39},
+ {38, 42, 37, 41},
+ {42, 38, 43, 39},
+ {36, 40, 37, 41},
+ },
+ {
+ {45, 41, 44, 40},
+ {39, 43, 38, 42},
+ {43, 39, 44, 40},
+ {37, 41, 38, 42},
+ },
+ {
+ {46, 42, 45, 41},
+ {40, 44, 39, 43},
+ {44, 40, 45, 41},
+ {38, 42, 39, 43},
+ },
+ {
+ {47, 43, 46, 42},
+ {41, 45, 40, 44},
+ {45, 41, 46, 42},
+ {39, 43, 40, 44},
+ },
+ {
+ {48, 44, 47, 43},
+ {42, 46, 41, 45},
+ {46, 42, 47, 43},
+ {40, 44, 41, 45},
+ },
+ {
+ {49, 45, 48, 44},
+ {43, 47, 42, 46},
+ {47, 43, 48, 44},
+ {41, 45, 42, 46},
+ },
+ {
+ {50, 46, 49, 45},
+ {44, 48, 43, 47},
+ {48, 44, 49, 45},
+ {42, 46, 43, 47},
+ },
+ {
+ {51, 47, 50, 46},
+ {45, 49, 44, 48},
+ {49, 45, 50, 46},
+ {43, 47, 44, 48},
+ },
+ {
+ {52, 48, 51, 47},
+ {46, 50, 45, 49},
+ {50, 46, 51, 47},
+ {44, 48, 45, 49},
+ },
+ {
+ {53, 49, 52, 48},
+ {47, 51, 46, 50},
+ {51, 47, 52, 48},
+ {45, 49, 46, 50},
+ },
+ {
+ {54, 50, 53, 49},
+ {48, 52, 47, 51},
+ {52, 48, 53, 49},
+ {46, 50, 47, 51},
+ },
+ {
+ {55, 51, 54, 50},
+ {49, 53, 48, 52},
+ {53, 49, 54, 50},
+ {47, 51, 48, 52},
+ },
+ {
+ {56, 52, 55, 51},
+ {50, 54, 49, 53},
+ {54, 50, 55, 51},
+ {48, 52, 49, 53},
+ },
+ {
+ {57, 53, 56, 52},
+ {51, 55, 50, 54},
+ {55, 51, 56, 52},
+ {49, 53, 50, 54},
+ },
+ {
+ {58, 54, 57, 53},
+ {52, 56, 51, 55},
+ {56, 52, 57, 53},
+ {50, 54, 51, 55},
+ },
+ {
+ {59, 55, 58, 54},
+ {53, 57, 52, 56},
+ {57, 53, 58, 54},
+ {51, 55, 52, 56},
+ },
+ {
+ {60, 56, 59, 55},
+ {54, 58, 53, 57},
+ {58, 54, 59, 55},
+ {52, 56, 53, 57},
+ },
+ {
+ {61, 57, 60, 56},
+ {55, 59, 54, 58},
+ {59, 55, 60, 56},
+ {53, 57, 54, 58},
+ },
+ {
+ {62, 58, 61, 57},
+ {56, 60, 55, 59},
+ {60, 56, 61, 57},
+ {54, 58, 55, 59},
+ },
+ {
+ {63, 59, 62, 58},
+ {57, 61, 56, 60},
+ {61, 57, 62, 58},
+ {55, 59, 56, 60},
+ },
+ {
+ {64, 60, 63, 59},
+ {58, 62, 57, 61},
+ {62, 58, 63, 59},
+ {56, 60, 57, 61},
+ },
+ {
+ {65, 61, 64, 60},
+ {59, 63, 58, 62},
+ {63, 59, 64, 60},
+ {57, 61, 58, 62},
+ },
+ {
+ {66, 62, 65, 61},
+ {60, 64, 59, 63},
+ {64, 60, 65, 61},
+ {58, 62, 59, 63},
+ },
+ {
+ {67, 63, 66, 62},
+ {61, 65, 60, 64},
+ {65, 61, 66, 62},
+ {59, 63, 60, 64},
+ },
+ {
+ {68, 64, 67, 63},
+ {62, 66, 61, 65},
+ {66, 62, 67, 63},
+ {60, 64, 61, 65},
+ },
+ {
+ {69, 65, 68, 64},
+ {63, 67, 62, 66},
+ {67, 63, 68, 64},
+ {61, 65, 62, 66},
+ },
+ {
+ {70, 66, 69, 65},
+ {64, 68, 63, 67},
+ {68, 64, 69, 65},
+ {62, 66, 63, 67},
+ },
+ {
+ {71, 67, 70, 66},
+ {65, 69, 64, 68},
+ {69, 65, 70, 66},
+ {63, 67, 64, 68},
+ },
+ {
+ {72, 68, 71, 67},
+ {66, 70, 65, 69},
+ {70, 66, 71, 67},
+ {64, 68, 65, 69},
+ },
+ {
+ {73, 69, 72, 68},
+ {67, 71, 66, 70},
+ {71, 67, 72, 68},
+ {65, 69, 66, 70},
+ },
+ {
+ {74, 70, 73, 69},
+ {68, 72, 67, 71},
+ {72, 68, 73, 69},
+ {66, 70, 67, 71},
+ },
+ {
+ {75, 71, 74, 70},
+ {69, 73, 68, 72},
+ {73, 69, 74, 70},
+ {67, 71, 68, 72},
+ },
+ {
+ {76, 72, 75, 71},
+ {70, 74, 69, 73},
+ {74, 70, 75, 71},
+ {68, 72, 69, 73},
+ },
+ {
+ {77, 73, 76, 72},
+ {71, 75, 70, 74},
+ {75, 71, 76, 72},
+ {69, 73, 70, 74},
+ },
+ {
+ {78, 74, 77, 73},
+ {72, 76, 71, 75},
+ {76, 72, 77, 73},
+ {70, 74, 71, 75},
+ },
+ {
+ {79, 75, 78, 74},
+ {73, 77, 72, 76},
+ {77, 73, 78, 74},
+ {71, 75, 72, 76},
+ },
+ {
+ {80, 76, 79, 75},
+ {74, 78, 73, 77},
+ {78, 74, 79, 75},
+ {72, 76, 73, 77},
+ },
+ {
+ {81, 77, 80, 76},
+ {75, 79, 74, 78},
+ {79, 75, 80, 76},
+ {73, 77, 74, 78},
+ },
+ {
+ {82, 78, 81, 77},
+ {76, 80, 75, 79},
+ {80, 76, 81, 77},
+ {74, 78, 75, 79},
+ },
+ {
+ {83, 79, 82, 78},
+ {77, 81, 76, 80},
+ {81, 77, 82, 78},
+ {75, 79, 76, 80},
+ },
+ {
+ {84, 80, 83, 79},
+ {78, 82, 77, 81},
+ {82, 78, 83, 79},
+ {76, 80, 77, 81},
+ },
+ {
+ {85, 81, 84, 80},
+ {79, 83, 78, 82},
+ {83, 79, 84, 80},
+ {77, 81, 78, 82},
+ },
+ {
+ {86, 82, 85, 81},
+ {80, 84, 79, 83},
+ {84, 80, 85, 81},
+ {78, 82, 79, 83},
+ },
+ {
+ {87, 83, 86, 82},
+ {81, 85, 80, 84},
+ {85, 81, 86, 82},
+ {79, 83, 80, 84},
+ },
+ {
+ {88, 84, 87, 83},
+ {82, 86, 81, 85},
+ {86, 82, 87, 83},
+ {80, 84, 81, 85},
+ },
+ {
+ {89, 85, 88, 84},
+ {83, 87, 82, 86},
+ {87, 83, 88, 84},
+ {81, 85, 82, 86},
+ },
+ {
+ {90, 86, 89, 85},
+ {84, 88, 83, 87},
+ {88, 84, 89, 85},
+ {82, 86, 83, 87},
+ },
+ {
+ {91, 87, 90, 86},
+ {85, 89, 84, 88},
+ {89, 85, 90, 86},
+ {83, 87, 84, 88},
+ },
+ {
+ {92, 88, 91, 87},
+ {86, 90, 85, 89},
+ {90, 86, 91, 87},
+ {84, 88, 85, 89},
+ },
+ {
+ {93, 89, 92, 88},
+ {87, 91, 86, 90},
+ {91, 87, 92, 88},
+ {85, 89, 86, 90},
+ },
+ {
+ {94, 90, 93, 89},
+ {88, 92, 87, 91},
+ {92, 88, 93, 89},
+ {86, 90, 87, 91},
+ },
+ {
+ {95, 91, 94, 90},
+ {89, 93, 88, 92},
+ {93, 89, 94, 90},
+ {87, 91, 88, 92},
+ },
+ {
+ {96, 92, 95, 91},
+ {90, 94, 89, 93},
+ {94, 90, 95, 91},
+ {88, 92, 89, 93},
+ },
+ {
+ {97, 93, 96, 92},
+ {91, 95, 90, 94},
+ {95, 91, 96, 92},
+ {89, 93, 90, 94},
+ },
+ {
+ {98, 94, 97, 93},
+ {92, 96, 91, 95},
+ {96, 92, 97, 93},
+ {90, 94, 91, 95},
+ },
+ {
+ {99, 95, 98, 94},
+ {93, 97, 92, 96},
+ {97, 93, 98, 94},
+ {91, 95, 92, 96},
+ },
+ {
+ {100, 96, 99, 95},
+ {94, 98, 93, 97},
+ {98, 94, 99, 95},
+ {92, 96, 93, 97},
+ },
+ {
+ {101, 97, 100, 96},
+ {95, 99, 94, 98},
+ {99, 95, 100, 96},
+ {93, 97, 94, 98},
+ },
+ {
+ {102, 98, 101, 97},
+ {96, 100, 95, 99},
+ {100, 96, 101, 97},
+ {94, 98, 95, 99},
+ },
+ {
+ {103, 99, 102, 98},
+ {97, 101, 96, 100},
+ {101, 97, 102, 98},
+ {95, 99, 96, 100},
+ },
+ {
+ {104, 100, 103, 99},
+ {98, 102, 97, 101},
+ {102, 98, 103, 99},
+ {96, 100, 97, 101},
+ },
+ {
+ {105, 101, 104, 100},
+ {99, 103, 98, 102},
+ {103, 99, 104, 100},
+ {97, 101, 98, 102},
+ },
+ {
+ {106, 102, 105, 101},
+ {100, 104, 99, 103},
+ {104, 100, 105, 101},
+ {98, 102, 99, 103},
+ },
+ {
+ {107, 103, 106, 102},
+ {101, 105, 100, 104},
+ {105, 101, 106, 102},
+ {99, 103, 100, 104},
+ },
+ {
+ {108, 104, 107, 103},
+ {102, 106, 101, 105},
+ {106, 102, 107, 103},
+ {100, 104, 101, 105},
+ },
+ {
+ {109, 105, 108, 104},
+ {103, 107, 102, 106},
+ {107, 103, 108, 104},
+ {101, 105, 102, 106},
+ },
+ {
+ {110, 106, 109, 105},
+ {104, 108, 103, 107},
+ {108, 104, 109, 105},
+ {102, 106, 103, 107},
+ },
+ {
+ {111, 107, 110, 106},
+ {105, 109, 104, 108},
+ {109, 105, 110, 106},
+ {103, 107, 104, 108},
+ },
+ {
+ {112, 108, 111, 107},
+ {106, 110, 105, 109},
+ {110, 106, 111, 107},
+ {104, 108, 105, 109},
+ },
+ {
+ {113, 109, 112, 108},
+ {107, 111, 106, 110},
+ {111, 107, 112, 108},
+ {105, 109, 106, 110},
+ },
+ {
+ {114, 110, 113, 109},
+ {108, 112, 107, 111},
+ {112, 108, 113, 109},
+ {106, 110, 107, 111},
+ },
+ {
+ {115, 111, 114, 110},
+ {109, 113, 108, 112},
+ {113, 109, 114, 110},
+ {107, 111, 108, 112},
+ },
+ {
+ {116, 112, 115, 111},
+ {110, 114, 109, 113},
+ {114, 110, 115, 111},
+ {108, 112, 109, 113},
+ },
+ {
+ {117, 113, 116, 112},
+ {111, 115, 110, 114},
+ {115, 111, 116, 112},
+ {109, 113, 110, 114},
+ },
+ {
+ {118, 114, 117, 113},
+ {112, 116, 111, 115},
+ {116, 112, 117, 113},
+ {110, 114, 111, 115},
+ },
+ {
+ {119, 115, 118, 114},
+ {113, 117, 112, 116},
+ {117, 113, 118, 114},
+ {111, 115, 112, 116},
+ },
+ {
+ {120, 116, 119, 115},
+ {114, 118, 113, 117},
+ {118, 114, 119, 115},
+ {112, 116, 113, 117},
+ },
+ {
+ {121, 117, 120, 116},
+ {115, 119, 114, 118},
+ {119, 115, 120, 116},
+ {113, 117, 114, 118},
+ },
+ {
+ {122, 118, 121, 117},
+ {116, 120, 115, 119},
+ {120, 116, 121, 117},
+ {114, 118, 115, 119},
+ },
+ {
+ {123, 119, 122, 118},
+ {117, 121, 116, 120},
+ {121, 117, 122, 118},
+ {115, 119, 116, 120},
+ },
+ {
+ {124, 120, 123, 119},
+ {118, 122, 117, 121},
+ {122, 118, 123, 119},
+ {116, 120, 117, 121},
+ },
+ {
+ {125, 121, 124, 120},
+ {119, 123, 118, 122},
+ {123, 119, 124, 120},
+ {117, 121, 118, 122},
+ },
+ {
+ {126, 122, 125, 121},
+ {120, 124, 119, 123},
+ {124, 120, 125, 121},
+ {118, 122, 119, 123},
+ },
+ {
+ {127, 123, 126, 122},
+ {121, 125, 120, 124},
+ {125, 121, 126, 122},
+ {119, 123, 120, 124},
+ },
+ {
+ {128, 124, 127, 123},
+ {122, 126, 121, 125},
+ {126, 122, 127, 123},
+ {120, 124, 121, 125},
+ },
+ {
+ {129, 125, 128, 124},
+ {123, 127, 122, 126},
+ {127, 123, 128, 124},
+ {121, 125, 122, 126},
+ },
+ {
+ {130, 126, 129, 125},
+ {124, 128, 123, 127},
+ {128, 124, 129, 125},
+ {122, 126, 123, 127},
+ },
+ {
+ {131, 127, 130, 126},
+ {125, 129, 124, 128},
+ {129, 125, 130, 126},
+ {123, 127, 124, 128},
+ },
+ {
+ {132, 128, 131, 127},
+ {126, 130, 125, 129},
+ {130, 126, 131, 127},
+ {124, 128, 125, 129},
+ },
+ {
+ {133, 129, 132, 128},
+ {127, 131, 126, 130},
+ {131, 127, 132, 128},
+ {125, 129, 126, 130},
+ },
+ {
+ {134, 130, 133, 129},
+ {128, 132, 127, 131},
+ {132, 128, 133, 129},
+ {126, 130, 127, 131},
+ },
+ {
+ {135, 131, 134, 130},
+ {129, 133, 128, 132},
+ {133, 129, 134, 130},
+ {127, 131, 128, 132},
+ },
+ {
+ {136, 132, 135, 131},
+ {130, 134, 129, 133},
+ {134, 130, 135, 131},
+ {128, 132, 129, 133},
+ },
+ {
+ {137, 133, 136, 132},
+ {131, 135, 130, 134},
+ {135, 131, 136, 132},
+ {129, 133, 130, 134},
+ },
+ {
+ {138, 134, 137, 133},
+ {132, 136, 131, 135},
+ {136, 132, 137, 133},
+ {130, 134, 131, 135},
+ },
+ {
+ {139, 135, 138, 134},
+ {133, 137, 132, 136},
+ {137, 133, 138, 134},
+ {131, 135, 132, 136},
+ },
+ {
+ {140, 136, 139, 135},
+ {134, 138, 133, 137},
+ {138, 134, 139, 135},
+ {132, 136, 133, 137},
+ },
+ {
+ {141, 137, 140, 136},
+ {135, 139, 134, 138},
+ {139, 135, 140, 136},
+ {133, 137, 134, 138},
+ },
+ {
+ {142, 138, 141, 137},
+ {136, 140, 135, 139},
+ {140, 136, 141, 137},
+ {134, 138, 135, 139},
+ },
+ {
+ {143, 139, 142, 138},
+ {137, 141, 136, 140},
+ {141, 137, 142, 138},
+ {135, 139, 136, 140},
+ },
+ {
+ {144, 140, 143, 139},
+ {138, 142, 137, 141},
+ {142, 138, 143, 139},
+ {136, 140, 137, 141},
+ },
+ {
+ {145, 141, 144, 140},
+ {139, 143, 138, 142},
+ {143, 139, 144, 140},
+ {137, 141, 138, 142},
+ },
+ {
+ {146, 142, 145, 141},
+ {140, 144, 139, 143},
+ {144, 140, 145, 141},
+ {138, 142, 139, 143},
+ },
+ {
+ {147, 143, 146, 142},
+ {141, 145, 140, 144},
+ {145, 141, 146, 142},
+ {139, 143, 140, 144},
+ },
+ {
+ {148, 144, 147, 143},
+ {142, 146, 141, 145},
+ {146, 142, 147, 143},
+ {140, 144, 141, 145},
+ },
+ {
+ {149, 145, 148, 144},
+ {143, 147, 142, 146},
+ {147, 143, 148, 144},
+ {141, 145, 142, 146},
+ },
+ {
+ {150, 146, 149, 145},
+ {144, 148, 143, 147},
+ {148, 144, 149, 145},
+ {142, 146, 143, 147},
+ },
+ {
+ {151, 147, 150, 146},
+ {145, 149, 144, 148},
+ {149, 145, 150, 146},
+ {143, 147, 144, 148},
+ },
+ {
+ {152, 148, 151, 147},
+ {146, 150, 145, 149},
+ {150, 146, 151, 147},
+ {144, 148, 145, 149},
+ },
+ {
+ {153, 149, 152, 148},
+ {147, 151, 146, 150},
+ {151, 147, 152, 148},
+ {145, 149, 146, 150},
+ },
+ {
+ {154, 150, 153, 149},
+ {148, 152, 147, 151},
+ {152, 148, 153, 149},
+ {146, 150, 147, 151},
+ },
+ {
+ {155, 151, 154, 150},
+ {149, 153, 148, 152},
+ {153, 149, 154, 150},
+ {147, 151, 148, 152},
+ },
+ {
+ {156, 152, 155, 151},
+ {150, 154, 149, 153},
+ {154, 150, 155, 151},
+ {148, 152, 149, 153},
+ },
+ {
+ {157, 153, 156, 152},
+ {151, 155, 150, 154},
+ {155, 151, 156, 152},
+ {149, 153, 150, 154},
+ },
+ {
+ {158, 154, 157, 153},
+ {152, 156, 151, 155},
+ {156, 152, 157, 153},
+ {150, 154, 151, 155},
+ },
+ {
+ {159, 155, 158, 154},
+ {153, 157, 152, 156},
+ {157, 153, 158, 154},
+ {151, 155, 152, 156},
+ },
+ {
+ {160, 156, 159, 155},
+ {154, 158, 153, 157},
+ {158, 154, 159, 155},
+ {152, 156, 153, 157},
+ },
+ {
+ {161, 157, 160, 156},
+ {155, 159, 154, 158},
+ {159, 155, 160, 156},
+ {153, 157, 154, 158},
+ },
+ {
+ {162, 158, 161, 157},
+ {156, 160, 155, 159},
+ {160, 156, 161, 157},
+ {154, 158, 155, 159},
+ },
+ {
+ {163, 159, 162, 158},
+ {157, 161, 156, 160},
+ {161, 157, 162, 158},
+ {155, 159, 156, 160},
+ },
+ {
+ {164, 160, 163, 159},
+ {158, 162, 157, 161},
+ {162, 158, 163, 159},
+ {156, 160, 157, 161},
+ },
+ {
+ {165, 161, 164, 160},
+ {159, 163, 158, 162},
+ {163, 159, 164, 160},
+ {157, 161, 158, 162},
+ },
+ {
+ {166, 162, 165, 161},
+ {160, 164, 159, 163},
+ {164, 160, 165, 161},
+ {158, 162, 159, 163},
+ },
+ {
+ {167, 163, 166, 162},
+ {161, 165, 160, 164},
+ {165, 161, 166, 162},
+ {159, 163, 160, 164},
+ },
+ {
+ {168, 164, 167, 163},
+ {162, 166, 161, 165},
+ {166, 162, 167, 163},
+ {160, 164, 161, 165},
+ },
+ {
+ {169, 165, 168, 164},
+ {163, 167, 162, 166},
+ {167, 163, 168, 164},
+ {161, 165, 162, 166},
+ },
+ {
+ {170, 166, 169, 165},
+ {164, 168, 163, 167},
+ {168, 164, 169, 165},
+ {162, 166, 163, 167},
+ },
+ {
+ {171, 167, 170, 166},
+ {165, 169, 164, 168},
+ {169, 165, 170, 166},
+ {163, 167, 164, 168},
+ },
+ {
+ {172, 168, 171, 167},
+ {166, 170, 165, 169},
+ {170, 166, 171, 167},
+ {164, 168, 165, 169},
+ },
+ {
+ {173, 169, 172, 168},
+ {167, 171, 166, 170},
+ {171, 167, 172, 168},
+ {165, 169, 166, 170},
+ },
+ {
+ {174, 170, 173, 169},
+ {168, 172, 167, 171},
+ {172, 168, 173, 169},
+ {166, 170, 167, 171},
+ },
+ {
+ {175, 171, 174, 170},
+ {169, 173, 168, 172},
+ {173, 169, 174, 170},
+ {167, 171, 168, 172},
+ },
+ {
+ {176, 172, 175, 171},
+ {170, 174, 169, 173},
+ {174, 170, 175, 171},
+ {168, 172, 169, 173},
+ },
+ {
+ {177, 173, 176, 172},
+ {171, 175, 170, 174},
+ {175, 171, 176, 172},
+ {169, 173, 170, 174},
+ },
+ {
+ {178, 174, 177, 173},
+ {172, 176, 171, 175},
+ {176, 172, 177, 173},
+ {170, 174, 171, 175},
+ },
+ {
+ {179, 175, 178, 174},
+ {173, 177, 172, 176},
+ {177, 173, 178, 174},
+ {171, 175, 172, 176},
+ },
+ {
+ {180, 176, 179, 175},
+ {174, 178, 173, 177},
+ {178, 174, 179, 175},
+ {172, 176, 173, 177},
+ },
+ {
+ {181, 177, 180, 176},
+ {175, 179, 174, 178},
+ {179, 175, 180, 176},
+ {173, 177, 174, 178},
+ },
+ {
+ {182, 178, 181, 177},
+ {176, 180, 175, 179},
+ {180, 176, 181, 177},
+ {174, 178, 175, 179},
+ },
+ {
+ {183, 179, 182, 178},
+ {177, 181, 176, 180},
+ {181, 177, 182, 178},
+ {175, 179, 176, 180},
+ },
+ {
+ {184, 180, 183, 179},
+ {178, 182, 177, 181},
+ {182, 178, 183, 179},
+ {176, 180, 177, 181},
+ },
+ {
+ {185, 181, 184, 180},
+ {179, 183, 178, 182},
+ {183, 179, 184, 180},
+ {177, 181, 178, 182},
+ },
+ {
+ {186, 182, 185, 181},
+ {180, 184, 179, 183},
+ {184, 180, 185, 181},
+ {178, 182, 179, 183},
+ },
+ {
+ {187, 183, 186, 182},
+ {181, 185, 180, 184},
+ {185, 181, 186, 182},
+ {179, 183, 180, 184},
+ },
+ {
+ {188, 184, 187, 183},
+ {182, 186, 181, 185},
+ {186, 182, 187, 183},
+ {180, 184, 181, 185},
+ },
+ {
+ {189, 185, 188, 184},
+ {183, 187, 182, 186},
+ {187, 183, 188, 184},
+ {181, 185, 182, 186},
+ },
+ {
+ {190, 186, 189, 185},
+ {184, 188, 183, 187},
+ {188, 184, 189, 185},
+ {182, 186, 183, 187},
+ },
+ {
+ {191, 187, 190, 186},
+ {185, 189, 184, 188},
+ {189, 185, 190, 186},
+ {183, 187, 184, 188},
+ },
+ {
+ {192, 188, 191, 187},
+ {186, 190, 185, 189},
+ {190, 186, 191, 187},
+ {184, 188, 185, 189},
+ },
+ {
+ {193, 189, 192, 188},
+ {187, 191, 186, 190},
+ {191, 187, 192, 188},
+ {185, 189, 186, 190},
+ },
+ {
+ {194, 190, 193, 189},
+ {188, 192, 187, 191},
+ {192, 188, 193, 189},
+ {186, 190, 187, 191},
+ },
+ {
+ {195, 191, 194, 190},
+ {189, 193, 188, 192},
+ {193, 189, 194, 190},
+ {187, 191, 188, 192},
+ },
+ {
+ {196, 192, 195, 191},
+ {190, 194, 189, 193},
+ {194, 190, 195, 191},
+ {188, 192, 189, 193},
+ },
+ {
+ {197, 193, 196, 192},
+ {191, 195, 190, 194},
+ {195, 191, 196, 192},
+ {189, 193, 190, 194},
+ },
+ {
+ {198, 194, 197, 193},
+ {192, 196, 191, 195},
+ {196, 192, 197, 193},
+ {190, 194, 191, 195},
+ },
+ {
+ {199, 195, 198, 194},
+ {193, 197, 192, 196},
+ {197, 193, 198, 194},
+ {191, 195, 192, 196},
+ },
+ {
+ {200, 196, 199, 195},
+ {194, 198, 193, 197},
+ {198, 194, 199, 195},
+ {192, 196, 193, 197},
+ },
+ {
+ {201, 197, 200, 196},
+ {195, 199, 194, 198},
+ {199, 195, 200, 196},
+ {193, 197, 194, 198},
+ },
+ {
+ {202, 198, 201, 197},
+ {196, 200, 195, 199},
+ {200, 196, 201, 197},
+ {194, 198, 195, 199},
+ },
+ {
+ {203, 199, 202, 198},
+ {197, 201, 196, 200},
+ {201, 197, 202, 198},
+ {195, 199, 196, 200},
+ },
+ {
+ {204, 200, 203, 199},
+ {198, 202, 197, 201},
+ {202, 198, 203, 199},
+ {196, 200, 197, 201},
+ },
+ {
+ {205, 201, 204, 200},
+ {199, 203, 198, 202},
+ {203, 199, 204, 200},
+ {197, 201, 198, 202},
+ },
+ {
+ {206, 202, 205, 201},
+ {200, 204, 199, 203},
+ {204, 200, 205, 201},
+ {198, 202, 199, 203},
+ },
+ {
+ {207, 203, 206, 202},
+ {201, 205, 200, 204},
+ {205, 201, 206, 202},
+ {199, 203, 200, 204},
+ },
+ {
+ {208, 204, 207, 203},
+ {202, 206, 201, 205},
+ {206, 202, 207, 203},
+ {200, 204, 201, 205},
+ },
+ {
+ {209, 205, 208, 204},
+ {203, 207, 202, 206},
+ {207, 203, 208, 204},
+ {201, 205, 202, 206},
+ },
+ {
+ {210, 206, 209, 205},
+ {204, 208, 203, 207},
+ {208, 204, 209, 205},
+ {202, 206, 203, 207},
+ },
+ {
+ {211, 207, 210, 206},
+ {205, 209, 204, 208},
+ {209, 205, 210, 206},
+ {203, 207, 204, 208},
+ },
+ {
+ {212, 208, 211, 207},
+ {206, 210, 205, 209},
+ {210, 206, 211, 207},
+ {204, 208, 205, 209},
+ },
+ {
+ {213, 209, 212, 208},
+ {207, 211, 206, 210},
+ {211, 207, 212, 208},
+ {205, 209, 206, 210},
+ },
+ {
+ {214, 210, 213, 209},
+ {208, 212, 207, 211},
+ {212, 208, 213, 209},
+ {206, 210, 207, 211},
+ },
+ {
+ {215, 211, 214, 210},
+ {209, 213, 208, 212},
+ {213, 209, 214, 210},
+ {207, 211, 208, 212},
+ },
+ {
+ {216, 212, 215, 211},
+ {210, 214, 209, 213},
+ {214, 210, 215, 211},
+ {208, 212, 209, 213},
+ },
+ {
+ {217, 213, 216, 212},
+ {211, 215, 210, 214},
+ {215, 211, 216, 212},
+ {209, 213, 210, 214},
+ },
+ {
+ {218, 214, 217, 213},
+ {212, 216, 211, 215},
+ {216, 212, 217, 213},
+ {210, 214, 211, 215},
+ },
+ {
+ {219, 215, 218, 214},
+ {213, 217, 212, 216},
+ {217, 213, 218, 214},
+ {211, 215, 212, 216},
+ },
+ {
+ {220, 216, 219, 215},
+ {214, 218, 213, 217},
+ {218, 214, 219, 215},
+ {212, 216, 213, 217},
+ },
+ {
+ {221, 217, 220, 216},
+ {215, 219, 214, 218},
+ {219, 215, 220, 216},
+ {213, 217, 214, 218},
+ },
+ {
+ {222, 218, 221, 217},
+ {216, 220, 215, 219},
+ {220, 216, 221, 217},
+ {214, 218, 215, 219},
+ },
+ {
+ {223, 219, 222, 218},
+ {217, 221, 216, 220},
+ {221, 217, 222, 218},
+ {215, 219, 216, 220},
+ },
+ {
+ {224, 220, 223, 219},
+ {218, 222, 217, 221},
+ {222, 218, 223, 219},
+ {216, 220, 217, 221},
+ },
+ {
+ {225, 221, 224, 220},
+ {219, 223, 218, 222},
+ {223, 219, 224, 220},
+ {217, 221, 218, 222},
+ },
+ {
+ {226, 222, 225, 221},
+ {220, 224, 219, 223},
+ {224, 220, 225, 221},
+ {218, 222, 219, 223},
+ },
+ {
+ {227, 223, 226, 222},
+ {221, 225, 220, 224},
+ {225, 221, 226, 222},
+ {219, 223, 220, 224},
+ },
+ {
+ {228, 224, 227, 223},
+ {222, 226, 221, 225},
+ {226, 222, 227, 223},
+ {220, 224, 221, 225},
+ },
+ {
+ {229, 225, 228, 224},
+ {223, 227, 222, 226},
+ {227, 223, 228, 224},
+ {221, 225, 222, 226},
+ },
+ {
+ {230, 226, 229, 225},
+ {224, 228, 223, 227},
+ {228, 224, 229, 225},
+ {222, 226, 223, 227},
+ },
+ {
+ {231, 227, 230, 226},
+ {225, 229, 224, 228},
+ {229, 225, 230, 226},
+ {223, 227, 224, 228},
+ },
+ {
+ {232, 228, 231, 227},
+ {226, 230, 225, 229},
+ {230, 226, 231, 227},
+ {224, 228, 225, 229},
+ },
+ {
+ {233, 229, 232, 228},
+ {227, 231, 226, 230},
+ {231, 227, 232, 228},
+ {225, 229, 226, 230},
+ },
+ {
+ {234, 230, 233, 229},
+ {228, 232, 227, 231},
+ {232, 228, 233, 229},
+ {226, 230, 227, 231},
+ },
+ {
+ {235, 231, 234, 230},
+ {229, 233, 228, 232},
+ {233, 229, 234, 230},
+ {227, 231, 228, 232},
+ },
+ {
+ {236, 232, 235, 231},
+ {230, 234, 229, 233},
+ {234, 230, 235, 231},
+ {228, 232, 229, 233},
+ },
+ {
+ {237, 233, 236, 232},
+ {231, 235, 230, 234},
+ {235, 231, 236, 232},
+ {229, 233, 230, 234},
+ },
+ {
+ {238, 234, 237, 233},
+ {232, 236, 231, 235},
+ {236, 232, 237, 233},
+ {230, 234, 231, 235},
+ },
+ {
+ {239, 235, 238, 234},
+ {233, 237, 232, 236},
+ {237, 233, 238, 234},
+ {231, 235, 232, 236},
+ },
+ {
+ {240, 236, 239, 235},
+ {234, 238, 233, 237},
+ {238, 234, 239, 235},
+ {232, 236, 233, 237},
+ },
+ {
+ {241, 237, 240, 236},
+ {235, 239, 234, 238},
+ {239, 235, 240, 236},
+ {233, 237, 234, 238},
+ },
+ {
+ {242, 238, 241, 237},
+ {236, 240, 235, 239},
+ {240, 236, 241, 237},
+ {234, 238, 235, 239},
+ },
+ {
+ {243, 239, 242, 238},
+ {237, 241, 236, 240},
+ {241, 237, 242, 238},
+ {235, 239, 236, 240},
+ },
+ {
+ {244, 240, 243, 239},
+ {238, 242, 237, 241},
+ {242, 238, 243, 239},
+ {236, 240, 237, 241},
+ },
+ {
+ {245, 241, 244, 240},
+ {239, 243, 238, 242},
+ {243, 239, 244, 240},
+ {237, 241, 238, 242},
+ },
+ {
+ {246, 242, 245, 241},
+ {240, 244, 239, 243},
+ {244, 240, 245, 241},
+ {238, 242, 239, 243},
+ },
+ {
+ {247, 243, 246, 242},
+ {241, 245, 240, 244},
+ {245, 241, 246, 242},
+ {239, 243, 240, 244},
+ },
+ {
+ {248, 244, 247, 243},
+ {242, 246, 241, 245},
+ {246, 242, 247, 243},
+ {240, 244, 241, 245},
+ },
+ {
+ {249, 245, 248, 244},
+ {243, 247, 242, 246},
+ {247, 243, 248, 244},
+ {241, 245, 242, 246},
+ },
+ {
+ {250, 246, 249, 245},
+ {244, 248, 243, 247},
+ {248, 244, 249, 245},
+ {242, 246, 243, 247},
+ },
+ {
+ {251, 247, 250, 246},
+ {245, 249, 244, 248},
+ {249, 245, 250, 246},
+ {243, 247, 244, 248},
+ },
+ {
+ {252, 248, 251, 247},
+ {246, 250, 245, 249},
+ {250, 246, 251, 247},
+ {244, 248, 245, 249},
+ },
+ {
+ {253, 249, 252, 248},
+ {247, 251, 246, 250},
+ {251, 247, 252, 248},
+ {245, 249, 246, 250},
+ },
+ {
+ {254, 250, 253, 249},
+ {248, 252, 247, 251},
+ {252, 248, 253, 249},
+ {246, 250, 247, 251},
+ },
+ {
+ {255, 251, 254, 250},
+ {249, 253, 248, 252},
+ {253, 249, 254, 250},
+ {247, 251, 248, 252},
+ },
+ {
+ {255, 252, 255, 251},
+ {250, 254, 249, 253},
+ {254, 250, 255, 251},
+ {248, 252, 249, 253},
+ },
+ {
+ {255, 253, 255, 252},
+ {251, 255, 250, 254},
+ {255, 251, 255, 252},
+ {249, 253, 250, 254},
+ },
+ {
+ {255, 254, 255, 253},
+ {252, 255, 251, 255},
+ {255, 252, 255, 253},
+ {250, 254, 251, 255},
+ },
+ {
+ {255, 255, 255, 254},
+ {253, 255, 252, 255},
+ {255, 253, 255, 254},
+ {251, 255, 252, 255},
+ },
+ {
+ {255, 255, 255, 255},
+ {254, 255, 253, 255},
+ {255, 254, 255, 255},
+ {252, 255, 253, 255},
+ },
+};
+
+static const uint8_t dithersub_g[256][4][4] =
+{
+ {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ },
+ {
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0},
+ },
+ {
+ {5, 3, 4, 2},
+ {2, 4, 1, 3},
+ {4, 2, 4, 2},
+ {1, 3, 1, 3},
+ },
+ {
+ {6, 4, 5, 3},
+ {3, 5, 2, 4},
+ {5, 3, 5, 3},
+ {2, 4, 2, 4},
+ },
+ {
+ {7, 5, 6, 4},
+ {4, 6, 3, 5},
+ {6, 4, 6, 4},
+ {3, 5, 3, 5},
+ },
+ {
+ {8, 6, 7, 5},
+ {5, 7, 4, 6},
+ {7, 5, 7, 5},
+ {4, 6, 4, 6},
+ },
+ {
+ {9, 7, 8, 6},
+ {6, 8, 5, 7},
+ {8, 6, 8, 6},
+ {5, 7, 5, 7},
+ },
+ {
+ {10, 8, 9, 7},
+ {7, 9, 6, 8},
+ {9, 7, 9, 7},
+ {6, 8, 6, 8},
+ },
+ {
+ {11, 9, 10, 8},
+ {8, 10, 7, 9},
+ {10, 8, 10, 8},
+ {7, 9, 7, 9},
+ },
+ {
+ {12, 10, 11, 9},
+ {9, 11, 8, 10},
+ {11, 9, 11, 9},
+ {8, 10, 8, 10},
+ },
+ {
+ {13, 11, 12, 10},
+ {10, 12, 9, 11},
+ {12, 10, 12, 10},
+ {9, 11, 9, 11},
+ },
+ {
+ {14, 12, 13, 11},
+ {11, 13, 10, 12},
+ {13, 11, 13, 11},
+ {10, 12, 10, 12},
+ },
+ {
+ {15, 13, 14, 12},
+ {12, 14, 11, 13},
+ {14, 12, 14, 12},
+ {11, 13, 11, 13},
+ },
+ {
+ {16, 14, 15, 13},
+ {13, 15, 12, 14},
+ {15, 13, 15, 13},
+ {12, 14, 12, 14},
+ },
+ {
+ {17, 15, 16, 14},
+ {14, 16, 13, 15},
+ {16, 14, 16, 14},
+ {13, 15, 13, 15},
+ },
+ {
+ {18, 16, 17, 15},
+ {15, 17, 14, 16},
+ {17, 15, 17, 15},
+ {14, 16, 14, 16},
+ },
+ {
+ {19, 17, 18, 16},
+ {16, 18, 15, 17},
+ {18, 16, 18, 16},
+ {15, 17, 15, 17},
+ },
+ {
+ {20, 18, 19, 17},
+ {17, 19, 16, 18},
+ {19, 17, 19, 17},
+ {16, 18, 16, 18},
+ },
+ {
+ {21, 19, 20, 18},
+ {18, 20, 17, 19},
+ {20, 18, 20, 18},
+ {17, 19, 17, 19},
+ },
+ {
+ {22, 20, 21, 19},
+ {19, 21, 18, 20},
+ {21, 19, 21, 19},
+ {18, 20, 18, 20},
+ },
+ {
+ {23, 21, 22, 20},
+ {20, 22, 19, 21},
+ {22, 20, 22, 20},
+ {19, 21, 19, 21},
+ },
+ {
+ {24, 22, 23, 21},
+ {21, 23, 20, 22},
+ {23, 21, 23, 21},
+ {20, 22, 20, 22},
+ },
+ {
+ {25, 23, 24, 22},
+ {22, 24, 21, 23},
+ {24, 22, 24, 22},
+ {21, 23, 21, 23},
+ },
+ {
+ {26, 24, 25, 23},
+ {23, 25, 22, 24},
+ {25, 23, 25, 23},
+ {22, 24, 22, 24},
+ },
+ {
+ {27, 25, 26, 24},
+ {24, 26, 23, 25},
+ {26, 24, 26, 24},
+ {23, 25, 23, 25},
+ },
+ {
+ {28, 26, 27, 25},
+ {25, 27, 24, 26},
+ {27, 25, 27, 25},
+ {24, 26, 24, 26},
+ },
+ {
+ {29, 27, 28, 26},
+ {26, 28, 25, 27},
+ {28, 26, 28, 26},
+ {25, 27, 25, 27},
+ },
+ {
+ {30, 28, 29, 27},
+ {27, 29, 26, 28},
+ {29, 27, 29, 27},
+ {26, 28, 26, 28},
+ },
+ {
+ {31, 29, 30, 28},
+ {28, 30, 27, 29},
+ {30, 28, 30, 28},
+ {27, 29, 27, 29},
+ },
+ {
+ {32, 30, 31, 29},
+ {29, 31, 28, 30},
+ {31, 29, 31, 29},
+ {28, 30, 28, 30},
+ },
+ {
+ {33, 31, 32, 30},
+ {30, 32, 29, 31},
+ {32, 30, 32, 30},
+ {29, 31, 29, 31},
+ },
+ {
+ {34, 32, 33, 31},
+ {31, 33, 30, 32},
+ {33, 31, 33, 31},
+ {30, 32, 30, 32},
+ },
+ {
+ {35, 33, 34, 32},
+ {32, 34, 31, 33},
+ {34, 32, 34, 32},
+ {31, 33, 31, 33},
+ },
+ {
+ {36, 34, 35, 33},
+ {33, 35, 32, 34},
+ {35, 33, 35, 33},
+ {32, 34, 32, 34},
+ },
+ {
+ {37, 35, 36, 34},
+ {34, 36, 33, 35},
+ {36, 34, 36, 34},
+ {33, 35, 33, 35},
+ },
+ {
+ {38, 36, 37, 35},
+ {35, 37, 34, 36},
+ {37, 35, 37, 35},
+ {34, 36, 34, 36},
+ },
+ {
+ {39, 37, 38, 36},
+ {36, 38, 35, 37},
+ {38, 36, 38, 36},
+ {35, 37, 35, 37},
+ },
+ {
+ {40, 38, 39, 37},
+ {37, 39, 36, 38},
+ {39, 37, 39, 37},
+ {36, 38, 36, 38},
+ },
+ {
+ {41, 39, 40, 38},
+ {38, 40, 37, 39},
+ {40, 38, 40, 38},
+ {37, 39, 37, 39},
+ },
+ {
+ {42, 40, 41, 39},
+ {39, 41, 38, 40},
+ {41, 39, 41, 39},
+ {38, 40, 38, 40},
+ },
+ {
+ {43, 41, 42, 40},
+ {40, 42, 39, 41},
+ {42, 40, 42, 40},
+ {39, 41, 39, 41},
+ },
+ {
+ {44, 42, 43, 41},
+ {41, 43, 40, 42},
+ {43, 41, 43, 41},
+ {40, 42, 40, 42},
+ },
+ {
+ {45, 43, 44, 42},
+ {42, 44, 41, 43},
+ {44, 42, 44, 42},
+ {41, 43, 41, 43},
+ },
+ {
+ {46, 44, 45, 43},
+ {43, 45, 42, 44},
+ {45, 43, 45, 43},
+ {42, 44, 42, 44},
+ },
+ {
+ {47, 45, 46, 44},
+ {44, 46, 43, 45},
+ {46, 44, 46, 44},
+ {43, 45, 43, 45},
+ },
+ {
+ {48, 46, 47, 45},
+ {45, 47, 44, 46},
+ {47, 45, 47, 45},
+ {44, 46, 44, 46},
+ },
+ {
+ {49, 47, 48, 46},
+ {46, 48, 45, 47},
+ {48, 46, 48, 46},
+ {45, 47, 45, 47},
+ },
+ {
+ {50, 48, 49, 47},
+ {47, 49, 46, 48},
+ {49, 47, 49, 47},
+ {46, 48, 46, 48},
+ },
+ {
+ {51, 49, 50, 48},
+ {48, 50, 47, 49},
+ {50, 48, 50, 48},
+ {47, 49, 47, 49},
+ },
+ {
+ {52, 50, 51, 49},
+ {49, 51, 48, 50},
+ {51, 49, 51, 49},
+ {48, 50, 48, 50},
+ },
+ {
+ {53, 51, 52, 50},
+ {50, 52, 49, 51},
+ {52, 50, 52, 50},
+ {49, 51, 49, 51},
+ },
+ {
+ {54, 52, 53, 51},
+ {51, 53, 50, 52},
+ {53, 51, 53, 51},
+ {50, 52, 50, 52},
+ },
+ {
+ {55, 53, 54, 52},
+ {52, 54, 51, 53},
+ {54, 52, 54, 52},
+ {51, 53, 51, 53},
+ },
+ {
+ {56, 54, 55, 53},
+ {53, 55, 52, 54},
+ {55, 53, 55, 53},
+ {52, 54, 52, 54},
+ },
+ {
+ {57, 55, 56, 54},
+ {54, 56, 53, 55},
+ {56, 54, 56, 54},
+ {53, 55, 53, 55},
+ },
+ {
+ {58, 56, 57, 55},
+ {55, 57, 54, 56},
+ {57, 55, 57, 55},
+ {54, 56, 54, 56},
+ },
+ {
+ {59, 57, 58, 56},
+ {56, 58, 55, 57},
+ {58, 56, 58, 56},
+ {55, 57, 55, 57},
+ },
+ {
+ {60, 58, 59, 57},
+ {57, 59, 56, 58},
+ {59, 57, 59, 57},
+ {56, 58, 56, 58},
+ },
+ {
+ {61, 59, 60, 58},
+ {58, 60, 57, 59},
+ {60, 58, 60, 58},
+ {57, 59, 57, 59},
+ },
+ {
+ {62, 60, 61, 59},
+ {59, 61, 58, 60},
+ {61, 59, 61, 59},
+ {58, 60, 58, 60},
+ },
+ {
+ {63, 61, 62, 60},
+ {60, 62, 59, 61},
+ {62, 60, 62, 60},
+ {59, 61, 59, 61},
+ },
+ {
+ {64, 62, 63, 61},
+ {61, 63, 60, 62},
+ {63, 61, 63, 61},
+ {60, 62, 60, 62},
+ },
+ {
+ {65, 63, 64, 62},
+ {62, 64, 61, 63},
+ {64, 62, 64, 62},
+ {61, 63, 61, 63},
+ },
+ {
+ {66, 64, 65, 63},
+ {63, 65, 62, 64},
+ {65, 63, 65, 63},
+ {62, 64, 62, 64},
+ },
+ {
+ {67, 65, 66, 64},
+ {64, 66, 63, 65},
+ {66, 64, 66, 64},
+ {63, 65, 63, 65},
+ },
+ {
+ {68, 66, 67, 65},
+ {65, 67, 64, 66},
+ {67, 65, 67, 65},
+ {64, 66, 64, 66},
+ },
+ {
+ {69, 67, 68, 66},
+ {66, 68, 65, 67},
+ {68, 66, 68, 66},
+ {65, 67, 65, 67},
+ },
+ {
+ {70, 68, 69, 67},
+ {67, 69, 66, 68},
+ {69, 67, 69, 67},
+ {66, 68, 66, 68},
+ },
+ {
+ {71, 69, 70, 68},
+ {68, 70, 67, 69},
+ {70, 68, 70, 68},
+ {67, 69, 67, 69},
+ },
+ {
+ {72, 70, 71, 69},
+ {69, 71, 68, 70},
+ {71, 69, 71, 69},
+ {68, 70, 68, 70},
+ },
+ {
+ {73, 71, 72, 70},
+ {70, 72, 69, 71},
+ {72, 70, 72, 70},
+ {69, 71, 69, 71},
+ },
+ {
+ {74, 72, 73, 71},
+ {71, 73, 70, 72},
+ {73, 71, 73, 71},
+ {70, 72, 70, 72},
+ },
+ {
+ {75, 73, 74, 72},
+ {72, 74, 71, 73},
+ {74, 72, 74, 72},
+ {71, 73, 71, 73},
+ },
+ {
+ {76, 74, 75, 73},
+ {73, 75, 72, 74},
+ {75, 73, 75, 73},
+ {72, 74, 72, 74},
+ },
+ {
+ {77, 75, 76, 74},
+ {74, 76, 73, 75},
+ {76, 74, 76, 74},
+ {73, 75, 73, 75},
+ },
+ {
+ {78, 76, 77, 75},
+ {75, 77, 74, 76},
+ {77, 75, 77, 75},
+ {74, 76, 74, 76},
+ },
+ {
+ {79, 77, 78, 76},
+ {76, 78, 75, 77},
+ {78, 76, 78, 76},
+ {75, 77, 75, 77},
+ },
+ {
+ {80, 78, 79, 77},
+ {77, 79, 76, 78},
+ {79, 77, 79, 77},
+ {76, 78, 76, 78},
+ },
+ {
+ {81, 79, 80, 78},
+ {78, 80, 77, 79},
+ {80, 78, 80, 78},
+ {77, 79, 77, 79},
+ },
+ {
+ {82, 80, 81, 79},
+ {79, 81, 78, 80},
+ {81, 79, 81, 79},
+ {78, 80, 78, 80},
+ },
+ {
+ {83, 81, 82, 80},
+ {80, 82, 79, 81},
+ {82, 80, 82, 80},
+ {79, 81, 79, 81},
+ },
+ {
+ {84, 82, 83, 81},
+ {81, 83, 80, 82},
+ {83, 81, 83, 81},
+ {80, 82, 80, 82},
+ },
+ {
+ {85, 83, 84, 82},
+ {82, 84, 81, 83},
+ {84, 82, 84, 82},
+ {81, 83, 81, 83},
+ },
+ {
+ {86, 84, 85, 83},
+ {83, 85, 82, 84},
+ {85, 83, 85, 83},
+ {82, 84, 82, 84},
+ },
+ {
+ {87, 85, 86, 84},
+ {84, 86, 83, 85},
+ {86, 84, 86, 84},
+ {83, 85, 83, 85},
+ },
+ {
+ {88, 86, 87, 85},
+ {85, 87, 84, 86},
+ {87, 85, 87, 85},
+ {84, 86, 84, 86},
+ },
+ {
+ {89, 87, 88, 86},
+ {86, 88, 85, 87},
+ {88, 86, 88, 86},
+ {85, 87, 85, 87},
+ },
+ {
+ {90, 88, 89, 87},
+ {87, 89, 86, 88},
+ {89, 87, 89, 87},
+ {86, 88, 86, 88},
+ },
+ {
+ {91, 89, 90, 88},
+ {88, 90, 87, 89},
+ {90, 88, 90, 88},
+ {87, 89, 87, 89},
+ },
+ {
+ {92, 90, 91, 89},
+ {89, 91, 88, 90},
+ {91, 89, 91, 89},
+ {88, 90, 88, 90},
+ },
+ {
+ {93, 91, 92, 90},
+ {90, 92, 89, 91},
+ {92, 90, 92, 90},
+ {89, 91, 89, 91},
+ },
+ {
+ {94, 92, 93, 91},
+ {91, 93, 90, 92},
+ {93, 91, 93, 91},
+ {90, 92, 90, 92},
+ },
+ {
+ {95, 93, 94, 92},
+ {92, 94, 91, 93},
+ {94, 92, 94, 92},
+ {91, 93, 91, 93},
+ },
+ {
+ {96, 94, 95, 93},
+ {93, 95, 92, 94},
+ {95, 93, 95, 93},
+ {92, 94, 92, 94},
+ },
+ {
+ {97, 95, 96, 94},
+ {94, 96, 93, 95},
+ {96, 94, 96, 94},
+ {93, 95, 93, 95},
+ },
+ {
+ {98, 96, 97, 95},
+ {95, 97, 94, 96},
+ {97, 95, 97, 95},
+ {94, 96, 94, 96},
+ },
+ {
+ {99, 97, 98, 96},
+ {96, 98, 95, 97},
+ {98, 96, 98, 96},
+ {95, 97, 95, 97},
+ },
+ {
+ {100, 98, 99, 97},
+ {97, 99, 96, 98},
+ {99, 97, 99, 97},
+ {96, 98, 96, 98},
+ },
+ {
+ {101, 99, 100, 98},
+ {98, 100, 97, 99},
+ {100, 98, 100, 98},
+ {97, 99, 97, 99},
+ },
+ {
+ {102, 100, 101, 99},
+ {99, 101, 98, 100},
+ {101, 99, 101, 99},
+ {98, 100, 98, 100},
+ },
+ {
+ {103, 101, 102, 100},
+ {100, 102, 99, 101},
+ {102, 100, 102, 100},
+ {99, 101, 99, 101},
+ },
+ {
+ {104, 102, 103, 101},
+ {101, 103, 100, 102},
+ {103, 101, 103, 101},
+ {100, 102, 100, 102},
+ },
+ {
+ {105, 103, 104, 102},
+ {102, 104, 101, 103},
+ {104, 102, 104, 102},
+ {101, 103, 101, 103},
+ },
+ {
+ {106, 104, 105, 103},
+ {103, 105, 102, 104},
+ {105, 103, 105, 103},
+ {102, 104, 102, 104},
+ },
+ {
+ {107, 105, 106, 104},
+ {104, 106, 103, 105},
+ {106, 104, 106, 104},
+ {103, 105, 103, 105},
+ },
+ {
+ {108, 106, 107, 105},
+ {105, 107, 104, 106},
+ {107, 105, 107, 105},
+ {104, 106, 104, 106},
+ },
+ {
+ {109, 107, 108, 106},
+ {106, 108, 105, 107},
+ {108, 106, 108, 106},
+ {105, 107, 105, 107},
+ },
+ {
+ {110, 108, 109, 107},
+ {107, 109, 106, 108},
+ {109, 107, 109, 107},
+ {106, 108, 106, 108},
+ },
+ {
+ {111, 109, 110, 108},
+ {108, 110, 107, 109},
+ {110, 108, 110, 108},
+ {107, 109, 107, 109},
+ },
+ {
+ {112, 110, 111, 109},
+ {109, 111, 108, 110},
+ {111, 109, 111, 109},
+ {108, 110, 108, 110},
+ },
+ {
+ {113, 111, 112, 110},
+ {110, 112, 109, 111},
+ {112, 110, 112, 110},
+ {109, 111, 109, 111},
+ },
+ {
+ {114, 112, 113, 111},
+ {111, 113, 110, 112},
+ {113, 111, 113, 111},
+ {110, 112, 110, 112},
+ },
+ {
+ {115, 113, 114, 112},
+ {112, 114, 111, 113},
+ {114, 112, 114, 112},
+ {111, 113, 111, 113},
+ },
+ {
+ {116, 114, 115, 113},
+ {113, 115, 112, 114},
+ {115, 113, 115, 113},
+ {112, 114, 112, 114},
+ },
+ {
+ {117, 115, 116, 114},
+ {114, 116, 113, 115},
+ {116, 114, 116, 114},
+ {113, 115, 113, 115},
+ },
+ {
+ {118, 116, 117, 115},
+ {115, 117, 114, 116},
+ {117, 115, 117, 115},
+ {114, 116, 114, 116},
+ },
+ {
+ {119, 117, 118, 116},
+ {116, 118, 115, 117},
+ {118, 116, 118, 116},
+ {115, 117, 115, 117},
+ },
+ {
+ {120, 118, 119, 117},
+ {117, 119, 116, 118},
+ {119, 117, 119, 117},
+ {116, 118, 116, 118},
+ },
+ {
+ {121, 119, 120, 118},
+ {118, 120, 117, 119},
+ {120, 118, 120, 118},
+ {117, 119, 117, 119},
+ },
+ {
+ {122, 120, 121, 119},
+ {119, 121, 118, 120},
+ {121, 119, 121, 119},
+ {118, 120, 118, 120},
+ },
+ {
+ {123, 121, 122, 120},
+ {120, 122, 119, 121},
+ {122, 120, 122, 120},
+ {119, 121, 119, 121},
+ },
+ {
+ {124, 122, 123, 121},
+ {121, 123, 120, 122},
+ {123, 121, 123, 121},
+ {120, 122, 120, 122},
+ },
+ {
+ {125, 123, 124, 122},
+ {122, 124, 121, 123},
+ {124, 122, 124, 122},
+ {121, 123, 121, 123},
+ },
+ {
+ {126, 124, 125, 123},
+ {123, 125, 122, 124},
+ {125, 123, 125, 123},
+ {122, 124, 122, 124},
+ },
+ {
+ {127, 125, 126, 124},
+ {124, 126, 123, 125},
+ {126, 124, 126, 124},
+ {123, 125, 123, 125},
+ },
+ {
+ {128, 126, 127, 125},
+ {125, 127, 124, 126},
+ {127, 125, 127, 125},
+ {124, 126, 124, 126},
+ },
+ {
+ {129, 127, 128, 126},
+ {126, 128, 125, 127},
+ {128, 126, 128, 126},
+ {125, 127, 125, 127},
+ },
+ {
+ {130, 128, 129, 127},
+ {127, 129, 126, 128},
+ {129, 127, 129, 127},
+ {126, 128, 126, 128},
+ },
+ {
+ {131, 129, 130, 128},
+ {128, 130, 127, 129},
+ {130, 128, 130, 128},
+ {127, 129, 127, 129},
+ },
+ {
+ {132, 130, 131, 129},
+ {129, 131, 128, 130},
+ {131, 129, 131, 129},
+ {128, 130, 128, 130},
+ },
+ {
+ {133, 131, 132, 130},
+ {130, 132, 129, 131},
+ {132, 130, 132, 130},
+ {129, 131, 129, 131},
+ },
+ {
+ {134, 132, 133, 131},
+ {131, 133, 130, 132},
+ {133, 131, 133, 131},
+ {130, 132, 130, 132},
+ },
+ {
+ {135, 133, 134, 132},
+ {132, 134, 131, 133},
+ {134, 132, 134, 132},
+ {131, 133, 131, 133},
+ },
+ {
+ {136, 134, 135, 133},
+ {133, 135, 132, 134},
+ {135, 133, 135, 133},
+ {132, 134, 132, 134},
+ },
+ {
+ {137, 135, 136, 134},
+ {134, 136, 133, 135},
+ {136, 134, 136, 134},
+ {133, 135, 133, 135},
+ },
+ {
+ {138, 136, 137, 135},
+ {135, 137, 134, 136},
+ {137, 135, 137, 135},
+ {134, 136, 134, 136},
+ },
+ {
+ {139, 137, 138, 136},
+ {136, 138, 135, 137},
+ {138, 136, 138, 136},
+ {135, 137, 135, 137},
+ },
+ {
+ {140, 138, 139, 137},
+ {137, 139, 136, 138},
+ {139, 137, 139, 137},
+ {136, 138, 136, 138},
+ },
+ {
+ {141, 139, 140, 138},
+ {138, 140, 137, 139},
+ {140, 138, 140, 138},
+ {137, 139, 137, 139},
+ },
+ {
+ {142, 140, 141, 139},
+ {139, 141, 138, 140},
+ {141, 139, 141, 139},
+ {138, 140, 138, 140},
+ },
+ {
+ {143, 141, 142, 140},
+ {140, 142, 139, 141},
+ {142, 140, 142, 140},
+ {139, 141, 139, 141},
+ },
+ {
+ {144, 142, 143, 141},
+ {141, 143, 140, 142},
+ {143, 141, 143, 141},
+ {140, 142, 140, 142},
+ },
+ {
+ {145, 143, 144, 142},
+ {142, 144, 141, 143},
+ {144, 142, 144, 142},
+ {141, 143, 141, 143},
+ },
+ {
+ {146, 144, 145, 143},
+ {143, 145, 142, 144},
+ {145, 143, 145, 143},
+ {142, 144, 142, 144},
+ },
+ {
+ {147, 145, 146, 144},
+ {144, 146, 143, 145},
+ {146, 144, 146, 144},
+ {143, 145, 143, 145},
+ },
+ {
+ {148, 146, 147, 145},
+ {145, 147, 144, 146},
+ {147, 145, 147, 145},
+ {144, 146, 144, 146},
+ },
+ {
+ {149, 147, 148, 146},
+ {146, 148, 145, 147},
+ {148, 146, 148, 146},
+ {145, 147, 145, 147},
+ },
+ {
+ {150, 148, 149, 147},
+ {147, 149, 146, 148},
+ {149, 147, 149, 147},
+ {146, 148, 146, 148},
+ },
+ {
+ {151, 149, 150, 148},
+ {148, 150, 147, 149},
+ {150, 148, 150, 148},
+ {147, 149, 147, 149},
+ },
+ {
+ {152, 150, 151, 149},
+ {149, 151, 148, 150},
+ {151, 149, 151, 149},
+ {148, 150, 148, 150},
+ },
+ {
+ {153, 151, 152, 150},
+ {150, 152, 149, 151},
+ {152, 150, 152, 150},
+ {149, 151, 149, 151},
+ },
+ {
+ {154, 152, 153, 151},
+ {151, 153, 150, 152},
+ {153, 151, 153, 151},
+ {150, 152, 150, 152},
+ },
+ {
+ {155, 153, 154, 152},
+ {152, 154, 151, 153},
+ {154, 152, 154, 152},
+ {151, 153, 151, 153},
+ },
+ {
+ {156, 154, 155, 153},
+ {153, 155, 152, 154},
+ {155, 153, 155, 153},
+ {152, 154, 152, 154},
+ },
+ {
+ {157, 155, 156, 154},
+ {154, 156, 153, 155},
+ {156, 154, 156, 154},
+ {153, 155, 153, 155},
+ },
+ {
+ {158, 156, 157, 155},
+ {155, 157, 154, 156},
+ {157, 155, 157, 155},
+ {154, 156, 154, 156},
+ },
+ {
+ {159, 157, 158, 156},
+ {156, 158, 155, 157},
+ {158, 156, 158, 156},
+ {155, 157, 155, 157},
+ },
+ {
+ {160, 158, 159, 157},
+ {157, 159, 156, 158},
+ {159, 157, 159, 157},
+ {156, 158, 156, 158},
+ },
+ {
+ {161, 159, 160, 158},
+ {158, 160, 157, 159},
+ {160, 158, 160, 158},
+ {157, 159, 157, 159},
+ },
+ {
+ {162, 160, 161, 159},
+ {159, 161, 158, 160},
+ {161, 159, 161, 159},
+ {158, 160, 158, 160},
+ },
+ {
+ {163, 161, 162, 160},
+ {160, 162, 159, 161},
+ {162, 160, 162, 160},
+ {159, 161, 159, 161},
+ },
+ {
+ {164, 162, 163, 161},
+ {161, 163, 160, 162},
+ {163, 161, 163, 161},
+ {160, 162, 160, 162},
+ },
+ {
+ {165, 163, 164, 162},
+ {162, 164, 161, 163},
+ {164, 162, 164, 162},
+ {161, 163, 161, 163},
+ },
+ {
+ {166, 164, 165, 163},
+ {163, 165, 162, 164},
+ {165, 163, 165, 163},
+ {162, 164, 162, 164},
+ },
+ {
+ {167, 165, 166, 164},
+ {164, 166, 163, 165},
+ {166, 164, 166, 164},
+ {163, 165, 163, 165},
+ },
+ {
+ {168, 166, 167, 165},
+ {165, 167, 164, 166},
+ {167, 165, 167, 165},
+ {164, 166, 164, 166},
+ },
+ {
+ {169, 167, 168, 166},
+ {166, 168, 165, 167},
+ {168, 166, 168, 166},
+ {165, 167, 165, 167},
+ },
+ {
+ {170, 168, 169, 167},
+ {167, 169, 166, 168},
+ {169, 167, 169, 167},
+ {166, 168, 166, 168},
+ },
+ {
+ {171, 169, 170, 168},
+ {168, 170, 167, 169},
+ {170, 168, 170, 168},
+ {167, 169, 167, 169},
+ },
+ {
+ {172, 170, 171, 169},
+ {169, 171, 168, 170},
+ {171, 169, 171, 169},
+ {168, 170, 168, 170},
+ },
+ {
+ {173, 171, 172, 170},
+ {170, 172, 169, 171},
+ {172, 170, 172, 170},
+ {169, 171, 169, 171},
+ },
+ {
+ {174, 172, 173, 171},
+ {171, 173, 170, 172},
+ {173, 171, 173, 171},
+ {170, 172, 170, 172},
+ },
+ {
+ {175, 173, 174, 172},
+ {172, 174, 171, 173},
+ {174, 172, 174, 172},
+ {171, 173, 171, 173},
+ },
+ {
+ {176, 174, 175, 173},
+ {173, 175, 172, 174},
+ {175, 173, 175, 173},
+ {172, 174, 172, 174},
+ },
+ {
+ {177, 175, 176, 174},
+ {174, 176, 173, 175},
+ {176, 174, 176, 174},
+ {173, 175, 173, 175},
+ },
+ {
+ {178, 176, 177, 175},
+ {175, 177, 174, 176},
+ {177, 175, 177, 175},
+ {174, 176, 174, 176},
+ },
+ {
+ {179, 177, 178, 176},
+ {176, 178, 175, 177},
+ {178, 176, 178, 176},
+ {175, 177, 175, 177},
+ },
+ {
+ {180, 178, 179, 177},
+ {177, 179, 176, 178},
+ {179, 177, 179, 177},
+ {176, 178, 176, 178},
+ },
+ {
+ {181, 179, 180, 178},
+ {178, 180, 177, 179},
+ {180, 178, 180, 178},
+ {177, 179, 177, 179},
+ },
+ {
+ {182, 180, 181, 179},
+ {179, 181, 178, 180},
+ {181, 179, 181, 179},
+ {178, 180, 178, 180},
+ },
+ {
+ {183, 181, 182, 180},
+ {180, 182, 179, 181},
+ {182, 180, 182, 180},
+ {179, 181, 179, 181},
+ },
+ {
+ {184, 182, 183, 181},
+ {181, 183, 180, 182},
+ {183, 181, 183, 181},
+ {180, 182, 180, 182},
+ },
+ {
+ {185, 183, 184, 182},
+ {182, 184, 181, 183},
+ {184, 182, 184, 182},
+ {181, 183, 181, 183},
+ },
+ {
+ {186, 184, 185, 183},
+ {183, 185, 182, 184},
+ {185, 183, 185, 183},
+ {182, 184, 182, 184},
+ },
+ {
+ {187, 185, 186, 184},
+ {184, 186, 183, 185},
+ {186, 184, 186, 184},
+ {183, 185, 183, 185},
+ },
+ {
+ {188, 186, 187, 185},
+ {185, 187, 184, 186},
+ {187, 185, 187, 185},
+ {184, 186, 184, 186},
+ },
+ {
+ {189, 187, 188, 186},
+ {186, 188, 185, 187},
+ {188, 186, 188, 186},
+ {185, 187, 185, 187},
+ },
+ {
+ {190, 188, 189, 187},
+ {187, 189, 186, 188},
+ {189, 187, 189, 187},
+ {186, 188, 186, 188},
+ },
+ {
+ {191, 189, 190, 188},
+ {188, 190, 187, 189},
+ {190, 188, 190, 188},
+ {187, 189, 187, 189},
+ },
+ {
+ {192, 190, 191, 189},
+ {189, 191, 188, 190},
+ {191, 189, 191, 189},
+ {188, 190, 188, 190},
+ },
+ {
+ {193, 191, 192, 190},
+ {190, 192, 189, 191},
+ {192, 190, 192, 190},
+ {189, 191, 189, 191},
+ },
+ {
+ {194, 192, 193, 191},
+ {191, 193, 190, 192},
+ {193, 191, 193, 191},
+ {190, 192, 190, 192},
+ },
+ {
+ {195, 193, 194, 192},
+ {192, 194, 191, 193},
+ {194, 192, 194, 192},
+ {191, 193, 191, 193},
+ },
+ {
+ {196, 194, 195, 193},
+ {193, 195, 192, 194},
+ {195, 193, 195, 193},
+ {192, 194, 192, 194},
+ },
+ {
+ {197, 195, 196, 194},
+ {194, 196, 193, 195},
+ {196, 194, 196, 194},
+ {193, 195, 193, 195},
+ },
+ {
+ {198, 196, 197, 195},
+ {195, 197, 194, 196},
+ {197, 195, 197, 195},
+ {194, 196, 194, 196},
+ },
+ {
+ {199, 197, 198, 196},
+ {196, 198, 195, 197},
+ {198, 196, 198, 196},
+ {195, 197, 195, 197},
+ },
+ {
+ {200, 198, 199, 197},
+ {197, 199, 196, 198},
+ {199, 197, 199, 197},
+ {196, 198, 196, 198},
+ },
+ {
+ {201, 199, 200, 198},
+ {198, 200, 197, 199},
+ {200, 198, 200, 198},
+ {197, 199, 197, 199},
+ },
+ {
+ {202, 200, 201, 199},
+ {199, 201, 198, 200},
+ {201, 199, 201, 199},
+ {198, 200, 198, 200},
+ },
+ {
+ {203, 201, 202, 200},
+ {200, 202, 199, 201},
+ {202, 200, 202, 200},
+ {199, 201, 199, 201},
+ },
+ {
+ {204, 202, 203, 201},
+ {201, 203, 200, 202},
+ {203, 201, 203, 201},
+ {200, 202, 200, 202},
+ },
+ {
+ {205, 203, 204, 202},
+ {202, 204, 201, 203},
+ {204, 202, 204, 202},
+ {201, 203, 201, 203},
+ },
+ {
+ {206, 204, 205, 203},
+ {203, 205, 202, 204},
+ {205, 203, 205, 203},
+ {202, 204, 202, 204},
+ },
+ {
+ {207, 205, 206, 204},
+ {204, 206, 203, 205},
+ {206, 204, 206, 204},
+ {203, 205, 203, 205},
+ },
+ {
+ {208, 206, 207, 205},
+ {205, 207, 204, 206},
+ {207, 205, 207, 205},
+ {204, 206, 204, 206},
+ },
+ {
+ {209, 207, 208, 206},
+ {206, 208, 205, 207},
+ {208, 206, 208, 206},
+ {205, 207, 205, 207},
+ },
+ {
+ {210, 208, 209, 207},
+ {207, 209, 206, 208},
+ {209, 207, 209, 207},
+ {206, 208, 206, 208},
+ },
+ {
+ {211, 209, 210, 208},
+ {208, 210, 207, 209},
+ {210, 208, 210, 208},
+ {207, 209, 207, 209},
+ },
+ {
+ {212, 210, 211, 209},
+ {209, 211, 208, 210},
+ {211, 209, 211, 209},
+ {208, 210, 208, 210},
+ },
+ {
+ {213, 211, 212, 210},
+ {210, 212, 209, 211},
+ {212, 210, 212, 210},
+ {209, 211, 209, 211},
+ },
+ {
+ {214, 212, 213, 211},
+ {211, 213, 210, 212},
+ {213, 211, 213, 211},
+ {210, 212, 210, 212},
+ },
+ {
+ {215, 213, 214, 212},
+ {212, 214, 211, 213},
+ {214, 212, 214, 212},
+ {211, 213, 211, 213},
+ },
+ {
+ {216, 214, 215, 213},
+ {213, 215, 212, 214},
+ {215, 213, 215, 213},
+ {212, 214, 212, 214},
+ },
+ {
+ {217, 215, 216, 214},
+ {214, 216, 213, 215},
+ {216, 214, 216, 214},
+ {213, 215, 213, 215},
+ },
+ {
+ {218, 216, 217, 215},
+ {215, 217, 214, 216},
+ {217, 215, 217, 215},
+ {214, 216, 214, 216},
+ },
+ {
+ {219, 217, 218, 216},
+ {216, 218, 215, 217},
+ {218, 216, 218, 216},
+ {215, 217, 215, 217},
+ },
+ {
+ {220, 218, 219, 217},
+ {217, 219, 216, 218},
+ {219, 217, 219, 217},
+ {216, 218, 216, 218},
+ },
+ {
+ {221, 219, 220, 218},
+ {218, 220, 217, 219},
+ {220, 218, 220, 218},
+ {217, 219, 217, 219},
+ },
+ {
+ {222, 220, 221, 219},
+ {219, 221, 218, 220},
+ {221, 219, 221, 219},
+ {218, 220, 218, 220},
+ },
+ {
+ {223, 221, 222, 220},
+ {220, 222, 219, 221},
+ {222, 220, 222, 220},
+ {219, 221, 219, 221},
+ },
+ {
+ {224, 222, 223, 221},
+ {221, 223, 220, 222},
+ {223, 221, 223, 221},
+ {220, 222, 220, 222},
+ },
+ {
+ {225, 223, 224, 222},
+ {222, 224, 221, 223},
+ {224, 222, 224, 222},
+ {221, 223, 221, 223},
+ },
+ {
+ {226, 224, 225, 223},
+ {223, 225, 222, 224},
+ {225, 223, 225, 223},
+ {222, 224, 222, 224},
+ },
+ {
+ {227, 225, 226, 224},
+ {224, 226, 223, 225},
+ {226, 224, 226, 224},
+ {223, 225, 223, 225},
+ },
+ {
+ {228, 226, 227, 225},
+ {225, 227, 224, 226},
+ {227, 225, 227, 225},
+ {224, 226, 224, 226},
+ },
+ {
+ {229, 227, 228, 226},
+ {226, 228, 225, 227},
+ {228, 226, 228, 226},
+ {225, 227, 225, 227},
+ },
+ {
+ {230, 228, 229, 227},
+ {227, 229, 226, 228},
+ {229, 227, 229, 227},
+ {226, 228, 226, 228},
+ },
+ {
+ {231, 229, 230, 228},
+ {228, 230, 227, 229},
+ {230, 228, 230, 228},
+ {227, 229, 227, 229},
+ },
+ {
+ {232, 230, 231, 229},
+ {229, 231, 228, 230},
+ {231, 229, 231, 229},
+ {228, 230, 228, 230},
+ },
+ {
+ {233, 231, 232, 230},
+ {230, 232, 229, 231},
+ {232, 230, 232, 230},
+ {229, 231, 229, 231},
+ },
+ {
+ {234, 232, 233, 231},
+ {231, 233, 230, 232},
+ {233, 231, 233, 231},
+ {230, 232, 230, 232},
+ },
+ {
+ {235, 233, 234, 232},
+ {232, 234, 231, 233},
+ {234, 232, 234, 232},
+ {231, 233, 231, 233},
+ },
+ {
+ {236, 234, 235, 233},
+ {233, 235, 232, 234},
+ {235, 233, 235, 233},
+ {232, 234, 232, 234},
+ },
+ {
+ {237, 235, 236, 234},
+ {234, 236, 233, 235},
+ {236, 234, 236, 234},
+ {233, 235, 233, 235},
+ },
+ {
+ {238, 236, 237, 235},
+ {235, 237, 234, 236},
+ {237, 235, 237, 235},
+ {234, 236, 234, 236},
+ },
+ {
+ {239, 237, 238, 236},
+ {236, 238, 235, 237},
+ {238, 236, 238, 236},
+ {235, 237, 235, 237},
+ },
+ {
+ {240, 238, 239, 237},
+ {237, 239, 236, 238},
+ {239, 237, 239, 237},
+ {236, 238, 236, 238},
+ },
+ {
+ {241, 239, 240, 238},
+ {238, 240, 237, 239},
+ {240, 238, 240, 238},
+ {237, 239, 237, 239},
+ },
+ {
+ {242, 240, 241, 239},
+ {239, 241, 238, 240},
+ {241, 239, 241, 239},
+ {238, 240, 238, 240},
+ },
+ {
+ {243, 241, 242, 240},
+ {240, 242, 239, 241},
+ {242, 240, 242, 240},
+ {239, 241, 239, 241},
+ },
+ {
+ {244, 242, 243, 241},
+ {241, 243, 240, 242},
+ {243, 241, 243, 241},
+ {240, 242, 240, 242},
+ },
+ {
+ {245, 243, 244, 242},
+ {242, 244, 241, 243},
+ {244, 242, 244, 242},
+ {241, 243, 241, 243},
+ },
+ {
+ {246, 244, 245, 243},
+ {243, 245, 242, 244},
+ {245, 243, 245, 243},
+ {242, 244, 242, 244},
+ },
+ {
+ {247, 245, 246, 244},
+ {244, 246, 243, 245},
+ {246, 244, 246, 244},
+ {243, 245, 243, 245},
+ },
+ {
+ {248, 246, 247, 245},
+ {245, 247, 244, 246},
+ {247, 245, 247, 245},
+ {244, 246, 244, 246},
+ },
+ {
+ {249, 247, 248, 246},
+ {246, 248, 245, 247},
+ {248, 246, 248, 246},
+ {245, 247, 245, 247},
+ },
+ {
+ {250, 248, 249, 247},
+ {247, 249, 246, 248},
+ {249, 247, 249, 247},
+ {246, 248, 246, 248},
+ },
+ {
+ {251, 249, 250, 248},
+ {248, 250, 247, 249},
+ {250, 248, 250, 248},
+ {247, 249, 247, 249},
+ },
+ {
+ {252, 250, 251, 249},
+ {249, 251, 248, 250},
+ {251, 249, 251, 249},
+ {248, 250, 248, 250},
+ },
+ {
+ {253, 251, 252, 250},
+ {250, 252, 249, 251},
+ {252, 250, 252, 250},
+ {249, 251, 249, 251},
+ },
+ {
+ {254, 252, 253, 251},
+ {251, 253, 250, 252},
+ {253, 251, 253, 251},
+ {250, 252, 250, 252},
+ },
+ {
+ {255, 253, 254, 252},
+ {252, 254, 251, 253},
+ {254, 252, 254, 252},
+ {251, 253, 251, 253},
+ },
+ {
+ {255, 254, 255, 253},
+ {253, 255, 252, 254},
+ {255, 253, 255, 253},
+ {252, 254, 252, 254},
+ },
+ {
+ {255, 255, 255, 254},
+ {254, 255, 253, 255},
+ {255, 254, 255, 254},
+ {253, 255, 253, 255},
+ },
+ {
+ {255, 255, 255, 255},
+ {255, 255, 254, 255},
+ {255, 255, 255, 255},
+ {254, 255, 254, 255},
+ },
+};
+
+
+
+
+static const uint8_t dithersub_g2x2[256][2][2] =
+{
+ {
+ {0, 0},
+ {0, 0},
+ },
+ {
+ {0, 0},
+ {0, 0},
+ },
+ {
+ {4, 2},
+ {1, 3},
+ },
+ {
+ {5, 3},
+ {2, 4},
+ },
+ {
+ {6, 4},
+ {3, 5},
+ },
+ {
+ {7, 5},
+ {4, 6},
+ },
+ {
+ {8, 6},
+ {5, 7},
+ },
+ {
+ {9, 7},
+ {6, 8},
+ },
+ {
+ {10, 8},
+ {7, 9},
+ },
+ {
+ {11, 9},
+ {8, 10},
+ },
+ {
+ {12, 10},
+ {9, 11},
+ },
+ {
+ {13, 11},
+ {10, 12},
+ },
+ {
+ {14, 12},
+ {11, 13},
+ },
+ {
+ {15, 13},
+ {12, 14},
+ },
+ {
+ {16, 14},
+ {13, 15},
+ },
+ {
+ {17, 15},
+ {14, 16},
+ },
+ {
+ {18, 16},
+ {15, 17},
+ },
+ {
+ {19, 17},
+ {16, 18},
+ },
+ {
+ {20, 18},
+ {17, 19},
+ },
+ {
+ {21, 19},
+ {18, 20},
+ },
+ {
+ {22, 20},
+ {19, 21},
+ },
+ {
+ {23, 21},
+ {20, 22},
+ },
+ {
+ {24, 22},
+ {21, 23},
+ },
+ {
+ {25, 23},
+ {22, 24},
+ },
+ {
+ {26, 24},
+ {23, 25},
+ },
+ {
+ {27, 25},
+ {24, 26},
+ },
+ {
+ {28, 26},
+ {25, 27},
+ },
+ {
+ {29, 27},
+ {26, 28},
+ },
+ {
+ {30, 28},
+ {27, 29},
+ },
+ {
+ {31, 29},
+ {28, 30},
+ },
+ {
+ {32, 30},
+ {29, 31},
+ },
+ {
+ {33, 31},
+ {30, 32},
+ },
+ {
+ {34, 32},
+ {31, 33},
+ },
+ {
+ {35, 33},
+ {32, 34},
+ },
+ {
+ {36, 34},
+ {33, 35},
+ },
+ {
+ {37, 35},
+ {34, 36},
+ },
+ {
+ {38, 36},
+ {35, 37},
+ },
+ {
+ {39, 37},
+ {36, 38},
+ },
+ {
+ {40, 38},
+ {37, 39},
+ },
+ {
+ {41, 39},
+ {38, 40},
+ },
+ {
+ {42, 40},
+ {39, 41},
+ },
+ {
+ {43, 41},
+ {40, 42},
+ },
+ {
+ {44, 42},
+ {41, 43},
+ },
+ {
+ {45, 43},
+ {42, 44},
+ },
+ {
+ {46, 44},
+ {43, 45},
+ },
+ {
+ {47, 45},
+ {44, 46},
+ },
+ {
+ {48, 46},
+ {45, 47},
+ },
+ {
+ {49, 47},
+ {46, 48},
+ },
+ {
+ {50, 48},
+ {47, 49},
+ },
+ {
+ {51, 49},
+ {48, 50},
+ },
+ {
+ {52, 50},
+ {49, 51},
+ },
+ {
+ {53, 51},
+ {50, 52},
+ },
+ {
+ {54, 52},
+ {51, 53},
+ },
+ {
+ {55, 53},
+ {52, 54},
+ },
+ {
+ {56, 54},
+ {53, 55},
+ },
+ {
+ {57, 55},
+ {54, 56},
+ },
+ {
+ {58, 56},
+ {55, 57},
+ },
+ {
+ {59, 57},
+ {56, 58},
+ },
+ {
+ {60, 58},
+ {57, 59},
+ },
+ {
+ {61, 59},
+ {58, 60},
+ },
+ {
+ {62, 60},
+ {59, 61},
+ },
+ {
+ {63, 61},
+ {60, 62},
+ },
+ {
+ {64, 62},
+ {61, 63},
+ },
+ {
+ {65, 63},
+ {62, 64},
+ },
+ {
+ {66, 64},
+ {63, 65},
+ },
+ {
+ {67, 65},
+ {64, 66},
+ },
+ {
+ {68, 66},
+ {65, 67},
+ },
+ {
+ {69, 67},
+ {66, 68},
+ },
+ {
+ {70, 68},
+ {67, 69},
+ },
+ {
+ {71, 69},
+ {68, 70},
+ },
+ {
+ {72, 70},
+ {69, 71},
+ },
+ {
+ {73, 71},
+ {70, 72},
+ },
+ {
+ {74, 72},
+ {71, 73},
+ },
+ {
+ {75, 73},
+ {72, 74},
+ },
+ {
+ {76, 74},
+ {73, 75},
+ },
+ {
+ {77, 75},
+ {74, 76},
+ },
+ {
+ {78, 76},
+ {75, 77},
+ },
+ {
+ {79, 77},
+ {76, 78},
+ },
+ {
+ {80, 78},
+ {77, 79},
+ },
+ {
+ {81, 79},
+ {78, 80},
+ },
+ {
+ {82, 80},
+ {79, 81},
+ },
+ {
+ {83, 81},
+ {80, 82},
+ },
+ {
+ {84, 82},
+ {81, 83},
+ },
+ {
+ {85, 83},
+ {82, 84},
+ },
+ {
+ {86, 84},
+ {83, 85},
+ },
+ {
+ {87, 85},
+ {84, 86},
+ },
+ {
+ {88, 86},
+ {85, 87},
+ },
+ {
+ {89, 87},
+ {86, 88},
+ },
+ {
+ {90, 88},
+ {87, 89},
+ },
+ {
+ {91, 89},
+ {88, 90},
+ },
+ {
+ {92, 90},
+ {89, 91},
+ },
+ {
+ {93, 91},
+ {90, 92},
+ },
+ {
+ {94, 92},
+ {91, 93},
+ },
+ {
+ {95, 93},
+ {92, 94},
+ },
+ {
+ {96, 94},
+ {93, 95},
+ },
+ {
+ {97, 95},
+ {94, 96},
+ },
+ {
+ {98, 96},
+ {95, 97},
+ },
+ {
+ {99, 97},
+ {96, 98},
+ },
+ {
+ {100, 98},
+ {97, 99},
+ },
+ {
+ {101, 99},
+ {98, 100},
+ },
+ {
+ {102, 100},
+ {99, 101},
+ },
+ {
+ {103, 101},
+ {100, 102},
+ },
+ {
+ {104, 102},
+ {101, 103},
+ },
+ {
+ {105, 103},
+ {102, 104},
+ },
+ {
+ {106, 104},
+ {103, 105},
+ },
+ {
+ {107, 105},
+ {104, 106},
+ },
+ {
+ {108, 106},
+ {105, 107},
+ },
+ {
+ {109, 107},
+ {106, 108},
+ },
+ {
+ {110, 108},
+ {107, 109},
+ },
+ {
+ {111, 109},
+ {108, 110},
+ },
+ {
+ {112, 110},
+ {109, 111},
+ },
+ {
+ {113, 111},
+ {110, 112},
+ },
+ {
+ {114, 112},
+ {111, 113},
+ },
+ {
+ {115, 113},
+ {112, 114},
+ },
+ {
+ {116, 114},
+ {113, 115},
+ },
+ {
+ {117, 115},
+ {114, 116},
+ },
+ {
+ {118, 116},
+ {115, 117},
+ },
+ {
+ {119, 117},
+ {116, 118},
+ },
+ {
+ {120, 118},
+ {117, 119},
+ },
+ {
+ {121, 119},
+ {118, 120},
+ },
+ {
+ {122, 120},
+ {119, 121},
+ },
+ {
+ {123, 121},
+ {120, 122},
+ },
+ {
+ {124, 122},
+ {121, 123},
+ },
+ {
+ {125, 123},
+ {122, 124},
+ },
+ {
+ {126, 124},
+ {123, 125},
+ },
+ {
+ {127, 125},
+ {124, 126},
+ },
+ {
+ {128, 126},
+ {125, 127},
+ },
+ {
+ {129, 127},
+ {126, 128},
+ },
+ {
+ {130, 128},
+ {127, 129},
+ },
+ {
+ {131, 129},
+ {128, 130},
+ },
+ {
+ {132, 130},
+ {129, 131},
+ },
+ {
+ {133, 131},
+ {130, 132},
+ },
+ {
+ {134, 132},
+ {131, 133},
+ },
+ {
+ {135, 133},
+ {132, 134},
+ },
+ {
+ {136, 134},
+ {133, 135},
+ },
+ {
+ {137, 135},
+ {134, 136},
+ },
+ {
+ {138, 136},
+ {135, 137},
+ },
+ {
+ {139, 137},
+ {136, 138},
+ },
+ {
+ {140, 138},
+ {137, 139},
+ },
+ {
+ {141, 139},
+ {138, 140},
+ },
+ {
+ {142, 140},
+ {139, 141},
+ },
+ {
+ {143, 141},
+ {140, 142},
+ },
+ {
+ {144, 142},
+ {141, 143},
+ },
+ {
+ {145, 143},
+ {142, 144},
+ },
+ {
+ {146, 144},
+ {143, 145},
+ },
+ {
+ {147, 145},
+ {144, 146},
+ },
+ {
+ {148, 146},
+ {145, 147},
+ },
+ {
+ {149, 147},
+ {146, 148},
+ },
+ {
+ {150, 148},
+ {147, 149},
+ },
+ {
+ {151, 149},
+ {148, 150},
+ },
+ {
+ {152, 150},
+ {149, 151},
+ },
+ {
+ {153, 151},
+ {150, 152},
+ },
+ {
+ {154, 152},
+ {151, 153},
+ },
+ {
+ {155, 153},
+ {152, 154},
+ },
+ {
+ {156, 154},
+ {153, 155},
+ },
+ {
+ {157, 155},
+ {154, 156},
+ },
+ {
+ {158, 156},
+ {155, 157},
+ },
+ {
+ {159, 157},
+ {156, 158},
+ },
+ {
+ {160, 158},
+ {157, 159},
+ },
+ {
+ {161, 159},
+ {158, 160},
+ },
+ {
+ {162, 160},
+ {159, 161},
+ },
+ {
+ {163, 161},
+ {160, 162},
+ },
+ {
+ {164, 162},
+ {161, 163},
+ },
+ {
+ {165, 163},
+ {162, 164},
+ },
+ {
+ {166, 164},
+ {163, 165},
+ },
+ {
+ {167, 165},
+ {164, 166},
+ },
+ {
+ {168, 166},
+ {165, 167},
+ },
+ {
+ {169, 167},
+ {166, 168},
+ },
+ {
+ {170, 168},
+ {167, 169},
+ },
+ {
+ {171, 169},
+ {168, 170},
+ },
+ {
+ {172, 170},
+ {169, 171},
+ },
+ {
+ {173, 171},
+ {170, 172},
+ },
+ {
+ {174, 172},
+ {171, 173},
+ },
+ {
+ {175, 173},
+ {172, 174},
+ },
+ {
+ {176, 174},
+ {173, 175},
+ },
+ {
+ {177, 175},
+ {174, 176},
+ },
+ {
+ {178, 176},
+ {175, 177},
+ },
+ {
+ {179, 177},
+ {176, 178},
+ },
+ {
+ {180, 178},
+ {177, 179},
+ },
+ {
+ {181, 179},
+ {178, 180},
+ },
+ {
+ {182, 180},
+ {179, 181},
+ },
+ {
+ {183, 181},
+ {180, 182},
+ },
+ {
+ {184, 182},
+ {181, 183},
+ },
+ {
+ {185, 183},
+ {182, 184},
+ },
+ {
+ {186, 184},
+ {183, 185},
+ },
+ {
+ {187, 185},
+ {184, 186},
+ },
+ {
+ {188, 186},
+ {185, 187},
+ },
+ {
+ {189, 187},
+ {186, 188},
+ },
+ {
+ {190, 188},
+ {187, 189},
+ },
+ {
+ {191, 189},
+ {188, 190},
+ },
+ {
+ {192, 190},
+ {189, 191},
+ },
+ {
+ {193, 191},
+ {190, 192},
+ },
+ {
+ {194, 192},
+ {191, 193},
+ },
+ {
+ {195, 193},
+ {192, 194},
+ },
+ {
+ {196, 194},
+ {193, 195},
+ },
+ {
+ {197, 195},
+ {194, 196},
+ },
+ {
+ {198, 196},
+ {195, 197},
+ },
+ {
+ {199, 197},
+ {196, 198},
+ },
+ {
+ {200, 198},
+ {197, 199},
+ },
+ {
+ {201, 199},
+ {198, 200},
+ },
+ {
+ {202, 200},
+ {199, 201},
+ },
+ {
+ {203, 201},
+ {200, 202},
+ },
+ {
+ {204, 202},
+ {201, 203},
+ },
+ {
+ {205, 203},
+ {202, 204},
+ },
+ {
+ {206, 204},
+ {203, 205},
+ },
+ {
+ {207, 205},
+ {204, 206},
+ },
+ {
+ {208, 206},
+ {205, 207},
+ },
+ {
+ {209, 207},
+ {206, 208},
+ },
+ {
+ {210, 208},
+ {207, 209},
+ },
+ {
+ {211, 209},
+ {208, 210},
+ },
+ {
+ {212, 210},
+ {209, 211},
+ },
+ {
+ {213, 211},
+ {210, 212},
+ },
+ {
+ {214, 212},
+ {211, 213},
+ },
+ {
+ {215, 213},
+ {212, 214},
+ },
+ {
+ {216, 214},
+ {213, 215},
+ },
+ {
+ {217, 215},
+ {214, 216},
+ },
+ {
+ {218, 216},
+ {215, 217},
+ },
+ {
+ {219, 217},
+ {216, 218},
+ },
+ {
+ {220, 218},
+ {217, 219},
+ },
+ {
+ {221, 219},
+ {218, 220},
+ },
+ {
+ {222, 220},
+ {219, 221},
+ },
+ {
+ {223, 221},
+ {220, 222},
+ },
+ {
+ {224, 222},
+ {221, 223},
+ },
+ {
+ {225, 223},
+ {222, 224},
+ },
+ {
+ {226, 224},
+ {223, 225},
+ },
+ {
+ {227, 225},
+ {224, 226},
+ },
+ {
+ {228, 226},
+ {225, 227},
+ },
+ {
+ {229, 227},
+ {226, 228},
+ },
+ {
+ {230, 228},
+ {227, 229},
+ },
+ {
+ {231, 229},
+ {228, 230},
+ },
+ {
+ {232, 230},
+ {229, 231},
+ },
+ {
+ {233, 231},
+ {230, 232},
+ },
+ {
+ {234, 232},
+ {231, 233},
+ },
+ {
+ {235, 233},
+ {232, 234},
+ },
+ {
+ {236, 234},
+ {233, 235},
+ },
+ {
+ {237, 235},
+ {234, 236},
+ },
+ {
+ {238, 236},
+ {235, 237},
+ },
+ {
+ {239, 237},
+ {236, 238},
+ },
+ {
+ {240, 238},
+ {237, 239},
+ },
+ {
+ {241, 239},
+ {238, 240},
+ },
+ {
+ {242, 240},
+ {239, 241},
+ },
+ {
+ {243, 241},
+ {240, 242},
+ },
+ {
+ {244, 242},
+ {241, 243},
+ },
+ {
+ {245, 243},
+ {242, 244},
+ },
+ {
+ {246, 244},
+ {243, 245},
+ },
+ {
+ {247, 245},
+ {244, 246},
+ },
+ {
+ {248, 246},
+ {245, 247},
+ },
+ {
+ {249, 247},
+ {246, 248},
+ },
+ {
+ {250, 248},
+ {247, 249},
+ },
+ {
+ {251, 249},
+ {248, 250},
+ },
+ {
+ {252, 250},
+ {249, 251},
+ },
+ {
+ {253, 251},
+ {250, 252},
+ },
+ {
+ {254, 252},
+ {251, 253},
+ },
+ {
+ {255, 253},
+ {252, 254},
+ },
+ {
+ {255, 254},
+ {253, 255},
+ },
+ {
+ {255, 255},
+ {254, 255},
+ },
+};
+
+
+static const uint8_t dithersub_rb2x2[256][2][2] =
+{
+ {
+ {0, 0},
+ {0, 0},
+ },
+ {
+ {0, 0},
+ {0, 0},
+ },
+ {
+ {0, 0},
+ {0, 0},
+ },
+ {
+ {0, 0},
+ {0, 0},
+ },
+ {
+ {8, 4},
+ {2, 6},
+ },
+ {
+ {9, 5},
+ {3, 7},
+ },
+ {
+ {10, 6},
+ {4, 8},
+ },
+ {
+ {11, 7},
+ {5, 9},
+ },
+ {
+ {12, 8},
+ {6, 10},
+ },
+ {
+ {13, 9},
+ {7, 11},
+ },
+ {
+ {14, 10},
+ {8, 12},
+ },
+ {
+ {15, 11},
+ {9, 13},
+ },
+ {
+ {16, 12},
+ {10, 14},
+ },
+ {
+ {17, 13},
+ {11, 15},
+ },
+ {
+ {18, 14},
+ {12, 16},
+ },
+ {
+ {19, 15},
+ {13, 17},
+ },
+ {
+ {20, 16},
+ {14, 18},
+ },
+ {
+ {21, 17},
+ {15, 19},
+ },
+ {
+ {22, 18},
+ {16, 20},
+ },
+ {
+ {23, 19},
+ {17, 21},
+ },
+ {
+ {24, 20},
+ {18, 22},
+ },
+ {
+ {25, 21},
+ {19, 23},
+ },
+ {
+ {26, 22},
+ {20, 24},
+ },
+ {
+ {27, 23},
+ {21, 25},
+ },
+ {
+ {28, 24},
+ {22, 26},
+ },
+ {
+ {29, 25},
+ {23, 27},
+ },
+ {
+ {30, 26},
+ {24, 28},
+ },
+ {
+ {31, 27},
+ {25, 29},
+ },
+ {
+ {32, 28},
+ {26, 30},
+ },
+ {
+ {33, 29},
+ {27, 31},
+ },
+ {
+ {34, 30},
+ {28, 32},
+ },
+ {
+ {35, 31},
+ {29, 33},
+ },
+ {
+ {36, 32},
+ {30, 34},
+ },
+ {
+ {37, 33},
+ {31, 35},
+ },
+ {
+ {38, 34},
+ {32, 36},
+ },
+ {
+ {39, 35},
+ {33, 37},
+ },
+ {
+ {40, 36},
+ {34, 38},
+ },
+ {
+ {41, 37},
+ {35, 39},
+ },
+ {
+ {42, 38},
+ {36, 40},
+ },
+ {
+ {43, 39},
+ {37, 41},
+ },
+ {
+ {44, 40},
+ {38, 42},
+ },
+ {
+ {45, 41},
+ {39, 43},
+ },
+ {
+ {46, 42},
+ {40, 44},
+ },
+ {
+ {47, 43},
+ {41, 45},
+ },
+ {
+ {48, 44},
+ {42, 46},
+ },
+ {
+ {49, 45},
+ {43, 47},
+ },
+ {
+ {50, 46},
+ {44, 48},
+ },
+ {
+ {51, 47},
+ {45, 49},
+ },
+ {
+ {52, 48},
+ {46, 50},
+ },
+ {
+ {53, 49},
+ {47, 51},
+ },
+ {
+ {54, 50},
+ {48, 52},
+ },
+ {
+ {55, 51},
+ {49, 53},
+ },
+ {
+ {56, 52},
+ {50, 54},
+ },
+ {
+ {57, 53},
+ {51, 55},
+ },
+ {
+ {58, 54},
+ {52, 56},
+ },
+ {
+ {59, 55},
+ {53, 57},
+ },
+ {
+ {60, 56},
+ {54, 58},
+ },
+ {
+ {61, 57},
+ {55, 59},
+ },
+ {
+ {62, 58},
+ {56, 60},
+ },
+ {
+ {63, 59},
+ {57, 61},
+ },
+ {
+ {64, 60},
+ {58, 62},
+ },
+ {
+ {65, 61},
+ {59, 63},
+ },
+ {
+ {66, 62},
+ {60, 64},
+ },
+ {
+ {67, 63},
+ {61, 65},
+ },
+ {
+ {68, 64},
+ {62, 66},
+ },
+ {
+ {69, 65},
+ {63, 67},
+ },
+ {
+ {70, 66},
+ {64, 68},
+ },
+ {
+ {71, 67},
+ {65, 69},
+ },
+ {
+ {72, 68},
+ {66, 70},
+ },
+ {
+ {73, 69},
+ {67, 71},
+ },
+ {
+ {74, 70},
+ {68, 72},
+ },
+ {
+ {75, 71},
+ {69, 73},
+ },
+ {
+ {76, 72},
+ {70, 74},
+ },
+ {
+ {77, 73},
+ {71, 75},
+ },
+ {
+ {78, 74},
+ {72, 76},
+ },
+ {
+ {79, 75},
+ {73, 77},
+ },
+ {
+ {80, 76},
+ {74, 78},
+ },
+ {
+ {81, 77},
+ {75, 79},
+ },
+ {
+ {82, 78},
+ {76, 80},
+ },
+ {
+ {83, 79},
+ {77, 81},
+ },
+ {
+ {84, 80},
+ {78, 82},
+ },
+ {
+ {85, 81},
+ {79, 83},
+ },
+ {
+ {86, 82},
+ {80, 84},
+ },
+ {
+ {87, 83},
+ {81, 85},
+ },
+ {
+ {88, 84},
+ {82, 86},
+ },
+ {
+ {89, 85},
+ {83, 87},
+ },
+ {
+ {90, 86},
+ {84, 88},
+ },
+ {
+ {91, 87},
+ {85, 89},
+ },
+ {
+ {92, 88},
+ {86, 90},
+ },
+ {
+ {93, 89},
+ {87, 91},
+ },
+ {
+ {94, 90},
+ {88, 92},
+ },
+ {
+ {95, 91},
+ {89, 93},
+ },
+ {
+ {96, 92},
+ {90, 94},
+ },
+ {
+ {97, 93},
+ {91, 95},
+ },
+ {
+ {98, 94},
+ {92, 96},
+ },
+ {
+ {99, 95},
+ {93, 97},
+ },
+ {
+ {100, 96},
+ {94, 98},
+ },
+ {
+ {101, 97},
+ {95, 99},
+ },
+ {
+ {102, 98},
+ {96, 100},
+ },
+ {
+ {103, 99},
+ {97, 101},
+ },
+ {
+ {104, 100},
+ {98, 102},
+ },
+ {
+ {105, 101},
+ {99, 103},
+ },
+ {
+ {106, 102},
+ {100, 104},
+ },
+ {
+ {107, 103},
+ {101, 105},
+ },
+ {
+ {108, 104},
+ {102, 106},
+ },
+ {
+ {109, 105},
+ {103, 107},
+ },
+ {
+ {110, 106},
+ {104, 108},
+ },
+ {
+ {111, 107},
+ {105, 109},
+ },
+ {
+ {112, 108},
+ {106, 110},
+ },
+ {
+ {113, 109},
+ {107, 111},
+ },
+ {
+ {114, 110},
+ {108, 112},
+ },
+ {
+ {115, 111},
+ {109, 113},
+ },
+ {
+ {116, 112},
+ {110, 114},
+ },
+ {
+ {117, 113},
+ {111, 115},
+ },
+ {
+ {118, 114},
+ {112, 116},
+ },
+ {
+ {119, 115},
+ {113, 117},
+ },
+ {
+ {120, 116},
+ {114, 118},
+ },
+ {
+ {121, 117},
+ {115, 119},
+ },
+ {
+ {122, 118},
+ {116, 120},
+ },
+ {
+ {123, 119},
+ {117, 121},
+ },
+ {
+ {124, 120},
+ {118, 122},
+ },
+ {
+ {125, 121},
+ {119, 123},
+ },
+ {
+ {126, 122},
+ {120, 124},
+ },
+ {
+ {127, 123},
+ {121, 125},
+ },
+ {
+ {128, 124},
+ {122, 126},
+ },
+ {
+ {129, 125},
+ {123, 127},
+ },
+ {
+ {130, 126},
+ {124, 128},
+ },
+ {
+ {131, 127},
+ {125, 129},
+ },
+ {
+ {132, 128},
+ {126, 130},
+ },
+ {
+ {133, 129},
+ {127, 131},
+ },
+ {
+ {134, 130},
+ {128, 132},
+ },
+ {
+ {135, 131},
+ {129, 133},
+ },
+ {
+ {136, 132},
+ {130, 134},
+ },
+ {
+ {137, 133},
+ {131, 135},
+ },
+ {
+ {138, 134},
+ {132, 136},
+ },
+ {
+ {139, 135},
+ {133, 137},
+ },
+ {
+ {140, 136},
+ {134, 138},
+ },
+ {
+ {141, 137},
+ {135, 139},
+ },
+ {
+ {142, 138},
+ {136, 140},
+ },
+ {
+ {143, 139},
+ {137, 141},
+ },
+ {
+ {144, 140},
+ {138, 142},
+ },
+ {
+ {145, 141},
+ {139, 143},
+ },
+ {
+ {146, 142},
+ {140, 144},
+ },
+ {
+ {147, 143},
+ {141, 145},
+ },
+ {
+ {148, 144},
+ {142, 146},
+ },
+ {
+ {149, 145},
+ {143, 147},
+ },
+ {
+ {150, 146},
+ {144, 148},
+ },
+ {
+ {151, 147},
+ {145, 149},
+ },
+ {
+ {152, 148},
+ {146, 150},
+ },
+ {
+ {153, 149},
+ {147, 151},
+ },
+ {
+ {154, 150},
+ {148, 152},
+ },
+ {
+ {155, 151},
+ {149, 153},
+ },
+ {
+ {156, 152},
+ {150, 154},
+ },
+ {
+ {157, 153},
+ {151, 155},
+ },
+ {
+ {158, 154},
+ {152, 156},
+ },
+ {
+ {159, 155},
+ {153, 157},
+ },
+ {
+ {160, 156},
+ {154, 158},
+ },
+ {
+ {161, 157},
+ {155, 159},
+ },
+ {
+ {162, 158},
+ {156, 160},
+ },
+ {
+ {163, 159},
+ {157, 161},
+ },
+ {
+ {164, 160},
+ {158, 162},
+ },
+ {
+ {165, 161},
+ {159, 163},
+ },
+ {
+ {166, 162},
+ {160, 164},
+ },
+ {
+ {167, 163},
+ {161, 165},
+ },
+ {
+ {168, 164},
+ {162, 166},
+ },
+ {
+ {169, 165},
+ {163, 167},
+ },
+ {
+ {170, 166},
+ {164, 168},
+ },
+ {
+ {171, 167},
+ {165, 169},
+ },
+ {
+ {172, 168},
+ {166, 170},
+ },
+ {
+ {173, 169},
+ {167, 171},
+ },
+ {
+ {174, 170},
+ {168, 172},
+ },
+ {
+ {175, 171},
+ {169, 173},
+ },
+ {
+ {176, 172},
+ {170, 174},
+ },
+ {
+ {177, 173},
+ {171, 175},
+ },
+ {
+ {178, 174},
+ {172, 176},
+ },
+ {
+ {179, 175},
+ {173, 177},
+ },
+ {
+ {180, 176},
+ {174, 178},
+ },
+ {
+ {181, 177},
+ {175, 179},
+ },
+ {
+ {182, 178},
+ {176, 180},
+ },
+ {
+ {183, 179},
+ {177, 181},
+ },
+ {
+ {184, 180},
+ {178, 182},
+ },
+ {
+ {185, 181},
+ {179, 183},
+ },
+ {
+ {186, 182},
+ {180, 184},
+ },
+ {
+ {187, 183},
+ {181, 185},
+ },
+ {
+ {188, 184},
+ {182, 186},
+ },
+ {
+ {189, 185},
+ {183, 187},
+ },
+ {
+ {190, 186},
+ {184, 188},
+ },
+ {
+ {191, 187},
+ {185, 189},
+ },
+ {
+ {192, 188},
+ {186, 190},
+ },
+ {
+ {193, 189},
+ {187, 191},
+ },
+ {
+ {194, 190},
+ {188, 192},
+ },
+ {
+ {195, 191},
+ {189, 193},
+ },
+ {
+ {196, 192},
+ {190, 194},
+ },
+ {
+ {197, 193},
+ {191, 195},
+ },
+ {
+ {198, 194},
+ {192, 196},
+ },
+ {
+ {199, 195},
+ {193, 197},
+ },
+ {
+ {200, 196},
+ {194, 198},
+ },
+ {
+ {201, 197},
+ {195, 199},
+ },
+ {
+ {202, 198},
+ {196, 200},
+ },
+ {
+ {203, 199},
+ {197, 201},
+ },
+ {
+ {204, 200},
+ {198, 202},
+ },
+ {
+ {205, 201},
+ {199, 203},
+ },
+ {
+ {206, 202},
+ {200, 204},
+ },
+ {
+ {207, 203},
+ {201, 205},
+ },
+ {
+ {208, 204},
+ {202, 206},
+ },
+ {
+ {209, 205},
+ {203, 207},
+ },
+ {
+ {210, 206},
+ {204, 208},
+ },
+ {
+ {211, 207},
+ {205, 209},
+ },
+ {
+ {212, 208},
+ {206, 210},
+ },
+ {
+ {213, 209},
+ {207, 211},
+ },
+ {
+ {214, 210},
+ {208, 212},
+ },
+ {
+ {215, 211},
+ {209, 213},
+ },
+ {
+ {216, 212},
+ {210, 214},
+ },
+ {
+ {217, 213},
+ {211, 215},
+ },
+ {
+ {218, 214},
+ {212, 216},
+ },
+ {
+ {219, 215},
+ {213, 217},
+ },
+ {
+ {220, 216},
+ {214, 218},
+ },
+ {
+ {221, 217},
+ {215, 219},
+ },
+ {
+ {222, 218},
+ {216, 220},
+ },
+ {
+ {223, 219},
+ {217, 221},
+ },
+ {
+ {224, 220},
+ {218, 222},
+ },
+ {
+ {225, 221},
+ {219, 223},
+ },
+ {
+ {226, 222},
+ {220, 224},
+ },
+ {
+ {227, 223},
+ {221, 225},
+ },
+ {
+ {228, 224},
+ {222, 226},
+ },
+ {
+ {229, 225},
+ {223, 227},
+ },
+ {
+ {230, 226},
+ {224, 228},
+ },
+ {
+ {231, 227},
+ {225, 229},
+ },
+ {
+ {232, 228},
+ {226, 230},
+ },
+ {
+ {233, 229},
+ {227, 231},
+ },
+ {
+ {234, 230},
+ {228, 232},
+ },
+ {
+ {235, 231},
+ {229, 233},
+ },
+ {
+ {236, 232},
+ {230, 234},
+ },
+ {
+ {237, 233},
+ {231, 235},
+ },
+ {
+ {238, 234},
+ {232, 236},
+ },
+ {
+ {239, 235},
+ {233, 237},
+ },
+ {
+ {240, 236},
+ {234, 238},
+ },
+ {
+ {241, 237},
+ {235, 239},
+ },
+ {
+ {242, 238},
+ {236, 240},
+ },
+ {
+ {243, 239},
+ {237, 241},
+ },
+ {
+ {244, 240},
+ {238, 242},
+ },
+ {
+ {245, 241},
+ {239, 243},
+ },
+ {
+ {246, 242},
+ {240, 244},
+ },
+ {
+ {247, 243},
+ {241, 245},
+ },
+ {
+ {248, 244},
+ {242, 246},
+ },
+ {
+ {249, 245},
+ {243, 247},
+ },
+ {
+ {250, 246},
+ {244, 248},
+ },
+ {
+ {251, 247},
+ {245, 249},
+ },
+ {
+ {252, 248},
+ {246, 250},
+ },
+ {
+ {253, 249},
+ {247, 251},
+ },
+ {
+ {254, 250},
+ {248, 252},
+ },
+ {
+ {255, 251},
+ {249, 253},
+ },
+ {
+ {255, 252},
+ {250, 254},
+ },
+ {
+ {255, 253},
+ {251, 255},
+ },
+ {
+ {255, 254},
+ {252, 255},
+ },
+ {
+ {255, 255},
+ {253, 255},
+ },
+};
+
FBZ_DEPTH_BIAS = (1 << 16),
+ FBZ_DITHER_SUB = (1 << 19),
FBZ_DEPTH_SOURCE = (1 << 20),
FBZ_PARAM_ADJUST = (1 << 26)
#define depth_op ( (params->fbzMode >> 5) & 7)
#define dither ( params->fbzMode & FBZ_DITHER)
#define dither2x2 (params->fbzMode & FBZ_DITHER_2x2)
+#define dithersub (params->fbzMode & FBZ_DITHER_SUB)
+
uint8_t (__cdecl *voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y);
#endif
int y_diff = SLI_ENABLED ? 2 : 1;
+ int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? voodoo->y_origin_swap : (voodoo->v_disp-1);
if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH ||
(params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL)
int test_y;
if (params->fbzMode & (1 << 17))
- test_y = (voodoo->v_disp-1) - state->y;
+ test_y = y_origin - state->y;
else
test_y = state->y;
x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4);
if (params->fbzMode & (1 << 17))
- real_y = (voodoo->v_disp-1) - (real_y >> 4);
+ real_y = y_origin - (real_y >> 4);
else
real_y >>= 4;
ALPHA_TEST(src_a);
if (params->alphaMode & (1 << 4))
+ {
+ if (dithersub && !dither2x2 && voodoo->dithersub_enabled)
+ {
+ dest_r = dithersub_rb[dest_r][real_y & 3][x & 3];
+ dest_g = dithersub_g [dest_g][real_y & 3][x & 3];
+ dest_b = dithersub_rb[dest_b][real_y & 3][x & 3];
+ }
+ if (dithersub && dither2x2 && voodoo->dithersub_enabled)
+ {
+ dest_r = dithersub_rb2x2[dest_r][real_y & 1][x & 1];
+ dest_g = dithersub_g2x2 [dest_g][real_y & 1][x & 1];
+ dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1];
+ }
ALPHA_BLEND(src_r, src_g, src_b, src_a);
+ }
if (update)
{
-
#if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__)
#define NO_CODEGEN
#endif
typedef struct
{
uint32_t base;
- uint32_t limit;
- uint8_t access;
+ uint32_t limit, limit_raw;
+ uint8_t access, access2;
uint16_t seg;
uint32_t limit_low, limit_high;
int checked; /*Non-zero if selector is known to be valid*/
int8_t ssegs;
int8_t ismmx;
int8_t abrt;
+ int8_t smi_pending;
int _cycles;
int cpu_recomp_ins;
} CR0;
uint16_t flags, eflags;
+
+ uint32_t smbase;
} CPU_STATE;
extern CPU_STATE cpu_state;
#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128)
#define cycles cpu_state._cycles
+extern int cycles_main;
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
extern uint32_t cr2, cr3, cr4;
extern uint32_t dr[8];
+extern uint16_t sysenter_cs;
+extern uint32_t sysenter_eip, sysenter_esp;
+
extern uint16_t cpu_cur_status;
#define CPU_STATUS_STACK32 (1 << 1)
#define CPU_STATUS_PMODE (1 << 2)
#define CPU_STATUS_V86 (1 << 3)
+#define CPU_STATUS_SMM (1 << 4)
#define CPU_STATUS_FLAGS 0xff
/*If the flags below are set in cpu_cur_status, they must be set in block->status.
ABRT_PF = 0xE
};
+#define ABRT_MASK 0x7f
+/*An 'expected' exception is one that would be expected to occur on every execution
+ of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is
+ one that would be unlikely to occur on the next exception, eg a page fault may be
+ fixed up by the exception handler and the next execution would not hit it.
+
+ This distinction is used by the dynarec; a block that hits an 'expected' exception
+ would be compiled, a block that hits an 'unexpected' exception would be rejected so
+ that we don't end up with an unnecessarily short block*/
+#define ABRT_EXPECTED 0x80
extern uint32_t abrt_error;
void x86_doabrt(int x86_abrt);
void x86seg_reset();
void x86gpf(const char *s, uint16_t error);
+void x86gpf_expected(const char *s, uint16_t error);
void resetx86();
void softresetx86();
void x86_int_sw(int num);
int x86_int_sw_rm(int num);
+void sysenter(void);
+void sysexit(void);
+
int divl(uint32_t val);
int idivl(int32_t val);
+extern int cpu_end_block_after_ins;
+
+void x86_smi_trigger(void);
+void x86_smi_enter(void);
+void x86_smi_leave(void);
+
+void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg);
+void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
+
+#define SMHR_VALID (1 << 0)
+#define SMHR_ADDR_MASK (0xfffffffc)
+
+struct
+{
+ struct
+ {
+ uint32_t base;
+ uint64_t size;
+ } arr[8];
+ uint32_t smhr;
+} cyrix;
+
#endif
extern OpFn dynarec_ops_pentium_0f[1024];
extern OpFn dynarec_ops_pentiummmx_0f[1024];
+extern OpFn dynarec_ops_pentiumpro_0f[1024];
+extern OpFn dynarec_ops_pentium2_0f[1024];
+
+extern OpFn dynarec_ops_c6x86_0f[1024];
extern OpFn dynarec_ops_c6x86mx_0f[1024];
extern OpFn dynarec_ops_fpu_d8_a16[32];
extern OpFn ops_pentium_0f[1024];
extern OpFn ops_pentiummmx_0f[1024];
+extern OpFn ops_pentiumpro_0f[1024];
+extern OpFn ops_pentium2_0f[1024];
+extern OpFn ops_c6x86_0f[1024];
extern OpFn ops_c6x86mx_0f[1024];
extern OpFn ops_fpu_d8_a16[32];
--- /dev/null
+/*Cyrix-only instructions*/
+/*System Management Mode*/
+static void opSVDC_common(uint32_t fetchdat)
+{
+ switch (rmdat & 0x38)
+ {
+ case 0x00: /*ES*/
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
+ writememw(0, easeg+cpu_state.eaaddr+8, ES);
+ break;
+ case 0x08: /*CS*/
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs);
+ writememw(0, easeg+cpu_state.eaaddr+8, CS);
+ break;
+ case 0x18: /*DS*/
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
+ writememw(0, easeg+cpu_state.eaaddr+8, DS);
+ break;
+ case 0x10: /*SS*/
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
+ writememw(0, easeg+cpu_state.eaaddr+8, SS);
+ break;
+ case 0x20: /*FS*/
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
+ writememw(0, easeg+cpu_state.eaaddr+8, FS);
+ break;
+ case 0x28: /*GS*/
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
+ writememw(0, easeg+cpu_state.eaaddr+8, GS);
+ break;
+ default:
+ pclog("opSVDC: unknown rmdat %02x\n", rmdat);
+ x86illegal();
+ }
+}
+static int opSVDC_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_16(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ opSVDC_common(fetchdat);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+static int opSVDC_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_32(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ opSVDC_common(fetchdat);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+
+static void opRSDC_common(uint32_t fetchdat)
+{
+ switch (rmdat & 0x38)
+ {
+ case 0x00: /*ES*/
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
+ break;
+ case 0x18: /*DS*/
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
+ break;
+ case 0x10: /*SS*/
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
+ break;
+ case 0x20: /*FS*/
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
+ break;
+ case 0x28: /*GS*/
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
+ break;
+ default:
+ pclog("opRSDC: unknown rmdat %02x\n", rmdat);
+ x86illegal();
+ }
+}
+static int opRSDC_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_16(fetchdat);
+ SEG_CHECK_READ(cpu_state.ea_seg);
+ opRSDC_common(fetchdat);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+static int opRSDC_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_32(fetchdat);
+ SEG_CHECK_READ(cpu_state.ea_seg);
+ opRSDC_common(fetchdat);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+
+static int opSVLDT_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_16(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
+ writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+static int opSVLDT_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_32(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
+ writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+
+static int opRSLDT_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_16(fetchdat);
+ SEG_CHECK_READ(cpu_state.ea_seg);
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+static int opRSLDT_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_32(fetchdat);
+ SEG_CHECK_READ(cpu_state.ea_seg);
+ cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+
+static int opSVTS_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_16(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
+ writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+static int opSVTS_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_32(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
+ writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+
+static int opRSTS_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_16(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
+ writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+static int opRSTS_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ {
+ fetch_ea_32(fetchdat);
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
+ writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
+ }
+ else
+ x86illegal();
+
+ return cpu_state.abrt;
+}
+
+static int opSMINT(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ fatal("opSMINT\n");
+ else
+ x86illegal();
+
+ return 1;
+}
+
+static int opRDSHR_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ fatal("opRDSHR_a16\n");
+ else
+ x86illegal();
+
+ return 1;
+}
+static int opRDSHR_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ fatal("opRDSHR_a32\n");
+ else
+ x86illegal();
+
+ return 1;
+}
+
+static int opWRSHR_a16(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ fatal("opWRSHR_a16\n");
+ else
+ x86illegal();
+
+ return 1;
+}
+static int opWRSHR_a32(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ fatal("opWRSHR_a32\n");
+ else
+ x86illegal();
+
+ return 1;
+}
else
cpu_state.flags |= I_FLAG;
- CPU_BLOCK_END();
-
+ /*First instruction after STI will always execute, regardless of whether
+ there is a pending interrupt*/
+ cpu_end_block_after_ins = 2;
+
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
return 0;
}
}
}
- x86gpf(NULL,0);
+ x86gpf_expected(NULL,0);
return 1;
}
// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc);
AL = inb(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
AX = inw(port);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
outb(port, AL);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0);
- if (port == 0x64)
- return x86_was_reset;
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
+ if (port == 0x64)
+ return x86_was_reset;
return 0;
}
static int opOUT_AX_imm(uint32_t fetchdat)
outw(port, AX);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
outl(port, EAX);
CLOCK_CYCLES(10);
PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
AL = inb(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
AX = inw(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
EAX = inl(DX);
CLOCK_CYCLES(12);
PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
outb(DX, AL);
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return x86_was_reset;
outw(DX, AX);
CLOCK_CYCLES(11);
PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
check_io_perm(DX + 3);
outl(DX, EAX);
PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0);
+ if (cpu_state.smi_pending)
+ return 1;
if (nmi && nmi_enable && nmi_mask)
return 1;
return 0;
return 1;
}
+static int opSYSENTER(uint32_t fetchdat)
+{
+ if (!(cr0 & 1) || !(sysenter_cs & 0xfffc))
+ {
+ x86gpf(NULL,0);
+ return 1;
+ }
+// pclog("opSYSENTER: CS=%04x EIP=%08x ESP=%08x %04x:%08x %i\n", sysenter_cs, sysenter_eip, sysenter_esp, CS,cpu_state.pc, times);
+ sysenter();
+ CPU_BLOCK_END();
+ return 0;
+}
+
+static int opSYSEXIT(uint32_t fetchdat)
+{
+ if (!(cr0 & 1) || !(sysenter_cs & 0xfffc) || CPL)
+ {
+ x86gpf(NULL,0);
+ return 1;
+ }
+// pclog("opSYSEXIT\n");
+ sysexit();
+ CPU_BLOCK_END();
+ return 0;
+}
+
+static int opHINTNOP_a16(uint32_t fetchdat)
+{
+ fetch_ea_16(fetchdat);
+ return 0;
+}
+static int opHINTNOP_a32(uint32_t fetchdat)
+{
+ fetch_ea_32(fetchdat);
+ return 0;
+}
static int opMOVD_mm_l_a16(uint32_t fetchdat)
{
MMX_ENTER();
-
+
fetch_ea_16(fetchdat);
if (cpu_mod == 3)
{
static int opMOVD_mm_l_a32(uint32_t fetchdat)
{
MMX_ENTER();
+
+ fetch_ea_32(fetchdat);
+ if (cpu_mod == 3)
+ {
+ cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
+ CLOCK_CYCLES(1);
+ }
+ else
+ {
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
+ writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
+ CLOCK_CYCLES(2);
+ }
+ return 0;
+}
+
+/*Cyrix maps both MOVD and SMINT to the same opcode*/
+static int opMOVD_mm_l_a16_cx(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ return opSMINT(fetchdat);
+
+ MMX_ENTER();
+
+ fetch_ea_16(fetchdat);
+ if (cpu_mod == 3)
+ {
+ cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
+ CLOCK_CYCLES(1);
+ }
+ else
+ {
+ SEG_CHECK_WRITE(cpu_state.ea_seg);
+ CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
+ writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
+ CLOCK_CYCLES(2);
+ }
+ return 0;
+}
+static int opMOVD_mm_l_a32_cx(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ return opSMINT(fetchdat);
+
+ MMX_ENTER();
fetch_ea_32(fetchdat);
if (cpu_mod == 3)
int dpl, valid, granularity;
uint32_t addr, base, limit;
uint16_t desc, sel;
- uint8_t access;
+ uint8_t access, access2;
// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
switch (rmdat & 0x38)
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
access = readmemb(0, addr + 5);
+ access2 = readmemb(0, addr + 6);
granularity = readmemb(0, addr + 6) & 0x80;
if (cpu_state.abrt) return 1;
ldt.limit = limit;
+ ldt.limit_raw = limit;
ldt.access = access;
+ ldt.access2 = access2;
if (granularity)
{
ldt.limit <<= 12;
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
access = readmemb(0, addr + 5);
+ access2 = readmemb(0, addr + 6);
granularity = readmemb(0, addr + 6) & 0x80;
if (cpu_state.abrt) return 1;
access |= 2;
if (cpu_state.abrt) return 1;
tr.seg = sel;
tr.limit = limit;
+ tr.limit_raw = limit;
tr.access = access;
+ tr.access2 = access2;
if (granularity)
{
tr.limit <<= 12;
return op0F01_common(fetchdat, 0, 1, 0);
}
+
+
+static int opRSM(uint32_t fetchdat)
+{
+ if (cpu_cur_status & CPU_STATUS_SMM)
+ x86_smi_leave();
+ else
+ x86illegal();
+
+ return 1;
+}
}
else
{
- x86gpf(NULL,0);
+ x86gpf_expected(NULL,0);
return 1;
}
}
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
{
- x86gpf(NULL,0);
+ x86gpf_expected(NULL,0);
return 1;
}
if (msw & 1)
#include "cpu.h"
#include "config.h"
#include "paths.h"
+#include "i440bx.h"
/*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/
#define CS_ACCESSED
static void seg_reset(x86seg *s)
{
s->access = (0 << 5) | 2;
+ s->access2 = 0;
s->limit = 0xFFFF;
s->limit_low = 0;
s->limit_high = 0xffff;
}
void x86gpf(const char *s, uint16_t error)
{
-// pclog("GPF %04X\n", error);
+// pclog("GPF %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc);
cpu_state.abrt = ABRT_GPF;
abrt_error = error;
}
-void x86ss(const char *s, uint16_t error)
+void x86gpf_expected(const char *s, uint16_t error)
+{
+// pclog("GPF_v86 %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc);
+ cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
+ abrt_error = error;
+}
+void x86ss(char *s, uint16_t error)
{
// pclog("SS %04X\n", error);
cpu_state.abrt = ABRT_SS;
static void do_seg_load(x86seg *s, uint16_t *segdat)
{
s->limit = segdat[0] | ((segdat[3] & 0xF) << 16);
+ s->limit_raw = s->limit;
if (segdat[3] & 0x80)
s->limit = (s->limit << 12) | 0xFFF;
s->base = segdat[1] | ((segdat[2] & 0xFF) << 16);
if (is386)
s->base |= ((segdat[3] >> 8) << 24);
s->access = segdat[2] >> 8;
+ s->access2 = segdat[3] & 0xf0;
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
{
static void do_seg_v86_init(x86seg *s)
{
s->access = (3 << 5) | 2;
+ s->access2 = 0;
s->limit = 0xffff;
s->limit_low = 0;
s->limit_high = 0xffff;
else
{
s->access = (3 << 5) | 2;
+ s->access2 = 0;
s->base = seg << 4;
s->seg = seg;
s->checked = 1;
if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
if (!(segdat[2]&0x1F00))
{
- //pclog("No seg\n");
- x86gpf(NULL,(num*8)+2);
+// pclog("No seg\n");
+ if (cpu_state.eflags & VM_FLAG) /*This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn*/
+ x86gpf_expected(NULL,(num*8)+2);
+ else
+ x86gpf(NULL,(num*8)+2);
return;
}
if (DPL<CPL && soft)
tr.access=segdat[2]>>8;
}
+
+void sysenter(void)
+{
+ cpu_state.eflags &= ~VM_FLAG;
+ cpu_state.flags &= ~I_FLAG;
+
+ ESP = sysenter_esp;
+ cpu_state.pc = sysenter_eip;
+
+ cpu_state.seg_cs.seg = sysenter_cs & 0xfffc;
+ cpu_state.seg_cs.base = 0;
+ cpu_state.seg_cs.limit_low = 0;
+ cpu_state.seg_cs.limit = 0xffffffff;
+ cpu_state.seg_cs.limit_high = 0xffffffff;
+ cpu_state.seg_cs.access = 0x1b;
+ cpu_state.seg_cs.checked = 1;
+ oldcpl = 0;
+
+ cpu_state.seg_ss.seg = (sysenter_cs & 0xfffc) + 8;
+ cpu_state.seg_ss.base = 0;
+ cpu_state.seg_ss.limit_low = 0;
+ cpu_state.seg_ss.limit = 0xffffffff;
+ cpu_state.seg_ss.limit_high = 0xffffffff;
+ cpu_state.seg_ss.access = 0x13;
+ cpu_state.seg_ss.checked = 1;
+
+ cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86);
+ cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE);
+ set_use32(1);
+ set_stack32(1);
+
+// pclog("syscall to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP);
+}
+
+void sysexit(void)
+{
+ ESP = ECX;
+ cpu_state.pc = EDX;
+
+ cpu_state.seg_cs.seg = (sysenter_cs | 3) + 16;
+ cpu_state.seg_cs.base = 0;
+ cpu_state.seg_cs.limit_low = 0;
+ cpu_state.seg_cs.limit = 0xffffffff;
+ cpu_state.seg_cs.limit_high = 0xffffffff;
+ cpu_state.seg_cs.access = 0x7b;
+ cpu_state.seg_cs.checked = 1;
+ oldcpl = 3;
+
+ cpu_state.seg_ss.seg = (sysenter_cs | 3) + 24;
+ cpu_state.seg_ss.base = 0;
+ cpu_state.seg_ss.limit_low = 0;
+ cpu_state.seg_ss.limit = 0xffffffff;
+ cpu_state.seg_ss.limit_high = 0xffffffff;
+ cpu_state.seg_ss.access = 0x73;
+ cpu_state.seg_ss.checked = 1;
+
+ cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86);
+ cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE);
+ flushmmucache_cr3();
+ set_use32(1);
+ set_stack32(1);
+
+// pclog("sysexit to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP);
+}
+
+void x86_smi_trigger(void)
+{
+ cpu_state.smi_pending = 1;
+}
+
+static void smi_write_descriptor_cache(uint32_t addr, x86seg *seg)
+{
+ writememl(0, addr + 8, seg->seg | (seg->access << 16) | (seg->access2 << 24));
+ writememl(0, addr + 4, seg->base);
+ writememl(0, addr, seg->limit);
+}
+static void smi_load_descriptor_cache(uint32_t addr, x86seg *seg)
+{
+ uint32_t temp;
+
+ temp = readmeml(0, addr + 8);
+ seg->base = readmeml(0, addr + 4);
+ seg->limit = readmeml(0, addr);
+ seg->seg = temp & 0xffff;
+ seg->access = temp >> 16;
+ seg->access2 = temp >> 24;
+ if ((seg->access & 0x18) != 0x10 || !(seg->access & (1 << 2))) /*expand-down*/
+ {
+ seg->limit_high = seg->limit;
+ seg->limit_low = 0;
+ }
+ else
+ {
+ seg->limit_high = (seg->access2 & 0x40) ? 0xffffffff : 0xffff;
+ seg->limit_low = seg->limit + 1;
+ }
+}
+
+static void smi_load_smi_selector(x86seg *seg)
+{
+ seg->seg = 0;
+ seg->base = 0;
+ seg->limit = 0xffffffff;
+ seg->limit_low = 0;
+ seg->limit_high = 0xffffffff;
+ seg->access = (3 << 5) | 2;
+ seg->access2 = 0;
+}
+
+void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
+{
+ writememl(0, addr, (seg->limit_raw & 0xffff) | (seg->base << 16));
+ writememl(0, addr+4, ((seg->base >> 16) & 0xff) |
+ (seg->access << 8) |
+ (seg->limit_raw & 0xf0000) |
+ (seg->access2 << 16) |
+ (seg->base & 0xff000000));
+}
+
+void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
+{
+ uint16_t segdat[4], selector;
+
+ segdat[0] = readmemw(0, addr);
+ segdat[1] = readmemw(0, addr+2);
+ segdat[2] = readmemw(0, addr+4);
+ segdat[3] = readmemw(0, addr+6);
+ selector = readmemw(0, addr+8);
+
+ if (!cpu_state.abrt)
+ {
+ do_seg_load(seg, segdat);
+ seg->seg = selector;
+ seg->checked = 0;
+ if (seg == &cpu_state.seg_ds)
+ {
+ if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff)
+ cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
+ else
+ cpu_cur_status |= CPU_STATUS_NOTFLATDS;
+ codegen_flat_ds = 0;
+ }
+ if (seg == &cpu_state.seg_ss)
+ {
+ if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff)
+ cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
+ else
+ cpu_cur_status |= CPU_STATUS_NOTFLATSS;
+ set_stack32((segdat[3] & 0x40) ? 1 : 0);
+ codegen_flat_ss = 0;
+ }
+ }
+}
+
+void x86_smi_enter(void)
+{
+ uint32_t old_cr0 = cr0;
+
+ if (smram_enable)
+ smram_enable();
+ flushmmucache();
+
+ cpu_386_flags_rebuild();
+ cpl_override = 1;
+ cr0 = 0; /*Disable MMU*/
+
+ if (cpu_iscyrix)
+ {
+ uint32_t base;
+
+ if (!(cyrix.smhr & SMHR_VALID))
+ cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID;
+ base = cyrix.smhr & SMHR_ADDR_MASK;
+
+ writememl(0, base-4, dr[7]);
+ writememl(0, base-8, cpu_state.flags | (cpu_state.eflags << 16));
+ writememl(0, base-0xc, old_cr0);
+ writememl(0, base-0x10, cpu_state.oldpc);
+ writememl(0, base-0x14, cpu_state.pc);
+ writememl(0, base-0x18, CS | (CPL << 21));
+ cyrix_write_seg_descriptor(base-0x20, &cpu_state.seg_cs);
+ writememl(0, base-0x24, 0);
+
+ cpl_override = 0;
+
+ cpu_cur_status = CPU_STATUS_SMM;
+ cpu_state.flags = 2;
+ cpu_state.eflags = 0;
+ cpu_state.pc = 0;
+ cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31));
+ dr[7] = 0x400;
+ cpu_state.seg_cs.seg = cyrix.arr[3].base >> 4; /*Guess*/
+ cpu_state.seg_cs.base = cyrix.arr[3].base;
+ cpu_state.seg_cs.limit = 0xffffffff;
+ cpu_state.seg_cs.limit_low = 0;
+ cpu_state.seg_cs.limit_high = 0xffffffff;
+ cpu_state.seg_cs.access = (0 << 5) | 2;
+
+ use32 = 0;
+ stack32 = 0;
+ }
+ else
+ {
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16));
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs);
+ smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase);
+ writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000);
+ cpl_override = 0;
+
+ cpu_cur_status = CPU_STATUS_SMM;
+ cpu_state.flags = 2;
+ cpu_state.eflags = 0;
+ cpu_state.pc = 0x8000;
+ cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31));
+ dr[7] = 0x400;
+ smi_load_smi_selector(&cpu_state.seg_ds);
+ smi_load_smi_selector(&cpu_state.seg_es);
+ smi_load_smi_selector(&cpu_state.seg_fs);
+ smi_load_smi_selector(&cpu_state.seg_gs);
+ smi_load_smi_selector(&cpu_state.seg_ss);
+ cpu_state.seg_cs.seg = 0x3000;
+ cpu_state.seg_cs.base = cpu_state.smbase;
+ cpu_state.seg_cs.limit = 0xffffffff;
+ cpu_state.seg_cs.limit_low = 0;
+ cpu_state.seg_cs.limit_high = 0xffffffff;
+ cpu_state.seg_cs.access = (0 << 5) | 2;
+
+ use32 = 0;
+ stack32 = 0;
+ }
+
+ oldcpl = 0;
+
+// pclog("x86_smi_enter\n");
+}
+
+void x86_smi_leave(void)
+{
+ uint32_t temp;
+ uint32_t new_cr0;
+
+ if (cpu_iscyrix)
+ {
+ uint32_t base = cyrix.smhr & SMHR_ADDR_MASK;
+
+ cpl_override = 1;
+ dr[7] = readmeml(0, base-4);
+ temp = readmeml(0, base-8);
+ cpu_state.flags = temp & 0xffff;
+ cpu_state.eflags = temp >> 16;
+ new_cr0 = readmeml(0, base-0xc);
+ cpu_state.pc = readmeml(0, base-0x14);
+ cyrix_load_seg_descriptor(base-0x20, &cpu_state.seg_cs);
+ cpl_override = 0;
+
+ cr0 = new_cr0;
+ }
+ else
+ {
+ cpl_override = 1;
+ new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc);
+ cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8);
+ temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4);
+ cpu_state.flags = temp & 0xffff;
+ cpu_state.eflags = temp >> 16;
+ cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0);
+ EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec);
+ ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8);
+ EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4);
+ ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0);
+ EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc);
+ EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8);
+ ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4);
+ EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0);
+ dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc);
+ dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8);
+ tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4);
+ ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0);
+ cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc);
+ cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8);
+ cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4);
+ cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0);
+ cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac);
+ cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs);
+ smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es);
+ cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28);
+ cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8);
+ cpl_override = 0;
+
+ cr0 = new_cr0;
+ }
+
+ cpu_386_flags_extract();
+ cpu_cur_status = 0;
+ use32 = stack32 = 0;
+ if (cr0 & 1)
+ {
+ cpu_cur_status |= CPU_STATUS_PMODE;
+ if (cpu_state.eflags & VM_FLAG)
+ cpu_cur_status |= CPU_STATUS_V86;
+ else
+ {
+ if (cpu_state.seg_cs.access2 & 0x40)
+ {
+ cpu_cur_status |= CPU_STATUS_USE32;
+ use32 = 0x300;
+ }
+ if (cpu_state.seg_ss.access2 & 0x40)
+ {
+ cpu_cur_status |= CPU_STATUS_STACK32;
+ stack32 = 1;
+ }
+ }
+ }
+ if (!(cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff))
+ cpu_cur_status |= CPU_STATUS_NOTFLATDS;
+ if (!(cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff))
+ cpu_cur_status |= CPU_STATUS_NOTFLATSS;
+
+ if (smram_disable)
+ smram_disable();
+ flushmmucache();
+
+ oldcpl = CPL;
+
+// pclog("x86_smi_leave\n");
+}
cpu_state.pc++;
if (fplog) pclog("FSCALE\n");
temp64 = (int64_t)ST(1);
- ST(0) = ST(0) * pow(2.0, (double)temp64);
+ if (ST(0) != 0.0)
+ ST(0) = ST(0) * pow(2.0, (double)temp64);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
CLOCK_CYCLES(x87_timings.fscale);
return 0;
{
FP_ENTER();
if (fplog) pclog("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr);
+ cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11);
+
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/