Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-04-09 13:39:45 +01:00
committed by GitHub
29 changed files with 189 additions and 89 deletions

View File

@@ -375,7 +375,7 @@ sis_85c4xx_init(const device_t *info)
dev->reg_base = info->local & 0xff;
if (dev->is_471) {
dev->reg_last = dev->reg_base + 0x76;
dev->reg_last = 0x76;
dev->smram = smram_add();

View File

@@ -600,12 +600,12 @@ ropMOV_seg_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t
MEM_LOAD_ADDR_EA_L(target_seg); \
STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, 0); \
LOAD_EA(); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4, op_32); \
} else { \
MEM_LOAD_ADDR_EA_W(target_seg); \
STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, 0); \
LOAD_EA(); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2, op_32); \
} \
LOAD_SEG(0, &rseg); \
if (op_32 & 0x100) { \

View File

@@ -1049,11 +1049,18 @@ MEM_LOAD_ADDR_EA_W(x86seg *seg)
/*done:*/
}
static __inline void
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset, int op_32)
{
addbyte(0x83); /*ADD EAX, offset*/
addbyte(0xc0);
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);
}
static __inline void

View File

@@ -789,7 +789,7 @@ MEM_LOAD_ADDR_EA_W(x86seg *seg)
host_reg_mapping[0] = 8;
}
static __inline void
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset, int op_32)
{
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) {
addbyte(0x31); /*XOR EDX, EDX*/
@@ -802,6 +802,13 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
addbyte(0x83); /*ADD EAX, offset*/
addbyte(0xc0);
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*/
addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4]));

View File

@@ -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);
if (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)) {
host_arm64_call(block, codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -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);
if (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)) {
host_arm_BL(block, (uintptr_t) codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -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);
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
if (uop->imm_data)
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
if (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)) {
host_x86_CALL(block, codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -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);
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
if (uop->imm_data)
host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data);
if (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)) {
host_x86_CALL(block, codegen_mem_load_byte);
} else if (REG_IS_W(dest_size)) {

View File

@@ -340,6 +340,7 @@ typedef struct uop_t {
void *p;
ir_host_reg_t dest_reg_a_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_list_next;
void *jump_dest;
@@ -364,6 +365,8 @@ uop_alloc(ir_data_t *ir, uint32_t uop_type)
uop = &ir->uops[ir->wr_pos++];
uop->is_a16 = 0;
uop->dest_reg_a = invalid_ir_reg;
uop->src_reg_a = 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->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->imm_data = imm;
}

View File

@@ -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); \
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); \
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \
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), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 2); \
uop_LOAD_SEG(ir, seg, IREG_temp1_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); \
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); \
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \
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), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 4); \
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \
\

View File

@@ -169,6 +169,8 @@ struct
[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_eaa16] = { REG_WORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT},
/*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
not be read again.*/

View File

@@ -132,7 +132,9 @@ enum {
IREG_GS_limit_high = 86,
IREG_SS_limit_high = 87,
IREG_COUNT = 88,
IREG_eaa16 = 88,
IREG_COUNT = 89,
IREG_INVALID = 255,

View File

@@ -1840,6 +1840,8 @@ config_load(void)
cassette_pcm = 0;
cassette_ui_writeprot = 0;
lang_id = DEFAULT_LANGUAGE;
config_log("Config file not present or invalid!\n");
} else {
load_general(); /* General */

View File

@@ -248,6 +248,19 @@ int checkio(uint32_t port, int mask);
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) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
x86gpf("Limit check (READ)", 0); \
@@ -277,6 +290,19 @@ int checkio(uint32_t port, int mask);
#define CHECK_WRITE(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) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
x86gpf("Limit check (WRITE REP)", 0); \

View File

@@ -335,7 +335,10 @@ typedef struct {
uint8_t tag[8];
x86seg *ea_seg;
uint32_t eaaddr;
union {
uint32_t eaaddr;
uint16_t eaa16[2];
};
int flags_op;
uint32_t flags_res;

View File

@@ -272,9 +272,10 @@ opLDS_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
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.eaa16[0]);
seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ds);
@@ -318,9 +319,10 @@ opLDS_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
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.eaa16[0]);
seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ds);
@@ -365,9 +367,10 @@ opLSS_w_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
addr = readmemw(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 2);
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.eaa16[0]);
seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff);
if (cpu_state.abrt)
return 1;
op_loadseg(seg, &cpu_state.seg_ss);
@@ -411,9 +414,11 @@ opLSS_l_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
ILLEGAL_ON(cpu_mod == 3);
SEG_CHECK_READ(cpu_state.ea_seg);
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
addr = readmeml(easeg, cpu_state.eaaddr);
seg = readmemw(easeg, cpu_state.eaaddr + 4);
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);
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)
return 1;
op_loadseg(seg, &cpu_state.seg_ss);
@@ -457,9 +462,9 @@ opLSS_l_a32(uint32_t fetchdat)
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
addr = readmemw(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
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.eaa16[0]); \
seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff); \
if (cpu_state.abrt) \
return 1; \
op_loadseg(seg, &sel); \
@@ -502,9 +507,9 @@ opLSS_l_a32(uint32_t fetchdat)
fetch_ea_16(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
ILLEGAL_ON(cpu_mod == 3); \
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
addr = readmeml(easeg, cpu_state.eaaddr); \
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
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.eaa16[0]); \
seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff); \
if (cpu_state.abrt) \
return 1; \
op_loadseg(seg, &sel); \

View File

@@ -15,7 +15,7 @@
op_loadcs(readmemw(ss, ESP + 2)); \
} else { \
cpu_state.pc = readmemw(ss, SP); \
op_loadcs(readmemw(ss, SP + 2)); \
op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \
} \
if (cpu_state.abrt) \
return 1; \

View File

@@ -15,7 +15,7 @@
op_loadcs(readmemw(ss, ESP + 2)); \
} else { \
cpu_state.pc = readmemw(ss, SP); \
op_loadcs(readmemw(ss, SP + 2)); \
op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \
} \
if (cpu_state.abrt) \
return 1; \

View File

@@ -1208,7 +1208,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide->tf->atastat = BSY_STAT;
if (ide->tf->pos >= dev->packet_len) {
ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
// ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
ide_log("%i bytes %s, command done, %i sectors left\n", ide->tf->pos, out ? "written" : "read",
dev->sector_len);
ide->tf->pos = dev->request_pos = 0;
@@ -1262,13 +1264,12 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide_atapi_callback(ide);
ide_set_callback(ide, 0.0);
} else {
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if (ide->phase_data_out != NULL)
(void) ide->phase_data_out(dev);
ide_atapi_callback(ide);
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
(ide->sc->callback == 0.0))
ide_atapi_callback(ide);
}
}
} else {
@@ -1280,10 +1281,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
if (ide->command_stop != NULL)
ide->command_stop(dev);
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
ide_atapi_callback(ide);
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
(ide->sc->callback == 0.0))
ide_atapi_callback(ide);
}
} else if (ide->read != NULL)
ide->read(dev);
@@ -1299,8 +1299,8 @@ ide_atapi_packet_read(ide_t *ide)
uint16_t ret = 0;
if (dev && dev->temp_buffer && (dev->packet_status == PHASE_DATA_IN)) {
ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n",
dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len);
/* ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n",
dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len); */
bufferw = (uint16_t *) dev->temp_buffer;
@@ -1722,7 +1722,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
break;
case 0x7: /* Command register */
if (ide->tf->atastat & (BSY_STAT | DRQ_STAT))
if ((ide->tf->atastat & (BSY_STAT | DRQ_STAT)) &&
((val != WIN_SRST) || (ide->type != IDE_ATAPI)))
break;
if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS)))
@@ -2158,7 +2159,8 @@ ide_read_alt_status(UNUSED(const uint16_t addr), void *priv)
if (!(addr & 0x0001))
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
// ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
// ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
return ret;
}
@@ -3159,6 +3161,13 @@ ide_init(const device_t *info)
ide_board_init(1, HDC_SECONDARY_IRQ, HDC_SECONDARY_BASE, HDC_SECONDARY_SIDE, info->local, info->flags);
break;
case 8 ... 0x0d:
ide_board_init(2, -1, 0, 0, info->local, info->flags);
if (info->local & 1)
ide_board_init(3, -1, 0, 0, info->local, info->flags);
break;
default:
break;
}
@@ -3540,7 +3549,7 @@ const device_t mcide_device = {
.name = "MCA McIDE Controller",
.internal_name = "ide_mcide",
.flags = DEVICE_MCA,
.local = 3,
.local = 1,
.init = mcide_init,
.close = mcide_close,
.reset = mcide_reset,
@@ -3661,3 +3670,17 @@ const device_t ide_qua_pnp_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t ide_pci_ter_qua_2ch_device = {
.name = "PCI IDE Controller (Dual-Channel Tertiary/Quaternary)",
.internal_name = "ide_pci_ter_qua_2ch",
.flags = DEVICE_PCI,
.local = 0x0d,
.init = ide_init,
.close = ide_close,
.reset = ide_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -584,7 +584,10 @@ mo_data_command_finish(mo_t *dev, int len, const int block_len,
mo_command_write_dma(dev);
} else {
mo_update_request_length(dev, len, block_len);
if (direction == 0)
if ((dev->drv->bus_type != MO_BUS_SCSI) &&
(dev->tf->request_length == 0))
mo_command_complete(dev);
else if (direction == 0)
mo_command_read(dev);
else
mo_command_write(dev);

View File

@@ -665,7 +665,10 @@ zip_data_command_finish(zip_t *dev, int len, const int block_len,
zip_command_write_dma(dev);
} else {
zip_update_request_length(dev, len, block_len);
if (direction == 0)
if ((dev->drv->bus_type != ZIP_BUS_SCSI) &&
(dev->tf->request_length == 0))
zip_command_complete(dev);
else if (direction == 0)
zip_command_read(dev);
else
zip_command_write(dev);

View File

@@ -45,7 +45,7 @@
#define MAX_UUID_LEN 64
/* Default language 0xFFFF = from system, 0x409 = en-US */
#define DEFAULT_LANGUAGE 0x0409
#define DEFAULT_LANGUAGE 0xffff
#define POSTCARDS_NUM 4
#define POSTCARD_MASK (POSTCARDS_NUM - 1)

View File

@@ -70,6 +70,7 @@ typedef struct scsi_cdrom_t {
int was_cached;
int toc_cached;
int media_access;
int sectors_num;
uint8_t vendor_type;
uint8_t ven_cmd_is_data[256];

View File

@@ -47,7 +47,7 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch)
machine_at_common_init_ex(model, 2);
device_add(&amstrad_megapc_nvr_device);
device_add(&ide_pci_device);
device_add(&ide_pci_2ch_device);
pci_init(PCI_CONFIG_TYPE_2 | pci_switch);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);

View File

@@ -674,7 +674,11 @@ MainWindow::MainWindow(QWidget *parent)
/* Remove default Shift+F10 handler, which unfocuses keyboard input even with no context menu. */
connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, [](){});
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
auto windowedShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_PageDown), this);
#else
auto windowedShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_PageDown), this);
#endif
windowedShortcut->setContext(Qt::ShortcutContext::ApplicationShortcut);
connect(windowedShortcut, &QShortcut::activated, this, [this] () {
if (video_fullscreen)

View File

@@ -680,8 +680,7 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev)
/* Seek time is in us. */
period = cdrom_seek_time(dev->drv);
scsi_cdrom_log(dev->log, "Seek period: %" PRIu64 " us\n",
(uint64_t) period);
scsi_cdrom_log(dev->log, "Seek period: %lf us\n", period);
dev->callback += period;
/* 44100 * 16 bits * 2 channels = 176400 bytes per second */
@@ -696,21 +695,17 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev)
}
period = 1000000.0 / bytes_per_second;
scsi_cdrom_log(dev->log, "Byte transfer period: %" PRIu64 " us\n",
(uint64_t) period);
scsi_cdrom_log(dev->log, "Byte transfer period: %lf us\n", period);
if (dev->was_cached == -1)
period *= (double) dev->packet_len;
else {
const int num = ((dev->drv->bus_type == CDROM_BUS_SCSI) ||
(dev->block_len == 0)) ?
dev->requested_blocks :
((scsi_cdrom_current_mode(dev) == 2) ? 1 :
(dev->packet_len / dev->block_len));
(dev->block_len == 0)) ? dev->sectors_num :
((scsi_cdrom_current_mode(dev) == 2) ? 1 : dev->sectors_num);
period *= ((double) num) * 2352.0;
}
scsi_cdrom_log(dev->log, "Sector transfer period: %" PRIu64 " us\n",
(uint64_t) period);
scsi_cdrom_log(dev->log, "Sector transfer period: %lf us\n", period);
dev->callback += period;
}
scsi_cdrom_set_callback(dev);
@@ -800,7 +795,10 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al
scsi_cdrom_command_write_dma(dev);
} else {
scsi_cdrom_update_request_length(dev, len, block_len);
if (direction == 0)
if ((dev->drv->bus_type != CDROM_BUS_SCSI) &&
(dev->tf->request_length == 0))
scsi_cdrom_command_complete(dev);
else if (direction == 0)
scsi_cdrom_command_read(dev);
else
scsi_cdrom_command_write(dev);
@@ -1048,6 +1046,8 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, const int msf, const int type, const int
int num = (dev->drv->bus_type == CDROM_BUS_SCSI) ?
dev->requested_blocks : 1;
dev->sectors_num = 0;
if (dev->drv->cd_status == CD_STATUS_EMPTY)
scsi_cdrom_not_ready(dev);
else if (dev->sector_pos > dev->drv->cdrom_capacity) {
@@ -1082,6 +1082,7 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, const int msf, const int type, const int
dev->drv->seek_pos = dev->sector_pos;
dev->sector_len--;
dev->sectors_num++;
dev->buffer_pos += temp_len;
}
@@ -2420,6 +2421,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb)
int32_t *BufLen;
dev->was_cached = -1;
dev->sectors_num = 1;
if (dev->drv->bus_type == CDROM_BUS_SCSI) {
BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length;

View File

@@ -570,7 +570,10 @@ scsi_disk_data_command_finish(scsi_disk_t *dev, int len, const int block_len,
scsi_disk_command_write_dma(dev);
} else {
scsi_disk_update_request_length(dev, len, block_len);
if (direction == 0)
if ((dev->drv->bus_type != HDD_BUS_SCSI) &&
(dev->tf->request_length == 0))
scsi_disk_command_complete(dev);
else if (direction == 0)
scsi_disk_command_read(dev);
else
scsi_disk_command_write(dev);

View File

@@ -1050,7 +1050,7 @@ spock_callback(void *priv)
spock_execute_cmd(scsi, scb);
}
if (scsi->attention_wait) {
if (scsi->attention_wait && ((scsi->scb_state == 0) || (scsi->attention_pending & 0xf0) == 0xe0)) {
scsi->attention_wait--;
if (!scsi->attention_wait) {
scsi->attention = scsi->attention_pending;

View File

@@ -338,20 +338,13 @@ bochs_vbe_recalctimings(svga_t* svga)
svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3;
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3);
svga->fullchange = 3;
} else {
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8));
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
}
if (svga->ma_latch != dev->ma_latch_old) {
if (svga->bpp == 4) {
svga->maback = (svga->maback - (dev->ma_latch_old << 2)) +
(svga->ma_latch << 2);
} else {
svga->maback = (svga->maback - (dev->ma_latch_old)) +
(svga->ma_latch);
dev->ma_latch_old = svga->ma_latch;
}
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
svga->fullchange = 3;
}
if (svga->bpp == 4)
@@ -482,18 +475,10 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv)
} else {
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8));
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
}
if (svga->ma_latch != dev->ma_latch_old) {
if (svga->bpp == 4) {
svga->maback = (svga->maback - (dev->ma_latch_old << 2)) +
(svga->ma_latch << 2);
} else {
svga->maback = (svga->maback - (dev->ma_latch_old)) +
(svga->ma_latch);
dev->ma_latch_old = svga->ma_latch;
}
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
}
svga->fullchange = 3;
}
else
svga_recalctimings(&dev->svga);