mirror of
https://github.com/holub/mame
synced 2025-05-23 22:20:01 +03:00
CPU header cleanups....
i86/i286/i386/nec/v30mz: * renamed i86.h -> i86priv.h * renamed i86intrf.h -> i86.h * consolidated i88intrf.h, i186intf.h, i188intf.h, etc into i86.h m6805: * moved memory read/write macros out of public header m37710: * moved memory read/write macros out of public header spc700: * moved many structs/functions/macros out of public header tms32010: * moved memory read/write macros out of public header sm8500: * pointer-ified the core (apparently never had get/set context!) g65816: * moved memory read/write macros out of public header pic16c5x: * moved memory read/write macros out of public header t11: * moved memory read/write macros out of public header
This commit is contained in:
parent
785b6a50c6
commit
aa7e2482e2
13
.gitattributes
vendored
13
.gitattributes
vendored
@ -129,11 +129,11 @@ src/emu/cpu/i386/cycles.h svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386.h svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386dasm.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386intf.h svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386op16.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386op32.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386ops.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386ops.h svneol=native#text/plain
|
||||
src/emu/cpu/i386/i386priv.h svneol=native#text/plain
|
||||
src/emu/cpu/i386/i486ops.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/pentops.c svneol=native#text/plain
|
||||
src/emu/cpu/i386/x87ops.c svneol=native#text/plain
|
||||
@ -144,18 +144,15 @@ src/emu/cpu/i8085/i8085cpu.h svneol=native#text/plain
|
||||
src/emu/cpu/i8085/i8085daa.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/ea.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/host.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i186intf.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i188intf.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i286.c svneol=native#text/plain
|
||||
src/emu/cpu/i86/i286intf.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i286.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86.c svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86.txt svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86intf.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86mem.c svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86mem.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86priv.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/i86time.c svneol=native#text/plain
|
||||
src/emu/cpu/i86/i88intf.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/instr186.c svneol=native#text/plain
|
||||
src/emu/cpu/i86/instr186.h svneol=native#text/plain
|
||||
src/emu/cpu/i86/instr286.c svneol=native#text/plain
|
||||
@ -296,8 +293,8 @@ src/emu/cpu/nec/necdasm.c svneol=native#text/plain
|
||||
src/emu/cpu/nec/necea.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/nechost.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necinstr.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necintrf.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necmodrm.h svneol=native#text/plain
|
||||
src/emu/cpu/nec/necpriv.h svneol=native#text/plain
|
||||
src/emu/cpu/pdp1/pdp1.c svneol=native#text/plain
|
||||
src/emu/cpu/pdp1/pdp1.h svneol=native#text/plain
|
||||
src/emu/cpu/pdp1/pdp1dasm.c svneol=native#text/plain
|
||||
@ -431,10 +428,10 @@ src/emu/cpu/upd7810/7810ops.c svneol=native#text/plain
|
||||
src/emu/cpu/upd7810/7810tbl.c svneol=native#text/plain
|
||||
src/emu/cpu/upd7810/upd7810.c svneol=native#text/plain
|
||||
src/emu/cpu/upd7810/upd7810.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/nec.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/necea.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/nechost.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/necinstr.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/necintrf.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/necmodrm.h svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/v30mz.c svneol=native#text/plain
|
||||
src/emu/cpu/v30mz/v30mz.h svneol=native#text/plain
|
||||
|
@ -755,26 +755,25 @@ DBGOBJS += $(CPUOBJ)/i386/i386dasm.o
|
||||
endif
|
||||
|
||||
I86DEPS = \
|
||||
$(CPUSRC)/i86/i86.h \
|
||||
$(CPUSRC)/i86/i86priv.h \
|
||||
$(CPUSRC)/i86/ea.h \
|
||||
$(CPUSRC)/i86/host.h \
|
||||
$(CPUSRC)/i86/modrm.h
|
||||
|
||||
$(CPUOBJ)/i86/i86.o: $(CPUSRC)/i86/i86.c \
|
||||
$(CPUSRC)/i86/i86.h \
|
||||
$(CPUSRC)/i86/instr86.c \
|
||||
$(CPUSRC)/i86/instr186.c \
|
||||
$(CPUSRC)/i86/i86intf.h \
|
||||
$(CPUSRC)/i86/i186intf.h \
|
||||
$(I86DEPS)
|
||||
|
||||
$(CPUOBJ)/i86/i286.o: $(CPUSRC)/i86/i86.c \
|
||||
$(CPUOBJ)/i86/i286.o: $(CPUSRC)/i86/i286.c \
|
||||
$(CPUSRC)/i86/i286.h \
|
||||
$(CPUSRC)/i86/instr286.c \
|
||||
$(CPUSRC)/i86/i286intf.h \
|
||||
$(I86DEPS)
|
||||
|
||||
$(CPUOBJ)/i386/i386.o: $(CPUSRC)/i386/i386.c \
|
||||
$(CPUSRC)/i386/i386.h \
|
||||
$(CPUSRC)/i386/i386intf.h \
|
||||
$(CPUSRC)/i386/i386priv.h \
|
||||
$(CPUSRC)/i386/i386op16.c \
|
||||
$(CPUSRC)/i386/i386op32.c \
|
||||
$(CPUSRC)/i386/i386ops.c \
|
||||
@ -1274,11 +1273,11 @@ endif
|
||||
|
||||
$(CPUOBJ)/nec/nec.o: $(CPUSRC)/nec/nec.c \
|
||||
$(CPUSRC)/nec/nec.h \
|
||||
$(CPUSRC)/nec/necintrf.h \
|
||||
$(CPUSRC)/nec/necea.h \
|
||||
$(CPUSRC)/nec/nechost.h \
|
||||
$(CPUSRC)/nec/necinstr.h \
|
||||
$(CPUSRC)/nec/necmodrm.h
|
||||
$(CPUSRC)/nec/necmodrm.h \
|
||||
$(CPUSRC)/nec/necpriv.h
|
||||
|
||||
$(CPUOBJ)/v30mz/v30mz.o: $(CPUSRC)/v30mz/v30mz.c \
|
||||
$(CPUSRC)/v30mz/v30mz.h \
|
||||
@ -1286,7 +1285,7 @@ $(CPUOBJ)/v30mz/v30mz.o: $(CPUSRC)/v30mz/v30mz.c \
|
||||
$(CPUSRC)/v30mz/necinstr.h \
|
||||
$(CPUSRC)/v30mz/necea.h \
|
||||
$(CPUSRC)/v30mz/nechost.h \
|
||||
$(CPUSRC)/v30mz/necintrf.h
|
||||
$(CPUSRC)/v30mz/nec.h
|
||||
|
||||
|
||||
|
||||
|
@ -67,15 +67,6 @@ enum
|
||||
CPU_GET_INFO( g65816 );
|
||||
#define CPU_G65816 CPU_GET_INFO_NAME( g65816 )
|
||||
|
||||
#undef G65816_CALL_DEBUGGER
|
||||
#define G65816_CALL_DEBUGGER(x) debugger_instruction_hook(cpustate->device, x)
|
||||
|
||||
#define g65816_read_8(addr) memory_read_byte_8be(cpustate->program, addr)
|
||||
#define g65816_write_8(addr,data) memory_write_byte_8be(cpustate->program, addr,data)
|
||||
#define g65816_read_8_immediate(A) memory_read_byte_8be(cpustate->program, A)
|
||||
#define g65816_jumping(A)
|
||||
#define g65816_branching(A)
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
|
@ -9,6 +9,16 @@
|
||||
#define g65816i_jumping(A)
|
||||
|
||||
|
||||
#undef G65816_CALL_DEBUGGER
|
||||
#define G65816_CALL_DEBUGGER(x) debugger_instruction_hook(cpustate->device, x)
|
||||
|
||||
#define g65816_read_8(addr) memory_read_byte_8be(cpustate->program, addr)
|
||||
#define g65816_write_8(addr,data) memory_write_byte_8be(cpustate->program, addr,data)
|
||||
#define g65816_read_8_immediate(A) memory_read_byte_8be(cpustate->program, A)
|
||||
#define g65816_jumping(A)
|
||||
#define g65816_branching(A)
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================ INCLUDES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
@ -11,8 +11,8 @@
|
||||
*/
|
||||
|
||||
#include "debugger.h"
|
||||
#include "i386priv.h"
|
||||
#include "i386.h"
|
||||
#include "i386intf.h"
|
||||
|
||||
#include "debug/debugcpu.h"
|
||||
|
||||
|
@ -1,900 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __I386_H__
|
||||
#define __I386_H__
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
#define I386OP(XX) i386_##XX
|
||||
#define I486OP(XX) i486_##XX
|
||||
#define PENTIUMOP(XX) pentium_##XX
|
||||
#define MMXOP(XX) mmx_##XX
|
||||
#ifndef __I386INTF_H__
|
||||
#define __I386INTF_H__
|
||||
|
||||
#define INPUT_LINE_A20 1
|
||||
|
||||
extern int i386_dasm_one(char *buffer, UINT32 pc, const UINT8 *oprom, int mode);
|
||||
#include "cpuintrf.h"
|
||||
|
||||
typedef enum { ES, CS, SS, DS, FS, GS } SREGS;
|
||||
CPU_GET_INFO( i386 );
|
||||
CPU_GET_INFO( i486 );
|
||||
CPU_GET_INFO( pentium );
|
||||
CPU_GET_INFO( mediagx );
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum
|
||||
{
|
||||
AL = 0,
|
||||
AH = 1,
|
||||
CL = 4,
|
||||
CH = 5,
|
||||
DL = 8,
|
||||
DH = 9,
|
||||
BL = 12,
|
||||
BH = 13
|
||||
} BREGS;
|
||||
#else
|
||||
typedef enum
|
||||
{
|
||||
AL = 3,
|
||||
AH = 2,
|
||||
CL = 7,
|
||||
CH = 6,
|
||||
DL = 11,
|
||||
DH = 10,
|
||||
BL = 15,
|
||||
BH = 14
|
||||
} BREGS;
|
||||
#endif
|
||||
#define CPU_I386 CPU_GET_INFO_NAME( i386 )
|
||||
#define CPU_I486 CPU_GET_INFO_NAME( i486 )
|
||||
#define CPU_PENTIUM CPU_GET_INFO_NAME( pentium )
|
||||
#define CPU_MEDIAGX CPU_GET_INFO_NAME( mediagx )
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum
|
||||
{
|
||||
AX = 0,
|
||||
CX = 2,
|
||||
DX = 4,
|
||||
BX = 6,
|
||||
SP = 8,
|
||||
BP = 10,
|
||||
SI = 12,
|
||||
DI = 14
|
||||
} WREGS;
|
||||
#else
|
||||
typedef enum
|
||||
{
|
||||
AX = 1,
|
||||
CX = 3,
|
||||
DX = 5,
|
||||
BX = 7,
|
||||
SP = 9,
|
||||
BP = 11,
|
||||
SI = 13,
|
||||
DI = 15
|
||||
} WREGS;
|
||||
#endif
|
||||
|
||||
typedef enum { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI } DREGS;
|
||||
|
||||
enum
|
||||
{
|
||||
I386_PC = 0,
|
||||
|
||||
/* 8-bit registers */
|
||||
I386_AL,
|
||||
I386_AH,
|
||||
I386_BL,
|
||||
I386_BH,
|
||||
I386_CL,
|
||||
I386_CH,
|
||||
I386_DL,
|
||||
I386_DH,
|
||||
|
||||
/* 16-bit registers */
|
||||
I386_AX,
|
||||
I386_BX,
|
||||
I386_CX,
|
||||
I386_DX,
|
||||
I386_BP,
|
||||
I386_SP,
|
||||
I386_SI,
|
||||
I386_DI,
|
||||
I386_IP,
|
||||
|
||||
/* 32-bit registers */
|
||||
I386_EAX,
|
||||
I386_ECX,
|
||||
I386_EDX,
|
||||
I386_EBX,
|
||||
I386_EBP,
|
||||
I386_ESP,
|
||||
I386_ESI,
|
||||
I386_EDI,
|
||||
I386_EIP,
|
||||
|
||||
/* segment registers */
|
||||
I386_CS,
|
||||
I386_CS_BASE,
|
||||
I386_CS_LIMIT,
|
||||
I386_CS_FLAGS,
|
||||
I386_SS,
|
||||
I386_SS_BASE,
|
||||
I386_SS_LIMIT,
|
||||
I386_SS_FLAGS,
|
||||
I386_DS,
|
||||
I386_DS_BASE,
|
||||
I386_DS_LIMIT,
|
||||
I386_DS_FLAGS,
|
||||
I386_ES,
|
||||
I386_ES_BASE,
|
||||
I386_ES_LIMIT,
|
||||
I386_ES_FLAGS,
|
||||
I386_FS,
|
||||
I386_FS_BASE,
|
||||
I386_FS_LIMIT,
|
||||
I386_FS_FLAGS,
|
||||
I386_GS,
|
||||
I386_GS_BASE,
|
||||
I386_GS_LIMIT,
|
||||
I386_GS_FLAGS,
|
||||
|
||||
/* other */
|
||||
I386_EFLAGS,
|
||||
|
||||
I386_CR0,
|
||||
I386_CR1,
|
||||
I386_CR2,
|
||||
I386_CR3,
|
||||
|
||||
I386_DR0,
|
||||
I386_DR1,
|
||||
I386_DR2,
|
||||
I386_DR3,
|
||||
I386_DR4,
|
||||
I386_DR5,
|
||||
I386_DR6,
|
||||
I386_DR7,
|
||||
|
||||
I386_TR6,
|
||||
I386_TR7,
|
||||
|
||||
I386_GDTR_BASE,
|
||||
I386_GDTR_LIMIT,
|
||||
I386_IDTR_BASE,
|
||||
I386_IDTR_LIMIT,
|
||||
I386_TR,
|
||||
I386_TR_BASE,
|
||||
I386_TR_LIMIT,
|
||||
I386_TR_FLAGS,
|
||||
I386_LDTR,
|
||||
I386_LDTR_BASE,
|
||||
I386_LDTR_LIMIT,
|
||||
I386_LDTR_FLAGS,
|
||||
|
||||
X87_CTRL,
|
||||
X87_STATUS,
|
||||
X87_ST0,
|
||||
X87_ST1,
|
||||
X87_ST2,
|
||||
X87_ST3,
|
||||
X87_ST4,
|
||||
X87_ST5,
|
||||
X87_ST6,
|
||||
X87_ST7,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINT16 selector;
|
||||
UINT16 flags;
|
||||
UINT32 base;
|
||||
UINT32 limit;
|
||||
int d; // Operand size
|
||||
} I386_SREG;
|
||||
|
||||
typedef struct {
|
||||
UINT32 base;
|
||||
UINT16 limit;
|
||||
} I386_SYS_TABLE;
|
||||
|
||||
typedef struct {
|
||||
UINT16 segment;
|
||||
UINT16 flags;
|
||||
UINT32 base;
|
||||
UINT32 limit;
|
||||
} I386_SEG_DESC;
|
||||
|
||||
typedef union {
|
||||
UINT32 d[8];
|
||||
UINT16 w[16];
|
||||
UINT8 b[32];
|
||||
} I386_GPR;
|
||||
|
||||
typedef union {
|
||||
UINT64 i;
|
||||
double f;
|
||||
} X87_REG;
|
||||
|
||||
typedef struct _i386_state i386_state;
|
||||
struct _i386_state
|
||||
{
|
||||
I386_GPR reg;
|
||||
I386_SREG sreg[6];
|
||||
UINT32 eip;
|
||||
UINT32 pc;
|
||||
UINT32 prev_eip;
|
||||
UINT32 eflags;
|
||||
UINT8 CF;
|
||||
UINT8 DF;
|
||||
UINT8 SF;
|
||||
UINT8 OF;
|
||||
UINT8 ZF;
|
||||
UINT8 PF;
|
||||
UINT8 AF;
|
||||
UINT8 IF;
|
||||
UINT8 TF;
|
||||
|
||||
UINT8 performed_intersegment_jump;
|
||||
|
||||
UINT32 cr[4]; // Control registers
|
||||
UINT32 dr[8]; // Debug registers
|
||||
UINT32 tr[8]; // Test registers
|
||||
|
||||
I386_SYS_TABLE gdtr; // Global Descriptor Table Register
|
||||
I386_SYS_TABLE idtr; // Interrupt Descriptor Table Register
|
||||
I386_SEG_DESC task; // Task register
|
||||
I386_SEG_DESC ldtr; // Local Descriptor Table Register
|
||||
|
||||
int halted;
|
||||
|
||||
int operand_size;
|
||||
int address_size;
|
||||
|
||||
int segment_prefix;
|
||||
int segment_override;
|
||||
|
||||
int cycles;
|
||||
int base_cycles;
|
||||
UINT8 opcode;
|
||||
|
||||
UINT8 irq_state;
|
||||
cpu_irq_callback irq_callback;
|
||||
const device_config *device;
|
||||
const address_space *program;
|
||||
const address_space *io;
|
||||
UINT32 a20_mask;
|
||||
|
||||
int cpuid_max_input_value_eax;
|
||||
UINT32 cpuid_id0, cpuid_id1, cpuid_id2;
|
||||
UINT32 cpu_version;
|
||||
UINT32 feature_flags;
|
||||
UINT64 tsc;
|
||||
|
||||
// FPU
|
||||
X87_REG fpu_reg[8];
|
||||
UINT16 fpu_control_word;
|
||||
UINT16 fpu_status_word;
|
||||
UINT16 fpu_tag_word;
|
||||
UINT64 fpu_data_ptr;
|
||||
UINT64 fpu_inst_ptr;
|
||||
UINT16 fpu_opcode;
|
||||
int fpu_top;
|
||||
|
||||
void (*opcode_table1_16[256])(i386_state *cpustate);
|
||||
void (*opcode_table1_32[256])(i386_state *cpustate);
|
||||
void (*opcode_table2_16[256])(i386_state *cpustate);
|
||||
void (*opcode_table2_32[256])(i386_state *cpustate);
|
||||
|
||||
UINT8 *cycle_table_pm;
|
||||
UINT8 *cycle_table_rm;
|
||||
};
|
||||
|
||||
|
||||
extern int i386_parity_table[256];
|
||||
|
||||
#define PROTECTED_MODE (cpustate->cr[0] & 0x1)
|
||||
#define STACK_32BIT (cpustate->sreg[SS].d)
|
||||
#define V8086_MODE (cpustate->eflags & 0x00020000)
|
||||
|
||||
#define SetOF_Add32(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80000000) ? 1: 0)
|
||||
#define SetOF_Add16(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? 1 : 0)
|
||||
#define SetOF_Add8(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? 1 : 0)
|
||||
|
||||
#define SetOF_Sub32(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80000000) ? 1 : 0)
|
||||
#define SetOF_Sub16(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? 1 : 0)
|
||||
#define SetOF_Sub8(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? 1 : 0)
|
||||
|
||||
#define SetCF8(x) {cpustate->CF = ((x) & 0x100) ? 1 : 0; }
|
||||
#define SetCF16(x) {cpustate->CF = ((x) & 0x10000) ? 1 : 0; }
|
||||
#define SetCF32(x) {cpustate->CF = ((x) & (((UINT64)1) << 32)) ? 1 : 0; }
|
||||
|
||||
#define SetSF(x) (cpustate->SF = (x))
|
||||
#define SetZF(x) (cpustate->ZF = (x))
|
||||
#define SetAF(x,y,z) (cpustate->AF = (((x) ^ ((y) ^ (z))) & 0x10) ? 1 : 0)
|
||||
#define SetPF(x) (cpustate->PF = i386_parity_table[(x) & 0xFF])
|
||||
|
||||
#define SetSZPF8(x) {cpustate->ZF = ((UINT8)(x)==0); cpustate->SF = ((x)&0x80) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
|
||||
#define SetSZPF16(x) {cpustate->ZF = ((UINT16)(x)==0); cpustate->SF = ((x)&0x8000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
|
||||
#define SetSZPF32(x) {cpustate->ZF = ((UINT32)(x)==0); cpustate->SF = ((x)&0x80000000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
int b;
|
||||
int w;
|
||||
int d;
|
||||
} reg;
|
||||
struct {
|
||||
int b;
|
||||
int w;
|
||||
int d;
|
||||
} rm;
|
||||
} MODRM_TABLE;
|
||||
|
||||
extern MODRM_TABLE i386_MODRM_table[256];
|
||||
|
||||
#define REG8(x) (cpustate->reg.b[x])
|
||||
#define REG16(x) (cpustate->reg.w[x])
|
||||
#define REG32(x) (cpustate->reg.d[x])
|
||||
|
||||
#define LOAD_REG8(x) (REG8(i386_MODRM_table[x].reg.b))
|
||||
#define LOAD_REG16(x) (REG16(i386_MODRM_table[x].reg.w))
|
||||
#define LOAD_REG32(x) (REG32(i386_MODRM_table[x].reg.d))
|
||||
#define LOAD_RM8(x) (REG8(i386_MODRM_table[x].rm.b))
|
||||
#define LOAD_RM16(x) (REG16(i386_MODRM_table[x].rm.w))
|
||||
#define LOAD_RM32(x) (REG32(i386_MODRM_table[x].rm.d))
|
||||
|
||||
#define STORE_REG8(x, value) (REG8(i386_MODRM_table[x].reg.b) = value)
|
||||
#define STORE_REG16(x, value) (REG16(i386_MODRM_table[x].reg.w) = value)
|
||||
#define STORE_REG32(x, value) (REG32(i386_MODRM_table[x].reg.d) = value)
|
||||
#define STORE_RM8(x, value) (REG8(i386_MODRM_table[x].rm.b) = value)
|
||||
#define STORE_RM16(x, value) (REG16(i386_MODRM_table[x].rm.w) = value)
|
||||
#define STORE_RM32(x, value) (REG32(i386_MODRM_table[x].rm.d) = value)
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
INLINE UINT32 i386_translate(i386_state *cpustate, int segment, UINT32 ip)
|
||||
{
|
||||
// TODO: segment limit
|
||||
return cpustate->sreg[segment].base + ip;
|
||||
}
|
||||
|
||||
INLINE int translate_address(i386_state *cpustate, UINT32 *address)
|
||||
{
|
||||
UINT32 a = *address;
|
||||
UINT32 pdbr = cpustate->cr[3] & 0xfffff000;
|
||||
UINT32 directory = (a >> 22) & 0x3ff;
|
||||
UINT32 table = (a >> 12) & 0x3ff;
|
||||
UINT32 offset = a & 0xfff;
|
||||
|
||||
// TODO: 4MB pages
|
||||
UINT32 page_dir = memory_read_dword_32le(cpustate->program, pdbr + directory * 4);
|
||||
UINT32 page_entry = memory_read_dword_32le(cpustate->program, (page_dir & 0xfffff000) + (table * 4));
|
||||
|
||||
*address = (page_entry & 0xfffff000) | offset;
|
||||
return 1;
|
||||
}
|
||||
|
||||
INLINE void CHANGE_PC(i386_state *cpustate, UINT32 pc)
|
||||
{
|
||||
UINT32 address;
|
||||
cpustate->pc = i386_translate(cpustate, CS, pc );
|
||||
|
||||
address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void NEAR_BRANCH(i386_state *cpustate, INT32 offs)
|
||||
{
|
||||
UINT32 address;
|
||||
/* TODO: limit */
|
||||
cpustate->eip += offs;
|
||||
cpustate->pc += offs;
|
||||
|
||||
address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE UINT8 FETCH(i386_state *cpustate)
|
||||
{
|
||||
UINT8 value;
|
||||
UINT32 address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
value = memory_decrypted_read_byte(cpustate->program, address & cpustate->a20_mask);
|
||||
cpustate->eip++;
|
||||
cpustate->pc++;
|
||||
return value;
|
||||
}
|
||||
INLINE UINT16 FETCH16(i386_state *cpustate)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
if( address & 0x1 ) { /* Unaligned read */
|
||||
address &= cpustate->a20_mask;
|
||||
value = (memory_decrypted_read_byte(cpustate->program, address+0) << 0) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+1) << 8);
|
||||
} else {
|
||||
address &= cpustate->a20_mask;
|
||||
value = memory_decrypted_read_word(cpustate->program, address);
|
||||
}
|
||||
cpustate->eip += 2;
|
||||
cpustate->pc += 2;
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 FETCH32(i386_state *cpustate)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
if( cpustate->pc & 0x3 ) { /* Unaligned read */
|
||||
address &= cpustate->a20_mask;
|
||||
value = (memory_decrypted_read_byte(cpustate->program, address+0) << 0) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+1) << 8) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+2) << 16) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+3) << 24);
|
||||
} else {
|
||||
address &= cpustate->a20_mask;
|
||||
value = memory_decrypted_read_dword(cpustate->program, address);
|
||||
}
|
||||
cpustate->eip += 4;
|
||||
cpustate->pc += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE UINT8 READ8(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
return memory_read_byte_32le(cpustate->program, address);
|
||||
}
|
||||
INLINE UINT16 READ16(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x1 ) { /* Unaligned read */
|
||||
value = (memory_read_byte_32le( cpustate->program, address+0 ) << 0) |
|
||||
(memory_read_byte_32le( cpustate->program, address+1 ) << 8);
|
||||
} else {
|
||||
value = memory_read_word_32le( cpustate->program, address );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 READ32(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x3 ) { /* Unaligned read */
|
||||
value = (memory_read_byte_32le( cpustate->program, address+0 ) << 0) |
|
||||
(memory_read_byte_32le( cpustate->program, address+1 ) << 8) |
|
||||
(memory_read_byte_32le( cpustate->program, address+2 ) << 16) |
|
||||
(memory_read_byte_32le( cpustate->program, address+3 ) << 24);
|
||||
} else {
|
||||
value = memory_read_dword_32le( cpustate->program, address );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE UINT64 READ64(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT64 value;
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x7 ) { /* Unaligned read */
|
||||
value = (((UINT64) memory_read_byte_32le( cpustate->program, address+0 )) << 0) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+1 )) << 8) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+2 )) << 16) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+3 )) << 24) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+4 )) << 32) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+5 )) << 40) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+6 )) << 48) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+7 )) << 56);
|
||||
} else {
|
||||
value = (((UINT64) memory_read_dword_32le( cpustate->program, address+0 )) << 0) |
|
||||
(((UINT64) memory_read_dword_32le( cpustate->program, address+4 )) << 32);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE void WRITE8(i386_state *cpustate,UINT32 ea, UINT8 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
memory_write_byte_32le(cpustate->program, address, value);
|
||||
}
|
||||
INLINE void WRITE16(i386_state *cpustate,UINT32 ea, UINT16 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x1 ) { /* Unaligned write */
|
||||
memory_write_byte_32le( cpustate->program, address+0, value & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+1, (value >> 8) & 0xff );
|
||||
} else {
|
||||
memory_write_word_32le(cpustate->program, address, value);
|
||||
}
|
||||
}
|
||||
INLINE void WRITE32(i386_state *cpustate,UINT32 ea, UINT32 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
ea &= cpustate->a20_mask;
|
||||
if( ea & 0x3 ) { /* Unaligned write */
|
||||
memory_write_byte_32le( cpustate->program, address+0, value & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+1, (value >> 8) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+2, (value >> 16) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+3, (value >> 24) & 0xff );
|
||||
} else {
|
||||
memory_write_dword_32le(cpustate->program, address, value);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void WRITE64(i386_state *cpustate,UINT32 ea, UINT64 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
ea &= cpustate->a20_mask;
|
||||
if( ea & 0x7 ) { /* Unaligned write */
|
||||
memory_write_byte_32le( cpustate->program, address+0, value & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+1, (value >> 8) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+2, (value >> 16) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+3, (value >> 24) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+4, (value >> 32) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+5, (value >> 40) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+6, (value >> 48) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+7, (value >> 56) & 0xff );
|
||||
} else {
|
||||
memory_write_dword_32le(cpustate->program, address+0, value & 0xffffffff);
|
||||
memory_write_dword_32le(cpustate->program, address+4, (value >> 32) & 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
INLINE UINT8 OR8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT8 res = dst | src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF8(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT16 OR16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT16 res = dst | src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF16(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT32 OR32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT32 res = dst | src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE UINT8 AND8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT8 res = dst & src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF8(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT16 AND16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT16 res = dst & src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF16(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT32 AND32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT32 res = dst & src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE UINT8 XOR8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT8 res = dst ^ src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF8(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT16 XOR16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT16 res = dst ^ src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF16(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT32 XOR32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT32 res = dst ^ src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE UINT8 SUB8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT16 res = (UINT16)dst - (UINT16)src;
|
||||
SetCF8(res);
|
||||
SetOF_Sub8(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 SUB16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT32 res = (UINT32)dst - (UINT32)src;
|
||||
SetCF16(res);
|
||||
SetOF_Sub16(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 SUB32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT64 res = (UINT64)dst - (UINT64)src;
|
||||
SetCF32(res);
|
||||
SetOF_Sub32(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
INLINE UINT8 ADD8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT16 res = (UINT16)dst + (UINT16)src;
|
||||
SetCF8(res);
|
||||
SetOF_Add8(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 ADD16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT32 res = (UINT32)dst + (UINT32)src;
|
||||
SetCF16(res);
|
||||
SetOF_Add16(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 ADD32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT64 res = (UINT64)dst + (UINT64)src;
|
||||
SetCF32(res);
|
||||
SetOF_Add32(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
INLINE UINT8 INC8(i386_state *cpustate,UINT8 dst)
|
||||
{
|
||||
UINT16 res = (UINT16)dst + 1;
|
||||
SetOF_Add8(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 INC16(i386_state *cpustate,UINT16 dst)
|
||||
{
|
||||
UINT32 res = (UINT32)dst + 1;
|
||||
SetOF_Add16(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 INC32(i386_state *cpustate,UINT32 dst)
|
||||
{
|
||||
UINT64 res = (UINT64)dst + 1;
|
||||
SetOF_Add32(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
INLINE UINT8 DEC8(i386_state *cpustate,UINT8 dst)
|
||||
{
|
||||
UINT16 res = (UINT16)dst - 1;
|
||||
SetOF_Sub8(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 DEC16(i386_state *cpustate,UINT16 dst)
|
||||
{
|
||||
UINT32 res = (UINT32)dst - 1;
|
||||
SetOF_Sub16(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 DEC32(i386_state *cpustate,UINT32 dst)
|
||||
{
|
||||
UINT64 res = (UINT64)dst - 1;
|
||||
SetOF_Sub32(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INLINE void PUSH16(i386_state *cpustate,UINT16 value)
|
||||
{
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) -= 2;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
WRITE16(cpustate, ea, value );
|
||||
} else {
|
||||
REG16(SP) -= 2;
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
WRITE16(cpustate, ea, value );
|
||||
}
|
||||
}
|
||||
INLINE void PUSH32(i386_state *cpustate,UINT32 value)
|
||||
{
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) -= 4;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
WRITE32(cpustate, ea, value );
|
||||
} else {
|
||||
REG16(SP) -= 4;
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
WRITE32(cpustate, ea, value );
|
||||
}
|
||||
}
|
||||
INLINE void PUSH8(i386_state *cpustate,UINT8 value)
|
||||
{
|
||||
if( cpustate->operand_size ) {
|
||||
PUSH32(cpustate,(INT32)(INT8)value);
|
||||
} else {
|
||||
PUSH16(cpustate,(INT16)(INT8)value);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE UINT8 POP8(i386_state *cpustate)
|
||||
{
|
||||
UINT8 value;
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
value = READ8(cpustate, ea );
|
||||
REG32(ESP) += 1;
|
||||
} else {
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
value = READ8(cpustate, ea );
|
||||
REG16(SP) += 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT16 POP16(i386_state *cpustate)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
value = READ16(cpustate, ea );
|
||||
REG32(ESP) += 2;
|
||||
} else {
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
value = READ16(cpustate, ea );
|
||||
REG16(SP) += 2;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 POP32(i386_state *cpustate)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
value = READ32(cpustate, ea );
|
||||
REG32(ESP) += 4;
|
||||
} else {
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
value = READ32(cpustate, ea );
|
||||
REG16(SP) += 4;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE void BUMP_SI(i386_state *cpustate,int adjustment)
|
||||
{
|
||||
if ( cpustate->address_size )
|
||||
REG32(ESI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
else
|
||||
REG16(SI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
}
|
||||
|
||||
INLINE void BUMP_DI(i386_state *cpustate,int adjustment)
|
||||
{
|
||||
if ( cpustate->address_size )
|
||||
REG32(EDI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
else
|
||||
REG16(DI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
#define READPORT8(port) (memory_read_byte_32le(cpustate->io, port))
|
||||
#define READPORT16(port) (memory_read_word_32le(cpustate->io, port))
|
||||
#define READPORT32(port) (memory_read_dword_32le(cpustate->io, port))
|
||||
#define WRITEPORT8(port, value) (memory_write_byte_32le(cpustate->io, port, value))
|
||||
#define WRITEPORT16(port, value) (memory_write_word_32le(cpustate->io, port, value))
|
||||
#define WRITEPORT32(port, value) (memory_write_dword_32le(cpustate->io, port, value))
|
||||
|
||||
#endif /* __I386_H__ */
|
||||
#endif /* __I386INTF_H__ */
|
||||
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __I386INTF_H__
|
||||
#define __I386INTF_H__
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
CPU_GET_INFO( i386 );
|
||||
CPU_GET_INFO( i486 );
|
||||
CPU_GET_INFO( pentium );
|
||||
CPU_GET_INFO( mediagx );
|
||||
|
||||
#define CPU_I386 CPU_GET_INFO_NAME( i386 )
|
||||
#define CPU_I486 CPU_GET_INFO_NAME( i486 )
|
||||
#define CPU_PENTIUM CPU_GET_INFO_NAME( pentium )
|
||||
#define CPU_MEDIAGX CPU_GET_INFO_NAME( mediagx )
|
||||
|
||||
|
||||
|
||||
#endif /* __I386INTF_H__ */
|
898
src/emu/cpu/i386/i386priv.h
Normal file
898
src/emu/cpu/i386/i386priv.h
Normal file
@ -0,0 +1,898 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __I386_H__
|
||||
#define __I386_H__
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
#define I386OP(XX) i386_##XX
|
||||
#define I486OP(XX) i486_##XX
|
||||
#define PENTIUMOP(XX) pentium_##XX
|
||||
#define MMXOP(XX) mmx_##XX
|
||||
|
||||
extern int i386_dasm_one(char *buffer, UINT32 pc, const UINT8 *oprom, int mode);
|
||||
|
||||
typedef enum { ES, CS, SS, DS, FS, GS } SREGS;
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum
|
||||
{
|
||||
AL = 0,
|
||||
AH = 1,
|
||||
CL = 4,
|
||||
CH = 5,
|
||||
DL = 8,
|
||||
DH = 9,
|
||||
BL = 12,
|
||||
BH = 13
|
||||
} BREGS;
|
||||
#else
|
||||
typedef enum
|
||||
{
|
||||
AL = 3,
|
||||
AH = 2,
|
||||
CL = 7,
|
||||
CH = 6,
|
||||
DL = 11,
|
||||
DH = 10,
|
||||
BL = 15,
|
||||
BH = 14
|
||||
} BREGS;
|
||||
#endif
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum
|
||||
{
|
||||
AX = 0,
|
||||
CX = 2,
|
||||
DX = 4,
|
||||
BX = 6,
|
||||
SP = 8,
|
||||
BP = 10,
|
||||
SI = 12,
|
||||
DI = 14
|
||||
} WREGS;
|
||||
#else
|
||||
typedef enum
|
||||
{
|
||||
AX = 1,
|
||||
CX = 3,
|
||||
DX = 5,
|
||||
BX = 7,
|
||||
SP = 9,
|
||||
BP = 11,
|
||||
SI = 13,
|
||||
DI = 15
|
||||
} WREGS;
|
||||
#endif
|
||||
|
||||
typedef enum { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI } DREGS;
|
||||
|
||||
enum
|
||||
{
|
||||
I386_PC = 0,
|
||||
|
||||
/* 8-bit registers */
|
||||
I386_AL,
|
||||
I386_AH,
|
||||
I386_BL,
|
||||
I386_BH,
|
||||
I386_CL,
|
||||
I386_CH,
|
||||
I386_DL,
|
||||
I386_DH,
|
||||
|
||||
/* 16-bit registers */
|
||||
I386_AX,
|
||||
I386_BX,
|
||||
I386_CX,
|
||||
I386_DX,
|
||||
I386_BP,
|
||||
I386_SP,
|
||||
I386_SI,
|
||||
I386_DI,
|
||||
I386_IP,
|
||||
|
||||
/* 32-bit registers */
|
||||
I386_EAX,
|
||||
I386_ECX,
|
||||
I386_EDX,
|
||||
I386_EBX,
|
||||
I386_EBP,
|
||||
I386_ESP,
|
||||
I386_ESI,
|
||||
I386_EDI,
|
||||
I386_EIP,
|
||||
|
||||
/* segment registers */
|
||||
I386_CS,
|
||||
I386_CS_BASE,
|
||||
I386_CS_LIMIT,
|
||||
I386_CS_FLAGS,
|
||||
I386_SS,
|
||||
I386_SS_BASE,
|
||||
I386_SS_LIMIT,
|
||||
I386_SS_FLAGS,
|
||||
I386_DS,
|
||||
I386_DS_BASE,
|
||||
I386_DS_LIMIT,
|
||||
I386_DS_FLAGS,
|
||||
I386_ES,
|
||||
I386_ES_BASE,
|
||||
I386_ES_LIMIT,
|
||||
I386_ES_FLAGS,
|
||||
I386_FS,
|
||||
I386_FS_BASE,
|
||||
I386_FS_LIMIT,
|
||||
I386_FS_FLAGS,
|
||||
I386_GS,
|
||||
I386_GS_BASE,
|
||||
I386_GS_LIMIT,
|
||||
I386_GS_FLAGS,
|
||||
|
||||
/* other */
|
||||
I386_EFLAGS,
|
||||
|
||||
I386_CR0,
|
||||
I386_CR1,
|
||||
I386_CR2,
|
||||
I386_CR3,
|
||||
|
||||
I386_DR0,
|
||||
I386_DR1,
|
||||
I386_DR2,
|
||||
I386_DR3,
|
||||
I386_DR4,
|
||||
I386_DR5,
|
||||
I386_DR6,
|
||||
I386_DR7,
|
||||
|
||||
I386_TR6,
|
||||
I386_TR7,
|
||||
|
||||
I386_GDTR_BASE,
|
||||
I386_GDTR_LIMIT,
|
||||
I386_IDTR_BASE,
|
||||
I386_IDTR_LIMIT,
|
||||
I386_TR,
|
||||
I386_TR_BASE,
|
||||
I386_TR_LIMIT,
|
||||
I386_TR_FLAGS,
|
||||
I386_LDTR,
|
||||
I386_LDTR_BASE,
|
||||
I386_LDTR_LIMIT,
|
||||
I386_LDTR_FLAGS,
|
||||
|
||||
X87_CTRL,
|
||||
X87_STATUS,
|
||||
X87_ST0,
|
||||
X87_ST1,
|
||||
X87_ST2,
|
||||
X87_ST3,
|
||||
X87_ST4,
|
||||
X87_ST5,
|
||||
X87_ST6,
|
||||
X87_ST7,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINT16 selector;
|
||||
UINT16 flags;
|
||||
UINT32 base;
|
||||
UINT32 limit;
|
||||
int d; // Operand size
|
||||
} I386_SREG;
|
||||
|
||||
typedef struct {
|
||||
UINT32 base;
|
||||
UINT16 limit;
|
||||
} I386_SYS_TABLE;
|
||||
|
||||
typedef struct {
|
||||
UINT16 segment;
|
||||
UINT16 flags;
|
||||
UINT32 base;
|
||||
UINT32 limit;
|
||||
} I386_SEG_DESC;
|
||||
|
||||
typedef union {
|
||||
UINT32 d[8];
|
||||
UINT16 w[16];
|
||||
UINT8 b[32];
|
||||
} I386_GPR;
|
||||
|
||||
typedef union {
|
||||
UINT64 i;
|
||||
double f;
|
||||
} X87_REG;
|
||||
|
||||
typedef struct _i386_state i386_state;
|
||||
struct _i386_state
|
||||
{
|
||||
I386_GPR reg;
|
||||
I386_SREG sreg[6];
|
||||
UINT32 eip;
|
||||
UINT32 pc;
|
||||
UINT32 prev_eip;
|
||||
UINT32 eflags;
|
||||
UINT8 CF;
|
||||
UINT8 DF;
|
||||
UINT8 SF;
|
||||
UINT8 OF;
|
||||
UINT8 ZF;
|
||||
UINT8 PF;
|
||||
UINT8 AF;
|
||||
UINT8 IF;
|
||||
UINT8 TF;
|
||||
|
||||
UINT8 performed_intersegment_jump;
|
||||
|
||||
UINT32 cr[4]; // Control registers
|
||||
UINT32 dr[8]; // Debug registers
|
||||
UINT32 tr[8]; // Test registers
|
||||
|
||||
I386_SYS_TABLE gdtr; // Global Descriptor Table Register
|
||||
I386_SYS_TABLE idtr; // Interrupt Descriptor Table Register
|
||||
I386_SEG_DESC task; // Task register
|
||||
I386_SEG_DESC ldtr; // Local Descriptor Table Register
|
||||
|
||||
int halted;
|
||||
|
||||
int operand_size;
|
||||
int address_size;
|
||||
|
||||
int segment_prefix;
|
||||
int segment_override;
|
||||
|
||||
int cycles;
|
||||
int base_cycles;
|
||||
UINT8 opcode;
|
||||
|
||||
UINT8 irq_state;
|
||||
cpu_irq_callback irq_callback;
|
||||
const device_config *device;
|
||||
const address_space *program;
|
||||
const address_space *io;
|
||||
UINT32 a20_mask;
|
||||
|
||||
int cpuid_max_input_value_eax;
|
||||
UINT32 cpuid_id0, cpuid_id1, cpuid_id2;
|
||||
UINT32 cpu_version;
|
||||
UINT32 feature_flags;
|
||||
UINT64 tsc;
|
||||
|
||||
// FPU
|
||||
X87_REG fpu_reg[8];
|
||||
UINT16 fpu_control_word;
|
||||
UINT16 fpu_status_word;
|
||||
UINT16 fpu_tag_word;
|
||||
UINT64 fpu_data_ptr;
|
||||
UINT64 fpu_inst_ptr;
|
||||
UINT16 fpu_opcode;
|
||||
int fpu_top;
|
||||
|
||||
void (*opcode_table1_16[256])(i386_state *cpustate);
|
||||
void (*opcode_table1_32[256])(i386_state *cpustate);
|
||||
void (*opcode_table2_16[256])(i386_state *cpustate);
|
||||
void (*opcode_table2_32[256])(i386_state *cpustate);
|
||||
|
||||
UINT8 *cycle_table_pm;
|
||||
UINT8 *cycle_table_rm;
|
||||
};
|
||||
|
||||
|
||||
extern int i386_parity_table[256];
|
||||
|
||||
#define PROTECTED_MODE (cpustate->cr[0] & 0x1)
|
||||
#define STACK_32BIT (cpustate->sreg[SS].d)
|
||||
#define V8086_MODE (cpustate->eflags & 0x00020000)
|
||||
|
||||
#define SetOF_Add32(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80000000) ? 1: 0)
|
||||
#define SetOF_Add16(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? 1 : 0)
|
||||
#define SetOF_Add8(r,s,d) (cpustate->OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? 1 : 0)
|
||||
|
||||
#define SetOF_Sub32(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80000000) ? 1 : 0)
|
||||
#define SetOF_Sub16(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? 1 : 0)
|
||||
#define SetOF_Sub8(r,s,d) (cpustate->OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? 1 : 0)
|
||||
|
||||
#define SetCF8(x) {cpustate->CF = ((x) & 0x100) ? 1 : 0; }
|
||||
#define SetCF16(x) {cpustate->CF = ((x) & 0x10000) ? 1 : 0; }
|
||||
#define SetCF32(x) {cpustate->CF = ((x) & (((UINT64)1) << 32)) ? 1 : 0; }
|
||||
|
||||
#define SetSF(x) (cpustate->SF = (x))
|
||||
#define SetZF(x) (cpustate->ZF = (x))
|
||||
#define SetAF(x,y,z) (cpustate->AF = (((x) ^ ((y) ^ (z))) & 0x10) ? 1 : 0)
|
||||
#define SetPF(x) (cpustate->PF = i386_parity_table[(x) & 0xFF])
|
||||
|
||||
#define SetSZPF8(x) {cpustate->ZF = ((UINT8)(x)==0); cpustate->SF = ((x)&0x80) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
|
||||
#define SetSZPF16(x) {cpustate->ZF = ((UINT16)(x)==0); cpustate->SF = ((x)&0x8000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
|
||||
#define SetSZPF32(x) {cpustate->ZF = ((UINT32)(x)==0); cpustate->SF = ((x)&0x80000000) ? 1 : 0; cpustate->PF = i386_parity_table[x & 0xFF]; }
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
int b;
|
||||
int w;
|
||||
int d;
|
||||
} reg;
|
||||
struct {
|
||||
int b;
|
||||
int w;
|
||||
int d;
|
||||
} rm;
|
||||
} MODRM_TABLE;
|
||||
|
||||
extern MODRM_TABLE i386_MODRM_table[256];
|
||||
|
||||
#define REG8(x) (cpustate->reg.b[x])
|
||||
#define REG16(x) (cpustate->reg.w[x])
|
||||
#define REG32(x) (cpustate->reg.d[x])
|
||||
|
||||
#define LOAD_REG8(x) (REG8(i386_MODRM_table[x].reg.b))
|
||||
#define LOAD_REG16(x) (REG16(i386_MODRM_table[x].reg.w))
|
||||
#define LOAD_REG32(x) (REG32(i386_MODRM_table[x].reg.d))
|
||||
#define LOAD_RM8(x) (REG8(i386_MODRM_table[x].rm.b))
|
||||
#define LOAD_RM16(x) (REG16(i386_MODRM_table[x].rm.w))
|
||||
#define LOAD_RM32(x) (REG32(i386_MODRM_table[x].rm.d))
|
||||
|
||||
#define STORE_REG8(x, value) (REG8(i386_MODRM_table[x].reg.b) = value)
|
||||
#define STORE_REG16(x, value) (REG16(i386_MODRM_table[x].reg.w) = value)
|
||||
#define STORE_REG32(x, value) (REG32(i386_MODRM_table[x].reg.d) = value)
|
||||
#define STORE_RM8(x, value) (REG8(i386_MODRM_table[x].rm.b) = value)
|
||||
#define STORE_RM16(x, value) (REG16(i386_MODRM_table[x].rm.w) = value)
|
||||
#define STORE_RM32(x, value) (REG32(i386_MODRM_table[x].rm.d) = value)
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
INLINE UINT32 i386_translate(i386_state *cpustate, int segment, UINT32 ip)
|
||||
{
|
||||
// TODO: segment limit
|
||||
return cpustate->sreg[segment].base + ip;
|
||||
}
|
||||
|
||||
INLINE int translate_address(i386_state *cpustate, UINT32 *address)
|
||||
{
|
||||
UINT32 a = *address;
|
||||
UINT32 pdbr = cpustate->cr[3] & 0xfffff000;
|
||||
UINT32 directory = (a >> 22) & 0x3ff;
|
||||
UINT32 table = (a >> 12) & 0x3ff;
|
||||
UINT32 offset = a & 0xfff;
|
||||
|
||||
// TODO: 4MB pages
|
||||
UINT32 page_dir = memory_read_dword_32le(cpustate->program, pdbr + directory * 4);
|
||||
UINT32 page_entry = memory_read_dword_32le(cpustate->program, (page_dir & 0xfffff000) + (table * 4));
|
||||
|
||||
*address = (page_entry & 0xfffff000) | offset;
|
||||
return 1;
|
||||
}
|
||||
|
||||
INLINE void CHANGE_PC(i386_state *cpustate, UINT32 pc)
|
||||
{
|
||||
UINT32 address;
|
||||
cpustate->pc = i386_translate(cpustate, CS, pc );
|
||||
|
||||
address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void NEAR_BRANCH(i386_state *cpustate, INT32 offs)
|
||||
{
|
||||
UINT32 address;
|
||||
/* TODO: limit */
|
||||
cpustate->eip += offs;
|
||||
cpustate->pc += offs;
|
||||
|
||||
address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE UINT8 FETCH(i386_state *cpustate)
|
||||
{
|
||||
UINT8 value;
|
||||
UINT32 address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
value = memory_decrypted_read_byte(cpustate->program, address & cpustate->a20_mask);
|
||||
cpustate->eip++;
|
||||
cpustate->pc++;
|
||||
return value;
|
||||
}
|
||||
INLINE UINT16 FETCH16(i386_state *cpustate)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
if( address & 0x1 ) { /* Unaligned read */
|
||||
address &= cpustate->a20_mask;
|
||||
value = (memory_decrypted_read_byte(cpustate->program, address+0) << 0) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+1) << 8);
|
||||
} else {
|
||||
address &= cpustate->a20_mask;
|
||||
value = memory_decrypted_read_word(cpustate->program, address);
|
||||
}
|
||||
cpustate->eip += 2;
|
||||
cpustate->pc += 2;
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 FETCH32(i386_state *cpustate)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 address = cpustate->pc;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
if( cpustate->pc & 0x3 ) { /* Unaligned read */
|
||||
address &= cpustate->a20_mask;
|
||||
value = (memory_decrypted_read_byte(cpustate->program, address+0) << 0) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+1) << 8) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+2) << 16) |
|
||||
(memory_decrypted_read_byte(cpustate->program, address+3) << 24);
|
||||
} else {
|
||||
address &= cpustate->a20_mask;
|
||||
value = memory_decrypted_read_dword(cpustate->program, address);
|
||||
}
|
||||
cpustate->eip += 4;
|
||||
cpustate->pc += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE UINT8 READ8(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
return memory_read_byte_32le(cpustate->program, address);
|
||||
}
|
||||
INLINE UINT16 READ16(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x1 ) { /* Unaligned read */
|
||||
value = (memory_read_byte_32le( cpustate->program, address+0 ) << 0) |
|
||||
(memory_read_byte_32le( cpustate->program, address+1 ) << 8);
|
||||
} else {
|
||||
value = memory_read_word_32le( cpustate->program, address );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 READ32(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x3 ) { /* Unaligned read */
|
||||
value = (memory_read_byte_32le( cpustate->program, address+0 ) << 0) |
|
||||
(memory_read_byte_32le( cpustate->program, address+1 ) << 8) |
|
||||
(memory_read_byte_32le( cpustate->program, address+2 ) << 16) |
|
||||
(memory_read_byte_32le( cpustate->program, address+3 ) << 24);
|
||||
} else {
|
||||
value = memory_read_dword_32le( cpustate->program, address );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE UINT64 READ64(i386_state *cpustate,UINT32 ea)
|
||||
{
|
||||
UINT64 value;
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x7 ) { /* Unaligned read */
|
||||
value = (((UINT64) memory_read_byte_32le( cpustate->program, address+0 )) << 0) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+1 )) << 8) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+2 )) << 16) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+3 )) << 24) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+4 )) << 32) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+5 )) << 40) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+6 )) << 48) |
|
||||
(((UINT64) memory_read_byte_32le( cpustate->program, address+7 )) << 56);
|
||||
} else {
|
||||
value = (((UINT64) memory_read_dword_32le( cpustate->program, address+0 )) << 0) |
|
||||
(((UINT64) memory_read_dword_32le( cpustate->program, address+4 )) << 32);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE void WRITE8(i386_state *cpustate,UINT32 ea, UINT8 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
memory_write_byte_32le(cpustate->program, address, value);
|
||||
}
|
||||
INLINE void WRITE16(i386_state *cpustate,UINT32 ea, UINT16 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
address &= cpustate->a20_mask;
|
||||
if( ea & 0x1 ) { /* Unaligned write */
|
||||
memory_write_byte_32le( cpustate->program, address+0, value & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+1, (value >> 8) & 0xff );
|
||||
} else {
|
||||
memory_write_word_32le(cpustate->program, address, value);
|
||||
}
|
||||
}
|
||||
INLINE void WRITE32(i386_state *cpustate,UINT32 ea, UINT32 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
ea &= cpustate->a20_mask;
|
||||
if( ea & 0x3 ) { /* Unaligned write */
|
||||
memory_write_byte_32le( cpustate->program, address+0, value & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+1, (value >> 8) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+2, (value >> 16) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+3, (value >> 24) & 0xff );
|
||||
} else {
|
||||
memory_write_dword_32le(cpustate->program, address, value);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void WRITE64(i386_state *cpustate,UINT32 ea, UINT64 value)
|
||||
{
|
||||
UINT32 address = ea;
|
||||
|
||||
if (cpustate->cr[0] & 0x80000000) // page translation enabled
|
||||
{
|
||||
translate_address(cpustate,&address);
|
||||
}
|
||||
|
||||
ea &= cpustate->a20_mask;
|
||||
if( ea & 0x7 ) { /* Unaligned write */
|
||||
memory_write_byte_32le( cpustate->program, address+0, value & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+1, (value >> 8) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+2, (value >> 16) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+3, (value >> 24) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+4, (value >> 32) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+5, (value >> 40) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+6, (value >> 48) & 0xff );
|
||||
memory_write_byte_32le( cpustate->program, address+7, (value >> 56) & 0xff );
|
||||
} else {
|
||||
memory_write_dword_32le(cpustate->program, address+0, value & 0xffffffff);
|
||||
memory_write_dword_32le(cpustate->program, address+4, (value >> 32) & 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
INLINE UINT8 OR8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT8 res = dst | src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF8(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT16 OR16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT16 res = dst | src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF16(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT32 OR32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT32 res = dst | src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE UINT8 AND8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT8 res = dst & src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF8(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT16 AND16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT16 res = dst & src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF16(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT32 AND32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT32 res = dst & src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE UINT8 XOR8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT8 res = dst ^ src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF8(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT16 XOR16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT16 res = dst ^ src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF16(res);
|
||||
return res;
|
||||
}
|
||||
INLINE UINT32 XOR32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT32 res = dst ^ src;
|
||||
cpustate->CF = cpustate->OF = 0;
|
||||
SetSZPF32(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
INLINE UINT8 SUB8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT16 res = (UINT16)dst - (UINT16)src;
|
||||
SetCF8(res);
|
||||
SetOF_Sub8(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 SUB16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT32 res = (UINT32)dst - (UINT32)src;
|
||||
SetCF16(res);
|
||||
SetOF_Sub16(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 SUB32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT64 res = (UINT64)dst - (UINT64)src;
|
||||
SetCF32(res);
|
||||
SetOF_Sub32(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
INLINE UINT8 ADD8(i386_state *cpustate,UINT8 dst, UINT8 src)
|
||||
{
|
||||
UINT16 res = (UINT16)dst + (UINT16)src;
|
||||
SetCF8(res);
|
||||
SetOF_Add8(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 ADD16(i386_state *cpustate,UINT16 dst, UINT16 src)
|
||||
{
|
||||
UINT32 res = (UINT32)dst + (UINT32)src;
|
||||
SetCF16(res);
|
||||
SetOF_Add16(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 ADD32(i386_state *cpustate,UINT32 dst, UINT32 src)
|
||||
{
|
||||
UINT64 res = (UINT64)dst + (UINT64)src;
|
||||
SetCF32(res);
|
||||
SetOF_Add32(res,src,dst);
|
||||
SetAF(res,src,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
INLINE UINT8 INC8(i386_state *cpustate,UINT8 dst)
|
||||
{
|
||||
UINT16 res = (UINT16)dst + 1;
|
||||
SetOF_Add8(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 INC16(i386_state *cpustate,UINT16 dst)
|
||||
{
|
||||
UINT32 res = (UINT32)dst + 1;
|
||||
SetOF_Add16(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 INC32(i386_state *cpustate,UINT32 dst)
|
||||
{
|
||||
UINT64 res = (UINT64)dst + 1;
|
||||
SetOF_Add32(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
INLINE UINT8 DEC8(i386_state *cpustate,UINT8 dst)
|
||||
{
|
||||
UINT16 res = (UINT16)dst - 1;
|
||||
SetOF_Sub8(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF8(res);
|
||||
return (UINT8)res;
|
||||
}
|
||||
INLINE UINT16 DEC16(i386_state *cpustate,UINT16 dst)
|
||||
{
|
||||
UINT32 res = (UINT32)dst - 1;
|
||||
SetOF_Sub16(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF16(res);
|
||||
return (UINT16)res;
|
||||
}
|
||||
INLINE UINT32 DEC32(i386_state *cpustate,UINT32 dst)
|
||||
{
|
||||
UINT64 res = (UINT64)dst - 1;
|
||||
SetOF_Sub32(res,1,dst);
|
||||
SetAF(res,1,dst);
|
||||
SetSZPF32(res);
|
||||
return (UINT32)res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
INLINE void PUSH16(i386_state *cpustate,UINT16 value)
|
||||
{
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) -= 2;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
WRITE16(cpustate, ea, value );
|
||||
} else {
|
||||
REG16(SP) -= 2;
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
WRITE16(cpustate, ea, value );
|
||||
}
|
||||
}
|
||||
INLINE void PUSH32(i386_state *cpustate,UINT32 value)
|
||||
{
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
REG32(ESP) -= 4;
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
WRITE32(cpustate, ea, value );
|
||||
} else {
|
||||
REG16(SP) -= 4;
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
WRITE32(cpustate, ea, value );
|
||||
}
|
||||
}
|
||||
INLINE void PUSH8(i386_state *cpustate,UINT8 value)
|
||||
{
|
||||
if( cpustate->operand_size ) {
|
||||
PUSH32(cpustate,(INT32)(INT8)value);
|
||||
} else {
|
||||
PUSH16(cpustate,(INT16)(INT8)value);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE UINT8 POP8(i386_state *cpustate)
|
||||
{
|
||||
UINT8 value;
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
value = READ8(cpustate, ea );
|
||||
REG32(ESP) += 1;
|
||||
} else {
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
value = READ8(cpustate, ea );
|
||||
REG16(SP) += 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT16 POP16(i386_state *cpustate)
|
||||
{
|
||||
UINT16 value;
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
value = READ16(cpustate, ea );
|
||||
REG32(ESP) += 2;
|
||||
} else {
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
value = READ16(cpustate, ea );
|
||||
REG16(SP) += 2;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
INLINE UINT32 POP32(i386_state *cpustate)
|
||||
{
|
||||
UINT32 value;
|
||||
UINT32 ea;
|
||||
if( STACK_32BIT ) {
|
||||
ea = i386_translate(cpustate, SS, REG32(ESP) );
|
||||
value = READ32(cpustate, ea );
|
||||
REG32(ESP) += 4;
|
||||
} else {
|
||||
ea = i386_translate(cpustate, SS, REG16(SP) );
|
||||
value = READ32(cpustate, ea );
|
||||
REG16(SP) += 4;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE void BUMP_SI(i386_state *cpustate,int adjustment)
|
||||
{
|
||||
if ( cpustate->address_size )
|
||||
REG32(ESI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
else
|
||||
REG16(SI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
}
|
||||
|
||||
INLINE void BUMP_DI(i386_state *cpustate,int adjustment)
|
||||
{
|
||||
if ( cpustate->address_size )
|
||||
REG32(EDI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
else
|
||||
REG16(DI) += ((cpustate->DF) ? -adjustment : +adjustment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
#define READPORT8(port) (memory_read_byte_32le(cpustate->io, port))
|
||||
#define READPORT16(port) (memory_read_word_32le(cpustate->io, port))
|
||||
#define READPORT32(port) (memory_read_dword_32le(cpustate->io, port))
|
||||
#define WRITEPORT8(port, value) (memory_write_byte_32le(cpustate->io, port, value))
|
||||
#define WRITEPORT16(port, value) (memory_write_word_32le(cpustate->io, port, value))
|
||||
#define WRITEPORT32(port, value) (memory_write_dword_32le(cpustate->io, port, value))
|
||||
|
||||
#endif /* __I386_H__ */
|
@ -1,11 +0,0 @@
|
||||
/* ASG 971222 -- rewrote this interface */
|
||||
#ifndef __I186INTF_H__
|
||||
#define __I186INTF_H__
|
||||
|
||||
#include "i86intf.h"
|
||||
|
||||
/* Public functions */
|
||||
CPU_GET_INFO( i80186 );
|
||||
#define CPU_I80186 CPU_GET_INFO_NAME( i80186 )
|
||||
|
||||
#endif /* __I186INTF_H__ */
|
@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __I186INTF_H__
|
||||
#define __I186INTF_H__
|
||||
|
||||
#include "i186intf.h"
|
||||
|
||||
/* Public functions */
|
||||
CPU_GET_INFO( i80188 );
|
||||
#define CPU_I80188 CPU_GET_INFO_NAME( i80188 )
|
||||
|
||||
#endif /* __I186INTF_H__ */
|
@ -16,8 +16,8 @@
|
||||
|
||||
#define INPUT_LINE_A20 1
|
||||
|
||||
#include "i86.h"
|
||||
#include "i286intf.h"
|
||||
#include "i86priv.h"
|
||||
#include "i286.h"
|
||||
|
||||
|
||||
#include "i86time.c"
|
||||
|
@ -4,7 +4,7 @@
|
||||
#ifndef __I286INTF_H__
|
||||
#define __I286INTF_H__
|
||||
|
||||
#include "i86intf.h"
|
||||
#include "i86.h"
|
||||
|
||||
enum
|
||||
{
|
@ -8,8 +8,8 @@
|
||||
#include "cpuintrf.h"
|
||||
|
||||
#include "host.h"
|
||||
#include "i86priv.h"
|
||||
#include "i86.h"
|
||||
#include "i86intf.h"
|
||||
|
||||
#include "i86mem.h"
|
||||
|
||||
@ -268,7 +268,7 @@ static CPU_DISASSEMBLE( i8086 )
|
||||
|
||||
#if (HAS_I80186 || HAS_I80188)
|
||||
|
||||
#include "i186intf.h"
|
||||
#include "i86.h"
|
||||
|
||||
#undef PREFIX
|
||||
#define PREFIX(name) i80186##name
|
||||
|
@ -1,129 +1,44 @@
|
||||
/****************************************************************************/
|
||||
/* real mode i286 emulator by Fabrice Frances */
|
||||
/* (initial work based on David Hedley's pcemu) */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
/* ASG 971222 -- rewrote this interface */
|
||||
#pragma once
|
||||
|
||||
#ifndef __I86_H__
|
||||
#define __I86_H__
|
||||
#ifndef __I86INTF_H__
|
||||
#define __I86INTF_H__
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
#define I8086_NMI_INT_VECTOR 2
|
||||
#define INPUT_LINE_TEST 20 /* PJB 03/05 */
|
||||
|
||||
typedef enum { ES, CS, SS, DS } SREGS;
|
||||
typedef enum { AX, CX, DX, BX, SP, BP, SI, DI } WREGS;
|
||||
enum
|
||||
{
|
||||
I8086_PC=0,
|
||||
I8086_IP,
|
||||
I8086_AX,
|
||||
I8086_CX,
|
||||
I8086_DX,
|
||||
I8086_BX,
|
||||
I8086_SP,
|
||||
I8086_BP,
|
||||
I8086_SI,
|
||||
I8086_DI,
|
||||
I8086_FLAGS,
|
||||
I8086_ES,
|
||||
I8086_CS,
|
||||
I8086_SS,
|
||||
I8086_DS,
|
||||
I8086_VECTOR
|
||||
};
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
/* Public functions */
|
||||
CPU_GET_INFO( i8086 );
|
||||
#define CPU_I8086 CPU_GET_INFO_NAME( i8086 )
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,SIL,SIH,DIL,DIH } BREGS;
|
||||
#else
|
||||
typedef enum { AH,AL,CH,CL,DH,DL,BH,BL,SPH,SPL,BPH,BPL,SIH,SIL,DIH,DIL } BREGS;
|
||||
#endif
|
||||
CPU_GET_INFO( i8088 );
|
||||
#define CPU_I8088 CPU_GET_INFO_NAME( i8088 )
|
||||
|
||||
/* parameter x = result, y = source 1, z = source 2 */
|
||||
CPU_GET_INFO( i80186 );
|
||||
#define CPU_I80186 CPU_GET_INFO_NAME( i80186 )
|
||||
|
||||
#define SetTF(x) (cpustate->TF = (x))
|
||||
#define SetIF(x) (cpustate->IF = (x))
|
||||
#define SetDF(x) (cpustate->DirVal = (x) ? -1 : 1)
|
||||
CPU_GET_INFO( i80188 );
|
||||
#define CPU_I80188 CPU_GET_INFO_NAME( i80188 )
|
||||
|
||||
#define SetOFW_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
|
||||
#define SetOFB_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
|
||||
#define SetOFW_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
|
||||
#define SetOFB_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
|
||||
|
||||
#define SetCFB(x) (cpustate->CarryVal = (x) & 0x100)
|
||||
#define SetCFW(x) (cpustate->CarryVal = (x) & 0x10000)
|
||||
#define SetAF(x,y,z) (cpustate->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
|
||||
#define SetSF(x) (cpustate->SignVal = (x))
|
||||
#define SetZF(x) (cpustate->ZeroVal = (x))
|
||||
#define SetPF(x) (cpustate->ParityVal = (x))
|
||||
|
||||
#define SetSZPF_Byte(x) (cpustate->ParityVal = cpustate->SignVal = cpustate->ZeroVal = (INT8)(x))
|
||||
#define SetSZPF_Word(x) (cpustate->ParityVal = cpustate->SignVal = cpustate->ZeroVal = (INT16)(x))
|
||||
|
||||
#define ADDB(dst,src) { unsigned res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define ADDW(dst,src) { unsigned res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define SUBB(dst,src) { unsigned res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define SUBW(dst,src) { unsigned res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define ORB(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define ORW(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
#define ANDB(dst,src) dst &= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define ANDW(dst,src) dst &= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
#define XORB(dst,src) dst ^= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define XORW(dst,src) dst ^= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
#define CF (cpustate->CarryVal != 0)
|
||||
#define SF (cpustate->SignVal < 0)
|
||||
#define ZF (cpustate->ZeroVal == 0)
|
||||
#define PF parity_table[cpustate->ParityVal]
|
||||
#define AF (cpustate->AuxVal != 0)
|
||||
#define OF (cpustate->OverVal != 0)
|
||||
#define DF (cpustate->DirVal < 0)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define read_byte(a) (*cpustate->mem.rbyte)(cpustate->program, a)
|
||||
#define read_word(a) (*cpustate->mem.rword)(cpustate->program, a)
|
||||
#define write_byte(a,d) (*cpustate->mem.wbyte)(cpustate->program, (a),(d))
|
||||
#define write_word(a,d) (*cpustate->mem.wword)(cpustate->program, (a),(d))
|
||||
|
||||
#define read_port_byte(a) (*cpustate->mem.rbyte)(cpustate->io, a)
|
||||
#define read_port_word(a) (*cpustate->mem.rword)(cpustate->io, a)
|
||||
#define write_port_byte(a,d) (*cpustate->mem.wbyte)(cpustate->io, (a),(d))
|
||||
#define write_port_word(a,d) (*cpustate->mem.wword)(cpustate->io, (a),(d))
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define SegBase(Seg) (cpustate->sregs[Seg] << 4)
|
||||
|
||||
#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->prefix_base : cpustate->base[Seg])
|
||||
|
||||
#define GetMemB(Seg,Off) (read_byte((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define GetMemW(Seg,Off) (read_word((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define PutMemB(Seg,Off,x) write_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))
|
||||
#define PutMemW(Seg,Off,x) write_word((DefaultBase(Seg) + (Off)) & AMASK, (x))
|
||||
|
||||
#define PEEKBYTE(ea) (read_byte((ea) & AMASK))
|
||||
#define ReadByte(ea) (read_byte((ea) & AMASK))
|
||||
#define ReadWord(ea) (read_word((ea) & AMASK))
|
||||
#define WriteByte(ea,val) write_byte((ea) & AMASK, val);
|
||||
#define WriteWord(ea,val) write_word((ea) & AMASK, val);
|
||||
|
||||
#define FETCH_XOR(a) ((a) ^ cpustate->mem.fetch_xor)
|
||||
#define FETCH (memory_raw_read_byte(cpustate->program, FETCH_XOR(cpustate->pc++)))
|
||||
#define FETCHOP (memory_decrypted_read_byte(cpustate->program, FETCH_XOR(cpustate->pc++)))
|
||||
#define PEEKOP(addr) (memory_decrypted_read_byte(cpustate->program, FETCH_XOR(addr)))
|
||||
#define FETCHWORD(var) { var = memory_raw_read_byte(cpustate->program, FETCH_XOR(cpustate->pc)); var += (memory_raw_read_byte(cpustate->program, FETCH_XOR(cpustate->pc + 1)) << 8); cpustate->pc += 2; }
|
||||
#define CHANGE_PC(addr)
|
||||
#define PUSH(val) { cpustate->regs.w[SP] -= 2; WriteWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK), val); }
|
||||
#define POP(var) { var = ReadWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK)); cpustate->regs.w[SP] += 2; }
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define CompressFlags() (WORD)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
|
||||
| (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) \
|
||||
| (DF << 10) | (OF << 11))
|
||||
|
||||
#define ExpandFlags(f) \
|
||||
{ \
|
||||
cpustate->CarryVal = (f) & 1; \
|
||||
cpustate->ParityVal = !((f) & 4); \
|
||||
cpustate->AuxVal = (f) & 16; \
|
||||
cpustate->ZeroVal = !((f) & 64); \
|
||||
cpustate->SignVal = ((f) & 128) ? -1 : 0; \
|
||||
cpustate->TF = ((f) & 256) >> 8; \
|
||||
cpustate->IF = ((f) & 512) >> 9; \
|
||||
cpustate->DirVal = ((f) & 1024) ? -1 : 1; \
|
||||
cpustate->OverVal = (f) & 2048; \
|
||||
}
|
||||
|
||||
#endif /* __I86_H__ */
|
||||
#endif /* __I86INTF_H__ */
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* ASG 971222 -- rewrote this interface */
|
||||
#pragma once
|
||||
|
||||
#ifndef __I86INTF_H__
|
||||
#define __I86INTF_H__
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
enum
|
||||
{
|
||||
I8086_PC=0,
|
||||
I8086_IP,
|
||||
I8086_AX,
|
||||
I8086_CX,
|
||||
I8086_DX,
|
||||
I8086_BX,
|
||||
I8086_SP,
|
||||
I8086_BP,
|
||||
I8086_SI,
|
||||
I8086_DI,
|
||||
I8086_FLAGS,
|
||||
I8086_ES,
|
||||
I8086_CS,
|
||||
I8086_SS,
|
||||
I8086_DS,
|
||||
I8086_VECTOR
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
CPU_GET_INFO( i8086 );
|
||||
#define CPU_I8086 CPU_GET_INFO_NAME( i8086 )
|
||||
|
||||
#endif /* __I86INTF_H__ */
|
128
src/emu/cpu/i86/i86priv.h
Normal file
128
src/emu/cpu/i86/i86priv.h
Normal file
@ -0,0 +1,128 @@
|
||||
/****************************************************************************/
|
||||
/* real mode i286 emulator by Fabrice Frances */
|
||||
/* (initial work based on David Hedley's pcemu) */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#ifndef __I86_H__
|
||||
#define __I86_H__
|
||||
|
||||
#define I8086_NMI_INT_VECTOR 2
|
||||
|
||||
typedef enum { ES, CS, SS, DS } SREGS;
|
||||
typedef enum { AX, CX, DX, BX, SP, BP, SI, DI } WREGS;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,SIL,SIH,DIL,DIH } BREGS;
|
||||
#else
|
||||
typedef enum { AH,AL,CH,CL,DH,DL,BH,BL,SPH,SPL,BPH,BPL,SIH,SIL,DIH,DIL } BREGS;
|
||||
#endif
|
||||
|
||||
/* parameter x = result, y = source 1, z = source 2 */
|
||||
|
||||
#define SetTF(x) (cpustate->TF = (x))
|
||||
#define SetIF(x) (cpustate->IF = (x))
|
||||
#define SetDF(x) (cpustate->DirVal = (x) ? -1 : 1)
|
||||
|
||||
#define SetOFW_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
|
||||
#define SetOFB_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
|
||||
#define SetOFW_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
|
||||
#define SetOFB_Sub(x,y,z) (cpustate->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
|
||||
|
||||
#define SetCFB(x) (cpustate->CarryVal = (x) & 0x100)
|
||||
#define SetCFW(x) (cpustate->CarryVal = (x) & 0x10000)
|
||||
#define SetAF(x,y,z) (cpustate->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
|
||||
#define SetSF(x) (cpustate->SignVal = (x))
|
||||
#define SetZF(x) (cpustate->ZeroVal = (x))
|
||||
#define SetPF(x) (cpustate->ParityVal = (x))
|
||||
|
||||
#define SetSZPF_Byte(x) (cpustate->ParityVal = cpustate->SignVal = cpustate->ZeroVal = (INT8)(x))
|
||||
#define SetSZPF_Word(x) (cpustate->ParityVal = cpustate->SignVal = cpustate->ZeroVal = (INT16)(x))
|
||||
|
||||
#define ADDB(dst,src) { unsigned res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define ADDW(dst,src) { unsigned res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define SUBB(dst,src) { unsigned res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define SUBW(dst,src) { unsigned res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define ORB(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define ORW(dst,src) dst |= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
#define ANDB(dst,src) dst &= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define ANDW(dst,src) dst &= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
#define XORB(dst,src) dst ^= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Byte(dst)
|
||||
#define XORW(dst,src) dst ^= src; cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0; SetSZPF_Word(dst)
|
||||
|
||||
#define CF (cpustate->CarryVal != 0)
|
||||
#define SF (cpustate->SignVal < 0)
|
||||
#define ZF (cpustate->ZeroVal == 0)
|
||||
#define PF parity_table[cpustate->ParityVal]
|
||||
#define AF (cpustate->AuxVal != 0)
|
||||
#define OF (cpustate->OverVal != 0)
|
||||
#define DF (cpustate->DirVal < 0)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define read_byte(a) (*cpustate->mem.rbyte)(cpustate->program, a)
|
||||
#define read_word(a) (*cpustate->mem.rword)(cpustate->program, a)
|
||||
#define write_byte(a,d) (*cpustate->mem.wbyte)(cpustate->program, (a),(d))
|
||||
#define write_word(a,d) (*cpustate->mem.wword)(cpustate->program, (a),(d))
|
||||
|
||||
#define read_port_byte(a) (*cpustate->mem.rbyte)(cpustate->io, a)
|
||||
#define read_port_word(a) (*cpustate->mem.rword)(cpustate->io, a)
|
||||
#define write_port_byte(a,d) (*cpustate->mem.wbyte)(cpustate->io, (a),(d))
|
||||
#define write_port_word(a,d) (*cpustate->mem.wword)(cpustate->io, (a),(d))
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define SegBase(Seg) (cpustate->sregs[Seg] << 4)
|
||||
|
||||
#define DefaultBase(Seg) ((cpustate->seg_prefix && (Seg == DS || Seg == SS)) ? cpustate->prefix_base : cpustate->base[Seg])
|
||||
|
||||
#define GetMemB(Seg,Off) (read_byte((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define GetMemW(Seg,Off) (read_word((DefaultBase(Seg) + (Off)) & AMASK))
|
||||
#define PutMemB(Seg,Off,x) write_byte((DefaultBase(Seg) + (Off)) & AMASK, (x))
|
||||
#define PutMemW(Seg,Off,x) write_word((DefaultBase(Seg) + (Off)) & AMASK, (x))
|
||||
|
||||
#define PEEKBYTE(ea) (read_byte((ea) & AMASK))
|
||||
#define ReadByte(ea) (read_byte((ea) & AMASK))
|
||||
#define ReadWord(ea) (read_word((ea) & AMASK))
|
||||
#define WriteByte(ea,val) write_byte((ea) & AMASK, val);
|
||||
#define WriteWord(ea,val) write_word((ea) & AMASK, val);
|
||||
|
||||
#define FETCH_XOR(a) ((a) ^ cpustate->mem.fetch_xor)
|
||||
#define FETCH (memory_raw_read_byte(cpustate->program, FETCH_XOR(cpustate->pc++)))
|
||||
#define FETCHOP (memory_decrypted_read_byte(cpustate->program, FETCH_XOR(cpustate->pc++)))
|
||||
#define PEEKOP(addr) (memory_decrypted_read_byte(cpustate->program, FETCH_XOR(addr)))
|
||||
#define FETCHWORD(var) { var = memory_raw_read_byte(cpustate->program, FETCH_XOR(cpustate->pc)); var += (memory_raw_read_byte(cpustate->program, FETCH_XOR(cpustate->pc + 1)) << 8); cpustate->pc += 2; }
|
||||
#define CHANGE_PC(addr)
|
||||
#define PUSH(val) { cpustate->regs.w[SP] -= 2; WriteWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK), val); }
|
||||
#define POP(var) { var = ReadWord(((cpustate->base[SS] + cpustate->regs.w[SP]) & AMASK)); cpustate->regs.w[SP] += 2; }
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define CompressFlags() (WORD)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
|
||||
| (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) \
|
||||
| (DF << 10) | (OF << 11))
|
||||
|
||||
#define ExpandFlags(f) \
|
||||
{ \
|
||||
cpustate->CarryVal = (f) & 1; \
|
||||
cpustate->ParityVal = !((f) & 4); \
|
||||
cpustate->AuxVal = (f) & 16; \
|
||||
cpustate->ZeroVal = !((f) & 64); \
|
||||
cpustate->SignVal = ((f) & 128) ? -1 : 0; \
|
||||
cpustate->TF = ((f) & 256) >> 8; \
|
||||
cpustate->IF = ((f) & 512) >> 9; \
|
||||
cpustate->DirVal = ((f) & 1024) ? -1 : 1; \
|
||||
cpustate->OverVal = (f) & 2048; \
|
||||
}
|
||||
|
||||
#endif /* __I86_H__ */
|
@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __I88INTF_H__
|
||||
#define __I88INTF_H__
|
||||
|
||||
#include "i86intf.h"
|
||||
|
||||
/* Public functions */
|
||||
CPU_GET_INFO( i8088 );
|
||||
#define CPU_I8088 CPU_GET_INFO_NAME( i8088 )
|
||||
|
||||
#endif /* __I88INTF_H__ */
|
@ -85,31 +85,6 @@ enum
|
||||
M37710_SER0_XMIT, M37710_SER1_REC, M37710_SER1_XMIT
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= MAME ================================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* Clean up after the emulation core - Not used in this core - */
|
||||
CPU_EXIT( m37710 );
|
||||
|
||||
/* Save the current CPU state to disk */
|
||||
void m37710_state_save(void *file);
|
||||
|
||||
/* Load a CPU state from disk */
|
||||
void m37710_state_load(void *file);
|
||||
|
||||
#undef M37710_CALL_DEBUGGER
|
||||
|
||||
#define M37710_CALL_DEBUGGER(x) debugger_instruction_hook(cpustate->device, x)
|
||||
#define m37710_read_8(addr) memory_read_byte_16le(cpustate->program, addr)
|
||||
#define m37710_write_8(addr,data) memory_write_byte_16le(cpustate->program, addr,data)
|
||||
#define m37710_read_8_immediate(A) memory_read_byte_16le(cpustate->program, A)
|
||||
#define m37710_read_16(addr) memory_read_word_16le(cpustate->program, addr)
|
||||
#define m37710_write_16(addr,data) memory_write_word_16le(cpustate->program, addr,data)
|
||||
#define m37710_jumping(A)
|
||||
#define m37710_branching(A)
|
||||
|
||||
|
||||
CPU_GET_INFO( m37710 );
|
||||
CPU_GET_INFO( m37702 );
|
||||
|
||||
|
@ -17,6 +17,31 @@
|
||||
#include "m37710.h"
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= MAME ================================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* Clean up after the emulation core - Not used in this core - */
|
||||
CPU_EXIT( m37710 );
|
||||
|
||||
/* Save the current CPU state to disk */
|
||||
void m37710_state_save(void *file);
|
||||
|
||||
/* Load a CPU state from disk */
|
||||
void m37710_state_load(void *file);
|
||||
|
||||
#undef M37710_CALL_DEBUGGER
|
||||
|
||||
#define M37710_CALL_DEBUGGER(x) debugger_instruction_hook(cpustate->device, x)
|
||||
#define m37710_read_8(addr) memory_read_byte_16le(cpustate->program, addr)
|
||||
#define m37710_write_8(addr,data) memory_write_byte_16le(cpustate->program, addr,data)
|
||||
#define m37710_read_8_immediate(A) memory_read_byte_16le(cpustate->program, A)
|
||||
#define m37710_read_16(addr) memory_read_word_16le(cpustate->program, addr)
|
||||
#define m37710_write_16(addr,data) memory_write_word_16le(cpustate->program, addr,data)
|
||||
#define m37710_jumping(A)
|
||||
#define m37710_branching(A)
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================ GENERAL =============================== */
|
||||
/* ======================================================================== */
|
||||
|
@ -66,6 +66,30 @@ typedef struct
|
||||
int nmi_state;
|
||||
} m6805_Regs;
|
||||
|
||||
/****************************************************************************/
|
||||
/* Read a byte from given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDMEM(Addr) ((unsigned)memory_read_byte_8be(cpustate->program, Addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/* Write a byte to given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_WRMEM(Addr,Value) (memory_write_byte_8be(cpustate->program, Addr,Value))
|
||||
|
||||
/****************************************************************************/
|
||||
/* M6805_RDOP() is identical to M6805_RDMEM() except it is used for reading */
|
||||
/* opcodes. In case of system with memory mapped I/O, this function can be */
|
||||
/* used to greatly speed up emulation */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDOP(Addr) ((unsigned)memory_decrypted_read_byte(cpustate->program, Addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/* M6805_RDOP_ARG() is identical to M6805_RDOP() but it's used for reading */
|
||||
/* opcode arguments. This difference can be used to support systems that */
|
||||
/* use different encoding mechanisms for opcodes and opcode arguments */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDOP_ARG(Addr) ((unsigned)memory_raw_read_byte(cpustate->program, Addr))
|
||||
|
||||
#define SUBTYPE cpustate->subtype /* CPU Type */
|
||||
#define SP_MASK cpustate->sp_mask /* stack pointer mask */
|
||||
#define SP_LOW cpustate->sp_low /* stack pointer low water mark */
|
||||
|
@ -63,30 +63,6 @@ extern CPU_GET_INFO( hd63705 );
|
||||
#define CPU_HD63705 CPU_GET_INFO_NAME( hd63705 )
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* Read a byte from given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDMEM(Addr) ((unsigned)memory_read_byte_8be(cpustate->program, Addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/* Write a byte to given memory location */
|
||||
/****************************************************************************/
|
||||
#define M6805_WRMEM(Addr,Value) (memory_write_byte_8be(cpustate->program, Addr,Value))
|
||||
|
||||
/****************************************************************************/
|
||||
/* M6805_RDOP() is identical to M6805_RDMEM() except it is used for reading */
|
||||
/* opcodes. In case of system with memory mapped I/O, this function can be */
|
||||
/* used to greatly speed up emulation */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDOP(Addr) ((unsigned)memory_decrypted_read_byte(cpustate->program, Addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/* M6805_RDOP_ARG() is identical to M6805_RDOP() but it's used for reading */
|
||||
/* opcode arguments. This difference can be used to support systems that */
|
||||
/* use different encoding mechanisms for opcodes and opcode arguments */
|
||||
/****************************************************************************/
|
||||
#define M6805_RDOP_ARG(Addr) ((unsigned)memory_raw_read_byte(cpustate->program, Addr))
|
||||
|
||||
CPU_DISASSEMBLE( m6805 );
|
||||
|
||||
#endif /* __M6805_H__ */
|
||||
|
@ -110,8 +110,8 @@ typedef UINT8 BYTE;
|
||||
typedef UINT16 WORD;
|
||||
typedef UINT32 DWORD;
|
||||
|
||||
#include "necpriv.h"
|
||||
#include "nec.h"
|
||||
#include "necintrf.h"
|
||||
|
||||
#define PC(n) (((n)->sregs[PS]<<4)+(n)->ip)
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
/* ASG 971222 -- rewrote this interface */
|
||||
#ifndef __NEC_H_
|
||||
#define __NEC_H_
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
typedef struct _nec_config nec_config;
|
||||
@ -6,377 +10,27 @@ struct _nec_config
|
||||
const UINT8* v25v35_decryptiontable; // internal decryption table
|
||||
};
|
||||
|
||||
|
||||
typedef enum { DS1, PS, SS, DS0 } SREGS;
|
||||
typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
|
||||
|
||||
#define NEC_NMI_INT_VECTOR 2
|
||||
#define NEC_INPUT_LINE_POLL 20
|
||||
|
||||
/* Cpu types, steps of 8 to help the cycle count calculation */
|
||||
#define V33 0
|
||||
#define V30 8
|
||||
#define V20 16
|
||||
enum
|
||||
{
|
||||
NEC_PC=0,
|
||||
NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
|
||||
NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
|
||||
NEC_VECTOR, NEC_PENDING
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
extern CPU_GET_INFO( v20 );
|
||||
extern CPU_GET_INFO( v25 );
|
||||
extern CPU_GET_INFO( v30 );
|
||||
extern CPU_GET_INFO( v33 );
|
||||
extern CPU_GET_INFO( v35 );
|
||||
|
||||
#define CPU_V20 CPU_GET_INFO_NAME( v20 )
|
||||
#define CPU_V25 CPU_GET_INFO_NAME( v25 )
|
||||
#define CPU_V30 CPU_GET_INFO_NAME( v30 )
|
||||
#define CPU_V33 CPU_GET_INFO_NAME( v33 )
|
||||
#define CPU_V35 CPU_GET_INFO_NAME( v35 )
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,IXL,IXH,IYL,IYH } BREGS;
|
||||
#else
|
||||
typedef enum { AH,AL,CH,CL,DH,DL,BH,BL,SPH,SPL,BPH,BPL,IXH,IXL,IYH,IYL } BREGS;
|
||||
#endif
|
||||
|
||||
/* parameter x = result, y = source 1, z = source 2 */
|
||||
|
||||
#define SetTF(x) (nec_state->TF = (x))
|
||||
#define SetIF(x) (nec_state->IF = (x))
|
||||
#define SetDF(x) (nec_state->DF = (x))
|
||||
#define SetMD(x) (nec_state->MF = (x)) /* OB [19.07.99] Mode Flag V30 */
|
||||
|
||||
#define SetCFB(x) (nec_state->CarryVal = (x) & 0x100)
|
||||
#define SetCFW(x) (nec_state->CarryVal = (x) & 0x10000)
|
||||
#define SetAF(x,y,z) (nec_state->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
|
||||
#define SetSF(x) (nec_state->SignVal = (x))
|
||||
#define SetZF(x) (nec_state->ZeroVal = (x))
|
||||
#define SetPF(x) (nec_state->ParityVal = (x))
|
||||
|
||||
#define SetSZPF_Byte(x) (nec_state->SignVal=nec_state->ZeroVal=nec_state->ParityVal=(INT8)(x))
|
||||
#define SetSZPF_Word(x) (nec_state->SignVal=nec_state->ZeroVal=nec_state->ParityVal=(INT16)(x))
|
||||
|
||||
#define SetOFW_Add(x,y,z) (nec_state->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
|
||||
#define SetOFB_Add(x,y,z) (nec_state->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
|
||||
#define SetOFW_Sub(x,y,z) (nec_state->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
|
||||
#define SetOFB_Sub(x,y,z) (nec_state->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
|
||||
|
||||
#define ADDB { UINT32 res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define ADDW { UINT32 res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define SUBB { UINT32 res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define SUBW { UINT32 res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define ORB dst|=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
|
||||
#define ORW dst|=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
|
||||
|
||||
#define ANDB dst&=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
|
||||
#define ANDW dst&=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
|
||||
|
||||
#define XORB dst^=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
|
||||
#define XORW dst^=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
|
||||
|
||||
#define CF (nec_state->CarryVal!=0)
|
||||
#define SF (nec_state->SignVal<0)
|
||||
#define ZF (nec_state->ZeroVal==0)
|
||||
#define PF parity_table[(BYTE)nec_state->ParityVal]
|
||||
#define AF (nec_state->AuxVal!=0)
|
||||
#define OF (nec_state->OverVal!=0)
|
||||
#define MD (nec_state->MF!=0)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define read_byte(a) (*nec_state->mem.rbyte)(nec_state->program, a)
|
||||
#define read_word(a) (*nec_state->mem.rword)(nec_state->program, a)
|
||||
#define write_byte(a,d) (*nec_state->mem.wbyte)(nec_state->program, (a),(d))
|
||||
#define write_word(a,d) (*nec_state->mem.wword)(nec_state->program, (a),(d))
|
||||
|
||||
#define read_port_byte(a) (*nec_state->mem.rbyte)(nec_state->io, a)
|
||||
#define read_port_word(a) (*nec_state->mem.rword)(nec_state->io, a)
|
||||
#define write_port_byte(a,d) (*nec_state->mem.wbyte)(nec_state->io, (a),(d))
|
||||
#define write_port_word(a,d) (*nec_state->mem.wword)(nec_state->io, (a),(d))
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0)
|
||||
|
||||
#define SegBase(Seg) (nec_state->sregs[Seg] << 4)
|
||||
|
||||
#define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS)) ? nec_state->prefix_base : nec_state->sregs[Seg] << 4)
|
||||
|
||||
#define GetMemB(Seg,Off) (read_byte(DefaultBase(Seg) + (Off)))
|
||||
#define GetMemW(Seg,Off) (read_word(DefaultBase(Seg) + (Off)))
|
||||
|
||||
#define PutMemB(Seg,Off,x) { write_byte(DefaultBase(Seg) + (Off), (x)); }
|
||||
#define PutMemW(Seg,Off,x) { write_word(DefaultBase(Seg) + (Off), (x)); }
|
||||
|
||||
/* prefetch timing */
|
||||
|
||||
#define FETCH() fetch(nec_state)
|
||||
#define FETCH_XOR(a) ((a) ^ nec_state->mem.fetch_xor)
|
||||
#define FETCHWORD() fetchword(nec_state)
|
||||
#define EMPTY_PREFETCH() nec_state->prefetch_reset = 1
|
||||
|
||||
|
||||
#define PUSH(val) { nec_state->regs.w[SP]-=2; write_word((((nec_state->sregs[SS]<<4)+nec_state->regs.w[SP])),val); }
|
||||
#define POP(var) { var = read_word((((nec_state->sregs[SS]<<4)+nec_state->regs.w[SP]))); nec_state->regs.w[SP]+=2; }
|
||||
|
||||
#define GetModRM UINT32 ModRM=FETCH()
|
||||
|
||||
/* Cycle count macros:
|
||||
CLK - cycle count is the same on all processors
|
||||
CLKS - cycle count differs between processors, list all counts
|
||||
CLKW - cycle count for word read/write differs for odd/even source/destination address
|
||||
CLKM - cycle count for reg/mem instructions
|
||||
CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
|
||||
|
||||
|
||||
Prefetch & buswait time is not emulated.
|
||||
Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
|
||||
*/
|
||||
|
||||
#define CLK(all) nec_state->icount-=all
|
||||
#define CLKS(v20,v30,v33) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33; nec_state->icount-=(ccount>>nec_state->chip_type)&0x7f; }
|
||||
#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
|
||||
#define CLKM(v20,v30,v33,v20m,v30m,v33m) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33, mcount=(v20m<<16)|(v30m<<8)|v33m; nec_state->icount-=( ModRM >=0xc0 )?((ccount>>nec_state->chip_type)&0x7f):((mcount>>nec_state->chip_type)&0x7f); }
|
||||
#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_state->icount-=vall; else nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
|
||||
|
||||
/************************************************************************/
|
||||
#define CompressFlags() (WORD)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
|
||||
| (SF << 7) | (nec_state->TF << 8) | (nec_state->IF << 9) \
|
||||
| (nec_state->DF << 10) | (OF << 11)| (MD << 15))
|
||||
|
||||
#define ExpandFlags(f) \
|
||||
{ \
|
||||
nec_state->CarryVal = (f) & 1; \
|
||||
nec_state->ParityVal = !((f) & 4); \
|
||||
nec_state->AuxVal = (f) & 16; \
|
||||
nec_state->ZeroVal = !((f) & 64); \
|
||||
nec_state->SignVal = (f) & 128 ? -1 : 0; \
|
||||
nec_state->TF = ((f) & 256) == 256; \
|
||||
nec_state->IF = ((f) & 512) == 512; \
|
||||
nec_state->DF = ((f) & 1024) == 1024; \
|
||||
nec_state->OverVal = (f) & 2048; \
|
||||
nec_state->MF = ((f) & 0x8000) == 0x8000; \
|
||||
}
|
||||
|
||||
#define IncWordReg(Reg) \
|
||||
unsigned tmp = (unsigned)nec_state->regs.w[Reg]; \
|
||||
unsigned tmp1 = tmp+1; \
|
||||
nec_state->OverVal = (tmp == 0x7fff); \
|
||||
SetAF(tmp1,tmp,1); \
|
||||
SetSZPF_Word(tmp1); \
|
||||
nec_state->regs.w[Reg]=tmp1
|
||||
|
||||
#define DecWordReg(Reg) \
|
||||
unsigned tmp = (unsigned)nec_state->regs.w[Reg]; \
|
||||
unsigned tmp1 = tmp-1; \
|
||||
nec_state->OverVal = (tmp == 0x8000); \
|
||||
SetAF(tmp1,tmp,1); \
|
||||
SetSZPF_Word(tmp1); \
|
||||
nec_state->regs.w[Reg]=tmp1
|
||||
|
||||
#define JMP(flag) \
|
||||
int tmp; \
|
||||
EMPTY_PREFETCH(); \
|
||||
tmp = (int)((INT8)FETCH()); \
|
||||
if (flag) \
|
||||
{ \
|
||||
static const UINT8 table[3]={3,10,10}; \
|
||||
nec_state->ip = (WORD)(nec_state->ip+tmp); \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
CHANGE_PC; \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define ADJ4(param1,param2) \
|
||||
if (AF || ((nec_state->regs.b[AL] & 0xf) > 9)) \
|
||||
{ \
|
||||
UINT16 tmp; \
|
||||
tmp = nec_state->regs.b[AL] + param1; \
|
||||
nec_state->regs.b[AL] = tmp; \
|
||||
nec_state->AuxVal = 1; \
|
||||
nec_state->CarryVal |= tmp & 0x100; \
|
||||
} \
|
||||
if (CF || (nec_state->regs.b[AL]>0x9f)) \
|
||||
{ \
|
||||
nec_state->regs.b[AL] += param2; \
|
||||
nec_state->CarryVal = 1; \
|
||||
} \
|
||||
SetSZPF_Byte(nec_state->regs.b[AL])
|
||||
|
||||
#define ADJB(param1,param2) \
|
||||
if (AF || ((nec_state->regs.b[AL] & 0xf) > 9)) \
|
||||
{ \
|
||||
nec_state->regs.b[AL] += param1; \
|
||||
nec_state->regs.b[AH] += param2; \
|
||||
nec_state->AuxVal = 1; \
|
||||
nec_state->CarryVal = 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
nec_state->AuxVal = 0; \
|
||||
nec_state->CarryVal = 0; \
|
||||
} \
|
||||
nec_state->regs.b[AL] &= 0x0F
|
||||
|
||||
#define BITOP_BYTE \
|
||||
ModRM = FETCH(); \
|
||||
if (ModRM >= 0xc0) { \
|
||||
tmp=nec_state->regs.b[Mod_RM.RM.b[ModRM]]; \
|
||||
} \
|
||||
else { \
|
||||
(*GetEA[ModRM])(nec_state); \
|
||||
tmp=read_byte(EA); \
|
||||
}
|
||||
|
||||
#define BITOP_WORD \
|
||||
ModRM = FETCH(); \
|
||||
if (ModRM >= 0xc0) { \
|
||||
tmp=nec_state->regs.w[Mod_RM.RM.w[ModRM]]; \
|
||||
} \
|
||||
else { \
|
||||
(*GetEA[ModRM])(nec_state); \
|
||||
tmp=read_word(EA); \
|
||||
}
|
||||
|
||||
#define BIT_NOT \
|
||||
if (tmp & (1<<tmp2)) \
|
||||
tmp &= ~(1<<tmp2); \
|
||||
else \
|
||||
tmp |= (1<<tmp2)
|
||||
|
||||
#define XchgAWReg(Reg) \
|
||||
WORD tmp; \
|
||||
tmp = nec_state->regs.w[Reg]; \
|
||||
nec_state->regs.w[Reg] = nec_state->regs.w[AW]; \
|
||||
nec_state->regs.w[AW] = tmp
|
||||
|
||||
#define ROL_BYTE nec_state->CarryVal = dst & 0x80; dst = (dst << 1)+CF
|
||||
#define ROL_WORD nec_state->CarryVal = dst & 0x8000; dst = (dst << 1)+CF
|
||||
#define ROR_BYTE nec_state->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7)
|
||||
#define ROR_WORD nec_state->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15)
|
||||
#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst)
|
||||
#define ROLC_WORD dst = (dst << 1) + CF; SetCFW(dst)
|
||||
#define RORC_BYTE dst = (CF<<8)+dst; nec_state->CarryVal = dst & 0x01; dst >>= 1
|
||||
#define RORC_WORD dst = (CF<<16)+dst; nec_state->CarryVal = dst & 0x01; dst >>= 1
|
||||
#define SHL_BYTE(c) nec_state->icount-=c; dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
|
||||
#define SHL_WORD(c) nec_state->icount-=c; dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
|
||||
#define SHR_BYTE(c) nec_state->icount-=c; dst >>= c-1; nec_state->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
|
||||
#define SHR_WORD(c) nec_state->icount-=c; dst >>= c-1; nec_state->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
|
||||
#define SHRA_BYTE(c) nec_state->icount-=c; dst = ((INT8)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT8)((BYTE)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
|
||||
#define SHRA_WORD(c) nec_state->icount-=c; dst = ((INT16)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT16)((WORD)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
|
||||
|
||||
#define DIVUB \
|
||||
uresult = nec_state->regs.w[AW]; \
|
||||
uresult2 = uresult % tmp; \
|
||||
if ((uresult /= tmp) > 0xff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.b[AL] = uresult; \
|
||||
nec_state->regs.b[AH] = uresult2; \
|
||||
}
|
||||
|
||||
#define DIVB \
|
||||
result = (INT16)nec_state->regs.w[AW]; \
|
||||
result2 = result % (INT16)((INT8)tmp); \
|
||||
if ((result /= (INT16)((INT8)tmp)) > 0xff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.b[AL] = result; \
|
||||
nec_state->regs.b[AH] = result2; \
|
||||
}
|
||||
|
||||
#define DIVUW \
|
||||
uresult = (((UINT32)nec_state->regs.w[DW]) << 16) | nec_state->regs.w[AW];\
|
||||
uresult2 = uresult % tmp; \
|
||||
if ((uresult /= tmp) > 0xffff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.w[AW]=uresult; \
|
||||
nec_state->regs.w[DW]=uresult2; \
|
||||
}
|
||||
|
||||
#define DIVW \
|
||||
result = ((UINT32)nec_state->regs.w[DW] << 16) + nec_state->regs.w[AW]; \
|
||||
result2 = result % (INT32)((INT16)tmp); \
|
||||
if ((result /= (INT32)((INT16)tmp)) > 0xffff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.w[AW]=result; \
|
||||
nec_state->regs.w[DW]=result2; \
|
||||
}
|
||||
|
||||
#define ADD4S { \
|
||||
int i,v1,v2,result; \
|
||||
int count = (nec_state->regs.b[CL]+1)/2; \
|
||||
unsigned di = nec_state->regs.w[IY]; \
|
||||
unsigned si = nec_state->regs.w[IX]; \
|
||||
static const UINT8 table[3]={18,19,19}; \
|
||||
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for add4s\n",PC(nec_state)); \
|
||||
nec_state->ZeroVal = nec_state->CarryVal = 0; \
|
||||
for (i=0;i<count;i++) { \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
tmp = GetMemB(DS0, si); \
|
||||
tmp2 = GetMemB(DS1, di); \
|
||||
v1 = (tmp>>4)*10 + (tmp&0xf); \
|
||||
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
|
||||
result = v1+v2+nec_state->CarryVal; \
|
||||
nec_state->CarryVal = result > 99 ? 1 : 0; \
|
||||
result = result % 100; \
|
||||
v1 = ((result/10)<<4) | (result % 10); \
|
||||
PutMemB(DS1, di,v1); \
|
||||
if (v1) nec_state->ZeroVal = 1; \
|
||||
si++; \
|
||||
di++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUB4S { \
|
||||
int count = (nec_state->regs.b[CL]+1)/2; \
|
||||
int i,v1,v2,result; \
|
||||
unsigned di = nec_state->regs.w[IY]; \
|
||||
unsigned si = nec_state->regs.w[IX]; \
|
||||
static const UINT8 table[3]={18,19,19}; \
|
||||
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for sub4s\n",PC(nec_state)); \
|
||||
nec_state->ZeroVal = nec_state->CarryVal = 0; \
|
||||
for (i=0;i<count;i++) { \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
tmp = GetMemB(DS1, di); \
|
||||
tmp2 = GetMemB(DS0, si); \
|
||||
v1 = (tmp>>4)*10 + (tmp&0xf); \
|
||||
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
|
||||
if (v1 < (v2+nec_state->CarryVal)) { \
|
||||
v1+=100; \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 1; \
|
||||
} else { \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 0; \
|
||||
} \
|
||||
v1 = ((result/10)<<4) | (result % 10); \
|
||||
PutMemB(DS1, di,v1); \
|
||||
if (v1) nec_state->ZeroVal = 1; \
|
||||
si++; \
|
||||
di++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CMP4S { \
|
||||
int count = (nec_state->regs.b[CL]+1)/2; \
|
||||
int i,v1,v2,result; \
|
||||
unsigned di = nec_state->regs.w[IY]; \
|
||||
unsigned si = nec_state->regs.w[IX]; \
|
||||
static const UINT8 table[3]={14,19,19}; \
|
||||
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for cmp4s\n",PC(nec_state)); \
|
||||
nec_state->ZeroVal = nec_state->CarryVal = 0; \
|
||||
for (i=0;i<count;i++) { \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
tmp = GetMemB(DS1, di); \
|
||||
tmp2 = GetMemB(DS0, si); \
|
||||
v1 = (tmp>>4)*10 + (tmp&0xf); \
|
||||
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
|
||||
if (v1 < (v2+nec_state->CarryVal)) { \
|
||||
v1+=100; \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 1; \
|
||||
} else { \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 0; \
|
||||
} \
|
||||
v1 = ((result/10)<<4) | (result % 10); \
|
||||
if (v1) nec_state->ZeroVal = 1; \
|
||||
si++; \
|
||||
di++; \
|
||||
} \
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* ASG 971222 -- rewrote this interface */
|
||||
#ifndef __NEC_H_
|
||||
#define __NEC_H_
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
enum
|
||||
{
|
||||
NEC_PC=0,
|
||||
NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
|
||||
NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
|
||||
NEC_VECTOR, NEC_PENDING
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
extern CPU_GET_INFO( v20 );
|
||||
extern CPU_GET_INFO( v25 );
|
||||
extern CPU_GET_INFO( v30 );
|
||||
extern CPU_GET_INFO( v33 );
|
||||
extern CPU_GET_INFO( v35 );
|
||||
|
||||
#define CPU_V20 CPU_GET_INFO_NAME( v20 )
|
||||
#define CPU_V25 CPU_GET_INFO_NAME( v25 )
|
||||
#define CPU_V30 CPU_GET_INFO_NAME( v30 )
|
||||
#define CPU_V33 CPU_GET_INFO_NAME( v33 )
|
||||
#define CPU_V35 CPU_GET_INFO_NAME( v35 )
|
||||
|
||||
#endif
|
374
src/emu/cpu/nec/necpriv.h
Normal file
374
src/emu/cpu/nec/necpriv.h
Normal file
@ -0,0 +1,374 @@
|
||||
#include "cpuintrf.h"
|
||||
|
||||
typedef enum { DS1, PS, SS, DS0 } SREGS;
|
||||
typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS;
|
||||
|
||||
#define NEC_NMI_INT_VECTOR 2
|
||||
|
||||
/* Cpu types, steps of 8 to help the cycle count calculation */
|
||||
#define V33 0
|
||||
#define V30 8
|
||||
#define V20 16
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
typedef enum { AL,AH,CL,CH,DL,DH,BL,BH,SPL,SPH,BPL,BPH,IXL,IXH,IYL,IYH } BREGS;
|
||||
#else
|
||||
typedef enum { AH,AL,CH,CL,DH,DL,BH,BL,SPH,SPL,BPH,BPL,IXH,IXL,IYH,IYL } BREGS;
|
||||
#endif
|
||||
|
||||
/* parameter x = result, y = source 1, z = source 2 */
|
||||
|
||||
#define SetTF(x) (nec_state->TF = (x))
|
||||
#define SetIF(x) (nec_state->IF = (x))
|
||||
#define SetDF(x) (nec_state->DF = (x))
|
||||
#define SetMD(x) (nec_state->MF = (x)) /* OB [19.07.99] Mode Flag V30 */
|
||||
|
||||
#define SetCFB(x) (nec_state->CarryVal = (x) & 0x100)
|
||||
#define SetCFW(x) (nec_state->CarryVal = (x) & 0x10000)
|
||||
#define SetAF(x,y,z) (nec_state->AuxVal = ((x) ^ ((y) ^ (z))) & 0x10)
|
||||
#define SetSF(x) (nec_state->SignVal = (x))
|
||||
#define SetZF(x) (nec_state->ZeroVal = (x))
|
||||
#define SetPF(x) (nec_state->ParityVal = (x))
|
||||
|
||||
#define SetSZPF_Byte(x) (nec_state->SignVal=nec_state->ZeroVal=nec_state->ParityVal=(INT8)(x))
|
||||
#define SetSZPF_Word(x) (nec_state->SignVal=nec_state->ZeroVal=nec_state->ParityVal=(INT16)(x))
|
||||
|
||||
#define SetOFW_Add(x,y,z) (nec_state->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000)
|
||||
#define SetOFB_Add(x,y,z) (nec_state->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x80)
|
||||
#define SetOFW_Sub(x,y,z) (nec_state->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x8000)
|
||||
#define SetOFB_Sub(x,y,z) (nec_state->OverVal = ((z) ^ (y)) & ((z) ^ (x)) & 0x80)
|
||||
|
||||
#define ADDB { UINT32 res=dst+src; SetCFB(res); SetOFB_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define ADDW { UINT32 res=dst+src; SetCFW(res); SetOFW_Add(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define SUBB { UINT32 res=dst-src; SetCFB(res); SetOFB_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Byte(res); dst=(BYTE)res; }
|
||||
#define SUBW { UINT32 res=dst-src; SetCFW(res); SetOFW_Sub(res,src,dst); SetAF(res,src,dst); SetSZPF_Word(res); dst=(WORD)res; }
|
||||
|
||||
#define ORB dst|=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
|
||||
#define ORW dst|=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
|
||||
|
||||
#define ANDB dst&=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
|
||||
#define ANDW dst&=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
|
||||
|
||||
#define XORB dst^=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Byte(dst)
|
||||
#define XORW dst^=src; nec_state->CarryVal=nec_state->OverVal=nec_state->AuxVal=0; SetSZPF_Word(dst)
|
||||
|
||||
#define CF (nec_state->CarryVal!=0)
|
||||
#define SF (nec_state->SignVal<0)
|
||||
#define ZF (nec_state->ZeroVal==0)
|
||||
#define PF parity_table[(BYTE)nec_state->ParityVal]
|
||||
#define AF (nec_state->AuxVal!=0)
|
||||
#define OF (nec_state->OverVal!=0)
|
||||
#define MD (nec_state->MF!=0)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define read_byte(a) (*nec_state->mem.rbyte)(nec_state->program, a)
|
||||
#define read_word(a) (*nec_state->mem.rword)(nec_state->program, a)
|
||||
#define write_byte(a,d) (*nec_state->mem.wbyte)(nec_state->program, (a),(d))
|
||||
#define write_word(a,d) (*nec_state->mem.wword)(nec_state->program, (a),(d))
|
||||
|
||||
#define read_port_byte(a) (*nec_state->mem.rbyte)(nec_state->io, a)
|
||||
#define read_port_word(a) (*nec_state->mem.rword)(nec_state->io, a)
|
||||
#define write_port_byte(a,d) (*nec_state->mem.wbyte)(nec_state->io, (a),(d))
|
||||
#define write_port_word(a,d) (*nec_state->mem.wword)(nec_state->io, (a),(d))
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0)
|
||||
|
||||
#define SegBase(Seg) (nec_state->sregs[Seg] << 4)
|
||||
|
||||
#define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS)) ? nec_state->prefix_base : nec_state->sregs[Seg] << 4)
|
||||
|
||||
#define GetMemB(Seg,Off) (read_byte(DefaultBase(Seg) + (Off)))
|
||||
#define GetMemW(Seg,Off) (read_word(DefaultBase(Seg) + (Off)))
|
||||
|
||||
#define PutMemB(Seg,Off,x) { write_byte(DefaultBase(Seg) + (Off), (x)); }
|
||||
#define PutMemW(Seg,Off,x) { write_word(DefaultBase(Seg) + (Off), (x)); }
|
||||
|
||||
/* prefetch timing */
|
||||
|
||||
#define FETCH() fetch(nec_state)
|
||||
#define FETCH_XOR(a) ((a) ^ nec_state->mem.fetch_xor)
|
||||
#define FETCHWORD() fetchword(nec_state)
|
||||
#define EMPTY_PREFETCH() nec_state->prefetch_reset = 1
|
||||
|
||||
|
||||
#define PUSH(val) { nec_state->regs.w[SP]-=2; write_word((((nec_state->sregs[SS]<<4)+nec_state->regs.w[SP])),val); }
|
||||
#define POP(var) { var = read_word((((nec_state->sregs[SS]<<4)+nec_state->regs.w[SP]))); nec_state->regs.w[SP]+=2; }
|
||||
|
||||
#define GetModRM UINT32 ModRM=FETCH()
|
||||
|
||||
/* Cycle count macros:
|
||||
CLK - cycle count is the same on all processors
|
||||
CLKS - cycle count differs between processors, list all counts
|
||||
CLKW - cycle count for word read/write differs for odd/even source/destination address
|
||||
CLKM - cycle count for reg/mem instructions
|
||||
CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
|
||||
|
||||
|
||||
Prefetch & buswait time is not emulated.
|
||||
Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
|
||||
*/
|
||||
|
||||
#define CLK(all) nec_state->icount-=all
|
||||
#define CLKS(v20,v30,v33) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33; nec_state->icount-=(ccount>>nec_state->chip_type)&0x7f; }
|
||||
#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
|
||||
#define CLKM(v20,v30,v33,v20m,v30m,v33m) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33, mcount=(v20m<<16)|(v30m<<8)|v33m; nec_state->icount-=( ModRM >=0xc0 )?((ccount>>nec_state->chip_type)&0x7f):((mcount>>nec_state->chip_type)&0x7f); }
|
||||
#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_state->icount-=vall; else nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
|
||||
|
||||
/************************************************************************/
|
||||
#define CompressFlags() (WORD)(CF | (PF << 2) | (AF << 4) | (ZF << 6) \
|
||||
| (SF << 7) | (nec_state->TF << 8) | (nec_state->IF << 9) \
|
||||
| (nec_state->DF << 10) | (OF << 11)| (MD << 15))
|
||||
|
||||
#define ExpandFlags(f) \
|
||||
{ \
|
||||
nec_state->CarryVal = (f) & 1; \
|
||||
nec_state->ParityVal = !((f) & 4); \
|
||||
nec_state->AuxVal = (f) & 16; \
|
||||
nec_state->ZeroVal = !((f) & 64); \
|
||||
nec_state->SignVal = (f) & 128 ? -1 : 0; \
|
||||
nec_state->TF = ((f) & 256) == 256; \
|
||||
nec_state->IF = ((f) & 512) == 512; \
|
||||
nec_state->DF = ((f) & 1024) == 1024; \
|
||||
nec_state->OverVal = (f) & 2048; \
|
||||
nec_state->MF = ((f) & 0x8000) == 0x8000; \
|
||||
}
|
||||
|
||||
#define IncWordReg(Reg) \
|
||||
unsigned tmp = (unsigned)nec_state->regs.w[Reg]; \
|
||||
unsigned tmp1 = tmp+1; \
|
||||
nec_state->OverVal = (tmp == 0x7fff); \
|
||||
SetAF(tmp1,tmp,1); \
|
||||
SetSZPF_Word(tmp1); \
|
||||
nec_state->regs.w[Reg]=tmp1
|
||||
|
||||
#define DecWordReg(Reg) \
|
||||
unsigned tmp = (unsigned)nec_state->regs.w[Reg]; \
|
||||
unsigned tmp1 = tmp-1; \
|
||||
nec_state->OverVal = (tmp == 0x8000); \
|
||||
SetAF(tmp1,tmp,1); \
|
||||
SetSZPF_Word(tmp1); \
|
||||
nec_state->regs.w[Reg]=tmp1
|
||||
|
||||
#define JMP(flag) \
|
||||
int tmp; \
|
||||
EMPTY_PREFETCH(); \
|
||||
tmp = (int)((INT8)FETCH()); \
|
||||
if (flag) \
|
||||
{ \
|
||||
static const UINT8 table[3]={3,10,10}; \
|
||||
nec_state->ip = (WORD)(nec_state->ip+tmp); \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
CHANGE_PC; \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define ADJ4(param1,param2) \
|
||||
if (AF || ((nec_state->regs.b[AL] & 0xf) > 9)) \
|
||||
{ \
|
||||
UINT16 tmp; \
|
||||
tmp = nec_state->regs.b[AL] + param1; \
|
||||
nec_state->regs.b[AL] = tmp; \
|
||||
nec_state->AuxVal = 1; \
|
||||
nec_state->CarryVal |= tmp & 0x100; \
|
||||
} \
|
||||
if (CF || (nec_state->regs.b[AL]>0x9f)) \
|
||||
{ \
|
||||
nec_state->regs.b[AL] += param2; \
|
||||
nec_state->CarryVal = 1; \
|
||||
} \
|
||||
SetSZPF_Byte(nec_state->regs.b[AL])
|
||||
|
||||
#define ADJB(param1,param2) \
|
||||
if (AF || ((nec_state->regs.b[AL] & 0xf) > 9)) \
|
||||
{ \
|
||||
nec_state->regs.b[AL] += param1; \
|
||||
nec_state->regs.b[AH] += param2; \
|
||||
nec_state->AuxVal = 1; \
|
||||
nec_state->CarryVal = 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
nec_state->AuxVal = 0; \
|
||||
nec_state->CarryVal = 0; \
|
||||
} \
|
||||
nec_state->regs.b[AL] &= 0x0F
|
||||
|
||||
#define BITOP_BYTE \
|
||||
ModRM = FETCH(); \
|
||||
if (ModRM >= 0xc0) { \
|
||||
tmp=nec_state->regs.b[Mod_RM.RM.b[ModRM]]; \
|
||||
} \
|
||||
else { \
|
||||
(*GetEA[ModRM])(nec_state); \
|
||||
tmp=read_byte(EA); \
|
||||
}
|
||||
|
||||
#define BITOP_WORD \
|
||||
ModRM = FETCH(); \
|
||||
if (ModRM >= 0xc0) { \
|
||||
tmp=nec_state->regs.w[Mod_RM.RM.w[ModRM]]; \
|
||||
} \
|
||||
else { \
|
||||
(*GetEA[ModRM])(nec_state); \
|
||||
tmp=read_word(EA); \
|
||||
}
|
||||
|
||||
#define BIT_NOT \
|
||||
if (tmp & (1<<tmp2)) \
|
||||
tmp &= ~(1<<tmp2); \
|
||||
else \
|
||||
tmp |= (1<<tmp2)
|
||||
|
||||
#define XchgAWReg(Reg) \
|
||||
WORD tmp; \
|
||||
tmp = nec_state->regs.w[Reg]; \
|
||||
nec_state->regs.w[Reg] = nec_state->regs.w[AW]; \
|
||||
nec_state->regs.w[AW] = tmp
|
||||
|
||||
#define ROL_BYTE nec_state->CarryVal = dst & 0x80; dst = (dst << 1)+CF
|
||||
#define ROL_WORD nec_state->CarryVal = dst & 0x8000; dst = (dst << 1)+CF
|
||||
#define ROR_BYTE nec_state->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<7)
|
||||
#define ROR_WORD nec_state->CarryVal = dst & 0x1; dst = (dst >> 1)+(CF<<15)
|
||||
#define ROLC_BYTE dst = (dst << 1) + CF; SetCFB(dst)
|
||||
#define ROLC_WORD dst = (dst << 1) + CF; SetCFW(dst)
|
||||
#define RORC_BYTE dst = (CF<<8)+dst; nec_state->CarryVal = dst & 0x01; dst >>= 1
|
||||
#define RORC_WORD dst = (CF<<16)+dst; nec_state->CarryVal = dst & 0x01; dst >>= 1
|
||||
#define SHL_BYTE(c) nec_state->icount-=c; dst <<= c; SetCFB(dst); SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
|
||||
#define SHL_WORD(c) nec_state->icount-=c; dst <<= c; SetCFW(dst); SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
|
||||
#define SHR_BYTE(c) nec_state->icount-=c; dst >>= c-1; nec_state->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
|
||||
#define SHR_WORD(c) nec_state->icount-=c; dst >>= c-1; nec_state->CarryVal = dst & 0x1; dst >>= 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
|
||||
#define SHRA_BYTE(c) nec_state->icount-=c; dst = ((INT8)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT8)((BYTE)dst)) >> 1; SetSZPF_Byte(dst); PutbackRMByte(ModRM,(BYTE)dst)
|
||||
#define SHRA_WORD(c) nec_state->icount-=c; dst = ((INT16)dst) >> (c-1); nec_state->CarryVal = dst & 0x1; dst = ((INT16)((WORD)dst)) >> 1; SetSZPF_Word(dst); PutbackRMWord(ModRM,(WORD)dst)
|
||||
|
||||
#define DIVUB \
|
||||
uresult = nec_state->regs.w[AW]; \
|
||||
uresult2 = uresult % tmp; \
|
||||
if ((uresult /= tmp) > 0xff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.b[AL] = uresult; \
|
||||
nec_state->regs.b[AH] = uresult2; \
|
||||
}
|
||||
|
||||
#define DIVB \
|
||||
result = (INT16)nec_state->regs.w[AW]; \
|
||||
result2 = result % (INT16)((INT8)tmp); \
|
||||
if ((result /= (INT16)((INT8)tmp)) > 0xff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.b[AL] = result; \
|
||||
nec_state->regs.b[AH] = result2; \
|
||||
}
|
||||
|
||||
#define DIVUW \
|
||||
uresult = (((UINT32)nec_state->regs.w[DW]) << 16) | nec_state->regs.w[AW];\
|
||||
uresult2 = uresult % tmp; \
|
||||
if ((uresult /= tmp) > 0xffff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.w[AW]=uresult; \
|
||||
nec_state->regs.w[DW]=uresult2; \
|
||||
}
|
||||
|
||||
#define DIVW \
|
||||
result = ((UINT32)nec_state->regs.w[DW] << 16) + nec_state->regs.w[AW]; \
|
||||
result2 = result % (INT32)((INT16)tmp); \
|
||||
if ((result /= (INT32)((INT16)tmp)) > 0xffff) { \
|
||||
nec_interrupt(nec_state, 0,0); break; \
|
||||
} else { \
|
||||
nec_state->regs.w[AW]=result; \
|
||||
nec_state->regs.w[DW]=result2; \
|
||||
}
|
||||
|
||||
#define ADD4S { \
|
||||
int i,v1,v2,result; \
|
||||
int count = (nec_state->regs.b[CL]+1)/2; \
|
||||
unsigned di = nec_state->regs.w[IY]; \
|
||||
unsigned si = nec_state->regs.w[IX]; \
|
||||
static const UINT8 table[3]={18,19,19}; \
|
||||
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for add4s\n",PC(nec_state)); \
|
||||
nec_state->ZeroVal = nec_state->CarryVal = 0; \
|
||||
for (i=0;i<count;i++) { \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
tmp = GetMemB(DS0, si); \
|
||||
tmp2 = GetMemB(DS1, di); \
|
||||
v1 = (tmp>>4)*10 + (tmp&0xf); \
|
||||
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
|
||||
result = v1+v2+nec_state->CarryVal; \
|
||||
nec_state->CarryVal = result > 99 ? 1 : 0; \
|
||||
result = result % 100; \
|
||||
v1 = ((result/10)<<4) | (result % 10); \
|
||||
PutMemB(DS1, di,v1); \
|
||||
if (v1) nec_state->ZeroVal = 1; \
|
||||
si++; \
|
||||
di++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUB4S { \
|
||||
int count = (nec_state->regs.b[CL]+1)/2; \
|
||||
int i,v1,v2,result; \
|
||||
unsigned di = nec_state->regs.w[IY]; \
|
||||
unsigned si = nec_state->regs.w[IX]; \
|
||||
static const UINT8 table[3]={18,19,19}; \
|
||||
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for sub4s\n",PC(nec_state)); \
|
||||
nec_state->ZeroVal = nec_state->CarryVal = 0; \
|
||||
for (i=0;i<count;i++) { \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
tmp = GetMemB(DS1, di); \
|
||||
tmp2 = GetMemB(DS0, si); \
|
||||
v1 = (tmp>>4)*10 + (tmp&0xf); \
|
||||
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
|
||||
if (v1 < (v2+nec_state->CarryVal)) { \
|
||||
v1+=100; \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 1; \
|
||||
} else { \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 0; \
|
||||
} \
|
||||
v1 = ((result/10)<<4) | (result % 10); \
|
||||
PutMemB(DS1, di,v1); \
|
||||
if (v1) nec_state->ZeroVal = 1; \
|
||||
si++; \
|
||||
di++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CMP4S { \
|
||||
int count = (nec_state->regs.b[CL]+1)/2; \
|
||||
int i,v1,v2,result; \
|
||||
unsigned di = nec_state->regs.w[IY]; \
|
||||
unsigned si = nec_state->regs.w[IX]; \
|
||||
static const UINT8 table[3]={14,19,19}; \
|
||||
if (nec_state->seg_prefix) logerror("%06x: Warning: seg_prefix defined for cmp4s\n",PC(nec_state)); \
|
||||
nec_state->ZeroVal = nec_state->CarryVal = 0; \
|
||||
for (i=0;i<count;i++) { \
|
||||
nec_state->icount-=table[nec_state->chip_type/8]; \
|
||||
tmp = GetMemB(DS1, di); \
|
||||
tmp2 = GetMemB(DS0, si); \
|
||||
v1 = (tmp>>4)*10 + (tmp&0xf); \
|
||||
v2 = (tmp2>>4)*10 + (tmp2&0xf); \
|
||||
if (v1 < (v2+nec_state->CarryVal)) { \
|
||||
v1+=100; \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 1; \
|
||||
} else { \
|
||||
result = v1-(v2+nec_state->CarryVal); \
|
||||
nec_state->CarryVal = 0; \
|
||||
} \
|
||||
v1 = ((result/10)<<4) | (result % 10); \
|
||||
if (v1) nec_state->ZeroVal = 1; \
|
||||
si++; \
|
||||
di++; \
|
||||
} \
|
||||
}
|
@ -126,6 +126,60 @@ struct _pic16c5x_opcode_00x
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read the state of the T0 Clock input signal
|
||||
*/
|
||||
|
||||
#define PIC16C5x_T0_In (memory_read_byte_8le(cpustate->io, PIC16C5x_T0))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Input a word from given I/O port
|
||||
*/
|
||||
|
||||
#define PIC16C5x_In(Port) ((UINT8)memory_read_byte_8le(cpustate->io, (Port)))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Output a word to given I/O port
|
||||
*/
|
||||
|
||||
#define PIC16C5x_Out(Port,Value) (memory_write_byte_8le(cpustate->io, (Port),Value))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read a word from given RAM memory location
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RAM_RDMEM(A) ((UINT8)memory_read_byte_8le(cpustate->data, A))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write a word to given RAM memory location
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RAM_WRMEM(A,V) (memory_write_byte_8le(cpustate->data, A,V))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PIC16C5X_RDOP() is identical to PIC16C5X_RDMEM() except it is used for
|
||||
* reading opcodes. In case of system with memory mapped I/O, this function
|
||||
* can be used to greatly speed up emulation
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RDOP(A) (memory_decrypted_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PIC16C5X_RDOP_ARG() is identical to PIC16C5X_RDOP() except it is used
|
||||
* for reading opcode arguments. This difference can be used to support systems
|
||||
* that use different encoding mechanisms for opcodes and opcode arguments
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RDOP_ARG(A) (memory_raw_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
#define TMR0 internalram[1]
|
||||
#define PCL internalram[2]
|
||||
|
@ -35,6 +35,8 @@ enum
|
||||
PIC16C5x_PSCL
|
||||
};
|
||||
|
||||
#define PIC16C5x_T0 0x10
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Function to configure the CONFIG register. This is actually hard-wired
|
||||
@ -45,63 +47,6 @@ enum
|
||||
void pic16c5x_set_config(const device_config *cpu, int data);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read the state of the T0 Clock input signal
|
||||
*/
|
||||
|
||||
#define PIC16C5x_T0 0x10
|
||||
#define PIC16C5x_T0_In (memory_read_byte_8le(cpustate->io, PIC16C5x_T0))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Input a word from given I/O port
|
||||
*/
|
||||
|
||||
#define PIC16C5x_In(Port) ((UINT8)memory_read_byte_8le(cpustate->io, (Port)))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Output a word to given I/O port
|
||||
*/
|
||||
|
||||
#define PIC16C5x_Out(Port,Value) (memory_write_byte_8le(cpustate->io, (Port),Value))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read a word from given RAM memory location
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RAM_RDMEM(A) ((UINT8)memory_read_byte_8le(cpustate->data, A))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write a word to given RAM memory location
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RAM_WRMEM(A,V) (memory_write_byte_8le(cpustate->data, A,V))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PIC16C5X_RDOP() is identical to PIC16C5X_RDMEM() except it is used for
|
||||
* reading opcodes. In case of system with memory mapped I/O, this function
|
||||
* can be used to greatly speed up emulation
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RDOP(A) (memory_decrypted_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PIC16C5X_RDOP_ARG() is identical to PIC16C5X_RDOP() except it is used
|
||||
* for reading opcode arguments. This difference can be used to support systems
|
||||
* that use different encoding mechanisms for opcodes and opcode arguments
|
||||
*/
|
||||
|
||||
#define PIC16C5x_RDOP_ARG(A) (memory_raw_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
|
||||
|
||||
#if (HAS_PIC16C54)
|
||||
CPU_GET_INFO( pic16c54 );
|
||||
|
@ -21,7 +21,9 @@
|
||||
#define FLAG_B 0x02
|
||||
#define FLAG_I 0x01
|
||||
|
||||
typedef struct {
|
||||
typedef struct _sm8500_state sm8500_state;
|
||||
struct _sm8500_state
|
||||
{
|
||||
SM8500_CONFIG config;
|
||||
UINT16 PC;
|
||||
UINT8 *register_base;
|
||||
@ -46,158 +48,167 @@ typedef struct {
|
||||
UINT8 IFLAGS;
|
||||
UINT8 CheckInterrupts;
|
||||
int halted;
|
||||
int icount;
|
||||
cpu_irq_callback irq_callback;
|
||||
const device_config *device;
|
||||
const address_space *program;
|
||||
UINT8 internal_ram[0x500];
|
||||
} sm8500_regs;
|
||||
|
||||
static sm8500_regs regs;
|
||||
|
||||
/* nr of cycles to run */
|
||||
static int sm8500_icount;
|
||||
};
|
||||
|
||||
static const UINT8 sm8500_b2w[8] = {
|
||||
0, 8, 2, 10, 4, 12, 6, 14
|
||||
};
|
||||
|
||||
UINT8 sm85cpu_mem_readbyte( UINT32 offset ) {
|
||||
return ( offset < 0x10 ) ? regs.register_base[offset] : memory_read_byte_8be( regs.program, offset );
|
||||
UINT8 sm85cpu_mem_readbyte( sm8500_state *cpustate, UINT32 offset ) {
|
||||
return ( offset < 0x10 ) ? cpustate->register_base[offset] : memory_read_byte_8be( cpustate->program, offset );
|
||||
}
|
||||
|
||||
void sm85cpu_mem_writebyte( UINT32 offset, UINT8 data ) {
|
||||
void sm85cpu_mem_writebyte( sm8500_state *cpustate, UINT32 offset, UINT8 data ) {
|
||||
if ( offset < 0x10 ) {
|
||||
regs.register_base[offset] = data;
|
||||
cpustate->register_base[offset] = data;
|
||||
} else {
|
||||
memory_write_byte_8be( regs.program, offset, data );
|
||||
memory_write_byte_8be( cpustate->program, offset, data );
|
||||
}
|
||||
}
|
||||
|
||||
UINT8* sm8500_internal_ram( void )
|
||||
INLINE UINT16 sm85cpu_mem_readword( sm8500_state *cpustate, UINT32 address )
|
||||
{
|
||||
return regs.internal_ram;
|
||||
UINT16 value = (UINT16) sm85cpu_mem_readbyte( cpustate, address ) << 8;
|
||||
value |= sm85cpu_mem_readbyte( cpustate, ( address + 1 ) & 0xffff );
|
||||
return value;
|
||||
}
|
||||
|
||||
static CPU_INIT( sm8500 ) {
|
||||
regs.irq_callback = irqcallback;
|
||||
regs.device = device;
|
||||
regs.program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
|
||||
INLINE void sm85cpu_mem_writeword( sm8500_state *cpustate, UINT32 address, UINT16 value )
|
||||
{
|
||||
sm85cpu_mem_writebyte( cpustate, address, value >> 8 );
|
||||
sm85cpu_mem_writebyte( cpustate, ( address + 1 ) & 0xffff, value & 0xff );
|
||||
}
|
||||
|
||||
static CPU_INIT( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = device->token;
|
||||
|
||||
cpustate->irq_callback = irqcallback;
|
||||
cpustate->device = device;
|
||||
cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
|
||||
if ( device->static_config != NULL ) {
|
||||
regs.config.handle_dma = ((SM8500_CONFIG *)device->static_config)->handle_dma;
|
||||
regs.config.handle_timers = ((SM8500_CONFIG *)device->static_config)->handle_timers;
|
||||
cpustate->config.handle_dma = ((SM8500_CONFIG *)device->static_config)->handle_dma;
|
||||
cpustate->config.handle_timers = ((SM8500_CONFIG *)device->static_config)->handle_timers;
|
||||
} else {
|
||||
regs.config.handle_dma = NULL;
|
||||
regs.config.handle_timers = NULL;
|
||||
cpustate->config.handle_dma = NULL;
|
||||
cpustate->config.handle_timers = NULL;
|
||||
}
|
||||
regs.register_base = regs.internal_ram;
|
||||
cpustate->register_base = cpustate->internal_ram;
|
||||
}
|
||||
|
||||
static CPU_RESET( sm8500 )
|
||||
{
|
||||
regs.PC = 0x1020;
|
||||
regs.IE0 = 0;
|
||||
regs.IE1 = 0;
|
||||
regs.IR0 = 0;
|
||||
regs.IR1 = 0;
|
||||
regs.P0 = 0xFF;
|
||||
regs.P1 = 0xFF;
|
||||
regs.P2 = 0xFF;
|
||||
regs.P3 = 0;
|
||||
regs.SYS = 0;
|
||||
regs.CKC = 0; regs.clock_changed = 0;
|
||||
regs.PS1 = 0;
|
||||
regs.register_base = regs.internal_ram;
|
||||
regs.halted = 0;
|
||||
sm8500_state *cpustate = device->token;
|
||||
|
||||
cpustate->PC = 0x1020;
|
||||
cpustate->IE0 = 0;
|
||||
cpustate->IE1 = 0;
|
||||
cpustate->IR0 = 0;
|
||||
cpustate->IR1 = 0;
|
||||
cpustate->P0 = 0xFF;
|
||||
cpustate->P1 = 0xFF;
|
||||
cpustate->P2 = 0xFF;
|
||||
cpustate->P3 = 0;
|
||||
cpustate->SYS = 0;
|
||||
cpustate->CKC = 0; cpustate->clock_changed = 0;
|
||||
cpustate->PS1 = 0;
|
||||
cpustate->register_base = cpustate->internal_ram;
|
||||
cpustate->halted = 0;
|
||||
}
|
||||
|
||||
static CPU_EXIT( sm8500 )
|
||||
{
|
||||
}
|
||||
|
||||
#define PUSH_BYTE(X) regs.SP = regs.SP - 1; \
|
||||
if ( ( regs.SYS & 0x40 ) == 0 ) { \
|
||||
regs.SP = regs.SP & 0xFF; \
|
||||
#define PUSH_BYTE(X) cpustate->SP = cpustate->SP - 1; \
|
||||
if ( ( cpustate->SYS & 0x40 ) == 0 ) { \
|
||||
cpustate->SP = cpustate->SP & 0xFF; \
|
||||
} \
|
||||
sm85cpu_mem_writebyte( regs.SP, X );
|
||||
sm85cpu_mem_writebyte( cpustate, cpustate->SP, X );
|
||||
|
||||
INLINE void sm8500_do_interrupt(UINT16 vector) {
|
||||
INLINE void sm8500_do_interrupt(sm8500_state *cpustate, UINT16 vector) {
|
||||
/* Push PC */
|
||||
PUSH_BYTE( regs.PC & 0xFF );
|
||||
PUSH_BYTE( regs.PC >> 8 );
|
||||
PUSH_BYTE( cpustate->PC & 0xFF );
|
||||
PUSH_BYTE( cpustate->PC >> 8 );
|
||||
/* Push PS1 */
|
||||
PUSH_BYTE( regs.PS1 );
|
||||
PUSH_BYTE( cpustate->PS1 );
|
||||
/* Clear I flag */
|
||||
regs.PS1 &= ~ 0x01;
|
||||
cpustate->PS1 &= ~ 0x01;
|
||||
/* Change PC to address stored at "vector" */
|
||||
regs.PC = sm85cpu_mem_readword( vector );
|
||||
cpustate->PC = sm85cpu_mem_readword( cpustate, vector );
|
||||
}
|
||||
|
||||
INLINE void sm8500_process_interrupts(void) {
|
||||
if ( regs.CheckInterrupts ) {
|
||||
INLINE void sm8500_process_interrupts(sm8500_state *cpustate) {
|
||||
if ( cpustate->CheckInterrupts ) {
|
||||
int irqline = 0;
|
||||
while( irqline < 11 ) {
|
||||
if ( regs.IFLAGS & ( 1 << irqline ) ) {
|
||||
regs.halted = 0;
|
||||
if ( cpustate->IFLAGS & ( 1 << irqline ) ) {
|
||||
cpustate->halted = 0;
|
||||
switch( irqline ) {
|
||||
case ILL_INT:
|
||||
sm8500_do_interrupt( 0x101C );
|
||||
sm8500_do_interrupt( cpustate, 0x101C );
|
||||
break;
|
||||
case WDT_INT:
|
||||
sm8500_do_interrupt( 0x101E );
|
||||
sm8500_do_interrupt( cpustate, 0x101E );
|
||||
break;
|
||||
case NMI_INT:
|
||||
sm8500_do_interrupt( 0x101E );
|
||||
sm8500_do_interrupt( cpustate, 0x101E );
|
||||
break;
|
||||
case DMA_INT:
|
||||
regs.IR0 |= 0x80;
|
||||
if ( ( regs.IE0 & 0x80 ) && ( ( regs.PS0 & 0x07 ) < 8 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x1000 );
|
||||
cpustate->IR0 |= 0x80;
|
||||
if ( ( cpustate->IE0 & 0x80 ) && ( ( cpustate->PS0 & 0x07 ) < 8 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1000 );
|
||||
}
|
||||
break;
|
||||
case TIM0_INT:
|
||||
regs.IR0 |= 0x40;
|
||||
if ( ( regs.IE0 & 0x40 ) && ( ( regs.PS0 & 0x07 ) < 8 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x1002 );
|
||||
cpustate->IR0 |= 0x40;
|
||||
if ( ( cpustate->IE0 & 0x40 ) && ( ( cpustate->PS0 & 0x07 ) < 8 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1002 );
|
||||
}
|
||||
break;
|
||||
case EXT_INT:
|
||||
regs.IR0 |= 0x10;
|
||||
if ( ( regs.IE0 & 0x10 ) && ( ( regs.PS0 & 0x07 ) < 7 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x1006 );
|
||||
cpustate->IR0 |= 0x10;
|
||||
if ( ( cpustate->IE0 & 0x10 ) && ( ( cpustate->PS0 & 0x07 ) < 7 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1006 );
|
||||
}
|
||||
break;
|
||||
case UART_INT:
|
||||
regs.IR0 |= 0x08;
|
||||
if ( ( regs.IE0 & 0x08 ) && ( ( regs.PS0 & 0x07 ) < 6 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x1008 );
|
||||
cpustate->IR0 |= 0x08;
|
||||
if ( ( cpustate->IE0 & 0x08 ) && ( ( cpustate->PS0 & 0x07 ) < 6 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1008 );
|
||||
}
|
||||
break;
|
||||
case LCDC_INT:
|
||||
regs.IR0 |= 0x01;
|
||||
if ( ( regs.IE0 & 0x01 ) && ( ( regs.PS0 & 0x07 ) < 5 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x100E );
|
||||
cpustate->IR0 |= 0x01;
|
||||
if ( ( cpustate->IE0 & 0x01 ) && ( ( cpustate->PS0 & 0x07 ) < 5 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x100E );
|
||||
}
|
||||
break;
|
||||
case TIM1_INT:
|
||||
regs.IR1 |= 0x40;
|
||||
if ( ( regs.IE1 & 0x40 ) && ( ( regs.PS0 & 0x07 ) < 4 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x1012 );
|
||||
cpustate->IR1 |= 0x40;
|
||||
if ( ( cpustate->IE1 & 0x40 ) && ( ( cpustate->PS0 & 0x07 ) < 4 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1012 );
|
||||
}
|
||||
break;
|
||||
case CK_INT:
|
||||
regs.IR1 |= 0x10;
|
||||
if ( ( regs.IE1 & 0x10 ) && ( ( regs.PS0 & 0x07 ) < 3 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x1016 );
|
||||
cpustate->IR1 |= 0x10;
|
||||
if ( ( cpustate->IE1 & 0x10 ) && ( ( cpustate->PS0 & 0x07 ) < 3 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x1016 );
|
||||
}
|
||||
break;
|
||||
case PIO_INT:
|
||||
regs.IR1 |= 0x04;
|
||||
if ( ( regs.IE1 & 0x04 ) && ( ( regs.PS0 & 0x07 ) < 2 ) && ( regs.PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( 0x101A );
|
||||
cpustate->IR1 |= 0x04;
|
||||
if ( ( cpustate->IE1 & 0x04 ) && ( ( cpustate->PS0 & 0x07 ) < 2 ) && ( cpustate->PS1 & 0x01 ) ) {
|
||||
sm8500_do_interrupt( cpustate, 0x101A );
|
||||
}
|
||||
break;
|
||||
}
|
||||
regs.IFLAGS &= ~ ( 1 << irqline );
|
||||
cpustate->IFLAGS &= ~ ( 1 << irqline );
|
||||
}
|
||||
irqline++;
|
||||
}
|
||||
@ -206,11 +217,12 @@ INLINE void sm8500_process_interrupts(void) {
|
||||
|
||||
static CPU_EXECUTE( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = device->token;
|
||||
UINT8 op;
|
||||
UINT16 oldpc;
|
||||
int mycycles;
|
||||
|
||||
sm8500_icount = cycles;
|
||||
cpustate->icount = cycles;
|
||||
|
||||
do
|
||||
{
|
||||
@ -219,154 +231,158 @@ static CPU_EXECUTE( sm8500 )
|
||||
UINT32 d1,d2;
|
||||
UINT32 res;
|
||||
|
||||
debugger_instruction_hook(device, regs.PC);
|
||||
oldpc = regs.PC;
|
||||
debugger_instruction_hook(device, cpustate->PC);
|
||||
oldpc = cpustate->PC;
|
||||
mycycles = 0;
|
||||
sm8500_process_interrupts();
|
||||
if ( !regs.halted ) {
|
||||
op = sm85cpu_mem_readbyte( regs.PC++ );
|
||||
sm8500_process_interrupts(cpustate);
|
||||
if ( !cpustate->halted ) {
|
||||
op = sm85cpu_mem_readbyte( cpustate, cpustate->PC++ );
|
||||
switch( op )
|
||||
{
|
||||
#include "sm85ops.h"
|
||||
}
|
||||
} else {
|
||||
mycycles = 4;
|
||||
if ( regs.config.handle_dma ) {
|
||||
regs.config.handle_dma( mycycles );
|
||||
if ( cpustate->config.handle_dma ) {
|
||||
cpustate->config.handle_dma( device, mycycles );
|
||||
}
|
||||
}
|
||||
if ( regs.config.handle_timers ) {
|
||||
regs.config.handle_timers( mycycles );
|
||||
if ( cpustate->config.handle_timers ) {
|
||||
cpustate->config.handle_timers( device, mycycles );
|
||||
}
|
||||
sm8500_icount -= mycycles;
|
||||
} while ( sm8500_icount > 0 );
|
||||
cpustate->icount -= mycycles;
|
||||
} while ( cpustate->icount > 0 );
|
||||
|
||||
return cycles - sm8500_icount;
|
||||
return cycles - cpustate->icount;
|
||||
}
|
||||
|
||||
static CPU_BURN( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = device->token;
|
||||
|
||||
if ( cycles > 0 ) {
|
||||
/* burn a number of 4 cycles */
|
||||
int n = ( cycles + 3 ) / 4;
|
||||
sm8500_icount -= 4 * n;
|
||||
cpustate->icount -= 4 * n;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned sm8500_get_reg( int regnum )
|
||||
unsigned sm8500_get_reg( sm8500_state *cpustate, int regnum )
|
||||
{
|
||||
switch( regnum )
|
||||
{
|
||||
case REG_PC:
|
||||
case SM8500_PC: return regs.PC;
|
||||
case SM8500_PC: return cpustate->PC;
|
||||
case REG_SP:
|
||||
case SM8500_SP: return ( regs.SYS & 0x40 ) ? regs.SP : regs.SP & 0xFF ;
|
||||
case SM8500_PS: return ( regs.PS0 << 8 ) | regs.PS1;
|
||||
case SM8500_SYS16: return regs.SYS;
|
||||
case SM8500_RR0: return sm85cpu_mem_readword( 0x00 );
|
||||
case SM8500_RR2: return sm85cpu_mem_readword( 0x02 );
|
||||
case SM8500_RR4: return sm85cpu_mem_readword( 0x04 );
|
||||
case SM8500_RR6: return sm85cpu_mem_readword( 0x06 );
|
||||
case SM8500_RR8: return sm85cpu_mem_readword( 0x08 );
|
||||
case SM8500_RR10: return sm85cpu_mem_readword( 0x0A );
|
||||
case SM8500_RR12: return sm85cpu_mem_readword( 0x0C );
|
||||
case SM8500_RR14: return sm85cpu_mem_readword( 0x0E );
|
||||
case SM8500_IE0: return regs.IE0;
|
||||
case SM8500_IE1: return regs.IE1;
|
||||
case SM8500_IR0: return regs.IR0;
|
||||
case SM8500_IR1: return regs.IR1;
|
||||
case SM8500_P0: return regs.P0;
|
||||
case SM8500_P1: return regs.P1;
|
||||
case SM8500_P2: return regs.P2;
|
||||
case SM8500_P3: return regs.P3;
|
||||
case SM8500_SYS: return regs.SYS;
|
||||
case SM8500_CKC: return regs.CKC;
|
||||
case SM8500_SPH: return (regs.SP >> 8);
|
||||
case SM8500_SPL: return regs.SP & 0xFF;
|
||||
case SM8500_PS0: return regs.PS0;
|
||||
case SM8500_PS1: return regs.PS1;
|
||||
case SM8500_P0C: return regs.P0C;
|
||||
case SM8500_P1C: return regs.P1C;
|
||||
case SM8500_P2C: return regs.P2C;
|
||||
case SM8500_P3C: return regs.P3C;
|
||||
case SM8500_SP: return ( cpustate->SYS & 0x40 ) ? cpustate->SP : cpustate->SP & 0xFF ;
|
||||
case SM8500_PS: return ( cpustate->PS0 << 8 ) | cpustate->PS1;
|
||||
case SM8500_SYS16: return cpustate->SYS;
|
||||
case SM8500_RR0: return sm85cpu_mem_readword( cpustate, 0x00 );
|
||||
case SM8500_RR2: return sm85cpu_mem_readword( cpustate, 0x02 );
|
||||
case SM8500_RR4: return sm85cpu_mem_readword( cpustate, 0x04 );
|
||||
case SM8500_RR6: return sm85cpu_mem_readword( cpustate, 0x06 );
|
||||
case SM8500_RR8: return sm85cpu_mem_readword( cpustate, 0x08 );
|
||||
case SM8500_RR10: return sm85cpu_mem_readword( cpustate, 0x0A );
|
||||
case SM8500_RR12: return sm85cpu_mem_readword( cpustate, 0x0C );
|
||||
case SM8500_RR14: return sm85cpu_mem_readword( cpustate, 0x0E );
|
||||
case SM8500_IE0: return cpustate->IE0;
|
||||
case SM8500_IE1: return cpustate->IE1;
|
||||
case SM8500_IR0: return cpustate->IR0;
|
||||
case SM8500_IR1: return cpustate->IR1;
|
||||
case SM8500_P0: return cpustate->P0;
|
||||
case SM8500_P1: return cpustate->P1;
|
||||
case SM8500_P2: return cpustate->P2;
|
||||
case SM8500_P3: return cpustate->P3;
|
||||
case SM8500_SYS: return cpustate->SYS;
|
||||
case SM8500_CKC: return cpustate->CKC;
|
||||
case SM8500_SPH: return (cpustate->SP >> 8);
|
||||
case SM8500_SPL: return cpustate->SP & 0xFF;
|
||||
case SM8500_PS0: return cpustate->PS0;
|
||||
case SM8500_PS1: return cpustate->PS1;
|
||||
case SM8500_P0C: return cpustate->P0C;
|
||||
case SM8500_P1C: return cpustate->P1C;
|
||||
case SM8500_P2C: return cpustate->P2C;
|
||||
case SM8500_P3C: return cpustate->P3C;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sm8500_set_reg( int regnum, unsigned val )
|
||||
static void sm8500_set_reg( sm8500_state *cpustate, int regnum, unsigned val )
|
||||
{
|
||||
switch( regnum )
|
||||
{
|
||||
case REG_PC:
|
||||
case SM8500_PC: regs.PC = val; break;
|
||||
case SM8500_PC: cpustate->PC = val; break;
|
||||
case REG_SP:
|
||||
case SM8500_SP: regs.SP = val; break;
|
||||
case SM8500_PS: sm8500_set_reg( SM8500_PS0, ( val >> 8 ) & 0xFF ); sm8500_set_reg( SM8500_PS1, val & 0xFF ); break;
|
||||
case SM8500_SYS16: regs.SYS = val; break;
|
||||
case SM8500_RR0: sm85cpu_mem_writeword( 0x00, val); break;
|
||||
case SM8500_RR2: sm85cpu_mem_writeword( 0x02, val); break;
|
||||
case SM8500_RR4: sm85cpu_mem_writeword( 0x04, val); break;
|
||||
case SM8500_RR6: sm85cpu_mem_writeword( 0x06, val); break;
|
||||
case SM8500_RR8: sm85cpu_mem_writeword( 0x08, val); break;
|
||||
case SM8500_RR10: sm85cpu_mem_writeword( 0x0A, val); break;
|
||||
case SM8500_RR12: sm85cpu_mem_writeword( 0x0C, val); break;
|
||||
case SM8500_RR14: sm85cpu_mem_writeword( 0x0E, val); break;
|
||||
case SM8500_IE0: regs.IE0 = val; break;
|
||||
case SM8500_IE1: regs.IE1 = val; break;
|
||||
case SM8500_IR0: regs.IR0 = val; break;
|
||||
case SM8500_IR1: regs.IR1 = val; break;
|
||||
case SM8500_P0: regs.P0 = val; break;
|
||||
case SM8500_P1: regs.P1 = val; break;
|
||||
case SM8500_P2: regs.P2 = val; break;
|
||||
case SM8500_P3: regs.P3 = val; break;
|
||||
case SM8500_SYS: regs.SYS = val; break;
|
||||
case SM8500_CKC: regs.CKC = val; if ( val & 0x80 ) { regs.clock_changed = 1; }; break;
|
||||
case SM8500_SPH: regs.SP = ( ( val & 0xFF ) << 8 ) | ( regs.SP & 0xFF ); break;
|
||||
case SM8500_SPL: regs.SP = ( regs.SP & 0xFF00 ) | ( val & 0xFF ); break;
|
||||
case SM8500_PS0: regs.PS0 = val; regs.register_base = regs.internal_ram + ( val & 0xF8 ); break;
|
||||
case SM8500_PS1: regs.PS1 = val; break;
|
||||
case SM8500_P0C: regs.P0C = val; break;
|
||||
case SM8500_P1C: regs.P1C = val; break;
|
||||
case SM8500_P2C: regs.P2C = val; break;
|
||||
case SM8500_P3C: regs.P3C = val; break;
|
||||
case SM8500_SP: cpustate->SP = val; break;
|
||||
case SM8500_PS: sm8500_set_reg( cpustate, SM8500_PS0, ( val >> 8 ) & 0xFF ); sm8500_set_reg( cpustate, SM8500_PS1, val & 0xFF ); break;
|
||||
case SM8500_SYS16: cpustate->SYS = val; break;
|
||||
case SM8500_RR0: sm85cpu_mem_writeword( cpustate, 0x00, val); break;
|
||||
case SM8500_RR2: sm85cpu_mem_writeword( cpustate, 0x02, val); break;
|
||||
case SM8500_RR4: sm85cpu_mem_writeword( cpustate, 0x04, val); break;
|
||||
case SM8500_RR6: sm85cpu_mem_writeword( cpustate, 0x06, val); break;
|
||||
case SM8500_RR8: sm85cpu_mem_writeword( cpustate, 0x08, val); break;
|
||||
case SM8500_RR10: sm85cpu_mem_writeword( cpustate, 0x0A, val); break;
|
||||
case SM8500_RR12: sm85cpu_mem_writeword( cpustate, 0x0C, val); break;
|
||||
case SM8500_RR14: sm85cpu_mem_writeword( cpustate, 0x0E, val); break;
|
||||
case SM8500_IE0: cpustate->IE0 = val; break;
|
||||
case SM8500_IE1: cpustate->IE1 = val; break;
|
||||
case SM8500_IR0: cpustate->IR0 = val; break;
|
||||
case SM8500_IR1: cpustate->IR1 = val; break;
|
||||
case SM8500_P0: cpustate->P0 = val; break;
|
||||
case SM8500_P1: cpustate->P1 = val; break;
|
||||
case SM8500_P2: cpustate->P2 = val; break;
|
||||
case SM8500_P3: cpustate->P3 = val; break;
|
||||
case SM8500_SYS: cpustate->SYS = val; break;
|
||||
case SM8500_CKC: cpustate->CKC = val; if ( val & 0x80 ) { cpustate->clock_changed = 1; }; break;
|
||||
case SM8500_SPH: cpustate->SP = ( ( val & 0xFF ) << 8 ) | ( cpustate->SP & 0xFF ); break;
|
||||
case SM8500_SPL: cpustate->SP = ( cpustate->SP & 0xFF00 ) | ( val & 0xFF ); break;
|
||||
case SM8500_PS0: cpustate->PS0 = val; cpustate->register_base = cpustate->internal_ram + ( val & 0xF8 ); break;
|
||||
case SM8500_PS1: cpustate->PS1 = val; break;
|
||||
case SM8500_P0C: cpustate->P0C = val; break;
|
||||
case SM8500_P1C: cpustate->P1C = val; break;
|
||||
case SM8500_P2C: cpustate->P2C = val; break;
|
||||
case SM8500_P3C: cpustate->P3C = val; break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sm8500_set_irq_line( int irqline, int state )
|
||||
static void sm8500_set_irq_line( sm8500_state *cpustate, int irqline, int state )
|
||||
{
|
||||
if ( state == ASSERT_LINE ) {
|
||||
regs.IFLAGS |= ( 0x01 << irqline );
|
||||
regs.CheckInterrupts = 1;
|
||||
cpustate->IFLAGS |= ( 0x01 << irqline );
|
||||
cpustate->CheckInterrupts = 1;
|
||||
switch( irqline ) {
|
||||
case DMA_INT: regs.IR0 |= 0x80; break;
|
||||
case TIM0_INT: regs.IR0 |= 0x40; break;
|
||||
case EXT_INT: regs.IR0 |= 0x10; break;
|
||||
case UART_INT: regs.IR0 |= 0x08; break;
|
||||
case LCDC_INT: regs.IR0 |= 0x01; break;
|
||||
case TIM1_INT: regs.IR1 |= 0x40; break;
|
||||
case CK_INT: regs.IR1 |= 0x10; break;
|
||||
case PIO_INT: regs.IR1 |= 0x04; break;
|
||||
case DMA_INT: cpustate->IR0 |= 0x80; break;
|
||||
case TIM0_INT: cpustate->IR0 |= 0x40; break;
|
||||
case EXT_INT: cpustate->IR0 |= 0x10; break;
|
||||
case UART_INT: cpustate->IR0 |= 0x08; break;
|
||||
case LCDC_INT: cpustate->IR0 |= 0x01; break;
|
||||
case TIM1_INT: cpustate->IR1 |= 0x40; break;
|
||||
case CK_INT: cpustate->IR1 |= 0x10; break;
|
||||
case PIO_INT: cpustate->IR1 |= 0x04; break;
|
||||
}
|
||||
} else {
|
||||
regs.IFLAGS &= ~( 0x01 << irqline );
|
||||
cpustate->IFLAGS &= ~( 0x01 << irqline );
|
||||
switch( irqline ) {
|
||||
case DMA_INT: regs.IR0 &= ~0x80; break;
|
||||
case TIM0_INT: regs.IR0 &= ~0x40; break;
|
||||
case EXT_INT: regs.IR0 &= ~0x10; break;
|
||||
case UART_INT: regs.IR0 &= ~0x08; break;
|
||||
case LCDC_INT: regs.IR0 &= ~0x01; break;
|
||||
case TIM1_INT: regs.IR1 &= ~0x40; break;
|
||||
case CK_INT: regs.IR1 &= ~0x10; break;
|
||||
case PIO_INT: regs.IR1 &= ~0x04; break;
|
||||
case DMA_INT: cpustate->IR0 &= ~0x80; break;
|
||||
case TIM0_INT: cpustate->IR0 &= ~0x40; break;
|
||||
case EXT_INT: cpustate->IR0 &= ~0x10; break;
|
||||
case UART_INT: cpustate->IR0 &= ~0x08; break;
|
||||
case LCDC_INT: cpustate->IR0 &= ~0x01; break;
|
||||
case TIM1_INT: cpustate->IR1 &= ~0x40; break;
|
||||
case CK_INT: cpustate->IR1 &= ~0x10; break;
|
||||
case PIO_INT: cpustate->IR1 &= ~0x04; break;
|
||||
}
|
||||
if ( 0 == regs.IFLAGS ) {
|
||||
regs.CheckInterrupts = 0;
|
||||
if ( 0 == cpustate->IFLAGS ) {
|
||||
cpustate->CheckInterrupts = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static CPU_SET_INFO( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = device->token;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case CPUINFO_INT_INPUT_STATE + 0:
|
||||
@ -380,7 +396,7 @@ static CPU_SET_INFO( sm8500 )
|
||||
case CPUINFO_INT_INPUT_STATE + 8:
|
||||
case CPUINFO_INT_INPUT_STATE + 9:
|
||||
case CPUINFO_INT_INPUT_STATE + 10:
|
||||
sm8500_set_irq_line( state - CPUINFO_INT_INPUT_STATE, info->i ); break;
|
||||
sm8500_set_irq_line( cpustate, state - CPUINFO_INT_INPUT_STATE, info->i ); break;
|
||||
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR2:
|
||||
@ -412,16 +428,18 @@ static CPU_SET_INFO( sm8500 )
|
||||
case CPUINFO_INT_REGISTER + SM8500_P1C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P2C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P3C:
|
||||
sm8500_set_reg( state - CPUINFO_INT_REGISTER, info->i ); break;
|
||||
sm8500_set_reg( cpustate, state - CPUINFO_INT_REGISTER, info->i ); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CPU_GET_INFO( sm8500 )
|
||||
{
|
||||
sm8500_state *cpustate = (device != NULL) ? device->token : NULL;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(sm8500_regs); break;
|
||||
case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(sm8500_state); break;
|
||||
case CPUINFO_INT_INPUT_LINES: info->i = 8; break;
|
||||
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break;
|
||||
case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
|
||||
@ -447,7 +465,7 @@ CPU_GET_INFO( sm8500 )
|
||||
case CPUINFO_INT_INPUT_STATE + 4:
|
||||
case CPUINFO_INT_INPUT_STATE + 5:
|
||||
case CPUINFO_INT_INPUT_STATE + 6:
|
||||
case CPUINFO_INT_INPUT_STATE + 7: info->i = regs.IFLAGS & ( 1 << (state - CPUINFO_INT_INPUT_STATE)); break;
|
||||
case CPUINFO_INT_INPUT_STATE + 7: info->i = cpustate->IFLAGS & ( 1 << (state - CPUINFO_INT_INPUT_STATE)); break;
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR0:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR2:
|
||||
case CPUINFO_INT_REGISTER + SM8500_RR4:
|
||||
@ -478,9 +496,9 @@ CPU_GET_INFO( sm8500 )
|
||||
case CPUINFO_INT_REGISTER + SM8500_P1C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P2C:
|
||||
case CPUINFO_INT_REGISTER + SM8500_P3C:
|
||||
info->i = sm8500_get_reg( state - CPUINFO_INT_REGISTER ); break;
|
||||
case CPUINFO_INT_REGISTER + REG_PC: info->i = sm8500_get_reg( SM8500_PC ); break;
|
||||
case CPUINFO_INT_REGISTER + REG_SP: info->i = sm8500_get_reg( SM8500_SP ); break;
|
||||
info->i = sm8500_get_reg( cpustate, state - CPUINFO_INT_REGISTER ); break;
|
||||
case CPUINFO_INT_REGISTER + REG_PC: info->i = sm8500_get_reg( cpustate, SM8500_PC ); break;
|
||||
case CPUINFO_INT_REGISTER + REG_SP: info->i = sm8500_get_reg( cpustate, SM8500_SP ); break;
|
||||
case CPUINFO_INT_PREVIOUSPC: info->i = 0x0000; break;
|
||||
|
||||
|
||||
@ -491,7 +509,8 @@ CPU_GET_INFO( sm8500 )
|
||||
case CPUINFO_PTR_EXECUTE: info->execute = CPU_EXECUTE_NAME(sm8500); break;
|
||||
case CPUINFO_PTR_BURN: info->burn = CPU_BURN_NAME(sm8500); break;
|
||||
case CPUINFO_PTR_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(sm8500); break;
|
||||
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &sm8500_icount; break;
|
||||
case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
|
||||
case CPUINFO_PTR_SM8500_INTERNAL_RAM: info->p = cpustate->internal_ram; break;
|
||||
|
||||
case CPUINFO_STR_NAME: strcpy( info->s, "sm8500" ); break;
|
||||
case CPUINFO_STR_CORE_FAMILY: strcpy( info->s, "Sharp SM8500" ); break;
|
||||
@ -500,27 +519,27 @@ CPU_GET_INFO( sm8500 )
|
||||
case CPUINFO_STR_CORE_CREDITS: strcpy( info->s, "Copyright The MESS Team." ); break;
|
||||
case CPUINFO_STR_FLAGS:
|
||||
sprintf( info->s, "%c%c%c%c%c%c%c%c",
|
||||
regs.PS1 & FLAG_C ? 'C' : '.',
|
||||
regs.PS1 & FLAG_Z ? 'Z' : '.',
|
||||
regs.PS1 & FLAG_S ? 'S' : '.',
|
||||
regs.PS1 & FLAG_V ? 'V' : '.',
|
||||
regs.PS1 & FLAG_D ? 'D' : '.',
|
||||
regs.PS1 & FLAG_H ? 'H' : '.',
|
||||
regs.PS1 & FLAG_B ? 'B' : '.',
|
||||
regs.PS1 & FLAG_I ? 'I' : '.' );
|
||||
cpustate->PS1 & FLAG_C ? 'C' : '.',
|
||||
cpustate->PS1 & FLAG_Z ? 'Z' : '.',
|
||||
cpustate->PS1 & FLAG_S ? 'S' : '.',
|
||||
cpustate->PS1 & FLAG_V ? 'V' : '.',
|
||||
cpustate->PS1 & FLAG_D ? 'D' : '.',
|
||||
cpustate->PS1 & FLAG_H ? 'H' : '.',
|
||||
cpustate->PS1 & FLAG_B ? 'B' : '.',
|
||||
cpustate->PS1 & FLAG_I ? 'I' : '.' );
|
||||
break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR0: sprintf(info->s, "RR0:%04X", sm85cpu_mem_readword( 0x00 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR2: sprintf(info->s, "RR2:%04X", sm85cpu_mem_readword( 0x02 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR4: sprintf(info->s, "RR4:%04X", sm85cpu_mem_readword( 0x04 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR6: sprintf(info->s, "RR6:%04X", sm85cpu_mem_readword( 0x06 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR8: sprintf(info->s, "RR8:%04X", sm85cpu_mem_readword( 0x08 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR10: sprintf(info->s, "RR10:%04X", sm85cpu_mem_readword( 0x0A ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR12: sprintf(info->s, "RR12:%04X", sm85cpu_mem_readword( 0x0C ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR14: sprintf(info->s, "RR14:%04X", sm85cpu_mem_readword( 0x0E ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_PC: sprintf(info->s, "PC:%04X", regs.PC); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_SP: sprintf(info->s, "SP:%04X", regs.SP); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_PS: sprintf(info->s, "PS:%04X", ( regs.PS0 << 8 ) | regs.PS1 ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_SYS16: sprintf(info->s, "SYS:%04X", regs.SYS ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR0: sprintf(info->s, "RR0:%04X", sm85cpu_mem_readword( cpustate, 0x00 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR2: sprintf(info->s, "RR2:%04X", sm85cpu_mem_readword( cpustate, 0x02 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR4: sprintf(info->s, "RR4:%04X", sm85cpu_mem_readword( cpustate, 0x04 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR6: sprintf(info->s, "RR6:%04X", sm85cpu_mem_readword( cpustate, 0x06 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR8: sprintf(info->s, "RR8:%04X", sm85cpu_mem_readword( cpustate, 0x08 ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR10: sprintf(info->s, "RR10:%04X", sm85cpu_mem_readword( cpustate, 0x0A ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR12: sprintf(info->s, "RR12:%04X", sm85cpu_mem_readword( cpustate, 0x0C ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_RR14: sprintf(info->s, "RR14:%04X", sm85cpu_mem_readword( cpustate, 0x0E ) ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_PC: sprintf(info->s, "PC:%04X", cpustate->PC); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_SP: sprintf(info->s, "SP:%04X", cpustate->SP); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_PS: sprintf(info->s, "PS:%04X", ( cpustate->PS0 << 8 ) | cpustate->PS1 ); break;
|
||||
case CPUINFO_STR_REGISTER + SM8500_SYS16: sprintf(info->s, "SYS:%04X", cpustate->SYS ); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
#include "cpuintrf.h"
|
||||
|
||||
typedef struct {
|
||||
void (*handle_dma)(int cycles);
|
||||
void (*handle_timers)(int cycles);
|
||||
void (*handle_dma)(const device_config *device, int cycles);
|
||||
void (*handle_timers)(const device_config *device, int cycles);
|
||||
} SM8500_CONFIG;
|
||||
|
||||
/* interrupts */
|
||||
@ -23,6 +23,12 @@ typedef struct {
|
||||
#define WDT_INT 9
|
||||
#define NMI_INT 10
|
||||
|
||||
enum
|
||||
{
|
||||
CPUINFO_PTR_SM8500_INTERNAL_RAM = CPUINFO_PTR_CPU_SPECIFIC
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
/* "main" 16 bit register */
|
||||
@ -33,26 +39,8 @@ enum
|
||||
SM8500_SPH, SM8500_SPL, SM8500_PS0, SM8500_PS1, SM8500_P0C, SM8500_P1C, SM8500_P2C, SM8500_P3C,
|
||||
};
|
||||
|
||||
extern UINT8* sm8500_internal_ram( void ) ;
|
||||
extern unsigned sm8500_get_reg( int regnum );
|
||||
extern CPU_GET_INFO( sm8500 );
|
||||
#define CPU_sm8500 CPU_GET_INFO_NAME( sm8500 )
|
||||
|
||||
UINT8 sm85cpu_mem_readbyte( UINT32 offset );
|
||||
void sm85cpu_mem_writebyte( UINT32 offset, UINT8 data );
|
||||
|
||||
INLINE UINT16 sm85cpu_mem_readword( UINT32 address )
|
||||
{
|
||||
UINT16 value = (UINT16) sm85cpu_mem_readbyte( address ) << 8;
|
||||
value |= sm85cpu_mem_readbyte( ( address + 1 ) & 0xffff );
|
||||
return value;
|
||||
}
|
||||
|
||||
INLINE void sm85cpu_mem_writeword( UINT32 address, UINT16 value )
|
||||
{
|
||||
sm85cpu_mem_writebyte( address, value >> 8 );
|
||||
sm85cpu_mem_writebyte( ( address + 1 ) & 0xffff, value & 0xff );
|
||||
}
|
||||
#define CPU_SM8500 CPU_GET_INFO_NAME( sm8500 )
|
||||
|
||||
extern CPU_DISASSEMBLE( sm8500 );
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,6 +64,39 @@ Address Function Register R/W When Reset Remarks
|
||||
#include "debugger.h"
|
||||
#include "spc700.h"
|
||||
|
||||
/* CPU Structure */
|
||||
typedef struct
|
||||
{
|
||||
uint a; /* Accumulator */
|
||||
uint x; /* Index Register X */
|
||||
uint y; /* Index Register Y */
|
||||
uint s; /* Stack Pointer */
|
||||
uint pc; /* Program Counter */
|
||||
uint ppc; /* Previous Program Counter */
|
||||
uint flag_n; /* Negative Flag */
|
||||
uint flag_z; /* Zero flag */
|
||||
uint flag_v; /* Overflow Flag */
|
||||
uint flag_p; /* Direct Page Flag */
|
||||
uint flag_b; /* BRK Instruction Flag */
|
||||
uint flag_h; /* Half-carry Flag */
|
||||
uint flag_i; /* Interrupt Mask Flag */
|
||||
uint flag_c; /* Carry Flag */
|
||||
uint line_irq; /* Status of the IRQ line */
|
||||
uint line_nmi; /* Status of the NMI line */
|
||||
uint line_rst; /* Status of the RESET line */
|
||||
uint ir; /* Instruction Register */
|
||||
cpu_irq_callback int_ack;
|
||||
const device_config *device;
|
||||
const address_space *program;
|
||||
uint stopped; /* stopped status */
|
||||
int ICount;
|
||||
uint source;
|
||||
uint destination;
|
||||
uint temp1, temp2, temp3;
|
||||
short spc_int16;
|
||||
int spc_int32;
|
||||
} spc700i_cpu;
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
|
||||
/* ======================================================================== */
|
||||
@ -206,6 +239,82 @@ INLINE int MAKE_INT_8(int A) {return (A & 0x80) ? A | ~0xff : A & 0xff;}
|
||||
#define NZFLAG_16(A) (((A)&0x7f) | (((A)>>1)&0x40) | (((A)>>8)&0xff))
|
||||
#define CFLAG_16(A) ((A)>>8)
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= MAME ================================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#define spc700_read_8(addr) memory_read_byte_8le(cpustate->program,addr)
|
||||
#define spc700_write_8(addr,data) memory_write_byte_8le(cpustate->program,addr,data)
|
||||
|
||||
#define spc700_read_8_direct(A) spc700_read_8(A)
|
||||
#define spc700_write_8_direct(A, V) spc700_write_8(A, V)
|
||||
//#define spc700_read_instruction(A) memory_decrypted_read_byte(cpustate->program,A)
|
||||
//#define spc700_read_8_immediate(A) memory_raw_read_byte(cpustate->program,A)
|
||||
#define spc700_read_instruction(A) memory_read_byte_8le(cpustate->program,A)
|
||||
#define spc700_read_8_immediate(A) memory_read_byte_8le(cpustate->program,A)
|
||||
#define spc700_jumping(A)
|
||||
#define spc700_branching(A)
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================= INTERFACE API ============================ */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* This is the interface, not the implementation. Please call the */
|
||||
/* implementation APIs below. */
|
||||
|
||||
|
||||
CPU_INIT( spc700 );
|
||||
|
||||
/* Pulse the RESET pin on the CPU */
|
||||
CPU_RESET( spc700 );
|
||||
|
||||
/* Set the RESET line on the CPU */
|
||||
void spc700_set_reset_line(spc700i_cpu *cpustate, int state, void* param);
|
||||
|
||||
/* Clean up after the emulation core - Not used in this core - */
|
||||
CPU_EXIT( spc700 );
|
||||
|
||||
/* Get the current Program Counter */
|
||||
unsigned spc700_get_pc(spc700i_cpu *cpustate);
|
||||
|
||||
/* Set the current Program Counter */
|
||||
void spc700_set_pc(spc700i_cpu *cpustate,unsigned val);
|
||||
|
||||
/* Get the current Stack Pointer */
|
||||
unsigned spc700_get_sp(spc700i_cpu *cpustate);
|
||||
|
||||
/* Set the current Stack Pointer */
|
||||
void spc700_set_sp(spc700i_cpu *cpustate,unsigned val);
|
||||
|
||||
/* Get a register from the core */
|
||||
unsigned spc700_get_reg(spc700i_cpu *cpustate,int regnum);
|
||||
|
||||
/* Set a register in the core */
|
||||
void spc700_set_reg(spc700i_cpu *cpustate,int regnum, unsigned val);
|
||||
|
||||
/* Note about NMI:
|
||||
* NMI is a one-shot trigger. In order to trigger NMI again, you must
|
||||
* clear NMI and then assert it again.
|
||||
*/
|
||||
void spc700_set_nmi_line(spc700i_cpu *cpustate,int state);
|
||||
|
||||
/* Assert or clear the IRQ pin */
|
||||
void spc700_set_irq_line(spc700i_cpu *cpustate,int line, int state);
|
||||
|
||||
/* Set the callback that will be called when an interrupt is serviced */
|
||||
void spc700_set_irq_callback(spc700i_cpu *cpustate,cpu_irq_callback callback);
|
||||
|
||||
/* Get a formatted string representing a register and its contents */
|
||||
const char *spc700_info(spc700i_cpu *cpustate,void *context, int regnum);
|
||||
|
||||
|
||||
/* Pulse the SO (Set Overflow) pin on the CPU */
|
||||
void spc700_pulse_so(spc700i_cpu *cpustate);
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================ UTILITY MACROS ============================ */
|
||||
/* ======================================================================== */
|
||||
|
@ -3,6 +3,11 @@
|
||||
#ifndef __SPC700_H__
|
||||
#define __SPC700_H__
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
extern CPU_GET_INFO( spc700 );
|
||||
#define CPU_SPC700 CPU_GET_INFO_NAME( spc700 )
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================= Configuration ============================ */
|
||||
/* ======================================================================== */
|
||||
@ -31,142 +36,6 @@ enum
|
||||
#define SPC700_INT_IRQ 1
|
||||
#define SPC700_INT_NMI 2
|
||||
|
||||
/* CPU Structure */
|
||||
typedef struct
|
||||
{
|
||||
uint a; /* Accumulator */
|
||||
uint x; /* Index Register X */
|
||||
uint y; /* Index Register Y */
|
||||
uint s; /* Stack Pointer */
|
||||
uint pc; /* Program Counter */
|
||||
uint ppc; /* Previous Program Counter */
|
||||
uint flag_n; /* Negative Flag */
|
||||
uint flag_z; /* Zero flag */
|
||||
uint flag_v; /* Overflow Flag */
|
||||
uint flag_p; /* Direct Page Flag */
|
||||
uint flag_b; /* BRK Instruction Flag */
|
||||
uint flag_h; /* Half-carry Flag */
|
||||
uint flag_i; /* Interrupt Mask Flag */
|
||||
uint flag_c; /* Carry Flag */
|
||||
uint line_irq; /* Status of the IRQ line */
|
||||
uint line_nmi; /* Status of the NMI line */
|
||||
uint line_rst; /* Status of the RESET line */
|
||||
uint ir; /* Instruction Register */
|
||||
cpu_irq_callback int_ack;
|
||||
const device_config *device;
|
||||
const address_space *program;
|
||||
uint stopped; /* stopped status */
|
||||
int ICount;
|
||||
uint source;
|
||||
uint destination;
|
||||
uint temp1, temp2, temp3;
|
||||
short spc_int16;
|
||||
int spc_int32;
|
||||
} spc700i_cpu;
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================= INTERFACE API ============================ */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* This is the interface, not the implementation. Please call the */
|
||||
/* implementation APIs below. */
|
||||
|
||||
|
||||
CPU_INIT( spc700 );
|
||||
|
||||
/* Pulse the RESET pin on the CPU */
|
||||
CPU_RESET( spc700 );
|
||||
|
||||
/* Set the RESET line on the CPU */
|
||||
void spc700_set_reset_line(spc700i_cpu *cpustate, int state, void* param);
|
||||
|
||||
/* Clean up after the emulation core - Not used in this core - */
|
||||
CPU_EXIT( spc700 );
|
||||
|
||||
/* Get the current Program Counter */
|
||||
unsigned spc700_get_pc(spc700i_cpu *cpustate);
|
||||
|
||||
/* Set the current Program Counter */
|
||||
void spc700_set_pc(spc700i_cpu *cpustate,unsigned val);
|
||||
|
||||
/* Get the current Stack Pointer */
|
||||
unsigned spc700_get_sp(spc700i_cpu *cpustate);
|
||||
|
||||
/* Set the current Stack Pointer */
|
||||
void spc700_set_sp(spc700i_cpu *cpustate,unsigned val);
|
||||
|
||||
/* Get a register from the core */
|
||||
unsigned spc700_get_reg(spc700i_cpu *cpustate,int regnum);
|
||||
|
||||
/* Set a register in the core */
|
||||
void spc700_set_reg(spc700i_cpu *cpustate,int regnum, unsigned val);
|
||||
|
||||
/* Note about NMI:
|
||||
* NMI is a one-shot trigger. In order to trigger NMI again, you must
|
||||
* clear NMI and then assert it again.
|
||||
*/
|
||||
void spc700_set_nmi_line(spc700i_cpu *cpustate,int state);
|
||||
|
||||
/* Assert or clear the IRQ pin */
|
||||
void spc700_set_irq_line(spc700i_cpu *cpustate,int line, int state);
|
||||
|
||||
/* Set the callback that will be called when an interrupt is serviced */
|
||||
void spc700_set_irq_callback(spc700i_cpu *cpustate,cpu_irq_callback callback);
|
||||
|
||||
/* Get a formatted string representing a register and its contents */
|
||||
const char *spc700_info(spc700i_cpu *cpustate,void *context, int regnum);
|
||||
|
||||
|
||||
/* Pulse the SO (Set Overflow) pin on the CPU */
|
||||
void spc700_pulse_so(spc700i_cpu *cpustate);
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* =================== Functions Implemented by the Host ================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
/* Read data from RAM */
|
||||
unsigned int spc700_read_8(unsigned int address);
|
||||
|
||||
/* Read data from the direct page */
|
||||
unsigned int spc700_read_8_direct(unsigned int address);
|
||||
|
||||
/* Read data from ROM */
|
||||
unsigned int spc700_read_8_immediate(unsigned int address);
|
||||
unsigned int spc700_read_8_instruction(unsigned int address);
|
||||
|
||||
/* Write data to RAM */
|
||||
void spc700_write_8(unsigned int address, unsigned int value);
|
||||
void spc700_write_8_direct(unsigned int address, unsigned int value);
|
||||
|
||||
void spc700_jumping(unsigned int new_pc);
|
||||
void spc700_branching(unsigned int new_pc);
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ================================= MAME ================================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#include "cpuintrf.h"
|
||||
|
||||
extern CPU_GET_INFO( spc700 );
|
||||
#define CPU_SPC700 CPU_GET_INFO_NAME( spc700 )
|
||||
|
||||
#define spc700_read_8(addr) memory_read_byte_8le(cpustate->program,addr)
|
||||
#define spc700_write_8(addr,data) memory_write_byte_8le(cpustate->program,addr,data)
|
||||
|
||||
#define spc700_read_8_direct(A) spc700_read_8(A)
|
||||
#define spc700_write_8_direct(A, V) spc700_write_8(A, V)
|
||||
//#define spc700_read_instruction(A) memory_decrypted_read_byte(cpustate->program,A)
|
||||
//#define spc700_read_8_immediate(A) memory_raw_read_byte(cpustate->program,A)
|
||||
#define spc700_read_instruction(A) memory_read_byte_8le(cpustate->program,A)
|
||||
#define spc700_read_8_immediate(A) memory_read_byte_8le(cpustate->program,A)
|
||||
#define spc700_jumping(A)
|
||||
#define spc700_branching(A)
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
|
@ -57,7 +57,6 @@ struct _t11_state
|
||||
#define PSW psw.b.l
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Low-level memory operations
|
||||
@ -74,25 +73,25 @@ INLINE int ROPCODE(t11_state *cpustate)
|
||||
|
||||
INLINE int RBYTE(t11_state *cpustate, int addr)
|
||||
{
|
||||
return T11_RDMEM(cpustate, addr);
|
||||
return memory_read_byte_16le(cpustate->program, addr);
|
||||
}
|
||||
|
||||
|
||||
INLINE void WBYTE(t11_state *cpustate, int addr, int data)
|
||||
{
|
||||
T11_WRMEM(cpustate, addr, data);
|
||||
memory_write_byte_16le(cpustate->program, addr, data);
|
||||
}
|
||||
|
||||
|
||||
INLINE int RWORD(t11_state *cpustate, int addr)
|
||||
{
|
||||
return T11_RDMEM_WORD(cpustate, addr & 0xfffe);
|
||||
return memory_read_word_16le(cpustate->program, addr & 0xfffe);
|
||||
}
|
||||
|
||||
|
||||
INLINE void WWORD(t11_state *cpustate, int addr, int data)
|
||||
{
|
||||
T11_WRMEM_WORD(cpustate, addr & 0xfffe, data);
|
||||
memory_write_word_16le(cpustate->program, addr & 0xfffe, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,18 +36,6 @@ struct t11_setup
|
||||
extern CPU_GET_INFO( t11 );
|
||||
#define CPU_T11 CPU_GET_INFO_NAME( t11 )
|
||||
|
||||
/****************************************************************************/
|
||||
/* Read a byte from given memory location */
|
||||
/****************************************************************************/
|
||||
#define T11_RDMEM(T,A) ((unsigned)memory_read_byte_16le((T)->program, A))
|
||||
#define T11_RDMEM_WORD(T,A) ((unsigned)memory_read_word_16le((T)->program, A))
|
||||
|
||||
/****************************************************************************/
|
||||
/* Write a byte to given memory location */
|
||||
/****************************************************************************/
|
||||
#define T11_WRMEM(T,A,V) (memory_write_byte_16le((T)->program, A,V))
|
||||
#define T11_WRMEM_WORD(T,A,V) (memory_write_word_16le((T)->program, A,V))
|
||||
|
||||
CPU_DISASSEMBLE( t11 );
|
||||
|
||||
#endif /* __T11_H__ */
|
||||
|
@ -138,6 +138,75 @@ struct _tms32010_opcode_7F
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read the state of the BIO pin
|
||||
*/
|
||||
|
||||
#define TMS32010_BIO_In (memory_read_word_16be(cpustate->io, TMS32010_BIO<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Input a word from given I/O port
|
||||
*/
|
||||
|
||||
#define TMS32010_In(Port) (memory_read_word_16be(cpustate->io, (Port)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Output a word to given I/O port
|
||||
*/
|
||||
|
||||
#define TMS32010_Out(Port,Value) (memory_write_word_16be(cpustate->io, (Port)<<1,Value))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read a word from given ROM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_ROM_RDMEM(A) (memory_read_word_16be(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write a word to given ROM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_ROM_WRMEM(A,V) (memory_write_word_16be(cpustate->program, (A)<<1,V))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read a word from given RAM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_RAM_RDMEM(A) (memory_read_word_16be(cpustate->data, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write a word to given RAM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_RAM_WRMEM(A,V) (memory_write_word_16be(cpustate->data, (A)<<1,V))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* TMS32010_RDOP() is identical to TMS32010_RDMEM() except it is used for reading
|
||||
* opcodes. In case of system with memory mapped I/O, this function can be
|
||||
* used to greatly speed up emulation
|
||||
*/
|
||||
|
||||
#define TMS32010_RDOP(A) (memory_decrypted_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* TMS32010_RDOP_ARG() is identical to TMS32010_RDOP() except it is used
|
||||
* for reading opcode arguments. This difference can be used to support systems
|
||||
* that use different encoding mechanisms for opcodes and opcode arguments
|
||||
*/
|
||||
|
||||
#define TMS32010_RDOP_ARG(A) (memory_raw_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Shortcuts
|
||||
|
@ -55,78 +55,6 @@ CPU_GET_INFO( tms32010 );
|
||||
#define CPU_TMS32010 CPU_GET_INFO_NAME( tms32010 )
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read the state of the BIO pin
|
||||
*/
|
||||
|
||||
#define TMS32010_BIO_In (memory_read_word_16be(cpustate->io, TMS32010_BIO<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Input a word from given I/O port
|
||||
*/
|
||||
|
||||
#define TMS32010_In(Port) (memory_read_word_16be(cpustate->io, (Port)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Output a word to given I/O port
|
||||
*/
|
||||
|
||||
#define TMS32010_Out(Port,Value) (memory_write_word_16be(cpustate->io, (Port)<<1,Value))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read a word from given ROM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_ROM_RDMEM(A) (memory_read_word_16be(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write a word to given ROM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_ROM_WRMEM(A,V) (memory_write_word_16be(cpustate->program, (A)<<1,V))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Read a word from given RAM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_RAM_RDMEM(A) (memory_read_word_16be(cpustate->data, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Write a word to given RAM memory location
|
||||
*/
|
||||
|
||||
#define TMS32010_RAM_WRMEM(A,V) (memory_write_word_16be(cpustate->data, (A)<<1,V))
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* TMS32010_RDOP() is identical to TMS32010_RDMEM() except it is used for reading
|
||||
* opcodes. In case of system with memory mapped I/O, this function can be
|
||||
* used to greatly speed up emulation
|
||||
*/
|
||||
|
||||
#define TMS32010_RDOP(A) (memory_decrypted_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* TMS32010_RDOP_ARG() is identical to TMS32010_RDOP() except it is used
|
||||
* for reading opcode arguments. This difference can be used to support systems
|
||||
* that use different encoding mechanisms for opcodes and opcode arguments
|
||||
*/
|
||||
|
||||
#define TMS32010_RDOP_ARG(A) (memory_raw_read_word(cpustate->program, (A)<<1))
|
||||
|
||||
|
||||
|
||||
CPU_DISASSEMBLE( tms32010 );
|
||||
|
||||
#endif /* __TMS32010_H__ */
|
||||
|
@ -50,7 +50,7 @@ typedef UINT16 WORD;
|
||||
typedef UINT32 DWORD;
|
||||
|
||||
#include "v30mz.h"
|
||||
#include "necintrf.h"
|
||||
#include "nec.h"
|
||||
|
||||
extern int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom);
|
||||
|
||||
|
@ -79,7 +79,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "streams.h"
|
||||
#include "cpu/i86/i186intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "leland.h"
|
||||
#include "sound/custom.h"
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i186intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "machine/eeprom.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "leland.h"
|
||||
|
@ -22,8 +22,8 @@ TODO:
|
||||
*************************************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/i86/i186intf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "fashion.lh"
|
||||
|
||||
static UINT16 *blit_ram;
|
||||
|
@ -40,7 +40,6 @@ In test mode (c) is 2000
|
||||
*************************************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
|
||||
#define xxxx 0x90 /* Unknown */
|
||||
|
@ -57,7 +57,7 @@
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
|
||||
static VIDEO_START(comebaby)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ Dip locations and factory settings verified with US manual
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "deprecat.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "sound/2203intf.h"
|
||||
|
@ -63,7 +63,7 @@ Also, implemented conditional port for Coin Mode (SW1:1)
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "sound/3812intf.h"
|
||||
|
@ -45,9 +45,9 @@ Year + Game Main CPU Sound CPU Sound Video
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/i86/i88intf.h"
|
||||
#include "cpu/i86/i86intf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "sound/2151intf.h"
|
||||
#include "sound/3812intf.h"
|
||||
#include "sound/dac.h"
|
||||
|
@ -64,7 +64,7 @@ AH
|
||||
******************************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i88intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "video/generic.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/8255ppi.h"
|
||||
|
@ -60,7 +60,7 @@
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
#include "memconv.h"
|
||||
#include "devconv.h"
|
||||
#include "deprecat.h"
|
||||
@ -73,7 +73,6 @@
|
||||
#include "machine/8042kbdc.h"
|
||||
#include "machine/pckeybrd.h"
|
||||
#include "machine/idectrl.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
|
||||
static void ide_interrupt(const device_config *device, int state);
|
||||
|
||||
|
@ -52,7 +52,7 @@ Notes:
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "deprecat.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "sound/3812intf.h"
|
||||
|
@ -177,7 +177,7 @@ VBlank duration: 1/VSYNC * (16/256) = 1017.6 us
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i88intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "machine/6532riot.h"
|
||||
#include "machine/laserdsc.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
@ -46,7 +46,7 @@ Notes:
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
|
||||
static UINT16 *unkram;
|
||||
static UINT16 *mainram;
|
||||
|
@ -459,7 +459,7 @@ or Fatal Fury for example).
|
||||
#define MASTER_CLOCK 50000000
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "deprecat.h"
|
||||
#include "cpu/mips/mips3.h"
|
||||
|
||||
|
@ -42,7 +42,7 @@ so it could be by them instead
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i88intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
static UINT8 *hotblock_ram;
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i186intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "machine/eeprom.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "leland.h"
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "sound/2203intf.h"
|
||||
#include "sound/flt_vol.h"
|
||||
#include "lockon.h"
|
||||
|
@ -24,13 +24,12 @@ confirmed for m107 games as well.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "m107.h"
|
||||
#include "iremipt.h"
|
||||
#include "machine/irem_cpu.h"
|
||||
#include "sound/2151intf.h"
|
||||
#include "sound/iremga20.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
|
||||
|
||||
#define M107_IRQ_0 ((m107_irq_vectorbase+0)/4) /* VBL interrupt*/
|
||||
|
@ -82,7 +82,7 @@ other supported games as well.
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "deprecat.h"
|
||||
#include "machine/irem_cpu.h"
|
||||
#include "audio/m72.h"
|
||||
@ -90,7 +90,6 @@ other supported games as well.
|
||||
#include "sound/2151intf.h"
|
||||
#include "iremipt.h"
|
||||
#include "m72.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
|
||||
#define MASTER_CLOCK XTAL_32MHz
|
||||
|
@ -26,14 +26,13 @@ Notes:
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "deprecat.h"
|
||||
#include "iremipt.h"
|
||||
#include "machine/irem_cpu.h"
|
||||
#include "audio/m72.h"
|
||||
#include "sound/dac.h"
|
||||
#include "sound/2151intf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
|
||||
static UINT32 bankaddress;
|
||||
|
||||
|
@ -194,13 +194,12 @@ psoldier dip locations still need veritication.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "m92.h"
|
||||
#include "iremipt.h"
|
||||
#include "machine/irem_cpu.h"
|
||||
#include "sound/2151intf.h"
|
||||
#include "sound/iremga20.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
|
||||
static UINT8 irqvector;
|
||||
static UINT16 sound_status;
|
||||
|
@ -64,7 +64,7 @@
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
#include "devconv.h"
|
||||
#include "deprecat.h"
|
||||
#include "machine/8237dma.h"
|
||||
@ -76,7 +76,6 @@
|
||||
#include "machine/8042kbdc.h"
|
||||
#include "machine/pckeybrd.h"
|
||||
#include "machine/idectrl.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
#include "sound/dmadac.h"
|
||||
|
||||
#define SPEEDUP_HACKS 1
|
||||
|
@ -90,7 +90,7 @@ Arcade Version (Coin-Op) by InfoCube (Pisa, Italy)
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
|
||||
static VIDEO_START(pangofun)
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ D.9B [f99cac4b] /
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "deprecat.h"
|
||||
#include "audio/t5182.h"
|
||||
|
||||
|
@ -17,7 +17,7 @@ ROMs epia BIOS + solid state HD
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
|
||||
VIDEO_START(queen)
|
||||
{
|
||||
|
@ -36,7 +36,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "sound/3812intf.h"
|
||||
|
@ -136,7 +136,7 @@ Current Problem(s) - in order of priority
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "machine/eeprom.h"
|
||||
|
@ -294,7 +294,7 @@ Stadium Cross EPR15093 EPR15094 EPR15018 EPR15019 EPR15192 EPR15020 EPR150
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/v60/v60.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "rendlay.h"
|
||||
#include "segas32.h"
|
||||
#include "machine/eeprom.h"
|
||||
|
@ -670,7 +670,7 @@ Notes:
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
#include "machine/ds2404.h"
|
||||
#include "machine/eeprom.h"
|
||||
#include "machine/intelfsh.h"
|
||||
|
@ -52,7 +52,7 @@ RSSENGO2.72 chr.
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "sound/3812intf.h"
|
||||
|
||||
|
@ -23,7 +23,7 @@ displayed.
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "audio/seibu.h"
|
||||
#include "video/hd63484.h"
|
||||
|
||||
|
@ -285,7 +285,7 @@ U145 1Brown PAL14H4CN
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i88intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "machine/8255ppi.h"
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i386/i386intf.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
#include "memconv.h"
|
||||
#include "devconv.h"
|
||||
#include "deprecat.h"
|
||||
@ -17,7 +17,6 @@
|
||||
#include "machine/8042kbdc.h"
|
||||
#include "machine/pckeybrd.h"
|
||||
#include "machine/idectrl.h"
|
||||
#include "cpu/i386/i386.h"
|
||||
|
||||
static void ide_interrupt(const device_config *device, int state);
|
||||
|
||||
|
@ -139,7 +139,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "tatsumi.h"
|
||||
#include "sound/2151intf.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i88intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
|
||||
static int crtindex;
|
||||
static int crtdata[256];
|
||||
|
@ -244,7 +244,7 @@ To Do / Unknowns:
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z180/z180.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/eeprom.h"
|
||||
|
@ -42,7 +42,7 @@ The PCB is Spanish and manufacured by Gamart.
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
|
||||
static UINT16 *peno_vram;
|
||||
|
||||
|
@ -49,7 +49,7 @@ Electronic Devices was printed on rom labels
|
||||
*/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/necintrf.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
static UINT16 *twins_videoram;
|
||||
|
@ -42,10 +42,9 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/i86/i86intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "sound/custom.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "rendlay.h"
|
||||
#include "tx1.h"
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "cpu/i86/i186intf.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "machine/eeprom.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "leland.h"
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "lockon.h"
|
||||
#include "video/resnet.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "video/resnet.h"
|
||||
|
||||
#define CURSOR_XPOS 168
|
||||
#define CURSOR_YPOS 239
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include "render.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "video/resnet.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "tx1.h"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user