mirror of
https://github.com/86Box/86Box.git
synced 2026-02-26 05:53:15 -07:00
LDS/LES/LFS/LGS/LSS: Fix segment wraparounds in 16-bit address mode.
This commit is contained in:
@@ -1054,6 +1054,13 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
|||||||
addbyte(0x83); /*ADD EAX, offset*/
|
addbyte(0x83); /*ADD EAX, offset*/
|
||||||
addbyte(0xc0);
|
addbyte(0xc0);
|
||||||
addbyte(offset);
|
addbyte(offset);
|
||||||
|
if (!(op_32 & 0x200)) {
|
||||||
|
addbyte(0x25) /* AND EAX, ffffh */
|
||||||
|
addbyte(0xff);
|
||||||
|
addbyte(0xff);
|
||||||
|
addbyte(0x00);
|
||||||
|
addbyte(0x00);
|
||||||
|
}
|
||||||
MEM_LOAD_ADDR_EA_W(seg);
|
MEM_LOAD_ADDR_EA_W(seg);
|
||||||
}
|
}
|
||||||
static __inline void
|
static __inline void
|
||||||
|
|||||||
@@ -802,6 +802,13 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
|||||||
addbyte(0x83); /*ADD EAX, offset*/
|
addbyte(0x83); /*ADD EAX, offset*/
|
||||||
addbyte(0xc0);
|
addbyte(0xc0);
|
||||||
addbyte(offset);
|
addbyte(offset);
|
||||||
|
if (!(op_32 & 0x200)) {
|
||||||
|
addbyte(0x25) /* AND EAX, ffffh */
|
||||||
|
addbyte(0xff);
|
||||||
|
addbyte(0xff);
|
||||||
|
addbyte(0x00);
|
||||||
|
addbyte(0x00);
|
||||||
|
}
|
||||||
addbyte(0xe8); /*CALL mem_load_addr_ea_w*/
|
addbyte(0xe8); /*CALL mem_load_addr_ea_w*/
|
||||||
addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4]));
|
addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4]));
|
||||||
|
|
||||||
|
|||||||
@@ -931,6 +931,8 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||||||
host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0);
|
host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0);
|
||||||
if (uop->imm_data)
|
if (uop->imm_data)
|
||||||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||||
|
if (uop->is_a16)
|
||||||
|
host_arm64_AND_IMM(block, REG_X0, REG_X0, 0xffff);
|
||||||
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) {
|
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) {
|
||||||
host_arm64_call(block, codegen_mem_load_byte);
|
host_arm64_call(block, codegen_mem_load_byte);
|
||||||
} else if (REG_IS_W(dest_size)) {
|
} else if (REG_IS_W(dest_size)) {
|
||||||
|
|||||||
@@ -995,6 +995,8 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||||
if (uop->imm_data)
|
if (uop->imm_data)
|
||||||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||||
|
if (uop->is_a16)
|
||||||
|
host_arm_AND_IMM(block, REG_R0, REG_R0, 0xffff);
|
||||||
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) {
|
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) {
|
||||||
host_arm_BL(block, (uintptr_t) codegen_mem_load_byte);
|
host_arm_BL(block, (uintptr_t) codegen_mem_load_byte);
|
||||||
} else if (REG_IS_W(dest_size)) {
|
} else if (REG_IS_W(dest_size)) {
|
||||||
|
|||||||
@@ -997,8 +997,13 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||||
|
|
||||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||||
if (uop->imm_data)
|
if (uop->imm_data) {
|
||||||
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
|
if (uop->is_a16) {
|
||||||
|
host_x86_ADD16_REG_IMM(block, REG_SI, uop->imm_data);
|
||||||
|
} else {
|
||||||
|
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (REG_IS_B(dest_size)) {
|
if (REG_IS_B(dest_size)) {
|
||||||
host_x86_CALL(block, codegen_mem_load_byte);
|
host_x86_CALL(block, codegen_mem_load_byte);
|
||||||
} else if (REG_IS_W(dest_size)) {
|
} else if (REG_IS_W(dest_size)) {
|
||||||
|
|||||||
@@ -981,8 +981,13 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||||
|
|
||||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||||
if (uop->imm_data)
|
if (uop->imm_data) {
|
||||||
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
|
if (uop->is_a16) {
|
||||||
|
host_x86_ADD16_REG_IMM(block, REG_SI, uop->imm_data);
|
||||||
|
} else {
|
||||||
|
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (REG_IS_B(dest_size)) {
|
if (REG_IS_B(dest_size)) {
|
||||||
host_x86_CALL(block, codegen_mem_load_byte);
|
host_x86_CALL(block, codegen_mem_load_byte);
|
||||||
} else if (REG_IS_W(dest_size)) {
|
} else if (REG_IS_W(dest_size)) {
|
||||||
|
|||||||
@@ -340,6 +340,7 @@ typedef struct uop_t {
|
|||||||
void *p;
|
void *p;
|
||||||
ir_host_reg_t dest_reg_a_real;
|
ir_host_reg_t dest_reg_a_real;
|
||||||
ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real;
|
ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real;
|
||||||
|
int is_a16;
|
||||||
int jump_dest_uop;
|
int jump_dest_uop;
|
||||||
int jump_list_next;
|
int jump_list_next;
|
||||||
void *jump_dest;
|
void *jump_dest;
|
||||||
@@ -364,6 +365,8 @@ uop_alloc(ir_data_t *ir, uint32_t uop_type)
|
|||||||
|
|
||||||
uop = &ir->uops[ir->wr_pos++];
|
uop = &ir->uops[ir->wr_pos++];
|
||||||
|
|
||||||
|
uop->is_a16 = 0;
|
||||||
|
|
||||||
uop->dest_reg_a = invalid_ir_reg;
|
uop->dest_reg_a = invalid_ir_reg;
|
||||||
uop->src_reg_a = invalid_ir_reg;
|
uop->src_reg_a = invalid_ir_reg;
|
||||||
uop->src_reg_b = invalid_ir_reg;
|
uop->src_reg_b = invalid_ir_reg;
|
||||||
@@ -489,7 +492,12 @@ uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src
|
|||||||
|
|
||||||
uop->type = uop_type;
|
uop->type = uop_type;
|
||||||
uop->src_reg_a = codegen_reg_read(src_reg_a);
|
uop->src_reg_a = codegen_reg_read(src_reg_a);
|
||||||
uop->src_reg_b = codegen_reg_read(src_reg_b);
|
uop->is_a16 = 0;
|
||||||
|
if (src_reg_b == IREG_eaa16) {
|
||||||
|
uop->src_reg_b = codegen_reg_read(IREG_eaaddr);
|
||||||
|
uop->is_a16 = 1;
|
||||||
|
} else
|
||||||
|
uop->src_reg_b = codegen_reg_read(src_reg_b);
|
||||||
uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1);
|
uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1);
|
||||||
uop->imm_data = imm;
|
uop->imm_data = imm;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -533,8 +533,8 @@ ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSE
|
|||||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
|
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
|
||||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \
|
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \
|
||||||
codegen_check_seg_read(block, ir, target_seg); \
|
codegen_check_seg_read(block, ir, target_seg); \
|
||||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \
|
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16); \
|
||||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \
|
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 2); \
|
||||||
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
|
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
|
||||||
uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \
|
uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \
|
||||||
\
|
\
|
||||||
@@ -556,8 +556,8 @@ ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSE
|
|||||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
|
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
|
||||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \
|
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \
|
||||||
codegen_check_seg_read(block, ir, target_seg); \
|
codegen_check_seg_read(block, ir, target_seg); \
|
||||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \
|
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16); \
|
||||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \
|
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 4); \
|
||||||
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
|
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
|
||||||
uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \
|
uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \
|
||||||
\
|
\
|
||||||
|
|||||||
@@ -169,6 +169,8 @@ struct
|
|||||||
[IREG_GS_limit_high] = { REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT},
|
[IREG_GS_limit_high] = { REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT},
|
||||||
[IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT},
|
[IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT},
|
||||||
|
|
||||||
|
[IREG_eaa16] = { REG_WORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT},
|
||||||
|
|
||||||
/*Temporary registers are stored on the stack, and are not guaranteed to
|
/*Temporary registers are stored on the stack, and are not guaranteed to
|
||||||
be preserved across uOPs. They will not be written back if they will
|
be preserved across uOPs. They will not be written back if they will
|
||||||
not be read again.*/
|
not be read again.*/
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ enum {
|
|||||||
IREG_GS_limit_high = 86,
|
IREG_GS_limit_high = 86,
|
||||||
IREG_SS_limit_high = 87,
|
IREG_SS_limit_high = 87,
|
||||||
|
|
||||||
IREG_COUNT = 88,
|
IREG_eaa16 = 88,
|
||||||
|
|
||||||
|
IREG_COUNT = 89,
|
||||||
|
|
||||||
IREG_INVALID = 255,
|
IREG_INVALID = 255,
|
||||||
|
|
||||||
|
|||||||
@@ -248,6 +248,19 @@ int checkio(uint32_t port, int mask);
|
|||||||
return 1; \
|
return 1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK_READ_2OP(chseg, low, high, low2, high2) \
|
||||||
|
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || (low2 < (chseg)->limit_low) || (high2 > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) { \
|
||||||
|
x86gpf("Limit check (READ)", 0); \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
|
||||||
|
if ((chseg) == &cpu_state.seg_ss) \
|
||||||
|
x86ss(NULL, (chseg)->seg & 0xfffc); \
|
||||||
|
else \
|
||||||
|
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
|
||||||
#define CHECK_READ_REP(chseg, low, high) \
|
#define CHECK_READ_REP(chseg, low, high) \
|
||||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
|
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
|
||||||
x86gpf("Limit check (READ)", 0); \
|
x86gpf("Limit check (READ)", 0); \
|
||||||
@@ -277,6 +290,19 @@ int checkio(uint32_t port, int mask);
|
|||||||
#define CHECK_WRITE(chseg, low, high) \
|
#define CHECK_WRITE(chseg, low, high) \
|
||||||
CHECK_WRITE_COMMON(chseg, low, high)
|
CHECK_WRITE_COMMON(chseg, low, high)
|
||||||
|
|
||||||
|
#define CHECK_WRITE_2OP(chseg, low, high, low2, high2) \
|
||||||
|
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || (low2 < (chseg)->limit_low) || (high2 > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \
|
||||||
|
x86gpf("Limit check (WRITE)", 0); \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
|
||||||
|
if ((chseg) == &cpu_state.seg_ss) \
|
||||||
|
x86ss(NULL, (chseg)->seg & 0xfffc); \
|
||||||
|
else \
|
||||||
|
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
|
||||||
#define CHECK_WRITE_REP(chseg, low, high) \
|
#define CHECK_WRITE_REP(chseg, low, high) \
|
||||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
|
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
|
||||||
x86gpf("Limit check (WRITE REP)", 0); \
|
x86gpf("Limit check (WRITE REP)", 0); \
|
||||||
|
|||||||
@@ -335,7 +335,10 @@ typedef struct {
|
|||||||
uint8_t tag[8];
|
uint8_t tag[8];
|
||||||
|
|
||||||
x86seg *ea_seg;
|
x86seg *ea_seg;
|
||||||
uint32_t eaaddr;
|
union {
|
||||||
|
uint32_t eaaddr;
|
||||||
|
uint16_t eaa16[2];
|
||||||
|
};
|
||||||
|
|
||||||
int flags_op;
|
int flags_op;
|
||||||
uint32_t flags_res;
|
uint32_t flags_res;
|
||||||
|
|||||||
@@ -272,9 +272,10 @@ opLDS_w_a16(uint32_t fetchdat)
|
|||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
ILLEGAL_ON(cpu_mod == 3);
|
ILLEGAL_ON(cpu_mod == 3);
|
||||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 1,
|
||||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
((cpu_state.eaa16[0] + 2) & 0xffff), ((cpu_state.eaa16[0] + 2) & 0xffff) + 1);
|
||||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
addr = readmemw(easeg, cpu_state.eaa16[0]);
|
||||||
|
seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff);
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
return 1;
|
return 1;
|
||||||
op_loadseg(seg, &cpu_state.seg_ds);
|
op_loadseg(seg, &cpu_state.seg_ds);
|
||||||
@@ -318,9 +319,10 @@ opLDS_l_a16(uint32_t fetchdat)
|
|||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
ILLEGAL_ON(cpu_mod == 3);
|
ILLEGAL_ON(cpu_mod == 3);
|
||||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 3,
|
||||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
((cpu_state.eaa16[0] + 4) & 0xffff), ((cpu_state.eaa16[0] + 4) & 0xffff) + 1);
|
||||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
addr = readmeml(easeg, cpu_state.eaa16[0]);
|
||||||
|
seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff);
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
return 1;
|
return 1;
|
||||||
op_loadseg(seg, &cpu_state.seg_ds);
|
op_loadseg(seg, &cpu_state.seg_ds);
|
||||||
@@ -365,9 +367,10 @@ opLSS_w_a16(uint32_t fetchdat)
|
|||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
ILLEGAL_ON(cpu_mod == 3);
|
ILLEGAL_ON(cpu_mod == 3);
|
||||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 1,
|
||||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
((cpu_state.eaa16[0] + 2) & 0xffff), ((cpu_state.eaa16[0] + 2) & 0xffff) + 1);
|
||||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
addr = readmemw(easeg, cpu_state.eaa16[0]);
|
||||||
|
seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff);
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
return 1;
|
return 1;
|
||||||
op_loadseg(seg, &cpu_state.seg_ss);
|
op_loadseg(seg, &cpu_state.seg_ss);
|
||||||
@@ -411,9 +414,11 @@ opLSS_l_a16(uint32_t fetchdat)
|
|||||||
fetch_ea_16(fetchdat);
|
fetch_ea_16(fetchdat);
|
||||||
ILLEGAL_ON(cpu_mod == 3);
|
ILLEGAL_ON(cpu_mod == 3);
|
||||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 3,
|
||||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
((cpu_state.eaa16[0] + 4) & 0xffff), ((cpu_state.eaa16[0] + 4) & 0xffff) + 1);
|
||||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 5) & 0xffff));
|
||||||
|
addr = readmeml(easeg, cpu_state.eaa16[0]);
|
||||||
|
seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff);
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
return 1;
|
return 1;
|
||||||
op_loadseg(seg, &cpu_state.seg_ss);
|
op_loadseg(seg, &cpu_state.seg_ss);
|
||||||
@@ -457,9 +462,9 @@ opLSS_l_a32(uint32_t fetchdat)
|
|||||||
fetch_ea_16(fetchdat); \
|
fetch_ea_16(fetchdat); \
|
||||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||||
ILLEGAL_ON(cpu_mod == 3); \
|
ILLEGAL_ON(cpu_mod == 3); \
|
||||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 1, ((cpu_state.eaa16[0] + 2) & 0xffff), ((cpu_state.eaa16[0] + 2) & 0xffff) + 1); \
|
||||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
addr = readmemw(easeg, cpu_state.eaa16[0]); \
|
||||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
|
seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff); \
|
||||||
if (cpu_state.abrt) \
|
if (cpu_state.abrt) \
|
||||||
return 1; \
|
return 1; \
|
||||||
op_loadseg(seg, &sel); \
|
op_loadseg(seg, &sel); \
|
||||||
@@ -502,9 +507,9 @@ opLSS_l_a32(uint32_t fetchdat)
|
|||||||
fetch_ea_16(fetchdat); \
|
fetch_ea_16(fetchdat); \
|
||||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||||
ILLEGAL_ON(cpu_mod == 3); \
|
ILLEGAL_ON(cpu_mod == 3); \
|
||||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
|
CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 3, ((cpu_state.eaa16[0] + 4) & 0xffff), ((cpu_state.eaa16[0] + 4) & 0xffff) + 1); \
|
||||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
addr = readmeml(easeg, cpu_state.eaa16[0]); \
|
||||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
|
seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff); \
|
||||||
if (cpu_state.abrt) \
|
if (cpu_state.abrt) \
|
||||||
return 1; \
|
return 1; \
|
||||||
op_loadseg(seg, &sel); \
|
op_loadseg(seg, &sel); \
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
op_loadcs(readmemw(ss, ESP + 2)); \
|
op_loadcs(readmemw(ss, ESP + 2)); \
|
||||||
} else { \
|
} else { \
|
||||||
cpu_state.pc = readmemw(ss, SP); \
|
cpu_state.pc = readmemw(ss, SP); \
|
||||||
op_loadcs(readmemw(ss, SP + 2)); \
|
op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \
|
||||||
} \
|
} \
|
||||||
if (cpu_state.abrt) \
|
if (cpu_state.abrt) \
|
||||||
return 1; \
|
return 1; \
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
op_loadcs(readmemw(ss, ESP + 2)); \
|
op_loadcs(readmemw(ss, ESP + 2)); \
|
||||||
} else { \
|
} else { \
|
||||||
cpu_state.pc = readmemw(ss, SP); \
|
cpu_state.pc = readmemw(ss, SP); \
|
||||||
op_loadcs(readmemw(ss, SP + 2)); \
|
op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \
|
||||||
} \
|
} \
|
||||||
if (cpu_state.abrt) \
|
if (cpu_state.abrt) \
|
||||||
return 1; \
|
return 1; \
|
||||||
|
|||||||
Reference in New Issue
Block a user