diff --git a/src/86box.h b/src/86box.h index d45b1bead..06975312f 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,7 +1,7 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.20" -#define emulator_version_w L"1.20" +#define emulator_version "2.00" +#define emulator_version_w L"2.00" #define CONFIG_FILE L"86box.cfg" diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 06066223f..328289d53 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -21,6 +21,8 @@ #define CPU_BLOCK_END() cpu_block_end = 1 +uint32_t cpu_cur_status = 0; + int cpu_reps, cpu_reps_latched; int cpu_notreps, cpu_notreps_latched; @@ -1372,7 +1374,7 @@ void exec386_dynarec(int cycs) and physical address. The physical address check will also catch any page faults at this stage*/ valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32); + (block->phys == phys_addr) && (block->status == cpu_cur_status); if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); @@ -1384,7 +1386,7 @@ void exec386_dynarec(int cycs) if (new_block) { valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32); + (new_block->phys == phys_addr) && (new_block->status == cpu_cur_status); if (valid_block) block = new_block; } diff --git a/src/CPU/808x.c b/src/CPU/808x.c index c102fa45f..80af2c9be 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -546,6 +546,7 @@ void resetx86() resets++; ins = 0; use32=0; + cpu_cur_status = 0; stack32=0; cpu_state.pc=0; msw=0; @@ -583,6 +584,7 @@ void softresetx86() { use32=0; stack32=0; + cpu_cur_status = 0; cpu_state.pc=0; msw=0; cr0=0; diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index ad0b3f63a..5a076db8f 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -35,6 +35,9 @@ typedef struct codeblock_t { + uint64_t page_mask, page_mask2; + uint64_t cmp; + /*Previous and next pointers, for the codeblock list associated with each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ @@ -45,22 +48,19 @@ typedef struct codeblock_t fails.*/ struct codeblock_t *parent, *left, *right; + int pnt; + int ins; + + int was_recompiled; + int TOP; + uint32_t pc; uint32_t _cs; uint32_t endpc; uint32_t phys, phys_2; - uint32_t use32; - int stack32; - int pnt; - int ins; - uint64_t page_mask, page_mask2; - - int was_recompiled; + uint32_t status; uint32_t flags; - int TOP; - - uint64_t cmp; - + uint8_t data[2048]; } codeblock_t; diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index 8573ab495..c27b0f37e 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -866,6 +866,10 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; if (IS_32_ADDR(&seg->base)) { @@ -900,6 +904,10 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; if (IS_32_ADDR(&seg->base)) { @@ -926,6 +934,11 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; + if (IS_32_ADDR(&seg->base)) { addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ @@ -962,7 +975,13 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1030,7 +1049,13 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1114,7 +1139,13 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1190,7 +1221,13 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1309,7 +1346,13 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1388,7 +1431,13 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1478,7 +1527,13 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1566,7 +1621,13 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5252,7 +5313,13 @@ static void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5299,12 +5366,16 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } if (IS_32_ADDR(writelookup2)) { addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ @@ -5328,7 +5399,9 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0); // addbyte(0xc3); /*RET*/ - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); @@ -5373,7 +5446,13 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5416,15 +5495,23 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } addbyte(0x8d); /*LEA ESI, 1[EDI]*/ addbyte(0x77); addbyte(0x01); - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5475,7 +5562,9 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5510,7 +5599,13 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5553,15 +5648,23 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } addbyte(0x8d); /*LEA ESI, 3[EDI]*/ addbyte(0x77); addbyte(0x03); - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5612,7 +5715,9 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5642,7 +5747,13 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5709,7 +5820,13 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5785,7 +5902,13 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5883,7 +6006,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -5955,7 +6084,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -6038,7 +6173,13 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h index c8c18a28c..229c066ca 100644 --- a/src/CPU/codegen_ops_x86.h +++ b/src/CPU/codegen_ops_x86.h @@ -616,6 +616,10 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -637,6 +641,10 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -650,6 +658,11 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ addbyte(0x05); addlong((uint32_t)&seg->limit_low); @@ -675,9 +688,18 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -685,9 +707,18 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -697,9 +728,18 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -707,9 +747,18 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); @@ -720,9 +769,18 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -732,9 +790,18 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -743,9 +810,18 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -756,9 +832,18 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -786,9 +871,18 @@ static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -799,9 +893,18 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -812,9 +915,18 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -825,9 +937,18 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -838,9 +959,18 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -851,9 +981,18 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -874,9 +1013,18 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x89); /*MOV ECX, host_reg2*/ addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); } - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } @@ -3792,9 +3940,18 @@ static void LOAD_EA() static void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write*/ addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3802,9 +3959,18 @@ static void MEM_CHECK_WRITE(x86seg *seg) static void MEM_CHECK_WRITE_W(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write_w*/ addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3812,9 +3978,18 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) static void MEM_CHECK_WRITE_L(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write_l*/ addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index e591adc95..9f42b07dd 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -274,13 +274,13 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; - block->use32 = use32; - block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = 0; + block->status = cpu_cur_status; + block->was_recompiled = 0; recomp_page = block->phys & ~0xfff; diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index a42b32104..01015ce87 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1401,12 +1401,11 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; - block->use32 = use32; - block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; block->was_recompiled = 0; diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h index a2b4f6f31..c47517c37 100644 --- a/src/CPU/x86_ops_misc.h +++ b/src/CPU/x86_ops_misc.h @@ -755,9 +755,17 @@ static int opLOADALL(uint32_t fetchdat) ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); _ss.access = readmemb(0, 0x845); _ss.limit = readmemw(0, 0x846); + if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); _ds.access = readmemb(0, 0x84B); _ds.limit = readmemw(0, 0x84C); + if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); gdt.limit = readmemw(0, 0x852); ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); @@ -797,8 +805,29 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0; if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0; + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); + if (use32) + cpu_cur_status |= CPU_STATUS_USE32; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; set_segment_limit(s, segdat3); + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } static int opLOADALL386(uint32_t fetchdat) diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index cc0cc6dbc..10e79b7c9 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -159,6 +159,29 @@ void x86np(char *s, uint16_t error) } +static void set_stack32(int s) +{ + stack32 = s; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; + else + cpu_cur_status &= ~CPU_STATUS_STACK32; +} + +static void set_use32(int u) +{ + if (u) + { + use32 = 0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + } +} + void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); @@ -179,6 +202,21 @@ void do_seg_load(x86seg *s, uint16_t *segdat) s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; s->limit_low = s->limit + 1; } + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } static void do_seg_v86_init(x86seg *s) @@ -251,6 +289,8 @@ void loadseg(uint16_t seg, x86seg *s) s->seg=0; s->access = 0x80; s->base=-1; + if (s == &_ds) + cpu_cur_status &= ~CPU_STATUS_FLATDS; return; } addr=seg&~7; @@ -303,7 +343,7 @@ void loadseg(uint16_t seg, x86seg *s) x86ss(NULL,seg&~3); return; } - stack32 = (segdat[3] & 0x40) ? 1 : 0; + set_stack32((segdat[3] & 0x40) ? 1 : 0); } else if (s!=&_cs) { @@ -359,6 +399,22 @@ void loadseg(uint16_t seg, x86seg *s) stack32 = 0; s->checked = 1; } + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } #define DPL ((segdat[2]>>13)&3) @@ -426,8 +482,7 @@ void loadcs(uint16_t seg) x86np("Load CS not present", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3] & 0x40); CS=(seg&~3)|CPL; do_seg_load(&_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; @@ -530,8 +585,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) x86np("Load CS JMP not present\n", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -544,7 +598,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; cycles -= timing_jmp_pm; } else /*System segment*/ @@ -642,8 +695,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - cpu_state.pc=newpc; + set_use32(segdat[3]&0x40); + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -828,8 +881,7 @@ void loadcscall(uint16_t seg) x86np("Load CS call not present", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -848,7 +900,6 @@ void loadcscall(uint16_t seg) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; if (csout) pclog("Complete\n"); cycles -= timing_call_pm; } @@ -1005,7 +1056,7 @@ void loadcscall(uint16_t seg) } if (!stack32) oldsp &= 0xFFFF; SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; @@ -1022,7 +1073,7 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3]&0x40); cpu_state.pc=newpc; if (output) pclog("Set access 2\n"); @@ -1101,8 +1152,8 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - cpu_state.pc=newpc; + set_use32(segdat[3]&0x40); + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -1245,8 +1296,8 @@ void pmoderetf(int is32, uint16_t off) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - + set_use32(segdat[3] & 0x40); + cycles -= timing_retf_pm; } else @@ -1353,7 +1404,7 @@ void pmoderetf(int is32, uint16_t off) return; } SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -1375,7 +1426,7 @@ void pmoderetf(int is32, uint16_t off) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3] & 0x40); if (stack32) ESP+=off; else SP+=off; @@ -1570,7 +1621,7 @@ void pmodeint(int num, int soft) return; } SS=newss; - stack32 = (segdat3[3] & 0x40) ? 1 : 0; + set_stack32((segdat3[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat3); @@ -1655,7 +1706,7 @@ void pmodeint(int num, int soft) if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; - use32=(segdat2[3]&0x40)?0x300:0; + set_use32(segdat2[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -1809,6 +1860,7 @@ void pmodeiret(int is32) do_seg_v86_init(&_es); loadseg(segs[1],&_ds); do_seg_v86_init(&_ds); + cpu_cur_status &= ~CPU_STATUS_FLATDS; loadseg(segs[2],&_fs); do_seg_v86_init(&_fs); loadseg(segs[3],&_gs); @@ -1826,7 +1878,9 @@ void pmodeiret(int is32) ESP=newsp; loadseg(newss,&_ss); do_seg_v86_init(&_ss); + cpu_cur_status &= ~CPU_STATUS_FLATSS; use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; flags=(tempflags&0xFFD5)|2; cycles -= timing_iret_v86; return; @@ -1913,7 +1967,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -1996,7 +2050,7 @@ void pmodeiret(int is32) return; } SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -2018,7 +2072,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3] & 0x40); check_seg_valid(&_ds); check_seg_valid(&_es); @@ -2208,7 +2262,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat2[3]&0x40)?0x300:0; + set_use32(segdat2[3] & 0x40); EAX=new_eax; ECX=new_ecx; diff --git a/src/ICONS/hard_disk_rll.ico b/src/ICONS/hard_disk_rll.ico new file mode 100644 index 000000000..6d329868b Binary files /dev/null and b/src/ICONS/hard_disk_rll.ico differ diff --git a/src/ICONS/hard_disk_rll_active.ico b/src/ICONS/hard_disk_rll_active.ico new file mode 100644 index 000000000..5692d2452 Binary files /dev/null and b/src/ICONS/hard_disk_rll_active.ico differ diff --git a/src/ICONS/hard_disk_xtide.ico b/src/ICONS/hard_disk_xtide.ico new file mode 100644 index 000000000..3f64e2882 Binary files /dev/null and b/src/ICONS/hard_disk_xtide.ico differ diff --git a/src/ICONS/hard_disk_xtide_active.ico b/src/ICONS/hard_disk_xtide_active.ico new file mode 100644 index 000000000..806329fea Binary files /dev/null and b/src/ICONS/hard_disk_xtide_active.ico differ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ed0cb81f8..8bc62edbc 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -195,8 +195,8 @@ WINOBJ = win.o \ win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \ win_d3d.o win_d3d_fs.o \ win_language.o win_status.o win_opendir.o win_dynld.o \ - win_video.o win_serial.o win_mouse.o \ - win_joystick.o win_midi.o \ + win_video.o win_serial.o win_keyboard.o win_mouse.o \ + win_iodev.o win_joystick.o win_midi.o \ win_settings.o win_deviceconfig.o win_joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ diff --git a/src/SOUND/snd_gus.c b/src/SOUND/snd_gus.c index 2735d77fd..bf625dfb2 100644 --- a/src/SOUND/snd_gus.c +++ b/src/SOUND/snd_gus.c @@ -547,7 +547,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); uint8_t readgus(uint16_t addr, void *p) { gus_t *gus = (gus_t *)p; - uint8_t val; + uint8_t val = 0xff; switch (addr) { case 0x340: /*MIDI status*/ diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 40bfd4213..e94646fd3 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -322,10 +322,10 @@ uint8_t sb_16_mixer_read(uint16_t addr, void *p) case 0x80: switch (sb->dsp.sb_irqnum) { - case 2: return 1; /*IRQ 7*/ - case 5: return 2; /*IRQ 7*/ + case 2: return 1; /*IRQ 2*/ + case 5: return 2; /*IRQ 5*/ case 7: return 4; /*IRQ 7*/ - case 10: return 8; /*IRQ 7*/ + case 10: return 8; /*IRQ 10*/ } break; case 0x81: @@ -465,7 +465,7 @@ void sb_pro_mcv_write(int port, uint8_t val, void *p) void *sb_1_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -482,7 +482,7 @@ void *sb_1_init() void *sb_15_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -517,7 +517,7 @@ void *sb_mcv_init() void *sb_2_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -535,7 +535,7 @@ void *sb_2_init() void *sb_pro_v1_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -563,7 +563,7 @@ void *sb_pro_v1_init() void *sb_pro_v2_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl3_init(&sb->opl); @@ -594,9 +594,6 @@ void *sb_pro_mcv_init() opl3_init(&sb->opl); sb_dsp_init(&sb->dsp, SBPRO2); - /*sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));*/ sb_mixer_init(&sb->mixer); io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); sound_add_handler(sb_get_buffer_opl3, sb); @@ -616,7 +613,7 @@ void *sb_pro_mcv_init() void *sb_16_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl3_init(&sb->opl); @@ -631,7 +628,7 @@ void *sb_16_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); - mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); + mpu401_init(&sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq401"), device_get_config_int("mode401")); sb->mixer.regs[0x30] = 31 << 3; sb->mixer.regs[0x31] = 31 << 3; @@ -661,7 +658,7 @@ int sb_awe32_available() void *sb_awe32_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); int onboard_ram = device_get_config_int("onboard_ram"); memset(sb, 0, sizeof(sb_t)); @@ -677,7 +674,7 @@ void *sb_awe32_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); + mpu401_init(&sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq401"), device_get_config_int("mode401")); emu8k_init(&sb->emu8k, onboard_ram); sb->mixer.regs[0x30] = 31 << 3; @@ -733,7 +730,7 @@ void sb_add_status_info(char *s, int max_len, void *p) static device_config_t sb_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -826,7 +823,7 @@ static device_config_t sb_mcv_config[] = static device_config_t sb_pro_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -881,7 +878,7 @@ static device_config_t sb_pro_config[] = static device_config_t sb_16_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -901,7 +898,7 @@ static device_config_t sb_16_config[] = } }, { - "addr401", "MPU-401 Address", CONFIG_SELECTION, "", 0x330, + "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, { { "0x300", 0x300 @@ -1016,7 +1013,7 @@ static device_config_t sb_16_config[] = static device_config_t sb_awe32_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -1036,7 +1033,7 @@ static device_config_t sb_awe32_config[] = } }, { - "addr401", "MPU-401 Address", CONFIG_SELECTION, "", 0x330, + "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, { { "0x300", 0x300 diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index e41ecbda8..b8761032d 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -32,194 +32,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US STATUSBARMENU MENU DISCARDABLE BEGIN - POPUP "FDD 1" - BEGIN - MENUITEM "&Change...", IDM_DISC_1 - MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP - MENUITEM "&Eject FDD 1", IDM_EJECT_1 - END - POPUP "FDD 2" - BEGIN - MENUITEM "&Change...", IDM_DISC_2 - MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP - MENUITEM "&Eject FDD 2", IDM_EJECT_2 - END - POPUP "FDD 3" - BEGIN - MENUITEM "&Change...", IDM_DISC_3 - MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP - MENUITEM "&Eject FDD 3", IDM_EJECT_3 - END - POPUP "FDD 4" - BEGIN - MENUITEM "&Change...", IDM_DISC_4 - MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP - MENUITEM "&Eject FDD 4", IDM_EJECT_4 - END - POPUP "CD-ROM 1" - BEGIN - MENUITEM "&Mute", IDM_CDROM_1_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_1_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_1_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_1_IMAGE - END - POPUP "CD-ROM 2" - BEGIN - MENUITEM "&Mute", IDM_CDROM_2_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_2_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_2_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_2_IMAGE - END - POPUP "CD-ROM 3" - BEGIN - MENUITEM "&Mute", IDM_CDROM_3_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_3_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_3_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_3_IMAGE - END - POPUP "CD-ROM 4" - BEGIN - MENUITEM "&Mute", IDM_CDROM_4_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_4_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_4_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_4_IMAGE - END - POPUP "Removable disk 01" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_01_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_01_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_01_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_01_EIMAGE - END - POPUP "Removable disk 02" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_02_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_02_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_02_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_02_EIMAGE - END - POPUP "Removable disk 03" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_03_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_03_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_03_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_03_EIMAGE - END - POPUP "Removable disk 04" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_04_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_04_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_04_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_04_EIMAGE - END - POPUP "Removable disk 05" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_05_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_05_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_05_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_05_EIMAGE - END - POPUP "Removable disk 06" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_06_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_06_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_06_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_06_EIMAGE - END - POPUP "Removable disk 07" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_07_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_07_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_07_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_07_EIMAGE - END - POPUP "Removable disk 08" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_08_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_08_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_08_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_08_EIMAGE - END - POPUP "Removable disk 09" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_09_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_09_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_09_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_09_EIMAGE - END - POPUP "Removable disk 10" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_10_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_10_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_10_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_10_EIMAGE - END - POPUP "Removable disk 11" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_11_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_11_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_11_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_11_EIMAGE - END - POPUP "Removable disk 12" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_12_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_12_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_12_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_12_EIMAGE - END - POPUP "Removable disk 13" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_13_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_13_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_13_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_13_EIMAGE - END - POPUP "Removable disk 14" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_14_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_14_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_14_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_14_EIMAGE - END - POPUP "Removable disk 15" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_15_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_15_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_15_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_15_EIMAGE - END - POPUP "Removable disk 16" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_16_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_16_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_16_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_16_EIMAGE - END END MAINMENU MENU DISCARDABLE @@ -254,7 +66,7 @@ BEGIN MENUITEM "&2x", IDM_VID_SCALE_4X END MENUITEM SEPARATOR - MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN + MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" BEGIN MENUITEM "&Full screen stretch", IDM_VID_FS_FULL @@ -346,6 +158,7 @@ BEGIN #ifdef ENABLE_LOG_BREAKPOINT VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY #endif + VK_PRIOR, IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL END @@ -668,12 +481,16 @@ END 177 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_active.ico" 192 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" 193 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" -194 ICON DISCARDABLE "ICONS/hard_disk.ico" -195 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -196 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -197 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -198 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -199 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +194 ICON DISCARDABLE "ICONS/hard_disk_xtide.ico" +195 ICON DISCARDABLE "ICONS/hard_disk_xtide_active.ico" +196 ICON DISCARDABLE "ICONS/hard_disk_rll.ico" +197 ICON DISCARDABLE "ICONS/hard_disk_rll_active.ico" +198 ICON DISCARDABLE "ICONS/hard_disk.ico" +199 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +200 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +201 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +202 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +203 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" 256 ICON DISCARDABLE "ICONS/machine.ico" 257 ICON DISCARDABLE "ICONS/video.ico" 258 ICON DISCARDABLE "ICONS/input_devices.ico" @@ -972,9 +789,9 @@ BEGIN 2163 "Attempting to create a spuriously large hard disk image" 2164 "Invalid number of sectors (valid values are between 1 and 99)" 2165 "MFM" - 2166 "IDE (PIO-only)" - 2167 "IDE (PIO and DMA)" - 2168 "SCSI" + 2166 "XT IDE" + 2167 "RLL" + 2168 "IDE (PIO-only)" 2169 "%01i:%01i" 2170 "Custom..." 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" @@ -1004,13 +821,30 @@ BEGIN 2195 "IDE (PIO-only) (%01i:%01i)" 2196 "Add New Hard Disk" 2197 "Add Existing Hard Disk" - 2198 "Removable disk %i: %s" + 2198 "SCSI removable disk %i: %s" 2199 "USB is not yet supported" 2200 "Invalid PCap device" - 2201 "SCSI removable disk: %ws" - 2202 "" - 2203 "English (United States)" + 2201 "&Notify disk change" + 2202 "SCSI (removable)" + 2203 "SCSI (removable) (%02i:%02i)" 2204 "Pcap Library Not Available" + 2205 "RLL (%01i:%01i)" + 2206 "XT IDE (%01i:%01i)" + 2207 "RLL hard disk" + 2208 "XT IDE hard disk" + 2209 "IDE (PIO and DMA)" + 2210 "SCSI" + 2211 "&New image..." + 2212 "Existing image..." + 2213 "Existing image (&Write-protected)..." + 2214 "E&ject" + 2215 "&Mute" + 2216 "E&mpty" + 2217 "&Reload previous image" + 2218 "&Image..." + 2219 "PCap failed to set up because it may not be initialized" + 2220 "Image (&Write-protected)..." + 2221 "English (United States)" END diff --git a/src/WIN/plat_iodev.h b/src/WIN/plat_iodev.h new file mode 100644 index 000000000..650973483 --- /dev/null +++ b/src/WIN/plat_iodev.h @@ -0,0 +1,5 @@ +extern void cdrom_eject(uint8_t id); +extern void cdrom_reload(uint8_t id); +extern void removable_disk_unload(uint8_t id); +extern void removable_disk_eject(uint8_t id); +extern void removable_disk_reload(uint8_t id); diff --git a/src/WIN/resource.h b/src/WIN/resource.h index d70d84a2d..fdc53b649 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -117,19 +117,6 @@ #define IDM_ABOUT 40001 #define IDC_ABOUT_ICON 65535 -#define IDM_DISC_1 40000 -#define IDM_DISC_2 40001 -#define IDM_DISC_3 40002 -#define IDM_DISC_4 40003 -#define IDM_DISC_1_WP 40004 -#define IDM_DISC_2_WP 40005 -#define IDM_DISC_3_WP 40006 -#define IDM_DISC_4_WP 40007 -#define IDM_EJECT_1 40008 -#define IDM_EJECT_2 40009 -#define IDM_EJECT_3 40010 -#define IDM_EJECT_4 40011 - #define IDM_FILE_RESET 40015 #define IDM_FILE_HRESET 40016 #define IDM_FILE_EXIT 40017 @@ -159,92 +146,6 @@ #define IDM_VID_SCREENSHOT 40078 #define IDM_VID_INVERT 40079 -#define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_IMAGE 40144 -#define IDM_CDROM_1_RELOAD 40160 -#define IDM_CDROM_1_EMPTY 40176 -#define IDM_CDROM_1_REAL 40192 -#define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_IMAGE 40145 -#define IDM_CDROM_2_RELOAD 40161 -#define IDM_CDROM_2_EMPTY 40177 -#define IDM_CDROM_2_REAL 40193 -#define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_IMAGE 40146 -#define IDM_CDROM_3_RELOAD 40162 -#define IDM_CDROM_3_EMPTY 40178 -#define IDM_CDROM_3_REAL 40194 -#define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_IMAGE 40147 -#define IDM_CDROM_4_RELOAD 40163 -#define IDM_CDROM_4_EMPTY 40179 -#define IDM_CDROM_4_REAL 40195 - -#define IDM_RDISK_01_IMAGE 3200 -#define IDM_RDISK_01_EIMAGE 3216 -#define IDM_RDISK_01_RELOAD 3232 -#define IDM_RDISK_01_EMPTY 3248 -#define IDM_RDISK_02_IMAGE 3201 -#define IDM_RDISK_02_EIMAGE 3217 -#define IDM_RDISK_02_RELOAD 3233 -#define IDM_RDISK_02_EMPTY 3249 -#define IDM_RDISK_03_IMAGE 3202 -#define IDM_RDISK_03_EIMAGE 3218 -#define IDM_RDISK_03_RELOAD 3234 -#define IDM_RDISK_03_EMPTY 3250 -#define IDM_RDISK_04_IMAGE 3203 -#define IDM_RDISK_04_EIMAGE 3219 -#define IDM_RDISK_04_RELOAD 3235 -#define IDM_RDISK_04_EMPTY 3251 -#define IDM_RDISK_05_IMAGE 3204 -#define IDM_RDISK_05_EIMAGE 3220 -#define IDM_RDISK_05_RELOAD 3236 -#define IDM_RDISK_05_EMPTY 3252 -#define IDM_RDISK_06_IMAGE 3205 -#define IDM_RDISK_06_EIMAGE 3221 -#define IDM_RDISK_06_RELOAD 3237 -#define IDM_RDISK_06_EMPTY 3253 -#define IDM_RDISK_07_IMAGE 3206 -#define IDM_RDISK_07_EIMAGE 3222 -#define IDM_RDISK_07_RELOAD 3238 -#define IDM_RDISK_07_EMPTY 3254 -#define IDM_RDISK_08_IMAGE 3207 -#define IDM_RDISK_08_EIMAGE 3223 -#define IDM_RDISK_08_RELOAD 3239 -#define IDM_RDISK_08_EMPTY 3255 -#define IDM_RDISK_09_IMAGE 3208 -#define IDM_RDISK_09_EIMAGE 3224 -#define IDM_RDISK_09_RELOAD 3240 -#define IDM_RDISK_09_EMPTY 3256 -#define IDM_RDISK_10_IMAGE 3209 -#define IDM_RDISK_10_EIMAGE 3225 -#define IDM_RDISK_10_RELOAD 3241 -#define IDM_RDISK_10_EMPTY 3257 -#define IDM_RDISK_11_IMAGE 3210 -#define IDM_RDISK_11_EIMAGE 3226 -#define IDM_RDISK_11_RELOAD 3242 -#define IDM_RDISK_11_EMPTY 3258 -#define IDM_RDISK_12_IMAGE 3211 -#define IDM_RDISK_12_EIMAGE 3227 -#define IDM_RDISK_12_RELOAD 3243 -#define IDM_RDISK_12_EMPTY 3259 -#define IDM_RDISK_13_IMAGE 3212 -#define IDM_RDISK_13_EIMAGE 3228 -#define IDM_RDISK_13_RELOAD 3244 -#define IDM_RDISK_13_EMPTY 3260 -#define IDM_RDISK_14_IMAGE 3213 -#define IDM_RDISK_14_EIMAGE 3229 -#define IDM_RDISK_14_RELOAD 3245 -#define IDM_RDISK_14_EMPTY 3261 -#define IDM_RDISK_15_IMAGE 3214 -#define IDM_RDISK_15_EIMAGE 3230 -#define IDM_RDISK_15_RELOAD 3246 -#define IDM_RDISK_15_EMPTY 3262 -#define IDM_RDISK_16_IMAGE 3215 -#define IDM_RDISK_16_EIMAGE 3231 -#define IDM_RDISK_16_RELOAD 3247 -#define IDM_RDISK_16_EMPTY 3263 - #define IDM_IDE_TER_ENABLED 44000 #define IDM_IDE_TER_IRQ9 44009 #define IDM_IDE_TER_IRQ10 44010 @@ -326,85 +227,7 @@ #define IDC_EDIT6 1035 #define IDC_COMBOHDT 1036 -#define IDC_EJECTC 1040 -#define IDC_EDITC 1050 #define IDC_CFILE 1060 -#define IDC_CNEW 1070 -#define IDC_EDIT_C_SPT 1200 -#define IDC_EDIT_C_HPC 1210 -#define IDC_EDIT_C_CYL 1220 -#define IDC_EDIT_C_FN 1230 -#define IDC_TEXT_C_SIZE 1240 - -#define IDC_EJECTD 1041 -#define IDC_EDITD 1051 -#define IDC_DFILE 1061 -#define IDC_DNEW 1071 -#define IDC_EDIT_D_SPT 1201 -#define IDC_EDIT_D_HPC 1211 -#define IDC_EDIT_D_CYL 1221 -#define IDC_EDIT_D_FN 1231 -#define IDC_TEXT_D_SIZE 1241 - -#define IDC_EJECTE 1042 -#define IDC_EDITE 1052 -#define IDC_EFILE 1062 -#define IDC_ENEW 1072 -#define IDC_EDIT_E_SPT 1202 -#define IDC_EDIT_E_HPC 1212 -#define IDC_EDIT_E_CYL 1222 -#define IDC_EDIT_E_FN 1232 -#define IDC_TEXT_E_SIZE 1242 - -#define IDC_EJECTF 1043 -#define IDC_EDITF 1053 -#define IDC_FFILE 1063 -#define IDC_FNEW 1073 -#define IDC_EDIT_F_SPT 1203 -#define IDC_EDIT_F_HPC 1213 -#define IDC_EDIT_F_CYL 1223 -#define IDC_EDIT_F_FN 1233 -#define IDC_TEXT_F_SIZE 1243 - -#define IDC_EJECTG 1044 -#define IDC_EDITG 1054 -#define IDC_GFILE 1064 -#define IDC_GNEW 1074 -#define IDC_EDIT_G_SPT 1204 -#define IDC_EDIT_G_HPC 1214 -#define IDC_EDIT_G_CYL 1224 -#define IDC_EDIT_G_FN 1234 -#define IDC_TEXT_G_SIZE 1244 - -#define IDC_EJECTH 1045 -#define IDC_EDITH 1055 -#define IDC_HFILE 1065 -#define IDC_HNEW 1075 -#define IDC_EDIT_H_SPT 1205 -#define IDC_EDIT_H_HPC 1215 -#define IDC_EDIT_H_CYL 1225 -#define IDC_EDIT_H_FN 1235 -#define IDC_TEXT_H_SIZE 1245 - -#define IDC_EJECTI 1046 -#define IDC_EDITI 1056 -#define IDC_IFILE 1066 -#define IDC_INEW 1076 -#define IDC_EDIT_I_SPT 1206 -#define IDC_EDIT_I_HPC 1216 -#define IDC_EDIT_I_CYL 1226 -#define IDC_EDIT_I_FN 1236 -#define IDC_TEXT_I_SIZE 1246 - -#define IDC_EJECTJ 1047 -#define IDC_EDITJ 1057 -#define IDC_JFILE 1067 -#define IDC_JNEW 1077 -#define IDC_EDIT_J_SPT 1207 -#define IDC_EDIT_J_HPC 1217 -#define IDC_EDIT_J_CYL 1227 -#define IDC_EDIT_J_FN 1237 -#define IDC_TEXT_J_SIZE 1247 #define IDC_HDTYPE 1280 @@ -441,47 +264,26 @@ #define IDC_CONFIG_BASE 1200 -#define WM_RESETD3D WM_USER -#define WM_LEAVEFULLSCREEN WM_USER + 1 +/* The biggest amount of low bits needed for CD-ROMS (2 bits for ID and 5 bits for host drive, so 7 bits), + and removable disks (5 bits for ID), so we choose an 256-entry spacing for convenience. */ -#define C_BASE 6 -#define D_BASE 44 -#define E_BASE 82 -#define F_BASE 120 -#define G_BASE 158 -#define H_BASE 196 -#define I_BASE 234 -#define J_BASE 272 -#define CMD_BASE 314 -#define DLG_HEIGHT 346 +#define IDM_FLOPPY_IMAGE_NEW 0x1200 +#define IDM_FLOPPY_IMAGE_EXISTING 0x1300 +#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400 +#define IDM_FLOPPY_DUMP_86F 0x1500 +#define IDM_FLOPPY_EJECT 0x1600 -#define IDC_CHECK_CDROM_1_ENABLED 1536 -#define IDC_COMBO_CDROM_1_BUS 1544 -#define IDC_COMBO_CDROM_1_CHANNEL 1552 -#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 -#define IDC_COMBO_CDROM_1_SCSI_ID 1568 -#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 +#define IDM_CDROM_MUTE 0x2200 +#define IDM_CDROM_EMPTY 0x2300 +#define IDM_CDROM_RELOAD 0x2400 +#define IDM_CDROM_IMAGE 0x2500 +#define IDM_CDROM_HOST_DRIVE 0x2600 -#define IDC_CHECK_CDROM_2_ENABLED 1537 -#define IDC_COMBO_CDROM_2_BUS 1545 -#define IDC_COMBO_CDROM_2_CHANNEL 1553 -#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 -#define IDC_COMBO_CDROM_2_SCSI_ID 1569 -#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 - -#define IDC_CHECK_CDROM_3_ENABLED 1538 -#define IDC_COMBO_CDROM_3_BUS 1546 -#define IDC_COMBO_CDROM_3_CHANNEL 1554 -#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 -#define IDC_COMBO_CDROM_3_SCSI_ID 1570 -#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 - -#define IDC_CHECK_CDROM_4_ENABLED 1539 -#define IDC_COMBO_CDROM_4_BUS 1547 -#define IDC_COMBO_CDROM_4_CHANNEL 1555 -#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 -#define IDC_COMBO_CDROM_4_SCSI_ID 1571 -#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 +#define IDM_RDISK_EJECT 0x3200 +#define IDM_RDISK_RELOAD 0x3300 +#define IDM_RDISK_SEND_CHANGE 0x3400 +#define IDM_RDISK_IMAGE 0x3500 +#define IDM_RDISK_IMAGE_WP 0x3600 #define IDC_STATIC 1792 @@ -495,3 +297,5 @@ # define _APS_NEXT_SYMED_VALUE 101 # endif #endif + +#define STRINGS_NUM 174 diff --git a/src/WIN/win.c b/src/WIN/win.c index 4b6c771d0..41e94fa54 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -23,12 +23,15 @@ #include "../cdrom_null.h" #include "../cdrom_ioctl.h" #include "../cdrom_image.h" +#include "../scsi.h" +#include "../scsi_disk.h" #include "../video/video.h" #include "../video/vid_ega.h" #include "../mouse.h" #include "../sound/sound.h" #include "../sound/snd_dbopl.h" #include "plat_keyboard.h" +#include "plat_iodev.h" #include "plat_mouse.h" #include "plat_midi.h" @@ -36,10 +39,12 @@ #include "win_ddraw.h" #include "win_d3d.h" #include "win_language.h" + #include #include #include #include + #include "resource.h" @@ -47,13 +52,45 @@ #define MAPVK_VK_TO_VSC 0 #endif -static int save_window_pos = 0; -uint64_t timer_freq; +/* Declare Windows procedure */ +LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -int rawinputkey[272]; +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#define TIMER_1SEC 1 + +extern int updatestatus; + + +typedef struct win_event_t +{ + HANDLE handle; +} win_event_t; + +LONG_PTR OriginalStatusBarProcedure; +HWND ghwnd; +HINSTANCE hinstance; +HMENU menu; +int pause = 0; +int scale = 0; +HWND hwndRender, hwndStatus; +uint64_t timer_freq; +int winsizex=640, winsizey=480; +int efwinsizey=480; +int gfx_present[GFX_MAX]; +HANDLE ghMutex; +HANDLE mainthreadh; +int infocus=1; +int drawits=0; +int romspresent[ROM_MAX]; +int quited=0; +RECT oldclip; +int mousecapture=0; +int recv_key[272]; +HMENU *sb_menu_handles; +uint64_t main_time; -static RAWINPUTDEVICE device; -static uint16_t scancode_map[65536]; static struct { @@ -61,65 +98,47 @@ static struct void (*close)(); void (*resize)(int x, int y); } vid_apis[2][2] = -{ - { - ddraw_init, ddraw_close, NULL, - d3d_init, d3d_close, d3d_resize - }, - { - ddraw_fs_init, ddraw_fs_close, NULL, - d3d_fs_init, d3d_fs_close, NULL - }, -}; +{ { { ddraw_init, ddraw_close, NULL }, + { d3d_init, d3d_close, d3d_resize } }, + { { ddraw_fs_init, ddraw_fs_close, NULL }, + { d3d_fs_init, d3d_fs_close, NULL } } }; -#define TIMER_1SEC 1 +static int save_window_pos = 0; -int winsizex=640,winsizey=480; -int efwinsizey=480; -int gfx_present[GFX_MAX]; +static RAWINPUTDEVICE device; -HANDLE ghMutex; +static int win_doresize = 0; -HANDLE mainthreadh; +static int leave_fullscreen_flag = 0; -int infocus=1; +static int unscaled_size_x = 0; +static int unscaled_size_y = 0; -int drawits=0; +static uint64_t start_time; +static uint64_t end_time; -int romspresent[ROM_MAX]; -int quited=0; +HMENU smenu; -RECT oldclip; -int mousecapture=0; +static uint8_t host_cdrom_drive_available[26]; -/* Declare Windows procedure */ -LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +static uint8_t host_cdrom_drive_available_num = 0; -LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +static wchar_t **argv; +static int argc; +static wchar_t *argbuf; -LONG_PTR OriginalStatusBarProcedure; +static HANDLE hinstAcc; -HWND ghwnd; +static HICON hIcon[512]; -HINSTANCE hinstance; +static int *iStatusWidths; +static int *sb_icon_flags; +static int *sb_part_meanings; +static int *sb_part_icons; +static WCHAR **sbTips; -HMENU menu; +static int sb_parts = 0; -extern int updatestatus; - -int pause=0; - -static int win_doresize = 0; - -static int leave_fullscreen_flag = 0; - -static int unscaled_size_x = 0; -static int unscaled_size_y = 0; - -int scale = 0; - -HWND hwndRender, hwndStatus; void updatewindowsize(int x, int y) { @@ -236,11 +255,6 @@ void leave_fullscreen() leave_fullscreen_flag = 1; } -uint64_t main_time; - -uint64_t start_time; -uint64_t end_time; - void mainthread(LPVOID param) { int frames = 0; @@ -253,12 +267,14 @@ void mainthread(LPVOID param) old_time = GetTickCount(); while (!quited) { - if (updatestatus) - { - updatestatus = 0; - if (status_is_open) - SendMessage(status_hwnd, WM_USER, 0, 0); - } + if (updatestatus) + { + updatestatus = 0; + if (status_is_open) + { + SendMessage(status_hwnd, WM_USER, 0, 0); + } + } new_time = GetTickCount(); drawits += new_time - old_time; old_time = new_time; @@ -285,15 +301,9 @@ void mainthread(LPVOID param) video_wait_for_blit(); SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); GetWindowRect(ghwnd, &r); - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); GetWindowRect(hwndRender, &r); - MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), - winsizex, - 17, - TRUE); + MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), winsizex, 17, TRUE); GetWindowRect(ghwnd, &r); MoveWindow(ghwnd, r.left, r.top, @@ -331,11 +341,6 @@ void thread_sleep(int t) Sleep(t); } -typedef struct win_event_t -{ - HANDLE handle; -} win_event_t; - event_t *thread_create_event() { win_event_t *event = malloc(sizeof(win_event_t)); @@ -380,30 +385,123 @@ void thread_destroy_event(event_t *_event) free(event); } -HMENU smenu; - -static void initmenu(void) +static void init_cdrom_host_drives(void) { - int i, c; - HMENU m; + int i = 0; WCHAR s[64]; - for (i = 0; i < CDROM_NUM; i++) - { - m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ + host_cdrom_drive_available_num = 0; - /* Loop through each Windows drive letter and test to see if - it's a CDROM */ - for (c='A';c<='Z';c++) - { - _swprintf(s,L"%c:\\",c); - if (GetDriveType(s)==DRIVE_CDROM) - { - _swprintf(s, win_language_get_string_from_id(2076), c); - AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); - } - } + for (i='A'; i<='Z'; i++) + { + _swprintf(s, L"%c:\\", i + 0x41); + + if (GetDriveType(s)==DRIVE_CDROM) + { + host_cdrom_drive_available[i - 'A'] = 1; + + host_cdrom_drive_available_num++; + } + else + { + host_cdrom_drive_available[i - 'A'] = 0; + } + } +} + + +HMENU create_popup_menu(int part) +{ + HMENU newHandle; + newHandle = CreatePopupMenu(); + AppendMenu(smenu, MF_POPUP, (UINT_PTR) newHandle, 0); + return newHandle; +} + + +void create_floppy_submenu(HMENU m, int id) +{ + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, win_language_get_string_from_id(2211)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, win_language_get_string_from_id(2212)); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, win_language_get_string_from_id(2213)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, win_language_get_string_from_id(2214)); +} + +void create_cdrom_submenu(HMENU m, int id) +{ + int i = 0; + WCHAR s[64]; + + AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, win_language_get_string_from_id(2215)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, win_language_get_string_from_id(2216)); + AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, win_language_get_string_from_id(2217)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, win_language_get_string_from_id(2218)); + + if (host_cdrom_drive_available_num == 0) + { + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + cdrom_drives[id].host_drive = 0; + } + + goto check_menu_items; } + else + { + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + if (!host_cdrom_drive_available[cdrom_drives[id].host_drive]) + { + cdrom_drives[id].host_drive = 0; + } + } + } + + AppendMenu(m, MF_SEPARATOR, 0, 0); + + for (i = 0; i < 26; i++) + { + _swprintf(s, L"%c:\\", i + 0x41); + if (host_cdrom_drive_available[i]) + { + AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i << 3) | id, s); + } + } + +check_menu_items: + if (!cdrom_drives[id].sound_on) + { + CheckMenuItem(smenu, IDM_CDROM_MUTE | id, MF_CHECKED); + } + + if (cdrom_drives[id].host_drive == 200) + { + CheckMenuItem(smenu, IDM_CDROM_IMAGE | id, MF_CHECKED); + } + else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(smenu, IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + } + else + { + cdrom_drives[id].host_drive = 0; + CheckMenuItem(smenu, IDM_CDROM_EMPTY | id, MF_CHECKED); + } +} + +void create_removable_disk_submenu(HMENU m, int id) +{ + AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, win_language_get_string_from_id(2216)); + AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, win_language_get_string_from_id(2217)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, win_language_get_string_from_id(2201)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, win_language_get_string_from_id(2218)); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(2220)); } void get_executable_name(WCHAR *s, int size) @@ -425,96 +523,6 @@ uint64_t timer_read() return qpc_time.QuadPart; } -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -UINT16 convert_scan_code(UINT16 scan_code) -{ - switch (scan_code) - { - case 0xE001: - return 0xF001; - case 0xE002: - return 0xF002; - case 0xE0AA: - return 0xF003; - case 0xE005: - return 0xF005; - case 0xE006: - return 0xF006; - case 0xE007: - return 0xF007; - case 0xE071: - return 0xF008; - case 0xE072: - return 0xF009; - case 0xE07F: - return 0xF00A; - case 0xE0E1: - return 0xF00B; - case 0xE0EE: - return 0xF00C; - case 0xE0F1: - return 0xF00D; - case 0xE0FE: - return 0xF00E; - case 0xE0EF: - return 0xF00F; - - default: - return scan_code; - } -} - -void get_registry_key_map() -{ - WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - WCHAR *valueName = L"Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - - /* First, prepare the default scan code map list which is 1:1. - Remappings will be inserted directly into it. - 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, - since each array element is a scan code and provides for E0, etc. ones too. */ - for (j = 0; j < 65536; j++) - scancode_map[j] = convert_scan_code(j); - - bufSize = 32768; - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) - { - if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) - { - UINT32 *bufEx2 = (UINT32 *) buf; - int scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) - { - UINT16 *bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount*2; j += 2) - { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - int scancode_unmapped = bufEx[j + 1]; - int scancode_mapped = bufEx[j]; - - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Fixes scan code map logging. */ - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - -static wchar_t **argv; -static int argc; -static wchar_t *argbuf; - static void process_command_line() { WCHAR *cmdline; @@ -581,14 +589,6 @@ static void process_command_line() argv[argc] = NULL; } -int valid_models[2] = { 0, 1 }; -int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; -int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; -int valid_dma_channels[3] = { 5, 6, 7 }; -int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; -int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - int find_in_array(int *array, int val, int len, int menu_base) { int i = 0; @@ -604,8 +604,6 @@ int find_in_array(int *array, int val, int len, int menu_base) return temp; } -HANDLE hinstAcc; - HICON LoadIconEx(PCTSTR pszIconName) { return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); @@ -647,13 +645,6 @@ int fdd_type_to_icon(int type) } } -int sb_parts = 10; - -int sb_part_meanings[12]; -int sb_part_icons[12]; - -int sb_icon_width = 24; - int count_hard_disks(int bus) { int i = 0; @@ -671,29 +662,16 @@ int count_hard_disks(int bus) return c; } -HICON hIcon[512]; - -int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; - -#define SBI_FLAG_ACTIVE 1 -#define SBI_FLAG_EMPTY 256 - -int sb_icon_flags[512]; - -/* This is for the disk activity indicator. */ -void update_status_bar_icon(int tag, int active) +int find_status_bar_part(int tag) { int i = 0; int found = -1; - int temp_flags = 0; - if ((tag & 0xf0) >= 0x40) + if (sb_part_meanings == NULL) { - return; + return -1; } - temp_flags |= active; - for (i = 0; i < 12; i++) { if (sb_part_meanings[i] == tag) @@ -703,6 +681,24 @@ void update_status_bar_icon(int tag, int active) } } + return found; +} + +/* This is for the disk activity indicator. */ +void update_status_bar_icon(int tag, int active) +{ + int found = -1; + int temp_flags = 0; + + if (((tag & 0xf0) >= SB_TEXT) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) + { + return; + } + + temp_flags |= active; + + found = find_status_bar_part(tag); + if (found != -1) { if (temp_flags != (sb_icon_flags[found] & 1)) @@ -721,22 +717,14 @@ void update_status_bar_icon(int tag, int active) /* This is for the drive state indicator. */ void update_status_bar_icon_state(int tag, int state) { - int i = 0; int found = -1; - if ((tag & 0xf0) >= 0x20) + if (((tag & 0xf0) >= SB_HDD) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { return; } - for (i = 0; i < 12; i++) - { - if (sb_part_meanings[i] == tag) - { - found = i; - break; - } - } + found = find_status_bar_part(tag); if (found != -1) { @@ -750,31 +738,35 @@ void update_status_bar_icon_state(int tag, int state) } } -WCHAR sbTips[24][512]; - void create_floppy_tip(int part) { - WCHAR *szText; WCHAR wtext[512]; + WCHAR tempTip[512]; int drive = sb_part_meanings[part] & 0xf; mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); if (wcslen(discfns[drive]) == 0) { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); + _swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); } + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void create_cdrom_tip(int part) { - WCHAR *szText; - char ansi_text[3][512]; WCHAR wtext[512]; + WCHAR tempTip[512]; int drive = sb_part_meanings[part] & 0xf; @@ -782,48 +774,91 @@ void create_cdrom_tip(int part) { if (wcslen(cdrom_image[drive].image_path) == 0) { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); } } else if (cdrom_drives[drive].host_drive < 0x41) { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, wtext); } + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void create_removable_hd_tip(int part) { - WCHAR *szText; - WCHAR wtext[512]; + WCHAR tempTip[512]; - int drive = sb_part_meanings[part] & 0xf; + int drive = sb_part_meanings[part] & 0x1f; - if (wcslen(hdd_fn[drive]) == 0) + if (wcslen(hdc[drive].fn) == 0) { - _swprintf(sbTips[part], win_language_get_string_from_id(2201), win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2198), drive, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), hdd_fn[drive]); + _swprintf(tempTip, win_language_get_string_from_id(2198), drive, hdc[drive].fn); } + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void create_hd_tip(int part) { WCHAR *szText; + int id = 2181; int bus = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); - memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); + + switch(bus) + { + case HDD_BUS_MFM: + id = 2181; + break; + case HDD_BUS_RLL: + id = 2207; + break; + case HDD_BUS_XTIDE: + id = 2208; + break; + case HDD_BUS_IDE_PIO_ONLY: + id = 2182; + break; + case HDD_BUS_IDE_PIO_AND_DMA: + id = 2183; + break; + case HDD_BUS_SCSI: + id = 2184; + break; + } + + szText = (WCHAR *) win_language_get_string_from_id(id); + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(szText) << 1) + 2); + wcscpy(sbTips[part], szText); } void update_tip(int meaning) @@ -843,16 +878,16 @@ void update_tip(int meaning) { switch(meaning & 0xf0) { - case 0x00: + case SB_FLOPPY: create_floppy_tip(part); break; - case 0x10: + case SB_CDROM: create_cdrom_tip(part); break; - case 0x20: + case SB_RDISK: create_removable_hd_tip(part); break; - case 0x30: + case SB_HDD: create_hd_tip(part); break; default: @@ -863,30 +898,6 @@ void update_tip(int meaning) } } -static int get_floppy_state(int id) -{ - return (wcslen(discfns[id]) == 0) ? 1 : 0; -} - -static int get_cd_state(int id) -{ - if (cdrom_drives[id].host_drive < 0x41) - { - return 1; - } - else - { - if (cdrom_drives[id].host_drive == 0x200) - { - return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; - } - else - { - return 0; - } - } -} - void status_settextw(wchar_t *wstr) { int i = 0; @@ -894,7 +905,7 @@ void status_settextw(wchar_t *wstr) for (i = 0; i < sb_parts; i++) { - if (sb_part_meanings[i] == 0x40) + if (sb_part_meanings[i] == SB_TEXT) { part = i; } @@ -915,95 +926,218 @@ void status_settext(char *str) status_settextw(cwstr); } +void destroy_menu_handles() +{ + int i = 0; + + if (sb_parts == 0) + { + return; + } + + for (i = 0; i < sb_parts; i++) + { + DestroyMenu(sb_menu_handles[i]); + } + + free(sb_menu_handles); +} + +void destroy_tips() +{ + int i = 0; + + if (sb_parts == 0) + { + return; + } + + for (i = 0; i < sb_parts; i++) + { + free(sbTips[i]); + } + + free(sbTips); +} + void update_status_bar_panes(HWND hwnds) { int i, j, id; int edge = 0; - int c_rll = 0; int c_mfm = 0; + int c_rll = 0; + int c_xtide = 0; int c_ide_pio = 0; int c_ide_dma = 0; int c_scsi = 0; - c_mfm = count_hard_disks(1); - c_ide_pio = count_hard_disks(2); - c_ide_dma = count_hard_disks(3); - c_scsi = count_hard_disks(4); + c_mfm = count_hard_disks(HDD_BUS_MFM); + c_rll = count_hard_disks(HDD_BUS_RLL); + c_xtide = count_hard_disks(HDD_BUS_XTIDE); + c_ide_pio = count_hard_disks(HDD_BUS_IDE_PIO_ONLY); + c_ide_dma = count_hard_disks(HDD_BUS_IDE_PIO_AND_DMA); + c_scsi = count_hard_disks(HDD_BUS_SCSI); - for (i = 0; i < sb_parts; i++) + if (sb_parts > 0) { - SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + for (i = 0; i < sb_parts; i++) + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + + sb_parts = 0; + + free(iStatusWidths); + free(sb_part_meanings); + free(sb_part_icons); + free(sb_icon_flags); + destroy_menu_handles(); + destroy_tips(); } - sb_parts = 0; - memset(iStatusWidths, 0, 48); - memset(sb_part_meanings, 0, 48); - for (i = 0; i < 4; i++) + for (i = 0; i < FDD_NUM; i++) { if (fdd_get_type(i) != 0) { /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x00 | i; sb_parts++; } } - for (i = 0; i < 4; i++) + for (i = 0; i < CDROM_NUM; i++) { if (cdrom_drives[i].bus_type != 0) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x10 | i; sb_parts++; } } for (i = 0; i < 16; i++) { - if (hdc[i].bus == 5) + if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x20 | i; sb_parts++; } } - if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5) && !!memcmp(hdd_controller_name, "esdi", 4)) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x30; sb_parts++; } - if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + if (c_rll && !memcmp(hdd_controller_name, "esdi", 4)) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x31; sb_parts++; } - if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + if (c_xtide && !memcmp(hdd_controller_name, "xtide", 5)) { - edge += sb_icon_width; + sb_parts++; + } + if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE)) + { + sb_parts++; + } + if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE)) + { + sb_parts++; + } + if (c_scsi && (scsi_card_current != 0)) + { + sb_parts++; + } + sb_parts++; + + iStatusWidths = (int *) malloc(sb_parts << 2); + sb_part_meanings = (int *) malloc(sb_parts << 2); + sb_part_icons = (int *) malloc(sb_parts << 2); + sb_icon_flags = (int *) malloc(sb_parts << 2); + sb_menu_handles = (HMENU *) malloc(sb_parts * sizeof(HMENU)); + sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); + + memset(iStatusWidths, 0, sb_parts << 2); + memset(sb_part_meanings, 0, sb_parts << 2); + memset(sb_part_icons, 0, sb_parts << 2); + memset(sb_icon_flags, 0, sb_parts << 2); + memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); + + sb_parts = 0; + + for (i = 0; i < FDD_NUM; i++) + { + if (fdd_get_type(i) != 0) + { + /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_FLOPPY | i; + sb_parts++; + } + } + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type != 0) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_CDROM | i; + sb_parts++; + } + } + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_RDISK | i; + sb_parts++; + } + } + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5) && !!memcmp(hdd_controller_name, "esdi", 4)) + { + edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x32; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM; + sb_parts++; + } + if (c_rll && !memcmp(hdd_controller_name, "esdi", 4)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_RLL; + sb_parts++; + } + if (c_xtide && !memcmp(hdd_controller_name, "xtide", 5)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_XTIDE; + sb_parts++; + } + if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE_PIO_ONLY; + sb_parts++; + } + if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE_PIO_AND_DMA; sb_parts++; } if (c_scsi) { - edge += sb_icon_width; + edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x33; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_SCSI; sb_parts++; } if (sb_parts) { - iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); + iStatusWidths[sb_parts - 1] += (24 - SB_ICON_WIDTH); } iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = 0x40; + sb_part_meanings[sb_parts] = SB_TEXT; sb_parts++; SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); @@ -1012,13 +1146,16 @@ void update_status_bar_panes(HWND hwnds) { switch (sb_part_meanings[i] & 0xf0) { - case 0x00: + case SB_FLOPPY: /* Floppy */ sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; + sb_menu_handles[i] = create_popup_menu(i); + create_floppy_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf); + EnableMenuItem(sb_menu_handles[i], IDM_FLOPPY_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); create_floppy_tip(i); break; - case 0x10: + case SB_CDROM: /* CD-ROM */ id = sb_part_meanings[i] & 0xf; if (cdrom_drives[id].host_drive < 0x41) @@ -1036,11 +1173,11 @@ void update_status_bar_panes(HWND hwnds) sb_icon_flags[i] = 0; } } - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { j = 164; } - else if (cdrom_drives[id].bus_type == 3) + else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { j = 162; } @@ -1049,20 +1186,28 @@ void update_status_bar_panes(HWND hwnds) j = 160; } sb_part_icons[i] = j | sb_icon_flags[i]; + sb_menu_handles[i] = create_popup_menu(i); + create_cdrom_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf); + EnableMenuItem(sb_menu_handles[i], IDM_CDROM_RELOAD | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | MF_GRAYED); create_cdrom_tip(i); break; - case 0x20: + case SB_RDISK: /* Removable hard disk */ - sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(hdc[sb_part_meanings[i] & 0x1f].fn) == 0) ? 256 : 0; sb_part_icons[i] = 176 + sb_icon_flags[i]; + sb_menu_handles[i] = create_popup_menu(i); + create_removable_disk_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0x1f); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_EJECT | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_RELOAD | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_SEND_CHANGE | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); create_removable_hd_tip(i); break; - case 0x30: + case SB_HDD: /* Hard disk */ - sb_part_icons[i] = 192 + ((sb_part_meanings[i] & 0xf) << 1); + sb_part_icons[i] = 192 + (((sb_part_meanings[i] & 0xf) - 1) << 1); create_hd_tip(i); break; - case 0x40: + case SB_TEXT: /* Status text */ SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); sb_part_icons[i] = -1; @@ -1114,7 +1259,7 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) hIcon[i] = LoadIconEx((PCTSTR) i); } - for (i = 192; i < 200; i++) + for (i = 192; i < 204; i++) { hIcon[i] = LoadIconEx((PCTSTR) i); } @@ -1150,30 +1295,17 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) InitCommonControls(); - hwndStatus = CreateWindowEx( - 0, - STATUSCLASSNAME, - (PCTSTR) NULL, - SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, - 0, dh - 17, dw, 17, - hwndParent, - (HMENU) idStatus, - hinst, - NULL); + hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, (PCTSTR) NULL, SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, 0, dh - 17, dw, 17, hwndParent, + (HMENU) idStatus, hinst, NULL); GetWindowRect(hwndStatus, &rectDialog); - SetWindowPos( - hwndStatus, - HWND_TOPMOST, - rectDialog.left, - rectDialog.top, - rectDialog.right - rectDialog.left, - rectDialog.bottom - rectDialog.top, - SWP_SHOWWINDOW); + SetWindowPos(hwndStatus, HWND_TOPMOST, rectDialog.left, rectDialog.top, rectDialog.right - rectDialog.left, rectDialog.bottom - rectDialog.top, SWP_SHOWWINDOW); SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); + sb_parts = 0; + update_status_bar_panes(hwndStatus); return hwndStatus; @@ -1193,94 +1325,97 @@ void win_menu_update() #endif } -int recv_key[272]; - -int WINAPI WinMain (HINSTANCE hThisInstance, - HINSTANCE hPrevInstance, - LPSTR lpszArgument, - int nFunsterStil) - +int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { - HWND hwnd; /* This is the handle for our window */ - MSG messages; /* Here messages to the application are saved */ - WNDCLASSEX wincl; /* Data structure for the windowclass */ - int c, d, e, bRet; + HWND hwnd; /* This is the handle for our window */ + MSG messages; /* Here messages to the application are saved */ + WNDCLASSEX wincl; /* Data structure for the windowclass */ + int c, d, bRet; WCHAR emulator_title[200]; - LARGE_INTEGER qpc_freq; - HACCEL haccel; /* Handle to accelerator table */ + LARGE_INTEGER qpc_freq; + HACCEL haccel; /* Handle to accelerator table */ memset(recv_key, 0, sizeof(recv_key)); - process_command_line(); + process_command_line(); win_language_load_common_strings(); - - hinstance=hThisInstance; - /* The Window structure */ - wincl.hInstance = hThisInstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof (WNDCLASSEX); - /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hCursor = NULL; - wincl.lpszMenuName = NULL; /* No menu */ - wincl.cbClsExtra = 0; /* No extra bytes after the window class */ - wincl.cbWndExtra = 0; /* structure or the window instance */ - /* Use Windows's default color as the background of the window */ - wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; + hinstance=hThisInstance; + /* The Window structure */ + wincl.hInstance = hThisInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ + wincl.style = CS_DBLCLKS; /* Catch double-clicks */ + wincl.cbSize = sizeof (WNDCLASSEX); - /* Register the window class, and if it fails quit the program */ - if (!RegisterClassEx(&wincl)) - return 0; + /* Use default icon and mouse-pointer */ + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hCursor = NULL; + wincl.lpszMenuName = NULL; /* No menu */ + wincl.cbClsExtra = 0; /* No extra bytes after the window class */ + wincl.cbWndExtra = 0; /* structure or the window instance */ + /* Use Windows's default color as the background of the window */ + wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; - wincl.lpszClassName = szSubClassName; - wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ + /* Register the window class, and if it fails quit the program */ + if (!RegisterClassEx(&wincl)) + { + return 0; + } - if (!RegisterClassEx(&wincl)) - return 0; + wincl.lpszClassName = szSubClassName; + wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + if (!RegisterClassEx(&wincl)) + { + return 0; + } - /* The class is registered, let's create the program*/ - hwnd = CreateWindowEx ( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - emulator_title, /* Title Text */ - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where the window ends up on the screen */ - 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ - 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ - HWND_DESKTOP, /* The window is a child-window to desktop */ - menu, /* Menu */ - hThisInstance, /* Program Instance handler */ - NULL /* No Window Creation data */ + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + + /* The class is registered, let's create the program*/ + hwnd = CreateWindowEx ( + 0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + emulator_title, /* Title Text */ + (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ + CW_USEDEFAULT, /* Windows decides the position */ + CW_USEDEFAULT, /* where the window ends up on the screen */ + 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ + 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ + HWND_DESKTOP, /* The window is a child-window to desktop */ + menu, /* Menu */ + hThisInstance, /* Program Instance handler */ + NULL /* No Window Creation data */ ); - /* Make the window visible on the screen */ - ShowWindow (hwnd, nFunsterStil); + /* Make the window visible on the screen */ + ShowWindow (hwnd, nFunsterStil); - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstAcc, L"MainAccel"); - if (haccel == NULL) - fatal("haccel is null\n"); + /* Load the accelerator table */ + haccel = LoadAccelerators(hinstAcc, L"MainAccel"); + if (haccel == NULL) + { + fatal("haccel is null\n"); + } - memset(rawinputkey, 0, sizeof(rawinputkey)); device.usUsagePage = 0x01; device.usUsage = 0x06; device.dwFlags = RIDEV_NOHOTKEYS; device.hwndTarget = hwnd; if (RegisterRawInputDevices(&device, 1, sizeof(device))) + { pclog("Raw input registered!\n"); + } else + { pclog("Raw input registration failed!\n"); + } get_registry_key_map(); @@ -1296,7 +1431,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); + init_cdrom_host_drives(); if (vid_apis[0][vid_api].init(hwndRender) == 0) { @@ -1313,28 +1448,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)|WS_VISIBLE); else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); - /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ - for (e = 0; e < CDROM_NUM; e++) - { - if (!cdrom_drives[e].sound_on) - { - CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); - } - - if (cdrom_drives[e].host_drive == 200) - { - CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); - } - else if (cdrom_drives[e].host_drive >= 65) - { - CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); - } - else - { - CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); - } - } - #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); @@ -1407,9 +1520,10 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } } - - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); + for (c = 0; c < GFX_MAX; c++) + { + gfx_present[c] = video_card_available(video_old_to_new(c)); + } if (!video_card_available(video_old_to_new(gfxcard))) { @@ -1439,8 +1553,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, ghMutex = CreateMutex(NULL, FALSE, NULL); mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); - - + updatewindowsize(640, 480); QueryPerformanceFrequency(&qpc_freq); @@ -1501,9 +1614,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, mousecapture=0; } - if ((recv_key[0x1D] || recv_key[0x9D]) && - (recv_key[0x38] || recv_key[0xB8]) && - (recv_key[0x51] || recv_key[0xD1]) && + if ((recv_key[0x1D] || recv_key[0x9D]) && (recv_key[0x38] || recv_key[0xB8]) && (recv_key[0x51] || recv_key[0xD1]) && video_fullscreen) { leave_fullscreen(); @@ -1538,13 +1649,15 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HHOOK hKeyboardHook; int hook_enabled = 0; -LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { BOOL bControlKeyDown; KBDLLHOOKSTRUCT* p; - if (nCode < 0 || nCode != HC_ACTION) - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + if (nCode < 0 || nCode != HC_ACTION) + { + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + } p = (KBDLLHOOKSTRUCT*)lParam; @@ -1574,136 +1687,6 @@ void cdrom_close(uint8_t id) } } -int ide_ter_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[2] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[2] = irq; - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int ide_qua_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[3] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[3] = irq; - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -void video_toggle_option(HMENU hmenu, int *val, int id) -{ - *val ^= 1; - CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); -} - -void win_cdrom_eject(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - if (cdrom_drives[id].host_drive == 0) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - cdrom_drives[id].handler->exit(id); - cdrom_close(id); - cdrom_null_open(id, 0); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); - if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_drives[id].host_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - -void win_cdrom_reload(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - int new_cdrom_drive; - if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - cdrom_close(id); - if (cdrom_drives[id].prev_host_drive == 200) - { - image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); - } - else - { - new_cdrom_drive = cdrom_drives[id].prev_host_drive; - ioctl_open(id, new_cdrom_drive); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); - } - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; @@ -1734,520 +1717,464 @@ static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA void about_open(HWND hwnd) { - DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); + DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); +} + +static void win_pc_reset(int hard) +{ + pause=1; + Sleep(100); + savenvr(); + saveconfig(); + if (hard) + { + resetpchard(); + } + else + { + resetpc_cad(); + } + pause=0; +} + +void video_toggle_option(HMENU hmenu, int *val, int id) +{ + startblit(); + video_wait_for_blit(); + *val ^= 1; + CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); + endblit(); + saveconfig(); + device_force_redraw(); } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - HMENU hmenu; - RECT rect; - uint32_t ri_size = 0; - int edgex, edgey; - int sb_borders[3]; + HMENU hmenu; + RECT rect; - switch (message) - { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - break; - - case WM_COMMAND: - hmenu=GetMenu(hwnd); - switch (LOWORD(wParam)) - { - case IDM_FILE_HRESET: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpchard(); - pause=0; - break; - case IDM_FILE_RESET_CAD: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpc_cad(); - pause=0; - break; - case IDM_FILE_EXIT: - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - case IDM_CONFIG: - win_settings_open(hwnd); - break; - case IDM_ABOUT: - about_open(hwnd); + switch (message) + { + case WM_CREATE: + SetTimer(hwnd, TIMER_1SEC, 1000, NULL); + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; break; - case IDM_STATUS: - status_open(hwnd); - break; - - case IDM_VID_RESIZE: - vid_resize=!vid_resize; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); - if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)|WS_VISIBLE); - else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); - GetWindowRect(hwnd,&rect); - SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - GetWindowRect(hwndStatus,&rect); - SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - if (vid_resize) + + case WM_COMMAND: + hmenu=GetMenu(hwnd); + switch (LOWORD(wParam)) { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - win_doresize = 1; - saveconfig(); - break; - case IDM_VID_REMEMBER: - window_remember = !window_remember; - CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); - if (window_remember) - { - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - } - saveconfig(); - break; + case IDM_FILE_HRESET: + win_pc_reset(1); + break; - case IDM_VID_DDRAW: case IDM_VID_D3D: - startblit(); - video_wait_for_blit(); - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); - vid_apis[0][vid_api].close(); - vid_api = LOWORD(wParam) - IDM_VID_DDRAW; - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - vid_apis[0][vid_api].init(hwndRender); - endblit(); - saveconfig(); - device_force_redraw(); - break; + case IDM_FILE_RESET_CAD: + win_pc_reset(0); + break; - case IDM_VID_FULLSCREEN: - - if(video_fullscreen!=1){ - - if (video_fullscreen_first) - { - video_fullscreen_first = 0; - msgbox_info(ghwnd, 2193); - } - startblit(); - video_wait_for_blit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(ghwnd); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - } - break; + case IDM_FILE_EXIT: + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; - case IDM_VID_FS_FULL: - case IDM_VID_FS_43: - case IDM_VID_FS_SQ: - case IDM_VID_FS_INT: - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); - video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - saveconfig(); - break; + case IDM_CONFIG: + win_settings_open(hwnd); + break; - case IDM_VID_SCALE_1X: - case IDM_VID_SCALE_2X: - case IDM_VID_SCALE_3X: - case IDM_VID_SCALE_4X: - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - scale = LOWORD(wParam) - IDM_VID_SCALE_1X; - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - saveconfig(); - break; + case IDM_ABOUT: + about_open(hwnd); + break; - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - break; + case IDM_STATUS: + status_open(hwnd); + break; - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - break; + case IDM_VID_RESIZE: + vid_resize = !vid_resize; + CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)? MF_CHECKED : MF_UNCHECKED); + if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_MINIMIZEBOX) | WS_VISIBLE); + else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX) | WS_VISIBLE); + GetWindowRect(hwnd, &rect); + SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + GetWindowRect(hwndStatus,&rect); + SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + if (vid_resize) + { + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + } + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + win_doresize = 1; + saveconfig(); + break; - case IDM_VID_OVERSCAN: - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - update_overscan = 1; - break; + case IDM_VID_REMEMBER: + window_remember = !window_remember; + CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); + GetWindowRect(hwnd, &rect); + if (window_remember) + { + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + } + saveconfig(); + break; - case IDM_VID_FLASH: - video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); - break; + case IDM_VID_DDRAW: + case IDM_VID_D3D: + startblit(); + video_wait_for_blit(); + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); + vid_apis[0][vid_api].close(); + vid_api = LOWORD(wParam) - IDM_VID_DDRAW; + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); + vid_apis[0][vid_api].init(hwndRender); + endblit(); + saveconfig(); + device_force_redraw(); + break; - case IDM_VID_SCREENSHOT: - take_screenshot(); - break; + case IDM_VID_FULLSCREEN: + if(video_fullscreen != 1) + { + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + msgbox_info(ghwnd, 2193); + } + + startblit(); + video_wait_for_blit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(ghwnd); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + saveconfig(); + device_force_redraw(); + } + break; + + case IDM_VID_FS_FULL: + case IDM_VID_FS_43: + case IDM_VID_FS_SQ: + case IDM_VID_FS_INT: + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); + video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); + saveconfig(); + device_force_redraw(); + break; + + case IDM_VID_SCALE_1X: + case IDM_VID_SCALE_2X: + case IDM_VID_SCALE_3X: + case IDM_VID_SCALE_4X: + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + scale = LOWORD(wParam) - IDM_VID_SCALE_1X; + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + saveconfig(); + device_force_redraw(); + break; + + case IDM_VID_FORCE43: + video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); + break; + + case IDM_VID_INVERT: + video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); + break; + + case IDM_VID_OVERSCAN: + update_overscan = 1; + video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); + break; + + case IDM_VID_SCREENSHOT: + take_screenshot(); + break; #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG - case IDM_LOG_BUSLOGIC: - buslogic_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_BUSLOGIC: + buslogic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_CDROM_LOG - case IDM_LOG_CDROM: - cdrom_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_CDROM: + cdrom_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_D86F_LOG - case IDM_LOG_D86F: - d86f_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_D86F: + d86f_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_FDC_LOG - case IDM_LOG_FDC: - fdc_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_FDC: + fdc_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_IDE_LOG - case IDM_LOG_IDE: - ide_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_IDE: + ide_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_NE2000_LOG - case IDM_LOG_NE2000: - ne2000_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_NE2000: + ne2000_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #endif #ifdef ENABLE_LOG_BREAKPOINT - case IDM_LOG_BREAKPOINT: - pclog("---- LOG BREAKPOINT ----\n"); - break; + case IDM_LOG_BREAKPOINT: + pclog("---- LOG BREAKPOINT ----\n"); + break; #endif #ifdef ENABLE_VRAM_DUMP - case IDM_DUMP_VRAM: - svga_dump_vram(); - break; + case IDM_DUMP_VRAM: + svga_dump_vram(); + break; #endif - case IDM_CONFIG_LOAD: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 0)) - { - if (msgbox_reset_yn(ghwnd) == IDYES) - { - config_save(config_file_default); - loadconfig(wopenfilestring); - pclog_w(L"NVR path: %s\n", nvr_path); - mem_resize(); - loadbios(); - resetpchard(); - } - } - pause = 0; - break; - - case IDM_CONFIG_SAVE: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 1)) - config_save(wopenfilestring); - pause = 0; - break; - } - return 0; - - case WM_INPUT: - { - UINT size; - RAWINPUT *raw; - - if (!infocus) - break; - - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - - raw = malloc(size); - - if (raw == NULL) - { - return 0; - } - - /* Here we read the raw input data for the keyboard */ - ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); - - if(ri_size != size) - { - return 0; - } - - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) - { - const RAWKEYBOARD rawKB = raw->data.keyboard; - USHORT scancode = rawKB.MakeCode; - - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) - { - if (rawKB.Flags & RI_KEY_E0) - scancode |= (0xE0 << 8); - - /* Remap it according to the list from the Registry */ - scancode = scancode_map[scancode]; - - if ((scancode >> 8) == 0xF0) - scancode |= 0x100; /* Extended key code in disambiguated format */ - else if ((scancode >> 8) == 0xE0) - scancode |= 0x80; /* Normal extended key code */ - - /* If it's not 0 (therefore not 0xE1, 0xE2, etc), - then pass it on to the rawinputkey array */ - if (!(scancode & 0xf00)) + case IDM_CONFIG_LOAD: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 0)) { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + if (msgbox_reset_yn(ghwnd) == IDYES) + { + config_save(config_file_default); + loadconfig(wopenfilestring); + /* pclog_w(L"NVR path: %s\n", nvr_path); */ + mem_resize(); + loadbios(); + resetpchard(); + } } - } - else - { - if (rawKB.MakeCode == 0x1D) - scancode = 0xFF; - if (!(scancode & 0xf00)) + pause = 0; + break; + + case IDM_CONFIG_SAVE: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 1)) { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + config_save(wopenfilestring); + } + pause = 0; + break; + } + return 0; + + case WM_INPUT: + process_raw_input(lParam, infocus); + break; + + case WM_SETFOCUS: + infocus=1; + if (!hook_enabled) + { + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: + infocus=0; + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture=0; + } + memset(recv_key, 0, sizeof(recv_key)); + if (video_fullscreen) + { + leave_fullscreen_flag = 1; + } + if (hook_enabled) + { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; + + case WM_LBUTTONUP: + if (!mousecapture && !video_fullscreen) + { + GetClipCursor(&oldclip); + GetWindowRect(hwnd, &rect); + rect.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.right = GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 20; + rect.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + ClipCursor(&rect); + mousecapture = 1; + while (1) + { + if (ShowCursor(FALSE) < 0) + { + break; } } - } - free(raw); + } + break; - } - break; + case WM_MBUTTONUP: + if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + { + releasemouse(); + } + break; - case WM_SETFOCUS: - infocus=1; - if (!hook_enabled) - { - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - } - break; + case WM_ENTERMENULOOP: + break; - case WM_KILLFOCUS: - infocus=0; - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - memset(rawinputkey, 0, sizeof(rawinputkey)); - if (video_fullscreen) - leave_fullscreen_flag = 1; - if (hook_enabled) - { + case WM_SIZE: + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) + { + startblit(); + video_wait_for_blit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + endblit(); + } + + MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); + + if (mousecapture) + { + GetWindowRect(hwnd, &rect); + rect.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 20; + rect.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + ClipCursor(&rect); + } + + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_MOVE: + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_TIMER: + if (wParam == TIMER_1SEC) + { + onesec(); + } + break; + + case WM_RESETD3D: + startblit(); + if (video_fullscreen) + { + d3d_fs_reset(); + } + else + { + d3d_reset(); + } + endblit(); + break; + + case WM_LEAVEFULLSCREEN: + startblit(); + mouse_close(); + vid_apis[1][vid_api].close(); + video_fullscreen = 0; + vid_apis[0][vid_api].init(hwndRender); + mouse_init(); + endblit(); + device_force_redraw(); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + return 0; + + case WM_DESTROY: UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } - break; + KillTimer(hwnd, TIMER_1SEC); + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; - case WM_LBUTTONUP: - if (!mousecapture && !video_fullscreen) - { - RECT pcclip; + case WM_SYSCOMMAND: + /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) + { + return 0; /*disable ALT key for menu*/ + } - GetClipCursor(&oldclip); - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - mousecapture = 1; - while (1) - { - if (ShowCursor(FALSE) < 0) break; - } - } - break; - - case WM_MBUTTONUP: - if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - releasemouse(); - break; - - case WM_ENTERMENULOOP: - break; - - case WM_SIZE: - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) - { - startblit(); - video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } - - MoveWindow(hwndStatus, 0, winsizey + 6, - winsizex, - 17, - TRUE); - - if (mousecapture) - { - RECT pcclip; - - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - } - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_MOVE: - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_TIMER: - if (wParam == TIMER_1SEC) - onesec(); - break; - - case WM_RESETD3D: - startblit(); - if (video_fullscreen) - d3d_fs_reset(); - else - d3d_reset(); - endblit(); - break; - - case WM_LEAVEFULLSCREEN: - startblit(); - mouse_close(); - vid_apis[1][vid_api].close(); - video_fullscreen = 0; - vid_apis[0][vid_api].init(ghwnd); - mouse_init(); - endblit(); - device_force_redraw(); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - return 0; - - case WM_DESTROY: - UnhookWindowsHookEx( hKeyboardHook ); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - - case WM_SYSCOMMAND: - /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) - return 0; /*disable ALT key for menu*/ - - default: - return DefWindowProc (hwnd, message, wParam, lParam); - } - return 0; + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } + return 0; } LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) - { - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; + switch (message) + { + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; } VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) { - HMENU pmenu; - int menu_id = -1; if (id >= (sb_parts - 1)) { return; } - pt.x = id * sb_icon_width; /* Justify to the left. */ + pt.x = id * SB_ICON_WIDTH; /* Justify to the left. */ pt.y = 0; /* Justify to the top. */ ClientToScreen(hwnd, (LPPOINT) &pt); - if ((sb_part_meanings[id] & 0xf0) == 0x00) - { - menu_id = sb_part_meanings[id] & 0xf; - } - else if ((sb_part_meanings[id] & 0xf0) == 0x10) - { - menu_id = (sb_part_meanings[id] & 0xf) + 4; - } -#if 0 - else if ((sb_part_meanings[id] & 0xf0) == 0x20) - { - menu_id = (sb_part_meanings[id] & 0xf) + 8; - } -#endif - if (menu_id != -1) - { - pmenu = GetSubMenu(smenu, menu_id); - TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); - } + TrackPopupMenu(sb_menu_handles[id], TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); } LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -2257,211 +2184,212 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR WCHAR temp_image_path[1024]; int new_cdrom_drive; - int cdrom_id = 0; - int menu_sub_param = 0; - int menu_super_param = 0; int ret = 0; + int item_id = 0; + int item_params = 0; + int id = 0; + int part = 0; + int letter = 0; - HMENU hmenu; + HMENU hmenu; - switch (message) - { + switch (message) + { case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDM_DISC_1: - case IDM_DISC_1_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); - if (!ret) - { - disc_close(0); - ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, wopenfilestring); - update_status_bar_icon_state(0x00, 0); - update_tip(0x00); - saveconfig(); - } - break; - case IDM_DISC_2: - case IDM_DISC_2_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); - if (!ret) - { - disc_close(1); - ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, wopenfilestring); - update_status_bar_icon_state(0x01, 0); - update_tip(0x01); - saveconfig(); - } - break; - case IDM_DISC_3: - case IDM_DISC_3_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); - if (!ret) - { - disc_close(2); - ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, wopenfilestring); - update_status_bar_icon_state(0x02, 0); - update_tip(0x02); - saveconfig(); - } - break; - case IDM_DISC_4: - case IDM_DISC_4_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); - if (!ret) - { - disc_close(3); - ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, wopenfilestring); - update_status_bar_icon_state(0x03, 0); - update_tip(0x03); - saveconfig(); - } - break; - case IDM_EJECT_1: - disc_close(0); - update_status_bar_icon_state(0x00, 1); - update_tip(0x00); - saveconfig(); - break; - case IDM_EJECT_2: - disc_close(1); - update_status_bar_icon_state(0x01, 1); - update_tip(0x01); - saveconfig(); - break; - case IDM_EJECT_3: - disc_close(2); - update_status_bar_icon_state(0x02, 1); - update_tip(0x02); - saveconfig(); - break; - case IDM_EJECT_4: - disc_close(3); - update_status_bar_icon_state(0x03, 1); - update_tip(0x03); - saveconfig(); - break; + item_id = LOWORD(wParam) & 0xff00; /* Mask out the low 8 bits for item ID. */ + item_params = LOWORD(wParam) & 0x00ff; /* Mask out the high 8 bits for item parameter. */ - case IDM_CDROM_1_MUTE: - case IDM_CDROM_2_MUTE: - case IDM_CDROM_3_MUTE: - case IDM_CDROM_4_MUTE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - Sleep(100); - cdrom_drives[cdrom_id].sound_on ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); - saveconfig(); - sound_cd_thread_reset(); - break; + switch (item_id) + { + case IDM_FLOPPY_IMAGE_EXISTING: + case IDM_FLOPPY_IMAGE_EXISTING_WP: + id = item_params & 0x0003; + part = find_status_bar_part(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } - case IDM_CDROM_1_EMPTY: - case IDM_CDROM_2_EMPTY: - case IDM_CDROM_3_EMPTY: - case IDM_CDROM_4_EMPTY: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_eject(cdrom_id); - break; - - case IDM_CDROM_1_RELOAD: - case IDM_CDROM_2_RELOAD: - case IDM_CDROM_3_RELOAD: - case IDM_CDROM_4_RELOAD: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_reload(cdrom_id); - break; - - case IDM_CDROM_1_IMAGE: - case IDM_CDROM_2_IMAGE: - case IDM_CDROM_3_IMAGE: - case IDM_CDROM_4_IMAGE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) - { - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - wcscpy(temp_image_path, wopenfilestring); - if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) - { - /* Switching from image to the same image. Do nothing. */ + ret = file_dlg_w_st(hwnd, 2173, discfns[id], id); + if (!ret) + { + disc_close(id); + ui_writeprot[id] = (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0; + disc_load(id, wopenfilestring); + update_status_bar_icon_state(SB_FLOPPY | id, wcslen(discfns[id]) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(discfns[id]) ? MF_ENABLED : MF_GRAYED)); + update_tip(SB_FLOPPY | id); + saveconfig(); + } break; - } - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - image_open(cdrom_id, temp_image_path); - if (cdrom_drives[cdrom_id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - default: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; - /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ - if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) - { - new_cdrom_drive = menu_sub_param; - if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) - { - /* Switching to the same drive. Do nothing. */ + case IDM_FLOPPY_EJECT: + id = item_params & 0x0003; + part = find_status_bar_part(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + disc_close(id); + update_status_bar_icon_state(SB_FLOPPY | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_FLOPPY | id); + saveconfig(); break; - } - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - ioctl_open(cdrom_id, new_cdrom_drive); - if (cdrom_drives[cdrom_id].bus_type) - { + + case IDM_CDROM_MUTE: + id = item_params & 0x0007; + hmenu = GetSubMenu(smenu, id + 4); + Sleep(100); + cdrom_drives[id].sound_on ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_MUTE | id, cdrom_drives[id].sound_on ? MF_UNCHECKED : MF_CHECKED); + saveconfig(); + sound_cd_thread_reset(); + break; + + case IDM_CDROM_EMPTY: + id = item_params & 0x0007; + cdrom_eject(id); + break; + + case IDM_CDROM_RELOAD: + id = item_params & 0x0007; + cdrom_reload(id); + break; + + case IDM_CDROM_IMAGE: + id = item_params & 0x0007; + part = find_status_bar_part(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[id].image_path, 0)) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[id].image_path, temp_image_path) == 0) && (cdrom_drives[id].host_drive == 200)) + { + /* Switching from image to the same image. Do nothing. */ + break; + } + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + image_open(id, temp_image_path); + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_UNCHECKED); + } + cdrom_drives[id].host_drive = 200; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + update_tip(SB_CDROM | id); + saveconfig(); + } + break; + + case IDM_CDROM_HOST_DRIVE: + id = item_params & 0x0007; + letter = ((item_params >> 3) & 0x001f) + 'A'; + part = find_status_bar_part(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + new_cdrom_drive = letter; + if (cdrom_drives[id].host_drive == new_cdrom_drive) + { + /* Switching to the same drive. Do nothing. */ + break; + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + ioctl_open(id, new_cdrom_drive); /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); - cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - } - return 0; + cdrom_insert(id); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_UNCHECKED); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_CDROM | id); + saveconfig(); + break; + + case IDM_RDISK_EJECT: + id = item_params & 0x001f; + removable_disk_eject(id); + break; + + case IDM_RDISK_RELOAD: + id = item_params & 0x001f; + removable_disk_reload(id); + break; + + case IDM_RDISK_SEND_CHANGE: + id = item_params & 0x001f; + scsi_disk_insert(id); + break; + + case IDM_RDISK_IMAGE: + case IDM_RDISK_IMAGE_WP: + id = item_params & 0x001f; + ret = file_dlg_w_st(hwnd, 2172, hdc[id].fn, id); + if (!ret) + { + removable_disk_unload(id); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + wcscpy(hdc[id].fn, wopenfilestring); + hdc[id].wp = (item_id == IDM_RDISK_IMAGE_WP) ? 1 : 0; + scsi_loadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id); + scsi_disk_insert(id); + if (wcslen(hdc[id].fn) > 0) + { + update_status_bar_icon_state(SB_RDISK | id, 0); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_ENABLED); + } + else + { + update_status_bar_icon_state(SB_RDISK | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); + } + update_tip(SB_RDISK | id); + saveconfig(); + } + break; + + default: + break; + } + return 0; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: - GetClientRect(hwnd, (LPRECT)& rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect((LPRECT) &rc, pt)) - { - HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); - } - break; + GetClientRect(hwnd, (LPRECT)& rc); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + if (PtInRect((LPRECT) &rc, pt)) + { + HandlePopupMenu(hwnd, pt, (pt.x / SB_ICON_WIDTH)); + } + break; default: - return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); - } - return 0; + return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); + } + return 0; } diff --git a/src/WIN/win.h b/src/WIN/win.h index 1d4feec57..f36b487e5 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -8,14 +8,15 @@ */ #ifndef BOX_WIN_H # define BOX_WIN_H + # ifndef NO_UNICODE # define UNICODE # endif # define BITMAP WINDOWS_BITMAP -//# ifdef _WIN32_WINNT -//# undef _WIN32_WINNT -//# define _WIN32_WINNT 0x0501 -//# endif +/* # ifdef _WIN32_WINNT + # undef _WIN32_WINNT + # define _WIN32_WINNT 0x0501 + # endif */ # include # undef BITMAP @@ -25,6 +26,14 @@ #define szStatusBarClassName L"86BoxStatusBar" +#define WM_RESETD3D WM_USER +#define WM_LEAVEFULLSCREEN WM_USER + 1 + +#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + +#define SB_ICON_WIDTH 24 + + extern HINSTANCE hinstance; extern HWND ghwnd; extern HWND status_hwnd; @@ -37,6 +46,9 @@ extern WCHAR wopenfilestring[260]; extern int pause; +extern HMENU smenu; +extern HMENU *sb_menu_handles; + #ifdef __cplusplus extern "C" { @@ -66,6 +78,15 @@ extern void update_status_bar_panes(HWND hwnds); extern int fdd_type_to_icon(int type); extern void hard_disk_add_open(HWND hwnd, int is_existing); +extern int hard_disk_was_added(void); + +extern void get_registry_key_map(void); +extern void process_raw_input(LPARAM lParam, int infocus); + +extern int find_status_bar_part(int tag); + +extern void cdrom_close(uint8_t id); +extern void update_tip(int meaning); #ifdef __cplusplus } diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index c64dd3af7..1cfa026eb 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -42,7 +42,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id++; break; - + case CONFIG_SELECTION: val_int = config_get_int(config_device->name, config->name, config->default_int); @@ -58,6 +58,38 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + + case CONFIG_HEX16: + val_int = config_get_hex16(config_device->name, config->name, config->default_int); + + c = 0; + while (selection->description[0]) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); + if (val_int == selection->value) + SendMessage(h, CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; + + case CONFIG_HEX20: + val_int = config_get_hex20(config_device->name, config->name, config->default_int); + + c = 0; + while (selection->description[0]) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); + if (val_int == selection->value) + SendMessage(h, CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; } config++; } @@ -89,7 +121,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id++; break; - + case CONFIG_SELECTION: val_int = config_get_int(config_device->name, config->name, config->default_int); @@ -103,6 +135,34 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + + case CONFIG_HEX16: + val_int = config_get_hex16(config_device->name, config->name, config->default_int); + + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; + + case CONFIG_HEX20: + val_int = config_get_hex20(config_device->name, config->name, config->default_int); + + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; } config++; } @@ -134,7 +194,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id++; break; - + case CONFIG_SELECTION: c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) @@ -143,6 +203,24 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + + case CONFIG_HEX16: + c = SendMessage(h, CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_hex16(config_device->name, config->name, selection->value); + + id += 2; + break; + + case CONFIG_HEX20: + c = SendMessage(h, CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_hex20(config_device->name, config->name, selection->value); + + id += 2; + break; } config++; } @@ -219,6 +297,8 @@ void deviceconfig_open(HWND hwnd, device_t *device) break; case CONFIG_SELECTION: + case CONFIG_HEX16: + case CONFIG_HEX20: /*Combo box*/ item = (DLGITEMTEMPLATE *)data; item->x = 70; diff --git a/src/WIN/win_iodev.c b/src/WIN/win_iodev.c new file mode 100644 index 000000000..a008aab8d --- /dev/null +++ b/src/WIN/win_iodev.c @@ -0,0 +1,171 @@ +#define UNICODE +#define _WIN32_WINNT 0x0501 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ibm.h" +#include "../device.h" +#include "../cdrom.h" +#include "../cdrom_image.h" +#include "../cdrom_ioctl.h" +#include "../cdrom_null.h" +#include "../scsi_disk.h" +#include "plat_iodev.h" +#include "resource.h" +#include "win.h" + +void cdrom_eject(uint8_t id) +{ + int part; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + if (cdrom_drives[id].host_drive == 0) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + cdrom_null_open(id, 0); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drive << 3), MF_UNCHECKED); + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].host_drive=0; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED); + update_status_bar_icon_state(SB_CDROM | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); + update_tip(SB_CDROM | id); + saveconfig(); +} + +void cdrom_reload(uint8_t id) +{ + int part; + int new_cdrom_drive; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + cdrom_close(id); + if (cdrom_drives[id].prev_host_drive == 200) + { + image_open(id, cdrom_image[id].image_path); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + } + else + { + new_cdrom_drive = cdrom_drives[id].prev_host_drive; + ioctl_open(id, new_cdrom_drive); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + } + update_status_bar_icon_state(SB_CDROM | id, 0); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_CDROM | id); + saveconfig(); +} + +void removable_disk_unload(uint8_t id) +{ + if (wcslen(hdc[id].fn) == 0) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + scsi_unloadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id); + scsi_disk_insert(id); +} + +void removable_disk_eject(uint8_t id) +{ + int part = 0; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + removable_disk_unload(id); + update_status_bar_icon_state(SB_RDISK | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_RDISK | id); + saveconfig(); +} + +void removable_disk_reload(uint8_t id) +{ + int part = 0; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + if (wcslen(hdc[id].fn) != 0) + { + /* Attempting to reload while an image is already loaded. Do nothing. */ + return; + } + scsi_reloadhd(id); + /* scsi_disk_insert(id); */ + update_status_bar_icon_state(SB_RDISK | id, wcslen(hdc[id].fn) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED)); + update_tip(SB_RDISK | id); + saveconfig(); +} + diff --git a/src/WIN/win_keyboard.c b/src/WIN/win_keyboard.c new file mode 100644 index 000000000..89b4f6639 --- /dev/null +++ b/src/WIN/win_keyboard.c @@ -0,0 +1,195 @@ +#define UNICODE +#define _WIN32_WINNT 0x0501 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../device.h" +#include "plat_keyboard.h" + +#include "win.h" + +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#endif + +static uint16_t scancode_map[65536]; + +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +UINT16 convert_scan_code(UINT16 scan_code) +{ + switch (scan_code) + { + case 0xE001: + return 0xF001; + case 0xE002: + return 0xF002; + case 0xE0AA: + return 0xF003; + case 0xE005: + return 0xF005; + case 0xE006: + return 0xF006; + case 0xE007: + return 0xF007; + case 0xE071: + return 0xF008; + case 0xE072: + return 0xF009; + case 0xE07F: + return 0xF00A; + case 0xE0E1: + return 0xF00B; + case 0xE0EE: + return 0xF00C; + case 0xE0F1: + return 0xF00D; + case 0xE0FE: + return 0xF00E; + case 0xE0EF: + return 0xF00F; + + default: + return scan_code; + } +} + +void get_registry_key_map() +{ + WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + WCHAR *valueName = L"Scancode Map"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; + + /* First, prepare the default scan code map list which is 1:1. + Remappings will be inserted directly into it. + 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, + since each array element is a scan code and provides for E0, etc. ones too. */ + for (j = 0; j < 65536; j++) + scancode_map[j] = convert_scan_code(j); + + bufSize = 32768; + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) + { + if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) + { + bufEx2 = (UINT32 *) buf; + scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) + { + bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount*2; j += 2) + { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + scancode_unmapped = bufEx[j + 1]; + scancode_mapped = bufEx[j]; + + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Fixes scan code map logging. */ + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +void process_raw_input(LPARAM lParam, int infocus) +{ + uint32_t ri_size = 0; + UINT size; + RAWINPUT *raw; + USHORT scancode; + + if (!infocus) + { + return; + } + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + + raw = malloc(size); + + if (raw == NULL) + { + return; + } + + /* Here we read the raw input data for the keyboard */ + ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); + + if(ri_size != size) + { + return; + } + + /* If the input is keyboard, we process it */ + if (raw->header.dwType == RIM_TYPEKEYBOARD) + { + RAWKEYBOARD rawKB = raw->data.keyboard; + scancode = rawKB.MakeCode; + + /* If it's not a scan code that starts with 0xE1 */ + if (!(rawKB.Flags & RI_KEY_E1)) + { + if (rawKB.Flags & RI_KEY_E0) + { + scancode |= (0xE0 << 8); + } + + /* Remap it according to the list from the Registry */ + scancode = scancode_map[scancode]; + + if ((scancode >> 8) == 0xF0) + { + scancode |= 0x100; /* Extended key code in disambiguated format */ + } + else if ((scancode >> 8) == 0xE0) + { + scancode |= 0x80; /* Normal extended key code */ + } + + /* If it's not 0 (therefore not 0xE1, 0xE2, etc), + then pass it on to the rawinputkey array */ + if (!(scancode & 0xf00)) + { + recv_key[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + } + } + else + { + if (rawKB.MakeCode == 0x1D) + { + scancode = 0xFF; + } + if (!(scancode & 0xf00)) + { + recv_key[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + } + } + } + + free(raw); +} \ No newline at end of file diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index 7159f46c4..d7e78ac14 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -21,8 +21,6 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -#define STRINGS_NUM 157 /* FIXME: should be in resource.h !! --FvK */ - WCHAR lpResourceString[STRINGS_NUM][512]; char openfilestring[260]; diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc index f64b714a0..9a6f50e80 100644 --- a/src/WIN/win_mouse.cc +++ b/src/WIN/win_mouse.cc @@ -3,6 +3,7 @@ */ #define DIRECTINPUT_VERSION 0x0800 #include +#include #include "plat_mouse.h" #include "win.h" diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index db4f7da46..f586e6526 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -35,9 +35,6 @@ #include "resource.h" -#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ - - /* Machine category */ static int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; @@ -62,7 +59,6 @@ static char temp_hdc_name[16]; /* Hard disks category */ static hard_disk_t temp_hdc[HDC_NUM]; -static wchar_t temp_hdd_fn[HDC_NUM][512]; /* Removable devices category */ static int temp_fdd_types[FDD_NUM]; @@ -134,10 +130,6 @@ static void win_settings_init(void) /* Hard disks category */ memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); - } /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -199,10 +191,6 @@ static int win_settings_changed(void) /* Hard disks category */ i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (j = 0; j < HDC_NUM; j++) - { - i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); - } /* Removable devices category */ for (j = 0; j < FDD_NUM; j++) @@ -298,10 +286,6 @@ static void win_settings_save(void) /* Hard disks category */ memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); - } /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -687,11 +671,8 @@ static void recalc_vid_list(HWND hdlg) static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; - int c = 0; - int d = 0; LPTSTR lptsTemp; char *stransi; - char *s; int gfx = 0; switch (message) @@ -1499,7 +1480,6 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w int c = 0; int d = 0; LPTSTR lptsTemp; - device_t *scsi_dev; switch (message) { @@ -1652,13 +1632,17 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); - for (i = 0; i < 8; i += 2) + for (i = 0; i < 16; i += 2) { - hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); + hiconItem = LoadIcon(hinstance, (LPCWSTR) (192 + i)); ImageList_AddIcon(hSmall, hiconItem); DestroyIcon(hiconItem); } + hiconItem = LoadIcon(hinstance, (LPCWSTR) 176); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); return TRUE; @@ -1666,8 +1650,6 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) int next_free_id = 0; -wchar_t ifn[HDC_NUM][512]; - static void normalize_hd_list() { hard_disk_t ihdc[HDC_NUM]; @@ -1675,25 +1657,17 @@ static void normalize_hd_list() j = 0; memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) { - memset(ifn[i], 0, 1024); - } - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus > 0) + if (temp_hdc[i].bus != HDD_BUS_DISABLED) { memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); - memcpy(ifn[j], temp_hdd_fn[i], 1024); j++; } } memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], ifn[i], 1024); - } } int hdc_id_to_listview_index[HDC_NUM]; @@ -1734,6 +1708,11 @@ static void add_locations(HWND hdlg) { SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); } + for (i = 0; i < 2; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2209 + i)); + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2202)); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); for (i = 0; i < 8; i++) @@ -1800,10 +1779,11 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) { h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); bus = SendMessage(h, CB_GETCURSEL, 0, 0); + bus++; switch(bus) { - case 0: /* MFM/RLL */ + case HDD_BUS_MFM: /* MFM */ h = GetDlgItem(hdlg, 1799); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1813,8 +1793,28 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); break; - case 1: /* IDE (PIO-only) */ - case 2: /* IDE (PIO and DMA) */ + case HDD_BUS_RLL: /* RLL */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0); + break; + case HDD_BUS_XTIDE: /* XT IDE */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.xtide_channel : temp_hdc[hdlv_current_sel].xtide_channel, 0); + break; + case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */ + case HDD_BUS_IDE_PIO_AND_DMA: /* IDE (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1824,7 +1824,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); break; - case 3: /* SCSI */ + case HDD_BUS_SCSI: /* SCSI */ + case HDD_BUS_SCSI_REMOVABLE: /* SCSI (removable) */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1872,6 +1873,8 @@ static void recalc_next_free_id(HWND hdlg) int i; int c_mfm = 0; + int c_rll = 0; + int c_xtide = 0; int c_ide_pio = 0; int c_ide_dma = 0; int c_scsi = 0; @@ -1881,19 +1884,31 @@ static void recalc_next_free_id(HWND hdlg) for (i = 0; i < HDC_NUM; i++) { - if (temp_hdc[i].bus == 1) + if (temp_hdc[i].bus == HDD_BUS_MFM) { c_mfm++; } - else if (temp_hdc[i].bus == 2) + else if (temp_hdc[i].bus == HDD_BUS_RLL) + { + c_rll++; + } + else if (temp_hdc[i].bus == HDD_BUS_XTIDE) + { + c_xtide++; + } + else if (temp_hdc[i].bus == HDD_BUS_IDE_PIO_ONLY) { c_ide_pio++; } - else if (temp_hdc[i].bus == 3) + else if (temp_hdc[i].bus == HDD_BUS_IDE_PIO_AND_DMA) { c_ide_dma++; } - else if (temp_hdc[i].bus == 4) + else if (temp_hdc[i].bus == HDD_BUS_SCSI) + { + c_scsi++; + } + else if (temp_hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) { c_scsi++; } @@ -1901,7 +1916,7 @@ static void recalc_next_free_id(HWND hdlg) for (i = 0; i < HDC_NUM; i++) { - if (temp_hdc[i].bus == 0) + if (temp_hdc[i].bus == HDD_BUS_DISABLED) { next_free_id = i; break; @@ -1912,7 +1927,7 @@ static void recalc_next_free_id(HWND hdlg) enable_add = enable_add || (next_free_id >= 0); /* pclog("Enable add: %i\n", enable_add); */ - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_rll < RLL_NUM) || (c_xtide < XTIDE_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); /* pclog("Enable add: %i\n", enable_add); */ h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); @@ -1964,25 +1979,34 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column { switch(temp_hdc[i].bus) { - case 1: + case HDD_BUS_MFM: wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; - case 2: + case HDD_BUS_RLL: + wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); + break; + case HDD_BUS_XTIDE: + wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + break; + case HDD_BUS_IDE_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 3: + case HDD_BUS_IDE_PIO_AND_DMA: wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 4: + case HDD_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; + case HDD_BUS_SCSI_REMOVABLE: + wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; } lvI.pszText = szText; lvI.iImage = temp_hdc[i].bus - 1; } else if (column == 1) { - lvI.pszText = temp_hdd_fn[i]; + lvI.pszText = temp_hdc[i].fn; lvI.iImage = 0; } else if (column == 2) @@ -2039,18 +2063,27 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) lvI.iSubItem = 0; switch(temp_hdc[i].bus) { - case 1: + case HDD_BUS_MFM: wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; - case 2: + case HDD_BUS_RLL: + wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); + break; + case HDD_BUS_XTIDE: + wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + break; + case HDD_BUS_IDE_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 3: + case HDD_BUS_IDE_PIO_AND_DMA: wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 4: + case HDD_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; + case HDD_BUS_SCSI_REMOVABLE: + wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; } lvI.pszText = szText; lvI.iItem = j; @@ -2062,7 +2095,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 1; - lvI.pszText = temp_hdd_fn[i]; + lvI.pszText = temp_hdc[i].fn; lvI.iItem = j; lvI.iImage = 0; @@ -2210,6 +2243,8 @@ static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) int hard_disk_added = 0; int max_spt = 63; +int max_hpc = 255; +int max_tracks = 266305; int no_update = 0; @@ -2270,13 +2305,13 @@ static void recalc_selection(HWND hdlg) SendMessage(h, CB_SETCURSEL, selection, 0); } +static int chs_enabled = 0; + static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; int64_t i = 0; - int bus; uint64_t temp; - WCHAR szText[256]; FILE *f; uint32_t sector_size = 512; uint32_t zero = 0; @@ -2287,13 +2322,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W switch (message) { case WM_INITDIALOG: - memset(hd_file_name, 0, 512); - - hdc_ptr = (existing & 2) ? hdc : temp_hdc; + memset(hd_file_name, 0, sizeof(hd_file_name)); if (existing & 2) { - next_free_id = (existing & 0xf0) >> 4; + next_free_id = (existing >> 3) & 0x1f; + hdc_ptr = &(hdc[next_free_id]); + } + else + { + hdc_ptr = &(temp_hdc[next_free_id]); } SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? 2197 : 2196)); @@ -2320,19 +2358,64 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W EnableWindow(h, FALSE); h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); EnableWindow(h, FALSE); + chs_enabled = 0; + } + else + { + chs_enabled = 1; } add_locations(hdlg); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, 1, 0); + if (existing & 2) + { + hdc_ptr->bus = HDD_BUS_SCSI_REMOVABLE; + max_spt = 99; + max_hpc = 255; + } + else + { + hdc_ptr->bus = HDD_BUS_IDE_PIO_ONLY; + max_spt = 63; + max_hpc = 16; + } + SendMessage(h, CB_SETCURSEL, hdc_ptr->bus, 0); + max_tracks = 266305; recalc_location_controls(hdlg, 1); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, 0, 0); + if (existing & 2) + { + /* We're functioning as a load image dialog for a removable SCSI hard disk, + called from win.c, so let's hide the bus selection as we should not + allow it at this point. */ + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, 1798); + ShowWindow(h, SW_HIDE); + + /* Disable and hide the SCSI ID and LUN combo boxes. */ + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + /* Set the file name edit box contents to our existing parameters. */ + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) hdc[next_free_id].fn); + } + else + { + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); EnableWindow(h, FALSE); no_update = 0; @@ -2342,47 +2425,77 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W switch (LOWORD(wParam)) { case IDOK: - if (wcslen(hd_file_name) == 0) + if (!(existing & 2)) { + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + hdc_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + } + + /* Make sure no file name is allowed with removable SCSI hard disks. */ + if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE)) + { + hdc_ptr->bus = HDD_BUS_DISABLED; msgbox_error(hwndParentDialog, 2056); return TRUE; } + else if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE)) + { + /* Mark hard disk added but return empty - it will signify the disk was ejected. */ + hdc_ptr->spt = hdc_ptr->hpc = hdc_ptr->tracks = 0; + memset(hdc_ptr->fn, 0, sizeof(hdc_ptr->fn)); + + goto hd_add_ok_common; + } + + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdc_ptr->spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdc_ptr->hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdc_ptr->tracks)); + spt = hdc_ptr->spt; + hpc = hdc_ptr->hpc; + tracks = hdc_ptr->tracks; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdc_ptr[next_free_id].spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdc_ptr[next_free_id].hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdc_ptr[next_free_id].tracks)); - spt = hdc_ptr[next_free_id].spt; - hpc = hdc_ptr[next_free_id].hpc; - tracks = hdc_ptr[next_free_id].tracks; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdc_ptr[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdc_ptr[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hdc_ptr[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hdc_ptr[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hdc_ptr[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); if (existing & 2) { -#if 0 - if (hdc[next_free_id].bus == 5) + if (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE) { - memset(prev_hdd_fn[next_free_id], 0, 1024); - memcpy(prev_hdd_fn[next_free_id], hdd_fn[next_free_id], (wcslen(hdd_fn[next_free_id]) << 1) + 2); + memset(hdc_ptr->prev_fn, 0, sizeof(hdc_ptr->prev_fn)); + wcscpy(hdc_ptr->prev_fn, hdc_ptr->fn); } -#endif - - memset(hdd_fn[next_free_id], 0, 1024); - memcpy(hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); } else { - memset(temp_hdd_fn[next_free_id], 0, 1024); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + switch(hdc_ptr->bus) + { + case HDD_BUS_MFM: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdc_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_RLL: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdc_ptr->rll_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_XTIDE: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdc_ptr->xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + hdc_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_SCSI: + case HDD_BUS_SCSI_REMOVABLE: + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + hdc_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + hdc_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + } } + memset(hdc_ptr->fn, 0, sizeof(hdc_ptr->fn)); + wcscpy(hdc_ptr->fn, hd_file_name); + sector_size = 512; if (!(existing & 1) && (wcslen(hd_file_name) > 0)) @@ -2442,27 +2555,24 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W msgbox_info(hwndParentDialog, 2059); } -#if 0 - if ((existing & 2) && (hdc[next_free_id].bus == 5)) - { - scsi_hd_insert(id); - update_status_bar_icon_state(0x20 | next_free_id, 0); - } -#endif - +hd_add_ok_common: hard_disk_added = 1; EndDialog(hdlg, 0); return TRUE; case IDCANCEL: hard_disk_added = 0; + if (!(existing & 2)) + { + hdc_ptr->bus = HDD_BUS_DISABLED; + } EndDialog(hdlg, 0); return TRUE; case IDC_CFILE: if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !(existing & 1))) { - if (!existing) + if (!(existing & 1)) { f = _wfopen(wopenfilestring, L"rb"); if (f != NULL) @@ -2478,6 +2588,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); if (f == NULL) { +hdd_add_file_open_error: msgbox_error(hwndParentDialog, (existing & 1) ? 2060 : 2057); return TRUE; } @@ -2532,6 +2643,10 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W tracks = ((size >> 9) / hpc) / spt; } + if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) + { + goto hdd_add_file_open_error; + } no_update = 1; set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); @@ -2551,6 +2666,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); EnableWindow(h, TRUE); + chs_enabled = 1; + no_update = 0; } else @@ -2561,7 +2678,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); + memset(hd_file_name, 0, sizeof(hd_file_name)); + wcscpy(hd_file_name, wopenfilestring); return TRUE; @@ -2580,6 +2698,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2598,6 +2726,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); } + + if (hpc > max_hpc) + { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2616,6 +2754,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); } + + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2634,6 +2782,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); recalc_selection(hdlg); } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2671,6 +2829,34 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); } + + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + + if (hpc > max_hpc) + { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2683,17 +2869,114 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W no_update = 1; recalc_location_controls(hdlg, 1); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); - max_spt = (bus == 2) ? 99 : 63; + hdc_ptr->bus = SendMessage(h,CB_GETCURSEL,0,0) + 1; + + switch(hdc_ptr->bus) + { + case HDD_BUS_DISABLED: + default: + max_spt = max_hpc = max_tracks = 0; + break; + case HDD_BUS_MFM: + max_spt = 17; + max_hpc = 15; + max_tracks = 1023; + break; + case HDD_BUS_RLL: + case HDD_BUS_XTIDE: + max_spt = 63; + max_hpc = 16; + max_tracks = 1023; + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + max_spt = 63; + max_hpc = 16; + max_tracks = 266305; + break; + case HDD_BUS_SCSI_REMOVABLE: + if (spt == 0) + { + spt = 63; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + } + if (hpc == 0) + { + hpc = 16; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + } + if (tracks == 0) + { + tracks = 1023; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + } + case HDD_BUS_SCSI: + max_spt = 99; + max_hpc = 255; + max_tracks = 266305; + break; + } + + if ((hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, TRUE); + } + else if ((hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + } + if (spt > max_spt) { spt = max_spt; size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); recalc_selection(hdlg); } + + if (hpc > max_hpc) + { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; } @@ -2704,6 +2987,11 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W return FALSE; } +int hard_disk_was_added(void) +{ + return hard_disk_added; +} + void hard_disk_add_open(HWND hwnd, int is_existing) { BOOL ret; @@ -2806,7 +3094,18 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_MFM) + { + temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + } + else if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_RLL) + { + temp_hdc[hdlv_current_sel].rll_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + } + else if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_XTIDE) + { + temp_hdc[hdlv_current_sel].xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + } h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -2879,8 +3178,8 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA return FALSE; case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); - temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + memcpy(temp_hdc[hdlv_current_sel].fn, L"", 4); + temp_hdc[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ ignore_change = 1; h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); @@ -2916,17 +3215,17 @@ static int combo_id_to_string_id(int combo_id) { switch (combo_id) { - case 0: /* Disabled */ + case CDROM_BUS_DISABLED: /* Disabled */ default: return 2151; break; - case 2: /* Atapi (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */ return 2189; break; - case 3: /* Atapi (PIA and DMA) */ + case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */ return 2190; break; - case 4: /* SCSI */ + case CDROM_BUS_SCSI: /* SCSI */ return 2168; break; } @@ -2936,17 +3235,17 @@ static int combo_id_to_format_string_id(int combo_id) { switch (combo_id) { - case 0: /* Disabled */ + case CDROM_BUS_DISABLED: /* Disabled */ default: return 2151; break; - case 2: /* Atapi (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */ return 2191; break; - case 3: /* Atapi (PIA and DMA) */ + case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */ return 2192; break; - case 4: /* SCSI */ + case CDROM_BUS_SCSI: /* SCSI */ return 2158; break; } @@ -2980,9 +3279,6 @@ static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) HICON hiconItem; HIMAGELIST hSmall; - int i = 0; - int j = 0; - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); @@ -3044,9 +3340,7 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) { LVITEM lvI; int i = 0; - char s[256]; WCHAR szText[256]; - int bid = 0; int fsid = 0; lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; @@ -3058,32 +3352,30 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) switch (temp_cdrom_drives[i].bus_type) { - case 0: + case CDROM_BUS_DISABLED: default: lvI.pszText = win_language_get_string_from_id(fsid); + lvI.iImage = 0; break; - case 2: - case 3: + case CDROM_BUS_ATAPI_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); lvI.pszText = szText; + lvI.iImage = 1; break; - case 4: + case CDROM_BUS_ATAPI_PIO_AND_DMA: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + lvI.iImage = 2; + break; + case CDROM_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); lvI.pszText = szText; + lvI.iImage = 3; break; } lvI.iItem = i; - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; } @@ -3202,9 +3494,7 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) { LVITEM lvI; - char s[256]; WCHAR szText[256]; - int bid; int fsid; lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; @@ -3217,30 +3507,28 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) switch (temp_cdrom_drives[i].bus_type) { - case 0: + case CDROM_BUS_DISABLED: default: lvI.pszText = win_language_get_string_from_id(fsid); + lvI.iImage = 0; break; - case 2: - case 3: + case CDROM_BUS_ATAPI_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); lvI.pszText = szText; + lvI.iImage = 1; break; - case 4: + case CDROM_BUS_ATAPI_PIO_AND_DMA: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + lvI.iImage = 2; + break; + case CDROM_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); lvI.pszText = szText; + lvI.iImage = 3; break; } - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - if (ListView_SetItem(hwndList, &lvI) == -1) { return; @@ -3256,9 +3544,12 @@ static void cdrom_add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = 1; i < 5; i++) + for (i = CDROM_BUS_DISABLED; i < CDROM_BUS_SCSI; i++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI_PIO_ONLY)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + } } h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); @@ -3312,8 +3603,8 @@ static void cdrom_recalc_location_controls(HWND hdlg) switch(bus) { - case 2: /* ATAPI (PIO-only) */ - case 3: /* ATAPI (PIO and DMA) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* ATAPI (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_AND_DMA: /* ATAPI (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3323,7 +3614,7 @@ static void cdrom_recalc_location_controls(HWND hdlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); break; - case 4: /* SCSI */ + case CDROM_BUS_SCSI: /* SCSI */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3352,7 +3643,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message HWND h; int i = 0; int old_sel = 0; - int cid = 0; + int b = 0; WCHAR szText[256]; switch (message) @@ -3388,15 +3679,28 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message win_settings_cdrom_drives_recalc_list(h); ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); cdrom_add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + + switch (temp_cdrom_drives[cdlv_current_sel].bus_type) { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type - 1, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); + case CDROM_BUS_DISABLED: + default: + b = 0; + break; + case CDROM_BUS_ATAPI_PIO_ONLY: + b = 1; + break; + case CDROM_BUS_ATAPI_PIO_AND_DMA: + b = 2; + break; + case CDROM_BUS_SCSI: + b = 3; + break; } + + SendMessage(h, CB_SETCURSEL, b, 0); + cdrom_recalc_location_controls(hdlg); rd_ignore_change = 0; @@ -3446,15 +3750,28 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message return FALSE; } rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + + switch (temp_cdrom_drives[cdlv_current_sel].bus_type) { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type - 1, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); + case CDROM_BUS_DISABLED: + default: + b = 0; + break; + case CDROM_BUS_ATAPI_PIO_ONLY: + b = 1; + break; + case CDROM_BUS_ATAPI_PIO_AND_DMA: + b = 2; + break; + case CDROM_BUS_SCSI: + b = 3; + break; } + + SendMessage(h, CB_SETCURSEL, b, 0); + cdrom_recalc_location_controls(hdlg); rd_ignore_change = 0; } @@ -3485,10 +3802,21 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) + b = SendMessage(h, CB_GETCURSEL, 0, 0); + switch (b) { - temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + case 0: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_DISABLED; + break; + case 1: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_ATAPI_PIO_ONLY; + break; + case 2: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_ATAPI_PIO_AND_DMA; + break; + case 3: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_SCSI; + break; } cdrom_recalc_location_controls(hdlg); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); diff --git a/src/cdrom.c b/src/cdrom.c index 6540846ba..10c811f7d 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -13,6 +13,7 @@ #include "piix.h" #include "scsi.h" #include "timer.h" +#include "WIN/plat_iodev.h" /* Bits of 'status' */ #define ERR_STAT 0x01 @@ -732,7 +733,7 @@ int find_cdrom_for_channel(uint8_t channel) for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type < 4) && (cdrom_drives[i].ide_channel == channel)) + if (((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) && (cdrom_drives[i].ide_channel == channel)) { return i; } @@ -764,7 +765,7 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type == 4) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) + if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) { return i; } @@ -833,16 +834,16 @@ void cdrom_init(int id, int cdb_len_setting) cdrom[id].sense[0] = 0xf0; cdrom[id].sense[7] = 10; cdrom_drives[id].bus_mode = 0; - if (cdrom_drives[id].bus_type > 2) + if (cdrom_drives[id].bus_type > CDROM_BUS_ATAPI_PIO_AND_DMA) { cdrom_drives[id].bus_mode |= 2; } - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { cdrom_drives[id].bus_mode |= 1; } cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode); - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { cdrom_set_signature(id); cdrom_drives[id].max_blocks_at_once = 1; @@ -1076,7 +1077,7 @@ int cdrom_mode_select_header(uint8_t id, uint8_t val) } else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 2)) { - if ((cdrom_drives[id].bus_type == 4) && (cdrom[id].current_page_len == 8)) + if ((cdrom_drives[id].bus_type == CDROM_BUS_SCSI) && (cdrom[id].current_page_len == 8)) { cdrom[id].block_descriptor_len |= ((uint16_t) val) << 8; cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); @@ -1084,7 +1085,7 @@ int cdrom_mode_select_header(uint8_t id, uint8_t val) } else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 1)) { - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { cdrom[id].block_descriptor_len |= (uint16_t) val; cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); @@ -1470,7 +1471,7 @@ static void cdrom_command_write_dma(uint8_t id) static int cdrom_request_length_is_zero(uint8_t id) { - if ((cdrom[id].request_length == 0) && (cdrom_drives[id].bus_type < 4)) + if ((cdrom[id].request_length == 0) && (cdrom_drives[id].bus_type < CDROM_BUS_SCSI)) { return 1; } @@ -1490,7 +1491,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0)) { - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0; } @@ -1506,7 +1507,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (direction == 0) { - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; } @@ -2063,7 +2064,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { int ready = 0; - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { @@ -2075,20 +2076,20 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], (cdrom_drives[id].bus_type == 4) ? "SCSI" : ((cdrom_drives[id].bus_type == 3) ? "ATAPI PIO/DMA" : "ATAPI PIO")); + cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? "SCSI" : ((cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) ? "ATAPI PIO/DMA" : "ATAPI PIO")); cdrom_illegal_opcode(id); return 0; } - if ((cdrom_drives[id].bus_type < 4) && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) + if ((cdrom_drives[id].bus_type < CDROM_BUS_SCSI) && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", id, cdb[0]); cdrom_illegal_opcode(id); return 0; } - if ((cdrom_drives[id].bus_type == 4) && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) + if ((cdrom_drives[id].bus_type == CDROM_BUS_SCSI) && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", id, cdb[0]); cdrom_illegal_opcode(id); @@ -2297,13 +2298,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) int ret; int real_pos; int track = 0; - char device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; - char device_identify_ex[14] = { '8', '6', 'B', '_', 'C', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; #if 0 int CdbLength; #endif - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { cdrom[id].status &= ~ERR_STAT; } @@ -2315,12 +2316,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].packet_len = 0; cdrom[id].request_pos = 0; - device_identify[6] = id + 0x30; + device_identify[7] = id + 0x30; - device_identify_ex[6] = id + 0x30; - device_identify_ex[9] = emulator_version[0]; - device_identify_ex[11] = emulator_version[2]; - device_identify_ex[12] = emulator_version[3]; + device_identify_ex[7] = id + 0x30; + device_identify_ex[10] = emulator_version[0]; + device_identify_ex[12] = emulator_version[2]; + device_identify_ex[13] = emulator_version[3]; cdrom[id].data_pos = 0; @@ -2501,7 +2502,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } max_len = cdrom[id].sector_len; - /* if (cdrom_drives[id].bus_type == 4) */ + /* if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) */ if (cdrom_current_mode(id) == 2) { cdrom[id].requested_blocks = max_len; @@ -2529,11 +2530,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].all_blocks_total = cdrom[id].block_total; if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x10 | id, 1); + update_status_bar_icon(SB_CDROM | id, 1); } else { - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); } return; @@ -2573,7 +2574,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; } @@ -3116,16 +3117,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { cdrom_drives[id].handler->stop(id); } -#ifndef __unix - win_cdrom_eject(id); -#endif + cdrom_eject(id); break; case 3: /* Load the disc (close tray). */ -#ifndef __unix - win_cdrom_reload(id); -#else - cdrom_drives[id].handler->load(id); -#endif + cdrom_reload(id); break; } @@ -3197,8 +3192,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) memset(cdbufferb, 0, 8); cdbufferb[0] = 5; /*CD-ROM*/ cdbufferb[1] = 0x80; /*Removable*/ - cdbufferb[2] = (cdrom_drives[id].bus_type == 4) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - cdbufferb[3] = (cdrom_drives[id].bus_type == 4) ? 0x02 : 0x21; + cdbufferb[2] = (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + cdbufferb[3] = (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? 0x02 : 0x21; cdbufferb[4] = 31; ide_padstr8(cdbufferb + 8, 8, "86Box"); /* Vendor */ @@ -3352,7 +3347,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ { int old_pos = 0; - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); @@ -3478,7 +3473,7 @@ int cdrom_read_from_dma(uint8_t id) int in_data_length = 0; - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } @@ -3492,7 +3487,7 @@ int cdrom_read_from_dma(uint8_t id) return 0; } - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { in_data_length = SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength; cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length); @@ -3598,7 +3593,7 @@ int cdrom_write_to_dma(uint8_t id) { int ret = 0; - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } @@ -3617,7 +3612,7 @@ int cdrom_write_to_dma(uint8_t id) void cdrom_irq_raise(uint8_t id) { - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); } @@ -3645,7 +3640,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].status = READY_STAT; cdrom[id].phase = 3; cdrom[id].packet_status = 0xFF; - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT: @@ -3660,7 +3655,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_IN: @@ -3675,7 +3670,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_ERROR: diff --git a/src/cdrom.h b/src/cdrom.h index 63470c36f..5e167fe35 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -237,6 +237,8 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); void cdrom_insert(uint8_t id); +int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); + #define cdrom_sense_error cdrom[id].sense[0] #define cdrom_sense_key cdrom[id].sense[2] #define cdrom_asc cdrom[id].sense[12] diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index 53223a775..eadd5541b 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -18,6 +18,11 @@ /* Modified for use with PCem by bit */ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include + #include #include #include @@ -46,8 +51,8 @@ using namespace std; CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { - file = new ifstream(filename, ios::in | ios::binary); - error = (file == NULL) || (file->fail()); + file = fopen64(filename, "rb"); + error = (file == NULL); } CDROM_Interface_Image::BinaryFile::~BinaryFile() @@ -57,17 +62,17 @@ CDROM_Interface_Image::BinaryFile::~BinaryFile() bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) { - file->seekg(seek, ios::beg); - file->read((char*)buffer, count); - return !(file->fail()); + uint64_t offs = 0; + offs = ftello64(file); + fseeko64(file, offs, SEEK_SET); + offs = fread(buffer, 1, count, file); + return (offs == count); } -int CDROM_Interface_Image::BinaryFile::getLength() +uint64_t CDROM_Interface_Image::BinaryFile::getLength() { - file->seekg(0, ios::end); - int length = (int)file->tellg(); - if (file->fail()) return -1; - return length; + fseeko64(file, 0, SEEK_END); + return ftello64(file); } CDROM_Interface_Image::CDROM_Interface_Image() @@ -286,7 +291,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) { Track track = {0, 0, 0, 0, 0, 0, false, NULL}; tracks.clear(); - int shift = 0; + uint64_t shift = 0; int currPregap = 0; int totalPregap = 0; int prestart = 0; @@ -405,7 +410,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) return true; } -bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap) { // frames between index 0(prestart) and 1(curr.start) must be skipped int skip; @@ -429,14 +434,14 @@ bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int // current track consumes data from the same file as the previous if (prev.file == curr.file) { curr.start += shift; - prev.length = curr.start + totalPregap - prev.start - skip; + prev.length = curr.start + ((uint64_t) totalPregap) - prev.start - ((uint64_t) skip); curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; totalPregap += currPregap; curr.start += totalPregap; // current track uses a different file as the previous track } else { - int tmp = prev.file->getLength() - prev.skip; - prev.length = tmp / prev.sectorSize; + uint64_t tmp = prev.file->getLength() - ((uint64_t) prev.skip); + prev.length = tmp / ((uint64_t) prev.sectorSize); if (tmp % prev.sectorSize != 0) prev.length++; // padding curr.start += prev.start + prev.length + currPregap; diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index 39ed79bed..b545269f5 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -104,7 +104,7 @@ private: class TrackFile { public: virtual bool read(Bit8u *buffer, int seek, int count) = 0; - virtual int getLength() = 0; + virtual uint64_t getLength() = 0; virtual ~TrackFile() { }; }; @@ -113,10 +113,10 @@ private: BinaryFile(const char *filename, bool &error); ~BinaryFile(); bool read(Bit8u *buffer, int seek, int count); - int getLength(); + uint64_t getLength(); private: BinaryFile(); - std::ifstream *file; + FILE *file; }; struct Track { @@ -163,7 +163,7 @@ static void CDAudioCallBack(Bitu len); bool GetCueKeyword(std::string &keyword, std::istream &in); bool GetCueFrame(int &frames, std::istream &in); bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + bool AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap); std::vector tracks; typedef std::vector::iterator track_it; diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 6c14bf2c2..c941315cd 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -935,6 +935,7 @@ static int image_status(uint8_t id) void image_reset(uint8_t id) { + return; } void image_close(uint8_t id) diff --git a/src/config.c b/src/config.c index 26e65cfe6..4ac4837f1 100644 --- a/src/config.c +++ b/src/config.c @@ -6,6 +6,7 @@ #include #include #include + #include "cdrom.h" #include "config.h" #include "device.h" @@ -22,14 +23,15 @@ #include "network.h" #include "nvr.h" #include "scsi.h" -#include "plat_joystick.h" -#include "plat_midi.h" +#include "win/plat_joystick.h" +#include "win/plat_midi.h" #include "sound/snd_dbopl.h" #include "sound/snd_opl.h" #include "sound/sound.h" #include "video/video.h" -#include "win.h" -#include "win_language.h" + +#include "win/win.h" +#include "win/win_language.h" wchar_t config_file_default[256]; @@ -269,6 +271,26 @@ static entry_t *find_entry(section_t *section, char *name) } +static int entries_num(section_t *section) +{ + entry_t *current_entry; + int i = 0; + + current_entry = (entry_t *)section->entry_head.next; + + while (current_entry) + { + if (strlen(current_entry->name) > 0) + { + i++; + } + + current_entry = (entry_t *)current_entry->list.next; + } + return i; +} + + static section_t *create_section(char *name) { section_t *new_section = malloc(sizeof(section_t)); @@ -336,6 +358,50 @@ int config_get_hex16(char *head, char *name, int def) } +int config_get_hex20(char *head, char *name, int def) +{ + section_t *section; + entry_t *entry; + int value; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + sscanf(entry->data, "%05X", &value); + + return value; +} + + +int config_get_mac(char *head, char *name, int def) +{ + section_t *section; + entry_t *entry; + int val0 = 0, val1 = 0, val2 = 0; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + sscanf(entry->data, "%02x:%02x:%02x", &val0, &val1, &val2); + + return (val0 << 16) + (val1 << 8) + val2; +} + + char *config_get_string(char *head, char *name, char *def) { section_t *section; @@ -374,6 +440,46 @@ wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) } +void config_delete_var(char *head, char *name) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + return; + + entry = find_entry(section, name); + + if (!entry) + return; + + memset(entry->name, 0, strlen(entry->name)); + + return; +} + + +void config_delete_section_if_empty(char *head) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + return; + + if (entries_num(section) == 0) + { + memset(section->name, 0, strlen(section->name)); + } + + return; +} + + void config_set_int(char *head, char *name, int val) { section_t *section; @@ -414,6 +520,46 @@ void config_set_hex16(char *head, char *name, int val) } +void config_set_hex20(char *head, char *name, int val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + sprintf(entry->data, "%05X", val); + mbstowcs(entry->wdata, entry->data, 512); +} + + +void config_set_mac(char *head, char *name, int val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + sprintf(entry->data, "%02x:%02x:%02x", (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff); + mbstowcs(entry->wdata, entry->data, 512); +} + + void config_set_string(char *head, char *name, char *val) { section_t *section; @@ -575,16 +721,20 @@ void config_save(wchar_t *fn) while (current_entry) { - mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); - if (current_entry->wdata[0] == L'\0') + if(strlen(current_entry->name) > 0) { - fwprintf(f, L"%ws = \n", wname); + mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); + if (current_entry->wdata[0] == L'\0') + { + fwprintf(f, L"%ws = \n", wname); + } + else + { + fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); + } + + fl++; } - else - { - fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); - } - fl++; current_entry = (entry_t *)current_entry->list.next; } @@ -597,6 +747,8 @@ void config_save(wchar_t *fn) +static wchar_t *read_nvr_path; + /* General */ static void loadconfig_general(void) { @@ -622,35 +774,62 @@ static void loadconfig_general(void) vid_api = 1; } + config_delete_var(cat, "vid_api"); + video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); force_43 = !!config_get_int(cat, "force_43", 0); - scale = !!config_get_int(cat, "scale", 1); + scale = config_get_int(cat, "scale", 1); + if (scale > 3) + { + scale = 3; + } enable_overscan = !!config_get_int(cat, "enable_overscan", 0); - p = config_get_string(cat, "window_coordinates", NULL); - if (p == NULL) - p = "0, 0, 0, 0"; - sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); window_remember = config_get_int(cat, "window_remember", 0); + if (window_remember) + { + p = config_get_string(cat, "window_coordinates", NULL); + if (p == NULL) + p = "0, 0, 0, 0"; + sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); + } + else + { + config_delete_var(cat, "window_remember"); + config_delete_var(cat, "window_coordinates"); + window_w = window_h = window_x = window_y = 0; + } + + if (read_nvr_path != NULL) + { + free(read_nvr_path); + read_nvr_path = NULL; + } + memset(nvr_path, 0x00, sizeof(nvr_path)); wp = config_get_wstring(cat, "nvr_path", L""); if (wp != NULL) { - if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); + if (wcslen(wp) && (wcslen(wp) <= 992)) + { + read_nvr_path = (wchar_t *) malloc((wcslen(wp) << 1) + 2); + wcscpy(read_nvr_path, wp); + wcscpy(nvr_path, wp); + } else { - append_filename_w(nvr_path, pcempath, L"nvr", 511); + append_filename_w(nvr_path, pcempath, L"nvr\\", 511); } } - else append_filename_w(nvr_path, pcempath, L"nvr", 511); + else append_filename_w(nvr_path, pcempath, L"nvr\\", 511); if (nvr_path[wcslen(nvr_path) - 1] != L'/') { if (nvr_path[wcslen(nvr_path) - 1] != L'\\') { - nvr_path[wcslen(nvr_path)] = L'/'; + nvr_path[wcslen(nvr_path)] = L'\\'; nvr_path[wcslen(nvr_path) + 1] = L'\0'; } } @@ -732,7 +911,7 @@ static void loadconfig_input_devices(void) else mouse_type = 0; - joystick_type = config_get_int(cat, "joystick_type", 0); + joystick_type = config_get_int(cat, "joystick_type", 7); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { @@ -767,6 +946,7 @@ static void loadconfig_input_devices(void) static void loadconfig_sound(void) { char *cat = "Sound"; + char temps[512]; char *p; p = config_get_string(cat, "sndcard", NULL); @@ -780,7 +960,21 @@ static void loadconfig_sound(void) SSI2001 = !!config_get_int(cat, "ssi2001", 0); GAMEBLASTER = !!config_get_int(cat, "gameblaster", 0); GUS = !!config_get_int(cat, "gus", 0); - opl3_type = !!config_get_int(cat, "opl3_type", 1); + + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "opl3_type", "dbopl"); + if (p != NULL) + { + strcpy(temps, p); + } + if (!strcmp(temps, "nukedopl")) + { + opl3_type = 1; + } + else + { + opl3_type = 0; + } } @@ -788,9 +982,28 @@ static void loadconfig_sound(void) static void loadconfig_network(void) { char *cat = "Network"; + char temps[512]; char *p; - network_type = config_get_int(cat, "net_type", NET_TYPE_NONE); + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "net_type", "none"); + if (p != NULL) + { + strcpy(temps, p); + } + if (!strcmp(temps, "slirp")) + { + network_type = NET_TYPE_SLIRP; + } + else if (!strcmp(temps, "pcap")) + { + network_type = NET_TYPE_PCAP; + } + else + { + network_type = NET_TYPE_NONE; + } + memset(network_pcap, '\0', sizeof(network_pcap)); p = config_get_string(cat, "net_pcap_device", "none"); if (p != NULL) @@ -863,63 +1076,99 @@ static int config_string_to_bus(char *str, int cdrom) { if (!strcmp(str, "none")) { - return 0; + return HDD_BUS_DISABLED; } if (!strcmp(str, "mfm")) { if (cdrom) goto no_mfm_cdrom; - return 1; + return HDD_BUS_MFM; } if (!strcmp(str, "rll")) { if (cdrom) goto no_mfm_cdrom; - return 1; + return HDD_BUS_RLL; } if (!strcmp(str, "esdi")) { if (cdrom) goto no_mfm_cdrom; - return 1; + return HDD_BUS_RLL; } if (!strcmp(str, "ide_pio_only")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "ide")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; + } + + if (!strcmp(str, "atapi_pio_only")) + { + return HDD_BUS_IDE_PIO_ONLY; + } + + if (!strcmp(str, "atapi")) + { + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "eide")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "xtide")) { - return 2; + return HDD_BUS_XTIDE; } if (!strcmp(str, "atide")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "ide_pio_and_dma")) { - return 3; + return HDD_BUS_IDE_PIO_AND_DMA; + } + + if (!strcmp(str, "atapi_pio_and_dma")) + { + return HDD_BUS_IDE_PIO_AND_DMA; } if (!strcmp(str, "scsi")) { - return 4; + return HDD_BUS_SCSI; + } + + if (!strcmp(str, "removable")) + { + if (cdrom) goto no_mfm_cdrom; + + return HDD_BUS_SCSI_REMOVABLE; + } + + if (!strcmp(str, "scsi_removable")) + { + if (cdrom) goto no_mfm_cdrom; + + return HDD_BUS_SCSI_REMOVABLE; + } + + if (!strcmp(str, "removable_scsi")) + { + if (cdrom) goto no_mfm_cdrom; + + return HDD_BUS_SCSI_REMOVABLE; } if (!strcmp(str, "usb")) @@ -936,6 +1185,27 @@ no_mfm_cdrom: } +static int hard_disk_is_valid(int c) +{ + if (hdc[c].bus == HDD_BUS_DISABLED) + { + return 0; + } + + if ((wcslen(hdc[c].fn) == 0) && (hdc[c].bus != HDD_BUS_SCSI_REMOVABLE)) + { + return 0; + } + + if ((hdc[c].tracks == 0) || (hdc[c].hpc == 0) || (hdc[c].spt == 0)) + { + return 0; + } + + return 1; +} + + /* Hard disks */ static void loadconfig_hard_disks(void) { @@ -946,6 +1216,8 @@ static void loadconfig_hard_disks(void) int c; char *p; wchar_t *wp; + int max_spt, max_hpc, max_tracks; + int board = 0, dev = 0; memset(temps, '\0', sizeof(temps)); for (c = 0; c < HDC_NUM; c++) @@ -953,56 +1225,162 @@ static void loadconfig_hard_disks(void) sprintf(temps, "hdd_%02i_parameters", c + 1); p = config_get_string(cat, temps, NULL); if (p == NULL) - p = "0, 0, 0, none"; - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); + p = "0, 0, 0, 0, none"; + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, &hdc[c].wp, s); hdc[c].bus = config_string_to_bus(s, 0); - if (hdc[c].spt > 99) + switch(hdc[c].bus) { - hdc[c].spt = 99; + case HDD_BUS_DISABLED: + default: + max_spt = max_hpc = max_tracks = 0; + break; + case HDD_BUS_MFM: + max_spt = 17; + max_hpc = 15; + max_tracks = 1023; + break; + case HDD_BUS_RLL: + case HDD_BUS_XTIDE: + max_spt = 63; + max_hpc = 16; + max_tracks = 1023; + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + max_spt = 63; + max_hpc = 16; + max_tracks = 266305; + break; + case HDD_BUS_SCSI: + case HDD_BUS_SCSI_REMOVABLE: + max_spt = 99; + max_hpc = 255; + max_tracks = 266305; + break; } - if (hdc[c].hpc > 255) + + if (hdc[c].spt > max_spt) { - hdc[c].hpc = 255; + hdc[c].spt = max_spt; } - if (hdc[c].tracks > 266305) + if (hdc[c].hpc > max_hpc) { - hdc[c].tracks = 266305; + hdc[c].hpc = max_hpc; + } + if (hdc[c].tracks > max_tracks) + { + hdc[c].tracks = max_tracks; + } + + /* MFM */ + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + if (hdc[c].bus == HDD_BUS_MFM) + { + hdc[c].mfm_channel = !!config_get_int(cat, temps, c & 1); + } + else + { + config_delete_var(cat, temps); + } + + /* XT IDE */ + sprintf(temps, "hdd_%02i_xtide_channel", c + 1); + if (hdc[c].bus == HDD_BUS_XTIDE) + { + hdc[c].xtide_channel = !!config_get_int(cat, temps, c & 1); + } + else + { + config_delete_var(cat, temps); + } + + /* RLL (ESDI) */ + sprintf(temps, "hdd_%02i_rll_channel", c + 1); + if (hdc[c].bus == HDD_BUS_RLL) + { + hdc[c].rll_channel = !!config_get_int(cat, temps, c & 1); + } + else + { + config_delete_var(cat, temps); + } + + /* IDE */ + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + if ((hdc[c].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[c].bus == HDD_BUS_IDE_PIO_AND_DMA)) + { + sprintf(temps2, "%01u:%01u", c >> 1, c & 1); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%01u:%01u", &board, &dev); + + board &= 3; + dev %= 1; + hdc[c].ide_channel = (board << 1) + dev; + + if (hdc[c].ide_channel > 7) + { + hdc[c].ide_channel = 7; + } + } + else + { + config_delete_var(cat, temps); + } + + /* SCSI */ + sprintf(temps, "hdd_%02i_scsi_location", c + 1); + if ((hdc[c].bus == HDD_BUS_SCSI) || (hdc[c].bus == HDD_BUS_SCSI_REMOVABLE)) + { + sprintf(temps2, "%02u:%02u", c, 0); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); + + if (hdc[c].scsi_id > 15) + { + hdc[c].scsi_id = 15; + } + if (hdc[c].scsi_lun > 7) + { + hdc[c].scsi_lun = 7; + } + } + else + { + config_delete_var(cat, temps); + } + + memset(hdc[c].fn, 0, sizeof(hdc[c].fn)); + memset(hdc[c].prev_fn, 0, sizeof(hdc[c].prev_fn)); + sprintf(temps, "hdd_%02i_fn", c + 1); + wp = config_get_wstring(cat, temps, L""); + memcpy(hdc[c].fn, wp, (wcslen(wp) << 1) + 2); + + /* If the hard disk is in any way empty or invalid, mark the relevant variables for deletion. */ + if (!hard_disk_is_valid(c)) + { + sprintf(temps, "hdd_%02i_parameters", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_preide_channels", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_ide_channels", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_scsi_location", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_fn", c + 1); + config_delete_var(cat, temps); } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int(cat, temps, 0); - if (hdc[c].mfm_channel > 1) - { - hdc[c].mfm_channel = 1; - } + config_delete_var(cat, temps); sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int(cat, temps, 0); - if (hdc[c].ide_channel > 7) - { - hdc[c].ide_channel = 7; - } - - sprintf(temps, "hdd_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", c, 0); - p = config_get_string(cat, temps, temps2); - sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); - - if (hdc[c].scsi_id > 15) - { - hdc[c].scsi_id = 15; - } - if (hdc[c].scsi_lun > 7) - { - hdc[c].scsi_lun = 7; - } - - memset(hdd_fn[c], 0, 1024); - sprintf(temps, "hdd_%02i_fn", c + 1); - wp = config_get_wstring(cat, temps, L""); - memcpy(hdd_fn[c], wp, (wcslen(wp) << 1) + 2); + config_delete_var(cat, temps); } } @@ -1017,6 +1395,7 @@ static void loadconfig_removable_devices(void) int c; char *p; wchar_t *wp; + unsigned int board = 0, dev = 0; for (c = 0; c < FDD_NUM; c++) { @@ -1034,6 +1413,25 @@ static void loadconfig_removable_devices(void) printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); ui_writeprot[c] = !!config_get_int(cat, temps, 0); + + /* Check, whether each value is default, if yes, delete it so that only non-default values will later be saved. */ + if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_delete_var(cat, temps); + } + + if (wcslen(discfns[c]) == 0) + { + sprintf(temps, "fdd_%02i_fn", c + 1); + config_delete_var(cat, temps); + } + + if (ui_writeprot[c] == 0) + { + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_delete_var(cat, temps); + } } memset(temps, 0, 512); @@ -1057,29 +1455,77 @@ static void loadconfig_removable_devices(void) cdrom_drives[c].bus_type = config_string_to_bus(s, 1); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int(cat, temps, c + 2); - if (cdrom_drives[c].ide_channel > 7) + if ((cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { - cdrom_drives[c].ide_channel = 7; + sprintf(temps2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &board, &dev); + + board &= 3; + dev %= 1; + cdrom_drives[c].ide_channel = (board << 1) + dev; + + if (cdrom_drives[c].ide_channel > 7) + { + cdrom_drives[c].ide_channel = 7; + } + } + else + { + config_delete_var(cat, temps); } sprintf(temps, "cdrom_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", c + 2, 0); - p = config_get_string(cat, temps, temps2); - sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); + if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) + { + sprintf(temps2, "%02u:%02u", c + 2, 0); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); - if (cdrom_drives[c].scsi_device_id > 15) - { - cdrom_drives[c].scsi_device_id = 15; + if (cdrom_drives[c].scsi_device_id > 15) + { + cdrom_drives[c].scsi_device_id = 15; + } + if (cdrom_drives[c].scsi_device_lun > 7) + { + cdrom_drives[c].scsi_device_lun = 7; + } } - if (cdrom_drives[c].scsi_device_lun > 7) + else { - cdrom_drives[c].scsi_device_lun = 7; + config_delete_var(cat, temps); } sprintf(temps, "cdrom_%02i_image_path", c + 1); wp = config_get_wstring(cat, temps, L""); memcpy(cdrom_image[c].image_path, wp, (wcslen(wp) << 1) + 2); + + if ((cdrom_drives[c].host_drive < 0x41) || ((cdrom_drives[c].host_drive == 0x200) && (wcslen(cdrom_image[c].image_path) == 0))) + { + cdrom_drives[c].host_drive = 0; + } + + /* If the CD-ROM is disabled, delete all its variables. */ + if (cdrom_drives[c].bus_type == CDROM_BUS_DISABLED) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_parameters", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_scsi_location", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + config_delete_var(cat, temps); + } + + sprintf(temps, "cdrom_%02i_iso_path", c + 1); + config_delete_var(cat, temps); } } @@ -1144,32 +1590,107 @@ static void saveconfig_general(void) char temps[512]; config_set_int(cat, "vid_resize", vid_resize); - switch(vid_api) + if (vid_resize == 0) { - case 0: - config_set_string(cat, "vid_renderer", "ddraw"); - break; - case 1: - default: - config_set_string(cat, "vid_renderer", "d3d9"); - break; + config_delete_var(cat, "vid_resize"); } - config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - config_set_int(cat, "force_43", force_43); - config_set_int(cat, "scale", scale); - config_set_int(cat, "enable_overscan", enable_overscan); + if (vid_api == 1) + { + config_delete_var(cat, "vid_renderer"); + } + else + { + switch(vid_api) + { + case 0: + config_set_string(cat, "vid_renderer", "ddraw"); + break; + case 1: + default: + config_set_string(cat, "vid_renderer", "d3d9"); + break; + } + } + + if (video_fullscreen_scale == 0) + { + config_delete_var(cat, "video_fullscreen_scale"); + } + else + { + config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); + } + + if (video_fullscreen_first == 1) + { + config_delete_var(cat, "video_fullscreen_first"); + } + else + { + config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); + } + + if (force_43 == 0) + { + config_delete_var(cat, "force_43"); + } + else + { + config_set_int(cat, "force_43", force_43); + } + + if (scale == 1) + { + config_delete_var(cat, "scale"); + } + else + { + config_set_int(cat, "scale", scale); + } + + if (enable_overscan == 0) + { + config_delete_var(cat, "enable_overscan"); + } + else + { + config_set_int(cat, "enable_overscan", enable_overscan); + } - sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); - config_set_string(cat, "window_coordinates", temps); config_set_int(cat, "window_remember", window_remember); + if (window_remember) + { + sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); + config_set_string(cat, "window_coordinates", temps); + } + else + { + config_delete_var(cat, "window_remember"); + config_delete_var(cat, "window_coordinates"); + } - config_set_wstring(cat, "nvr_path", nvr_path); + if (read_nvr_path == NULL) + { + config_delete_var(cat, "nvr_path"); + } + else + { + config_set_wstring(cat, "nvr_path", nvr_path); + } #ifndef __unix - config_set_hex16(cat, "language", dwLanguage); + if (dwLanguage == 0x0409) + { + config_delete_var(cat, "language"); + } + else + { + config_set_hex16(cat, "language", dwLanguage); + } #endif + + config_delete_section_if_empty(cat); } @@ -1179,14 +1700,64 @@ static void saveconfig_machine(void) char *cat = "Machine"; config_set_string(cat, "model", model_get_internal_name()); - config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); - config_set_int(cat, "cpu", cpu); - config_set_int(cat, "cpu_waitstates", cpu_waitstates); - config_set_int(cat, "mem_size", mem_size); + if (cpu_manufacturer == 0) + { + config_delete_var(cat, "cpu_manufacturer"); + } + else + { + config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); + } + + if (cpu == 0) + { + config_delete_var(cat, "cpu"); + } + else + { + config_set_int(cat, "cpu", cpu); + } + + if (cpu_waitstates == 0) + { + config_delete_var(cat, "cpu_waitstates"); + } + else + { + config_set_int(cat, "cpu_waitstates", cpu_waitstates); + } + + if (mem_size == 4096) + { + config_delete_var(cat, "mem_size"); + } + else + { + config_set_int(cat, "mem_size", mem_size); + } + config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); - config_set_int(cat, "enable_sync", enable_sync); + + if (enable_external_fpu == 0) + { + config_delete_var(cat, "cpu_enable_fpu"); + } + else + { + config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); + } + + if (enable_sync == 0) + { + config_delete_var(cat, "enable_sync"); + } + else + { + config_set_int(cat, "enable_sync", enable_sync); + } + + config_delete_section_if_empty(cat); } @@ -1196,8 +1767,26 @@ static void saveconfig_video(void) char *cat = "Video"; config_set_string(cat, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(cat, "video_speed", video_speed); - config_set_int(cat, "voodoo", voodoo_enabled); + + if (video_speed == 3) + { + config_delete_var(cat, "video_speed"); + } + else + { + config_set_int(cat, "video_speed", video_speed); + } + + if (voodoo_enabled == 0) + { + config_delete_var(cat, "voodoo"); + } + else + { + config_set_int(cat, "voodoo", voodoo_enabled); + } + + config_delete_section_if_empty(cat); } @@ -1211,33 +1800,71 @@ static void saveconfig_input_devices(void) config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); - config_set_int(cat, "joystick_type", joystick_type); + if ((joystick_type == 0) || (joystick_type == 7)) + { + if (joystick_type == 7) + { + config_delete_var(cat, "joystick_type"); + } + else + { + config_set_int(cat, "joystick_type", joystick_type); + } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - sprintf(s, "joystick_%i_nr", c); - config_set_int(cat, s, joystick_state[c].plat_joystick_nr); + for (c = 0; c < 16; c++) + { + sprintf(s, "joystick_%i_nr", c); + config_delete_var(cat, s); - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int(cat, s, joystick_state[c].axis_mapping[d]); + for (d = 0; d < 16; d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_delete_var(cat, s); } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int(cat, s, joystick_state[c].button_mapping[d]); + for (d = 0; d < 16; d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_delete_var(cat, s); } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i", c, d); - sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); - config_set_string(cat, s, temps); - } - } - } + for (d = 0; d < 16; d++) + { + sprintf(s, "joystick_%i_pov_%i", c, d); + config_delete_var(cat, s); + } + } + } + else + { + config_set_int(cat, "joystick_type", joystick_type); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + config_set_int(cat, s, joystick_state[c].plat_joystick_nr); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int(cat, s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int(cat, s, joystick_state[c].button_mapping[d]); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i", c, d); + sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); + config_set_string(cat, s, temps); + } + } + } + } + + config_delete_section_if_empty(cat); } @@ -1246,14 +1873,61 @@ static void saveconfig_sound(void) { char *cat = "Sound"; - config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); + if (sound_card_current == 0) + { + config_delete_var(cat, "sndcard"); + } + else + { + config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); + } - config_set_int(cat, "midi_host_device", midi_id); + if (midi_id == 0) + { + config_delete_var(cat, "midi_host_device"); + } + else + { + config_set_int(cat, "midi_host_device", midi_id); + } - config_set_int(cat, "gameblaster", GAMEBLASTER); - config_set_int(cat, "gus", GUS); - config_set_int(cat, "ssi2001", SSI2001); - config_set_int(cat, "opl3_type", opl3_type); + if (SSI2001 == 0) + { + config_delete_var(cat, "ssi2001"); + } + else + { + config_set_int(cat, "ssi2001", SSI2001); + } + + if (GAMEBLASTER == 0) + { + config_delete_var(cat, "gameblaster"); + } + else + { + config_set_int(cat, "gameblaster", GAMEBLASTER); + } + + if (GUS == 0) + { + config_delete_var(cat, "gus"); + } + else + { + config_set_int(cat, "gus", GUS); + } + + if (opl3_type == 0) + { + config_delete_var(cat, "opl3_type"); + } + else + { + config_set_string(cat, "opl3_type", (opl3_type == 1) ? "nukedopl" : "dbopl"); + } + + config_delete_section_if_empty(cat); } @@ -1262,16 +1936,42 @@ static void saveconfig_network(void) { char *cat = "Network"; - if (network_pcap[0] != '\0') + if (network_type == NET_TYPE_NONE) { - config_set_string(cat, "net_pcap_device", network_pcap); + config_delete_var(cat, "net_type"); } else { - config_set_string(cat, "net_pcap_device", "none"); + config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "pcap" : "slirp"); } - config_set_int(cat, "net_type", network_type); - config_set_string(cat, "net_card", network_card_get_internal_name(network_card)); + + if (network_pcap[0] != '\0') + { + if (!strcmp(network_pcap, "none")) + { + config_delete_var(cat, "net_pcap_device"); + } + else + { + config_set_string(cat, "net_pcap_device", network_pcap); + } + } + else + { + /* config_set_string(cat, "net_pcap_device", "none"); */ + config_delete_var(cat, "net_pcap_device"); + } + + if (network_card == 0) + { + config_delete_var(cat, "net_card"); + } + else + { + config_set_string(cat, "net_card", network_card_get_internal_name(network_card)); + } + + config_delete_section_if_empty(cat); } @@ -1281,47 +1981,111 @@ static void saveconfig_other_peripherals(void) char *cat = "Other peripherals"; char temps[512]; char temps2[512]; - int c, d; + int c; - config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + if (scsi_card_current == 0) + { + config_delete_var(cat, "scsicard"); + } + else + { + config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + } - config_set_string(cat, "hdd_controller", hdd_controller_name); + if (!strcmp(hdd_controller_name, "none")) + { + config_delete_var(cat, "hdd_controller"); + } + else + { + config_set_string(cat, "hdd_controller", hdd_controller_name); + } memset(temps, '\0', sizeof(temps)); for (c = 2; c < 4; c++) { sprintf(temps, "ide_%02i", c + 1); sprintf(temps2, "%i, %02i", !!ide_enable[c], ide_irq[c]); - config_set_string(cat, temps, temps2); + + if (ide_enable[c] == 0) + { + config_delete_var(cat, temps); + } + else + { + config_set_string(cat, temps, temps2); + } } - config_set_int(cat, "serial1_enabled", serial_enabled[0]); - config_set_int(cat, "serial2_enabled", serial_enabled[1]); - config_set_int(cat, "lpt_enabled", lpt_enabled); - config_set_int(cat, "bugger_enabled", bugger_enabled); + if (serial_enabled[0]) + { + config_delete_var(cat, "serial1_enabled"); + } + else + { + config_set_int(cat, "serial1_enabled", serial_enabled[0]); + } + + if (serial_enabled[1]) + { + config_delete_var(cat, "serial2_enabled"); + } + else + { + config_set_int(cat, "serial2_enabled", serial_enabled[1]); + } + + if (lpt_enabled) + { + config_delete_var(cat, "lpt_enabled"); + } + else + { + config_set_int(cat, "lpt_enabled", lpt_enabled); + } + + if (bugger_enabled == 0) + { + config_delete_var(cat, "bugger_enabled"); + } + else + { + config_set_int(cat, "bugger_enabled", bugger_enabled); + } + + config_delete_section_if_empty(cat); } -static char *config_bus_to_string(int bus) +static char *config_bus_to_string(int bus, int cdrom) { switch (bus) { - case 0: + case HDD_BUS_DISABLED: default: return "none"; break; - case 1: + case HDD_BUS_MFM: return "mfm"; break; - case 2: - return "ide_pio_only"; + case HDD_BUS_XTIDE: + return "xtide"; break; - case 3: - return "ide_pio_and_dma"; + case HDD_BUS_RLL: + return "rll"; break; - case 4: + case HDD_BUS_IDE_PIO_ONLY: + return cdrom ? "atapi_pio_only" : "ide_pio_only"; + break; + case HDD_BUS_IDE_PIO_AND_DMA: + return cdrom ? "atapi_pio_and_dma" : "ide_pio_and_dma"; + break; + case HDD_BUS_SCSI: return "scsi"; break; + case HDD_BUS_SCSI_REMOVABLE: + return "scsi_removable"; + break; } } @@ -1330,34 +2094,92 @@ static char *config_bus_to_string(int bus) static void saveconfig_hard_disks(void) { char *cat = "Hard disks"; - char temps[512]; - char temps2[512]; + char temps[24]; + char temps2[64]; char s[512]; - int c, d; + int c; char *p; - memset(temps, '\0', sizeof(temps)); + memset(temps, 0, sizeof(temps)); for (c = 0; c < HDC_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); - memset(s, '\0', sizeof(s)); - p = config_bus_to_string(hdc[c].bus); - sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, p); - config_set_string(cat, temps, temps2); + memset(s, 0, sizeof(s)); + if (!hard_disk_is_valid(c)) + { + config_delete_var(cat, temps); + } + else + { + p = config_bus_to_string(hdc[c].bus, 0); + sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, hdc[c].wp, p); + config_set_string(cat, temps, temps2); + } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int(cat, temps, hdc[c].mfm_channel); + if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_MFM)) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, hdc[c].mfm_channel); + } + + sprintf(temps, "hdd_%02i_xtide_channel", c + 1); + if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_XTIDE)) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, hdc[c].xtide_channel); + } + + sprintf(temps, "hdd_%02i_rll_channel", c + 1); + if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_RLL)) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, hdc[c].rll_channel); + } sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int(cat, temps, hdc[c].ide_channel); + if (!hard_disk_is_valid(c) || ((hdc[c].bus != HDD_BUS_IDE_PIO_ONLY) && (hdc[c].bus != HDD_BUS_IDE_PIO_AND_DMA))) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%01u:%01u", hdc[c].ide_channel >> 1, hdc[c].ide_channel & 1); + config_set_string(cat, temps, temps2); + } sprintf(temps, "hdd_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); - config_set_string(cat, temps, temps2); + if (!hard_disk_is_valid(c) || ((hdc[c].bus != HDD_BUS_SCSI) && (hdc[c].bus != HDD_BUS_SCSI_REMOVABLE))) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); + config_set_string(cat, temps, temps2); + } sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring(cat, temps, hdd_fn[c]); + if (!hard_disk_is_valid(c) || (wcslen(hdc[c].fn) == 0)) + { + config_delete_var(cat, temps); + } + else + { + config_set_wstring(cat, temps, hdc[c].fn); + } } + + config_delete_section_if_empty(cat); } @@ -1367,46 +2189,110 @@ static void saveconfig_removable_devices(void) char *cat = "Removable devices"; char temps[512]; char temps2[512]; - int c, d; + int c; memset(temps, '\0', sizeof(temps)); for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string(cat, temps, fdd_get_internal_name(fdd_get_type(c))); + if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) + { + config_delete_var(cat, temps); + } + else + { + config_set_string(cat, temps, fdd_get_internal_name(fdd_get_type(c))); + } + sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring(cat, temps, discfns[c]); + if (wcslen(discfns[c]) == 0) + { + config_delete_var(cat, temps); + + ui_writeprot[c] = 0; + + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_delete_var(cat, temps); + } + else + { + config_set_wstring(cat, temps, discfns[c]); + } + sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int(cat, temps, ui_writeprot[c]); + if (ui_writeprot[c] == 0) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, ui_writeprot[c]); + } } memset(temps, '\0', sizeof(temps)); for (c = 0; c < CDROM_NUM; c++) { sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int(cat, temps, cdrom_drives[c].host_drive); + if ((cdrom_drives[c].bus_type == 0) || (cdrom_drives[c].host_drive < 'A') || ((cdrom_drives[c].host_drive > 'Z') && (cdrom_drives[c].host_drive != 200))) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, cdrom_drives[c].host_drive); + } sprintf(temps, "cdrom_%02i_parameters", c + 1); - sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type)); - config_set_string(cat, temps, temps2); + if (cdrom_drives[c].bus_type == 0) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type, 1)); + config_set_string(cat, temps, temps2); + } sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int(cat, temps, cdrom_drives[c].ide_channel); + if ((cdrom_drives[c].bus_type != CDROM_BUS_ATAPI_PIO_ONLY) && (cdrom_drives[c].bus_type != CDROM_BUS_ATAPI_PIO_AND_DMA)) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%01u:%01u", cdrom_drives[c].ide_channel >> 1, cdrom_drives[c].ide_channel & 1); + config_set_string(cat, temps, temps2); + } sprintf(temps, "cdrom_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); - config_set_string(cat, temps, temps2); + if (cdrom_drives[c].bus_type != CDROM_BUS_SCSI) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); + config_set_string(cat, temps, temps2); + } sprintf(temps, "cdrom_%02i_image_path", c + 1); - config_set_wstring(cat, temps, cdrom_image[c].image_path); + if ((cdrom_drives[c].bus_type == 0) || (wcslen(cdrom_image[c].image_path) == 0)) + { + config_delete_var(cat, temps); + } + else + { + config_set_wstring(cat, temps, cdrom_image[c].image_path); + } } + + config_delete_section_if_empty(cat); } void saveconfig(void) { - int c, d; - /* General */ saveconfig_general(); diff --git a/src/config.h b/src/config.h index fb33cd98d..c2b08da0b 100644 --- a/src/config.h +++ b/src/config.h @@ -11,9 +11,15 @@ extern "C" { #endif extern int config_get_int(char *head, char *name, int def); +extern int config_get_hex16(char *head, char *name, int def); +extern int config_get_hex20(char *head, char *name, int def); +extern int config_get_mac(char *head, char *name, int def); extern char *config_get_string(char *head, char *name, char *def); extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); extern void config_set_int(char *head, char *name, int val); +extern void config_set_hex16(char *head, char *name, int val); +extern void config_set_hex20(char *head, char *name, int val); +extern void config_set_mac(char *head, char *name, int val); extern void config_set_string(char *head, char *name, char *val); extern void config_set_wstring(char *head, char *name, wchar_t *val); diff --git a/src/device.c b/src/device.c index 5d92699c5..b706f99b9 100644 --- a/src/device.c +++ b/src/device.c @@ -145,6 +145,48 @@ int device_get_config_int_ex(char *s, int default_int) return default_int; } +int device_get_config_hex16(char *s) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_hex16(current_device->name, s, config->default_int); + + config++; + } + return 0; +} + +int device_get_config_hex20(char *s) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_hex20(current_device->name, s, config->default_int); + + config++; + } + return 0; +} + +int device_get_config_mac(char *s, int default_int) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_mac(current_device->name, s, default_int); + + config++; + } + return default_int; +} + void device_set_config_int(char *s, int val) { device_config_t *config = current_device->config; @@ -162,6 +204,57 @@ void device_set_config_int(char *s, int val) return; } +void device_set_config_hex16(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_hex16(current_device->name, s, val); + return; + } + + config++; + } + return; +} + +void device_set_config_hex20(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_hex20(current_device->name, s, val); + return; + } + + config++; + } + return; +} + +void device_set_config_mac(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_mac(current_device->name, s, val); + return; + } + + config++; + } + return; +} + char *device_get_config_string(char *s) { device_config_t *config = current_device->config; diff --git a/src/device.h b/src/device.h index 172c5c69b..7ad34630e 100644 --- a/src/device.h +++ b/src/device.h @@ -2,7 +2,9 @@ #define CONFIG_INT 1 #define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 -#define CONFIG_MAC 4 +#define CONFIG_HEX16 4 +#define CONFIG_HEX20 5 +#define CONFIG_MAC 6 typedef struct device_config_selection_t { @@ -43,7 +45,13 @@ char *device_add_status_info(char *s, int max_len); int device_get_config_int(char *name); int device_get_config_int_ex(char *s, int default_int); +int device_get_config_hex16(char *name); +int device_get_config_hex20(char *name); +int device_get_config_mac(char *name, int default_int); void device_set_config_int(char *s, int val); +void device_set_config_hex16(char *s, int val); +void device_set_config_hex20(char *s, int val); +void device_set_config_mac(char *s, int val); char *device_get_config_string(char *name); enum diff --git a/src/disc.c b/src/disc.c index ad7459fe2..74c779296 100644 --- a/src/disc.c +++ b/src/disc.c @@ -130,7 +130,7 @@ void disc_load(int drive, wchar_t *fn) pclog_w(L"Couldn't load %s %s\n",fn,p); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); - discfns[drive][0] = L'\0'; + memset(discfns[drive], 0, sizeof(discfns[drive])); update_status_bar_icon_state(drive, 1); } diff --git a/src/fdc.c b/src/fdc.c index 7a640096b..6392d41ac 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -957,7 +957,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); readflash = 1; fdc.inread = 1; break; @@ -1003,7 +1003,7 @@ bad_command: disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.pos = 0; if (fdc.pcjr) fdc.stat = 0xb0; @@ -1036,7 +1036,7 @@ bad_command: disc_comparesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.pos = 0; if (fdc.pcjr || !fdc.dma) { @@ -1080,7 +1080,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.inread = 1; break; @@ -1437,7 +1437,7 @@ void fdc_poll_common_finish(int compare, int st5) fdc.res[9]=fdc.sector; fdc.res[10]=fdc.params[4]; fdc_log("Read/write finish (%02X %02X %02X %02X %02X %02X %02X)\n" , fdc.res[4], fdc.res[5], fdc.res[6], fdc.res[7], fdc.res[8], fdc.res[9], fdc.res[10]); - update_status_bar_icon(fdc.drive, 0); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 0); paramstogo=7; } @@ -1483,7 +1483,7 @@ void fdc_callback() return; case 2: /*Read track*/ - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.eot[fdc.drive]--; fdc.read_track_sector.id.r++; if (!fdc.eot[fdc.drive] || fdc.tc) @@ -1643,7 +1643,7 @@ void fdc_callback() { fdc.sector++; } - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); switch (discint) { case 5: @@ -1882,7 +1882,7 @@ void fdc_error(int st5, int st6) fdc.res[10]=0; break; } - update_status_bar_icon(fdc.drive, 0); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 0); paramstogo=7; } @@ -1940,36 +1940,6 @@ int fdc_data(uint8_t data) } else { - if (fdc.tc) - { - fdc_log("FDC read: TC\n"); - return 0; - } - - if (dma_channel_write(2, data) & DMA_OVER) - { - fdc_log("FDC read: DMA over\n"); - fdc.tc = 1; - } - - if (!fdc.fifo) - { - fdc.data_ready = 1; - fdc.stat = 0xd0; - } - else - { - fdc_fifo_buf_advance(); - if (fdc.fifobufpos == 0) - { - /* We have wrapped around, means FIFO is over */ - fifo_count++; - fdc_log("%04X: FIFO wrap around (threshold == %02X), DRQ sent\n", fifo_count, fdc.tfifo); - fdc.data_ready = 1; - fdc.stat = 0xd0; - } - } -#if 0 result = dma_channel_write(2, data); if (fdc.tc) @@ -1998,7 +1968,6 @@ int fdc_data(uint8_t data) fdc.stat = 0xd0; } } -#endif } return 0; diff --git a/src/hdd.c b/src/hdd.c index f9491ec7a..694a42788 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -13,6 +13,8 @@ static device_t null_hdd_device; static int hdd_controller_current; +hard_disk_t hdc[HDC_NUM]; + static struct { char name[50]; diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index a6f5ce466..4772b2c48 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -433,7 +433,7 @@ static void esdi_callback(void *p) fatal("Read past end of drive\n"); fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); fread(esdi->data, 512, 1, drive->hdfile); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1); } while (esdi->data_pos < 256) { @@ -522,11 +522,11 @@ static void esdi_callback(void *p) fwrite(esdi->data, 512, 1, drive->hdfile); esdi->rba++; esdi->sector_pos++; - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1); esdi->data_pos = 0; } - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 0); esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; @@ -848,11 +848,11 @@ static void *esdi_init() for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + if ((hdc[i].bus == HDD_BUS_RLL) && (hdc[i].rll_channel < RLL_NUM)) { - loadhd(esdi, i, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(esdi, i, hdc[i].rll_channel, hdc[i].fn); c++; - if (c >= MFM_NUM) break; + if (c >= RLL_NUM) break; } } diff --git a/src/ibm.h b/src/ibm.h index 8b4680fc0..4b01f1584 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -161,6 +161,15 @@ struct } cpu_state; #define cycles cpu_state._cycles + +uint32_t cpu_cur_status; + +#define CPU_STATUS_USE32 (1 << 0) +#define CPU_STATUS_STACK32 (1 << 1) +#define CPU_STATUS_FLATDS (1 << 2) +#define CPU_STATUS_FLATSS (1 << 3) + + #define cpu_rm cpu_state.rm_data.rm_mod_reg.rm #define cpu_mod cpu_state.rm_data.rm_mod_reg.mod #define cpu_reg cpu_state.rm_data.rm_mod_reg.reg @@ -550,7 +559,27 @@ int gated,speakval,speakon; wchar_t pcempath[512]; -/*Hard disc*/ +/*Hard disk*/ +enum +{ + HDD_BUS_DISABLED = 0, + HDD_BUS_MFM, + HDD_BUS_XTIDE, + HDD_BUS_RLL, + HDD_BUS_IDE_PIO_ONLY, + HDD_BUS_IDE_PIO_AND_DMA, + HDD_BUS_SCSI, + HDD_BUS_SCSI_REMOVABLE, + HDD_BUS_USB +}; + +#define HDC_NUM 30 +#define MFM_NUM 2 +#define RLL_NUM 2 +#define XTIDE_NUM 2 +#define IDE_NUM 8 +#define SCSI_NUM 16 /* Theoretically the controller can have at least 64 devices, or even 128 in case of a wide bus, but + let's not exaggerate with them - 16 ought to be enough for everyone. */ #pragma pack(push,1) typedef struct { @@ -558,69 +587,28 @@ typedef struct { uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ uint64_t tracks; int is_hdi; + int wp; uint32_t base; uint64_t at_spt,at_hpc; /*[Translation] Sectors per track, heads per cylinder*/ unsigned int bus; /* 0 = none, 1 = MFM/RLL, 2 = IDE, 3 = SCSI */ unsigned int mfm_channel; + unsigned int rll_channel; + unsigned int xtide_channel; unsigned int ide_channel; unsigned int scsi_id; unsigned int scsi_lun; + wchar_t fn[260]; + wchar_t prev_fn[260]; } hard_disk_t; #pragma pack(pop) -#pragma pack(push,1) -typedef struct { - /* Stuff for SCSI hard disks. */ - uint8_t cdb[16]; - uint8_t current_cdb[16]; - uint8_t max_cdb_len; - int requested_blocks; - int max_blocks_at_once; - uint16_t request_length; - int block_total; - int all_blocks_total; - uint32_t packet_len; - int packet_status; - uint8_t status; - uint8_t phase; - uint32_t pos; - int callback; - int total_read; - int unit_attention; - uint8_t sense[256]; - uint8_t previous_command; - uint8_t error; - uint16_t buffer[390144]; - uint32_t sector_pos; - uint32_t sector_len; - uint32_t last_sector; - uint32_t seek_pos; - int data_pos; - int old_len; - int cdb_len_setting; - int cdb_len; - int request_pos; - uint64_t base; - uint8_t hd_cdb[16]; -} scsi_hard_disk_t; -#pragma pack(pop) - -#define HDC_NUM 16 -#define IDE_NUM 8 -#define MFM_NUM 2 -#define SCSI_NUM 16 /* Theoretically the controller can have at least 64 devices, or even 128 in case of a wide bus, but - let's not exaggerate with them - 16 ought to be enough for everyone. */ - -hard_disk_t hdc[HDC_NUM]; -scsi_hard_disk_t shdc[HDC_NUM]; +extern hard_disk_t hdc[HDC_NUM]; FILE *shdf[HDC_NUM]; uint64_t hdt[128][3]; uint64_t hdt_mfm[128][3]; -extern wchar_t hdd_fn[HDC_NUM][512]; - int image_is_hdi(const wchar_t *s); int image_is_hdx(const wchar_t *s, int check_signature); @@ -629,7 +617,16 @@ int keybsenddelay; /*CD-ROM*/ -extern int idecallback[4]; +enum +{ + CDROM_BUS_DISABLED = 0, + CDROM_BUS_ATAPI_PIO_ONLY = 4, + CDROM_BUS_ATAPI_PIO_AND_DMA, + CDROM_BUS_SCSI, + CDROM_BUS_USB = 8 +}; + +extern int idecallback[5]; #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 @@ -776,3 +773,9 @@ extern void update_status_bar_icon(int tag, int active); extern void update_status_bar_icon_state(int tag, int state); extern void status_settextw(wchar_t *wstr); extern void status_settext(char *str); + +#define SB_FLOPPY 0x00 +#define SB_CDROM 0x10 +#define SB_RDISK 0x20 +#define SB_HDD 0x40 +#define SB_TEXT 0x50 diff --git a/src/ide.c b/src/ide.c index 1308fcf89..7f1000264 100644 --- a/src/ide.c +++ b/src/ide.c @@ -92,19 +92,17 @@ uint64_t hdt[128][3] = { { 306, 4, 17 }, { 615, 2, 17 }, { 306, 4, 26 }, { { 1930, 4, 62 }, { 967, 16, 31 }, { 1013, 10, 63 }, { 1218, 15, 36 }, { 654, 16, 63 }, { 659, 16, 63 }, { 702, 16, 63 }, { 1002, 13, 63 }, /* 112-119 */ { 854, 16, 63 }, { 987, 16, 63 }, { 995, 16, 63 }, { 1024, 16, 63 }, { 1036, 16, 63 }, { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } }; /* 119-127 */ -IDE ide_drives[IDE_NUM]; +IDE ide_drives[IDE_NUM + XTIDE_NUM]; IDE *ext_ide; -wchar_t hdd_fn[HDC_NUM][512]; - int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); void (*ide_bus_master_set_irq)(int channel); -int idecallback[4] = {0, 0, 0, 0}; +int idecallback[5] = {0, 0, 0, 0, 0}; -int cur_ide[4]; +int cur_ide[5]; int ide_do_log = 0; @@ -132,7 +130,7 @@ int ide_drive_is_cdrom(IDE *ide) } else { - if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type > 1) && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type < 4)) + if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { return 1; } @@ -143,24 +141,18 @@ int ide_drive_is_cdrom(IDE *ide) } } -static char as[512]; - int image_is_hdi(const wchar_t *s) { - int i, len; - char ext[5] = { 0, 0, 0, 0, 0 }; - wcstombs(as, s, (wcslen(s) << 1) + 2); - len = strlen(as); - if ((len < 4) || (as[0] == '.')) + int len; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + char *ws = (char *) s; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) { return 0; } - memcpy(ext, as + len - 4, 4); - for (i = 0; i < 4; i++) - { - ext[i] = toupper(ext[i]); - } - if (strcmp(ext, ".HDI") == 0) + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcsicmp(ext, L".HDI") == 0) { return 1; } @@ -172,23 +164,19 @@ int image_is_hdi(const wchar_t *s) int image_is_hdx(const wchar_t *s, int check_signature) { - int i, len; + int len; FILE *f; uint64_t filelen; uint64_t signature; - char ext[5] = { 0, 0, 0, 0, 0 }; - wcstombs(as, s, (wcslen(s) << 1) + 2); - len = strlen(as); - if ((len < 4) || (as[0] == '.')) + char *ws = (char *) s; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) { return 0; } - memcpy(ext, as + len - 4, 4); - for (i = 0; i < 4; i++) - { - ext[i] = toupper(ext[i]); - } - if (strcmp(ext, ".HDX") == 0) + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcsicmp(ext, L".HDX") == 0) { if (check_signature) { @@ -226,7 +214,7 @@ int image_is_hdx(const wchar_t *s, int check_signature) } } -int ide_enable[4] = { 1, 1, 0, 0 }; +int ide_enable[5] = { 1, 1, 0, 0, 1 }; int ide_irq[4] = { 14, 15, 10, 11 }; void ide_irq_raise(IDE *ide) @@ -353,10 +341,13 @@ void ide_padstr8(uint8_t *buf, int buf_size, const char *src) static void ide_identify(IDE *ide) { uint32_t c, h, s; - char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; +#if 0 uint64_t full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); +#endif - device_identify[6] = ide->channel + 0x30; + device_identify[6] = (ide->hdc_num / 10) + 0x30; + device_identify[7] = (ide->hdc_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); memset(ide->buffer, 0, 512); @@ -382,7 +373,7 @@ static void ide_identify(IDE *ide) ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ ide->buffer[48] = 1; /*Dword transfers supported*/ - if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) { ide->buffer[49] = (1 << 8); /* LBA and DMA supported */ } @@ -418,7 +409,7 @@ static void ide_identify(IDE *ide) ide->buffer[60] = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[61] = ((hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) >> 16) & 0x0FFF; } - if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) { ide->buffer[52] = 2 << 8; /*DMA timing mode*/ @@ -436,13 +427,13 @@ static void ide_identify(IDE *ide) */ static void ide_atapi_identify(IDE *ide) { - char device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; uint8_t cdrom_id; memset(ide->buffer, 0, 512); cdrom_id = atapi_cdrom_drives[ide->channel]; - device_identify[6] = cdrom_id + 0x30; + device_identify[7] = cdrom_id + 0x30; ide_log("ATAPI Identify: %s\n", device_identify); ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ @@ -451,7 +442,7 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[49] = 0x200; /* LBA supported */ - if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) + if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] |= 0x100; /* DMA supported */ @@ -518,7 +509,7 @@ static void loadhd(IDE *ide, int d, const wchar_t *fn) if (ide->hdfile == NULL) { /* Try to open existing hard disk image */ - if (fn[0] == '.') + if (fn[0] == L'.') { ide->type = IDE_NONE; return; @@ -659,7 +650,7 @@ int ide_cdrom_is_pio_only(IDE *ide) { return 0; } - if (cdrom_drives[cdrom_id].bus_mode & 2) + if (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { return 0; } @@ -703,7 +694,7 @@ static int ide_set_features(IDE *ide) break; case 0x04: /* Multiword DMA mode */ - if (!PCI || (hdc[ide->hdc_num].bus != 3) || (ide->board >= 2) || (submode > 2)) + if (!PCI || (hdc[ide->hdc_num].bus != HDD_BUS_IDE_PIO_AND_DMA) || (ide->board >= 2) || (submode > 2)) { return 0; } @@ -750,7 +741,7 @@ void resetide(void) build_atapi_cdrom_map(); /* Close hard disk image files (if previously open) */ - for (d = 0; d < IDE_NUM; d++) + for (d = 0; d < (IDE_NUM + XTIDE_NUM); d++) { ide_drives[d].channel = d; ide_drives[d].type = IDE_NONE; @@ -774,12 +765,19 @@ void resetide(void) c = 0; for (d = 0; d < HDC_NUM; d++) { - if (((hdc[d].bus == 2) || (hdc[d].bus == 3)) && (hdc[d].ide_channel < IDE_NUM)) + if (((hdc[d].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[d].bus == HDD_BUS_IDE_PIO_AND_DMA)) && (hdc[d].ide_channel < IDE_NUM)) { pclog("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); - loadhd(&ide_drives[hdc[d].ide_channel], d, hdd_fn[d]); + loadhd(&ide_drives[hdc[d].ide_channel], d, hdc[d].fn); c++; - if (c >= IDE_NUM) break; + if (c >= (IDE_NUM + XTIDE_NUM)) break; + } + if ((hdc[d].bus == HDD_BUS_XTIDE) && (hdc[d].xtide_channel < XTIDE_NUM)) + { + pclog("Found XTIDE hard disk on channel %i\n", hdc[d].xtide_channel); + loadhd(&ide_drives[hdc[d].xtide_channel | 8], d, hdc[d].fn); + c++; + if (c >= (IDE_NUM + XTIDE_NUM)) break; } } @@ -800,7 +798,19 @@ void resetide(void) ide_drives[d].error = 1; } - for (d = 0; d < 4; d++) + for (d = 0; d < XTIDE_NUM; d++) + { + ide_set_signature(&ide_drives[d | 8]); + + if (ide_drives[d].type == IDE_HDD) + { + ide_drives[d].mdma_mode = 0; + } + + ide_drives[d].error = 1; + } + + for (d = 0; d < 5; d++) { cur_ide[d] = d << 1; } @@ -1399,7 +1409,7 @@ uint32_t ide_read_data(int ide_board, int length) } else { - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } } } @@ -1722,7 +1732,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); return; case WIN_READ_DMA: @@ -1756,12 +1766,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } } } @@ -1799,7 +1809,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); return; case WIN_WRITE: @@ -1822,12 +1832,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } return; @@ -1863,12 +1873,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } } } @@ -1899,12 +1909,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } return; @@ -1921,7 +1931,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); return; case WIN_FORMAT: @@ -1943,7 +1953,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); */ + /* update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: @@ -2124,6 +2134,12 @@ void ide_callback_qua() callbackide(3); } +void ide_callback_xtide() +{ + idecallback[4] = 0; + callbackide(4); +} + void ide_write_pri(uint16_t addr, uint8_t val, void *priv) { writeide(0, addr, val); @@ -2355,6 +2371,13 @@ void ide_init() timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); } +void ide_xtide_init() +{ + ide_bus_master_read = ide_bus_master_write = NULL; + + timer_add(ide_callback_xtide, &idecallback[4], &idecallback[4], NULL); +} + void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)) { ide_bus_master_read = read; diff --git a/src/ide.h b/src/ide.h index db8d52330..de63c9372 100644 --- a/src/ide.h +++ b/src/ide.h @@ -51,6 +51,7 @@ extern uint16_t readidew(int ide_board); extern void callbackide(int ide_board); extern void resetide(void); extern void ide_init(); +extern void ide_xtide_init(); extern void ide_ter_init(); extern void ide_qua_init(); extern void ide_pri_enable(); @@ -65,15 +66,15 @@ extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int trans extern int ideboard; -extern int ide_enable[4]; +extern int ide_enable[5]; extern int ide_irq[4]; -extern int idecallback[4]; +extern int idecallback[5]; void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); -IDE ide_drives[IDE_NUM]; +IDE ide_drives[IDE_NUM + XTIDE_NUM]; void ide_padstr8(uint8_t *buf, int buf_size, const char *src); diff --git a/src/mfm_at.c b/src/mfm_at.c index f0dd98ed1..b62fbbef0 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -439,7 +439,7 @@ uint16_t mfm_readw(uint16_t port, void *p) } else { - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); } } } @@ -505,7 +505,7 @@ void mfm_callback(void *p) mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; case CMD_WRITE: @@ -526,12 +526,12 @@ void mfm_callback(void *p) mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm->pos = 0; mfm_next_sector(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); } else { mfm->status = STAT_READY | STAT_DSC; - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); } break; @@ -540,7 +540,7 @@ void mfm_callback(void *p) mfm->pos = 0; mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; case CMD_FORMAT: @@ -560,7 +560,7 @@ void mfm_callback(void *p) } mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; case CMD_DIAGNOSE: @@ -596,9 +596,9 @@ void *mfm_init() c = 0; for (d = 0; d < HDC_NUM; d++) { - if ((hdc[d].bus == 1) && (hdc[d].mfm_channel < MFM_NUM)) + if ((hdc[d].bus == HDD_BUS_MFM) && (hdc[d].mfm_channel < MFM_NUM)) { - loadhd(mfm, hdc[d].mfm_channel, d, hdd_fn[d]); + loadhd(mfm, hdc[d].mfm_channel, d, hdc[d].fn); c++; if (c >= MFM_NUM) break; } diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index d7b80d831..b318c4de3 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -374,7 +374,7 @@ static void xebec_callback(void *p) xebec_complete(xebec); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; default: @@ -431,7 +431,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); } if (xebec->irq_dma_mask & DMA_ENA) xebec->callback = XEBEC_TIME; @@ -485,7 +485,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); xebec->state = STATE_SEND_DATA; @@ -500,7 +500,7 @@ static void xebec_callback(void *p) else { xebec_complete(xebec); - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); } break; @@ -572,7 +572,7 @@ static void xebec_callback(void *p) fwrite(xebec->sector_buf, 512, 1, drive->hdfile); } - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); xebec_next_sector(xebec); xebec->data_pos = 0; @@ -851,9 +851,9 @@ static void *xebec_init() for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + if ((hdc[i].bus == HDD_BUS_MFM) && (hdc[i].mfm_channel < MFM_NUM)) { - loadhd(xebec, i, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(xebec, i, hdc[i].mfm_channel, hdc[i].fn); c++; if (c > MFM_NUM) break; } @@ -914,9 +914,9 @@ static void *dtc_5150x_init() for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + if ((hdc[i].bus == HDD_BUS_MFM) && (hdc[i].mfm_channel < MFM_NUM)) { - loadhd(xebec, i, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(xebec, i, hdc[i].mfm_channel, hdc[i].fn); c++; if (c > MFM_NUM) break; } diff --git a/src/model.c b/src/model.c index 8b36ce114..b428c3628 100644 --- a/src/model.c +++ b/src/model.c @@ -544,16 +544,17 @@ void secondary_ide_check() for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].ide_channel >= 2) && (cdrom_drives[i].ide_channel <= 3) && !cdrom_drives[i].bus_type) + if ((cdrom_drives[i].ide_channel >= 2) && (cdrom_drives[i].ide_channel <= 3) && ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA))) { secondary_cdroms++; } - if (!secondary_cdroms) ide_sec_disable(); } + if (!secondary_cdroms) ide_sec_disable(); } void at_ali1429_init() { + ali1429_reset(); at_ide_init(); ali1429_init(); diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 47b5d52db..fee972934 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1906,13 +1906,13 @@ nic_init(int board) if (dev->is_pci) { dev->base_address = 0x340; } else { - dev->base_address = device_get_config_int("addr"); - dev->bios_addr = device_get_config_int("bios_addr"); + dev->base_address = device_get_config_hex16("base"); + dev->bios_addr = device_get_config_hex20("bios_addr"); } dev->base_irq = device_get_config_int("irq"); /* See if we have a local MAC address configured. */ - mac = device_get_config_int_ex("mac", -1); + mac = device_get_config_mac("mac", -1); /* Make this device known to the I/O system. */ nic_ioset(dev, dev->base_address); @@ -1984,7 +1984,7 @@ nic_init(int board) mac = (((int) dev->maclocal[3]) << 16); mac |= (((int) dev->maclocal[4]) << 8); mac |= ((int) dev->maclocal[5]); - device_set_config_int("mac", mac); + device_set_config_mac("mac", mac); } else { dev->maclocal[3] = (mac>>16) & 0xff; dev->maclocal[4] = (mac>>8) & 0xff; @@ -2065,7 +2065,7 @@ rtl8029as_init(void) static device_config_t ne1000_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x300, + "base", "Address", CONFIG_HEX16, "", 0x300, { { "0x280", 0x280 @@ -2111,7 +2111,7 @@ static device_config_t ne1000_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, { { "Disabled", 0x00000 @@ -2135,7 +2135,7 @@ static device_config_t ne1000_config[] = static device_config_t ne2000_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x300, + "base", "Address", CONFIG_HEX16, "", 0x300, { { "0x280", 0x280 @@ -2187,7 +2187,7 @@ static device_config_t ne2000_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, { { "Disabled", 0x00000 @@ -2236,23 +2236,6 @@ static device_config_t rtl8029as_config[] = { "mac", "MAC Address", CONFIG_MAC, "", -1 }, - { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, - { - { - "Disabled", 0x00000 - }, - { - "D000", 0xD0000 - }, - { - "C000", 0xC0000 - }, - { - "" - } - }, - }, { "", "", -1 } diff --git a/src/network.c b/src/network.c index c4cd9c547..14c62fb95 100644 --- a/src/network.c +++ b/src/network.c @@ -101,7 +101,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); if (ret < 0) { - msgbox_error(ghwnd, 2202); + msgbox_error(ghwnd, 2219); network_type = NET_TYPE_NONE; } break; @@ -143,6 +143,8 @@ network_close(void) void network_reset(void) { + int i = 0; + pclog("NETWORK: reset (type=%d, card=%d)\n", network_type, network_card); /* Just in case.. */ @@ -151,6 +153,8 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; + i = network_pcap_init(&network_devs[network_ndev]); + pclog("NETWORK: set up for %s, card='%s'\n", (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", net_cards[network_card].name); diff --git a/src/pc.c b/src/pc.c index 66e0bb4ef..5d6dc4244 100644 --- a/src/pc.c +++ b/src/pc.c @@ -374,20 +374,17 @@ void initpc(int argc, wchar_t *argv[]) SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); } - if (cdrom_drives[i].host_drive == 0) + if (cdrom_drives[i].host_drive == 200) { - cdrom_null_open(i, cdrom_drives[i].host_drive); + image_open(i, cdrom_image[i].image_path); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_open(i, cdrom_drives[i].host_drive); } else { - if (cdrom_drives[i].host_drive == 200) - { - image_open(i, cdrom_image[i].image_path); - } - else - { - ioctl_open(i, cdrom_drives[i].host_drive); - } + cdrom_null_open(i, cdrom_drives[i].host_drive); } } @@ -412,7 +409,6 @@ void initpc(int argc, wchar_t *argv[]) scsi_card_init(); fullspeed(); - ali1429_reset(); shadowbios=0; for (i = 0; i < CDROM_NUM; i++) @@ -423,7 +419,7 @@ void initpc(int argc, wchar_t *argv[]) { image_reset(i); } - else + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) { ioctl_reset(i); } @@ -528,7 +524,6 @@ void resetpchard(void) loadnvr(); shadowbios = 0; - ali1429_reset(); keyboard_at_reset(); @@ -542,7 +537,7 @@ void resetpchard(void) { image_reset(i); } - else + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) { ioctl_reset(i); } @@ -689,10 +684,10 @@ void closepc(void) cdrom_drives[i].handler->exit(i); } dumppic(); - disc_close(0); - disc_close(1); - disc_close(2); - disc_close(3); + for (i = 0; i < FDD_NUM; i++) + { + disc_close(i); + } dumpregs(0); closevideo(); device_close_all(); diff --git a/src/scsi.h b/src/scsi.h index 2c9280c29..e07317a77 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -78,20 +78,26 @@ /* SCSI Additional Sense Codes */ #define ASC_AUDIO_PLAY_OPERATION 0x00 +#define ASC_NOT_READY 0x04 #define ASC_ILLEGAL_OPCODE 0x20 #define ASC_LBA_OUT_OF_RANGE 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 #define ASC_INV_LUN 0x25 #define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 +#define ASC_WRITE_PROTECTED 0x27 #define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_INCOMPATIBLE_FORMAT 0x30 +#define ASC_CAPACITY_DATA_CHANGED 0x2A +#define ASC_INCOMPATIBLE_FORMAT 0x30 #define ASC_MEDIUM_NOT_PRESENT 0x3a #define ASC_DATA_PHASE_ERROR 0x4b #define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 +#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01 +#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02 +#define ASCQ_CAPACITY_DATA_CHANGED 0x09 #define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 +#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 +#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 /* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). Not that it means anything */ diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 7babc817a..f3c9bbbe2 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -35,6 +35,7 @@ #include "device.h" #include "cdrom.h" #include "scsi.h" +#include "scsi_disk.h" #include "scsi_aha154x.h" @@ -457,8 +458,6 @@ aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) static uint8_t aha154x_memory(uint8_t cmd) { - uint8_t r = 0xff; - pclog("AHA154x: MEMORY cmd=%02x\n", cmd); if (cmd == 0x27) { @@ -599,29 +598,6 @@ typedef struct { } ReplyInquireSetupInformation; #pragma pack(pop) -/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ -#pragma pack(push,1) -typedef struct { - uint8_t uBusType; - uint8_t uBiosAddress; - uint16_t u16ScatterGatherLimit; - uint8_t cMailbox; - uint32_t uMailboxAddressBase; - uint8_t uReserved1 :2, - fFastEISA :1, - uReserved2 :3, - fLevelSensitiveInterrupt:1, - uReserved3 :1; - uint8_t aFirmwareRevision[3]; - uint8_t fHostWideSCSI :1, - fHostDifferentialSCSI :1, - fHostSupportsSCAM :1, - fHostUltraSCSI :1, - fHostSmartTermination :1, - uReserved4 :3; -} ReplyInquireExtendedSetupInformation; -#pragma pack(pop) - #pragma pack(push,1) typedef struct { @@ -863,7 +839,7 @@ enum { }; -#ifdef xWALTJE +#ifdef WALTJE int aha_do_log = 1; # define ENABLE_AHA154X_LOG #else @@ -1355,39 +1331,15 @@ aha_readw(uint16_t port, void *priv) } -static uint32_t -aha_readl(uint16_t port, void *priv) -{ - return aha_read(port, priv); -} - - -/* This is BS - we just need a 'dev_present' indication.. --FvK */ -static int -aha_dev_present(uint8_t id, uint8_t lun) -{ - if (lun > 7) return(0); - - if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); - - if ((cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type == 4)) return(1); - - return(0); -} - - static void aha_write(uint16_t port, uint8_t val, void *priv) { int i = 0; uint8_t j = 0; aha_t *dev = (aha_t *)priv; - uint8_t max_id = 8; uint8_t Offset; MailboxInit_t *MailboxInit; ReplyInquireSetupInformation *ReplyISI; - ReplyInquireExtendedSetupInformation *ReplyIESI; - int cCharsToTransfer; pclog("AHA154X: Write Port 0x%02X, Value %02X\n", port, val); @@ -1745,13 +1697,6 @@ aha_writew(uint16_t Port, uint16_t Val, void *p) } -static void -aha_writeL(uint16_t Port, uint32_t Val, void *p) -{ - aha_write(Port, Val & 0xFF, p); -} - - static uint8_t ConvertSenseLength(uint8_t RequestSenseLength) { @@ -1824,6 +1769,8 @@ aha_disk_cmd(aha_t *dev) Lun = req->LUN; hdc_id = scsi_hard_disks[Id][Lun]; + if (hdc_id == 0xff) fatal("SCSI hard disk on %02i:%02i has disappeared\n", Id, Lun); + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", Id, Lun, hdc_id); @@ -1908,6 +1855,8 @@ aha_cdrom_cmd(aha_t *dev) Lun = req->LUN; cdrom_id = scsi_cdrom_drives[Id][Lun]; + if (cdrom_id == 0xff) fatal("SCSI CD-ROM on %02i:%02i has disappeared\n", Id, Lun); + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); @@ -2220,11 +2169,11 @@ aha_init(int chip, int has_bios) ResetDev = dev; dev->chip = chip; - dev->Base = device_get_config_int("addr"); + dev->Base = device_get_config_hex16("base"); dev->Irq = device_get_config_int("irq"); dev->DmaChannel = device_get_config_int("dma"); bios = device_get_config_int("bios"); - bios_addr = device_get_config_int("bios_addr"); + bios_addr = device_get_config_hex20("bios_addr"); if (dev->Base != 0) { io_sethandler(dev->Base, 4, @@ -2245,10 +2194,11 @@ aha_init(int chip, int has_bios) } } - for (i=0; i 7) return(0); - - if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); - - if ((cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type == 4)) return(1); - - return(0); -} - - static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); static void @@ -1020,7 +1004,6 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) int i = 0; uint8_t j = 0; Buslogic_t *bl = (Buslogic_t *)p; - uint8_t max_id = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 16 : 8; uint8_t Offset; MailboxInit_t *MailboxInit; ReplyInquireSetupInformation *ReplyISI; @@ -1130,8 +1113,6 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x01: -aha_0x01: - { bl->Mbx24bit = 1; MailboxInit = (MailboxInit_t *)bl->CmdBuf; @@ -1147,8 +1128,7 @@ aha_0x01: bl->Status &= ~STAT_INIT; bl->DataReplyLeft = 0; - } - break; + break; case 0x03: bl->DataBuf[0] = 0x00; @@ -1633,6 +1613,8 @@ BuslogicHDCommand(Buslogic_t *bl) Lun = req->LUN; hdc_id = scsi_hard_disks[Id][Lun]; + if (hdc_id == 0xff) fatal("SCSI hard disk on %02i:%02i has disappeared\n", Id, Lun); + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", Id, Lun, hdc_id); @@ -1717,6 +1699,8 @@ BuslogicCDROMCommand(Buslogic_t *bl) Lun = req->LUN; cdrom_id = scsi_cdrom_drives[Id][Lun]; + if (cdrom_id == 0xff) fatal("SCSI CD-ROM on %02i:%02i has disappeared\n", Id, Lun); + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); @@ -1913,7 +1897,7 @@ BuslogicProcessMailbox(Buslogic_t *bl) if (mb32.u.out.ActionCode != MBO_FREE) { /* We got the mailbox, mark it as free in the guest. */ - pclog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + pclog("BuslogicProcessMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); } @@ -2203,7 +2187,7 @@ BuslogicInit(int chip) chip = CHIP_BUSLOGIC_ISA; } bl->chip = chip; - bl->Base = device_get_config_int("addr"); + bl->Base = device_get_config_hex16("addr"); bl->PCIBase = 0; bl->MMIOBase = 0; bl->Irq = device_get_config_int("irq"); @@ -2233,14 +2217,16 @@ BuslogicInit(int chip) if (scsi_hard_disks[i][j] != 0xff) { SCSIDevices[i][j].LunType = SCSI_DISK; + pclog("Found SCSI disk: %02i:%02i\n", i, j); } } } - for (i=0; i> 9) - 1; + shdc[id].last_sector = 0; shdc[id].cdb_len = 12; } + + scsi_disk_insert(id); + + s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + + goto prepare_new_hard_disk; } else { /* Failed for another reason */ - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + scsi_hd_log("Failed for another reason\n"); + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + } return; } } @@ -272,41 +336,334 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) { fseeko64(shdf[id], 0x8, SEEK_SET); fread(&(shdc[id].base), 1, 4, shdf[id]); + fseeko64(shdf[id], 0xC, SEEK_SET); + full_size = 0; + fread(&full_size, 1, 4, shdf[id]); fseeko64(shdf[id], 0x10, SEEK_SET); fread(§or_size, 1, 4, shdf[id]); if (sector_size != 512) { /* Sector size is not 512 */ + scsi_hd_log("HDI: Sector size is not 512\n"); fclose(shdf[id]); - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + } return; } - fread(&(hdc[id].spt), 1, 4, shdf[id]); - fread(&(hdc[id].hpc), 1, 4, shdf[id]); - fread(&(hdc[id].tracks), 1, 4, shdf[id]); + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_load_error; + } + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; } else if (image_is_hdx(fn, 1)) { shdc[id].base = 0x28; + fseeko64(shdf[id], 8, SEEK_SET); + fread(&full_size, 1, 8, shdf[id]); fseeko64(shdf[id], 0x10, SEEK_SET); fread(§or_size, 1, 4, shdf[id]); if (sector_size != 512) { /* Sector size is not 512 */ + scsi_hd_log("HDX: Sector size is not 512\n"); fclose(shdf[id]); - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + } return; } - fread(&(hdc[id].spt), 1, 4, shdf[id]); - fread(&(hdc[id].hpc), 1, 4, shdf[id]); - fread(&(hdc[id].tracks), 1, 4, shdf[id]); + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_load_error; + } + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; fread(&(hdc[id].at_spt), 1, 4, shdf[id]); fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); } - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + else + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + } shdc[id].cdb_len = 12; + scsi_disk_insert(id); } + + fseeko64(shdf[id], 0, SEEK_END); + if (ftello64(shdf[id]) != (full_size + shdc[id].base)) + { + s = (full_size + shdc[id].base) - ftello64(shdf[id]); +prepare_new_hard_disk: + s >>= 9; + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } + } + + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + + fclose(shdf[id]); +} + +void scsi_reloadhd(int id) +{ + uint32_t sector_size = 512; + uint32_t zero = 0; + uint64_t signature = 0xD778A82044445459ll; + uint64_t full_size = 0; + uint64_t spt = 0, hpc = 0, tracks = 0; + int c; + uint64_t i = 0, s = 0;; + wchar_t *fn = hdc[id].fn; + + memset(empty_sector, 0, sizeof(empty_sector)); + + if(hdc[id].prev_fn == NULL) + { + return; + } + else + { + wcscpy(hdc[id].fn, hdc[id].prev_fn); + memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + } + + shdc[id].base = 0; + + if (shdf[id] != NULL) + { + fclose(shdf[id]); + shdf[id] = NULL; + } + + /* Try to open existing hard disk image */ + if (fn[0] == '.') + { + scsi_hd_log("File name starts with .\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + shdf[id] = _wfopen(fn, L"rb+"); + if (shdf[id] == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + if (hdc[id].wp) + { + scsi_hd_log("A write-protected image must exist\n"); + goto scsi_hd_reload_error; + } + + shdf[id] = _wfopen(fn, L"wb+"); + if (shdf[id] == NULL) + { +scsi_hd_reload_error: + scsi_hd_log("Unable to open image\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + else + { + memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); + if (image_is_hdi(fn)) + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + shdc[id].base = 0x1000; + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&(shdc[id].base), 1, 4, shdf[id]); + fwrite(&full_size, 1, 4, shdf[id]); + fwrite(§or_size, 1, 4, shdf[id]); + fwrite(&(hdc[id].spt), 1, 4, shdf[id]); + fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); + fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); + for (c = 0; c < 0x3f8; c++) + { + fwrite(&zero, 1, 4, shdf[id]); + } + } + else if (image_is_hdx(fn, 0)) + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + shdc[id].base = 0x28; + fwrite(&signature, 1, 8, shdf[id]); + fwrite(&full_size, 1, 8, shdf[id]); + fwrite(§or_size, 1, 4, shdf[id]); + fwrite(&(hdc[id].spt), 1, 4, shdf[id]); + fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); + fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + } + shdc[id].last_sector = 0; + shdc[id].cdb_len = 12; + } + + scsi_disk_insert(id); + + s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + + goto reload_prepare_new_hard_disk; + } + else + { + /* Failed for another reason */ + scsi_hd_log("Failed for another reason\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + } + else + { + memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); + if (image_is_hdi(fn)) + { + fseeko64(shdf[id], 0x8, SEEK_SET); + fread(&(shdc[id].base), 1, 4, shdf[id]); + fseeko64(shdf[id], 0xC, SEEK_SET); + full_size = 0; + fread(&full_size, 1, 4, shdf[id]); + fseeko64(shdf[id], 0x10, SEEK_SET); + fread(§or_size, 1, 4, shdf[id]); + if (sector_size != 512) + { + /* Sector size is not 512 */ + scsi_hd_log("HDI: Sector size is not 512\n"); + fclose(shdf[id]); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_reload_error; + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; + } + else if (image_is_hdx(fn, 1)) + { + shdc[id].base = 0x28; + fseeko64(shdf[id], 8, SEEK_SET); + fread(&full_size, 1, 8, shdf[id]); + fseeko64(shdf[id], 0x10, SEEK_SET); + fread(§or_size, 1, 4, shdf[id]); + if (sector_size != 512) + { + /* Sector size is not 512 */ + scsi_hd_log("HDX: Sector size is not 512\n"); + fclose(shdf[id]); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_reload_error; + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; + fread(&(hdc[id].at_spt), 1, 4, shdf[id]); + fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); + } + else + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + } + shdc[id].cdb_len = 12; + scsi_disk_insert(id); + } + + fseeko64(shdf[id], 0, SEEK_END); + if (ftello64(shdf[id]) != (full_size + shdc[id].base)) + { + s = (full_size + shdc[id].base) - ftello64(shdf[id]); +reload_prepare_new_hard_disk: + s >>= 9; + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } + } + + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; +} + +void scsi_unloadhd(int scsi_id, int scsi_lun, int id) +{ + if (wcslen(hdc[id].fn) == 0) + { + return; + } + + if (shdf[id] != NULL) + { + fclose(shdf[id]); + shdf[id] = NULL; + } + + shdc[id].last_sector = -1; + + memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + wcscpy(hdc[id].prev_fn, hdc[id].fn); + + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + + shdc[id].cdb_len = 12; + + fclose(shdf[id]); } void build_scsi_hd_map() @@ -326,7 +683,15 @@ void build_scsi_hd_map() scsi_hard_disks[i][j] = find_hdc_for_scsi_id(i, j); if (scsi_hard_disks[i][j] != 0xff) { - scsi_loadhd(i, j, scsi_hard_disks[i][j]); + memset(&(shdc[scsi_hard_disks[i][j]]), 0, sizeof(shdc[scsi_hard_disks[i][j]])); + if (wcslen(hdc[scsi_hard_disks[i][j]].fn) > 0) + { + scsi_loadhd(i, j, scsi_hard_disks[i][j]); + } + else + { + shdc[scsi_hard_disks[i][j]].cdb_len = 12; + } } } } @@ -334,7 +699,6 @@ void build_scsi_hd_map() int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { - int ret = 0; int size = 0; size = shdc[id].last_sector; @@ -477,7 +841,7 @@ static void scsi_hd_sense_clear(int id, int command) static void scsi_hd_cmd_error(uint8_t id) { shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; - if (shdc[id].unit_attention) + if (shdc[id].unit_attention & 3) { shdc[id].error |= MCR_ERR; } @@ -490,8 +854,8 @@ static void scsi_hd_cmd_error(uint8_t id) static void scsi_hd_unit_attention(uint8_t id) { - shdc[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (cdrom[id].unit_attention) + shdc[id].error = (SENSE_NOT_READY << 4) | ABRT_ERR; + if (shdc[id].unit_attention & 3) { shdc[id].error |= MCR_ERR; } @@ -510,6 +874,32 @@ static void scsi_hd_not_ready(uint8_t id) scsi_hd_cmd_error(id); } +#if 0 +static void scsi_hd_icmd_required(uint8_t id) +{ + scsi_hd_sense_key = SENSE_NOT_READY; + scsi_hd_asc = ASC_NOT_READY; + scsi_hd_ascq = ASCQ_INITIALIZING_COMMAND_REQUIRED; + scsi_hd_cmd_error(id); +} + +static void scsi_hd_capacity_data_changed(uint8_t id) +{ + scsi_hd_sense_key = SENSE_UNIT_ATTENTION; + scsi_hd_asc = ASC_CAPACITY_DATA_CHANGED; + scsi_hd_ascq = ASCQ_CAPACITY_DATA_CHANGED; + scsi_hd_cmd_error(id); +} +#endif + +static void scsi_hd_write_protected(uint8_t id) +{ + scsi_hd_sense_key = SENSE_UNIT_ATTENTION; + scsi_hd_asc = ASC_WRITE_PROTECTED; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + static void scsi_hd_invalid_lun(uint8_t id) { scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; @@ -586,78 +976,6 @@ void scsi_hd_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) } } -int scsi_hd_read_data(uint8_t id, uint32_t *len) -{ - uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; - - int temp_len = 0; - - int last_valid_data_pos = 0; - - uint64_t pos64 = (uint64_t) shdc[id].sector_pos; - - if (shdc[id].sector_pos > shdc[id].last_sector) - { - /* scsi_hd_log("SCSI HD %i: Trying to read beyond the end of disk\n", id); */ - scsi_hd_lba_out_of_range(id); - return 0; - } - - shdc[id].old_len = 0; - *len = 0; - - fseeko64(shdf[id], pos64 << 9, SEEK_SET); - fread(hdbufferb + shdc[id].data_pos, (shdc[id].sector_len << 9), 1, shdf[id]); - temp_len = (shdc[id].sector_len << 9); - - last_valid_data_pos = shdc[id].data_pos; - - shdc[id].data_pos += temp_len; - shdc[id].old_len += temp_len; - - *len += temp_len; - - scsi_hd_log("SCSI HD %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, hdbufferb[last_valid_data_pos + 0], hdbufferb[last_valid_data_pos + 1], hdbufferb[last_valid_data_pos + 2], hdbufferb[last_valid_data_pos + 3], hdbufferb[last_valid_data_pos + 4], hdbufferb[last_valid_data_pos + 5], hdbufferb[last_valid_data_pos + 6], hdbufferb[last_valid_data_pos + 7]); - - return 1; -} - -int scsi_hd_read_blocks(uint8_t id, uint32_t *len, int first_batch) -{ - int ret = 0; - - shdc[id].data_pos = 0; - - if (!shdc[id].sector_len) - { - scsi_hd_command_complete(id); - return -1; - } - - scsi_hd_log("Reading %i blocks starting from %i...\n", shdc[id].requested_blocks, shdc[id].sector_pos); - - scsi_hd_update_cdb(shdc[id].current_cdb, shdc[id].sector_pos, shdc[id].requested_blocks); - - ret = scsi_hd_read_data(id, len); - - scsi_hd_log("Read %i bytes of blocks...\n", *len); - - if (!ret) - { - return 0; - } - - shdc[id].sector_pos += shdc[id].requested_blocks; - shdc[id].sector_len -= shdc[id].requested_blocks; - - return 1; -} - -void scsi_disk_insert(uint8_t id) -{ - shdc[id].unit_attention = (hdc[id].bus == 5) ? 1 : 0; -} - /*SCSI Sense Initialization*/ void scsi_hd_sense_code_ok(uint8_t id) { @@ -680,14 +998,15 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) if (!(scsi_hd_command_flags[cdb[0]] & IMPLEMENTED)) { scsi_hd_log("SCSI HD %i: Attempting to execute unknown command %02X\n", id, cdb[0]); + /* pclog("SCSI HD %i: Attempting to execute unknown command %02X (%02X %02X)\n", id, cdb[0], ((cdb[1] >> 3) & 1) ? 0 : 1, cdb[2] & 0x3F); */ scsi_hd_illegal_opcode(id); return 0; } - if (hdc[id].bus == 5) + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { /* Removable disk, set ready state. */ - if (wcslen(hdd_fn[id]) > 0) + if (wcslen(hdc[id].fn) > 0) { ready = 1; } @@ -761,6 +1080,11 @@ static void scsi_hd_seek(uint8_t id, uint32_t pos) static void scsi_hd_rezero(uint8_t id) { + if (id == 255) + { + return; + } + shdc[id].sector_pos = shdc[id].sector_len = 0; scsi_hd_seek(id, 0); } @@ -775,6 +1099,8 @@ void scsi_hd_reset(uint8_t id) void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { + int is_ua = 0; + /*Will return 18 bytes of 0*/ if (alloc_length != 0) { @@ -788,7 +1114,8 @@ void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[13]=0; + buffer[13]=0x00; + is_ua = 1; } /* scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, hdbufferb[2], hdbufferb[12], hdbufferb[13]); */ @@ -808,10 +1135,10 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l { int ready = 1; - if (hdc[id].bus == 5) + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { /* Removable disk, set ready state. */ - if (wcslen(hdd_fn[id]) > 0) + if (wcslen(hdc[id].fn) > 0) { ready = 1; } @@ -851,10 +1178,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) unsigned size_idx; unsigned preamble_len; uint32_t alloc_length; - int ret; uint64_t pos64; - char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; - char device_identify_ex[14] = { '8', '6', 'B', '_', 'H', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + uint64_t full_size = 0; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; #if 0 int CdbLength; @@ -864,13 +1191,22 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].packet_len = 0; shdc[id].request_pos = 0; - device_identify[6] = id + 0x30; + device_identify[6] = (id / 10) + 0x30; + device_identify[7] = (id % 10) + 0x30; + + device_identify_ex[6] = (id / 10) + 0x30; + device_identify_ex[7] = (id % 10) + 0x30; + device_identify_ex[10] = emulator_version[0]; + device_identify_ex[12] = emulator_version[2]; + device_identify_ex[13] = emulator_version[3]; + + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + device_identify[4] = 'R'; + + device_identify_ex[4] = 'R'; + } - device_identify_ex[6] = id + 0x30; - device_identify_ex[9] = emulator_version[0]; - device_identify_ex[11] = emulator_version[2]; - device_identify_ex[12] = emulator_version[3]; - shdc[id].data_pos = 0; memcpy(shdc[id].current_cdb, cdb, shdc[id].cdb_len); @@ -958,20 +1294,15 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len = shdc[id].sector_len; shdc[id].requested_blocks = max_len; -#if 0 - ret = scsi_hd_read_blocks(id, &alloc_length, 1); - if (ret <= 0) - { - return; - } -#endif - pos64 = (uint64_t) shdc[id].sector_pos; if (shdc[id].requested_blocks > 0) { - fseeko64(shdf[id], pos64 << 9, SEEK_SET); - fread(hdbufferb, (shdc[id].sector_len << 9), 1, shdf[id]); + shdf[id] = _wfopen(hdc[id].fn, L"rb+"); + fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); + memset(hdbufferb, 0, shdc[id].sector_len << 9); + fread(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + fclose(shdf[id]); } alloc_length = shdc[id].packet_len = max_len << 9; @@ -986,17 +1317,23 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 1); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); } else { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } return; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_12: + if ((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) && hdc[id].wp) + { + scsi_hd_write_protected(id); + return; + } + switch(cdb[0]) { case GPCMD_WRITE_6: @@ -1031,8 +1368,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if (shdc[id].requested_blocks > 0) { - fseeko64(shdf[id], pos64 << 9, SEEK_SET); + shdf[id] = _wfopen(hdc[id].fn, L"rb+"); + fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); fwrite(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + fclose(shdf[id]); } alloc_length = shdc[id].packet_len = max_len << 9; @@ -1047,16 +1386,16 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 1); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); } else { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } return; case GPCMD_START_STOP_UNIT: - if (hdc[id].bus != 5) + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) { scsi_hd_illegal_opcode(id); break; @@ -1068,18 +1407,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) case 1: /* Start the disc and read the TOC. */ break; case 2: /* Eject the disc if possible. */ -#ifndef __unix -#if 0 - win_removable_disk_eject(id); -#endif -#endif + removable_disk_eject(id); break; case 3: /* Load the disc (close tray). */ -#ifndef __unix -#if 0 - win_removable_disk_reload(id); -#endif -#endif + removable_disk_reload(id); break; } @@ -1150,7 +1481,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) memset(hdbufferb, 0, 8); hdbufferb[0] = 0; /*SCSI HD*/ - if (hdc[id].bus == 5) + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { hdbufferb[1] = 0x80; /*Removable*/ } @@ -1204,6 +1535,7 @@ atapi_out: break; default: + /* pclog("SCSI HD %i: Attempting to execute pseudo-implemented command %02X\n", id, cdb[0]); */ scsi_hd_illegal_opcode(id); break; } @@ -1301,7 +1633,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].status = READY_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0xFF; - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_DATA_OUT: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); @@ -1314,7 +1646,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_DATA_IN: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); @@ -1327,7 +1659,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_ERROR: scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); diff --git a/src/scsi_disk.h b/src/scsi_disk.h new file mode 100644 index 000000000..59d210e69 --- /dev/null +++ b/src/scsi_disk.h @@ -0,0 +1,43 @@ +#pragma pack(push,1) +typedef struct { + /* Stuff for SCSI hard disks. */ + uint8_t cdb[16]; + uint8_t current_cdb[16]; + uint8_t max_cdb_len; + int requested_blocks; + int max_blocks_at_once; + uint16_t request_length; + int block_total; + int all_blocks_total; + uint32_t packet_len; + int packet_status; + uint8_t status; + uint8_t phase; + uint32_t pos; + int callback; + int total_read; + int unit_attention; + uint8_t sense[256]; + uint8_t previous_command; + uint8_t error; + uint16_t buffer[390144]; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t last_sector; + uint32_t seek_pos; + int data_pos; + int old_len; + int cdb_len_setting; + int cdb_len; + int request_pos; + uint64_t base; + uint8_t hd_cdb[16]; +} scsi_hard_disk_t; +#pragma pack(pop) + +extern scsi_hard_disk_t shdc[HDC_NUM]; + +extern void scsi_disk_insert(uint8_t id); +extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); +extern void scsi_reloadhd(int id); +extern void scsi_unloadhd(int scsi_id, int scsi_lun, int id); diff --git a/src/xtide.c b/src/xtide.c index ce827151b..78ca248fa 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -22,12 +22,12 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) switch (port & 0xf) { case 0x0: - writeidew(0, val | (xtide->data_high << 8)); + writeidew(8, val | (xtide->data_high << 8)); return; case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - writeide(0, (port & 0xf) | 0x1f0, val); + writeide(8, (port & 0xf) | 0x1f0, val); return; case 0x8: @@ -35,7 +35,7 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) return; case 0xe: - writeide(0, 0x3f6, val); + writeide(8, 0x3f6, val); return; } } @@ -49,19 +49,19 @@ static uint8_t xtide_read(uint16_t port, void *p) switch (port & 0xf) { case 0x0: - tempw = readidew(0); + tempw = readidew(8); xtide->data_high = tempw >> 8; return tempw & 0xff; case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - return readide(0, (port & 0xf) | 0x1f0); + return readide(8, (port & 0xf) | 0x1f0); case 0x8: return xtide->data_high; case 0xe: - return readide(0, 0x3f6); + return readide(8, 0x3f6); default: return 0xff; @@ -75,9 +75,7 @@ static void *xtide_init(void) memset(xtide, 0, sizeof(xtide_t)); rom_init(&xtide->bios_rom, L"roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); - ide_pri_disable(); - ide_sec_disable(); + ide_xtide_init(); io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); return xtide; @@ -102,9 +100,7 @@ static void *xtide_ps2_init(void) memset(xtide, 0, sizeof(xtide_t)); rom_init(&xtide->bios_rom, L"roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); - ide_pri_disable(); - ide_sec_disable(); + ide_xtide_init(); io_sethandler(0x0360, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); return xtide;