diff --git a/src/86box.h b/src/86box.h index d45b1bead..516356138 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,7 +1,42 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -#define emulator_version "1.20" -#define emulator_version_w L"1.20" +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Main emulator include file. + * + * Version: @(#)86box.h 1.0.2 2017/06/04 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ +#ifndef BOX_H +# define BOX_H -#define CONFIG_FILE L"86box.cfg" + +#if defined(ENABLE_BUSLOGIC_LOG) || \ + defined(ENABLE_CDROM_LOG) || \ + defined(ENABLE_D86F_LOG) || \ + defined(ENABLE_FDC_LOG) || \ + defined(ENABLE_IDE_LOG) || \ + defined(ENABLE_NIC_LOG) +# define ENABLE_LOG_TOGGLES 1 +#endif + +#if defined(ENABLE_LOG_BREAKPOINT) || defined(ENABLE_VRAM_DUMP) +# define ENABLE_LOG_COMMANDS 1 +#endif + +#define EMU_VERSION "2.00" +#define EMU_VERSION_W L"2.00" + +#define EMU_NAME "86Box" +#define EMU_NAME_W L"86Box" + +#define CONFIG_FILE_W L"86box.cfg" + + +#endif /*BOX_H*/ diff --git a/src/CPU/386.c b/src/CPU/386.c index 6bd69af85..074fa9696 100644 --- a/src/CPU/386.c +++ b/src/CPU/386.c @@ -28,6 +28,13 @@ uint32_t oldpc2; int trap; +uint16_t flags,eflags; +uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; + +x86seg gdt,ldt,idt,tr; +x86seg _cs,_ds,_es,_ss,_fs,_gs; +x86seg _oldds; + extern int cpl_override; @@ -40,6 +47,8 @@ uint16_t ea_rseg; int is486; int cgate32; +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; uint8_t romext[32768]; diff --git a/src/CPU/386_common.h b/src/CPU/386_common.h index a091a817d..562c2445d 100644 --- a/src/CPU/386_common.h +++ b/src/CPU/386_common.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Common 386 CPU code. + * + * Version: @(#)386_common.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern uint16_t ea_rseg; #undef readmemb @@ -8,39 +23,15 @@ extern uint16_t ea_rseg; #define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8)?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#if 0 -#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - x86gpf("check_io_perm(): no permission",0); \ - return 1; \ - } \ - } - -#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ - { \ - tempi = checkio(port); \ - if (cpu_state.abrt) break; \ - if (tempi) \ - { \ - x86gpf("checkio_perm(): no permission",0); \ - break; \ - } \ - } -#endif - #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \ { \ int tempi = checkio(port); \ @@ -138,8 +129,8 @@ static __inline uint16_t fastreadw(uint32_t a) uint16_t val; if ((a&0xFFF)>0xFFE) { - val = readmemb(0, a); - val |= (readmemb(0, a + 1) << 8); + val = fastreadb(a); + val |= (fastreadb(a + 1) << 8); return val; } if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); @@ -169,10 +160,8 @@ static __inline uint32_t fastreadl(uint32_t a) } return *((uint32_t *)&pccache2[a]); } - val =readmemb(0,a); - val |=(readmemb(0,a+1)<<8); - val |=(readmemb(0,a+2)<<16); - val |=(readmemb(0,a+3)<<24); + val = fastreadw(a); + val |= (fastreadw(a + 2) << 16); return val; } diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 06066223f..a362f50da 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; @@ -1278,6 +1280,19 @@ int dontprint=0; #define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG)) +static int cpu_cycle_period(void) +{ + switch(cpu_pci_speed) + { + case 333333333: + return is_pentium ? 1000 : 1333; + break; + default: + return 1000; + break; + } +} + static int cycles_main = 0; void exec386_dynarec(int cycs) { @@ -1292,8 +1307,42 @@ void exec386_dynarec(int cycs) while (cycles_main > 0) { int cycles_start; - - cycles += 1000; + +#if 0 + switch(cpu_pci_speed) + { + case 16000000: + cycles += 640; + break; + case 20000000: + cycles += 800; + break; + case 25000000: + default: + cycles += 1000; + break; + case 27500000: + cycles += 1100; + break; + case 30000000: + cycles += 1200; + break; + case 333333333: + cycles += 1333; + break; + case 37500000: + cycles += 1500; + break; + case 40000000: + cycles += 1600; + break; + case 41666667: + cycles += 1666; + break; + } +#endif + cycles += cpu_cycle_period(); + cycles_start = cycles; timer_start_period(cycles << TIMER_SHIFT); @@ -1372,7 +1421,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 +1433,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/386_ops.h b/src/CPU/386_ops.h index 4e5d78125..0217c384d 100644 --- a/src/CPU/386_ops.h +++ b/src/CPU/386_ops.h @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 286/386+ instruction handlers list. + * + * Version: @(#)386_ops.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include "x86_ops.h" diff --git a/src/CPU/808x.c b/src/CPU/808x.c index c102fa45f..32a52e955 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x CPU emulation. + * + * Version: @(#)808x.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*SHR AX,1 4 clocks - fetch opcode @@ -46,12 +61,14 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val); uint8_t readmemb(uint32_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=4; + if (readlookup2 == NULL) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } uint8_t readmembf(uint32_t a) { + if (readlookup2 == NULL) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } @@ -59,6 +76,7 @@ uint8_t readmembf(uint32_t a) uint16_t readmemw(uint32_t s, uint16_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086); + if (readlookup2 == NULL) return readmemwl(s,a); if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s,a); else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); } @@ -76,6 +94,7 @@ void writemembl(uint32_t addr, uint8_t val); void writememb(uint32_t a, uint8_t v) { memcycs+=4; + if (writelookup2 == NULL) writemembl(a,v); if (writelookup2[(a)>>12]==-1) writemembl(a,v); else *(uint8_t *)(writelookup2[a >> 12] + a) = v; } @@ -83,12 +102,14 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val); void writememw(uint32_t s, uint32_t a, uint16_t v) { memcycs+=(8>>is8086); + if (writelookup2 == NULL) writememwl(s,a,v); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } void writememll(uint32_t seg, uint32_t addr, uint32_t val); void writememl(uint32_t s, uint32_t a, uint32_t v) { + if (writelookup2 == NULL) writememll(s,a,v); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s,a,v); else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } @@ -546,6 +567,7 @@ void resetx86() resets++; ins = 0; use32=0; + cpu_cur_status = 0; stack32=0; cpu_state.pc=0; msw=0; @@ -583,6 +605,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..e85f5315f 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -866,6 +866,8 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && codegen_flat_ds) + return; if (IS_32_ADDR(&seg->base)) { @@ -900,6 +902,8 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && codegen_flat_ds) + return; if (IS_32_ADDR(&seg->base)) { @@ -926,6 +930,9 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + return; + if (IS_32_ADDR(&seg->base)) { addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ @@ -962,7 +969,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1030,7 +1042,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1049,16 +1066,14 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -1078,18 +1093,17 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x66); /*MOV AX,-1[RDI+RSI]*/ + addbyte(4+2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ addbyte(0x8b); - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12+4+6); /*slowpath:*/ @@ -1114,7 +1128,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1133,16 +1152,14 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -1162,17 +1179,16 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ - addbyte(0x44); + addbyte(3+2); + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12+4+6); /*slowpath:*/ @@ -1190,7 +1206,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1209,16 +1230,14 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 7[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -1238,18 +1257,17 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x48); /*MOV RAX,-7[RDI+RSI]*/ + addbyte(4+2); + addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ addbyte(0x8b); - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12+4+6); /*slowpath:*/ @@ -1309,7 +1327,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1388,7 +1411,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1407,16 +1435,14 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -1436,29 +1462,27 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 6:5)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 5:4)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 6:5)+2); + addbyte(((host_reg & 8) ? 5:4)+2); if (host_reg & 8) { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x44); addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } else { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12+4+6); @@ -1478,7 +1502,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1497,16 +1526,14 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -1526,27 +1553,25 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 4:3)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); + addbyte(((host_reg & 8) ? 4:3)+2); if (host_reg & 8) { addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } else { addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12+4+6); @@ -1566,7 +1591,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1585,16 +1615,14 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 7[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -1614,28 +1642,26 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); + addbyte(4+2); if (host_reg & 8) { - addbyte(0x4c); /*MOV -7[RDI+RSI],host_reg*/ + addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); } else { - addbyte(0x48); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12+4+6); @@ -5252,7 +5278,12 @@ static void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5299,12 +5330,15 @@ 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + 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 +5362,8 @@ 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); @@ -5373,7 +5408,12 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5416,15 +5456,21 @@ 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + 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 +5521,8 @@ 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + *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 +5557,12 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5553,15 +5605,21 @@ 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + 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 +5670,8 @@ 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 && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + *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 +5701,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5709,7 +5773,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5728,16 +5797,14 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -5757,18 +5824,17 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x66); /*MOV AX,-1[RDI+RSI]*/ + addbyte(4+2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ addbyte(0x8b); - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12); /*slowpath:*/ @@ -5785,7 +5851,12 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5804,16 +5875,14 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -5833,17 +5902,16 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+2); + addbyte(0x54); /*JNE slowpath*/ + addbyte(3+2+3+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); + addbyte(3+2); addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12); /*slowpath:*/ @@ -5883,7 +5951,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 +6029,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); @@ -5974,16 +6054,14 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x18); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -6003,29 +6081,27 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 6:5)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 5:4)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 6:5)+2); + addbyte(((host_reg & 8) ? 5:4)+2); if (host_reg & 8) { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x44); addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } else { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12); @@ -6038,7 +6114,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); @@ -6057,16 +6139,14 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x18); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -6086,27 +6166,25 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 4:3)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); + addbyte(((host_reg & 8) ? 4:3)+2); if (host_reg & 8) { - addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } else { - addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x44 | (host_reg << 3)); + addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12); diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h index c8c18a28c..5251884b7 100644 --- a/src/CPU/codegen_ops_x86.h +++ b/src/CPU/codegen_ops_x86.h @@ -616,6 +616,8 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if (seg == &_ds && codegen_flat_ds) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -637,6 +639,8 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if (seg == &_ds && codegen_flat_ds) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -650,6 +654,9 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + return; + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ addbyte(0x05); addlong((uint32_t)&seg->limit_low); @@ -675,9 +682,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 +701,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +721,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +739,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +760,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +780,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +799,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +820,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +858,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +879,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +900,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +921,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +942,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +963,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +994,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +3920,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +3938,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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 +3956,17 @@ 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + 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..c5214bd4b 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -22,6 +22,7 @@ #endif +int codegen_flat_ds, codegen_flat_ss; int codegen_flags_changed = 0; int codegen_fpu_entered = 0; int codegen_fpu_loaded_iq[8]; @@ -274,13 +275,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; @@ -386,6 +387,9 @@ void codegen_block_start_recompile(codeblock_t *block) codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; block->was_recompiled = 1; + + codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; + codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; } void codegen_block_remove() diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index a42b32104..a4f0ffe59 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -22,6 +22,7 @@ #include #endif +int codegen_flat_ds, codegen_flat_ss; int mmx_ebx_ecx_loaded; int codegen_flags_changed = 0; int codegen_fpu_entered = 0; @@ -135,31 +136,29 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 1[EDX]*/ - addbyte(0x7a); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x0f); /*MOVZX EAX, -1[EDX+EDI]W*/ + addbyte(4+1); + addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ addbyte(0xb7); - addbyte(0x44); + addbyte(0x04); addbyte(0x3a); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -192,30 +191,28 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 3[EDX]*/ - addbyte(0x7a); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x8b); /*MOV EAX, -3[EDX+EDI]*/ - addbyte(0x44); + addbyte(3+1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); addbyte(0x3a); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -245,34 +242,32 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_Q() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 7[EDX]*/ - addbyte(0x7a); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+4+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+4+1); + addbyte(3+4+1); addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x44); + addbyte(0x04); addbyte(0x3a); - addbyte(-7); addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ addbyte(0x54); addbyte(0x3a); - addbyte(-7+4); + addbyte(4); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -351,31 +346,29 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 1[ESI]*/ - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ + addbyte(4+1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ addbyte(0x89); - addbyte(0x44 | (REG_CX << 3)); + addbyte(0x04 | (REG_CX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -407,30 +400,28 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 3[ESI]*/ - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ - addbyte(0x44 | (REG_ECX << 3)); + addbyte(3+1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -462,34 +453,32 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q() addbyte(0xf2); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 7[ESI]*/ - addbyte(0x7e); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+4+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+4+1); - addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ - addbyte(0x44 | (REG_EBX << 3)); + addbyte(3+4+1); + addbyte(0x89); /*MOV [EDI+ESI],EBX*/ + addbyte(0x04 | (REG_EBX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); - addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ + addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ addbyte(0x44 | (REG_ECX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7+4); + addbyte(4); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -513,7 +502,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -575,7 +566,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -584,31 +577,29 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 1[EDX]*/ - addbyte(0x7a); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x0f); /*MOVZX EEX, -1[EDX+EDI]W*/ + addbyte(4+1); + addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ addbyte(0xb7); - addbyte(0x4c); + addbyte(0x0c); addbyte(0x3a); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -644,7 +635,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -653,30 +646,28 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 3[EDX]*/ - addbyte(0x7a); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x8b); /*MOV ECX, -3[EDX+EDI]*/ - addbyte(0x4c); + addbyte(3+1); + addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ + addbyte(0x0c); addbyte(0x3a); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -712,7 +703,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -770,7 +763,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -780,31 +775,29 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 1[ESI]*/ - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ + addbyte(4+1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ addbyte(0x89); - addbyte(0x44 | (REG_CX << 3)); + addbyte(0x04 | (REG_CX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -836,7 +829,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -846,30 +841,28 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 3[ESI]*/ - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ - addbyte(0x44 | (REG_ECX << 3)); + addbyte(3+1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -1401,12 +1394,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; @@ -1487,6 +1479,9 @@ void codegen_block_start_recompile(codeblock_t *block) block->TOP = cpu_state.TOP; block->was_recompiled = 1; + + codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; + codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; } void codegen_block_remove() diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index 453e8626a..0f12a59f1 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -1,8 +1,25 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * Version: @(#)cpu.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ #include "../ibm.h" #include "cpu.h" +#include "../device.h" #include "../model.h" #include "../io.h" #include "x86_ops.h" @@ -74,6 +91,9 @@ int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; +int cpu_cyrix_alignment; + +int hasfpu; uint64_t cpu_CR4_mask; @@ -81,6 +101,7 @@ int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; int cpu_prefetch_cycles, cpu_prefetch_width; int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; +int cpu_pci_speed; int is286, is386; int israpidcad, is_pentium; @@ -132,6 +153,7 @@ int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer; int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner; int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; +int timing_misaligned; static struct { @@ -183,6 +205,15 @@ CPU cpus_pcjr[] = {"", -1, 0, 0, 0, 0, 0,0,0,0} }; +CPU cpus_europc[] = +{ + /*8088 EuroPC*/ + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"", -1, 0, 0, 0, 0} +}; + CPU cpus_8086[] = { /*8086 standard*/ @@ -405,7 +436,7 @@ CPU cpus_Cx486[] = {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7}, {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9}, {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, + {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, {"", -1, 0, 0, 0} }; @@ -617,11 +648,6 @@ void cpu_set() if (enable_external_fpu) { hasfpu = 1; - if (cpu_s->cpu_type == CPU_i486SX) - { - /* The 487SX is a full implementation of the 486DX and takes over the entire CPU's operation. */ - cpu_s->cpu_type = CPU_i486DX; - } } } @@ -731,7 +757,10 @@ void cpu_set() } memset(&msr, 0, sizeof(msr)); - + + timing_misaligned = 0; + cpu_cyrix_alignment = 0; + switch (cpu_s->cpu_type) { case CPU_8088: @@ -925,6 +954,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_486DLC: @@ -958,6 +988,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_i486SX: @@ -991,6 +1022,7 @@ void cpu_set() timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_Am486SX: @@ -1025,6 +1057,7 @@ void cpu_set() timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_Cx486S: @@ -1058,6 +1091,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_Cx5x86: @@ -1090,6 +1124,8 @@ void cpu_set() timing_jmp_rm = 5; timing_jmp_pm = 7; timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; break; case CPU_WINCHIP: @@ -1128,6 +1164,8 @@ void cpu_set() timing_jmp_pm = 7; timing_jmp_pm_gate = 17; codegen_timing_set(&codegen_timing_winchip); + timing_misaligned = 2; + cpu_cyrix_alignment = 1; break; case CPU_PENTIUM: @@ -1160,6 +1198,7 @@ void cpu_set() timing_jmp_rm = 3; timing_jmp_pm = 3; timing_jmp_pm_gate = 18; + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1199,6 +1238,7 @@ void cpu_set() timing_jmp_rm = 3; timing_jmp_pm = 3; timing_jmp_pm_gate = 18; + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1237,6 +1277,8 @@ void cpu_set() timing_jmp_rm = 1; timing_jmp_pm = 4; timing_jmp_pm_gate = 14; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1275,6 +1317,8 @@ void cpu_set() timing_jmp_rm = 1; timing_jmp_pm = 4; timing_jmp_pm_gate = 14; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1296,6 +1340,8 @@ void cpu_set() timing_mml = 2; timing_bt = 5-1; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1347,6 +1393,8 @@ void cpu_set() timing_jmp_rm = 1; timing_jmp_pm = 4; timing_jmp_pm_gate = 14; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1369,6 +1417,7 @@ void cpu_set() timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1388,6 +1437,7 @@ void cpu_set() timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1420,6 +1470,7 @@ void cpu_set() timing_mml = 1; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1453,6 +1504,7 @@ void cpu_set() timing_mml = 1; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1486,6 +1538,7 @@ void cpu_set() timing_mml = 1; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index cbf7b7516..b792b36b8 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * Version: @(#)cpu.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef _CPU_H_ #define _CPU_H_ @@ -65,6 +82,8 @@ extern int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_g extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; +extern int timing_misaligned; + typedef struct { @@ -107,6 +126,7 @@ extern CPU cpus_Pentium2[]; extern CPU cpus_Pentium2D[]; extern CPU cpus_pcjr[]; +extern CPU cpus_europc[]; extern CPU cpus_pc1512[]; extern CPU cpus_ibmat[]; extern CPU cpus_ps1_m2011[]; @@ -117,6 +137,8 @@ extern int cpu_iscyrix; extern int cpu_16bitbus; extern int cpu_busspeed; extern int cpu_multi; +/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ +extern int cpu_cyrix_alignment; extern int cpu_hasrdtsc; extern int cpu_hasMSR; @@ -138,6 +160,7 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ extern int cpu_prefetch_cycles, cpu_prefetch_width; extern int cpu_waitstates; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; +extern int cpu_pci_speed; extern uint64_t tsc; diff --git a/src/CPU/x86.h b/src/CPU/x86.h index 565d52591..deb210cb6 100644 --- a/src/CPU/x86.h +++ b/src/CPU/x86.h @@ -102,3 +102,6 @@ void x86gpf(char *s, uint16_t error); extern uint16_t zero; extern int x86_was_reset; + +extern int codegen_flat_ds; +extern int codegen_flat_ss; diff --git a/src/CPU/x86_ops_i686.h b/src/CPU/x86_ops_i686.h index b684e1195..84a10c28b 100644 --- a/src/CPU/x86_ops_i686.h +++ b/src/CPU/x86_ops_i686.h @@ -1,6 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. + * + * Version: @(#)x86_ops_i686.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + static int internal_illegal(char *s) { cpu_state.pc = cpu_state.oldpc; diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h index a2b4f6f31..7734217eb 100644 --- a/src/CPU/x86_ops_misc.h +++ b/src/CPU/x86_ops_misc.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Miscellaneous x86 CPU Instructions. + * + * Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + static int opCBW(uint32_t fetchdat) { AH = (AL & 0x80) ? 0xff : 0; @@ -755,9 +773,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 +823,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..c200b3121 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 CPU segment emulation. + * + * Version: @(#)x86seg.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include @@ -159,6 +174,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 +217,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 +304,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 +358,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) { @@ -349,6 +404,10 @@ void loadseg(uint16_t seg, x86seg *s) } #endif s->checked = 0; + if (s == &_ds) + codegen_flat_ds = 0; + if (s == &_ss) + codegen_flat_ss = 0; } else { @@ -358,6 +417,26 @@ void loadseg(uint16_t seg, x86seg *s) if (s == &_ss) stack32 = 0; s->checked = 1; + if (s == &_ds) + codegen_flat_ds = 0; + if (s == &_ss) + codegen_flat_ss = 0; + } + + 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; } } @@ -426,8 +505,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 +608,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 +621,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 +718,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 +904,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 +923,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 +1079,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 +1096,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 +1175,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 +1319,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 +1427,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 +1449,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 +1644,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 +1729,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 +1883,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 +1901,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 +1990,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 +2073,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 +2095,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 +2285,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/CPU/x86seg.h b/src/CPU/x86seg.h index 4a36f360b..f4badadf4 100644 --- a/src/CPU/x86seg.h +++ b/src/CPU/x86seg.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 CPU segment emulation. + * + * Version: @(#)x86seg.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void do_seg_load(x86seg *s, uint16_t *segdat); diff --git a/src/CPU/x87_ops.h b/src/CPU/x87_ops.h index e212c6ccb..b9320081f 100644 --- a/src/CPU/x87_ops.h +++ b/src/CPU/x87_ops.h @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include #include diff --git a/src/CPU/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h index ed083b921..39a14c4fb 100644 --- a/src/CPU/x87_ops_loadstore.h +++ b/src/CPU/x87_ops_loadstore.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + static int opFILDiw_a16(uint32_t fetchdat) { int16_t temp; diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ea775f4c0..a6663057d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -6,11 +6,11 @@ # # This file is part of the 86Box distribution. # -# Modified Makefile for Win32 MinGW 32-bit environment. +# Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.16 2017/05/23 +# Version: @(#)Makefile.mingw 1.0.25 2017/06/04 # -# Authors: Kotori, +# Authors: Miran Grca, # Fred N. van Kempen, # Sarah Walker, # Richard G., @@ -33,7 +33,16 @@ endif >>>>>>> master # Add feature selections here. -# -DBUGGER adds the ISA BusBugger emulation. +# -DANSI_CFG forces the config file to ANSI encoding. +# -DENABLE_VRAM_DUMP enables Video Ram dumping. +# -DENABLE_LOG_BREAKPOINT enables extra logging. +# -DENABLE_BUSLOGIC_LOG enables extra logging. +# -DENABLE_CDROM_LOG enables extra logging. +# -DENABLE_D86F_LOG enables extra logging. +# -DENABLE_FDC_LOG enables extra logging. +# -DENABLE_IDE_LOG enables extra logging. +# -DENABLE_SERIAL_LOG enables extra logging. +# -DENABLE_NIC_LOG enables extra logging. ifndef EXTRAS EXTRAS = endif @@ -43,7 +52,13 @@ ifndef DEBUG DEBUG = n endif ifndef OPTIM -OPTIM = y +OPTIM = n +endif +ifndef RELEASE +RELEASE = n +endif +ifndef USB +USB = n endif ifndef X64 X64 = n @@ -133,7 +148,8 @@ SYSOBJ = model.o \ sis496.o \ wd76c10.o \ acer386sx.o acerm3a.o amstrad.o \ - compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ + compaq.o laserxt.o jim.o \ + olivetti_m24.o ps1.o ps2.o ps2_mca.o \ tandy_eeprom.o tandy_rom.o DEVOBJ = bugger.o lpt.o serial.o \ um8669f.o pc87306.o sis85c471.o w83877f.o \ @@ -153,7 +169,9 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc_random.o disc_td0.o \ cdrom.o \ cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o +ifdef USB USBOBJ = usb.o +endif NETOBJ = network.o \ net_pcap.o net_slirp.o \ net_ne2000.o @@ -173,7 +191,8 @@ SNDOBJ = sound.o \ snd_sn76489.o snd_ssi2001.o snd_wss.o \ snd_ym7128.o VIDOBJ = video.o \ - vid_cga.o vid_cga_comp.o vid_mda.o vid_ega.o \ + vid_cga.o vid_cga_comp.o vid_mda.o \ + vid_ega.o vid_ega_render.o \ vid_vga.o vid_svga.o vid_svga_render.o \ vid_hercules.o vid_herculesplus.o vid_incolor.o \ vid_colorplus.o \ @@ -200,8 +219,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) \ @@ -212,9 +231,9 @@ SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ ip_input.o queue.o tcp_input.o debug.o ip_output.o \ sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ - -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ - -lstdc++ -lpsapi -static-libstdc++ -static-libgcc +LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ + -mwindows -lcomctl32 -lwinmm -lwsock32 -liphlpapi -lpsapi \ + -static-libstdc++ -static -lstdc++ -static-libgcc -static -lgcc # Build rules. @@ -235,17 +254,14 @@ all: $(PROG).exe pcap_if.exe $(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe \ - $(OBJ) $(LZFOBJ) $(SLIRPOBJ) \ - $(LIBS) #-static -Lpcap -lwpcapdelay + @$(CC) -o $(PROG).exe $(OBJ) $(LZFOBJ) $(SLIRPOBJ) $(LIBS) ifneq ($(DEBUG), y) @strip $(PROG).exe endif -pcap_if.exe: pcap_if.o pcap_if.res +pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res @echo Linking pcap_if.exe .. - @$(CC) -o pcap_if.exe \ - pcap_if.o pcap_if.res -static -Lpcap -lwpcapdelay + @$(CC) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res ifneq ($(DEBUG), y) @strip pcap_if.exe endif @@ -253,13 +269,13 @@ endif clean: - rm *.o - rm *.exe - rm *.res + -rm *.o + -rm *.exe + -rm *.res 86Box.res: 86Box.rc @echo Processing $< - @$(WINDRES) $(RFLAGS) -i win/86Box.rc -o 86Box.res + @$(WINDRES) $(RFLAGS) $(EXTRAS) -i win/86Box.rc -o 86Box.res pcap_if.res: pcap_if.rc @echo Processing $< diff --git a/src/Makefile_AMD.mingw b/src/Makefile_AMD.mingw deleted file mode 100644 index 436b11d5f..000000000 --- a/src/Makefile_AMD.mingw +++ /dev/null @@ -1,2 +0,0 @@ -include Makefile.mingw -CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign \ No newline at end of file diff --git a/src/Makefile_AMD.mingw64 b/src/Makefile_AMD.mingw64 deleted file mode 100644 index d891ed4a4..000000000 --- a/src/Makefile_AMD.mingw64 +++ /dev/null @@ -1,2 +0,0 @@ -include Makefile.mingw64 -CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign \ No newline at end of file diff --git a/src/SOUND/filters.h b/src/SOUND/filters.h index 6269b55e3..528bf0b05 100644 --- a/src/SOUND/filters.h +++ b/src/SOUND/filters.h @@ -131,10 +131,10 @@ static __inline float high_cut_iir(int i, float NewSample) { #undef NCoef -#define NCoef 1 +#define NCoef 2 static __inline float sb_iir(int i, float NewSample) { -/* float ACoef[NCoef+1] = { + float ACoef[NCoef+1] = { 0.03356837051492005100, 0.06713674102984010200, 0.03356837051492005100 @@ -144,9 +144,9 @@ static __inline float sb_iir(int i, float NewSample) { 1.00000000000000000000, -1.41898265221812010000, 0.55326988968868285000 - };*/ + }; - float ACoef[NCoef+1] = { +/* float ACoef[NCoef+1] = { 0.17529642630084405000, 0.17529642630084405000 }; @@ -154,7 +154,8 @@ static __inline float sb_iir(int i, float NewSample) { float BCoef[NCoef+1] = { 1.00000000000000000000, -0.64940759319751051000 - }; + };*/ + static float y[2][NCoef+1]; /* output samples */ static float x[2][NCoef+1]; /* input samples */ int n; diff --git a/src/SOUND/snd_dbopl.cc b/src/SOUND/snd_dbopl.cc index cecc1c35e..cf4bc1ebe 100644 --- a/src/SOUND/snd_dbopl.cc +++ b/src/SOUND/snd_dbopl.cc @@ -88,7 +88,7 @@ void opl_write(int nr, uint16_t addr, uint8_t val) if (!(addr & 1)) { if (!opl[nr].is_opl3 || !opl3_type) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff; + opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & (opl[nr].is_opl3 ? 0x1ff : 0xff); else opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; } 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_mpu401.c b/src/SOUND/snd_mpu401.c index 474d717b9..60e3bd1c6 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -1,10 +1,35 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Roland MPU-401 emulation. + * + * Version: @(#)sound_mpu401.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * DOSBox Team, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2008-2017 DOSBox Team. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #include "../ibm.h" +#include "../device.h" #include "../io.h" #include "../pic.h" #include "../timer.h" #include "../win/plat_midi.h" /*YUCK*/ +#include "sound.h" #include "snd_mpu401.h" +#include #include enum @@ -16,6 +41,8 @@ enum static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); static void MPU401_EOIHandlerDispatch(void *p); +int mpu401_standalone_enable = 0; + static int mpu401_event_callback = 0; static int mpu401_eoi_callback = 0; static int mpu401_reset_callback = 0; @@ -135,7 +162,7 @@ static void MPU401_ResetDone(void *p) static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) { uint8_t i; - + if (mpu->state.reset) { mpu->state.cmd_pending=val+1; @@ -274,7 +301,9 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) mpu401_reset_callback = MPU401_RESETBUSY * 33 * TIMER_USEC; mpu->state.reset=1; MPU401_Reset(mpu); +#if 0 if (mpu->mode==M_UART) return;//do not send ack in UART mode +#endif break; case 0x3f: /* UART mode */ pclog("MPU-401:Set UART mode %X\n",val); @@ -706,6 +735,14 @@ next_event: void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) { +#if 0 + if (mode != M_INTELLIGENT) + { + mpu401_uart_init(mpu, addr); + return; + } +#endif + mpu->status = STATUS_INPUT_NOT_READY; mpu->irq = irq; mpu->queue_used = 0; @@ -727,3 +764,118 @@ void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) MPU401_Reset(mpu); } + +void mpu401_device_add(void) +{ + char *n; + + if (!mpu401_standalone_enable) + { + return; + } + + n = sound_card_get_internal_name(sound_card_current); + if (n != NULL) + { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + { + return; + } + } + + device_add(&mpu401_device); +} + +void *mpu401_standalone_init() +{ + mpu_t *mpu; + + mpu = malloc(sizeof(mpu_t)); + memset(mpu, 0, sizeof(mpu_t)); + + pclog("mpu_init\n"); + mpu401_init(mpu, device_get_config_hex16("base"), device_get_config_int("irq"), device_get_config_int("mode")); + + return mpu; +} + +void mpu401_standalone_close(void *p) +{ + mpu_t *mpu = (mpu_t *)p; + + free(mpu); +} + +static device_config_t mpu401_standalone_config[] = +{ + { + "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, + { + { + "0x300", 0x300 + }, + { + "0x330", 0x330 + }, + { + "" + } + } + }, + { + "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, + { + "mode", "Mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + +device_t mpu401_device = +{ + "MPU-401 (Standalone)", + 0, + mpu401_standalone_init, + mpu401_standalone_close, + NULL, + NULL, + NULL, + NULL, + mpu401_standalone_config +}; diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h index 8cb721883..41c1e9240 100644 --- a/src/SOUND/snd_mpu401.h +++ b/src/SOUND/snd_mpu401.h @@ -1,3 +1,25 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Roland MPU-401 emulation. + * + * Version: @(#)sound_mpu401.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * DOSBox Team, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2008-2017 DOSBox Team. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #define MPU401_VERSION 0x15 #define MPU401_REVISION 0x01 #define MPU401_QUEUE 32 @@ -21,6 +43,8 @@ typedef enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND} Mp typedef struct mpu_t { + int uart_mode; + uint8_t rx_data; int intelligent; MpuMode mode; int irq; @@ -61,3 +85,10 @@ typedef struct mpu_t uint8_t MPU401_ReadData(mpu_t *mpu); void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); + +extern int mpu401_standalone_enable; + +void mpu401_device_add(void); +device_t mpu401_device; + +void mpu401_uart_init(mpu_t *mpu, uint16_t addr); diff --git a/src/SOUND/snd_opl.c b/src/SOUND/snd_opl.c index d04b7be9a..c5ccc6070 100644 --- a/src/SOUND/snd_opl.c +++ b/src/SOUND/snd_opl.c @@ -88,8 +88,8 @@ void opl2_update2(opl_t *opl) opl2_update(1, &opl->buffer[opl->pos*2 + 1], sound_pos_global - opl->pos); for (; opl->pos < sound_pos_global; opl->pos++) { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 4) + ((opl->filtbuf[0] * 11) / 16); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 4) + ((opl->filtbuf[1] * 11) / 16); + opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); + opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); } } } @@ -101,8 +101,8 @@ void opl3_update2(opl_t *opl) opl3_update(0, &opl->buffer[opl->pos*2], sound_pos_global - opl->pos); for (; opl->pos < sound_pos_global; opl->pos++) { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 4) + ((opl->filtbuf[0] * 11) / 16); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 4) + ((opl->filtbuf[1] * 11) / 16); + opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); + opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); } } } diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 40bfd4213..179a449ee 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound Blaster emulation. + * + * Version: @(#)sound_sb.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #include #include "../ibm.h" #include "../io.h" @@ -6,6 +26,7 @@ #include "../rom.h" #include "../device.h" #include "sound.h" +#include "snd_dbopl.h" #include "snd_emu8k.h" #include "snd_mpu401.h" #include "snd_opl.h" @@ -43,9 +64,9 @@ typedef struct sb_t static int sb_att[]= { - 310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479, - 4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845, - 39036,46395,55140,65535 + 50,65,82,103,130,164,207,260,328,413,520,655,825,1038,1307, + 1645,2072,2608,3283,4134,5205,6553,8250,10385,13075,16461,20724,26089, + 32845,41349,52055,65535 }; static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) @@ -61,8 +82,8 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 51000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 51000) >> 16); if (sb->mixer.filter) { @@ -112,8 +133,8 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (opl3_type ? 47000 : 51000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (opl3_type ? 47000 : 51000)) >> 16); if (sb->mixer.filter) { @@ -245,7 +266,14 @@ uint8_t sb_pro_mixer_read(uint16_t addr, void *p) if (!(addr & 1)) return mixer->index; - return mixer->regs[mixer->index]; + switch (mixer->index) + { + case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: + case 0x22: case 0x26: case 0x28: case 0x2e: + return mixer->regs[mixer->index]; + } + + return 0xff; } void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) @@ -322,10 +350,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 +493,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 +510,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 +545,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 +563,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 +591,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 +622,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 +641,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 +656,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 +686,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 +702,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 +758,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 +851,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 +906,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 +926,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 +1041,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 +1061,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/SOUND/snd_sb.h b/src/SOUND/snd_sb.h index 4a0b974b8..de5b5af93 100644 --- a/src/SOUND/snd_sb.h +++ b/src/SOUND/snd_sb.h @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound Blaster emulation. + * + * Version: @(#)sound_sb.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + extern device_t sb_1_device; extern device_t sb_15_device; extern device_t sb_mcv_device; diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 8c6f4a036..a4cc3286b 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -11,6 +11,7 @@ #include "../dma.h" #include "../win/plat_midi.h" /*YUCK*/ #include "../timer.h" +#include "../device.h" #include "sound.h" #include "snd_mpu401.h" #include "snd_sb_dsp.h" @@ -514,6 +515,10 @@ void sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type < SB16) break; sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); break; + case 0xF8: + if (dsp->sb_type >= SB16) break; + sb_add_data(dsp, 0); + break; case 0xF9: if (dsp->sb_type < SB16) break; if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff); diff --git a/src/SOUND/snd_speaker.c b/src/SOUND/snd_speaker.c index 25344d922..3ac8298a9 100644 --- a/src/SOUND/snd_speaker.c +++ b/src/SOUND/snd_speaker.c @@ -8,6 +8,9 @@ int speaker_gated = 0; int speaker_enable = 0, was_speaker_enable = 0; +int gated,speakval,speakon; + + static int16_t speaker_buffer[SOUNDBUFLEN]; static int speaker_pos = 0; diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 24cf2c1c1..c233c0966 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -1,16 +1,35 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound emulation core. + * + * Version: @(#)sound.c 1.0.1 2017/06/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include #include #include "../ibm.h" #include "../device.h" #include "../timer.h" -#include "../thread.h" #include "../cdrom.h" +#include "../win/plat_thread.h" #include "sound.h" #include "snd_opl.h" #include "snd_adlib.h" #include "snd_adlibgold.h" +#if 0 #include "snd_pas16.h" +#endif #include "snd_sb.h" #include "snd_sb_dsp.h" #include "snd_wss.h" @@ -30,24 +49,27 @@ typedef struct static SOUND_CARD sound_cards[] = { - {"None", "none", NULL}, - {"Adlib", "adlib", &adlib_device}, - {"Adlib MCA", "adlib_mca", &adlib_mca_device}, - {"Sound Blaster 1.0", "sb", &sb_1_device}, - {"Sound Blaster 1.5", "sb1.5", &sb_15_device}, - {"Sound Blaster MCV", "sbmcv", &sb_mcv_device}, - {"Sound Blaster 2.0", "sb2.0", &sb_2_device}, - {"Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device}, - {"Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device}, - {"Sound Blaster Pro MCV", "sbpromcv", &sb_pro_mcv_device}, - {"Sound Blaster 16", "sb16", &sb_16_device}, - {"Sound Blaster AWE32", "sbawe32", &sb_awe32_device}, - {"Adlib Gold", "adlibgold", &adgold_device}, - {"Windows Sound System", "wss", &wss_device}, - {"Pro Audio Spectrum 16", "pas16", &pas16_device}, - {"", "", NULL} + { "None", "none", NULL }, + { "Adlib", "adlib", &adlib_device }, + { "Adlib MCA", "adlib_mca", &adlib_mca_device }, + { "Sound Blaster 1.0", "sb", &sb_1_device }, + { "Sound Blaster 1.5", "sb1.5", &sb_15_device }, + { "Sound Blaster MCV", "sbmcv", &sb_mcv_device }, + { "Sound Blaster 2.0", "sb2.0", &sb_2_device }, + { "Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device }, + { "Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device }, + { "Sound Blaster Pro MCV", "sbpromcv", &sb_pro_mcv_device }, + { "Sound Blaster 16", "sb16", &sb_16_device }, + { "Sound Blaster AWE32", "sbawe32", &sb_awe32_device }, + { "Adlib Gold", "adlibgold", &adgold_device }, + { "Windows Sound System", "wss", &wss_device }, +#if 0 + { "Pro Audio Spectrum 16", "pas16", &pas16_device }, +#endif + { "", "", NULL } }; + int sound_card_available(int card) { if (sound_cards[card].device) @@ -92,7 +114,7 @@ int sound_card_get_from_internal_name(char *s) return 0; } -void sound_card_init() +void sound_card_init(void) { if (sound_cards[sound_card_current].device) device_add(sound_cards[sound_card_current].device); @@ -215,7 +237,7 @@ static float *outbuffer_ex; static int cd_thread_enable = 0; -void sound_init() +void sound_init(void) { int i = 0; int available_cdrom_drives = 0; @@ -228,7 +250,7 @@ void sound_init() for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) { available_cdrom_drives++; } @@ -286,12 +308,12 @@ void sound_poll(void *priv) } } -void sound_speed_changed() +void sound_speed_changed(void) { sound_poll_latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); } -void sound_reset() +void sound_reset(void) { int i = 0; @@ -310,14 +332,14 @@ void sound_reset() } } -void sound_cd_thread_reset() +void sound_cd_thread_reset(void) { int i = 0; int available_cdrom_drives = 0; for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) { available_cdrom_drives++; } diff --git a/src/SOUND/sound.h b/src/SOUND/sound.h index ffa9d87af..22d2d2afa 100644 --- a/src/SOUND/sound.h +++ b/src/SOUND/sound.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound emulation core. + * + * Version: @(#)sound.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p); extern int sound_card_current; diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index 12bbf2383..4d530c7b9 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -1,12 +1,28 @@ -/*ATI Mach64 emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * ATi Mach64 graphics card emulation. + * + * Version: @(#)vid_ati_mach64.c 1.0.1 2017/06/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include "../ibm.h" +#include "../device.h" #include "../io.h" #include "../mem.h" #include "../pci.h" #include "../rom.h" -#include "../thread.h" -#include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -14,6 +30,9 @@ #include "vid_ati_eeprom.h" #include "vid_ics2595.h" +#ifdef CLAMP +#undef CLAMP +#endif #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -62,10 +81,12 @@ typedef struct mach64_t uint8_t regs[256]; int index; - - int type; + + int type; uint8_t pci_regs[256]; + uint8_t int_line; + int card; int bank_r[2]; int bank_w[2]; @@ -192,6 +213,7 @@ typedef struct mach64_t uint16_t pci_id; uint32_t config_chip_id; uint32_t block_decoded_io; + int use_block_decoded_io; int pll_addr; uint8_t pll_regs[16]; @@ -466,7 +488,7 @@ void mach64_updatemapping(mach64_t *mach64) if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - pclog("Update mapping - PCI disabled\n"); + /* pclog("Update mapping - PCI disabled\n"); */ mem_mapping_disable(&svga->mapping); mem_mapping_disable(&mach64->linear_mapping); mem_mapping_disable(&mach64->mmio_mapping); @@ -481,7 +503,7 @@ void mach64_updatemapping(mach64_t *mach64) case 0x0: /*128k at A0000*/ mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL); mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x1fc00); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_enable(&mach64->mmio_mapping); svga->banked_mask = 0xffff; break; @@ -500,37 +522,35 @@ void mach64_updatemapping(mach64_t *mach64) case 0xC: /*32k at B8000*/ mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x07c00); + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; } if (mach64->linear_base) { - if (mach64->type == MACH64_GX) - { - if ((mach64->config_cntl & 3) == 2) - { - /*8 MB aperture*/ - pclog("8 MB aperture\n"); - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x007FFC00); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x007FFC00, 0x400); - } - else - { - /*4 MB aperture*/ - pclog("4 MB aperture\n"); - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x003FFC00); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x003FFC00, 0x400); - } - svga->linear_base = mach64->linear_base; - } - else - { + if (mach64->type == MACH64_GX) + { + if ((mach64->config_cntl & 3) == 2) + { + /*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + } + else + { + /*4 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); + } + } + else + { /*2*8 MB aperture*/ mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); - } + } + svga->linear_base = mach64->linear_base; } else { @@ -540,6 +560,14 @@ void mach64_updatemapping(mach64_t *mach64) } } +static void mach64_update_irqs(mach64_t *mach64) +{ + if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) + pci_set_irq(mach64->card, PCI_INTA); + else + pci_clear_irq(mach64->card, PCI_INTA); +} + static __inline void wake_fifo_thread(mach64_t *mach64) { thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ @@ -594,8 +622,8 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val case 0x11e: case 0x11f: WRITE8(addr, mach64->dst_height_width, val); case 0x113: - if (((addr & 0x3ff) == 0x11b) || ((addr & 0x3ff) == 0x11f) || - (((addr & 0x3ff) == 0x113) && !(val & 0x80))) + if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || + (addr & 0x3ff) == 0x113) && !(val & 0x80)) { mach64_start_fill(mach64); #ifdef MACH64_DEBUG @@ -837,10 +865,6 @@ static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t static void fifo_thread(void *param) { mach64_t *mach64 = (mach64_t *)param; - fifo_entry_t *fifo; - - uint64_t start_time = 0; - uint64_t end_time = 0; while (1) { @@ -850,8 +874,9 @@ static void fifo_thread(void *param) mach64->blitter_busy = 1; while (!FIFO_EMPTY) { - start_time = timer_read(); - fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; switch (fifo->addr_type & FIFO_TYPE) { @@ -903,8 +928,7 @@ static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t void mach64_cursor_dump(mach64_t *mach64) { -/* pclog("Mach64 cursor :\n"); - pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff);*/ + return; } void mach64_start_fill(mach64_t *mach64) @@ -967,7 +991,7 @@ void mach64_start_fill(mach64_t *mach64) mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - + if (mach64->accel.src_size == WIDTH_1BIT) mach64->accel.src_offset <<= 3; else @@ -978,11 +1002,12 @@ void mach64_start_fill(mach64_t *mach64) else mach64->accel.dst_offset >>= mach64->accel.dst_size; - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; + mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - + + for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) @@ -996,6 +1021,9 @@ void mach64_start_fill(mach64_t *mach64) mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; + +/* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width]; + mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/ mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; @@ -1159,8 +1187,8 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) while (count) { uint32_t src_dat, dest_dat; - uint32_t host_dat; - int mix; + uint32_t host_dat = 0; + int mix = 0; int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; int src_x; @@ -1363,9 +1391,9 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case OP_LINE: while (count) { - uint32_t src_dat, dest_dat; - uint32_t host_dat; - int mix; + uint32_t src_dat = 0, dest_dat; + uint32_t host_dat = 0; + int mix = 0; int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); if (mach64->accel.source_host) @@ -1440,7 +1468,7 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); - + switch (mach64->accel.clr_cmp_fn) { case 1: /*TRUE*/ @@ -1611,18 +1639,18 @@ static void pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) break; case 2: /*Data*/ mach64->pll_regs[mach64->pll_addr] = val; - pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); + /* pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); */ - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { double m = (double)mach64->pll_regs[PLL_REF_DIV]; double n = (double)mach64->pll_regs[VCLK0_FB_DIV+c]; double r = 14318184.0; double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c*2)) & 3)); - pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); + /* pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); */ mach64->pll_freq[c] = (2.0 * r * n) / (m * p); - pclog(" %g\n", mach64->pll_freq[c]); + /* pclog(" %g\n", mach64->pll_freq[c]); */ } break; } @@ -1633,8 +1661,9 @@ static void mach64_vblank_start(svga_t *svga) { mach64_t *mach64 = (mach64_t *)svga->p; int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - + mach64->crtc_int_cntl |= 4; + mach64_update_irqs(mach64); svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; @@ -1657,7 +1686,10 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) uint8_t ret; if (!(addr & 0x400)) { - switch (addr & 0x3ff) +#ifdef MACH64_DEBUG + pclog("nmach64_ext_readb: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); +#endif + switch (addr & 0x3ff) { case 0x00: case 0x01: case 0x02: case 0x03: READ8(addr, mach64->overlay_y_x_start); @@ -1756,6 +1788,10 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->cur_horz_vert_off); break; + case 0x79: + ret = 0x30; + break; + case 0x80: case 0x81: case 0x82: case 0x83: READ8(addr, mach64->scratch_reg0); break; @@ -1763,10 +1799,6 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->scratch_reg1); break; - case 0x79: - ret = 0x30; - break; - case 0x90: case 0x91: case 0x92: case 0x93: READ8(addr, mach64->clock_cntl); break; @@ -2056,7 +2088,10 @@ uint32_t mach64_ext_readl(uint32_t addr, void *p) uint32_t ret; if (!(addr & 0x400)) { - ret = 0xffffffff; +#ifdef MACH64_DEBUG + pclog("nmach64_ext_readl: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); +#endif + ret = 0xffffffff; } else switch (addr & 0x3ff) { @@ -2186,6 +2221,7 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); if (val & 4) mach64->crtc_int_cntl &= ~4; + mach64_update_irqs(mach64); break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -2492,6 +2528,7 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) case 0x72ec: case 0x72ed: case 0x72ee: case 0x72ef: ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); + break; default: ret = 0; @@ -2678,7 +2715,7 @@ void mach64_ext_outw(uint16_t port, uint16_t val, void *p) } void mach64_ext_outl(uint16_t port, uint32_t val, void *p) { - pclog("mach64_ext_outl : port %04X val %08X\n", port, val); + /* pclog("mach64_ext_outl : port %04X val %08X\n", port, val); */ switch (port) { default: @@ -2980,7 +3017,7 @@ void mach64_overlay_draw(svga_t *svga, int displine) break; default: - pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); + /* pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); */ /*Fill buffer with something recognisably wrong*/ for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) mach64->overlay_dat[x] = 0xff00ff; @@ -3097,17 +3134,20 @@ static void mach64_io_set(mach64_t *mach64) io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - for (c = 0; c < 8; c++) + if (!mach64->use_block_decoded_io) { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + for (c = 0; c < 8; c++) + { + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } } io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } @@ -3135,12 +3175,12 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0x00; + case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ case 0x0b: return 0x03; case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return 0x00; + case 0x12: return mach64->linear_base >> 16; case 0x13: return mach64->linear_base >> 24; case 0x14: return 0x01; /*Block decoded IO address*/ @@ -3152,39 +3192,38 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return mach64->pci_regs[0x32]; case 0x33: return mach64->pci_regs[0x33]; + + case 0x3c: return mach64->int_line; + case 0x3d: return PCI_INTA; + + case 0x40: return mach64->use_block_decoded_io; } return 0; } -uint32_t bios_base = 0x000c0000; - void mach64_pci_write(int func, int addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; - + switch (addr) { case PCI_REG_COMMAND: mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; - if (val & PCI_COMMAND_IO) mach64_io_set(mach64); else mach64_io_remove(mach64); - mach64_updatemapping(mach64); break; - case 0x12: - if (mach64->type == MACH64_VT2) - val = 0; - break; - /* case 0x12: + case 0x12: + if (mach64->type == MACH64_VT2) + val = 0; mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); mach64_updatemapping(mach64); - break; */ + break; case 0x13: - mach64->linear_base = (val << 24); + mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); mach64_updatemapping(mach64); break; @@ -3224,16 +3263,30 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) if (mach64->pci_regs[0x30] & 0x01) { uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); - bios_base = addr; - pclog("Mach64 bios_rom enabled at %08x\n", addr); + /* pclog("Mach64 bios_rom enabled at %08x\n", addr); */ mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); } else { - pclog("Mach64 bios_rom disabled\n"); + /* pclog("Mach64 bios_rom disabled\n"); */ mem_mapping_disable(&mach64->bios_rom.mapping); } return; + + case 0x3c: + mach64->int_line = val; + break; + + case 0x40: + if (mach64->type == MACH64_VT2) + { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->use_block_decoded_io = val & 0x04; + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; } } @@ -3262,7 +3315,7 @@ static void *mach64_common_init() mach64_io_set(mach64); - pci_add(mach64_pci_read, mach64_pci_write, mach64); + mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; @@ -3270,7 +3323,7 @@ static void *mach64_common_init() mach64->pci_regs[0x33] = 0x00; ati68860_ramdac_init(&mach64->ramdac); - + mach64->dst_cntl = 3; mach64->wake_fifo_thread = thread_create_event(); @@ -3310,7 +3363,8 @@ static void *mach64vt2_init() mach64->config_chip_id = 0x40005654; mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ mach64->config_stat0 = 4; - + mach64->use_block_decoded_io = PCI ? 4 : 0; + ati_eeprom_load(&mach64->eeprom, L"mach64vt.nvr", 1); rom_init(&mach64->bios_rom, L"roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -3324,7 +3378,6 @@ int mach64gx_available() { return rom_present(L"roms/mach64gx/bios.bin"); } - int mach64vt2_available() { return rom_present(L"roms/atimach64vt2pci.bin"); @@ -3462,7 +3515,6 @@ device_t mach64gx_device = mach64_add_status_info, mach64gx_config }; - device_t mach64vt2_device = { "ATI Mach64VT2", diff --git a/src/VIDEO/vid_ati_mach64.h b/src/VIDEO/vid_ati_mach64.h index 2db76fa79..c159a6b57 100644 --- a/src/VIDEO/vid_ati_mach64.h +++ b/src/VIDEO/vid_ati_mach64.h @@ -1,2 +1,20 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * ATi Mach64 graphics card emulation. + * + * Version: @(#)vid_ati_mach64.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern device_t mach64gx_device; extern device_t mach64vt2_device; diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index afae65439..2bb16be22 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the old and new IBM CGA graphics cards. + * + * Version: @(#)vid_cga.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*CGA emulation*/ #include #include @@ -62,10 +77,6 @@ void cga_out(uint16_t addr, uint8_t val, void *p) if ((cga->cgamode ^ val) & 1) { cga_palette = (cga->rgb_type << 1); - if (!(val & 1) && (cga_palette > 0) && (cga_palette < 8)) - { - cga_palette--; - } cgapal_rebuild(); } #endif diff --git a/src/VIDEO/vid_cga.h b/src/VIDEO/vid_cga.h index ca513785d..bd8d5dbc5 100644 --- a/src/VIDEO/vid_cga.h +++ b/src/VIDEO/vid_cga.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the old and new IBM CGA graphics cards. + * + * Version: @(#)vid_cga.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + typedef struct cga_t { mem_mapping_t mapping; diff --git a/src/VIDEO/vid_cga_comp.c b/src/VIDEO/vid_cga_comp.c index a63d69f2e..513788bec 100644 --- a/src/VIDEO/vid_cga_comp.c +++ b/src/VIDEO/vid_cga_comp.c @@ -1,5 +1,21 @@ -/* Code borrowed from DOSBox and adapted by OBattler. - Original author: reenigne. */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * IBM CGA composite filter, borrowed from reenigne's DOSBox + * patch and ported to C. + * + * Version: @(#)vid_cga.c 1.0.0 2017/05/30 + * + * Author: reenigne, + * Miran Grca, + * Copyright 2015-2017 reenigne. + * Copyright 2015-2017 Miran Grca. + */ #include #include diff --git a/src/VIDEO/vid_cga_comp.h b/src/VIDEO/vid_cga_comp.h index 4640efd8f..fbea172e7 100644 --- a/src/VIDEO/vid_cga_comp.h +++ b/src/VIDEO/vid_cga_comp.h @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * IBM CGA composite filter, borrowed from reenigne's DOSBox + * patch and ported to C. + * + * Version: @(#)vid_cga.h 1.0.0 2017/05/30 + * + * Author: reenigne, + * Miran Grca, + * Copyright 2015-2017 reenigne. + * Copyright 2015-2017 Miran Grca. + */ + #define Bit8u uint8_t #define Bit32u uint32_t #define Bitu unsigned int diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index b64f30324..55f46f17e 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -1,4 +1,25 @@ -/*EGA emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the EGA, Chips & Technologies SuperEGA, and + * AX JEGA graphics cards. + * + * Version: @(#)vid_ega.c 1.0.1 2017/06/01 + * + * Author: Sarah Walker, + * Miran Grca, + * akm, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 akm. + */ + +#include #include #include "../ibm.h" #include "../io.h" @@ -8,6 +29,7 @@ #include "../device.h" #include "video.h" #include "vid_ega.h" +#include "vid_ega_render.h" extern uint8_t edatlookup[4][4]; @@ -23,11 +45,111 @@ static int old_overscan_color = 0; int update_overscan = 0; +#define SBCS 0 +#define DBCS 1 +#define ID_LEN 6 +#define NAME_LEN 8 +#define SBCS19_LEN 256 * 19 +#define DBCS16_LEN 65536 * 32 + +uint8_t jfont_sbcs_19[SBCS19_LEN];//256 * 19( * 8) +uint8_t jfont_dbcs_16[DBCS16_LEN];//65536 * 16 * 2 (* 8) + +typedef struct { + char id[ID_LEN]; + char name[NAME_LEN]; + unsigned char width; + unsigned char height; + unsigned char type; +} fontx_h; + +typedef struct { + uint16_t start; + uint16_t end; +} fontxTbl; + +void ega_jega_write_font(ega_t *ega) +{ + unsigned int chr = ega->RDFFB; + unsigned int chr_2 = ega->RDFSB; + + ega->RSTAT &= ~0x02; + + /* Check if the character code is in the Wide character set of Shift-JIS */ + if (((chr >= 0x40) && (chr <= 0x7e)) || ((chr >= 0x80) && (chr <= 0xfc))) + { + if (ega->font_index >= 32) + { + ega->font_index = 0; + } + chr <<= 8; + /* Fix vertical character position */ + chr |= chr_2; + if (ega->font_index < 16) + { + jfont_dbcs_16[(chr * 32) + (ega->font_index * 2)] = ega->RDFAP; /* 16x16 font */ + } + else + { + jfont_dbcs_16[(chr * 32) + ((ega->font_index - 16) * 2) + 1] = ega->RDFAP; /* 16x16 font */ + } + } + else + { + if (ega->font_index >= 19) + { + ega->font_index = 0; + } + jfont_sbcs_19[(chr * 19) + ega->font_index] = ega->RDFAP; /* 8x19 font */ + } + ega->font_index++; + ega->RSTAT |= 0x02; +} + +void ega_jega_read_font(ega_t *ega) +{ + unsigned int chr = ega->RDFFB; + unsigned int chr_2 = ega->RDFSB; + + ega->RSTAT &= ~0x02; + + /* Check if the character code is in the Wide character set of Shift-JIS */ + if (((chr >= 0x40) && (chr <= 0x7e)) || ((chr >= 0x80) && (chr <= 0xfc))) + { + if (ega->font_index >= 32) + { + ega->font_index = 0; + } + chr <<= 8; + /* Fix vertical character position */ + chr |= chr_2; + if (ega->font_index < 16) + { + ega->RDFAP = jfont_dbcs_16[(chr * 32) + (ega->font_index * 2)]; /* 16x16 font */ + } + else + { + ega->RDFAP = jfont_dbcs_16[(chr * 32) + ((ega->font_index - 16) * 2) + 1]; /* 16x16 font */ + } + } + else + { + if (ega->font_index >= 19) + { + ega->font_index = 0; + } + ega->RDFAP = jfont_sbcs_19[(chr * 19) + ega->font_index]; /* 8x19 font */ + } + ega->font_index++; + ega->RSTAT |= 0x02; +} + void ega_out(uint16_t addr, uint8_t val, void *p) { ega_t *ega = (ega_t *)p; int c; uint8_t o, old; + uint8_t crtcreg; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -130,21 +252,82 @@ void ega_out(uint16_t addr, uint8_t val, void *p) break; case 0x3d0: case 0x3d4: - ega->crtcreg = val & 31; + ega->crtcreg = val; return; case 0x3d1: case 0x3d5: - if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; - old = ega->crtc[ega->crtcreg]; - ega->crtc[ega->crtcreg] = val; - if (old != val) - { - if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) - { - fullchange = changeframecount; - ega_recalctimings(ega); - } - } + if ((ega->crtcreg < 0xb9) || !ega->is_jega) + { + crtcreg = ega->crtcreg & 0x1f; + if (crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; + old = ega->crtc[crtcreg]; + ega->crtc[crtcreg] = val; + if (old != val) + { + if (crtcreg < 0xe || crtcreg > 0x10) + { + fullchange = changeframecount; + ega_recalctimings(ega); + } + } + } + else + { + switch(ega->crtcreg) + { + case 0xb9: /* Mode register 1 */ + ega->RMOD1 = val; + break; + case 0xba: /* Mode register 2 */ + ega->RMOD2 = val; + break; + case 0xbb: /* ANK Group sel */ + ega->RDAGS = val; + break; + case 0xbc: /* Font access first byte */ + if (ega->RDFFB != val) + { + ega->RDFFB = val; + ega->font_index = 0; + } + break; + case 0xbd: /* Font access Second Byte */ + if (ega->RDFSB != val) + { + ega->RDFSB = val; + ega->font_index = 0; + } + break; + case 0xbe: /* Font Access Pattern */ + ega->RDFAP = val; + ega_jega_write_font(ega); + break; + case 0xdb: + ega->RPSSC = val; + break; + case 0xd9: + ega->RPSSU = val; + break; + case 0xda: + ega->RPSSL = val; + break; + case 0xdc: /* Superimposed mode (only AX-2 system, not implemented) */ + ega->RPPAJ = val; + break; + case 0xdd: + ega->RCMOD = val; + break; + case 0xde: /* Cursor Skew control */ + ega->RCSKW = val; + break; + case 0xdf: /* Font R/W register */ + ega->RSTAT = val; + break; + default: + pclog("JEGA: Write to illegal index %02X\n", ega->crtcreg); + break; + } + } break; } } @@ -174,6 +357,7 @@ static uint8_t ega_get_input_status_0(ega_t *ega) uint8_t ega_in(uint16_t addr, void *p) { ega_t *ega = (ega_t *)p; + int crtcreg; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -204,7 +388,49 @@ uint8_t ega_in(uint16_t addr, void *p) return ega->crtcreg; case 0x3d1: case 0x3d5: - return ega->crtc[ega->crtcreg]; + if ((ega->crtcreg < 0xb9) || !ega->is_jega) + { + crtcreg = ega->crtcreg & 0x1f; + return ega->crtc[crtcreg]; + } + else + { + switch(ega->crtcreg) + { + case 0xb9: + return ega->RMOD1; + case 0xba: + return ega->RMOD2; + case 0xbb: + return ega->RDAGS; + case 0xbc: /* BCh RDFFB Font access First Byte */ + return ega->RDFFB; + case 0xbd: /* BDh RDFFB Font access Second Byte */ + return ega->RDFSB; + case 0xbe: /* BEh RDFAP Font Access Pattern */ + ega_jega_read_font(ega); + return ega->RDFAP; + case 0xdb: + return ega->RPSSC; + case 0xd9: + return ega->RPSSU; + case 0xda: + return ega->RPSSL; + case 0xdc: + return ega->RPPAJ; + case 0xdd: + return ega->RCMOD; + case 0xde: + return ega->RCSKW; + case 0xdf: + return ega->ROMSL; + case 0xbf: + return 0x03; /* The font is always readable and writable */ + default: + pclog("JEGA: Read from illegal index %02X\n", ega->crtcreg); + return 0x00; + } + } case 0x3da: ega->attrff = 0; ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ @@ -270,28 +496,10 @@ void ega_recalctimings(ega_t *ega) ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -int ega_display_line(ega_t *ega) -{ - int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; - unsigned int dl = ega->displine; - if (ega->crtc[9] & 0x1f) - { - dl -= (ega->crtc[8] & 0x1f); - } - dl += y_add; - dl &= 0x7ff; - return dl; -} - void ega_poll(void *p) { ega_t *ega = (ega_t *)p; - uint8_t chr, dat, attr; - uint32_t charaddr; - int x, xx; - uint32_t fg, bg; - int offset; - uint8_t edat[4]; + int x; int drawcursor = 0; int y_add = enable_overscan ? (overscan_y >> 1) : 0; int x_add = enable_overscan ? 8 : 0; @@ -299,7 +507,6 @@ void ega_poll(void *p) int x_add_ex = enable_overscan ? 16 : 0; uint32_t *q, i, j; int wx = 640, wy = 350; - int dl = ega_display_line(ega); if (!ega->linepos) { @@ -318,204 +525,36 @@ void ega_poll(void *p) if (ega->scrblank) { - for (x = 0; x < ega->hdisp; x++) - { - switch (ega->seqregs[1] & 9) - { - case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = 0; - break; - case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = 0; - break; - case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = 0; - break; - case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = 0; - break; - } - } + ega_render_blank(ega); } else if (!(ega->gdcreg[6] & 1)) { - if (fullchange) - { - for (x = 0; x < ega->hdisp; x++) - { - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - - if (attr & 8) charaddr = ega->charsetb + (chr * 128); - else charaddr = ega->charseta + (chr * 128); - - if (drawcursor) - { - bg = ega->pallook[ega->egapal[attr & 15]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } - else - { - fg = ega->pallook[ega->egapal[attr & 15]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } - - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 8) - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - else - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } - } + ega_render_text_standard(ega, drawcursor); } else { switch (ega->gdcreg[5] & 0x20) { case 0x00: - if (ega->seqregs[1] & 8) - { - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; - - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } - else - { - offset = (8 - ega->scrollcache) + 24; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; - - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } - break; + if (ega->seqregs[1] & 8) + { + ega_render_4bpp_lowres(ega); + } + else + { + ega_render_4bpp_highres(ega); + } + break; case 0x20: - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; - edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; - } - else - { - edat[0] = ega->vram[(ega->ma << 1)]; - edat[1] = ega->vram[(ega->ma << 1) + 1]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; - - ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; - } - break; + if (ega->seqregs[1] & 8) + { + ega_render_2bpp_lowres(ega); + } + else + { + ega_render_2bpp_highres(ega); + } + break; } } if (ega->lastline < ega->displine) @@ -678,7 +717,8 @@ void ega_poll(void *p) else { if (ega->crtc[9] & 0x80) - ega->video_res_y /= 2; if (!(ega->crtc[0x17] & 1)) + ega->video_res_y /= 2; + if (!(ega->crtc[0x17] & 1)) ega->video_res_y *= 2; ega->video_res_y /= (ega->crtc[9] & 31) + 1; if (ega->seqregs[1] & 8) @@ -686,7 +726,6 @@ void ega_poll(void *p) ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; } - readflash=0; ega->firstline = 2000; ega->lastline = 0; @@ -937,6 +976,8 @@ void ega_common_defaults(ega_t *ega) ega->extvram = 1; update_overscan = 0; + + ega->is_jega = 0; } void *ega_standalone_init() @@ -1049,6 +1090,112 @@ void *sega_standalone_init() return ega; } +uint16_t chrtosht(FILE *fp) +{ + uint16_t i, j; + i = (uint8_t) getc(fp); + j = (uint8_t) getc(fp) << 8; + return (i | j); +} + +unsigned int getfontx2header(FILE *fp, fontx_h *header) +{ + fread(header->id, ID_LEN, 1, fp); + if (strncmp(header->id, "FONTX2", ID_LEN) != 0) + { + return 1; + } + fread(header->name, NAME_LEN, 1, fp); + header->width = (uint8_t)getc(fp); + header->height = (uint8_t)getc(fp); + header->type = (uint8_t)getc(fp); + return 0; +} + +void readfontxtbl(fontxTbl *table, unsigned int size, FILE *fp) +{ + while (size > 0) + { + table->start = chrtosht(fp); + table->end = chrtosht(fp); + ++table; + --size; + } +} + +static void LoadFontxFile(wchar_t *fname) +{ + fontx_h head; + fontxTbl *table; + unsigned int code; + uint8_t size; + unsigned int i; + + if (!fname) return; + if(*fname=='\0') return; + FILE * mfile=romfopen(fname,L"rb"); + if (!mfile) + { + pclog("MSG: Can't open FONTX2 file: %s\n",fname); + return; + } + if (getfontx2header(mfile, &head) != 0) + { + fclose(mfile); + pclog("MSG: FONTX2 header is incorrect\n"); + return; + } + /* switch whether the font is DBCS or not */ + if (head.type == DBCS) + { + if (head.width == 16 && head.height == 16) + { + size = getc(mfile); + table = (fontxTbl *)calloc(size, sizeof(fontxTbl)); + readfontxtbl(table, size, mfile); + for (i = 0; i < size; i++) + { + for (code = table[i].start; code <= table[i].end; code++) + { + fread(&jfont_dbcs_16[(code * 32)], sizeof(uint8_t), 32, mfile); + } + } + } + else + { + fclose(mfile); + pclog("MSG: FONTX2 DBCS font size is not correct\n"); + return; + } + } + else + { + if (head.width == 8 && head.height == 19) + { + fread(jfont_sbcs_19, sizeof(uint8_t), SBCS19_LEN, mfile); + } + else + { + fclose(mfile); + pclog("MSG: FONTX2 SBCS font size is not correct\n"); + return; + } + } + fclose(mfile); +} + +void *jega_standalone_init() +{ + ega_t *ega = (ega_t *) sega_standalone_init(); + + LoadFontxFile(L"roms/JPNHN19X.FNT"); + LoadFontxFile(L"roms/JPNZN16X.FNT"); + + ega->is_jega = 1; + + return ega; +} + static int ega_standalone_available() { return rom_present(L"roms/ibm_6277356_ega_card_u44_27128.bin"); @@ -1114,3 +1261,15 @@ device_t sega_device = NULL, NULL }; + +device_t jega_device = +{ + "AX JEGA", + 0, + jega_standalone_init, + ega_close, + sega_standalone_available, + ega_speed_changed, + NULL, + NULL +}; diff --git a/src/VIDEO/vid_ega.h b/src/VIDEO/vid_ega.h index 9b0e215d8..2fef2c0ca 100644 --- a/src/VIDEO/vid_ega.h +++ b/src/VIDEO/vid_ega.h @@ -1,6 +1,26 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the EGA, Chips & Technologies SuperEGA, and + * AX JEGA graphics cards. + * + * Version: @(#)vid_ega.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * akm, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 akm. + */ + +#include + typedef struct ega_t { mem_mapping_t mapping; @@ -68,6 +88,12 @@ typedef struct ega_t int vrammask; int video_res_x, video_res_y, video_bpp; + + uint8_t RMOD1, RMOD2, RDAGS, RDFFB, RDFSB, RDFAP, RPESL, RPULP, RPSSC, RPSSU, RPSSL; + uint8_t RPPAJ; + uint8_t RCMOD, RCCLH, RCCLL, RCCSL, RCCEL, RCSKW, ROMSL, RSTAT; + int is_jega, font_index; + int chr_left, chr_wide; } ega_t; extern int update_overscan; diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c new file mode 100644 index 000000000..f100b3c64 --- /dev/null +++ b/src/VIDEO/vid_ega_render.c @@ -0,0 +1,305 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * EGA renderers. + * + * Version: @(#)vid_ega_render.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + +#include +#include "../ibm.h" +#include "../device.h" +#include "../mem.h" +#include "../rom.h" +#include "video.h" +#include "vid_ega.h" +#include "vid_ega_render.h" + + +int ega_display_line(ega_t *ega) +{ + int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; + unsigned int dl = ega->displine; + if (ega->crtc[9] & 0x1f) + { + dl -= (ega->crtc[8] & 0x1f); + } + dl += y_add; + dl &= 0x7ff; + return dl; +} + +void ega_render_blank(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + int x, xx; + + for (x = 0; x < ega->hdisp; x++) + { + switch (ega->seqregs[1] & 9) + { + case 0: + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = 0; + break; + case 1: + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = 0; + break; + case 8: + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = 0; + break; + case 9: + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = 0; + break; + } + } +} + +void ega_render_text_standard(ega_t *ega, int drawcursor) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t chr, dat, attr; + uint32_t charaddr; + int x, xx; + uint32_t fg, bg; + + if (fullchange) + { + for (x = 0; x < ega->hdisp; x++) + { + drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + + if (attr & 8) charaddr = ega->charsetb + (chr * 128); + else charaddr = ega->charseta + (chr * 128); + + if (drawcursor) + { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } + else + { + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; + } + } + + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; + else + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; + } + } + else + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; + else + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; + } + } + ega->ma += 4; + ega->ma &= ega->vrammask; + } + } +} + +void ega_render_2bpp_lowres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + int x; + int offset; + uint8_t edat[4]; + + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; + edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; + } + else + { + edat[0] = ega->vram[(ega->ma << 1)]; + edat[1] = ega->vram[(ega->ma << 1) + 1]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + + ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } +} + +void ega_render_2bpp_highres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + int x; + int offset; + uint8_t edat[4]; + + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; + edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; + } + else + { + edat[0] = ega->vram[(ega->ma << 1)]; + edat[1] = ega->vram[(ega->ma << 1) + 1]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + + ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } +} + +void ega_render_4bpp_lowres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t dat; + int x; + int offset; + uint8_t edat[4]; + + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; + } + else + { + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } +} + +void ega_render_4bpp_highres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t dat; + int x; + int offset; + uint8_t edat[4]; + + offset = (8 - ega->scrollcache) + 24; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; + } + else + { + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } +} diff --git a/src/VIDEO/vid_ega_render.h b/src/VIDEO/vid_ega_render.h new file mode 100644 index 000000000..0f7805751 --- /dev/null +++ b/src/VIDEO/vid_ega_render.h @@ -0,0 +1,37 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * EGA renderers. + * + * Version: @(#)vid_ega_render.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + +extern int firstline_draw, lastline_draw; +extern int displine; +extern int sc; + +extern uint32_t ma, ca; +extern int con, cursoron, cgablink; + +extern int scrollcache; + +extern uint8_t edatlookup[4][4]; + +void ega_render_blank(ega_t *ega); +void ega_render_text_standard(ega_t *ega, int drawcursor); +void ega_render_text_jega(ega_t *ega); + +void ega_render_2bpp_lowres(ega_t *ega); +void ega_render_2bpp_highres(ega_t *ega); +void ega_render_4bpp_lowres(ega_t *ega); +void ega_render_4bpp_highres(ega_t *ega); diff --git a/src/VIDEO/vid_et4000w32.c b/src/VIDEO/vid_et4000w32.c index 69b21af50..254fe8072 100644 --- a/src/VIDEO/vid_et4000w32.c +++ b/src/VIDEO/vid_et4000w32.c @@ -10,7 +10,7 @@ #include "../pci.h" #include "../rom.h" #include "../device.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_icd2061.h" @@ -235,14 +235,6 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) return svga->crtcreg; case 0x3D5: return svga->crtc[svga->crtcreg]; - - case 0x3DA: - svga->attrff = 0; - svga->cgastat ^= 0x30; - temp = svga->cgastat & 0x39; - if (svga->hdisp_on) temp |= 2; - if (!(svga->cgastat & 8)) temp |= 0x80; - return temp; case 0x210A: case 0x211A: case 0x212A: case 0x213A: case 0x214A: case 0x215A: case 0x216A: case 0x217A: diff --git a/src/VIDEO/vid_nv_riva128.c b/src/VIDEO/vid_nv_riva128.c index a0bea095c..4d3d41b24 100644 --- a/src/VIDEO/vid_nv_riva128.c +++ b/src/VIDEO/vid_nv_riva128.c @@ -9,9 +9,9 @@ #include "../pci.h" #include "../pic.h" #include "../rom.h" -#include "../thread.h" #include "../timer.h" #include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_nv_riva128.h" #include "vid_svga.h" diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index de67496d7..8b762aeb9 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1,12 +1,29 @@ -/*S3 emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 + * graphics cards. + * + * Version: @(#)vid_s3.c 1.0.1 2017/06/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include "../ibm.h" #include "../io.h" #include "../mem.h" #include "../pci.h" #include "../rom.h" -#include "../thread.h" #include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_s3.h" #include "vid_svga.h" @@ -76,12 +93,15 @@ typedef struct s3_t int chip; uint8_t id, id_ext, id_ext_pci; + + uint8_t int_line; int packed_mmio; uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; uint32_t vram_mask; @@ -132,8 +152,17 @@ typedef struct s3_t int blitter_busy; uint64_t blitter_time; uint64_t status_time; + + uint8_t subsys_cntl, subsys_stat; + uint8_t status_9ae9; } s3_t; +#define INT_VSY (1 << 0) +#define INT_GE_BSY (1 << 1) +#define INT_FIFO_OVR (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_MASK 0xf + void s3_updatemapping(); void s3_accel_write(uint32_t addr, uint8_t val, void *p); @@ -155,6 +184,19 @@ static void s3_wait_fifo_idle(s3_t *s3) } } +static void s3_update_irqs(s3_t *s3) +{ + if (!PCI) + { + return; + } + + if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) + pci_set_irq(s3->card, PCI_INTA); + else + pci_clear_irq(s3->card, PCI_INTA); +} + void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); #define WRITE8(addr, var, val) switch ((addr) & 3) \ @@ -402,70 +444,88 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } + if (port & 0x8000) + { + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } + else + { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + } } static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x400) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } - else - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } - else - { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } + if (port & 0x8000) + { + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + s3_accel_out_fifo(s3, port + 2, val >> 16); + s3_accel_out_fifo(s3, port + 3, val >> 24); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x400) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } + else if ((s3->accel.cmd & 0x600) == 0x200) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } + else + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } + else + { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) + { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + else + { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } + } } static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) @@ -707,9 +767,19 @@ static void fifo_thread(void *param) s3->blitter_time += end_time - start_time; } s3->blitter_busy = 0; + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); } } +static void s3_vblank_start(svga_t *svga) +{ + s3_t *s3 = (s3_t *)svga->p; + + s3->subsys_stat |= INT_VSY; + s3_update_irqs(s3); +} + static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; @@ -1111,9 +1181,12 @@ void s3_accel_out(uint16_t port, uint8_t val, void *p) else switch (port) { case 0x42e8: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); break; case 0x42e9: - s3->accel.subsys_cntl = val; + s3->subsys_cntl = val; + s3_update_irqs(s3); break; case 0x46e8: s3->accel.setup_md = val; @@ -1143,9 +1216,9 @@ uint8_t s3_accel_in(uint16_t port, void *p) switch (port) { case 0x42e8: - return 0; + return s3->subsys_stat; case 0x42e9: - return 0; + return s3->subsys_cntl; case 0x82e8: s3_wait_fifo_idle(s3); @@ -1202,7 +1275,7 @@ uint8_t s3_accel_in(uint16_t port, void *p) if (!FIFO_EMPTY) temp |= 0x02; /*Hardware busy*/ else - temp |= 0x04; /*FIFO empty*/ + temp |= s3->status_9ae9; /*FIFO empty*/ if (FIFO_FULL) temp |= 0xf8; /*FIFO full*/ return temp; @@ -1587,6 +1660,15 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dest = s3->accel.cy * s3->width; } + + s3->status_9ae9 = 4; /*To avoid the spam from OS/2's drivers*/ + + if ((s3->accel.cmd & 0x100) && !cpu_input) + { + s3->status_9ae9 = 2; /*To avoid the spam from OS/2's drivers*/ + return; /*Wait for data from CPU*/ + } + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; @@ -2042,6 +2124,9 @@ uint8_t s3_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return s3->pci_regs[0x32]; case 0x33: return s3->pci_regs[0x33]; + + case 0x3c: return s3->int_line; + case 0x3d: return PCI_INTA; } return 0; } @@ -2054,7 +2139,7 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { case PCI_REG_COMMAND: - s3->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3->pci_regs[PCI_REG_COMMAND] = val & 0x23; if (val & PCI_COMMAND_IO) s3_io_set(s3); else @@ -2083,6 +2168,10 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&s3->bios_rom.mapping); } return; + + case 0x3c: + s3->int_line = val; + return; } } @@ -2135,6 +2224,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); svga->crtc[0x37] = 1 | (7 << 5); + svga->vblank_start = s3_vblank_start; + svga->crtc[0x53] = 1 << 3; svga->crtc[0x59] = 0x70; @@ -2142,9 +2233,9 @@ static void *s3_init(wchar_t *bios_fn, int chip) if (PCI) { - pci_add(s3_pci_read, s3_pci_write, s3); + s3->card = pci_add(s3_pci_read, s3_pci_write, s3); } - + s3->pci_regs[0x04] = 3; s3->pci_regs[0x30] = 0x00; @@ -2156,6 +2247,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); s3->fifo_thread = thread_create(fifo_thread, s3); + + s3->int_line = 0; return s3; } diff --git a/src/VIDEO/vid_s3.h b/src/VIDEO/vid_s3.h index 396e6523b..8ace7397d 100644 --- a/src/VIDEO/vid_s3.h +++ b/src/VIDEO/vid_s3.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 + * graphics cards. + * + * Version: @(#)vid_s3.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + device_t s3_bahamas64_device; device_t s3_9fx_device; device_t s3_phoenix_trio32_device; diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 21723de42..95f040128 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -9,7 +9,7 @@ #include "../pci.h" #include "../rom.h" #include "../device.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_s3_virge.h" #include "vid_svga.h" @@ -121,6 +121,7 @@ typedef struct virge_t uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; int is_375; @@ -228,6 +229,8 @@ typedef struct virge_t event_t *fifo_not_full_event; int virge_busy; + + uint8_t subsys_stat, subsys_cntl; } virge_t; static __inline void wake_fifo_thread(virge_t *virge) @@ -292,6 +295,26 @@ enum CMD_SET_COMMAND_NOP = (15 << 27) }; +#define INT_VSY (1 << 0) +#define INT_S3D_DONE (1 << 1) +#define INT_FIFO_OVF (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_3DF_EMP (1 << 6) +#define INT_MASK 0xff + +static void s3_virge_update_irqs(virge_t *virge) +{ + if (!PCI) + { + return; + } + + if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) + pci_set_irq(virge->card, PCI_INTA); + else + pci_clear_irq(virge->card, PCI_INTA); +} + static void s3_virge_out(uint16_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; @@ -339,6 +362,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x32: if ((svga->crtc[0x67] & 0xc) != 0xc) svga->vrammask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + s3_virge_update_irqs(virge); break; case 0x50: @@ -691,6 +715,14 @@ static void s3_virge_updatemapping(virge_t *virge) } +static void s3_virge_vblank_start(svga_t *svga) +{ + virge_t *virge = (virge_t *)svga->p; + + virge->subsys_stat |= INT_VSY; + s3_virge_update_irqs(virge); +} + static void s3_virge_wait_fifo_idle(virge_t *virge) { while (!FIFO_EMPTY) @@ -822,6 +854,7 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) ret = (0x10 << 8); else ret = (0x10 << 8) | (1 << 13); + ret |= virge->subsys_stat; if (!virge->virge_busy) wake_fifo_thread(virge); break; @@ -1441,6 +1474,12 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) svga_recalctimings(svga); svga->fullchange = changeframecount; break; + + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); + break; case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: @@ -3248,6 +3287,8 @@ static void render_thread(void *param) thread_set_event(virge->not_full_event); } virge->s3d_busy = 0; + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); } } @@ -3687,9 +3728,9 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&virge->bios_rom.mapping); } return; - /* case 0x3c: + case 0x3c: virge->pci_regs[0x3c] = val; - return; */ + return; } } @@ -3707,6 +3748,7 @@ static void *s3_virge_init() s3_virge_in, s3_virge_out, s3_virge_hwcursor_draw, s3_virge_overlay_draw); + virge->svga.vblank_start = s3_virge_vblank_start; rom_init(&virge->bios_rom, L"roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -3774,7 +3816,7 @@ static void *s3_virge_init() virge->is_375 = 0; - pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); @@ -3883,7 +3925,7 @@ static void *s3_virge_988_init() return virge; } -static void *s3_virge_375_init() +static void *s3_virge_375_init(wchar_t *romfn) { virge_t *virge = malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); @@ -3898,7 +3940,7 @@ static void *s3_virge_375_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, L"roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -3979,6 +4021,16 @@ static void *s3_virge_375_init() return virge; } +static void *s3_virge_375_1_init() +{ + return s3_virge_375_init(L"roms/86c375_1.bin"); +} + +static void *s3_virge_375_4_init() +{ + return s3_virge_375_init(L"roms/86c375_4.bin"); +} + static void s3_virge_close(void *p) { virge_t *virge = (virge_t *)p; @@ -4012,11 +4064,16 @@ static int s3_virge_988_available() return rom_present(L"roms/diamondstealth3000.VBI"); } -static int s3_virge_375_available() +static int s3_virge_375_1_available() { return rom_present(L"roms/86c375_1.bin"); } +static int s3_virge_375_4_available() +{ + return rom_present(L"roms/86c375_4.bin"); +} + static void s3_virge_speed_changed(void *p) { virge_t *virge = (virge_t *)p; @@ -4148,9 +4205,22 @@ device_t s3_virge_375_device = { "S3 ViRGE/DX", 0, - s3_virge_375_init, + s3_virge_375_1_init, s3_virge_close, - s3_virge_375_available, + s3_virge_375_1_available, + s3_virge_speed_changed, + s3_virge_force_redraw, + s3_virge_add_status_info, + s3_virge_config +}; + +device_t s3_virge_375_4_device = +{ + "S3 ViRGE/DX (VBE 2.0)", + 0, + s3_virge_375_4_init, + s3_virge_close, + s3_virge_375_4_available, s3_virge_speed_changed, s3_virge_force_redraw, s3_virge_add_status_info, diff --git a/src/VIDEO/vid_s3_virge.h b/src/VIDEO/vid_s3_virge.h index 2e8dfbe91..74ee6454b 100644 --- a/src/VIDEO/vid_s3_virge.h +++ b/src/VIDEO/vid_s3_virge.h @@ -4,3 +4,4 @@ extern device_t s3_virge_device; extern device_t s3_virge_988_device; extern device_t s3_virge_375_device; +extern device_t s3_virge_375_4_device; diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 39a72ae15..8684de91f 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -1,7 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Generic SVGA handling*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic SVGA handling. + * + * Version: @(#)vid_svga.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/ #include #include @@ -870,8 +884,6 @@ void svga_poll(void *p) if (!svga->override) svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); - readflash = 0; - svga->firstline = 2000; svga->lastline = 0; diff --git a/src/VIDEO/vid_svga.h b/src/VIDEO/vid_svga.h index 54270a0cb..d4307dfde 100644 --- a/src/VIDEO/vid_svga.h +++ b/src/VIDEO/vid_svga.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic SVGA handling. + * + * Version: @(#)vid_svga.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + typedef struct svga_t { mem_mapping_t mapping; diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index d51d6d249..0d09326e7 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * SVGA renderers. + * + * Version: @(#)vid_svga_render.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "../ibm.h" #include "../mem.h" @@ -43,10 +58,75 @@ int svga_display_line(svga_t *svga) void svga_render_blank(svga_t *svga) { +#if 0 int x, xx; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; int dl = svga_display_line(svga); + uint32_t *p; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (dl >= 2046) + { + return; + } + + for (x = 0; x < svga->hdisp; x++) + { + switch (svga->seqregs[1] & 9) + { + case 0: + for (xx = 0; xx < 9; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 9) + xx + 32 + x_add]) != NULL) + { + p[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + + case 1: + for (xx = 0; xx < 8; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 8) + xx + 32 + x_add]) != NULL) + { + p[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + + case 8: + for (xx = 0; xx < 18; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 18) + xx + 32 + x_add]) != NULL) + { + p[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + + case 9: + for (xx = 0; xx < 16; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 16) + xx + 32 + x_add]) != NULL) + { + p[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + } + } +#endif + int x, xx; + int y_add = (enable_overscan) ? 16 : 0; + int x_add = y_add >> 1; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -57,16 +137,16 @@ void svga_render_blank(svga_t *svga) switch (svga->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); break; case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); break; case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); break; case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); break; } } diff --git a/src/VIDEO/vid_svga_render.h b/src/VIDEO/vid_svga_render.h index f6611db57..eb3715fdd 100644 --- a/src/VIDEO/vid_svga_render.h +++ b/src/VIDEO/vid_svga_render.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * SVGA renderers. + * + * Version: @(#)vid_svga_render.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern int firstline_draw, lastline_draw; extern int displine; extern int sc; diff --git a/src/VIDEO/vid_tgui9440.c b/src/VIDEO/vid_tgui9440.c index e365ed4ac..d0a11d317 100644 --- a/src/VIDEO/vid_tgui9440.c +++ b/src/VIDEO/vid_tgui9440.c @@ -9,7 +9,7 @@ #include "../pci.h" #include "../rom.h" #include "../device.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/VIDEO/vid_voodoo.c b/src/VIDEO/vid_voodoo.c index 38d789a87..9b823e1a2 100644 --- a/src/VIDEO/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -6,9 +6,9 @@ #include "../mem.h" #include "../rom.h" #include "../pci.h" -#include "../thread.h" #include "../timer.h" #include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_voodoo.h" diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index 30f015570..baf4a41c3 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -12,8 +12,8 @@ #include "../rom.h" #include "../config.h" #include "../device.h" -#include "../thread.h" #include "../timer.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #ifndef __unix @@ -59,6 +59,7 @@ #include "vid_wy700.h" +int vid_cga_contrast = 0; int cga_palette = 0; typedef struct @@ -104,6 +105,7 @@ static VIDEO_CARD video_cards[] = {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64}, {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS}, {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX}, + {"S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20", &s3_virge_375_4_device, GFX_VIRGEDX4}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA}, {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000}, @@ -203,8 +205,8 @@ uint8_t edatlookup[4][4]; int enable_overscan; int overscan_x, overscan_y; + int force_43; -int enable_flash; /*Video timing settings - diff --git a/src/VIDEO/video.h b/src/VIDEO/video.h index 7054c33b3..f9b7fef85 100644 --- a/src/VIDEO/video.h +++ b/src/VIDEO/video.h @@ -81,10 +81,9 @@ extern void (*video_blit_memtoscreen_8_func)(int x, int y, int w, int h); /* Enable EGA/(S)VGA overscan border. */ extern int enable_overscan; extern int overscan_x, overscan_y; + /* Forcibly stretch emulated video output to 4:3 or not. */ extern int force_43; -/* Enable disk activity flash. */ -extern int enable_flash; extern int video_timing_b, video_timing_w, video_timing_l; extern int video_speed; @@ -112,6 +111,7 @@ void ddraw_fs_take_screenshot(wchar_t *fn); #endif extern int cga_palette; +extern int vid_cga_contrast; void loadfont(wchar_t *s, int format); void initvideo(); diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index e41ecbda8..e5b19e765 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -1,19 +1,29 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows resource script. + * + * Version: @(#)86Box.rc 1.0.2 2017/06/04 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Copyright 2016-2017 Miran Grca. + */ #include - -//Microsoft Developer Studio generated resource script. -// +#define IN_RESOURCE_H #include "resource.h" +#include "../86box.h" +#undef IN_RESOURCE_H #define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -30,206 +40,16 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Menu // -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 BEGIN POPUP "&Action" BEGIN - MENUITEM "&Hard Reset", IDM_FILE_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "E&xit", IDM_FILE_EXIT + MENUITEM "&Hard Reset", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_ACTION_EXIT END POPUP "&Tools" BEGIN @@ -240,7 +60,7 @@ BEGIN MENUITEM SEPARATOR POPUP "&Video" BEGIN - MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "&Resizeable window", IDM_VID_RESIZE MENUITEM "R&emember size && position", IDM_VID_REMEMBER MENUITEM SEPARATOR MENUITEM "&DirectDraw", IDM_VID_DDRAW @@ -254,7 +74,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 @@ -262,50 +82,52 @@ BEGIN MENUITEM "&Square pixels", IDM_VID_FS_SQ MENUITEM "&Integer scale", IDM_VID_FS_INT END - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT MENUITEM SEPARATOR + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT + MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON + END MENUITEM "S&tatus", IDM_STATUS -#ifdef ENABLE_LOG_TOGGLES -#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG - MENUITEM SEPARATOR -#endif -#ifdef ENABLE_BUSLOGIC_LOG - MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC -#endif -#ifdef ENABLE_CDROM_LOG - MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM -#endif -#ifdef ENABLE_D86F_LOG - MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F -#endif -#ifdef ENABLE_FDC_LOG - MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC -#endif -#ifdef ENABLE_IDE_LOG - MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE -#endif -#ifdef ENABLE_NE2000_LOG - MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - MENUITEM SEPARATOR - MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT -#ifdef ENABLE_VRAM_DUMP - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#else -#ifdef ENABLE_VRAM_DUMP - MENUITEM SEPARATOR - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#endif END +#if defined(ENABLE_LOG_TOGGLES) || defined(ENABLE_LOG_COMMANDS) + POPUP "&Logging" + BEGIN +# ifdef ENABLE_BUSLOGIC_LOG + MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC +# endif +# ifdef ENABLE_CDROM_LOG + MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM +# endif +# ifdef ENABLE_D86F_LOG + MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F +# endif +# ifdef ENABLE_FDC_LOG + MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC +# endif +# ifdef ENABLE_IDE_LOG + MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE +# endif +# ifdef ENABLE_SERIAL_LOG + MENUITEM "Enable Serial Port logs\tCtrl+F3", IDM_LOG_SERIAL +# endif +# ifdef ENABLE_NIC_LOG + MENUITEM "Enable Network logs\tCtrl+F9", IDM_LOG_NIC +# endif +# ifdef ENABLE_LOG_COMMANDS +# ifdef ENABLE_LOG_TOGGLES + MENUITEM SEPARATOR +# endif +# ifdef ENABLE_LOG_BREAKPOINT + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +# endif +# ifdef ENABLE_VRAM_DUMP + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +# endif +# endif + END +#endif POPUP "&Help" BEGIN MENUITEM "&About 86Box...", IDM_ABOUT @@ -321,33 +143,35 @@ END MAINACCEL ACCELERATORS MOVEABLE PURE BEGIN #ifdef ENABLE_VRAM_DUMP - VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY + VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_SERIAL_LOG + VK_F3, IDM_LOG_SERIAL, CONTROL, VIRTKEY #endif -#ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG - VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY #endif #ifdef ENABLE_CDROM_LOG - VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY #endif #ifdef ENABLE_D86F_LOG - VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY #endif #ifdef ENABLE_FDC_LOG - VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY #endif #ifdef ENABLE_IDE_LOG - VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_NE2000_LOG - VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY #endif +#ifdef ENABLE_NIC_LOG + VK_F9, IDM_LOG_NIC, CONTROL, VIRTKEY #endif #ifdef ENABLE_LOG_BREAKPOINT - VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY #endif - VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL - VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL + VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT + VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL + VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL END @@ -355,8 +179,29 @@ END // // Dialog // +DLG_ABOUT DIALOG DISCARDABLE 0, 0, 209, 114 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About 86Box" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,94,71,12 + ICON 100,IDC_ABOUT_ICON,7,7,20,20 + LTEXT "86Box v2.00 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + IDC_ABOUT_ICON,54,7,146,73 + CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, + 86,208,1 +END -CONFIGUREDLG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 +DLG_STATUS DIALOG DISCARDABLE 0, 0, 186, 386 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Status" +FONT 9, "Segoe UI" +BEGIN + LTEXT "1",IDT_SDEVICE,16,16,180,1000 + LTEXT "1",IDT_STEXT,16,186,180,1000 +END + +DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 241 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "86Box Settings" FONT 9, "Segoe UI" @@ -364,14 +209,182 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,246,220,50,14 PUSHBUTTON "Cancel",IDCANCEL,307,220,50,14 CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,90,197 + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,197 CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 - LTEXT "Language:",2047,7,222,41,10 + LTEXT "Language:",IDT_1700,7,222,41,10 COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP END -CONFIGUREDLG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 +DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Machine:",IDT_1701,7,8,60,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 + COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU type:",IDT_1702,7,26,59,10 + COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",IDT_1703,7,45,60,10 + COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU:",IDT_1704,124,26,18,10 + CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,147,80,113,10 + EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, + 12,12 + LTEXT "MB",IDT_1705,123,64,10,10 + LTEXT "Memory:",IDT_1706,7,64,30,10 + CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 +END + +DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Video:",IDT_1707,7,8,55,10 + COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_VID,214,7,46,12 + COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video speed:",IDT_1708,7,26,58,10 + CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_BUTTON_VOODOO,214,44,46,12 +END + +DLG_CFG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Mouse :",IDT_1709,7,8,57,10 + COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Joystick :",IDT_1710,7,26,58,10 + COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 + PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 + PUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 + PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 +END + +DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 98 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_SOUND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Sound card:",IDT_1711,7,8,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_SND,214,7,46,12 + COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "MIDI Out Device:",IDT_1712,7,26,59,10 + + CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MPU401,214,44,46,12 + + CONTROL "Innovation SSI-2001",IDC_CHECK_SSI,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,63,94,10 + CONTROL "CMS / Game Blaster",IDC_CHECK_CMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,63,94,10 + + CONTROL "Gravis Ultrasound",IDC_CHECK_GUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10 + CONTROL "Use Nuked OPL",IDC_CHECK_NUKEDOPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 +END + +DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Network type:",IDT_1713,7,8,59,10 + COMBOBOX IDC_COMBO_NET_TYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "PCap device:",IDT_1714,7,26,59,10 + COMBOBOX IDC_COMBO_PCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "Network adapter:",IDT_1715,7,44,59,10 + COMBOBOX IDC_COMBO_NET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_NET,214,43,46,12 +END + +DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "SCSI Controller:",IDT_1716,7,8,59,10 + COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 + + LTEXT "HD Controller:",IDT_1717,7,26,61,10 + COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Tertiary IDE:",IDT_1718,7,44,61,10 + COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Quaternary IDE:",IDT_1719,7,62,61,10 + COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + CONTROL "Serial port 1",IDC_CHECK_SERIAL1,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Serial port 2",IDC_CHECK_SERIAL2,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + + CONTROL "Parallel port",IDC_CHECK_PARALLEL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 + CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 +END + +DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,18,253,92 + LTEXT "Hard disks:",IDT_1720,7,7,34,8 + PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 + PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 + PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 + COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",IDT_1721,7,118,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",IDT_1722,131,118,38,8 + COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",IDT_1723,131,118,38,8 + COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",IDT_1724,200,118,38,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",IDT_1725,131,118,38,8 +END + +DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Add Hard Disk" FONT 9, "Segoe UI" @@ -386,238 +399,104 @@ BEGIN EDITTEXT IDC_EDIT_HD_SIZE,42,52,28,12 COMBOBOX IDC_COMBO_HD_TYPE,113,52,98,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Sectors:",IDC_STATIC,154,35,27,10 - LTEXT "Heads:",1793,81,35,29,8 - LTEXT "Cylinders:",1794,7,35,32,12 - LTEXT "Size (MB):",1795,7,54,33,8 - LTEXT "Type:",1797,86,54,24,8 - LTEXT "File name:",-1,7,7,204,9 + LTEXT "Sectors:",IDT_1726,154,35,27,10 + LTEXT "Heads:",IDT_1727,81,35,29,8 + LTEXT "Cylinders:",IDT_1728,7,35,32,12 + LTEXT "Size (MB):",IDT_1729,7,54,33,8 + LTEXT "Type:",IDT_1730,86,54,24,8 + LTEXT "File name:",IDT_1731,7,7,204,9 COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,72,24,8 + LTEXT "Bus:",IDT_1732,7,72,24,8 COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,99,72,34,8 + LTEXT "Channel:",IDT_1733,99,72,34,8 COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,117,72,15,8 + LTEXT "ID:",IDT_1734,117,72,15,8 COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,168,72,15,8 + LTEXT "LUN:",IDT_1735,168,72,15,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,99,72,34,8 + LTEXT "Channel:",IDT_1736,99,72,34,8 END -STATUSDLG DIALOG DISCARDABLE 0, 0, 186, 386 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Status" -FONT 9, "Segoe UI" -BEGIN - LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 - LTEXT "1",IDC_STEXT1,16,186,180,1000 -END +/* Static text label IDs. */ +#define IDT_1700 1700 // Language: +#define IDT_1701 1701 // Machine: +#define IDT_1702 1702 // CPU type: +#define IDT_1703 1703 // Wait states: +#define IDT_1704 1704 // CPU: +#define IDT_1705 1705 // MB == IDC_TEXT_MB +#define IDT_1706 1706 // Memory: +#define IDT_1707 1707 // Video: +#define IDT_1708 1708 // Video speed: +#define IDT_1709 1709 // Mouse: +#define IDT_1710 1710 // Joystick: +#define IDT_1711 1711 // Sound card: +#define IDT_1712 1712 // MIDI Out Device: +#define IDT_1713 1713 // Network type: +#define IDT_1714 1714 // PCap device: +#define IDT_1715 1715 // Network adapter: +#define IDT_1716 1716 // SCSI Controller: +#define IDT_1717 1717 // HD Controller: +#define IDT_1718 1718 // Tertiary IDE: +#define IDT_1719 1719 // Quaternary IDE: +#define IDT_1720 1720 // Hard disks: +#define IDT_1721 1721 // Bus: +#define IDT_1722 1722 // Channel: +#define IDT_1723 1723 // ID: +#define IDT_1724 1724 // LUN: +#define IDT_1725 1725 // Channel: +#define IDT_1726 1726 // Sectors: +#define IDT_1727 1727 // Heads: +#define IDT_1728 1728 // Cylinders: +#define IDT_1729 1729 // Size (MB): +#define IDT_1730 1730 // Type: +#define IDT_1731 1731 // File name: +#define IDT_1732 1732 // Bus: +#define IDT_1733 1733 // Channel: +#define IDT_1734 1734 // ID: +#define IDT_1735 1735 // LUN: +#define IDT_1736 1736 // Channel: +#define IDT_1737 1737 // Floppy drives: +#define IDT_1738 1738 // Type: +#define IDT_1739 1739 // CD-ROM drives: +#define IDT_1740 1740 // Bus: +#define IDT_1741 1741 // ID: +#define IDT_1742 1742 // LUN: +#define IDT_1743 1743 // Channel: -ABOUTDLG DIALOG DISCARDABLE 0, 0, 209, 114 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About 86Box" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,129,94,71,12 - ICON 100,IDC_ABOUT_ICON,7,7,20,20 - LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", - IDC_ABOUT_ICON,54,7,146,73 - CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, - 86,208,1 -END - -CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Machine:",1794,7,8,60,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 - COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU type:",1796,7,26,59,10 - COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Wait states:",1798,7,45,60,10 - COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU:",1797,124,26,18,10 - CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,147,80,113,10 - EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, - 12,12 - LTEXT "MB",IDC_TEXT_MB,123,64,10,10 - LTEXT "Memory:",1802,7,64,30,10 - CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 -END - -CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video:",1795,7,8,55,10 - COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video speed:",1800,7,26,58,10 - CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 - PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 -END - -CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Mouse :",IDC_STATIC,7,8,57,10 - COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - LTEXT "Joystick :",1793,7,26,58,10 - COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 - PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 - PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 -END - -CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Sound card:",1800,7,8,59,10 - PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 - COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "MIDI Out Device:",1801,7,26,59,10 - CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 - CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 -END - -CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Network type:",1800,7,8,59,10 - COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "PCap device:",1801,7,26,59,10 - COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "Network adapter:",1802,7,44,59,10 - COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 -END - -CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "SCSI Controller:",1804,7,8,59,10 - COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 - - LTEXT "HD Controller:",1799,7,26,61,10 - COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Tertiary IDE:",1802,7,44,61,10 - COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Quaternary IDE:",1803,7,62,61,10 - COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 - - CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 - CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 -END - -CONFIGUREDLG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,18,253,92 - LTEXT "Hard disks:",-1,7,7,34,8 - PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 - PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 - PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 - COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,118,24,8 - COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,131,118,38,8 - COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,118,38,8 - COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,118,38,8 - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,118,38,8 -END - -CONFIGUREDLG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 +DLG_CFG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, - 7,18,253,60 - LTEXT "Floppy drives:",-1,7,7,43,8 - CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 - LTEXT "CD-ROM drives:",-1,7,106,50,8 + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,18,253,60 + LTEXT "Floppy drives:",IDT_1737,7,7,43,8 COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Type:",1803,7,86,24,8 + LTEXT "Type:",IDT_1738,7,86,24,8 + CONTROL "Turbo timings (no accuracy)",IDC_CHECKTURBO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,131,86,129,10 + CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,116,253,60 + LTEXT "CD-ROM drives:",IDT_1739,7,106,50,8 COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,184,24,8 + LTEXT "Bus:",IDT_1740,7,184,24,8 COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,184,38,8 + LTEXT "ID:",IDT_1741,131,184,38,8 COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,184,38,8 + LTEXT "LUN:",IDT_1742,200,184,38,8 COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,184,38,8 + LTEXT "Channel:",IDT_1743,131,184,38,8 END @@ -637,77 +516,81 @@ END // remains consistent on all systems. #ifdef RELEASE_BUILD /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box-RB.ico" #else /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box.ico" #endif -128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" -129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" -130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" -131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" -132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" -133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" -134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" -135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" -144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" -145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" -146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" -147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" -150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" -151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" -152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" -153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" -160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" -161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" -162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" -163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" -164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" -165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi.ico" -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" -256 ICON DISCARDABLE "ICONS/machine.ico" -257 ICON DISCARDABLE "ICONS/video.ico" -258 ICON DISCARDABLE "ICONS/input_devices.ico" -259 ICON DISCARDABLE "ICONS/sound.ico" -260 ICON DISCARDABLE "ICONS/network.ico" -261 ICON DISCARDABLE "ICONS/other_peripherals.ico" -262 ICON DISCARDABLE "ICONS/hard_disk.ico" -263 ICON DISCARDABLE "ICONS/removable_devices.ico" -384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" -385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" -386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" -387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" -388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" -389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" -390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" -391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" -400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" -401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" -402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" -403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" -406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" -407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" -408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" -409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" -416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" -417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" -418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" -419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" -420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" -421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" -432 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_empty.ico" -433 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_empty_active.ico" -512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" -514 ICON DISCARDABLE "ICONS/cdrom_disabled.ico" +128 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd.ico" +129 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd_active.ico" +130 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd.ico" +131 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd_active.ico" +132 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd.ico" +133 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd_active.ico" +134 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd.ico" +135 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd_active.ico" +144 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd.ico" +145 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd_active.ico" +146 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd.ico" +147 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd_active.ico" +150 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd.ico" +151 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd_active.ico" +152 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed.ico" +153 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed_active.ico" +160 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi.ico" +161 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_active.ico" +162 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma.ico" +163 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma_active.ico" +164 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi.ico" +165 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi_active.ico" +176 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi.ico" +177 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi_active.ico" +192 ICON DISCARDABLE "WIN/ICONS/hard_disk_mfm.ico" +193 ICON DISCARDABLE "WIN/ICONS/hard_disk_mfm_active.ico" +194 ICON DISCARDABLE "WIN/ICONS/hard_disk_xtide.ico" +195 ICON DISCARDABLE "WIN/ICONS/hard_disk_xtide_active.ico" +196 ICON DISCARDABLE "WIN/ICONS/hard_disk_rll.ico" +197 ICON DISCARDABLE "WIN/ICONS/hard_disk_rll_active.ico" +198 ICON DISCARDABLE "WIN/ICONS/hard_disk.ico" +199 ICON DISCARDABLE "WIN/ICONS/hard_disk_active.ico" +200 ICON DISCARDABLE "WIN/ICONS/hard_disk_ide.ico" +201 ICON DISCARDABLE "WIN/ICONS/hard_disk_ide_active.ico" +202 ICON DISCARDABLE "WIN/ICONS/hard_disk_scsi.ico" +203 ICON DISCARDABLE "WIN/ICONS/hard_disk_scsi_active.ico" +256 ICON DISCARDABLE "WIN/ICONS/machine.ico" +257 ICON DISCARDABLE "WIN/ICONS/video.ico" +258 ICON DISCARDABLE "WIN/ICONS/input_devices.ico" +259 ICON DISCARDABLE "WIN/ICONS/sound.ico" +260 ICON DISCARDABLE "WIN/ICONS/network.ico" +261 ICON DISCARDABLE "WIN/ICONS/other_peripherals.ico" +262 ICON DISCARDABLE "WIN/ICONS/hard_disk.ico" +263 ICON DISCARDABLE "WIN/ICONS/removable_devices.ico" +384 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd_empty.ico" +385 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd_empty_active.ico" +386 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd_empty.ico" +387 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd_empty_active.ico" +388 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd_empty.ico" +389 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd_empty_active.ico" +390 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd_empty.ico" +391 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd_empty_active.ico" +400 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd_empty.ico" +401 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd_empty_active.ico" +402 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd_empty.ico" +403 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd_empty_active.ico" +406 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd_empty.ico" +407 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd_empty_active.ico" +408 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed_empty.ico" +409 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed_empty_active.ico" +416 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_empty.ico" +417 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_empty_active.ico" +418 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma_empty.ico" +419 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma_empty_active.ico" +420 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi_empty.ico" +421 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi_empty_active.ico" +432 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi_empty.ico" +433 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi_empty_active.ico" +512 ICON DISCARDABLE "WIN/ICONS/floppy_disabled.ico" +514 ICON DISCARDABLE "WIN/ICONS/cdrom_disabled.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -830,188 +713,210 @@ END STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" - IDS_STRING2049 "86Box Error" - IDS_STRING2050 "86Box Fatal Error" - IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" - IDS_STRING2052 "DirectDraw Screenshot Error" - IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" - IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" - IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" - IDS_STRING2056 "Please enter a valid file name" - IDS_STRING2057 "Unable to open the file for write" - IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" - IDS_STRING2059 "Remember to partition and format the new drive" - IDS_STRING2060 "Unable to open the file for read" - IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" - IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." - IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." + 2048 "86Box" + IDS_2049 "86Box Error" + IDS_2050 "86Box Fatal Error" + IDS_2051 "This will reset 86Box.\nAre you sure you want to save the settings?" + IDS_2052 "DirectDraw Screenshot Error" + IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)" + IDS_2054 "Invalid number of heads (valid values are between 1 and 16)" + IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)" + IDS_2056 "Please enter a valid file name" + IDS_2057 "Unable to open the file for write" + IDS_2058 "Attempting to create a HDI image larger than 4 GB" + IDS_2059 "Remember to partition and format the new drive" + IDS_2060 "Unable to open the file for read" + IDS_2061 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." + IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set." END STRINGTABLE DISCARDABLE BEGIN - IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." - IDS_STRING2065 "Machine" - IDS_STRING2066 "Video" - IDS_STRING2067 "Input devices" - IDS_STRING2068 "Sound" - IDS_STRING2069 "Network" - IDS_STRING2070 "Other peripherals" - IDS_STRING2071 "Hard disks" - IDS_STRING2072 "Removable devices" - IDS_STRING2073 "%i"" floppy drive: %s" - IDS_STRING2074 "Disabled CD-ROM drive" - IDS_STRING2075 "%s CD-ROM drive: %s" - IDS_STRING2076 "Host CD/DVD Drive (%c:)" - IDS_STRING2077 "Click to capture mouse" - IDS_STRING2078 "Press F12-F8 to release mouse" - IDS_STRING2079 "Press F12-F8 or middle button to release mouse" + IDS_2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." + IDS_2065 "Machine" + IDS_2066 "Video" + IDS_2067 "Input devices" + IDS_2068 "Sound" + IDS_2069 "Network" + IDS_2070 "Other peripherals" + IDS_2071 "Hard disks" + IDS_2072 "Removable devices" + IDS_2073 "%i"" floppy drive: %s" + IDS_2074 "Disabled CD-ROM drive" + IDS_2075 "%s CD-ROM drive: %s" + IDS_2076 "Host CD/DVD Drive (%c:)" + IDS_2077 "Click to capture mouse" + IDS_2078 "Press F12-F8 to release mouse" + IDS_2079 "Press F12-F8 or middle button to release mouse" END STRINGTABLE DISCARDABLE BEGIN - 2080 "Drive" - 2081 "Location" - 2082 "Bus" - 2083 "File" - 2084 "C" - 2085 "H" - 2086 "S" - 2087 "MB" - 2088 "%i" - 2089 "Enabled" - 2090 "Mute" - 2091 "Type" - 2092 "Bus" - 2093 "DMA" - 2094 "KB" - 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" + IDS_2080 "Drive" + IDS_2081 "Location" + IDS_2082 "Bus" + IDS_2083 "File" + IDS_2084 "C" + IDS_2085 "H" + IDS_2086 "S" + IDS_2087 "MB" + IDS_2088 "%i" + IDS_2089 "Enabled" + IDS_2090 "Mute" + IDS_2091 "Type" + IDS_2092 "Bus" + IDS_2093 "DMA" + IDS_2094 "KB" + IDS_2095 "MFM, RLL, or ESDI CD-ROM drives never existed" END STRINGTABLE DISCARDABLE BEGIN - 2096 "Slave" - 2097 "SCSI (ID %s, LUN %s)" - 2098 "Adapter Type" - 2099 "Base Address" - 2100 "IRQ" - 2101 "8-bit DMA" - 2102 "16-bit DMA" - 2103 "BIOS" - 2104 "Network Type" - 2105 "Surround Module" - 2106 "MPU-401 Base Address" - 2107 "No PCap devices found" - 2108 "On-board RAM" - 2109 "Memory Size" - 2110 "Display Type" - 2111 "RGB" + IDS_2096 "Slave" + IDS_2097 "SCSI (ID %s, LUN %s)" + IDS_2098 "Adapter Type" + IDS_2099 "Base Address" + IDS_2100 "IRQ" + IDS_2101 "8-bit DMA" + IDS_2102 "16-bit DMA" + IDS_2103 "BIOS" + IDS_2104 "Network Type" + IDS_2105 "Surround Module" + IDS_2106 "MPU-401 Base Address" + IDS_2107 "No PCap devices found" + IDS_2108 "On-board RAM" + IDS_2109 "Memory Size" + IDS_2110 "Display Type" + IDS_2111 "RGB" END STRINGTABLE DISCARDABLE BEGIN - 2112 "Composite" - 2113 "Composite Type" - 2114 "Old" - 2115 "New" - 2116 "RGB Type" - 2117 "Color" - 2118 "Monochrome (Green)" - 2119 "Monochrome (Amber)" - 2120 "Monochrome (Gray)" - 2121 "Color (no brown)" - 2122 "Monochrome (Default)" - 2123 "Snow Emulation" - 2124 "Bilinear Filtering" - 2125 "Dithering" - 2126 "Framebuffer Memory Size" - 2127 "Texture Memory Size" + IDS_2112 "Composite" + IDS_2113 "Composite Type" + IDS_2114 "Old" + IDS_2115 "New" + IDS_2116 "RGB Type" + IDS_2117 "Color" + IDS_2118 "Monochrome (Green)" + IDS_2119 "Monochrome (Amber)" + IDS_2120 "Monochrome (Gray)" + IDS_2121 "Color (no brown)" + IDS_2122 "Monochrome (Default)" + IDS_2123 "Snow Emulation" + IDS_2124 "Bilinear Filtering" + IDS_2125 "Dithering" + IDS_2126 "Framebuffer Memory Size" + IDS_2127 "Texture Memory Size" END STRINGTABLE DISCARDABLE BEGIN - 2128 "Screen Filter" - 2129 "Render Threads" - 2130 "Recompiler" - 2131 "System Default" - 2132 "%i Wait state(s)" - 2133 "8-bit" - 2134 "Slow 16-bit" - 2135 "Fast 16-bit" - 2136 "Slow VLB/PCI" - 2137 "Mid VLB/PCI" - 2138 "Fast VLB/PCI" - 2139 "Microsoft 2-button mouse (serial)" - 2140 "Mouse Systems mouse (serial)" - 2141 "2-button mouse (PS/2)" - 2142 "Microsoft Intellimouse (PS/2)" - 2143 "Bus mouse" + IDS_2128 "Screen Filter" + IDS_2129 "Render Threads" + IDS_2130 "Recompiler" + IDS_2131 "System Default" + IDS_2132 "%i Wait state(s)" + IDS_2133 "8-bit" + IDS_2134 "Slow 16-bit" + IDS_2135 "Fast 16-bit" + IDS_2136 "Slow VLB/PCI" + IDS_2137 "Mid VLB/PCI" + IDS_2138 "Fast VLB/PCI" + IDS_2139 "Microsoft 2-button mouse (serial)" + IDS_2140 "Mouse Systems mouse (serial)" + IDS_2141 "2-button mouse (PS/2)" + IDS_2142 "Microsoft Intellimouse (PS/2)" + IDS_2143 "Bus mouse" END STRINGTABLE DISCARDABLE BEGIN - 2144 "Standard 2-button joystick(s)" - 2145 "Standard 4-button joystick" - 2146 "Standard 6-button joystick" - 2147 "Standard 8-button joystick" - 2148 "CH Flightstick Pro" - 2149 "Microsoft SideWinder Pad" - 2150 "Thrustmaster Flight Control System" - 2151 "Disabled" - 2152 "None" - 2153 "AT Fixed Disk Adapter" - 2154 "Internal IDE" - 2155 "IRQ %i" - 2156 "MFM (%01i:%01i)" - 2157 "IDE (PIO+DMA) (%01i:%01i)" - 2158 "SCSI (%02i:%02i)" - 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" - 2160 "%" PRIu64 - 2161 "Genius Bus mouse" - 2162 "Amstrad mouse" - 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" - 2169 "%01i:%01i" - 2170 "Custom..." - 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" - 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" - 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" - 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2177 "Olivetti M24 mouse" - 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" - 2179 "Floppy %i (%s): %ws" - 2180 "CD-ROM %i: %ws" - 2181 "MFM hard disk" - 2182 "IDE hard disk (PIO-only)" - 2183 "IDE hard disk (PIO and DMA)" - 2184 "SCSI hard disk" - 2185 "(empty)" - 2186 "(host drive %c:)" - 2187 "Custom (large)..." - 2188 "Type" - 2189 "ATAPI (PIO-only)" - 2190 "ATAPI (PIO and DMA)" - 2191 "ATAPI (PIO-only) (%01i:%01i)" - 2192 "ATAPI (PIO and DMA) (%01i:%01i)" - 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2194 "Unable to create bitmap file: %s" - 2195 "IDE (PIO-only) (%01i:%01i)" - 2196 "Add New Hard Disk" - 2197 "Add Existing Hard Disk" - 2198 "Removable disk %i: %s" - 2199 "USB is not yet supported" - 2200 "Invalid PCap device" - 2201 "SCSI removable disk: %ws" - 2202 "" - 2203 "English (United States)" - 2204 "Pcap Library Not Available" + IDS_2144 "Standard 2-button joystick(s)" + IDS_2145 "Standard 4-button joystick" + IDS_2146 "Standard 6-button joystick" + IDS_2147 "Standard 8-button joystick" + IDS_2148 "CH Flightstick Pro" + IDS_2149 "Microsoft SideWinder Pad" + IDS_2150 "Thrustmaster Flight Control System" + IDS_2151 "Disabled" + IDS_2152 "None" + IDS_2153 "AT Fixed Disk Adapter" + IDS_2154 "Internal IDE" + IDS_2155 "IRQ %i" + IDS_2156 "MFM (%01i:%01i)" + IDS_2157 "IDE (PIO+DMA) (%01i:%01i)" + IDS_2158 "SCSI (%02i:%02i)" + IDS_2159 "Invalid number of cylinders (valid values are between 1 and 1023)" + IDS_2160 "%" PRIu64 + IDS_2161 "Genius Bus mouse" + IDS_2162 "Amstrad mouse" + IDS_2163 "Attempting to create a spuriously large hard disk image" + IDS_2164 "Invalid number of sectors (valid values are between 1 and 99)" + IDS_2165 "MFM" + IDS_2166 "XT IDE" + IDS_2167 "RLL" + IDS_2168 "IDE (PIO-only)" + IDS_2169 "%01i:%01i" + IDS_2170 "Custom..." + IDS_2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + IDS_2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" + IDS_2173"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" + IDS_2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" + IDS_2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + IDS_2176 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" + IDS_2177 "Olivetti M24 mouse" + IDS_2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" + IDS_2179 "Floppy %i (%s): %ws" + IDS_2180 "CD-ROM %i: %ws" + IDS_2181 "MFM hard disk" + IDS_2182 "IDE hard disk (PIO-only)" + IDS_2183 "IDE hard disk (PIO and DMA)" + IDS_2184 "SCSI hard disk" + IDS_2185 "(empty)" + IDS_2186 "(host drive %c:)" + IDS_2187 "Custom (large)..." + IDS_2188 "Type" + IDS_2189 "ATAPI (PIO-only)" + IDS_2190 "ATAPI (PIO and DMA)" + IDS_2191 "ATAPI (PIO-only) (%01i:%01i)" + IDS_2192 "ATAPI (PIO and DMA) (%01i:%01i)" + IDS_2193 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" + IDS_2194 "Unable to create bitmap file: %s" + IDS_2195 "IDE (PIO-only) (%01i:%01i)" + IDS_2196 "Add New Hard Disk" + IDS_2197 "Add Existing Hard Disk" + IDS_2198 "SCSI removable disk %i: %s" + IDS_2199 "USB is not yet supported" + IDS_2200 "Invalid PCap device" + IDS_2201 "&Notify disk change" + IDS_2202 "SCSI (removable)" + IDS_2203 "SCSI (removable) (%02i:%02i)" + IDS_2204 "Pcap Library Not Available" + IDS_2205 "RLL (%01i:%01i)" + IDS_2206 "XT IDE (%01i:%01i)" + IDS_2207 "RLL hard disk" + IDS_2208 "XT IDE hard disk" + IDS_2209 "IDE (PIO and DMA)" + IDS_2210 "SCSI" + IDS_2211 "&New image..." + IDS_2212 "Existing image..." + IDS_2213 "Existing image (&Write-protected)..." + IDS_2214 "E&ject" + IDS_2215 "&Mute" + IDS_2216 "E&mpty" + IDS_2217 "&Reload previous image" + IDS_2218 "&Image..." + IDS_2219 "PCap failed to set up because it may not be initialized" + IDS_2220 "Image (&Write-protected)..." + IDS_2221 "Turbo" + IDS_2222 "On" + IDS_2223 "Off" + IDS_2224 "" + IDS_2225 "English (United States)" END +#define IDS_LANG_ENUS IDS_2225 #ifndef _MAC @@ -1021,8 +926,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,20,0,0 - PRODUCTVERSION 1,20,0,0 + FILEVERSION 2,0,0,0 + PRODUCTVERSION 2,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1040,14 +945,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "IRC #SoftHistory\0" VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" - VALUE "FileVersion", "1.20\0" - VALUE "InternalName", "pc_new\0" + VALUE "FileVersion", "2.00\0" + VALUE "InternalName", "86Box\0" VALUE "LegalCopyright", "Copyright © SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "86Box.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "86Box Emulator\0" - VALUE "ProductVersion", "1.20\0" + VALUE "ProductVersion", "2.00\0" VALUE "SpecialBuild", "\0" END END @@ -1073,4 +978,3 @@ END ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED - diff --git a/src/ICONS/86Box-RB.ico b/src/WIN/ICONS/86Box-RB.ico similarity index 100% rename from src/ICONS/86Box-RB.ico rename to src/WIN/ICONS/86Box-RB.ico diff --git a/src/ICONS/86Box.ico b/src/WIN/ICONS/86Box.ico similarity index 100% rename from src/ICONS/86Box.ico rename to src/WIN/ICONS/86Box.ico diff --git a/src/ICONS/cdrom_atapi.ico b/src/WIN/ICONS/cdrom_atapi.ico similarity index 100% rename from src/ICONS/cdrom_atapi.ico rename to src/WIN/ICONS/cdrom_atapi.ico diff --git a/src/ICONS/cdrom_atapi_active.ico b/src/WIN/ICONS/cdrom_atapi_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_active.ico rename to src/WIN/ICONS/cdrom_atapi_active.ico diff --git a/src/ICONS/cdrom_atapi_dma.ico b/src/WIN/ICONS/cdrom_atapi_dma.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma.ico rename to src/WIN/ICONS/cdrom_atapi_dma.ico diff --git a/src/ICONS/cdrom_atapi_dma_active.ico b/src/WIN/ICONS/cdrom_atapi_dma_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma_active.ico rename to src/WIN/ICONS/cdrom_atapi_dma_active.ico diff --git a/src/ICONS/cdrom_atapi_dma_empty.ico b/src/WIN/ICONS/cdrom_atapi_dma_empty.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma_empty.ico rename to src/WIN/ICONS/cdrom_atapi_dma_empty.ico diff --git a/src/ICONS/cdrom_atapi_dma_empty_active.ico b/src/WIN/ICONS/cdrom_atapi_dma_empty_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma_empty_active.ico rename to src/WIN/ICONS/cdrom_atapi_dma_empty_active.ico diff --git a/src/ICONS/cdrom_atapi_empty.ico b/src/WIN/ICONS/cdrom_atapi_empty.ico similarity index 100% rename from src/ICONS/cdrom_atapi_empty.ico rename to src/WIN/ICONS/cdrom_atapi_empty.ico diff --git a/src/ICONS/cdrom_atapi_empty_active.ico b/src/WIN/ICONS/cdrom_atapi_empty_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_empty_active.ico rename to src/WIN/ICONS/cdrom_atapi_empty_active.ico diff --git a/src/ICONS/cdrom_disabled.ico b/src/WIN/ICONS/cdrom_disabled.ico similarity index 100% rename from src/ICONS/cdrom_disabled.ico rename to src/WIN/ICONS/cdrom_disabled.ico diff --git a/src/ICONS/cdrom_scsi.ico b/src/WIN/ICONS/cdrom_scsi.ico similarity index 100% rename from src/ICONS/cdrom_scsi.ico rename to src/WIN/ICONS/cdrom_scsi.ico diff --git a/src/ICONS/cdrom_scsi_active.ico b/src/WIN/ICONS/cdrom_scsi_active.ico similarity index 100% rename from src/ICONS/cdrom_scsi_active.ico rename to src/WIN/ICONS/cdrom_scsi_active.ico diff --git a/src/ICONS/cdrom_scsi_empty.ico b/src/WIN/ICONS/cdrom_scsi_empty.ico similarity index 100% rename from src/ICONS/cdrom_scsi_empty.ico rename to src/WIN/ICONS/cdrom_scsi_empty.ico diff --git a/src/ICONS/cdrom_scsi_empty_active.ico b/src/WIN/ICONS/cdrom_scsi_empty_active.ico similarity index 100% rename from src/ICONS/cdrom_scsi_empty_active.ico rename to src/WIN/ICONS/cdrom_scsi_empty_active.ico diff --git a/src/ICONS/floppy_35_1dd.ico b/src/WIN/ICONS/floppy_35_1dd.ico similarity index 100% rename from src/ICONS/floppy_35_1dd.ico rename to src/WIN/ICONS/floppy_35_1dd.ico diff --git a/src/ICONS/floppy_35_1dd_active.ico b/src/WIN/ICONS/floppy_35_1dd_active.ico similarity index 100% rename from src/ICONS/floppy_35_1dd_active.ico rename to src/WIN/ICONS/floppy_35_1dd_active.ico diff --git a/src/ICONS/floppy_35_1dd_empty.ico b/src/WIN/ICONS/floppy_35_1dd_empty.ico similarity index 100% rename from src/ICONS/floppy_35_1dd_empty.ico rename to src/WIN/ICONS/floppy_35_1dd_empty.ico diff --git a/src/ICONS/floppy_35_1dd_empty_active.ico b/src/WIN/ICONS/floppy_35_1dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_1dd_empty_active.ico rename to src/WIN/ICONS/floppy_35_1dd_empty_active.ico diff --git a/src/ICONS/floppy_35_2dd.ico b/src/WIN/ICONS/floppy_35_2dd.ico similarity index 100% rename from src/ICONS/floppy_35_2dd.ico rename to src/WIN/ICONS/floppy_35_2dd.ico diff --git a/src/ICONS/floppy_35_2dd_active.ico b/src/WIN/ICONS/floppy_35_2dd_active.ico similarity index 100% rename from src/ICONS/floppy_35_2dd_active.ico rename to src/WIN/ICONS/floppy_35_2dd_active.ico diff --git a/src/ICONS/floppy_35_2dd_empty.ico b/src/WIN/ICONS/floppy_35_2dd_empty.ico similarity index 100% rename from src/ICONS/floppy_35_2dd_empty.ico rename to src/WIN/ICONS/floppy_35_2dd_empty.ico diff --git a/src/ICONS/floppy_35_2dd_empty_active.ico b/src/WIN/ICONS/floppy_35_2dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_2dd_empty_active.ico rename to src/WIN/ICONS/floppy_35_2dd_empty_active.ico diff --git a/src/ICONS/floppy_35_2ed.ico b/src/WIN/ICONS/floppy_35_2ed.ico similarity index 100% rename from src/ICONS/floppy_35_2ed.ico rename to src/WIN/ICONS/floppy_35_2ed.ico diff --git a/src/ICONS/floppy_35_2ed_active.ico b/src/WIN/ICONS/floppy_35_2ed_active.ico similarity index 100% rename from src/ICONS/floppy_35_2ed_active.ico rename to src/WIN/ICONS/floppy_35_2ed_active.ico diff --git a/src/ICONS/floppy_35_2ed_empty.ico b/src/WIN/ICONS/floppy_35_2ed_empty.ico similarity index 100% rename from src/ICONS/floppy_35_2ed_empty.ico rename to src/WIN/ICONS/floppy_35_2ed_empty.ico diff --git a/src/ICONS/floppy_35_2ed_empty_active.ico b/src/WIN/ICONS/floppy_35_2ed_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_2ed_empty_active.ico rename to src/WIN/ICONS/floppy_35_2ed_empty_active.ico diff --git a/src/ICONS/floppy_35_2hd.ico b/src/WIN/ICONS/floppy_35_2hd.ico similarity index 100% rename from src/ICONS/floppy_35_2hd.ico rename to src/WIN/ICONS/floppy_35_2hd.ico diff --git a/src/ICONS/floppy_35_2hd_active.ico b/src/WIN/ICONS/floppy_35_2hd_active.ico similarity index 100% rename from src/ICONS/floppy_35_2hd_active.ico rename to src/WIN/ICONS/floppy_35_2hd_active.ico diff --git a/src/ICONS/floppy_35_2hd_empty.ico b/src/WIN/ICONS/floppy_35_2hd_empty.ico similarity index 100% rename from src/ICONS/floppy_35_2hd_empty.ico rename to src/WIN/ICONS/floppy_35_2hd_empty.ico diff --git a/src/ICONS/floppy_35_2hd_empty_active.ico b/src/WIN/ICONS/floppy_35_2hd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_2hd_empty_active.ico rename to src/WIN/ICONS/floppy_35_2hd_empty_active.ico diff --git a/src/ICONS/floppy_525_1dd.ico b/src/WIN/ICONS/floppy_525_1dd.ico similarity index 100% rename from src/ICONS/floppy_525_1dd.ico rename to src/WIN/ICONS/floppy_525_1dd.ico diff --git a/src/ICONS/floppy_525_1dd_active.ico b/src/WIN/ICONS/floppy_525_1dd_active.ico similarity index 100% rename from src/ICONS/floppy_525_1dd_active.ico rename to src/WIN/ICONS/floppy_525_1dd_active.ico diff --git a/src/ICONS/floppy_525_1dd_empty.ico b/src/WIN/ICONS/floppy_525_1dd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_1dd_empty.ico rename to src/WIN/ICONS/floppy_525_1dd_empty.ico diff --git a/src/ICONS/floppy_525_1dd_empty_active.ico b/src/WIN/ICONS/floppy_525_1dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_1dd_empty_active.ico rename to src/WIN/ICONS/floppy_525_1dd_empty_active.ico diff --git a/src/ICONS/floppy_525_2dd.ico b/src/WIN/ICONS/floppy_525_2dd.ico similarity index 100% rename from src/ICONS/floppy_525_2dd.ico rename to src/WIN/ICONS/floppy_525_2dd.ico diff --git a/src/ICONS/floppy_525_2dd_active.ico b/src/WIN/ICONS/floppy_525_2dd_active.ico similarity index 100% rename from src/ICONS/floppy_525_2dd_active.ico rename to src/WIN/ICONS/floppy_525_2dd_active.ico diff --git a/src/ICONS/floppy_525_2dd_empty.ico b/src/WIN/ICONS/floppy_525_2dd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_2dd_empty.ico rename to src/WIN/ICONS/floppy_525_2dd_empty.ico diff --git a/src/ICONS/floppy_525_2dd_empty_active.ico b/src/WIN/ICONS/floppy_525_2dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_2dd_empty_active.ico rename to src/WIN/ICONS/floppy_525_2dd_empty_active.ico diff --git a/src/ICONS/floppy_525_2hd.ico b/src/WIN/ICONS/floppy_525_2hd.ico similarity index 100% rename from src/ICONS/floppy_525_2hd.ico rename to src/WIN/ICONS/floppy_525_2hd.ico diff --git a/src/ICONS/floppy_525_2hd_active.ico b/src/WIN/ICONS/floppy_525_2hd_active.ico similarity index 100% rename from src/ICONS/floppy_525_2hd_active.ico rename to src/WIN/ICONS/floppy_525_2hd_active.ico diff --git a/src/ICONS/floppy_525_2hd_empty.ico b/src/WIN/ICONS/floppy_525_2hd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_2hd_empty.ico rename to src/WIN/ICONS/floppy_525_2hd_empty.ico diff --git a/src/ICONS/floppy_525_2hd_empty_active.ico b/src/WIN/ICONS/floppy_525_2hd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_2hd_empty_active.ico rename to src/WIN/ICONS/floppy_525_2hd_empty_active.ico diff --git a/src/ICONS/floppy_525_2qd.ico b/src/WIN/ICONS/floppy_525_2qd.ico similarity index 100% rename from src/ICONS/floppy_525_2qd.ico rename to src/WIN/ICONS/floppy_525_2qd.ico diff --git a/src/ICONS/floppy_525_2qd_active.ico b/src/WIN/ICONS/floppy_525_2qd_active.ico similarity index 100% rename from src/ICONS/floppy_525_2qd_active.ico rename to src/WIN/ICONS/floppy_525_2qd_active.ico diff --git a/src/ICONS/floppy_525_2qd_empty.ico b/src/WIN/ICONS/floppy_525_2qd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_2qd_empty.ico rename to src/WIN/ICONS/floppy_525_2qd_empty.ico diff --git a/src/ICONS/floppy_525_2qd_empty_active.ico b/src/WIN/ICONS/floppy_525_2qd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_2qd_empty_active.ico rename to src/WIN/ICONS/floppy_525_2qd_empty_active.ico diff --git a/src/ICONS/floppy_disabled.ico b/src/WIN/ICONS/floppy_disabled.ico similarity index 100% rename from src/ICONS/floppy_disabled.ico rename to src/WIN/ICONS/floppy_disabled.ico diff --git a/src/ICONS/hard_disk.ico b/src/WIN/ICONS/hard_disk.ico similarity index 100% rename from src/ICONS/hard_disk.ico rename to src/WIN/ICONS/hard_disk.ico diff --git a/src/ICONS/hard_disk_active.ico b/src/WIN/ICONS/hard_disk_active.ico similarity index 100% rename from src/ICONS/hard_disk_active.ico rename to src/WIN/ICONS/hard_disk_active.ico diff --git a/src/ICONS/hard_disk_ide.ico b/src/WIN/ICONS/hard_disk_ide.ico similarity index 100% rename from src/ICONS/hard_disk_ide.ico rename to src/WIN/ICONS/hard_disk_ide.ico diff --git a/src/ICONS/hard_disk_ide_active.ico b/src/WIN/ICONS/hard_disk_ide_active.ico similarity index 100% rename from src/ICONS/hard_disk_ide_active.ico rename to src/WIN/ICONS/hard_disk_ide_active.ico diff --git a/src/ICONS/hard_disk_mfm.ico b/src/WIN/ICONS/hard_disk_mfm.ico similarity index 100% rename from src/ICONS/hard_disk_mfm.ico rename to src/WIN/ICONS/hard_disk_mfm.ico diff --git a/src/ICONS/hard_disk_mfm_active.ico b/src/WIN/ICONS/hard_disk_mfm_active.ico similarity index 100% rename from src/ICONS/hard_disk_mfm_active.ico rename to src/WIN/ICONS/hard_disk_mfm_active.ico diff --git a/src/ICONS/hard_disk_removable_scsi.ico b/src/WIN/ICONS/hard_disk_removable_scsi.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi.ico rename to src/WIN/ICONS/hard_disk_removable_scsi.ico diff --git a/src/ICONS/hard_disk_removable_scsi_active.ico b/src/WIN/ICONS/hard_disk_removable_scsi_active.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi_active.ico rename to src/WIN/ICONS/hard_disk_removable_scsi_active.ico diff --git a/src/ICONS/hard_disk_removable_scsi_empty.ico b/src/WIN/ICONS/hard_disk_removable_scsi_empty.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi_empty.ico rename to src/WIN/ICONS/hard_disk_removable_scsi_empty.ico diff --git a/src/ICONS/hard_disk_removable_scsi_empty_active.ico b/src/WIN/ICONS/hard_disk_removable_scsi_empty_active.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi_empty_active.ico rename to src/WIN/ICONS/hard_disk_removable_scsi_empty_active.ico diff --git a/src/WIN/ICONS/hard_disk_rll.ico b/src/WIN/ICONS/hard_disk_rll.ico new file mode 100644 index 000000000..6d329868b Binary files /dev/null and b/src/WIN/ICONS/hard_disk_rll.ico differ diff --git a/src/WIN/ICONS/hard_disk_rll_active.ico b/src/WIN/ICONS/hard_disk_rll_active.ico new file mode 100644 index 000000000..5692d2452 Binary files /dev/null and b/src/WIN/ICONS/hard_disk_rll_active.ico differ diff --git a/src/ICONS/hard_disk_scsi.ico b/src/WIN/ICONS/hard_disk_scsi.ico similarity index 100% rename from src/ICONS/hard_disk_scsi.ico rename to src/WIN/ICONS/hard_disk_scsi.ico diff --git a/src/ICONS/hard_disk_scsi_active.ico b/src/WIN/ICONS/hard_disk_scsi_active.ico similarity index 100% rename from src/ICONS/hard_disk_scsi_active.ico rename to src/WIN/ICONS/hard_disk_scsi_active.ico diff --git a/src/WIN/ICONS/hard_disk_xtide.ico b/src/WIN/ICONS/hard_disk_xtide.ico new file mode 100644 index 000000000..3f64e2882 Binary files /dev/null and b/src/WIN/ICONS/hard_disk_xtide.ico differ diff --git a/src/WIN/ICONS/hard_disk_xtide_active.ico b/src/WIN/ICONS/hard_disk_xtide_active.ico new file mode 100644 index 000000000..806329fea Binary files /dev/null and b/src/WIN/ICONS/hard_disk_xtide_active.ico differ diff --git a/src/ICONS/input_devices.ico b/src/WIN/ICONS/input_devices.ico similarity index 100% rename from src/ICONS/input_devices.ico rename to src/WIN/ICONS/input_devices.ico diff --git a/src/ICONS/machine.ico b/src/WIN/ICONS/machine.ico similarity index 100% rename from src/ICONS/machine.ico rename to src/WIN/ICONS/machine.ico diff --git a/src/ICONS/network.ico b/src/WIN/ICONS/network.ico similarity index 100% rename from src/ICONS/network.ico rename to src/WIN/ICONS/network.ico diff --git a/src/ICONS/other_peripherals.ico b/src/WIN/ICONS/other_peripherals.ico similarity index 100% rename from src/ICONS/other_peripherals.ico rename to src/WIN/ICONS/other_peripherals.ico diff --git a/src/ICONS/removable_devices.ico b/src/WIN/ICONS/removable_devices.ico similarity index 100% rename from src/ICONS/removable_devices.ico rename to src/WIN/ICONS/removable_devices.ico diff --git a/src/ICONS/sound.ico b/src/WIN/ICONS/sound.ico similarity index 100% rename from src/ICONS/sound.ico rename to src/WIN/ICONS/sound.ico diff --git a/src/ICONS/video.ico b/src/WIN/ICONS/video.ico similarity index 100% rename from src/ICONS/video.ico rename to src/WIN/ICONS/video.ico diff --git a/src/WIN/pcap_if.rc b/src/WIN/pcap_if.rc index 57d78e657..dd4a8f120 100644 --- a/src/WIN/pcap_if.rc +++ b/src/WIN/pcap_if.rc @@ -5,12 +5,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #endif //_WIN32 +/* + * Icons by Devcore + * - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png + */ #ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box-RB.ico" #else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box.ico" #endif 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/plat_serial.h b/src/WIN/plat_serial.h index cf87192c0..56cf08126 100644 --- a/src/WIN/plat_serial.h +++ b/src/WIN/plat_serial.h @@ -8,7 +8,7 @@ * * Definitions for the Bottom Half of the SERIAL card. * - * Version: @(#)plat_serial.h 1.0.3 2017/05/17 + * Version: @(#)plat_serial.h 1.0.5 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -18,7 +18,7 @@ typedef struct { - char name[79]; /* name of open port */ + char name[80]; /* name of open port */ void (*rd_done)(void *, int); void *rd_arg; #ifdef BHTTY_C @@ -28,6 +28,9 @@ typedef struct { int tmo; /* current timeout value */ DCB dcb, /* terminal settings */ odcb; + thread_t *tid; /* pointer to receiver thread */ + char buff[1024]; + int icnt, ihead, itail; #endif } BHTTY; @@ -41,7 +44,7 @@ extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); extern int bhtty_sstate(BHTTY *, void *__arg); extern int bhtty_gstate(BHTTY *, void *__arg); extern int bhtty_crtscts(BHTTY *, char __yesno); - +extern int bhtty_active(BHTTY *, int); extern int bhtty_write(BHTTY *, unsigned char); extern int bhtty_read(BHTTY *, unsigned char *, int); diff --git a/src/WIN/plat_thread.h b/src/WIN/plat_thread.h new file mode 100644 index 000000000..dfb3a9c26 --- /dev/null +++ b/src/WIN/plat_thread.h @@ -0,0 +1,24 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifndef PLAT_THREAD_H +# define PLAT_THREAD_H + + +typedef void thread_t; +typedef void event_t; + + +extern thread_t *thread_create(void (*thread_rout)(void *param), void *param); +extern void thread_kill(thread_t *handle); + +extern event_t *thread_create_event(void); +extern void thread_set_event(event_t *event); +extern void thread_reset_event(event_t *_event); +extern int thread_wait_event(event_t *event, int timeout); +extern void thread_destroy_event(event_t *_event); + +extern void thread_sleep(int t); + + +#endif /*PLAT_THREAD_H*/ diff --git a/src/WIN/resource.h b/src/WIN/resource.h index d70d84a2d..47c92c31c 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -1,497 +1,457 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -/* {{NO_DEPENDENCIES}} - Microsoft Developer Studio generated include file. - Used by 86Box.rc -*/ -#define IDHDCONFIG 3 -#define IDCDCONFIG 4 -#define CONFIGUREDLG_MACHINE 101 -#define CONFIGUREDLG_VIDEO 102 -#define CONFIGUREDLG_INPUT 103 -#define CONFIGUREDLG_SOUND 104 -#define CONFIGUREDLG_NETWORK 105 -#define CONFIGUREDLG_PERIPHERALS 106 -#define CONFIGUREDLG_HARD_DISKS 107 -#define CONFIGUREDLG_REMOVABLE_DEVICES 108 -#define ABOUTDLG 109 -#define CONFIGUREDLG_HARD_DISKS_ADD 110 -#define CONFIGUREDLG_MAIN 117 -#define IDC_SETTINGSCATLIST 1004 -#define IDC_LIST_HARD_DISKS 1005 -#define IDC_COMBO_MACHINE 1006 -#define IDC_COMBO_CPU_TYPE 1007 -#define IDC_COMBO_CPU 1008 -#define IDC_COMBO_WS 1009 -#define IDC_CHECK_DYNAREC 1010 -#define IDC_CHECK_FPU 1011 -#define IDC_COMBO_SCSI 1012 -#define IDC_CONFIGURE_SCSI 1013 -#define IDC_COMBO_VIDEO 1014 -#define IDC_COMBO_VIDEO_SPEED 1015 -#define IDC_CHECK_VOODOO 1016 -#define IDC_CHECKCMS 1016 -#define IDC_CONFIGURE_VOODOO 1017 -#define IDC_CHECKNUKEDOPL 1018 -#define IDC_COMBO_JOYSTICK 1018 -#define IDC_CHECK_SYNC 1019 -#define IDC_LIST_FLOPPY_DRIVES 1020 -#define IDC_LIST_CDROM_DRIVES 1021 -#define IDC_CONFIGURE_MACHINE 1022 -#define IDC_COMBO_LANG 1023 -#define IDC_BUTTON_FDD_ADD 1024 -#define IDC_BUTTON_FDD_EDIT 1025 -#define IDC_BUTTON_FDD_REMOVE 1026 -#define IDC_BUTTON_CDROM_ADD 1027 -#define IDC_BUTTON_HDD_ADD_NEW 1027 -#define IDC_BUTTON_CDROM_EDIT 1028 -#define IDC_BUTTON_HDD_ADD 1028 -#define IDC_BUTTON_CDROM_REMOVE 1029 -#define IDC_BUTTON_HDD_REMOVE 1029 -#define IDC_HDIMAGE_NEW 1035 -#define IDC_HD_BUS 1036 -#define IDC_HDIMAGE_EXISTING 1037 -#define IDC_COMBO_HD_BUS 1038 -#define IDC_EDIT_HD_FILE_NAME 1039 -#define IDC_EDIT_HD_CYL 1040 -#define IDC_EDIT_HD_HPC 1041 -#define IDC_EDIT_HD_SPT 1042 -#define IDC_EDIT_HD_SIZE 1043 -#define IDC_COMBO_HD_TYPE 1044 -#define IDC_COMBO_HD_LOCATION 1045 -#define IDC_CHECKGUS 1046 -#define IDC_COMBO_HD_CHANNEL 1047 -#define IDC_COMBO_HD_CHANNEL_IDE 1048 -#define IDC_COMBO_HD_ID 1050 -#define IDC_COMBO_HD_LUN 1051 -#define IDC_CHECKBUGGER 1052 -#define IDC_CHECKSERIAL1 1053 -#define IDC_CHECKPARALLEL 1054 -#define IDC_CHECKSERIAL2 1055 -#define IDC_COMBO_HDC 1068 -#define IDC_COMBO_MOUSE 1069 -#define IDC_COMBO_IDE_TER 1069 -#define IDC_COMBO_IDE_QUA 1070 -#define IDC_COMBO_FD_TYPE 1071 -#define IDC_COMBO_CD_BUS 1072 -#define IDC_COMBO_CD_CHANNEL_IDE 1073 -#define IDC_COMBO_CD_ID 1074 -#define IDC_COMBO_CD_LUN 1075 -#define IDC_COMBO_MIDI 1076 -#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 -#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 -#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 -#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 -#define IDS_STRING2049 2049 -#define IDS_STRING2050 2050 -#define IDS_STRING2051 2051 -#define IDS_STRING2052 2052 -#define IDS_STRING2053 2053 -#define IDS_STRING2054 2054 -#define IDS_STRING2055 2055 -#define IDS_STRING2056 2056 -#define IDS_STRING2057 2057 -#define IDS_STRING2058 2058 -#define IDS_STRING2059 2059 -#define IDS_STRING2060 2060 -#define IDS_STRING2061 2061 -#define IDS_STRING2062 2062 -#define IDS_STRING2063 2063 -#define IDS_STRING2064 2064 -#define IDS_STRING2065 2065 -#define IDS_STRING2066 2066 -#define IDS_STRING2067 2067 -#define IDS_STRING2068 2068 -#define IDS_STRING2069 2069 -#define IDS_STRING2070 2070 -#define IDS_STRING2071 2071 -#define IDS_STRING2072 2072 -#define IDS_STRING2073 2073 -#define IDS_STRING2074 2074 -#define IDS_STRING2075 2075 -#define IDS_STRING2076 2076 -#define IDS_STRING2077 2077 -#define IDS_STRING2078 2078 -#define IDS_STRING2079 2079 -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows resource defines. + * + * NOTE: FIXME: Strings 2176 and 2193 are same. + * + * Version: @(#)resource.h 1.0.3 2017/06/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempem, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef WIN_RESOURCE_H +# define WIN_RESOURCE_H -#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 -#define IDM_FILE_RESET_CAD 40018 -#define IDM_HDCONF 40019 -#define IDM_CONFIG 40020 -#define IDM_CONFIG_LOAD 40021 -#define IDM_CONFIG_SAVE 40022 -#define IDM_USE_NUKEDOPL 40023 -#define IDM_STATUS 40030 -#define IDM_VID_RESIZE 40050 -#define IDM_VID_REMEMBER 40051 -#define IDM_VID_DDRAW 40060 -#define IDM_VID_D3D 40061 -#define IDM_VID_SCALE_1X 40064 -#define IDM_VID_SCALE_2X 40065 -#define IDM_VID_SCALE_3X 40066 -#define IDM_VID_SCALE_4X 40067 -#define IDM_VID_FULLSCREEN 40070 -#define IDM_VID_FS_FULL 40071 -#define IDM_VID_FS_43 40072 -#define IDM_VID_FS_SQ 40073 -#define IDM_VID_FS_INT 40074 -#define IDM_VID_FORCE43 40075 -#define IDM_VID_OVERSCAN 40076 -#define IDM_VID_FLASH 40077 -#define IDM_VID_SCREENSHOT 40078 -#define IDM_VID_INVERT 40079 +/* Dialog IDs. */ +#define DLG_ABOUT 101 /* top-level dialog */ +#define DLG_STATUS 102 /* top-level dialog */ +#define DLG_CONFIG 110 /* top-level dialog */ +#define DLG_CFG_MACHINE 111 /* sub-dialog of config */ +#define DLG_CFG_VIDEO 112 /* sub-dialog of config */ +#define DLG_CFG_INPUT 113 /* sub-dialog of config */ +#define DLG_CFG_SOUND 114 /* sub-dialog of config */ +#define DLG_CFG_NETWORK 115 /* sub-dialog of config */ +#define DLG_CFG_PERIPHERALS 116 /* sub-dialog of config */ +#define DLG_CFG_HARD_DISKS 117 /* sub-dialog of config */ +#define DLG_CFG_HARD_DISKS_ADD 118 /* sub-dialog of config */ +#define DLG_CFG_REMOVABLE_DEVICES 119 /* sub-dialog of config */ -#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 +/* Static text label IDs. */ +#define IDT_1700 1700 // Language: +#define IDT_1701 1701 // Machine: +#define IDT_1702 1702 // CPU type: +#define IDT_1703 1703 // Wait states: +#define IDT_1704 1704 // CPU: +#define IDT_1705 1705 // MB == IDC_TEXT_MB +#define IDT_1706 1706 // Memory: +#define IDT_1707 1707 // Video: +#define IDT_1708 1708 // Video speed: +#define IDT_1709 1709 // Mouse: +#define IDT_1710 1710 // Joystick: +#define IDT_1711 1711 // Sound card: +#define IDT_1712 1712 // MIDI Out Device: +#define IDT_1713 1713 // Network type: +#define IDT_1714 1714 // PCap device: +#define IDT_1715 1715 // Network adapter: +#define IDT_1716 1716 // SCSI Controller: +#define IDT_1717 1717 // HD Controller: +#define IDT_1718 1718 // Tertiary IDE: +#define IDT_1719 1719 // Quaternary IDE: +#define IDT_1720 1720 // Hard disks: +#define IDT_1721 1721 // Bus: +#define IDT_1722 1722 // Channel: +#define IDT_1723 1723 // ID: +#define IDT_1724 1724 // LUN: +#define IDT_1725 1725 // Channel: +#define IDT_1726 1726 // Sectors: +#define IDT_1727 1727 // Heads: +#define IDT_1728 1728 // Cylinders: +#define IDT_1729 1729 // Size (MB): +#define IDT_1730 1730 // Type: +#define IDT_1731 1731 // File name: +#define IDT_1732 1732 // Bus: +#define IDT_1733 1733 // Channel: +#define IDT_1734 1734 // ID: +#define IDT_1735 1735 // LUN: +#define IDT_1736 1736 // Channel: +#define IDT_1737 1737 // Floppy drives: +#define IDT_1738 1738 // Type: +#define IDT_1739 1739 // CD-ROM drives: +#define IDT_1740 1740 // Bus: +#define IDT_1741 1741 // ID: +#define IDT_1742 1742 // LUN: +#define IDT_1743 1743 // Channel: +#define IDT_STEXT 1744 // text in status window +#define IDT_SDEVICE 1745 // text in status window -#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 -#define IDM_IDE_TER_IRQ11 44011 -#define IDM_IDE_TER_IRQ12 44012 -#define IDM_IDE_TER_IRQ14 44014 -#define IDM_IDE_TER_IRQ15 44015 -#define IDM_IDE_QUA_ENABLED 44020 -#define IDM_IDE_QUA_IRQ9 44029 -#define IDM_IDE_QUA_IRQ10 44030 -#define IDM_IDE_QUA_IRQ11 44031 -#define IDM_IDE_QUA_IRQ12 44032 -#define IDM_IDE_QUA_IRQ14 44033 -#define IDM_IDE_QUA_IRQ15 44035 +/* + * To try to keep these organized, we now group the + * constants per dialog, as this allows easy adding + * and deleting items. + */ +#define IDC_SETTINGSCATLIST 1001 /* generic config */ +#define IDC_CFILE 1002 /* Select File dialog */ +#define IDC_CHECK_SYNC 1008 +#define IDC_COMBO_LANG 1009 -#ifdef ENABLE_LOG_TOGGLES -# ifdef ENABLE_BUSLOGIC_LOG -# define IDM_LOG_BUSLOGIC 51200 -# endif -# ifdef ENABLE_CDROM_LOG -# define IDM_LOG_CDROM 51201 -# endif -# ifdef ENABLE_D86F_LOG -# define IDM_LOG_D86F 51202 -# endif -# ifdef ENABLE_FDC_LOG -# define IDM_LOG_FDC 51203 -# endif -# ifdef ENABLE_IDE_LOG -# define IDM_LOG_IDE 51204 -# endif -# ifdef ENABLE_NE2000_LOG -# define IDM_LOG_NE2000 51205 -# endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT -# define IDM_LOG_BREAKPOINT 51206 -#endif -#ifdef ENABLE_VRAM_DUMP -# define IDM_DUMP_VRAM 51207 -#endif +#define IDC_COMBO_MACHINE 1010 /* machine/cpu config */ +#define IDC_CONFIGURE_MACHINE 1011 +#define IDC_COMBO_CPU_TYPE 1012 +#define IDC_COMBO_CPU 1013 +#define IDC_CHECK_FPU 1014 +#define IDC_COMBO_WS 1015 +#define IDC_CHECK_DYNAREC 1016 +#define IDC_MEMTEXT 1017 +#define IDC_MEMSPIN 1018 +#define IDC_TEXT_MB IDT_1705 -#define IDC_COMBO1 1000 -#define IDC_COMBOVID 1001 -#define IDC_COMBO3 1002 -#define IDC_COMBO4 1003 -#define IDC_COMBO5 1004 -#define IDC_COMBO386 1005 -#define IDC_COMBO486 1006 -#define IDC_COMBOSND 1007 -#define IDC_COMBONETTYPE 1008 -#define IDC_COMBOPCAP 1009 -#define IDC_COMBONET 1010 -#define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODR1 1062 -#define IDC_COMBODR2 1063 -#define IDC_COMBODR3 1064 -#define IDC_COMBODR4 1065 -#define IDC_COMBOJOY 1066 -#define IDC_COMBOWS 1067 -#define IDC_COMBOMOUSE 1068 -#define IDC_COMBOHDD 1069 -#define IDC_CHECK1 1010 -#define IDC_CHECK2 1011 -#define IDC_CHECK3 1012 -#define IDC_CHECKSSI 1014 -#define IDC_CHECKVOODOO 1015 -#define IDC_CHECKDYNAREC 1016 -#define IDC_CHECKBUSLOGIC 1017 -#define IDC_CHECKSYNC 1024 -#define IDC_CHECKXTIDE 1025 -#define IDC_CHECKFPU 1026 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_COMBOHDT 1036 +#define IDC_VIDEO 1030 /* video config */ +#define IDC_COMBO_VIDEO 1031 +#define IDC_COMBO_VIDEO_SPEED 1032 +#define IDC_CHECK_VOODOO 1033 +#define IDC_BUTTON_VOODOO 1034 -#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_INPUT 1050 /* input config */ +#define IDC_COMBO_MOUSE 1051 +#define IDC_COMBO_JOYSTICK 1052 +#define IDC_COMBO_JOY 1053 -#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_SOUND 1070 /* sound config */ +#define IDC_COMBO_SOUND 1071 +#define IDC_CHECK_SSI 1072 +#define IDC_CHECK_CMS 1073 +#define IDC_CHECK_GUS 1074 +#define IDC_CHECK_NUKEDOPL 1075 +#define IDC_COMBO_MIDI 1076 +#define IDC_CHECK_MPU401 1077 +#define IDC_CONFIGURE_MPU401 1078 -#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_COMBO_NET_TYPE 1090 /* network config */ +#define IDC_COMBO_PCAP 1091 +#define IDC_COMBO_NET 1092 -#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_OTHER_PERIPH 1110 /* other periph config */ +#define IDC_COMBO_SCSI 1111 +#define IDC_CONFIGURE_SCSI 1112 +#define IDC_COMBO_HDC 1113 +#define IDC_COMBO_IDE_TER 1114 +#define IDC_COMBO_IDE_QUA 1115 +#define IDC_CHECK_SERIAL1 1116 +#define IDC_CHECK_SERIAL2 1117 +#define IDC_CHECK_PARALLEL 1118 +#define IDC_CHECK_BUGGER 1119 -#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_HARD_DISKS 1130 /* hard disk config */ +#define IDC_LIST_HARD_DISKS 1131 +#define IDC_BUTTON_HDD_ADD_NEW 1132 +#define IDC_BUTTON_HDD_ADD 1133 +#define IDC_BUTTON_HDD_REMOVE 1134 +#define IDC_COMBO_HD_BUS 1135 +#define IDC_COMBO_HD_CHANNEL 1136 +#define IDC_COMBO_HD_ID 1137 +#define IDC_COMBO_HD_LUN 1138 +#define IDC_COMBO_HD_CHANNEL_IDE 1139 +#define IDC_EDIT_HD_FILE_NAME 1140 +#define IDC_EDIT_HD_SPT 1141 +#define IDC_EDIT_HD_HPC 1142 +#define IDC_EDIT_HD_CYL 1143 +#define IDC_EDIT_HD_SIZE 1144 +#define IDC_COMBO_HD_TYPE 1145 -#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_REMOV_DEVICES 1150 /* removable dev config */ +#define IDC_LIST_FLOPPY_DRIVES 1151 +#define IDC_COMBO_FD_TYPE 1152 +#define IDC_CHECKTURBO 1153 +#define IDC_BUTTON_FDD_ADD 1154 // status bar menu +#define IDC_BUTTON_FDD_EDIT 1155 // status bar menu +#define IDC_BUTTON_FDD_REMOVE 1156 // status bar menu +#define IDC_LIST_CDROM_DRIVES 1157 +#define IDC_COMBO_CD_BUS 1158 +#define IDC_COMBO_CD_ID 1159 +#define IDC_COMBO_CD_LUN 1160 +#define IDC_COMBO_CD_CHANNEL_IDE 1161 +#define IDC_BUTTON_CDROM_ADD 1162 // status bar menu +#define IDC_BUTTON_CDROM_EDIT 1163 // status bar menu +#define IDC_BUTTON_CDROM_REMOVE 1164 // status bar menu -#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 +/* For the DeviceConfig code, re-do later. */ +#define IDC_CONFIG_BASE 1200 +#define IDC_CONFIGURE_VID 1200 +#define IDC_CONFIGURE_SND 1201 +#define IDC_CONFIGURE_VOODOO 1202 +#define IDC_CONFIGURE_MOD 1203 +#define IDC_CONFIGURE_NET_TYPE 1204 +#define IDC_CONFIGURE_BUSLOGIC 1205 +#define IDC_CONFIGURE_PCAP 1206 +#define IDC_CONFIGURE_NET 1207 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 +#define IDC_HDTYPE 1280 +#define IDC_RENDER 1281 +#define IDC_STATUS 1282 -#define IDC_HDTYPE 1280 -#define IDC_RENDER 1281 -#define IDC_STATUS 1282 +/* String IDs. */ +#define IDS_STRINGS 2048 // "86Box" +#define IDS_2049 2049 // "86Box Error" +#define IDS_2050 2050 // "86Box Fatal Error" +#define IDS_2051 2051 // "This will reset 86Box.." +#define IDS_2052 2052 // "DirectDraw Screenshot Error" +#define IDS_2053 2053 // "Invalid number of sectors.." +#define IDS_2054 2054 // "Invalid number of heads.." +#define IDS_2055 2055 // "Invalid number of cylinders.." +#define IDS_2056 2056 // "Please enter a valid file name" +#define IDS_2057 2057 // "Unable to open the file for write" +#define IDS_2058 2058 // "Attempting to create a HDI.." +#define IDS_2059 2059 // "Remember to partition and.." +#define IDS_2060 2060 // "Unable to open the file.." +#define IDS_2061 2061 // "HDI or HDX image with a.." +#define IDS_2062 2062 // "86Box was unable to find any.." +#define IDS_2063 2063 // "Configured ROM set not avai.." +#define IDS_2064 2064 // "Configured video BIOS not.." +#define IDS_2065 2065 // "Machine" +#define IDS_2066 2066 // "Video" +#define IDS_2067 2067 // "Input devices" +#define IDS_2068 2068 // "Sound" +#define IDS_2069 2069 // "Network" +#define IDS_2070 2070 // "Other peripherals" +#define IDS_2071 2071 // "Hard disks" +#define IDS_2072 2072 // "Removable devices" +#define IDS_2073 2073 // "%i"" floppy drive: %s" +#define IDS_2074 2074 // "Disabled CD-ROM drive" +#define IDS_2075 2075 // "%s CD-ROM drive: %s" +#define IDS_2076 2076 // "Host CD/DVD Drive (%c:)" +#define IDS_2077 2077 // "Click to capture mouse" +#define IDS_2078 2078 // "Press F12-F8 to release mouse" +#define IDS_2079 2079 // "Press F12-F8 or middle button.." +#define IDS_2080 2080 // "Drive" +#define IDS_2081 2081 // "Location" +#define IDS_2082 2082 // "Bus" +#define IDS_2083 2083 // "File" +#define IDS_2084 2084 // "C" +#define IDS_2085 2085 // "H" +#define IDS_2086 2086 // "S" +#define IDS_2087 2087 // "MB" +#define IDS_2088 2088 // "%i" +#define IDS_2089 2089 // "Enabled" +#define IDS_2090 2090 // "Mute" +#define IDS_2091 2091 // "Type" +#define IDS_2092 2092 // "Bus" +#define IDS_2093 2093 // "DMA" +#define IDS_2094 2094 // "KB" +#define IDS_2095 2095 // "MFM, RLL, or ESDI CD-ROM.." +#define IDS_2096 2096 // "Slave" +#define IDS_2097 2097 // "SCSI (ID %s, LUN %s)" +#define IDS_2098 2098 // "Adapter Type" +#define IDS_2099 2099 // "Base Address" +#define IDS_2100 2100 // "IRQ" +#define IDS_2101 2101 // "8-bit DMA" +#define IDS_2102 2102 // "16-bit DMA" +#define IDS_2103 2103 // "BIOS" +#define IDS_2104 2104 // "Network Type" +#define IDS_2105 2105 // "Surround Module" +#define IDS_2106 2106 // "MPU-401 Base Address" +#define IDS_2107 2107 // "No PCap devices found" +#define IDS_2108 2108 // "On-board RAM" +#define IDS_2109 2109 // "Memory Size" +#define IDS_2110 2110 // "Display Type" +#define IDS_2111 2111 // "RGB" +#define IDS_2112 2112 // "Composite" +#define IDS_2113 2113 // "Composite Type" +#define IDS_2114 2114 // "Old" +#define IDS_2115 2115 // "New" +#define IDS_2116 2116 // "RGB Type" +#define IDS_2117 2117 // "Color" +#define IDS_2118 2118 // "Monochrome (Green)" +#define IDS_2119 2119 // "Monochrome (Amber)" +#define IDS_2120 2120 // "Monochrome (Gray)" +#define IDS_2121 2121 // "Color (no brown)" +#define IDS_2122 2122 // "Monochrome (Default)" +#define IDS_2123 2123 // "Snow Emulation" +#define IDS_2124 2124 // "Bilinear Filtering" +#define IDS_2125 2125 // "Dithering" +#define IDS_2126 2126 // "Framebuffer Memory Size" +#define IDS_2127 2127 // "Texture Memory Size" +#define IDS_2128 2128 // "Screen Filter" +#define IDS_2129 2129 // "Render Threads" +#define IDS_2130 2130 // "Recompiler" +#define IDS_2131 2131 // "System Default" +#define IDS_2132 2132 // "%i Wait state(s)" +#define IDS_2133 2133 // "8-bit" +#define IDS_2134 2134 // "Slow 16-bit" +#define IDS_2135 2135 // "Fast 16-bit" +#define IDS_2136 2136 // "Slow VLB/PCI" +#define IDS_2137 2137 // "Mid VLB/PCI" +#define IDS_2138 2138 // "Fast VLB/PCI" +#define IDS_2139 2139 // "Microsoft 2-button mouse (serial)" +#define IDS_2140 2140 // "Mouse Systems mouse (serial)" +#define IDS_2141 2141 // "2-button mouse (PS/2)" +#define IDS_2142 2142 // "Microsoft Intellimouse (PS/2)" +#define IDS_2143 2143 // "Bus mouse" +#define IDS_2144 2144 // "Standard 2-button joystick(s)" +#define IDS_2145 2145 // "Standard 4-button joystick" +#define IDS_2146 2146 // "Standard 6-button joystick" +#define IDS_2147 2147 // "Standard 8-button joystick" +#define IDS_2148 2148 // "CH Flightstick Pro" +#define IDS_2149 2149 // "Microsoft SideWinder Pad" +#define IDS_2150 2150 // "Thrustmaster Flight Control System" +#define IDS_2151 2151 // "Disabled" +#define IDS_2152 2152 // "None" +#define IDS_2153 2153 // "AT Fixed Disk Adapter" +#define IDS_2154 2154 // "Internal IDE" +#define IDS_2155 2155 // "IRQ %i" +#define IDS_2156 2156 // "MFM (%01i:%01i)" +#define IDS_2157 2157 // "IDE (PIO+DMA) (%01i:%01i)" +#define IDS_2158 2158 // "SCSI (%02i:%02i)" +#define IDS_2159 2159 // "Invalid number of cylinders.." +#define IDS_2160 2160 // "%" PRIu64 +#define IDS_2161 2161 // "Genius Bus mouse" +#define IDS_2162 2162 // "Amstrad mouse" +#define IDS_2163 2163 // "Attempting to create a spuriously.." +#define IDS_2164 2164 // "Invalid number of sectors.." +#define IDS_2165 2165 // "MFM" +#define IDS_2166 2166 // "XT IDE" +#define IDS_2167 2167 // "RLL" +#define IDS_2168 2168 // "IDE (PIO-only)" +#define IDS_2169 2169 // "%01i:%01i" +#define IDS_2170 2170 // "Custom..." +#define IDS_2171 2171 // "%" PRIu64 " MB (CHS: %" .. +#define IDS_2172 2172 // "Hard disk images .." +#define IDS_2173 2173 // "All floppy images .." +#define IDS_2174 2174 // "Configuration files .." +#define IDS_2175 2175 // "CD-ROM image .." +#define IDS_2176 2176 // "Use CTRL+ALT+PAGE DOWN .." +#define IDS_2177 2177 // "Olivetti M24 mouse" +#define IDS_2178 2178 // "This image exists and will.." +#define IDS_2179 2179 // "Floppy %i (%s): %ws" +#define IDS_2180 2180 // "CD-ROM %i: %ws" +#define IDS_2181 2181 // "MFM hard disk" +#define IDS_2182 2182 // "IDE hard disk (PIO-only)" +#define IDS_2183 2183 // "IDE hard disk (PIO and DMA)" +#define IDS_2184 2184 // "SCSI hard disk" +#define IDS_2185 2185 // "(empty)" +#define IDS_2186 2186 // "(host drive %c:)" +#define IDS_2187 2187 // "Custom (large)..." +#define IDS_2188 2188 // "Type" +#define IDS_2189 2189 // "ATAPI (PIO-only)" +#define IDS_2190 2190 // "ATAPI (PIO and DMA)" +#define IDS_2191 2191 // "ATAPI (PIO-only) (%01i:%01i)" +#define IDS_2192 2192 // "ATAPI (PIO and DMA) (%01i:%01i)" +#define IDS_2193 2193 // "Use CTRL+ALT+PAGE DOWN to .." +#define IDS_2194 2194 // "Unable to create bitmap file: %s" +#define IDS_2195 2195 // "IDE (PIO-only) (%01i:%01i)" +#define IDS_2196 2196 // "Add New Hard Disk" +#define IDS_2197 2197 // "Add Existing Hard Disk" +#define IDS_2198 2198 // "SCSI removable disk %i: %s" +#define IDS_2199 2199 // "USB is not yet supported" +#define IDS_2200 2200 // "Invalid PCap device" +#define IDS_2201 2201 // "&Notify disk change" +#define IDS_2202 2202 // "SCSI (removable)" +#define IDS_2203 2203 // "SCSI (removable) (%02i:%02i)" +#define IDS_2204 2204 // "Pcap Library Not Available" +#define IDS_2205 2205 // "RLL (%01i:%01i)" +#define IDS_2206 2206 // "XT IDE (%01i:%01i)" +#define IDS_2207 2207 // "RLL hard disk" +#define IDS_2208 2208 // "XT IDE hard disk" +#define IDS_2209 2209 // "IDE (PIO and DMA)" +#define IDS_2210 2210 // "SCSI" +#define IDS_2211 2211 // "&New image..." +#define IDS_2212 2212 // "Existing image..." +#define IDS_2213 2213 // "Existing image (&Write-.." +#define IDS_2214 2214 // "E&ject" +#define IDS_2215 2215 // "&Mute" +#define IDS_2216 2216 // "E&mpty" +#define IDS_2217 2217 // "&Reload previous image" +#define IDS_2218 2218 // "&Image..." +#define IDS_2219 2219 // "PCap failed to set up .." +#define IDS_2220 2220 // "Image (&Write-protected)..." +#define IDS_2221 2221 // "Turbo" +#define IDS_2222 2222 // "On" +#define IDS_2223 2223 // "Off" +#define IDS_2224 2224 // "" +#define IDS_2225 2225 // "English (United States)" -#define IDC_MEMSPIN 1100 -#define IDC_MEMTEXT 1101 -#define IDC_STEXT1 1102 -#define IDC_STEXT2 1103 -#define IDC_STEXT3 1104 -#define IDC_STEXT4 1105 -#define IDC_STEXT5 1106 -#define IDC_STEXT6 1107 -#define IDC_STEXT7 1108 -#define IDC_STEXT8 1109 -#define IDC_STEXT_DEVICE 1110 -#define IDC_TEXT_MB 1111 -#define IDC_TEXT1 1115 -#define IDC_TEXT2 1116 +#define IDS_LANG_ENUS IDS_2225 +#define STRINGS_NUM 178 -#define IDC_CONFIGUREVID 1200 -#define IDC_CONFIGURESND 1201 -#define IDC_CONFIGUREVOODOO 1202 -#define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENETTYPE 1204 -#define IDC_CONFIGUREBUSLOGIC 1205 -#define IDC_CONFIGUREPCAP 1206 -#define IDC_CONFIGURENET 1207 -#define IDC_JOY1 1210 -#define IDC_JOY2 1211 -#define IDC_JOY3 1212 -#define IDC_JOY4 1213 -#define IDC_CONFIG_BASE 1200 +#define IDM_ABOUT 40001 +#define IDC_ABOUT_ICON 65535 +#define IDM_ACTION_SCREENSHOT 40011 +#define IDM_ACTION_HRESET 40012 +#define IDM_ACTION_RESET_CAD 40013 +#define IDM_ACTION_EXIT 40014 +#define IDM_CONFIG 40020 +#define IDM_CONFIG_LOAD 40021 +#define IDM_CONFIG_SAVE 40022 +#define IDM_STATUS 40030 +#define IDM_VID_RESIZE 40050 +#define IDM_VID_REMEMBER 40051 +#define IDM_VID_DDRAW 40060 +#define IDM_VID_D3D 40061 +#define IDM_VID_SCALE_1X 40064 +#define IDM_VID_SCALE_2X 40065 +#define IDM_VID_SCALE_3X 40066 +#define IDM_VID_SCALE_4X 40067 +#define IDM_VID_FULLSCREEN 40070 +#define IDM_VID_FS_FULL 40071 +#define IDM_VID_FS_43 40072 +#define IDM_VID_FS_SQ 40073 +#define IDM_VID_FS_INT 40074 +#define IDM_VID_FORCE43 40075 +#define IDM_VID_OVERSCAN 40076 +#define IDM_VID_INVERT 40079 +#define IDM_VID_CGACON 40080 -#define WM_RESETD3D WM_USER -#define WM_LEAVEFULLSCREEN WM_USER + 1 +#define IDM_LOG_BREAKPOINT 51201 +#define IDM_DUMP_VRAM 51202 // should be an Action -#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_LOG_SERIAL 51211 +#define IDM_LOG_D86F 51212 +#define IDM_LOG_FDC 51213 +#define IDM_LOG_IDE 51214 +#define IDM_LOG_CDROM 51215 +#define IDM_LOG_NIC 51216 +#define IDM_LOG_BUSLOGIC 51217 -#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 +/* + * We need 7 bits for CDROM (2 bits ID and 5 bits for host drive), + * and 5 bits for Removable Disks (5 bits for ID), so we use an + * 8bit (256 entries) space for these devices. + */ +#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_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 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_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 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_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 IDC_STATIC 1792 /* Next default values for new objects */ #ifdef APSTUDIO_INVOKED # ifndef APSTUDIO_READONLY_SYMBOLS # define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 111 -# define _APS_NEXT_COMMAND_VALUE 40002 -# define _APS_NEXT_CONTROL_VALUE 1055 -# define _APS_NEXT_SYMED_VALUE 101 +# define _APS_NEXT_RESOURCE_VALUE 1400 +# define _APS_NEXT_COMMAND_VALUE 55000 +# define _APS_NEXT_CONTROL_VALUE 1800 +# define _APS_NEXT_SYMED_VALUE 200 # endif #endif + + +#endif /*WIN_RESOURCE_H*/ diff --git a/src/WIN/win.c b/src/WIN/win.c index 4b6c771d0..5a76bcc94 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * The Emulator's Windows core. + * + * Version: @(#)win.c 1.0.2 2017/06/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include #include @@ -15,7 +30,6 @@ #include "../mem.h" #include "../rom.h" #include "../nvr.h" -#include "../thread.h" #include "../config.h" #include "../model.h" #include "../ide.h" @@ -23,103 +37,123 @@ #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" +#include "plat_thread.h" #include "win.h" +#include "win_cgapal.h" #include "win_ddraw.h" #include "win_d3d.h" #include "win_language.h" + #include #include #include #include -#include "resource.h" #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 #endif -static int save_window_pos = 0; -uint64_t timer_freq; - -int rawinputkey[272]; - -static RAWINPUTDEVICE device; -static uint16_t scancode_map[65536]; - -static struct -{ - int (*init)(HWND h); - 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 - }, -}; - -#define TIMER_1SEC 1 - -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; - /* 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); LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -LONG_PTR OriginalStatusBarProcedure; +#define TIMER_1SEC 1 -HWND ghwnd; +extern int updatestatus; -HINSTANCE hinstance; -HMENU menu; +typedef struct win_event_t +{ + HANDLE handle; +} win_event_t; -extern int updatestatus; +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; -int pause=0; -static int win_doresize = 0; +static struct +{ + int (*init)(HWND h); + 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 } } }; -static int leave_fullscreen_flag = 0; +static int save_window_pos = 0; -static int unscaled_size_x = 0; -static int unscaled_size_y = 0; +static RAWINPUTDEVICE device; -int scale = 0; +static int win_doresize = 0; + +static int leave_fullscreen_flag = 0; + +static int unscaled_size_x = 0; +static int unscaled_size_y = 0; + +static uint64_t start_time; +static uint64_t end_time; + +HMENU smenu; + +static uint8_t host_cdrom_drive_available[26]; + +static uint8_t host_cdrom_drive_available_num = 0; + +static wchar_t **argv; +static int argc; +static wchar_t *argbuf; + +static HANDLE hinstAcc; + +static HICON hIcon[512]; + +static int *iStatusWidths; +static int *sb_icon_flags; +static int *sb_part_meanings; +static int *sb_part_icons; +static WCHAR **sbTips; + +static int sb_parts = 0; +static int sb_ready = 0; -HWND hwndRender, hwndStatus; void updatewindowsize(int x, int y) { @@ -236,11 +270,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 +282,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 +316,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, @@ -301,6 +326,12 @@ void mainthread(LPVOID param) winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, TRUE); + if (mousecapture) + { + GetWindowRect(hwndRender, &r); + ClipCursor(&r); + } + win_doresize = 0; } @@ -331,11 +362,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 +406,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); + + 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 - 'A']) + { + cdrom_drives[id].host_drive = 0; + } + } + } + + AppendMenu(m, MF_SEPARATOR, 0, 0); + + for (i = 0; i < 26; i++) + { + wsprintf(s, L"Host CD/DVD Drive (%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(m, IDM_CDROM_MUTE | id, MF_CHECKED); + } + + if (cdrom_drives[id].host_drive == 200) + { + CheckMenuItem(m, IDM_CDROM_IMAGE | id, MF_CHECKED); + } + else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(m, IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); + } + else + { + cdrom_drives[id].host_drive = 0; + CheckMenuItem(m, 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 +544,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 +610,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 +625,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 +666,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 +683,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_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) { - return; + return -1; } - temp_flags |= active; - for (i = 0; i < 12; i++) { if (sb_part_meanings[i] == tag) @@ -703,6 +702,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_ready || (sb_parts == 0) || (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 +738,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_ready || (sb_parts == 0) || (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 +759,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 +795,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) @@ -831,6 +887,11 @@ void update_tip(int meaning) int i = 0; int part = -1; + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) + { + return; + } + for (i = 0; i < sb_parts; i++) { if (sb_part_meanings[i] == meaning) @@ -843,16 +904,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,38 +924,19 @@ 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; int part = -1; + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) + { + return; + } + for (i = 0; i < sb_parts; i++) { - if (sb_part_meanings[i] == 0x40) + if (sb_part_meanings[i] == SB_TEXT) { part = i; } @@ -915,95 +957,221 @@ 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); + sb_ready = 0; - for (i = 0; i < sb_parts; i++) + 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); + + 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++) + for (i = 0; i < HDC_NUM; 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 * sizeof(int)); + sb_part_meanings = (int *) malloc(sb_parts * sizeof(int)); + sb_part_icons = (int *) malloc(sb_parts * sizeof(int)); + sb_icon_flags = (int *) malloc(sb_parts * sizeof(int)); + sb_menu_handles = (HMENU *) malloc(sb_parts * sizeof(HMENU)); + sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); + + memset(iStatusWidths, 0, sb_parts * sizeof(int)); + memset(sb_part_meanings, 0, sb_parts * sizeof(int)); + memset(sb_part_icons, 0, sb_parts * sizeof(int)); + memset(sb_icon_flags, 0, sb_parts * sizeof(int)); + memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); + memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); + + 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,35 +1180,35 @@ 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) + if (cdrom_drives[id].host_drive == 200) { - sb_icon_flags[i] = 256; + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; + } + else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + sb_icon_flags[i] = 0; } else { - if (cdrom_drives[id].host_drive == 0x200) - { - sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; - } - else - { - sb_icon_flags[i] = 0; - } + sb_icon_flags[i] = 256; } - 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 +1217,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; @@ -1080,6 +1256,8 @@ void update_status_bar_panes(HWND hwnds) SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); } } + + sb_ready = 1; } HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) @@ -1114,7 +1292,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 +1328,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,102 +1358,107 @@ 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"%s v%s", EMU_NAME_W, EMU_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(); ghwnd=hwnd; + hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + initpc(argc, argv); - hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + init_cdrom_host_drives(); hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); @@ -1296,7 +1466,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); + + initmodules(); if (vid_apis[0][vid_api].init(hwndRender) == 0) { @@ -1313,47 +1484,29 @@ 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 +# ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_CDROM_LOG +# endif +# ifdef ENABLE_CDROM_LOG CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_D86F_LOG +# endif +# ifdef ENABLE_D86F_LOG CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_FDC_LOG +# endif +# ifdef ENABLE_FDC_LOG CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_IDE_LOG +# endif +# ifdef ENABLE_IDE_LOG CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_NE2000_LOG - CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif +# endif +# ifdef ENABLE_SERIAL_LOG + CheckMenuItem(menu, IDM_LOG_SERIAL, serial_do_log ? MF_CHECKED : MF_UNCHECKED); +# endif +# ifdef ENABLE_NIC_LOG + /*FIXME: should be network_setlog(1:0) */ + CheckMenuItem(menu, IDM_LOG_NIC, nic_do_log ? MF_CHECKED : MF_UNCHECKED); +# endif #endif CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); @@ -1366,6 +1519,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); + d=romset; for (c=0;c= 0; c--) { @@ -1439,8 +1595,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 +1656,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 +1691,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 +1729,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 +1759,476 @@ 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)DLG_ABOUT, 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_ACTION_SCREENSHOT: + take_screenshot(); + 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_ACTION_HRESET: + win_pc_reset(1); + 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_ACTION_RESET_CAD: + win_pc_reset(0); + 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_ACTION_EXIT: + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + 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_CONFIG: + win_settings_open(hwnd); + break; - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - break; + case IDM_ABOUT: + about_open(hwnd); + break; - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - break; + case IDM_STATUS: + status_open(hwnd); + break; - case IDM_VID_OVERSCAN: - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - update_overscan = 1; - 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_FLASH: - video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); - 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_SCREENSHOT: - take_screenshot(); - 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_FULLSCREEN: + if(video_fullscreen != 1) + { + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + msgbox_info(ghwnd, IDS_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_CGACON: + vid_cga_contrast = !vid_cga_contrast; + CheckMenuItem(menu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); + cgapal_rebuild(); + saveconfig(); + 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; +#ifdef ENABLE_SERIAL_LOG + case IDM_LOG_SERIAL: + serial_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_SERIAL, serial_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_NIC_LOG + case IDM_LOG_NIC: + /*FIXME: should be network_setlog() */ + nic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NIC, nic_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, IDS_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, IDS_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(hwndRender, &rect); + + 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(hwndRender, &rect); + + 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; + } + + saveconfig(); + 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; + saveconfig(); + 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 +2238,223 @@ 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, IDS_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, IDS_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 - 'A') << 3), MF_UNCHECKED); + } + cdrom_drives[id].host_drive = (wcslen(cdrom_image[id].image_path) == 0) ? 0 : 200; + if (cdrom_drives[id].host_drive == 200) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + update_status_bar_icon_state(SB_CDROM | id, 0); + } + else + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + update_status_bar_icon_state(SB_CDROM | id, 1); + } + 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 - 'A') << 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 - 'A') << 3), MF_CHECKED); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + update_status_bar_icon_state(SB_CDROM | id, 0); + 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, IDS_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..72bad6dcf 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * The Emulator's Windows core. + * + * Version: @(#)win.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /* * This should be named 'plat.h' and then include any * Windows-specific header files needed, to keep them @@ -8,15 +26,17 @@ */ #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 +# include "resource.h" # undef BITMAP @@ -25,6 +45,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 +65,9 @@ extern WCHAR wopenfilestring[260]; extern int pause; +extern HMENU smenu; +extern HMENU *sb_menu_handles; + #ifdef __cplusplus extern "C" { @@ -66,6 +97,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_cgapal.h b/src/WIN/win_cgapal.h index d6ac7ffd8..0388cde27 100644 --- a/src/WIN/win_cgapal.h +++ b/src/WIN/win_cgapal.h @@ -1,3 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * The Windows CGA palette handler header. + * + * Version: @(#)win_cgapal.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern PALETTE cgapal; extern PALETTE cgapal_mono[6]; diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index ce2d9a3b5..f090465b3 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -1,12 +1,25 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Direct3D 9 rendererer and screenshots taking. + * + * Version: @(#)win_d3d.cc 1.0.0 2017/05/30 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include "../video/video.h" #include "win.h" #include "win_d3d.h" #include "win_cgapal.h" -#include "resource.h" extern "C" void fatal(const char *format, ...); diff --git a/src/WIN/win_d3d.h b/src/WIN/win_d3d.h index 5994a87b1..11128d486 100644 --- a/src/WIN/win_d3d.h +++ b/src/WIN/win_d3d.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Direct3D 9 rendererer and screenshots taking. + * + * Version: @(#)win_d3d.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef WIN_D3D_H # define WIN_D3D_H # define UNICODE diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 9e410ec3b..0f894dc34 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -1,6 +1,20 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Direct3D 9 full screen rendererer and screenshots taking. + * + * Version: @(#)win_d3d_fs.cc 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include #include "../86box.h" @@ -8,7 +22,6 @@ #include "win.h" #include "win_d3d.h" #include "win_cgapal.h" -#include "resource.h" extern "C" void fatal(const char *format, ...); @@ -83,13 +96,13 @@ PALETTE cgapal_mono[6] = {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, }, { // 4 - grey, 4-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, - {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},{0x33,0x34,0x32},{0x37,0x38,0x35}, + {0x09,0x0a,0x0b},{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, }, { // 5 - grey, 16-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, - {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, - }, + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c}, + {0x1f,0x21,0x21},{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, + } }; uint32_t pal_lookup[256]; @@ -115,20 +128,33 @@ void cgapal_rebuild(void) } if ((cga_palette > 1) && (cga_palette < 8)) { - for (c = 0; c < 16; c++) + if (vid_cga_contrast != 0) { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - } - } + for (c = 0; c < 16; c++) + { + pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + } + } + else + { + for (c = 0; c < 16; c++) + { + pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + } + } + } + if (cga_palette == 8) { pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); } } - int d3d_fs_init(HWND h) { @@ -142,7 +168,8 @@ int d3d_fs_init(HWND h) d3d_hwnd = h; - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + /*FIXME: should be done once, in win.c */ + _swprintf(emulator_title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); d3d_device_window = CreateWindowEx ( 0, szSubClassName, diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc index dd985baf8..dc111bab1 100644 --- a/src/WIN/win_ddraw.cc +++ b/src/WIN/win_ddraw.cc @@ -137,6 +137,12 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) return; /*Nothing to do*/ } + if (h <= 0) + { + video_blit_complete(); + return; + } + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -178,29 +184,6 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash) - { - readflash = 0; -#ifdef LEGACY_READ_FLASH - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - } -#endif - } lpdds_back2->Unlock(NULL); // pclog("Blit from %i,%i %i,%i to %i,%i %i,%i\n", r_src.left, r_src.top, r_src.right, r_src.bottom, r_dest.left, r_dest.top, r_dest.right, r_dest.bottom); @@ -276,29 +259,6 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash) - { - readflash = 0; - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - lpdds_back2->Unlock(NULL); - } - } - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); if (hr == DDERR_SURFACELOST) { diff --git a/src/WIN/win_ddraw_fs.cc b/src/WIN/win_ddraw_fs.cc index 88649f7e9..f29524d64 100644 --- a/src/WIN/win_ddraw_fs.cc +++ b/src/WIN/win_ddraw_fs.cc @@ -227,17 +227,6 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); if (hr == DDERR_SURFACELOST) { @@ -314,17 +303,6 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); } diff --git a/src/WIN/win_ddraw_screenshot.cc b/src/WIN/win_ddraw_screenshot.cc index 717b94348..b98a207d1 100644 --- a/src/WIN/win_ddraw_screenshot.cc +++ b/src/WIN/win_ddraw_screenshot.cc @@ -1,6 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * DirectDraw screenshot taking code. + * + * Version: @(#)win_ddraw_screenshot.cc 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include #include #define UNICODE diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index c64dd3af7..1b1f994ce 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -1,10 +1,23 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows device configuration dialog implementation. + * + * Version: @(#)win_deviceconfig.c 1.0.0 2017/05/30 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include "../ibm.h" #include "../config.h" #include "../device.h" -#include "resource.h" #define NO_UNICODE /*FIXME: not Unicode? */ #include "win.h" #include @@ -42,7 +55,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 +71,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 +134,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 +148,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 +207,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 +216,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 +310,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_dynld.c b/src/WIN/win_dynld.c index 229febc3a..9f7d4d3c5 100644 --- a/src/WIN/win_dynld.c +++ b/src/WIN/win_dynld.c @@ -8,7 +8,7 @@ * * Try to load a support DLL. * - * Version: @(#)win_dynld.c 1.0.1 2017/05/21 + * Version: @(#)win_dynld.c 1.0.2 2017/05/24 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen @@ -26,7 +26,7 @@ void * dynld_module(const char *name, dllimp_t *table) { - HANDLE h; + HMODULE h; dllimp_t *imp; void *func; char **foo; @@ -60,5 +60,5 @@ void dynld_close(void *handle) { if (handle != NULL) - CloseHandle((HANDLE *)handle); + FreeLibrary((HMODULE)handle); } diff --git a/src/WIN/win_iodev.c b/src/WIN/win_iodev.c new file mode 100644 index 000000000..c2c2de9db --- /dev/null +++ b/src/WIN/win_iodev.c @@ -0,0 +1,197 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows IO device menu handler. + * + * Version: @(#)win_iodev.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ +#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 "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_drives[id].host_drive - 'A') << 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); + } + if (wcslen(cdrom_image[id].image_path) == 0) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED); + cdrom_drives[id].host_drive = 0; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + update_status_bar_icon_state(SB_CDROM | id, 1); + } + else + { + 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); + update_status_bar_icon_state(SB_CDROM | id, 0); + } + } + 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_drives[id].host_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 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_joystick.cc b/src/WIN/win_joystick.cc index 63d970eaa..91c2138b0 100644 --- a/src/WIN/win_joystick.cc +++ b/src/WIN/win_joystick.cc @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Joystick interface to host device. + * + * Version: @(#)win_joystick.cc 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define DIRECTINPUT_VERSION 0x0800 #include #include diff --git a/src/WIN/win_joystickconfig.c b/src/WIN/win_joystickconfig.c index 8962366d6..3cd5a0c68 100644 --- a/src/WIN/win_joystickconfig.c +++ b/src/WIN/win_joystickconfig.c @@ -11,14 +11,15 @@ #include "../device.h" #include "../gameport.h" #include "plat_joystick.h" -#include "resource.h" #include "win.h" + static int joystick_nr; static int joystick_config_type; #define AXIS_STRINGS_MAX 3 static char *axis_strings[AXIS_STRINGS_MAX] = {"X Axis", "Y Axis", "Z Axis"}; + static void rebuild_axis_button_selections(HWND hdlg) { int id = IDC_CONFIG_BASE + 2; diff --git a/src/WIN/win_keyboard.c b/src/WIN/win_keyboard.c new file mode 100644 index 000000000..e7b847f7d --- /dev/null +++ b/src/WIN/win_keyboard.c @@ -0,0 +1,211 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows raw keyboard input handler. + * + * Version: @(#)win_d3d.cc 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + +#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..6279e2da6 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -1,6 +1,20 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows localization core. + * + * Version: @(#)win_language.c 1.0.0 2017/05/30 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -13,16 +27,14 @@ #include "../ibm.h" #include "../device.h" #include "../ide.h" -#include "resource.h" #include "win.h" #include "win_language.h" + 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_language.h b/src/WIN/win_language.h index 5c4237249..bb7af81b7 100644 --- a/src/WIN/win_language.h +++ b/src/WIN/win_language.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows localization core. + * + * Version: @(#)win_language.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #ifdef __cplusplus extern "C" { #endif diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c index 5ce523a0a..3850201bf 100644 --- a/src/WIN/win_midi.c +++ b/src/WIN/win_midi.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * MIDI interface to host device. + * + * Version: @(#)win_midi.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include "../ibm.h" @@ -49,8 +64,8 @@ void midi_init() { MMRESULT hr = MMSYSERR_NOERROR; - memset(midi_rt_buf, 0, 1024); - memset(midi_cmd_buf, 0, 1024); + memset(midi_rt_buf, 0, sizeof(midi_rt_buf)); + memset(midi_cmd_buf, 0, sizeof(midi_cmd_buf)); midi_cmd_pos = midi_cmd_len = 0; midi_status = 0; @@ -81,7 +96,7 @@ void midi_close() { midiOutReset(midi_out_device); midiOutClose(midi_out_device); - midi_out_device = NULL; + /* midi_out_device = NULL; */ CloseHandle(m_event); } } diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc index f64b714a0..105575557 100644 --- a/src/WIN/win_mouse.cc +++ b/src/WIN/win_mouse.cc @@ -1,8 +1,24 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mouse interface to host device. + * + * Version: @(#)win_mouse.cc 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define DIRECTINPUT_VERSION 0x0800 #include +#include #include "plat_mouse.h" #include "win.h" diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c index cfe8f0b43..1db962177 100644 --- a/src/WIN/win_serial.c +++ b/src/WIN/win_serial.c @@ -12,7 +12,7 @@ * Windows and UNIX systems, with support for FTDI and Prolific * USB ports. Support for these has been removed. * - * Version: @(#)win_serial.c 1.0.2 2017/05/17 + * Version: @(#)win_serial.c 1.0.3 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -21,6 +21,7 @@ #include #include #include +#include "plat_thread.h" #define BHTTY_C #include "plat_serial.h" @@ -28,6 +29,60 @@ extern void pclog(char *__fmt, ...); +/* Handle the receiving of data from the host port. */ +static void +bhtty_reader(void *arg) +{ + BHTTY *pp = (BHTTY *)arg; + unsigned char b; + DWORD n; + + pclog("%s: thread started\n", pp->name); + + /* As long as the channel is open.. */ + while (pp->tid != NULL) { + /* Post a READ on the device. */ + n = 0; + if (ReadFile(pp->handle, &b, (DWORD)1, &n, &pp->rov) == FALSE) { + n = GetLastError(); + if (n != ERROR_IO_PENDING) { + /* Not good, we got an error. */ + pclog("%s: I/O error %d in read!\n", pp->name, n); + break; + } + + /* The read is pending, wait for it.. */ + if (GetOverlappedResult(pp->handle, &pp->rov, &n, TRUE) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in read!\n", pp->name, n); + break; + } + } + +pclog("%s: got %d bytes of data\n", pp->name, n); + if (n == 1) { + /* We got data, update stuff. */ + if (pp->icnt < sizeof(pp->buff)) { +pclog("%s: queued byte %02x (%d)\n", pp->name, b, pp->icnt+1); + pp->buff[pp->ihead++] = b; + pp->ihead &= (sizeof(pp->buff)-1); + pp->icnt++; + + /* Do a callback to let them know. */ + if (pp->rd_done != NULL) + pp->rd_done(pp->rd_arg, n); + } else { + pclog("%s: RX buffer overrun!\n", pp->name); + } + } + } + + /* Error or done, clean up. */ + pp->tid = NULL; + pclog("%s: thread stopped.\n", pp->name); +} + + /* Set the state of a port. */ int bhtty_sstate(BHTTY *pp, void *arg) @@ -35,8 +90,8 @@ bhtty_sstate(BHTTY *pp, void *arg) int i = 0; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid argument\n"); + if (arg == NULL) { + pclog("%s: invalid argument\n", pp->name); return(-1); } @@ -57,8 +112,8 @@ bhtty_gstate(BHTTY *pp, void *arg) int i = 0; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("BHTTY: invalid argument\n"); + if (arg == NULL) { + pclog("%s: invalid argument\n", pp->name); return(-1); } @@ -76,12 +131,6 @@ bhtty_gstate(BHTTY *pp, void *arg) int bhtty_crtscts(BHTTY *pp, char yesno) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -124,12 +173,6 @@ bhtty_crtscts(BHTTY *pp, char yesno) int bhtty_params(BHTTY *pp, char dbit, char par, char sbit) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -220,8 +263,8 @@ bhtty_raw(BHTTY *pp, void *arg) DCB *dcb = (DCB *)arg; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid parameter\n"); + if (arg == NULL) { + pclog("%s: invalid parameter\n", pp->name); return; } @@ -263,12 +306,6 @@ bhtty_speed(BHTTY *pp, long speed) { int i; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode and speed. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -296,12 +333,6 @@ bhtty_flush(BHTTY *pp) COMSTAT cs; int i = 0; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* First, clear any errors. */ (void)ClearCommError(pp->handle, &dwErrs, &cs); @@ -327,13 +358,18 @@ bhtty_flush(BHTTY *pp) void bhtty_close(BHTTY *pp) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("BHTTY: invalid handle\n"); - return; - } + /* If the polling thread is running, stop it. */ + (void)bhtty_active(pp, 0); + + /* Close the event handles. */ + if (pp->rov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(pp->rov.hEvent); + if (pp->wov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(pp->wov.hEvent); if (pp->handle != INVALID_HANDLE_VALUE) { + pclog("%s: closing host port\n", pp->name); + /* Restore the previous port state, if any. */ (void)bhtty_sstate(pp, &pp->odcb); @@ -351,20 +387,11 @@ bhtty_close(BHTTY *pp) BHTTY * bhtty_open(char *port, int tmo) { - char buff[64]; + char temp[64]; COMMTIMEOUTS to; -#if 0 COMMCONFIG conf; - DWORD d; -#endif BHTTY *pp; - int i = 0; - - /* Make sure we can do this. */ - if (port == NULL) { - pclog("invalid argument!\n"); - return(NULL); - } + DWORD d; /* First things first... create a control block. */ if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) { @@ -375,45 +402,53 @@ bhtty_open(char *port, int tmo) strncpy(pp->name, port, sizeof(pp->name)-1); /* Try a regular Win32 serial port. */ - sprintf(buff, "\\\\.\\%s", pp->name); - pp->handle = CreateFile(buff, - (GENERIC_READ|GENERIC_WRITE), - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0); - if (pp->handle == INVALID_HANDLE_VALUE) { + sprintf(temp, "\\\\.\\%s", pp->name); + if ((pp->handle = CreateFile(temp, + (GENERIC_READ|GENERIC_WRITE), + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0)) == INVALID_HANDLE_VALUE) { pclog("%s: open port: %d\n", pp->name, GetLastError()); free(pp); return(NULL); } -#if 0 + /* Create event handles. */ + pp->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + pp->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + /* Set up buffer size of the port. */ if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { /* This fails on FTDI-based devices. */ pclog("%s: set buffers: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); +#if 0 + CloseHandle(pp->handle); + free(pp); + return(NULL); +#endif } /* Grab default config for the driver and set it. */ d = sizeof(COMMCONFIG); memset(&conf, 0x00, d); conf.dwSize = d; - if (GetDefaultCommConfig(pp->name, &conf, &d) == TRUE) { + if (GetDefaultCommConfig(temp, &conf, &d) == TRUE) { /* Change config here... */ /* Set new configuration. */ if (SetCommConfig(pp->handle, &conf, d) == FALSE) { /* This fails on FTDI-based devices. */ pclog("%s: set configuration: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); +#if 0 + CloseHandle(pp->handle); + free(pp); + return(NULL); +#endif } } -#endif + pclog("%s: host port '%s' open\n", pp->name, temp); /* * We now have an open port. To allow for clean exit @@ -460,8 +495,7 @@ bhtty_open(char *port, int tmo) to.ReadTotalTimeoutConstant = tmo; } if (SetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while setting TO\n", - pp->name, GetLastError()); + pclog("%s: error %d while setting TO\n", pp->name, GetLastError()); (void)bhtty_close(pp); return(NULL); } @@ -476,25 +510,22 @@ bhtty_open(char *port, int tmo) } -/* A pending WRITE has finished, handle it. */ -static VOID CALLBACK -bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) +/* Activate the I/O for this port. */ +int +bhtty_active(BHTTY *pp, int flg) { - BHTTY *pp = (BHTTY *)priv->hEvent; + if (flg) { + pclog("%s: starting thread..\n", pp->name); + pp->tid = thread_create(bhtty_reader, pp); + } else { + if (pp->tid != NULL) { + pclog("%s: stopping thread..\n", pp->name); + thread_kill(pp->tid); + pp->tid = NULL; + } + } -//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); -#if 0 - if ( - if (GetOverlappedResult(p->handle, - &p->rov, &mst, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - sprintf(serial_errmsg, - "%s: I/O read error!", p->name); - return(-1); - } -#endif + return(0); } @@ -502,56 +533,26 @@ bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) int bhtty_write(BHTTY *pp, unsigned char val) { - DWORD n; + DWORD n = 0; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } -//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); - - /* Save the control pointer for later use. */ - pp->wov.hEvent = (HANDLE)pp; - - if (WriteFileEx(pp->handle, - &val, 1, - &pp->wov, - bhtty_write_comp) == FALSE) { +pclog("%s: writing byte %02x\n", pp->name, val); + if (WriteFile(pp->handle, &val, 1, &n, &pp->wov) == FALSE) { n = GetLastError(); - pclog("%s: I/O error %d in write!\n", pp->name, n); - return(-1); + if (n != ERROR_IO_PENDING) { + /* Not good, we got an error. */ + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } + + /* The write is pending, wait for it.. */ + if (GetOverlappedResult(pp->handle, &pp->wov, &n, TRUE) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } } - /* Its pending, so handled in the completion routine. */ - SleepEx(1, TRUE); - - return(0); -} - - -/* - * A pending READ has finished, handle it. - */ -static VOID CALLBACK -bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - DWORD r; -//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); - - if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - pclog("%s: I/O read error!", pp->name); - return; - } -//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); - - /* Do a callback to let them know. */ - if (pp->rd_done != NULL) - pp->rd_done(pp->rd_arg, num); + return((int)n); } @@ -561,46 +562,18 @@ bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) * For now, we will use one byte per call. Eventually, * we should go back to loading a buffer full of data, * just to speed things up a bit. --FvK - * - * Also, not that we do not wait here. We just POST a - * read operation, and the completion routine will do - * the clean-up and notify the caller. */ int bhtty_read(BHTTY *pp, unsigned char *bufp, int max) { - DWORD r; + if (pp->icnt == 0) return(0); - /* Just one byte. */ - max = 1; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); + while (max-- > 0) { + *bufp++ = pp->buff[pp->itail++]; +pclog("%s: dequeued byte %02x (%d)\n", pp->name, *(bufp-1), pp->icnt); + pp->itail &= (sizeof(pp->buff)-1); + if (--pp->icnt == 0) break; } - /* Save the control pointer for later use. */ - pp->rov.hEvent = (HANDLE)pp; -//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); - - /* Post a READ on the device. */ - if (ReadFileEx(pp->handle, - bufp, (DWORD)max, - &pp->rov, - bhtty_read_comp) == FALSE) { - r = GetLastError(); - if (r != ERROR_IO_PENDING) { - /* OK, we're being shut down. */ - if (r != ERROR_INVALID_HANDLE) - pclog("%s: I/O read error!\n", pp->name); - return(-1); - } - } - - /* Make ourself alertable. */ - SleepEx(1, TRUE); - - /* OK, it's pending, so we are good for now. */ - return(0); + return(max); } diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index db4f7da46..702b8b5d5 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1,6 +1,18 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows 86Box Settings dialog handler. + * + * Version: @(#)win_settings.c 1.0.2 2017/06/04 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #define UNICODE #define BITMAP WINDOWS_BITMAP #include @@ -13,8 +25,8 @@ #include "../mem.h" #include "../cpu/cpu.h" #include "../nvr.h" -#include "../model.h" #include "../device.h" +#include "../model.h" #include "../cdrom.h" #include "../disc.h" #include "../fdd.h" @@ -25,6 +37,7 @@ #include "../network.h" #include "../sound/sound.h" #include "../sound/snd_dbopl.h" +#include "../sound/snd_mpu401.h" #include "../video/video.h" #include "../video/vid_voodoo.h" #include "../gameport.h" @@ -32,10 +45,6 @@ #include "plat_midi.h" #include "win.h" #include "win_language.h" -#include "resource.h" - - -#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ /* Machine category */ @@ -48,7 +57,7 @@ static int temp_gfxcard, temp_video_speed, temp_voodoo; static int temp_mouse, temp_joystick; /* Sound category */ -static int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; +static int temp_sound_card, temp_midi_id, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; /* Network category */ static int temp_net_type, temp_net_card; @@ -62,10 +71,10 @@ 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]; +static int temp_fdd_turbo[FDD_NUM]; static cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; static HWND hwndParentDialog, hwndChildDialog; @@ -91,6 +100,7 @@ static void win_settings_init(void) /* Machine category */ temp_model = model; temp_cpu_m = cpu_manufacturer; + temp_wait_states = cpu_waitstates; temp_cpu = cpu; temp_mem_size = mem_size; temp_dynarec = cpu_use_dynarec; @@ -109,6 +119,7 @@ static void win_settings_init(void) /* Sound category */ temp_sound_card = sound_card_current; temp_midi_id = midi_id; + temp_mpu401 = mpu401_standalone_enable; temp_SSI2001 = SSI2001; temp_GAMEBLASTER = GAMEBLASTER; temp_GUS = GUS; @@ -134,15 +145,12 @@ 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++) { temp_fdd_types[i] = fdd_get_type(i); + temp_fdd_turbo[i] = fdd_get_turbo(i); } memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); } @@ -157,6 +165,7 @@ static int win_settings_changed(void) /* Machine category */ i = i || (model != temp_model); i = i || (cpu_manufacturer != temp_cpu_m); + i = i || (cpu_waitstates != temp_wait_states); i = i || (cpu != temp_cpu); i = i || (mem_size != temp_mem_size); i = i || (temp_dynarec != cpu_use_dynarec); @@ -175,6 +184,7 @@ static int win_settings_changed(void) /* Sound category */ i = i || (sound_card_current != temp_sound_card); i = i || (midi_id != temp_midi_id); + i = i || (mpu401_standalone_enable != temp_mpu401); i = i || (SSI2001 != temp_SSI2001); i = i || (GAMEBLASTER != temp_GAMEBLASTER); i = i || (GUS != temp_GUS); @@ -199,15 +209,12 @@ 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++) { i = i || (temp_fdd_types[j] != fdd_get_type(j)); + i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); } i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); @@ -255,6 +262,7 @@ static void win_settings_save(void) model = temp_model; romset = model_getromset(); cpu_manufacturer = temp_cpu_m; + cpu_waitstates = temp_wait_states; cpu = temp_cpu; mem_size = temp_mem_size; cpu_use_dynarec = temp_dynarec; @@ -273,6 +281,7 @@ static void win_settings_save(void) /* Sound category */ sound_card_current = temp_sound_card; midi_id = temp_midi_id; + mpu401_standalone_enable = temp_mpu401; SSI2001 = temp_SSI2001; GAMEBLASTER = temp_GAMEBLASTER; GUS = temp_GUS; @@ -298,21 +307,20 @@ 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++) { fdd_set_type(i, temp_fdd_types[i]); + fdd_set_turbo(i, temp_fdd_turbo[i]); } memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); mem_resize(); loadbios(); + update_status_bar_panes(hwndStatus); + resetpchard(); cpu_set(); @@ -324,8 +332,6 @@ static void win_settings_save(void) speedchanged(); if (joystick_type != 7) gameport_update_joystick_type(); - - update_status_bar_panes(hwndStatus); } @@ -415,6 +421,10 @@ static void win_settings_machine_recalc_cpu_m(HWND hdlg) c++; } EnableWindow(h, TRUE); + if (temp_cpu > c) + { + temp_cpu = c; + } SendMessage(h, CB_SETCURSEL, temp_cpu, 0); win_settings_machine_recalc_cpu(hdlg); @@ -456,6 +466,10 @@ static void win_settings_machine_recalc_model(HWND hdlg) c++; } EnableWindow(h, TRUE); + if (temp_cpu_m > c) + { + temp_cpu_m = c; + } SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); if (c == 1) { @@ -477,13 +491,13 @@ static void win_settings_machine_recalc_model(HWND hdlg) { SendMessage(h, UDM_SETPOS, 0, temp_mem_size); h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(IDS_2094)); } else { SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(IDS_2087)); } free(lptsTemp); @@ -527,7 +541,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); h = GetDlgItem(hdlg, IDC_COMBO_WS); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2131)); for (c = 0; c < 8; c++) { @@ -535,7 +549,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); + SendMessage(h, CB_SETCURSEL, temp_wait_states, 0); h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); SendMessage(h, BM_SETCHECK, temp_dynarec, 0); @@ -660,7 +674,7 @@ static void recalc_vid_list(HWND hdlg) { mbstowcs(szText, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == gfxcard) + if (video_new_to_old(c) == temp_gfxcard) { SendMessage(h, CB_SETCURSEL, d, 0); @@ -679,7 +693,7 @@ static void recalc_vid_list(HWND hdlg) h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); } @@ -687,11 +701,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) @@ -703,12 +714,12 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa recalc_vid_list(hdlg); h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2133)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2134)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2135)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2136)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2137)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2138)); SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); @@ -719,7 +730,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); gfx = video_card_getid(stransi); - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); if (video_card_has_config(gfx)) { EnableWindow(h, TRUE); @@ -747,7 +758,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa gfx = video_card_getid(stransi); temp_gfxcard = video_new_to_old(gfx); - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); if (video_card_has_config(gfx)) { EnableWindow(h, TRUE); @@ -765,15 +776,15 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); EnableWindow(h, temp_voodoo ? TRUE : FALSE); break; - case IDC_CONFIGURE_VOODOO: + case IDC_BUTTON_VOODOO: deviceconfig_open(hdlg, (void *)&voodoo_device); break; - case IDC_CONFIGUREVID: + case IDC_CONFIGURE_VID: lptsTemp = (LPTSTR) malloc(512); stransi = (char *) malloc(512); @@ -855,28 +866,28 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa { case 0: /* MS Serial */ default: - str_id = 2139; + str_id = IDS_2139; break; case 1: /* PS2 2b */ - str_id = 2141; + str_id = IDS_2141; break; case 2: /* PS2 intelli 3b */ - str_id = 2142; + str_id = IDS_2142; break; case 3: /* MS/logi bus 2b */ - str_id = 2143; + str_id = IDS_2143; break; case 4: /* Amstrad */ - str_id = 2162; + str_id = IDS_2162; break; case 5: /* Olivetti M24 */ - str_id = 2177; + str_id = IDS_2177; break; case 6: /* MouseSystems */ - str_id = 2140; + str_id = IDS_2140; break; case 7: /* Genius Bus */ - str_id = 2161; + str_id = IDS_2161; break; } @@ -931,25 +942,25 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa break; case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 0, temp_joystick); break; case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 1, temp_joystick); break; case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 2, temp_joystick); break; case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 3, temp_joystick); break; @@ -985,12 +996,12 @@ static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) h = GetDlgItem(hdlg, IDC_COMBO_HDC); - if (models[model].flags & MODEL_HAS_IDE) + if (models[temp_model].flags & MODEL_HAS_IDE) { hdc_ignore = 1; SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2154)); EnableWindow(h, FALSE); SendMessage(h, CB_SETCURSEL, 0, 0); } @@ -1099,6 +1110,38 @@ int find_irq_in_array(int irq, int def) static char midi_dev_name_buf[512]; +int mpu401_present(void) +{ + char *n; + + n = sound_card_get_internal_name(temp_sound_card); + if (n != NULL) + { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + { + return 1; + } + } + + return temp_mpu401 ? 1 : 0; +} + +int mpu401_standalone_allow(void) +{ + char *n; + + n = sound_card_get_internal_name(temp_sound_card); + if (n != NULL) + { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + { + return 0; + } + } + + return 1; +} + static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; @@ -1113,7 +1156,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa case WM_INITDIALOG: lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBOSND); + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); c = d = 0; while (1) { @@ -1134,7 +1177,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa { if (c == 0) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2152)); } else { @@ -1150,7 +1193,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa } SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); - h = GetDlgItem(hdlg, IDC_CONFIGURESND); + h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); if (sound_card_has_config(temp_sound_card)) { EnableWindow(h, TRUE); @@ -1171,17 +1214,25 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa if (c == temp_midi_id) SendMessage(h, CB_SETCURSEL, c, 0); } + EnableWindow(h, mpu401_present() ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECKCMS); + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); + + h=GetDlgItem(hdlg, IDC_CHECK_CMS); SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); - h=GetDlgItem(hdlg, IDC_CHECKGUS); + h=GetDlgItem(hdlg, IDC_CHECK_GUS); SendMessage(h, BM_SETCHECK, temp_GUS, 0); - h=GetDlgItem(hdlg, IDC_CHECKSSI); + h=GetDlgItem(hdlg, IDC_CHECK_SSI); SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); - h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + h=GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); free(lptsTemp); @@ -1191,18 +1242,18 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa case WM_COMMAND: switch (LOWORD(wParam)) { - case IDC_CONFIGURESND: - h = GetDlgItem(hdlg, IDC_COMBOSND); + case IDC_CONFIGURE_SND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); break; - case IDC_COMBOSND: - h = GetDlgItem(hdlg, IDC_COMBOSND); + case IDC_COMBO_SOUND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - h = GetDlgItem(hdlg, IDC_CONFIGURESND); + h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); if (sound_card_has_config(temp_sound_card)) { EnableWindow(h, TRUE); @@ -1211,27 +1262,48 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa { EnableWindow(h, FALSE); } + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + break; + + case IDC_CHECK_MPU401: + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_MPU401: + deviceconfig_open(hdlg, (void *)&mpu401_device); break; } return FALSE; case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBOSND); + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; h = GetDlgItem(hdlg, IDC_COMBO_MIDI); temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKCMS); + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_CMS); temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKGUS); + h = GetDlgItem(hdlg, IDC_CHECK_GUS); temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKSSI); + h = GetDlgItem(hdlg, IDC_CHECK_SSI); temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + h = GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); default: @@ -1276,7 +1348,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR { if (c == 0) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2152)); } else { @@ -1309,7 +1381,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR for (c = 0; c < 11; c++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_2155), valid_ide_irqs[c]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } @@ -1323,11 +1395,11 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR } h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2151)); for (c = 0; c < 11; c++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_2155), valid_ide_irqs[c]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } @@ -1340,16 +1412,16 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR SendMessage(h, CB_SETCURSEL, 0, 0); } - h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); + h=GetDlgItem(hdlg, IDC_CHECK_SERIAL1); SendMessage(h, BM_SETCHECK, temp_serial[0], 0); - h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); + h=GetDlgItem(hdlg, IDC_CHECK_SERIAL2); SendMessage(h, BM_SETCHECK, temp_serial[1], 0); - h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); + h=GetDlgItem(hdlg, IDC_CHECK_PARALLEL); SendMessage(h, BM_SETCHECK, temp_lpt, 0); - h=GetDlgItem(hdlg, IDC_CHECKBUGGER); + h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); SendMessage(h, BM_SETCHECK, temp_bugger, 0); free(lptsTemp); @@ -1421,16 +1493,16 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR temp_ide_qua = 1; } - h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); + h = GetDlgItem(hdlg, IDC_CHECK_SERIAL1); temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); + h = GetDlgItem(hdlg, IDC_CHECK_SERIAL2); temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); + h = GetDlgItem(hdlg, IDC_CHECK_PARALLEL); temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKBUGGER); + h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); default: @@ -1448,7 +1520,7 @@ static void network_recalc_combos(HWND hdlg) net_ignore_message = 1; - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); if (temp_net_type == NET_TYPE_PCAP) { EnableWindow(h, TRUE); @@ -1458,7 +1530,7 @@ static void network_recalc_combos(HWND hdlg) EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); if (temp_net_type == NET_TYPE_SLIRP) { EnableWindow(h, TRUE); @@ -1473,7 +1545,7 @@ static void network_recalc_combos(HWND hdlg) EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_CONFIGURENET); + h = GetDlgItem(hdlg, IDC_CONFIGURE_NET); if (network_card_has_config(temp_net_card) && (temp_net_type == NET_TYPE_SLIRP)) { @@ -1499,20 +1571,19 @@ 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) { case WM_INITDIALOG: lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); SendMessage(h, CB_SETCURSEL, temp_net_type, 0); - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); if (temp_net_type == NET_TYPE_PCAP) { EnableWindow(h, TRUE); @@ -1522,7 +1593,7 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); for (c = 0; c < network_ndev; c++) { mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); @@ -1531,7 +1602,7 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); c = d = 0; while (1) { @@ -1572,50 +1643,50 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w case WM_COMMAND: switch (LOWORD(wParam)) { - case IDC_COMBONETTYPE: + case IDC_COMBO_NET_TYPE: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); network_recalc_combos(hdlg); break; - case IDC_COMBOPCAP: + case IDC_COMBO_PCAP: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); network_recalc_combos(hdlg); break; - case IDC_COMBONET: + case IDC_COMBO_NET: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; network_recalc_combos(hdlg); break; - case IDC_CONFIGURENET: + case IDC_CONFIGURE_NET: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); @@ -1624,14 +1695,14 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w return FALSE; case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; default: @@ -1652,13 +1723,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 +1741,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 +1748,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]; @@ -1708,7 +1773,12 @@ static int get_selected_hard_disk(HWND hdlg) int i, j = 0; HWND h; - for (i = 0; i < 6; i++) + if (hd_listview_items == 0) + { + return 0; + } + + for (i = 0; i < hd_listview_items; i++) { h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); j = ListView_GetItemState(h, i, LVIS_SELECTED); @@ -1734,6 +1804,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 +1875,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 +1889,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 +1920,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 +1969,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 +1980,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 +2012,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 +2023,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 +2075,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 +2159,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 +2191,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 +2339,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,30 +2401,36 @@ 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; uint32_t base = 0x1000; uint64_t signature = 0xD778A82044445459ll; char buf[512]; + char *big_buf; + int b = 0; + uint64_t r = 0; 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 +2457,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 +2524,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)) { - msgbox_error(hwndParentDialog, 2056); - return TRUE; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + hdc_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; } - 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); + /* 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, IDS_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; + 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)) @@ -2394,7 +2606,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (size >= 0x100000000ll) { fclose(f); - msgbox_error(hwndParentDialog, 2058); + msgbox_error(hwndParentDialog, IDS_2058); return TRUE; } @@ -2417,7 +2629,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (size > 0xffffffffffffffffll) { fclose(f); - msgbox_error(hwndParentDialog, 2163); + msgbox_error(hwndParentDialog, IDS_2163); return TRUE; } @@ -2433,42 +2645,57 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W memset(buf, 0, 512); size >>= 9; - for (i = 0; i < size; i++) + r = (size >> 11) << 11; + size -= r; + r >>= 11; + + if (size) { - fwrite(buf, 512, 1, f); + for (i = 0; i < size; i++) + { + fwrite(buf, 1, 512, f); + } + } + + if (r) + { + big_buf = (char *) malloc(1048576); + memset(big_buf, 0, 1048576); + for (i = 0; i < r; i++) + { + fwrite(big_buf, 1, 1048576, f); + } + free(big_buf); } fclose(f); - msgbox_info(hwndParentDialog, 2059); + msgbox_info(hwndParentDialog, IDS_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) { fclose(f); - if (msgbox_question(ghwnd, 2178) != IDYES) + if (msgbox_question(ghwnd, IDS_2178) != IDYES) { return FALSE; } @@ -2478,6 +2705,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; } @@ -2489,7 +2717,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W fread(§or_size, 1, 4, f); if (sector_size != 512) { - msgbox_error(hwndParentDialog, 2061); + msgbox_error(hwndParentDialog, IDS_2061); fclose(f); return TRUE; } @@ -2532,6 +2760,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 +2783,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 +2795,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 +2815,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 +2843,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 +2871,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 +2899,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 +2946,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 +2986,121 @@ 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; + b = SendMessage(h,CB_GETCURSEL,0,0) + 1; + if (b == hdc_ptr->bus) + { + goto hd_add_bus_skip; + } + + hdc_ptr->bus = b; + + 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); + } + +hd_add_bus_skip: no_update = 0; break; } @@ -2704,13 +3111,19 @@ 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; existing = is_existing; hard_disk_added = 0; - ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); + ret = DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, + hwnd, win_settings_hard_disks_add_proc); } int ignore_change = 0; @@ -2719,6 +3132,7 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA { HWND h; int old_sel = 0; + int b = 0; switch (message) { @@ -2790,11 +3204,17 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA } ignore_change = 1; - recalc_location_controls(hdlg, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + b = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + if (b == temp_hdc[hdlv_current_sel].bus) + { + goto hd_bus_skip; + } + temp_hdc[hdlv_current_sel].bus = b; + recalc_location_controls(hdlg, 0); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); +hd_bus_skip: ignore_change = 0; return FALSE; @@ -2806,7 +3226,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 +3310,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,18 +3347,18 @@ 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 */ - return 2168; + case CDROM_BUS_SCSI: /* SCSI */ + return 2210; break; } } @@ -2936,17 +3367,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 +3411,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); @@ -3016,10 +3444,11 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) WCHAR szText[256]; lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; + lvI.stateMask = lvI.state = 0; for (i = 0; i < 4; i++) { + lvI.iSubItem = 0; if (temp_fdd_types[i] > 0) { strcpy(s, fdd_getname(temp_fdd_types[i])); @@ -3035,6 +3464,16 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; + + lvI.iSubItem = 1; + lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } } return TRUE; @@ -3044,9 +3483,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 +3495,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; } @@ -3100,7 +3535,7 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) lvc.iSubItem = 0; lvc.pszText = win_language_get_string_from_id(2188); - lvc.cx = 392; + lvc.cx = 292; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) @@ -3108,6 +3543,17 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) return FALSE; } + lvc.iSubItem = 1; + lvc.pszText = win_language_get_string_from_id(2221); + + lvc.cx = 100; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) + { + return FALSE; + } + return TRUE; } @@ -3197,14 +3643,22 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) { return; } + + lvI.iSubItem = 1; + lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } } 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 +3671,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 +3708,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 +3767,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 +3778,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 +3807,8 @@ 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; + int b2 = 0; WCHAR szText[256]; switch (message) @@ -3381,6 +3837,9 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message } SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); + cdlv_current_sel = 0; h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_init_columns(h); @@ -3388,15 +3847,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; @@ -3427,6 +3899,8 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); rd_ignore_change = 0; } else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) @@ -3446,15 +3920,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; } @@ -3477,6 +3964,20 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 0; return FALSE; + case IDC_CHECKTURBO: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + temp_fdd_turbo[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, fdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + case IDC_COMBO_CD_BUS: if (rd_ignore_change) { @@ -3485,14 +3986,31 @@ 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: + b2 = CDROM_BUS_DISABLED; + break; + case 1: + b2 = CDROM_BUS_ATAPI_PIO_ONLY; + break; + case 2: + b2 = CDROM_BUS_ATAPI_PIO_AND_DMA; + break; + case 3: + b2 = CDROM_BUS_SCSI; + break; } + if (b2 == temp_cdrom_drives[cdlv_current_sel].bus_type) + { + goto cdrom_bus_skip; + } + temp_cdrom_drives[cdlv_current_sel].bus_type = b2; cdrom_recalc_location_controls(hdlg); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); +cdrom_bus_skip: rd_ignore_change = 0; return FALSE; @@ -3564,28 +4082,28 @@ void win_settings_show_child(HWND hwndParent, DWORD child_id) switch(child_id) { case 0: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); break; case 1: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); break; case 2: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_INPUT, hwndParent, win_settings_input_proc); break; case 3: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); break; case 4: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); break; case 5: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); break; case 6: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); break; case 7: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); break; default: fatal("Invalid child dialog ID\n"); @@ -3661,7 +4179,7 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, 2047); + h = GetDlgItem(hdlg, IDS_LANG_ENUS); /*was:2047 !*/ EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); return TRUE; @@ -3726,5 +4244,5 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar void win_settings_open(HWND hwnd) { - DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); + DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); } diff --git a/src/WIN/win_status.c b/src/WIN/win_status.c index 59a7a5947..0a0fc659c 100644 --- a/src/WIN/win_status.c +++ b/src/WIN/win_status.c @@ -11,7 +11,6 @@ #include "../cpu/x86_ops.h" #include "../cpu/codegen.h" #include "../device.h" -#include "resource.h" #include "win.h" @@ -65,11 +64,11 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq) ); main_time = 0; - SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + SendDlgItemMessage(hdlg, IDT_SDEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); device_s[0] = 0; device_add_status_info(device_s, 4096); - SendDlgItemMessage(hdlg, IDC_STEXT1, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + SendDlgItemMessage(hdlg, IDT_STEXT, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); } return TRUE; @@ -90,6 +89,6 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR void status_open(HWND hwnd) { - status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); + status_hwnd = CreateDialog(hinstance, (LPCSTR)DLG_STATUS, hwnd, status_dlgproc); ShowWindow(status_hwnd, SW_SHOW); } diff --git a/src/cdrom.c b/src/cdrom.c index 6540846ba..2bcfc20cc 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1,5 +1,19 @@ -/* CD-ROM emulation, used by both ATAPI and SCSI */ - +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. + * + * Version: @(#)cdrom.c 1.0.1 2017/06/03 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include #include #include @@ -13,6 +27,7 @@ #include "piix.h" #include "scsi.h" #include "timer.h" +#include "win/plat_iodev.h" /* Bits of 'status' */ #define ERR_STAT 0x01 @@ -732,7 +747,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 +779,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 +848,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 +1091,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 +1099,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 +1485,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 +1505,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 +1521,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 +2078,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,26 +2090,32 @@ 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); return 0; } + if ((cdrom_drives[id].handler->status(id) == CD_STATUS_PLAYING) || (cdrom_drives[id].handler->status(id) == CD_STATUS_PAUSED)) + { + ready = 1; + goto skip_ready_check; + } + if (cdrom_drives[id].handler->medium_changed(id)) { /* cdrom_log("CD-ROM %i: Medium has changed...\n", id); */ @@ -2103,6 +2124,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) ready = cdrom_drives[id].handler->ready(id); +skip_ready_check: if (!ready && cdrom[id].unit_attention) { /* If the drive is not ready, there is no reason to keep the @@ -2297,13 +2319,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 +2337,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] = EMU_VERSION[0]; + device_identify_ex[12] = EMU_VERSION[2]; + device_identify_ex[13] = EMU_VERSION[3]; cdrom[id].data_pos = 0; @@ -2398,7 +2420,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { - return; + /* return; */ + cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; + goto cdrom_readtoc_fallback; } alloc_length = cdbufferb[0]; alloc_length <<= 8; @@ -2411,6 +2435,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } else { +cdrom_readtoc_fallback: toc_format = cdb[2] & 0xf; if (toc_format == 0) @@ -2428,7 +2453,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[0] = 0; cdbufferb[1] = 0xA; break; case 2: /*Raw*/ - len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, max_len); + len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, max_len); break; default: cdrom_invalid_field(id); @@ -2501,7 +2526,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 +2554,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 +2598,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 +3141,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; } @@ -3176,7 +3195,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[idx++] = 0x01; cdbufferb[idx++] = 0x00; cdbufferb[idx++] = 68; - ide_padstr8(cdbufferb + idx, 8, "86Box"); /* Vendor */ + ide_padstr8(cdbufferb + idx, 8, EMU_NAME); /* Vendor */ idx += 8; ide_padstr8(cdbufferb + idx, 40, device_identify_ex); /* Product */ idx += 40; @@ -3197,13 +3216,13 @@ 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 */ + ide_padstr8(cdbufferb + 8, 8, EMU_NAME); /* Vendor */ ide_padstr8(cdbufferb + 16, 16, device_identify); /* Product */ - ide_padstr8(cdbufferb + 32, 4, emulator_version); /* Revision */ + ide_padstr8(cdbufferb + 32, 4, EMU_VERSION); /* Revision */ idx = 36; } @@ -3352,7 +3371,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 +3497,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 +3511,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 +3617,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 +3636,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 +3664,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 +3679,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 +3694,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..5b7cb1f8b 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -1,8 +1,24 @@ -#ifndef __CDROM_H__ -#define __CDROM_H__ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. + * + * Version: @(#)cdrom.h 1.0.1 2017/06/03 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_CDROM_H +#define EMU_CDROM_H -/*CD-ROM stuff*/ -#define CDROM_NUM 4 + +#define CDROM_NUM 4 #define CDROM_PHASE_IDLE 0 #define CDROM_PHASE_COMMAND 1 @@ -20,8 +36,8 @@ #define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) #define CDROM_TIME (5 * 100 * (1 << TIMER_SHIFT)) -typedef struct CDROM -{ + +typedef struct { int (*ready)(uint8_t id); int (*medium_changed)(uint8_t id); int (*media_type_id)(uint8_t id); @@ -29,7 +45,7 @@ typedef struct CDROM void (*audio_stop)(uint8_t id); int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); int (*readtoc_session)(uint8_t id, uint8_t *b, int msf, int maxlen); - int (*readtoc_raw)(uint8_t id, uint8_t *b, int msf, int maxlen); + int (*readtoc_raw)(uint8_t id, uint8_t *b, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len); int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); @@ -45,13 +61,8 @@ typedef struct CDROM void (*exit)(uint8_t id); } CDROM; -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute__((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { uint8_t previous_command; int toctimes; @@ -119,19 +130,10 @@ typedef struct __attribute__((__packed__)) int init_length; } cdrom_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -extern cdrom_t cdrom[CDROM_NUM]; - -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute__((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { int max_blocks_at_once; CDROM *handler; @@ -151,22 +153,9 @@ typedef struct __attribute__((__packed__)) unsigned int sound_on; unsigned int atapi_dma; } cdrom_drive_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -extern cdrom_drive_t cdrom_drives[CDROM_NUM]; - -extern uint8_t atapi_cdrom_drives[8]; - -extern uint8_t scsi_cdrom_drives[16][8]; - -extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); -extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); -extern void (*ide_bus_master_set_irq)(int channel); - -typedef struct -{ +typedef struct { int image_is_iso; uint32_t last_block; @@ -183,10 +172,7 @@ typedef struct int cd_buflen; } cdrom_image_t; -cdrom_image_t cdrom_image[CDROM_NUM]; - -typedef struct -{ +typedef struct { uint32_t last_block; uint32_t cdrom_capacity; int ioctl_inited; @@ -206,20 +192,29 @@ typedef struct int last_subchannel_pos; } cdrom_ioctl_t; -void ioctl_close(uint8_t id); -cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; +extern cdrom_t cdrom[CDROM_NUM]; +extern cdrom_drive_t cdrom_drives[CDROM_NUM]; +extern uint8_t atapi_cdrom_drives[8]; +extern uint8_t scsi_cdrom_drives[16][8]; + cdrom_image_t cdrom_image[CDROM_NUM]; + cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; -uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel); -uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel); -void build_atapi_cdrom_map(); -void build_scsi_cdrom_map(); -int cdrom_CDROM_PHASE_to_scsi(uint8_t id); -int cdrom_atapi_phase_to_scsi(uint8_t id); -void cdrom_command(uint8_t id, uint8_t *cdb); -void cdrom_phase_callback(uint8_t id); -uint32_t cdrom_read(uint8_t channel, int length); -void cdrom_write(uint8_t channel, uint32_t val, int length); +extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); +extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); +extern void (*ide_bus_master_set_irq)(int channel); +extern void ioctl_close(uint8_t id); + +extern uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel); +extern uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel); +extern void build_atapi_cdrom_map(void); +extern void build_scsi_cdrom_map(void); +extern int cdrom_CDROM_PHASE_to_scsi(uint8_t id); +extern int cdrom_atapi_phase_to_scsi(uint8_t id); +extern void cdrom_command(uint8_t id, uint8_t *cdb); +extern void cdrom_phase_callback(uint8_t id); +extern uint32_t cdrom_read(uint8_t channel, int length); +extern void cdrom_write(uint8_t channel, uint32_t val, int length); #ifdef __cplusplus extern "C" { @@ -237,10 +232,13 @@ 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] #define cdrom_ascq cdrom[id].sense[13] #define cdrom_drive cdrom_drives[id].host_drive -#endif \ No newline at end of file + +#endif /*EMU_CDROM_H*/ diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index 53223a775..be632fd38 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,28 +51,38 @@ 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); + memset(fn, 0, sizeof(fn)); + strcpy(fn, filename); + error = false; } CDROM_Interface_Image::BinaryFile::~BinaryFile() { - delete file; + // delete file; + memset(fn, 0, sizeof(fn)); } -bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) { - file->seekg(seek, ios::beg); - file->read((char*)buffer, count); - return !(file->fail()); + uint64_t offs = 0; + file = fopen64(fn, "rb"); + fseeko64(file, seek, SEEK_SET); + offs = fread(buffer, 1, count, file); + fclose(file); + // return (offs == count); + return 1; } -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; + uint64_t ret = 0; + file = fopen64(fn, "rb"); + fseeko64(file, 0, SEEK_END); + ret = ftello64(file); + fclose(file); + return ret; } CDROM_Interface_Image::CDROM_Interface_Image() @@ -180,9 +195,10 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se { int track = GetTrack(sector) - 1; if (track < 0) return false; - - int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; - int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + + uint64_t s = (uint64_t) sector; + uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize); + uint64_t length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; if (tracks[track].mode2 && !raw) seek += 24; @@ -254,10 +270,10 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) return true; } -bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2) { Bit8u pvd[COOKED_SECTOR_SIZE]; - int seek = 16 * sectorSize; // first vd is located at sector 16 + uint64_t seek = 16 * sectorSize; // first vd is located at sector 16 if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; if (mode2) seek += 24; file->read(pvd, seek, COOKED_SECTOR_SIZE); @@ -286,10 +302,10 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) { Track track = {0, 0, 0, 0, 0, 0, false, NULL}; tracks.clear(); - int shift = 0; - int currPregap = 0; - int totalPregap = 0; - int prestart = 0; + uint64_t shift = 0; + uint64_t currPregap = 0; + uint64_t totalPregap = 0; + uint64_t prestart = 0; bool success; bool canAddTrack = false; char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument @@ -348,9 +364,9 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) canAddTrack = true; } else if (command == "INDEX") { - int index; + uint64_t index; line >> index; - int frame; + uint64_t frame; success = GetCueFrame(frame, line); if (index == 1) track.start = frame; @@ -405,10 +421,10 @@ 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, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap) { // frames between index 0(prestart) and 1(curr.start) must be skipped - int skip; + uint64_t skip; if (prestart > 0) { if (prestart > curr.start) return false; skip = curr.start - prestart; @@ -430,13 +446,13 @@ bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int if (prev.file == curr.file) { curr.start += shift; prev.length = curr.start + totalPregap - prev.start - skip; - curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + 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; @@ -520,7 +536,7 @@ bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) return true; } -bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +bool CDROM_Interface_Image::GetCueFrame(uint64_t &frames, istream &in) { string msf; in >> msf; diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index 39ed79bed..243723fe4 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -103,8 +103,8 @@ class CDROM_Interface_Image : public CDROM_Interface private: class TrackFile { public: - virtual bool read(Bit8u *buffer, int seek, int count) = 0; - virtual int getLength() = 0; + virtual bool read(Bit8u *buffer, uint64_t seek, uint64_t count) = 0; + virtual uint64_t getLength() = 0; virtual ~TrackFile() { }; }; @@ -112,21 +112,22 @@ private: public: BinaryFile(const char *filename, bool &error); ~BinaryFile(); - bool read(Bit8u *buffer, int seek, int count); - int getLength(); + bool read(Bit8u *buffer, uint64_t seek, uint64_t count); + uint64_t getLength(); private: BinaryFile(); - std::ifstream *file; + char fn[260]; + FILE *file; }; struct Track { int number; int track_number; int attr; - int start; - int length; - int skip; - int sectorSize; + uint64_t start; + uint64_t length; + uint64_t skip; + uint64_t sectorSize; bool mode2; TrackFile *file; }; @@ -156,14 +157,14 @@ static void CDAudioCallBack(Bitu len); void ClearTracks(); bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2); // cue sheet processing bool LoadCueSheet(char *cuefile); bool GetRealFileName(std::string& filename, std::string& pathname); bool GetCueKeyword(std::string &keyword, std::istream &in); - bool GetCueFrame(int &frames, std::istream &in); + bool GetCueFrame(uint64_t &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, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap); std::vector tracks; typedef std::vector::iterator track_it; diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 6c14bf2c2..07380e79a 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -779,7 +779,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, break; cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); b[len++] = 0; /* reserved */ b[len++] = attr; b[len++] = number; /* track number */ @@ -805,20 +804,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, } b[0] = (uint8_t)(((len-2) >> 8) & 0xff); b[1] = (uint8_t)((len-2) & 0xff); - /* - pclog("Table of Contents:\n"); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); - } - for (c = 0;c <= last_track; c++) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); - } - */ return len; } @@ -869,7 +854,7 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl return len; } -static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) { int track; int len = 4; @@ -935,6 +920,7 @@ static int image_status(uint8_t id) void image_reset(uint8_t id) { + return; } void image_close(uint8_t id) @@ -994,7 +980,6 @@ int image_open(uint8_t id, wchar_t *fn) cdrom_image[id].image_inited = 1; } - update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index 5da98bda6..201753e47 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -1,8 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Win32 CD-ROM support via IOCTL*/ - +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM host drive IOCTL interface for + * Windows using SCSI Passthrough Direct. + * + * Version: @(#)cdrom_ioctl.c 1.0.2 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #define WINVER 0x0600 #include #include @@ -21,6 +34,7 @@ typedef struct { HANDLE hIOCTL; CDROM_TOC toc; + int is_playing; } cdrom_ioctl_windows_t; cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; @@ -48,6 +62,8 @@ void cdrom_ioctl_log(const char *format, ...) #endif } +static int ioctl_hopen(uint8_t id); + void ioctl_audio_callback(uint8_t id, int16_t *output, int len) { RAW_READ_INFO in; @@ -70,10 +86,11 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; - ioctl_open(id, 0); if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) { memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_buflen = len; } @@ -82,11 +99,12 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) cdrom[id].seek_pos++; cdrom_ioctl[id].cd_buflen += (2352 / 2); } - ioctl_close(id); } else { memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_buflen = len; } @@ -98,6 +116,8 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) void ioctl_audio_stop(uint8_t id) { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; } @@ -218,6 +238,11 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ cdrom[id].seek_pos = 150; } + if (!cdrom_ioctl_windows[id].is_playing) + { + ioctl_hopen(id); + cdrom_ioctl_windows[id].is_playing = 1; + } cdrom_ioctl[id].cd_state = CD_PLAYING; } @@ -251,6 +276,11 @@ static void ioctl_stop(uint8_t id) { return; } + if (cdrom_ioctl_windows[id].is_playing) + { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); + } cdrom_ioctl[id].cd_state = CD_STOPPED; } @@ -263,9 +293,16 @@ static int ioctl_ready(uint8_t id) { return 0; } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); + if (cdrom_ioctl_windows[id].hIOCTL == NULL) + { + ioctl_hopen(id); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + } + else + { + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + } if (!temp) { return 0; @@ -296,7 +333,7 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i return 0; } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); ioctl_close(id); cdrom_ioctl[id].tocvalid=1; @@ -312,6 +349,8 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i return lb; } +static void ioctl_read_capacity(uint8_t id, uint8_t *b); + static int ioctl_medium_changed(uint8_t id) { unsigned long size; @@ -321,7 +360,7 @@ static int ioctl_medium_changed(uint8_t id) { return 0; /* This will be handled by the not ready handler instead. */ } - ioctl_open(id, 0); + ioctl_hopen(id); temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); ioctl_close(id); if (!temp) @@ -337,6 +376,10 @@ static int ioctl_medium_changed(uint8_t id) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; } + ioctl_hopen(id); + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + ioctl_close(id); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; } @@ -349,6 +392,10 @@ static int ioctl_medium_changed(uint8_t id) cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_windows[id].toc = ltoc; + ioctl_hopen(id); + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + ioctl_close(id); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; /* TOC mismatches. */ } @@ -376,7 +423,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) else { insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); ioctl_close(id); memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); @@ -471,8 +518,13 @@ static void ioctl_eject(uint8_t id) { return; } + if (cdrom_ioctl_windows[id].is_playing) + { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_stop(id); + } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); ioctl_close(id); } @@ -484,9 +536,16 @@ static void ioctl_load(uint8_t id) { return; } + if (cdrom_ioctl_windows[id].is_playing) + { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_stop(id); + } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); ioctl_close(id); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); } @@ -583,10 +642,10 @@ struct sptd_with_sense static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) { - int sector_type = 0; - int temp_len = 0; + int sector_type = 0; + int temp_len = 0; - if (no_length_check) + if (no_length_check) { switch (cdb[0]) { @@ -739,8 +798,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) if (!cdrom_ioctl[id].capacity_read) { - ioctl_open(id, 0); - SCSICommand(id, cdb, buf, &len, 1); memcpy(cdrom_ioctl[id].rcbuf, buf, len); @@ -750,8 +807,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) { memcpy(b, cdrom_ioctl[id].rcbuf, 16); } - - ioctl_close(id); } static int ioctl_media_type_id(uint8_t id) @@ -768,7 +823,7 @@ static int ioctl_media_type_id(uint8_t id) old_sense[1] = cdrom_asc; old_sense[2] = cdrom_asc; - ioctl_open(id, 0); + ioctl_hopen(id); SCSICommand(id, cdb, msbuf, &len, 1); @@ -832,7 +887,7 @@ static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); cdb_msf[5] = cdb_msf[8] = (sector & 0xff); - ioctl_open(id, 0); + ioctl_hopen(id); if (ioctl_is_track_audio(id, sector, ismsf)) { @@ -887,7 +942,7 @@ static void ioctl_validate_toc(uint8_t id) return; } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); cdrom_ioctl_log("Validating TOC...\n"); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); @@ -921,7 +976,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t ioctl_validate_toc(id); } - ioctl_open(id, 0); + ioctl_hopen(id); memcpy((void *) cdb, in_cdb, 12); @@ -980,7 +1035,7 @@ split_block_read_iterate: cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); } - cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); ioctl_close(id); @@ -989,6 +1044,160 @@ split_block_read_iterate: return ret; } +static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + int len=4; + long size; + int c,d; + uint32_t temp; + uint32_t last_block; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_hopen(id); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid = 1; + b[2]=cdrom_ioctl_windows[id].toc.FirstTrack; + b[3]=cdrom_ioctl_windows[id].toc.LastTrack; + d=0; + for (c=0;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++) + { + if (cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber>=starttrack) + { + d=c; + break; + } + } + b[2]=cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber; + last_block = 0; + for (c=d;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++) + { + uint32_t address; + if ((len+8)>maxlen) break; + b[len++]=0; /*Reserved*/ + b[len++]=(cdrom_ioctl_windows[id].toc.TrackData[c].Adr<<4)|cdrom_ioctl_windows[id].toc.TrackData[c].Control; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber; + b[len++]=0; /*Reserved*/ + address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + if (address > last_block) + last_block = address; + + if (msf) + { + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[0]; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[1]; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[2]; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]; + } + else + { + temp=MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]) - 150; + b[len++]=temp>>24; + b[len++]=temp>>16; + b[len++]=temp>>8; + b[len++]=temp; + } + if (single) break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; +} + +static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + int len=4; + int size; + uint32_t temp; + CDROM_READ_TOC_EX toc_ex; + CDROM_TOC_SESSION_DATA toc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + memset(&toc_ex,0,sizeof(toc_ex)); + memset(&toc,0,sizeof(toc)); + toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_SESSION; + toc_ex.Msf=msf; + toc_ex.SessionTrack=0; + ioctl_hopen(id); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); + ioctl_close(id); + b[2]=toc.FirstCompleteSession; + b[3]=toc.LastCompleteSession; + b[len++]=0; /*Reserved*/ + b[len++]=(toc.TrackData[0].Adr<<4)|toc.TrackData[0].Control; + b[len++]=toc.TrackData[0].TrackNumber; + b[len++]=0; /*Reserved*/ + if (msf) + { + b[len++]=toc.TrackData[0].Address[0]; + b[len++]=toc.TrackData[0].Address[1]; + b[len++]=toc.TrackData[0].Address[2]; + b[len++]=toc.TrackData[0].Address[3]; + } + else + { + temp=MSFtoLBA(toc.TrackData[0].Address[1],toc.TrackData[0].Address[2],toc.TrackData[0].Address[3]) - 150; + b[len++]=temp>>24; + b[len++]=temp>>16; + b[len++]=temp>>8; + b[len++]=temp; + } + + return len; +} + +static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) +{ + int len=4; + int size; + uint32_t temp; + int i; + int BytesRead = 0; + CDROM_READ_TOC_EX toc_ex; + CDROM_TOC_FULL_TOC_DATA toc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + memset(&toc_ex,0,sizeof(toc_ex)); + memset(&toc,0,sizeof(toc)); + toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_FULL_TOC; + toc_ex.Msf=1; + toc_ex.SessionTrack=0; + ioctl_hopen(id); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); + ioctl_close(id); + b[2]=toc.FirstCompleteSession; + b[3]=toc.LastCompleteSession; + + size -= sizeof(CDROM_TOC_FULL_TOC_DATA); + size /= sizeof(toc.Descriptors[0]); + + for (i = 0; i <= size; i++) + { + b[len++]=toc.Descriptors[i].SessionNumber; + b[len++]=(toc.Descriptors[i].Adr<<4)|toc.Descriptors[i].Control; + b[len++]=0; + b[len++]=toc.Descriptors[i].Reserved1; /*Reserved*/ + b[len++]=toc.Descriptors[i].MsfExtra[0]; + b[len++]=toc.Descriptors[i].MsfExtra[1]; + b[len++]=toc.Descriptors[i].MsfExtra[2]; + b[len++]=toc.Descriptors[i].Zero; + b[len++]=toc.Descriptors[i].Msf[0]; + b[len++]=toc.Descriptors[i].Msf[1]; + b[len++]=toc.Descriptors[i].Msf[2]; + } + + return len; +} + static uint32_t ioctl_size(uint8_t id) { uint8_t capacity_buffer[8]; @@ -1032,7 +1241,7 @@ void ioctl_reset(uint8_t id) return; } - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); ioctl_close(id); @@ -1040,29 +1249,30 @@ void ioctl_reset(uint8_t id) cdrom_ioctl[id].tocvalid = 1; } +int ioctl_hopen(uint8_t id) +{ + if (cdrom_ioctl_windows[id].is_playing) return 0; + cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + return 0; +} + int ioctl_open(uint8_t id, char d) { - if (!cdrom_ioctl[id].ioctl_inited) - { - sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - cdrom_ioctl[id].tocvalid=0; - } + sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); + cdrom_ioctl[id].tocvalid=0; cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_drives[id].handler = &ioctl_cdrom; - if (!cdrom_ioctl[id].ioctl_inited) - { - cdrom_ioctl[id].ioctl_inited=1; - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - update_status_bar_icon_state(0x10 | id, 0); - } + cdrom_ioctl[id].ioctl_inited=1; + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; return 0; } void ioctl_close(uint8_t id) { + if (cdrom_ioctl_windows[id].is_playing) return; if (cdrom_ioctl_windows[id].hIOCTL) { CloseHandle(cdrom_ioctl_windows[id].hIOCTL); @@ -1072,6 +1282,7 @@ void ioctl_close(uint8_t id) static void ioctl_exit(uint8_t id) { + cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); cdrom_ioctl[id].ioctl_inited=0; cdrom_ioctl[id].tocvalid=0; @@ -1084,9 +1295,9 @@ static CDROM ioctl_cdrom= ioctl_media_type_id, ioctl_audio_callback, ioctl_audio_stop, - NULL, - NULL, - NULL, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, ioctl_getcurrentsubchannel, ioctl_pass_through, NULL, diff --git a/src/cdrom_ioctl.h b/src/cdrom_ioctl.h index e39f12ddf..b57689bf9 100644 --- a/src/cdrom_ioctl.h +++ b/src/cdrom_ioctl.h @@ -1,17 +1,35 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_IOCTL_H -#define CDROM_IOCTL_H +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM host drive IOCTL interface for + * Windows using SCSI Passthrough Direct. + * + * This file lists the functions provided by various platform- + * specific cdrom-ioctl files. + * + * Version: @(#)cdrom_ioctl.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_CDROM_IOCTL_H +#define EMU_CDROM_IOCTL_H -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ extern uint32_t cdrom_capacity; - -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); -extern void ioctl_close(uint8_t id); -#endif /* ! CDROM_IOCTL_H */ +extern int ioctl_open(uint8_t id, char d); +extern void ioctl_reset(uint8_t id); + +extern void ioctl_close(uint8_t id); + + +#endif /*EMU_CDROM_IOCTL_H */ diff --git a/src/cdrom_null.c b/src/cdrom_null.c index 5d86b7992..91acaf92f 100644 --- a/src/cdrom_null.c +++ b/src/cdrom_null.c @@ -1,12 +1,29 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM null interface for unmounted + * guest CD-ROM drives. + * + * Version: @(#)cdrom_null.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" #include "cdrom.h" #include "cdrom_ioctl.h" + static CDROM null_cdrom; + static int null_ready(uint8_t id) { return 0; @@ -47,7 +64,7 @@ static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxle return 0; } -static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +static int null_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) { return 0; } @@ -101,7 +118,7 @@ void cdrom_set_null_handler(uint8_t id) { cdrom_drives[id].handler = &null_cdrom; cdrom_drives[id].host_drive = 0; - update_status_bar_icon_state(0x10 | id, 1); + memset(cdrom_image[id].image_path, 0, sizeof(cdrom_image[id].image_path)); } static CDROM null_cdrom = diff --git a/src/cdrom_null.h b/src/cdrom_null.h index 7217760ca..75cc71da5 100644 --- a/src/cdrom_null.h +++ b/src/cdrom_null.h @@ -1,14 +1,28 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#ifndef CDROM_NULL_H -#define CDROM_NULL_H +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM null interface for unmounted + * guest CD-ROM drives. + * + * Version: @(#)cdrom_null.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_CDROM_NULL_H +#define EMU_CDROM_NULL_H -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ -int cdrom_null_open(uint8_t id, char d); -void cdrom_null_reset(uint8_t id); -void null_close(uint8_t id); +extern int cdrom_null_open(uint8_t id, char d); +extern void cdrom_null_reset(uint8_t id); +extern void null_close(uint8_t id); -#endif /* ! CDROM_NULL_H */ + +#endif /*EMU_CDROM_NULL_H*/ diff --git a/src/config.c b/src/config.c index 26e65cfe6..0b4dbce53 100644 --- a/src/config.c +++ b/src/config.c @@ -1,11 +1,16 @@ /* Copyright holders: Sarah Walker - see COPYING for more details -*/ + * see COPYING for more details + * + * NOTE: Forcing config files to be in Unicode encoding breaks it on + * Windows XP, and possibly also Vista. Use -DANSI_CFG for use + * on these systems. + */ #include #include #include #include #include + #include "cdrom.h" #include "config.h" #include "device.h" @@ -22,14 +27,16 @@ #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_mpu401.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]; @@ -132,25 +139,27 @@ static wchar_t cfgbuffer[1024]; static char sname[256]; static char ename[256]; -void config_load(wchar_t *fn) +int config_load(wchar_t *fn) { - int c; - + section_t *current_section; section_t *new_section; entry_t *new_entry; + FILE *f; + int c; int sd = 0, ed = 0, data_pos; - FILE *f = _wfopen(fn, L"rt, ccs=UNICODE"); - section_t *current_section; - - memset(&config_head, 0, sizeof(list_t)); - - current_section = malloc(sizeof(section_t)); - memset(current_section, 0, sizeof(section_t)); - list_add(¤t_section->list, &config_head); - +#ifdef ANSI_CFG + f = _wfopen(fn, L"rt"); +#else + f = _wfopen(fn, L"rt, ccs=UNICODE"); +#endif if (!f) - return; + return 0; + + current_section = malloc(sizeof(section_t)); + memset(current_section, 0x00, sizeof(section_t)); + memset(&config_head, 0x00, sizeof(list_t)); + list_add(¤t_section->list, &config_head); while (1) { @@ -222,12 +231,18 @@ void config_load(wchar_t *fn) fclose(f); config_dump(); + + return 1; } void config_new(void) { +#ifdef ANSI_CFG + FILE *f = _wfopen(config_file, L"wt"); +#else FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); +#endif fclose(f); } @@ -269,6 +284,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 +371,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 +453,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 +533,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; @@ -546,13 +705,19 @@ static wchar_t wname[512]; void config_save(wchar_t *fn) { - FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); section_t *current_section; - + FILE *f; int fl = 0; - + +#ifdef ANSI_CFG + f = _wfopen(fn, L"wt"); +#else + f = _wfopen(fn, L"wt, ccs=UNICODE"); +#endif + if (f == NULL) + return; + current_section = (section_t *)config_head.next; - while (current_section) { entry_t *current_entry; @@ -575,16 +740,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; } @@ -596,6 +765,8 @@ void config_save(wchar_t *fn) } +static wchar_t *read_nvr_path; + /* General */ static void loadconfig_general(void) @@ -622,35 +793,64 @@ 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); + video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0); 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); + vid_cga_contrast = !!config_get_int(cat, "vid_cga_contrast", 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'; } } @@ -687,9 +887,9 @@ static void loadconfig_machine(void) mem_size = config_get_int(cat, "mem_size", 4096); if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - if (mem_size > 1048576) + if (mem_size > 262144) { - mem_size = 1048576; + mem_size = 262144; } cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); @@ -732,7 +932,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 +967,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); @@ -776,11 +977,26 @@ static void loadconfig_sound(void) sound_card_current = 0; midi_id = config_get_int(cat, "midi_host_device", 0); + mpu401_standalone_enable = !!config_get_int(cat, "mpu401_standalone", 0); 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") || !strcmp(temps, "1")) + { + opl3_type = 1; + } + else + { + opl3_type = 0; + } } @@ -788,9 +1004,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") || !strcmp(temps, "2")) + { + network_type = NET_TYPE_SLIRP; + } + else if (!strcmp(temps, "pcap") || !strcmp(temps, "1")) + { + 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) @@ -798,11 +1033,11 @@ static void loadconfig_network(void) { if ((network_ndev == 1) && strcmp(network_pcap, "none")) { - msgbox_error(ghwnd, 2107); + msgbox_error(ghwnd, IDS_2107); } else if (network_dev_to_id(p) == -1) { - msgbox_error(ghwnd, 2200); + msgbox_error(ghwnd, IDS_2200); } strcpy(network_pcap, "none"); @@ -863,79 +1098,163 @@ 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")) { - msgbox_error(ghwnd, 2199); + msgbox_error(ghwnd, IDS_2199); return 0; } return 0; no_mfm_cdrom: - msgbox_error(ghwnd, 2095); + msgbox_error(ghwnd, IDS_2095); return 0; } +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; +} + + +static int tally_char(char *string, char c) +{ + int i = 0; + int tally = 0; + + if (string == NULL) + { + return 0; + } + + if (strlen(string) == 0) + { + return 0; + } + + for (i = 0; i < strlen(string); i++) + { + if (string[i] == c) + { + tally++; + } + } + + return tally; +} + + /* Hard disks */ static void loadconfig_hard_disks(void) { @@ -946,6 +1265,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 +1274,180 @@ 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"; + if (tally_char(p, ',') == 3) + { + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); + hdc[c].wp = 0; + } + else + { + 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); + + if (strstr(p, ":") == NULL) + { + sscanf(p, "%i", &hdc[c].ide_channel); + hdc[c].ide_channel &= 7; + } + else + { + 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 +1462,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 +1480,33 @@ 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); + sprintf(temps, "fdd_%02i_turbo", c + 1); + fdd_set_turbo(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); + } + + if (fdd_get_turbo(c) == 0) + { + sprintf(temps, "fdd_%02i_turbo", c + 1); + config_delete_var(cat, temps); + } } memset(temps, 0, 512); @@ -1057,38 +1530,123 @@ 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); + + if (strstr(p, ":") == NULL) + { + sscanf(p, "%i", &hdc[c].ide_channel); + cdrom_drives[c].ide_channel &= 7; + } + else + { + 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 < 'A') + { + cdrom_drives[c].host_drive = 0; + } + + if ((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); } } void loadconfig(wchar_t *fn) { + int i = 0; + if (fn == NULL) fn = config_file_default; - config_load(fn); + i = config_load(fn); + + if (i == 0) + { + cpu = 0; +#ifndef __unix + dwLanguage = 0x0409; +#endif + scale = 1; + vid_api = 1; + enable_sync = 1; + joystick_type = 7; + strcpy(hdd_controller_name, "none"); + serial_enabled[0] = 1; + serial_enabled[1] = 1; + lpt_enabled = 1; + fdd_set_type(0, 2); + fdd_set_type(1, 2); + mem_size = 640; + + return; + } /* General */ loadconfig_general(); @@ -1144,32 +1702,118 @@ 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; + } + } - 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 (video_fullscreen_scale == 0) + { + config_delete_var(cat, "video_fullscreen_scale"); + } + else + { + config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); + } - config_set_wstring(cat, "nvr_path", nvr_path); + if (video_fullscreen_first == 0) + { + 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); + } + + if (vid_cga_contrast == 0) + { + config_delete_var(cat, "vid_cga_contrast"); + } + else + { + config_set_int(cat, "vid_cga_contrast", vid_cga_contrast); + } + + + if (window_remember) + { + config_set_int(cat, "window_remember", 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"); + } + + 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 +1823,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 == 1) + { + config_delete_var(cat, "enable_sync"); + } + else + { + config_set_int(cat, "enable_sync", enable_sync); + } + + config_delete_section_if_empty(cat); } @@ -1196,8 +1890,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 +1923,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 +1996,70 @@ 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 (mpu401_standalone_enable == 0) + { + config_delete_var(cat, "mpu401_standalone"); + } + else + { + config_set_int(cat, "mpu401_standalone", mpu401_standalone_enable); + } + + 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 +2068,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) ? "slirp" : "pcap"); } - 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 +2113,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 +2226,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 +2321,120 @@ 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]); + } + + sprintf(temps, "fdd_%02i_turbo", c + 1); + if (fdd_get_turbo(c) == 0) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, fdd_get_turbo(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..9efe0edd4 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); @@ -27,7 +33,7 @@ extern char *get_extension(char *s); extern wchar_t *get_extension_w(wchar_t *s); -extern void config_load(wchar_t *fn); +extern int config_load(wchar_t *fn); extern void config_save(wchar_t *fn); extern void config_dump(void); diff --git a/src/device.c b/src/device.c index 5d92699c5..9b90c9ea1 100644 --- a/src/device.c +++ b/src/device.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the generic device interface to handle + * all devices attached to the emulator. + * + * Version: @(#)device.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" #include "cpu/cpu.h" #include "config.h" @@ -8,10 +26,10 @@ static void *device_priv[256]; static device_t *devices[256]; - static device_t *current_device; -void device_init() + +void device_init(void) { memset(devices, 0, sizeof(devices)); } @@ -67,7 +85,7 @@ int device_available(device_t *d) return 1; } -void device_speed_changed() +void device_speed_changed(void) { int c; @@ -85,7 +103,7 @@ void device_speed_changed() sound_speed_changed(); } -void device_force_redraw() +void device_force_redraw(void) { int c; @@ -145,6 +163,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 +222,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..5a2f9b17e 100644 --- a/src/device.h +++ b/src/device.h @@ -1,8 +1,43 @@ -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the generic device interface to handle + * all devices attached to the emulator. + * + * Version: @(#)device.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_DEVICE_H +# define EMU_DEVICE_H + + +#define CONFIG_STRING 0 +#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 + + +enum +{ + DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_AT = 2, /*Device requires an AT-compatible system*/ + DEVICE_PS2 = 4, /*Device requires a PS/1 or PS/2 system*/ + DEVICE_MCA = 0x20, /*Device requires the MCA bus*/ + DEVICE_PCI = 0x40 /*Device requires the PCI bus*/ +}; + typedef struct device_config_selection_t { @@ -33,27 +68,28 @@ typedef struct device_t device_config_t *config; } device_t; -void device_init(); -void device_add(device_t *d); -void device_close_all(); -int device_available(device_t *d); -void device_speed_changed(); -void device_force_redraw(); -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); -void device_set_config_int(char *s, int val); -char *device_get_config_string(char *name); +extern void device_init(void); +extern void device_add(device_t *d); +extern void device_close_all(void); +extern int device_available(device_t *d); +extern void device_speed_changed(void); +extern void device_force_redraw(void); +extern char *device_add_status_info(char *s, int max_len); -enum -{ - DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ - DEVICE_AT = 2, /*Device requires an AT-compatible system*/ - DEVICE_PS2 = 4, /*Device requires a PS/1 or PS/2 system*/ - DEVICE_MCA = 0x20, /*Device requires the MCA bus*/ - DEVICE_PCI = 0x40 /*Device requires the PCI bus*/ -}; +extern int device_get_config_int(char *name); +extern int device_get_config_int_ex(char *s, int default_int); +extern int device_get_config_hex16(char *name); +extern int device_get_config_hex20(char *name); +extern int device_get_config_mac(char *name, int default_int); +extern void device_set_config_int(char *s, int val); +extern void device_set_config_hex16(char *s, int val); +extern void device_set_config_hex20(char *s, int val); +extern void device_set_config_mac(char *s, int val); +extern char *device_get_config_string(char *name); -int model_get_config_int(char *s); -char *model_get_config_string(char *s); +extern int model_get_config_int(char *s); +extern char *model_get_config_string(char *s); + + +#endif /*EMU_DEVICE_H*/ diff --git a/src/disc.c b/src/disc.c index ad7459fe2..bdede24ed 100644 --- a/src/disc.c +++ b/src/disc.c @@ -1,11 +1,25 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic floppy disk interface that communicates with the + * other handlers. + * + * Version: @(#)disc.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #define UNICODE #include #include "ibm.h" - #include "config.h" #include "disc.h" #include "disc_fdi.h" @@ -17,6 +31,10 @@ #include "fdd.h" #include "timer.h" + +wchar_t discfns[4][256]; +extern int driveempty[4]; + int disc_poll_time[FDD_NUM] = { 16, 16, 16, 16 }; int disc_track[FDD_NUM]; @@ -57,14 +75,14 @@ int (*fdc_getdata)(int last); void (*fdc_sectorid)(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2); void (*fdc_indexpulse)();*/ + static struct { wchar_t *ext; void (*load)(int drive, wchar_t *fn); void (*close)(int drive); int size; -} -loaders[]= +} loaders[]= { {L"001", img_load, img_close, -1}, {L"002", img_load, img_close, -1}, @@ -130,7 +148,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); } @@ -176,6 +194,11 @@ double disc_byteperiod(int drive) if (drives[drive].byteperiod) { + if (fdd_get_turbo(drive)) + { + return 1.0; + } + return drives[drive].byteperiod(drive); } else @@ -194,7 +217,7 @@ double disc_real_period(int drive) dusec = (double) TIMER_USEC; /* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */ - if (romset == ROM_MRTHOR) + if ((romset == ROM_MRTHOR) && !fdd_get_turbo(drive)) { return (ddbp * dusec) / 4.0; } @@ -224,22 +247,22 @@ void disc_poll(int drive) } } -void disc_poll_0() +void disc_poll_0(void *priv) { disc_poll(0); } -void disc_poll_1() +void disc_poll_1(void *priv) { disc_poll(1); } -void disc_poll_2() +void disc_poll_2(void *priv) { disc_poll(2); } -void disc_poll_3() +void disc_poll_3(void *priv) { disc_poll(3); } diff --git a/src/disc.h b/src/disc.h index 4bf7a96cb..eb5c7a1bd 100644 --- a/src/disc.h +++ b/src/disc.h @@ -1,8 +1,28 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic floppy disk interface that communicates with the + * other handlers. + * + * Version: @(#)disc.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_DISC_H +# define EMU_DISC_H + + #define FDD_NUM 4 + typedef struct { void (*seek)(int drive, int track); @@ -17,42 +37,51 @@ typedef struct void (*poll)(int drive); } DRIVE; -extern DRIVE drives[FDD_NUM]; -extern int curdrive; +extern DRIVE drives[FDD_NUM]; +extern int curdrive; -void disc_load(int drive, wchar_t *fn); -void disc_new(int drive, char *fn); -void disc_close(int drive); -void disc_init(); -void disc_reset(); -void disc_poll(int drive); -void disc_poll_0(); -void disc_poll_1(); -void disc_seek(int drive, int track); -void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size); -void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size); -void disc_comparesector(int drive, int sector, int track, int side, int density, int sector_size); -void disc_readaddress(int drive, int side, int density); -void disc_format(int drive, int side, int density, uint8_t fill); -int disc_hole(int drive); -double disc_byteperiod(int drive); -void disc_stop(int drive); -int disc_empty(int drive); -void disc_set_rate(int drive, int drvden, int rate); -extern int disc_time; -extern int disc_poll_time[FDD_NUM]; +extern int disc_time; +extern int disc_poll_time[FDD_NUM]; + + +extern void disc_load(int drive, wchar_t *fn); +extern void disc_new(int drive, char *fn); +extern void disc_close(int drive); +extern void disc_init(void); +extern void disc_reset(void); +extern void disc_poll(int drive); +extern void disc_poll_0(void* priv); +extern void disc_poll_1(void* priv); +extern void disc_poll_2(void* priv); +extern void disc_poll_3(void* priv); +extern void disc_seek(int drive, int track); +extern void disc_readsector(int drive, int sector, int track, + int side, int density, int sector_size); +extern void disc_writesector(int drive, int sector, int track, + int side, int density, int sector_size); +extern void disc_comparesector(int drive, int sector, int track, + int side, int density, int sector_size); +extern void disc_readaddress(int drive, int side, int density); +extern void disc_format(int drive, int side, int density, uint8_t fill); +extern int disc_hole(int drive); +extern double disc_byteperiod(int drive); +extern void disc_stop(int drive); +extern int disc_empty(int drive); +extern void disc_set_rate(int drive, int drvden, int rate); + +extern void fdc_callback(void *priv); +extern int fdc_data(uint8_t dat); +extern void fdc_spindown(void); +extern void fdc_finishread(void); +extern void fdc_datacrcerror(void); +extern void fdc_headercrcerror(void); +extern void fdc_writeprotect(void); +extern int fdc_getdata(int last); +extern void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, + uint8_t size, uint8_t crc1, uint8_t crc2); +extern void fdc_indexpulse(void); -void fdc_callback(); -int fdc_data(uint8_t dat); -void fdc_spindown(); -void fdc_finishread(); -void fdc_datacrcerror(); -void fdc_headercrcerror(); -void fdc_writeprotect(); -int fdc_getdata(int last); -void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2); -void fdc_indexpulse(); /*extern int fdc_time; extern int fdc_ready; extern int fdc_indexcount;*/ @@ -201,3 +230,6 @@ typedef union uint8_t byte_array[4]; sector_id_fields_t id; } sector_id_t; + + +#endif /*EMU_DISC_H*/ diff --git a/src/disc_86f.c b/src/disc_86f.c index bfb8f6f50..9eb713365 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the 86F floppy image format (stores the + * data in the form of FM/MFM-encoded transitions) which also + * forms the core of the emulator's floppy disk emulation. + * + * Version: @(#)disc_86f.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include @@ -3041,7 +3059,7 @@ void d86f_load(int drive, wchar_t *fn) d86f[drive].f = _wfopen(fn, L"rb"); if (!d86f[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } writeprot[drive] = 1; @@ -3062,7 +3080,7 @@ void d86f_load(int drive, wchar_t *fn) { /* File is WAY too small, abort. */ fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3071,7 +3089,7 @@ void d86f_load(int drive, wchar_t *fn) /* File is not of the valid format, abort. */ d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3109,7 +3127,7 @@ void d86f_load(int drive, wchar_t *fn) { /* File too small, abort. */ fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3131,7 +3149,7 @@ void d86f_load(int drive, wchar_t *fn) { d86f_log("86F: CRC64 error\n"); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } #endif @@ -3147,7 +3165,7 @@ void d86f_load(int drive, wchar_t *fn) if (!d86f[drive].f) { d86f_log("86F: Unable to create temporary decompressed file\n"); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3177,7 +3195,7 @@ void d86f_load(int drive, wchar_t *fn) { d86f_log("86F: Error decompressing file\n"); _wremove(temp_file_name); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3193,7 +3211,7 @@ void d86f_load(int drive, wchar_t *fn) { _wremove(temp_file_name); } - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3206,7 +3224,7 @@ void d86f_load(int drive, wchar_t *fn) { _wremove(temp_file_name); } - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3239,16 +3257,16 @@ void d86f_load(int drive, wchar_t *fn) /* File has no track 0 side 0, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } if ((d86f_get_sides(drive) == 2) && !(d86f[drive].track_offset[1])) { /* File is 2-sided but has no track 0 side 1, abort. */ - d86f_log("86F: No Track 0 side 0\n"); + d86f_log("86F: No Track 0 side 1\n"); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } diff --git a/src/disc_86f.h b/src/disc_86f.h index 7efc9b3f5..ec7e83c1e 100644 --- a/src/disc_86f.h +++ b/src/disc_86f.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the 86F floppy image format (stores the + * data in the form of FM/MFM-encoded transitions) which also + * forms the core of the emulator's floppy disk emulation. + * + * Version: @(#)disc_86f.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void d86f_init(); void d86f_load(int drive, wchar_t *fn); void d86f_close(int drive); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index bf8410e91..af192b76f 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the FDI floppy stream image format + * interface to the FDI2RAW module. + * + * Version: @(#)disc_fdi.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include @@ -248,7 +264,7 @@ void fdi_load(int drive, wchar_t *fn) fdi[drive].f = _wfopen(fn, L"rb"); if (!fdi[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } diff --git a/src/disc_fdi.h b/src/disc_fdi.h index 781efac23..ae77e0279 100644 --- a/src/disc_fdi.h +++ b/src/disc_fdi.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the FDI floppy stream image format + * interface to the FDI2RAW module. + * + * Version: @(#)disc_fdi.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void fdi_init(); void fdi_load(int drive, wchar_t *fn); void fdi_close(int drive); diff --git a/src/disc_imd.c b/src/disc_imd.c index fcbed568d..b0a8b0016 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -1,6 +1,19 @@ -/* Copyright holders: Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IMD floppy image format. + * + * Version: @(#)disc_imd.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "disc.h" #include "disc_imd.h" @@ -80,7 +93,7 @@ void imd_load(int drive, wchar_t *fn) imd[drive].f = _wfopen(fn, L"rb"); if (!imd[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } writeprot[drive] = 1; @@ -97,7 +110,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: Not a valid ImageDisk image\n"); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -118,7 +131,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: No ASCII EOF character\n"); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -131,7 +144,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: File ends after ASCII EOF character\n"); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -250,7 +263,7 @@ void imd_load(int drive, wchar_t *fn) /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } } diff --git a/src/disc_imd.h b/src/disc_imd.h index a132605d9..f017cebf0 100644 --- a/src/disc_imd.h +++ b/src/disc_imd.h @@ -1,6 +1,19 @@ -/* Copyright holders: Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IMD floppy image format. + * + * Version: @(#)disc_imd.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void imd_init(); void imd_load(int drive, wchar_t *fn); void imd_close(int drive); diff --git a/src/disc_img.c b/src/disc_img.c index 0391820d0..f9016be4b 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the raw sector-based floppy image format, + * as well as the Japanese FDI, CopyQM, and FDF formats. + * + * Version: @(#)disc_img.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include @@ -337,7 +353,7 @@ void img_load(int drive, wchar_t *fn) img[drive].f = _wfopen(fn, L"rb"); if (!img[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } writeprot[drive] = 1; @@ -736,7 +752,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } } @@ -798,7 +814,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -815,7 +831,7 @@ jump_if_fdf: { pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); fclose(img[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } diff --git a/src/disc_img.h b/src/disc_img.h index 4cb82ea1f..94c4780cf 100644 --- a/src/disc_img.h +++ b/src/disc_img.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the raw sector-based floppy image format, + * as well as the Japanese FDI, CopyQM, and FDF formats. + * + * Version: @(#)disc_img.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void img_init(); void img_load(int drive, wchar_t *fn); void img_close(int drive); diff --git a/src/disc_random.c b/src/disc_random.c index 1712193e4..17b28c2e5 100644 --- a/src/disc_random.c +++ b/src/disc_random.c @@ -1,4 +1,19 @@ -/* Better random number generator by Battler. */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * A better random number generation, used for floppy weak bits + * and network MAC address generation. + * + * Version: @(#)disc_random.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include #include diff --git a/src/disc_random.h b/src/disc_random.h index 25dc87326..601e9d84f 100644 --- a/src/disc_random.h +++ b/src/disc_random.h @@ -1,2 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * A better random number generation, used for floppy weak bits + * and network MAC address generation. + * + * Version: @(#)disc_random.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + uint8_t disc_random_generate(); void disc_random_init(); diff --git a/src/disc_td0.c b/src/disc_td0.c index c63a62dc5..ac2cd9a6b 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -1,5 +1,29 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * +* Implementation of the Teledisk floppy image format. + * + * Version: @(#)disc_td0.c 1.0.0 2017/05/30 + * + * Author: Milodrag Milanovic, + * Haruhiko OKUMURA, + * Haruyasu YOSHIZAKI, + * Kenji RIKITAKE, + * Miran Grca, + * Copyright 1988-2017 Haruhiko OKUMURA. + * Copyright 1988-2017 Haruyasu YOSHIZAKI. + * Copyright 1988-2017 Kenji RIKITAKE. + * Copyright 2013-2017 Milodrag Milanovic. + * Copyright 2016-2017 Miran Grca. + */ + /* license:BSD-3-Clause - copyright-holders:Miodrag Milanovic,Kiririn (translation to C and port to 86Box) */ + copyright-holders:Miodrag Milanovic, Miran Grca (translation to C and port to 86Box) */ /********************************************************************* formats/td0_dsk.c @@ -511,7 +535,7 @@ void td0_load(int drive, wchar_t *fn) td0[drive].f = _wfopen(fn, L"rb"); if (!td0[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } fwriteprot[drive] = writeprot[drive]; @@ -521,7 +545,7 @@ void td0_load(int drive, wchar_t *fn) { pclog("TD0: Not a valid Teledisk image\n"); fclose(td0[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -536,7 +560,7 @@ void td0_load(int drive, wchar_t *fn) { pclog("TD0: Failed to initialize\n"); fclose(td0[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else diff --git a/src/disc_td0.h b/src/disc_td0.h index 306c7be20..e28f2dc7d 100644 --- a/src/disc_td0.h +++ b/src/disc_td0.h @@ -1,6 +1,27 @@ -/* Copyright holders: Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Teledisk floppy image format. + * + * Version: @(#)disc_td0.h 1.0.0 2017/05/30 + * + * Author: Milodrag Milanovic, + * Haruhiko OKUMURA, + * Haruyasu YOSHIZAKI, + * Kenji RIKITAKE, + * Miran Grca, + * Copyright 1988-2017 Haruhiko OKUMURA. + * Copyright 1988-2017 Haruyasu YOSHIZAKI. + * Copyright 1988-2017 Kenji RIKITAKE. + * Copyright 2013-2017 Milodrag Milanovic. + * Copyright 2016-2017 Miran Grca. + */ + void td0_init(); void td0_load(int drive, wchar_t *fn); void td0_close(int drive); diff --git a/src/dma.c b/src/dma.c index 259401dee..96f98bd96 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,6 +1,20 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel DMA controllers. + * + * Version: @(#)dma.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" #include "cpu/x86.h" #include "mem.h" @@ -12,9 +26,12 @@ static uint8_t dmaregs[16]; static uint8_t dma16regs[16]; static uint8_t dmapages[16]; +DMA dma, dma16; + void dma_reset(void) { +#if 1 int c; dma.wp = 0; for (c = 0; c < 16; c++) @@ -41,6 +58,13 @@ void dma_reset(void) dma16.cb[c] = 0; } dma16.m = 0; +#else + memset(dmaregs, 0, 16); + memset(dma16regs, 0, 16); + memset(dmapages, 0, 16); + memset(&dma, 0, sizeof(DMA)); + memset(&dma16, 0, sizeof(DMA)); +#endif } uint8_t dma_read(uint16_t addr, void *priv) @@ -481,7 +505,7 @@ void dma_alias_remove_piix(void) io_removehandler(0x009C, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void ps2_dma_init() +void ps2_dma_init(void) { io_sethandler(0x0018, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); io_sethandler(0x001a, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); diff --git a/src/dma.h b/src/dma.h index 515f02f87..29b3bba23 100644 --- a/src/dma.h +++ b/src/dma.h @@ -1,29 +1,53 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ -void dma_init(void); -void dma16_init(void); -void ps2_dma_init(void); -void dma_reset(void); -int dma_mode(int channel); +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel DMA controllers. + * + * Version: @(#)dma.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_DMA_H +# define EMU_DMA_H + #define DMA_NODATA -1 #define DMA_OVER 0x10000 #define DMA_VERIFY 0x20000 -void readdma0(void); -int readdma1(void); -uint8_t readdma2(void); -int readdma3(void); -void writedma2(uint8_t temp); +extern void dma_init(void); +extern void dma16_init(void); +extern void ps2_dma_init(void); +extern void dma_reset(void); +extern int dma_mode(int channel); -int dma_channel_read(int channel); -int dma_channel_write(int channel, uint16_t val); +extern void readdma0(void); +extern int readdma1(void); +extern uint8_t readdma2(void); +extern int readdma3(void); -void dma_alias_set(void); -void dma_alias_remove(void); -void dma_alias_remove_piix(void); +extern void writedma2(uint8_t temp); -void DMAPageRead(uint32_t PhysAddress, char *DataRead, uint32_t TotalSize); -void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); +extern int dma_channel_read(int channel); +extern int dma_channel_write(int channel, uint16_t val); + +extern void dma_alias_set(void); +extern void dma_alias_remove(void); +extern void dma_alias_remove_piix(void); + +extern void DMAPageRead(uint32_t PhysAddress, char *DataRead, + uint32_t TotalSize); +extern void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, + uint32_t TotalSize); + + +#endif /*EMU_DMA_H*/ diff --git a/src/fdc.c b/src/fdc.c index 7a640096b..e7f110440 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NEC uPD-765 and compatible floppy disk + * controller. + * + * Version: @(#)fdc.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include @@ -130,9 +146,11 @@ typedef struct FDC uint16_t base_address; } FDC; +int disctime; + static FDC fdc; -void fdc_callback(); +void fdc_callback(void *priv); int timetolive; int lastbyte=0; uint8_t disc_3f7; @@ -830,7 +848,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = 8; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 10: /*Read sector ID*/ fdc.pnum=0; @@ -856,13 +874,13 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = 0x0e; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 0x10: /*Get version*/ fdc.lastdrive = fdc.drive; discint = 0x10; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 0x12: /*Set perpendicular mode*/ if (!AT || fdc.pcjr || fdc.ps1) goto bad_command; @@ -882,7 +900,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = fdc.command; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 0x18: @@ -890,10 +908,10 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = 0x10; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); /* fdc.stat = 0x10; discint = 0xfc; - fdc_callback(); */ + fdc_callback(NULL); */ break; default: @@ -957,8 +975,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; - update_status_bar_icon(fdc.drive, 1); - readflash = 1; + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.inread = 1; break; @@ -1003,7 +1020,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 +1053,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 +1097,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 +1454,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; } @@ -1456,7 +1473,7 @@ void fdc_no_dma_end(int compare) fdc_poll_common_finish(compare, 0x80); } -void fdc_callback() +void fdc_callback(void *priv) { int compare = 0; int drive_num = 0; @@ -1483,7 +1500,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 +1660,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 +1899,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 +1957,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 +1985,6 @@ int fdc_data(uint8_t data) fdc.stat = 0xd0; } } -#endif } return 0; @@ -2014,7 +2000,7 @@ void fdc_track_finishread(int condition) fdc.stat = 0x10; fdc.satisfying_sectors |= condition; fdc.inread = 0; - fdc_callback(); + fdc_callback(NULL); } void fdc_sector_finishcompare(int satisfying) @@ -2022,14 +2008,14 @@ void fdc_sector_finishcompare(int satisfying) fdc.stat = 0x10; fdc.satisfying_sectors++; fdc.inread = 0; - fdc_callback(); + fdc_callback(NULL); } void fdc_sector_finishread() { fdc.stat = 0x10; fdc.inread = 0; - fdc_callback(); + fdc_callback(NULL); } /* There is no sector ID. */ diff --git a/src/fdc.h b/src/fdc.h index 5bdb7d00e..0e8c42654 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NEC uPD-765 and compatible floppy disk + * controller. + * + * Version: @(#)fdc.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void fdc_init(); void fdc_add(); void fdc_add_for_superio(); diff --git a/src/fdc37c665.c b/src/fdc37c665.c index bbcf157b5..00a80c429 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C665 Super I/O Chip. + * + * Version: @(#)fdc37c665.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "disc.h" @@ -31,7 +46,7 @@ static void write_lock(uint8_t val) static void ide_handler() { uint16_t or_value = 0; - if ((romset == ROM_440FX) || (romset == ROM_R418)) + if ((romset == ROM_440FX) || (romset == ROM_R418) || (romset == ROM_MB500N)) { return; } diff --git a/src/fdc37c665.h b/src/fdc37c665.h index 8f906807d..cbe28216f 100644 --- a/src/fdc37c665.h +++ b/src/fdc37c665.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C665 Super I/O Chip. + * + * Version: @(#)fdc37c665.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern void fdc37c665_init(); diff --git a/src/fdc37c669.c b/src/fdc37c669.c index 605b79e17..33d19b8ba 100644 --- a/src/fdc37c669.c +++ b/src/fdc37c669.c @@ -1,7 +1,18 @@ /* - SMSC SMC FDC37C669 Super I/O Chip - Used by the 430TX -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C669 Super I/O Chip. + * + * Version: @(#)fdc37c669.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/fdc37c669.h b/src/fdc37c669.h index f3fa420d7..31189524a 100644 --- a/src/fdc37c669.h +++ b/src/fdc37c669.h @@ -1 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C669 Super I/O Chip. + * + * Version: @(#)fdc37c669.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void fdc37c669_init(); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 5b4057d1e..d5faf988e 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -1,10 +1,18 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ /* - SMSC SMC fdc37c932fr Super I/O Chip - Used by all some Acer boards, and by the Epox P55-VA -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C932FR Super I/O Chip. + * + * Version: @(#)fdc37c932fr.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/fdc37c932fr.h b/src/fdc37c932fr.h index ef83f5d01..1e48bb0e9 100644 --- a/src/fdc37c932fr.h +++ b/src/fdc37c932fr.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C932FR Super I/O Chip. + * + * Version: @(#)fdc37c932fr.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void fdc37c932fr_init(); diff --git a/src/fdd.c b/src/fdd.c index 35a2b6865..dd6649ee2 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the floppy drive emulation. + * + * Version: @(#)fdd.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "disc.h" #include "fdc.h" @@ -15,6 +30,8 @@ static struct int densel; int head; + + int turbo; } fdd[FDD_NUM]; /* Flags: @@ -297,6 +314,16 @@ int fdd_get_head(int drive) return fdd[drive].head; } +void fdd_set_turbo(int drive, int turbo) +{ + fdd[drive].turbo = turbo; +} + +int fdd_get_turbo(int drive) +{ + return fdd[drive].turbo; +} + int fdd_get_densel(int drive) { if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL) diff --git a/src/fdd.h b/src/fdd.h index c4a18afbe..e8de9db96 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the floppy drive emulation. + * + * Version: @(#)fdd.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define SEEK_RECALIBRATE -999 void fdd_forced_seek(int drive, int track_diff); void fdd_seek(int drive, int track_diff); @@ -15,6 +30,8 @@ int fdd_is_ed(int drive); int fdd_is_double_sided(int drive); void fdd_set_head(int drive, int head); int fdd_get_head(int drive); +void fdd_set_turbo(int drive, int turbo); +int fdd_get_turbo(int drive); void fdd_set_type(int drive, int type); int fdd_get_type(int drive); diff --git a/src/hdd.c b/src/hdd.c index f9491ec7a..7fdb21d95 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -1,6 +1,8 @@ #include "ibm.h" +#include "CPU/cpu.h" #include "device.h" #include "hdd.h" +#include "model.h" #include "hdd_esdi.h" #include "mfm_at.h" @@ -13,6 +15,8 @@ static device_t null_hdd_device; static int hdd_controller_current; +hard_disk_t hdc[HDC_NUM]; + static struct { char name[50]; @@ -61,7 +65,12 @@ int hdd_controller_current_is_mfm() void hdd_controller_init(char *internal_name) { int c = 0; - + + if (models[model].flags & MODEL_HAS_IDE) + { + return; + } + while (hdd_controllers[c].device) { if (!strcmp(internal_name, hdd_controllers[c].internal_name)) 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/i430fx.c b/src/i430fx.c index a0324c3ce..a5100d789 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430FX PCISet chip. + * + * Version: @(#)i430fx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" @@ -34,15 +49,33 @@ static void i430fx_map(uint32_t addr, uint32_t size, int state) void i430fx_write(int func, int addr, uint8_t val, void *priv) { if (func) - return; + return; + + if (addr >= 0x10 && addr < 0x4f) + return; switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430fx[0x59] ^ val) & 0xf0) { diff --git a/src/i430fx.h b/src/i430fx.h index 9ed0f355e..1904ea0f5 100644 --- a/src/i430fx.h +++ b/src/i430fx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430FX PCISet chip. + * + * Version: @(#)i430fx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430fx_init(); diff --git a/src/i430hx.c b/src/i430hx.c index 80c52c02f..1e83fa513 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430HX PCISet chip. + * + * Version: @(#)i430hx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" @@ -37,13 +52,32 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430hx[0x59] ^ val) & 0xf0) { diff --git a/src/i430hx.h b/src/i430hx.h index a6899ca24..4ef96e6ae 100644 --- a/src/i430hx.h +++ b/src/i430hx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430HX PCISet chip. + * + * Version: @(#)i430hx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430hx_init(); diff --git a/src/i430lx.c b/src/i430lx.c index 7494b6c76..ff22680bf 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430LX PCISet chip. + * + * Version: @(#)i430lx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" @@ -36,13 +51,31 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x42; + val |= 0x04; + break; + case 0x05: + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430lx[0x59] ^ val) & 0xf0) { diff --git a/src/i430lx.h b/src/i430lx.h index 60c061df4..23153f7f4 100644 --- a/src/i430lx.h +++ b/src/i430lx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430LX PCISet chip. + * + * Version: @(#)i430lx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430lx_init(); diff --git a/src/i430nx.c b/src/i430nx.c index da7b1a5fe..2827b293b 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430NX PCISet chip. + * + * Version: @(#)i430nx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" @@ -36,13 +51,31 @@ void i430nx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x42; + val |= 0x04; + break; + case 0x05: + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430nx[0x59] ^ val) & 0xf0) { diff --git a/src/i430nx.h b/src/i430nx.h index 3c759a205..93d1466bb 100644 --- a/src/i430nx.h +++ b/src/i430nx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430NX PCISet chip. + * + * Version: @(#)i430nx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430nx_init(); diff --git a/src/i430vx.c b/src/i430vx.c index 2eef17d33..be47835fa 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430VX PCISet chip. + * + * Version: @(#)i430vx.c 1.0.1 2017/06/02 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" @@ -37,20 +52,39 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430vx[0x59] ^ val) & 0xf0) { i430vx_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } - pclog("i430vx_write : PAM0 write %02X\n", val); + /* pclog("i430vx_write : PAM0 write %02X\n", val); */ break; case 0x5a: /*PAM1*/ if ((card_i430vx[0x5a] ^ val) & 0x0f) @@ -81,14 +115,14 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) i430vx_map(0xe0000, 0x04000, val & 0xf); if ((card_i430vx[0x5e] ^ val) & 0xf0) i430vx_map(0xe4000, 0x04000, val >> 4); - pclog("i430vx_write : PAM5 write %02X\n", val); + /* pclog("i430vx_write : PAM5 write %02X\n", val); */ break; case 0x5f: /*PAM6*/ if ((card_i430vx[0x5f] ^ val) & 0x0f) i430vx_map(0xe8000, 0x04000, val & 0xf); if ((card_i430vx[0x5f] ^ val) & 0xf0) i430vx_map(0xec000, 0x04000, val >> 4); - pclog("i430vx_write : PAM6 write %02X\n", val); + /* pclog("i430vx_write : PAM6 write %02X\n", val); */ break; } diff --git a/src/i430vx.h b/src/i430vx.h index af7e5337e..8ed77f3fe 100644 --- a/src/i430vx.h +++ b/src/i430vx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430VX PCISet chip. + * + * Version: @(#)i430vx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430vx_init(); diff --git a/src/i440fx.c b/src/i440fx.c index 9074e2e7a..1a19b10bc 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 440FX PCISet chip. + * + * Version: @(#)i440fx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" @@ -37,20 +52,38 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i440fx[0x59] ^ val) & 0xf0) { i440fx_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } - // pclog("i440fx_write : PAM0 write %02X\n", val); break; case 0x5a: /*PAM1*/ if ((card_i440fx[0x5a] ^ val) & 0x0f) @@ -81,14 +114,12 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) i440fx_map(0xe0000, 0x04000, val & 0xf); if ((card_i440fx[0x5e] ^ val) & 0xf0) i440fx_map(0xe4000, 0x04000, val >> 4); - // pclog("i440fx_write : PAM5 write %02X\n", val); break; case 0x5f: /*PAM6*/ if ((card_i440fx[0x5f] ^ val) & 0x0f) i440fx_map(0xe8000, 0x04000, val & 0xf); if ((card_i440fx[0x5f] ^ val) & 0xf0) i440fx_map(0xec000, 0x04000, val >> 4); - // pclog("i440fx_write : PAM6 write %02X\n", val); break; } diff --git a/src/i440fx.h b/src/i440fx.h index 72cf59458..3ce8b744f 100644 --- a/src/i440fx.h +++ b/src/i440fx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 440FX PCISet chip. + * + * Version: @(#)i440fx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i440fx_init(); diff --git a/src/ibm.h b/src/ibm.h index 8b4680fc0..a95d3635e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -1,6 +1,20 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * General include file. + * + * Version: @(#)ibm.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include #include @@ -9,21 +23,21 @@ /*Memory*/ -uint8_t *ram; -uint32_t rammask; +extern uint8_t *ram; +extern uint32_t rammask; -int readlookup[256],readlookupp[256]; -uintptr_t *readlookup2; -int readlnext; -int writelookup[256],writelookupp[256]; -uintptr_t *writelookup2; -int writelnext; +extern int readlookup[256],readlookupp[256]; +extern uintptr_t *readlookup2; +extern int readlnext; +extern int writelookup[256],writelookupp[256]; +extern uintptr_t *writelookup2; +extern int writelnext; extern int mmu_perm; #define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE)?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC)?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) extern uint8_t readmembl(uint32_t addr); extern void writemembl(uint32_t addr, uint8_t val); @@ -161,6 +175,14 @@ struct } cpu_state; #define cycles cpu_state._cycles + +extern 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 @@ -177,18 +199,18 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) /*x86reg regs[8];*/ -uint16_t flags,eflags; -uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; +extern uint16_t flags,eflags; +extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; extern int ins,output; extern int cycdiff; -x86seg gdt,ldt,idt,tr; -x86seg _cs,_ds,_es,_ss,_fs,_gs; -x86seg _oldds; +extern x86seg gdt,ldt,idt,tr; +extern x86seg _cs,_ds,_es,_ss,_fs,_gs; +extern x86seg _oldds; -uint32_t pccache; -uint8_t *pccache2; +extern uint32_t pccache; +extern uint8_t *pccache2; /*Segments - _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data @@ -220,8 +242,8 @@ union #define cr0 CR0.l #define msw CR0.w -uint32_t cr2, cr3, cr4; -uint32_t dr[8]; +extern uint32_t cr2, cr3, cr4; +extern uint32_t dr[8]; #define C_FLAG 0x0001 #define P_FLAG 0x0004 @@ -319,7 +341,7 @@ typedef struct DMA uint8_t ps2_mode[4]; } DMA; -DMA dma,dma16; +extern DMA dma, dma16; /*PPI*/ @@ -329,7 +351,7 @@ typedef struct PPI uint8_t pa,pb; } PPI; -PPI ppi; +extern PPI ppi; /*PIC*/ @@ -341,13 +363,13 @@ typedef struct PIC int read; } PIC; -PIC pic,pic2; +extern PIC pic, pic2; extern int pic_intpending; -int disctime; -wchar_t discfns[4][256]; -int driveempty[4]; +extern int disctime; +extern wchar_t discfns[4][256]; +extern int driveempty[4]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset=ROM_IBMAT)) #define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && gfxcard!=GFX_HERCULESPLUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) @@ -447,14 +469,15 @@ enum ROM_CMDPC60, ROM_S1668, /*Tyan Titan-Pro ATX / 440FX / AMI BIOS / SMC FDC37C669*/ + ROM_IBMPS1_2133, ROM_MAX }; extern int romspresent[ROM_MAX]; -int hasfpu; -int romset; +extern int hasfpu; +extern int romset; enum { @@ -504,6 +527,7 @@ enum GFX_OTI037, /*Oak OTI-037*/ GFX_VIRGEVX, /*S3 Virge/VX*/ + GFX_VIRGEDX4, /*S3 Virge/DX (VBE 2.0)*/ GFX_MAX }; @@ -516,7 +540,6 @@ int cpuspeed; /*Video*/ -int readflash; extern int egareads,egawrites; extern int vid_resize; extern int vid_api; @@ -525,14 +548,14 @@ extern int changeframecount; /*Sound*/ -int ppispeakon; -float CGACONST; -float MDACONST; -float VGACONST1,VGACONST2; -float RTCCONST; -int gated,speakval,speakon; +extern int ppispeakon; +extern float CGACONST; +extern float MDACONST; +extern float VGACONST1,VGACONST2; +extern float RTCCONST; +extern int gated,speakval,speakon; -#define SOUNDBUFLEN (48000/20) +#define SOUNDBUFLEN (48000/50) /*Sound Blaster*/ @@ -547,10 +570,30 @@ int gated,speakval,speakon; #define SND_WSS 9 /*Windows Sound System*/ #define SND_PAS16 10 /*Pro Audio Spectrum 16*/ -wchar_t pcempath[512]; +extern 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,78 +601,44 @@ 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]; - -FILE *shdf[HDC_NUM]; +extern hard_disk_t hdc[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); /*Keyboard*/ -int keybsenddelay; +extern 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 @@ -684,7 +693,7 @@ extern int path_len; wchar_t *nvr_concat(wchar_t *to_concat); -int mem_a20_state; +extern int mem_a20_state; #ifdef ENABLE_LOG_TOGGLES @@ -693,7 +702,8 @@ extern int cdrom_do_log; extern int d86f_do_log; extern int fdc_do_log; extern int ide_do_log; -extern int ne2000_do_log; +extern int serial_do_log; +extern int nic_do_log; #endif extern int suppress_overscan; @@ -738,6 +748,7 @@ extern void execx86(int cycs); extern void flushmmucache(void); extern void flushmmucache_cr3(void); extern int idivl(int32_t val); +extern void initmodules(void); extern void initpc(int argc, wchar_t *argv[]); extern void loadcscall(uint16_t seg); extern void loadcsjmp(uint16_t seg, uint32_t oxpc); @@ -776,3 +787,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..87822a628 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. + * + * Version: @(#)ide.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _GNU_SOURCE @@ -92,19 +109,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; @@ -126,13 +141,18 @@ uint8_t getstat(IDE *ide) { return ide->atastat; } int ide_drive_is_cdrom(IDE *ide) { + if (ide->channel >= 8) + { + return 0; + } + if (atapi_cdrom_drives[ide->channel] >= CDROM_NUM) { return 0; } 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 +163,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 +186,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,13 +236,16 @@ int image_is_hdx(const wchar_t *s, int check_signature) } } -int ide_enable[4] = { 1, 1, 0, 0 }; -int ide_irq[4] = { 14, 15, 10, 11 }; +int ide_enable[5] = { 1, 1, 0, 0, 1 }; +int ide_irq[5] = { 14, 15, 10, 11, 0 }; void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { + ide->irqstat=1; + ide->service=1; + return; } @@ -259,6 +272,7 @@ void ide_irq_lower(IDE *ide) { if ((ide->board > 3) || !(ide->irqstat)) { + ide->irqstat=0; return; } @@ -353,10 +367,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); @@ -376,13 +393,13 @@ static void ide_identify(IDE *ide) ide->buffer[3] = hdc[ide->hdc_num].hpc; /* Heads */ ide->buffer[6] = hdc[ide->hdc_num].spt; /* Sectors */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[20] = 3; /*Buffer type*/ 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 +435,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,22 +453,22 @@ 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 */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ 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 +535,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 +676,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; } @@ -674,12 +691,12 @@ static int ide_set_features(IDE *ide) features = ide->cylprecomp; features_data = ide->secount; - pclog("Features code %02X\n", features); + ide_log("Features code %02X\n", features); switch(features) { case 0x03: /* Set transfer mode. */ - pclog("Transfer mode %02X\n", features_data >> 3); + ide_log("Transfer mode %02X\n", features_data >> 3); mode = (features_data >> 3); submode = features_data & 7; @@ -703,7 +720,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 +767,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; @@ -770,16 +787,24 @@ void resetide(void) idecallback[0]=idecallback[1]=0; idecallback[2]=idecallback[3]=0; + idecallback[4]=0; 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]); + ide_log("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); + 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)) + { + ide_log("Found XT IDE 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 +825,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 | 8].type == IDE_HDD) + { + ide_drives[d | 8].mdma_mode = 0; + } + + ide_drives[d | 8].error = 1; + } + + for (d = 0; d < 5; d++) { cur_ide[d] = d << 1; } @@ -1399,7 +1436,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); } } } @@ -1581,11 +1618,14 @@ void callbackide(int ide_board) int c; int64_t snum; int cdrom_id; - uint64_t full_size; + uint64_t full_size = 0; ide = &ide_drives[cur_ide[ide_board]]; ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; - full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + if (ide->type == IDE_HDD) + { + full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + } ext_ide = ide; if (ide_drive_is_cdrom(ide)) @@ -1722,7 +1762,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 +1796,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 +1839,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 +1862,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 +1903,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 +1939,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 +1961,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 +1983,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 +2164,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); @@ -2239,12 +2285,12 @@ void ide_pri_enable_ex() { if (ide_base_main[0] & 0x300) { - pclog("Enabling primary base (%04X)...\n", ide_base_main[0]); + ide_log("Enabling primary base (%04X)...\n", ide_base_main[0]); io_sethandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); } if (ide_side_main[0] & 0x300) { - pclog("Enabling primary side (%04X)...\n", ide_side_main[0]); + ide_log("Enabling primary side (%04X)...\n", ide_side_main[0]); io_sethandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); } } @@ -2355,6 +2401,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..003cbbb07 100644 --- a/src/ide.h +++ b/src/ide.h @@ -1,16 +1,29 @@ -/* Copyright holders: Sarah Walker, Tenshi, SA1988 - see COPYING for more details -*/ -#ifndef __IDE__ -#define __IDE__ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. + * + * Version: @(#)ide.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ +#ifndef EMU_IDE_H +# define EMU_IDE_H -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct IDE -#else -typedef struct __attribute__((__packed__)) IDE -#endif -{ + +#pragma pack(push,1) +typedef struct { int type; int board; uint8_t atastat; @@ -40,49 +53,50 @@ typedef struct __attribute__((__packed__)) IDE uint8_t specify_success; int mdma_mode; } IDE; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) + +extern int ideboard; + +extern int ide_enable[5]; +extern int ide_irq[5]; + +IDE ide_drives[IDE_NUM + XTIDE_NUM]; + + +extern int idecallback[5]; extern void writeide(int ide_board, uint16_t addr, uint8_t val); extern void writeidew(int ide_board, uint16_t val); extern uint8_t readide(int ide_board, uint16_t addr); extern uint16_t readidew(int ide_board); extern void callbackide(int ide_board); extern void resetide(void); -extern void ide_init(); -extern void ide_ter_init(); -extern void ide_qua_init(); -extern void ide_pri_enable(); -extern void ide_sec_enable(); -extern void ide_ter_enable(); -extern void ide_qua_enable(); -extern void ide_pri_disable(); -extern void ide_sec_disable(); -extern void ide_ter_disable(); -extern void ide_qua_disable(); +extern void ide_init(void); +extern void ide_xtide_init(void); +extern void ide_ter_init(void); +extern void ide_qua_init(void); +extern void ide_pri_enable(void); +extern void ide_sec_enable(void); +extern void ide_ter_enable(void); +extern void ide_qua_enable(void); +extern void ide_pri_disable(void); +extern void ide_sec_disable(void); +extern void ide_ter_disable(void); +extern void ide_qua_disable(void); extern 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)); -extern int ideboard; - -extern int ide_enable[4]; -extern int ide_irq[4]; - -extern int idecallback[4]; - void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); -IDE ide_drives[IDE_NUM]; - void ide_padstr8(uint8_t *buf, int buf_size, const char *src); void win_cdrom_eject(uint8_t id); void win_cdrom_reload(uint8_t id); -#endif - -void ide_pri_disable(); -void ide_pri_enable_ex(); +void ide_pri_disable(void); +void ide_pri_enable_ex(void); void ide_set_base(int controller, uint16_t port); void ide_set_side(int controller, uint16_t port); + + +#endif /*EMU_IDE_H*/ diff --git a/src/intel_flash.c b/src/intel_flash.c index 1ccb225a9..6ded787ef 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 2 Mbit 8-bit flash devices. + * + * Version: @(#)intel_flash.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" #include "device.h" diff --git a/src/intel_flash.h b/src/intel_flash.h index 242480961..d63b48c18 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 2 Mbit 8-bit flash devices. + * + * Version: @(#)intel_flash.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern device_t intel_flash_bxt_ami_device; extern device_t intel_flash_bxb_ami_device; extern device_t intel_flash_bxt_device; diff --git a/src/keyboard.c b/src/keyboard.c index 75ec25887..7a60c5a62 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,11 +1,27 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Host to guest keyboard interface and keyboard scan code sets. + * + * Version: @(#)keyboard.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "plat_keyboard.h" #include "keyboard.h" int keybsendcallback = 0; +int keybsenddelay; typedef struct { diff --git a/src/keyboard.h b/src/keyboard.h index b53b3a8d5..217f1cee1 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Host to guest keyboard interface and keyboard scan code sets. + * + * Version: @(#)keyboard.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern void (*keyboard_send)(uint8_t val); extern void (*keyboard_poll)(); extern int keyboard_scan; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4e6c7f7e9..fbd9c02e1 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Intel 8042 (AT keyboard controller) emulation. + * + * Version: @(#)keyboard_at.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" #include "io.h" @@ -630,7 +645,8 @@ bad_command: break; case 0xc0: /*Read input port*/ - keyboard_at_adddata((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()); + keyboard_at_adddata(keyboard_at.input_port | 4 | fdc_ps1_525()); + keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc) | fdc_ps1_525(); break; case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ diff --git a/src/keyboard_at.h b/src/keyboard_at.h index 2fdfb5ee8..d92101543 100644 --- a/src/keyboard_at.h +++ b/src/keyboard_at.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Intel 8042 (AT keyboard controller) emulation. + * + * Version: @(#)keyboard_at.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void keyboard_at_init(); void keyboard_at_init_ps2(); void keyboard_at_reset(); diff --git a/src/laserxt.c b/src/laserxt.c new file mode 100644 index 000000000..9ba6e3500 --- /dev/null +++ b/src/laserxt.c @@ -0,0 +1,121 @@ +/*This is the chipset used in the LaserXT series model*/ +#include "ibm.h" +#include "io.h" +#include "mem.h" + +static int laserxt_emspage[4]; +static int laserxt_emscontrol[4]; +static mem_mapping_t laserxt_ems_mapping[4]; +static int laserxt_ems_baseaddr_index = 0; + +uint32_t get_laserxt_ems_addr(uint32_t addr) +{ + if(laserxt_emspage[(addr >> 14) & 3] & 0x80) + { + addr = 0xA0000 + ((laserxt_emspage[(addr >> 14) & 3] & 0x0F) << 14) + ((laserxt_emspage[(addr >> 14) & 3] & 0x40) << 12) + (addr & 0x3FFF); + } + return addr; +} + +void laserxt_write(uint16_t port, uint8_t val, void *priv) +{ + int i; + uint32_t paddr, vaddr; + switch (port) + { + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + laserxt_emspage[port >> 14] = val; + paddr = 0xC0000 + (port & 0xC000) + (((laserxt_ems_baseaddr_index + (4 - (port >> 14))) & 0x0C) << 14); + if(val & 0x80) + { + mem_mapping_enable(&laserxt_ems_mapping[port >> 14]); + vaddr = get_laserxt_ems_addr(paddr); + //pclog("Mapping address %05X to %06X\n", paddr, vaddr); + mem_mapping_set_exec(&laserxt_ems_mapping[port >> 14], ram + vaddr); + } + else + { + //pclog("Unmap address %05X\n", paddr); + mem_mapping_disable(&laserxt_ems_mapping[port >> 14]); + } + //pclog("Write LaserXT port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); + flushmmucache(); + break; + case 0x0209: case 0x4209: case 0x8209: case 0xC209: + laserxt_emscontrol[port >> 14] = val; + laserxt_ems_baseaddr_index = 0; + for(i=0; i<4; i++) + { + laserxt_ems_baseaddr_index |= (laserxt_emscontrol[i] & 0x80) >> (7 - i); + } + //pclog("Set base_index to %d\n", laserxt_ems_baseaddr_index); + if(laserxt_ems_baseaddr_index < 3) + { + mem_mapping_disable(&romext_mapping); + } + else + { + mem_mapping_enable(&romext_mapping); + } + + mem_mapping_set_addr(&laserxt_ems_mapping[0], 0xC0000 + (((laserxt_ems_baseaddr_index + 4) & 0x0C) << 14), 0x4000); + mem_mapping_set_addr(&laserxt_ems_mapping[1], 0xC4000 + (((laserxt_ems_baseaddr_index + 3) & 0x0C) << 14), 0x4000); + mem_mapping_set_addr(&laserxt_ems_mapping[2], 0xC8000 + (((laserxt_ems_baseaddr_index + 2) & 0x0C) << 14), 0x4000); + mem_mapping_set_addr(&laserxt_ems_mapping[3], 0xCC000 + (((laserxt_ems_baseaddr_index + 1) & 0x0C) << 14), 0x4000); + //pclog("Write LaserXT port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); + flushmmucache(); + break; + } +} + +uint8_t laserxt_read(uint16_t port, void *priv) +{ + switch (port) + { + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + //pclog("Read LaserXT port %04X at %04X:%04X\n", port, CS, cpu_state.pc); + return laserxt_emspage[port >> 14]; + case 0x0209: case 0x4209: case 0x8209: case 0xC209: + return laserxt_emscontrol[port >> 14]; + break; + } + return 0xff; +} + +void mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) +{ + addr = get_laserxt_ems_addr(addr); + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +uint8_t mem_read_laserxtems(uint32_t addr, void *priv) +{ + uint8_t val = 0xFF; + addr = get_laserxt_ems_addr(addr); + if (addr < (mem_size << 10)) + val = ram[addr]; + return val; +} + +void laserxt_init() +{ + int i; + + if(mem_size > 640) + { + io_sethandler(0x0208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + io_sethandler(0x4208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + io_sethandler(0x8208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + io_sethandler(0xc208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + } + + for (i = 0; i < 4; i++) + { + laserxt_emspage[i] = 0x7F; + laserxt_emscontrol[i] = (i == 3) ? 0x00 : 0x80; + mem_mapping_add(&laserxt_ems_mapping[i], 0xE0000 + (i << 14), 0x4000, mem_read_laserxtems, NULL, NULL, mem_write_laserxtems, NULL, NULL, ram + 0xA0000 + (i << 14), 0, NULL); + mem_mapping_disable(&laserxt_ems_mapping[i]); + } + mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} diff --git a/src/laserxt.h b/src/laserxt.h new file mode 100644 index 000000000..08919ff6a --- /dev/null +++ b/src/laserxt.h @@ -0,0 +1 @@ +void laserxt_init(); diff --git a/src/cdrom_ioctl_linux.c b/src/lnx/cdrom_ioctl_linux.c similarity index 100% rename from src/cdrom_ioctl_linux.c rename to src/lnx/cdrom_ioctl_linux.c diff --git a/src/lnx/lnx_thread.c b/src/lnx/lnx_thread.c new file mode 100644 index 000000000..d9f16a0ef --- /dev/null +++ b/src/lnx/lnx_thread.c @@ -0,0 +1,108 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include +#include +#include "plat_thread.h" + + +typedef struct { + pthread_cond_t cond; + pthread_mutex_t mutex; +} event_pthread_t; + + +thread_t *thread_create(void (*thread_rout)(void *param), void *param) +{ + pthread_t *thread = malloc(sizeof(pthread_t)); + + if (thread != NULL) + pthread_create(thread, NULL, thread_rout, param); + + return(thread); +} + + +void thread_kill(thread_t *handle) +{ + pthread_t *thread = (pthread_t *)handle; + + if (thread != NULL) { + pthread_cancel(*thread); + pthread_join(*thread, NULL); + + free(thread); + } +} + + +event_t *thread_create_event(void) +{ + event_pthread_t *event = malloc(sizeof(event_pthread_t)); + + if (event != NULL) { + pthread_cond_init(&event->cond, NULL); + pthread_mutex_init(&event->mutex, NULL); + } + + return((event_t *)event); +} + + +void thread_set_event(event_t *handle) +{ + event_pthread_t *event = (event_pthread_t *)handle; + + if (event != NULL) { + pthread_mutex_lock(&event->mutex); + pthread_cond_broadcast(&event->cond); + pthread_mutex_unlock(&event->mutex); + } +} + + +void thread_reset_event(event_t *handle) +{ +} + + +int thread_wait_event(event_t *handle, int timeout) +{ + event_pthread_t *event = (event_pthread_t *)handle; + struct timespec abstime; + + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_nsec += (timeout % 1000) * 1000000; + abstime.tv_sec += (timeout / 1000); + if (abstime.tv_nsec > 1000000000) { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } + + pthread_mutex_lock(&event->mutex); + pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); + pthread_mutex_unlock(&event->mutex); + + return(0); +} + + +void thread_destroy_event(event_t *handle) +{ + event_pthread_t *event = (event_pthread_t *)handle; + + if (event != NULL) { + pthread_cond_destroy(&event->cond); + pthread_mutex_destroy(&event->mutex); + + free(event); + } +} + + +void thread_sleep(int t) +{ + usleep(t * 1000); +} diff --git a/src/lnx/plat_thread.h b/src/lnx/plat_thread.h new file mode 100644 index 000000000..dfb3a9c26 --- /dev/null +++ b/src/lnx/plat_thread.h @@ -0,0 +1,24 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifndef PLAT_THREAD_H +# define PLAT_THREAD_H + + +typedef void thread_t; +typedef void event_t; + + +extern thread_t *thread_create(void (*thread_rout)(void *param), void *param); +extern void thread_kill(thread_t *handle); + +extern event_t *thread_create_event(void); +extern void thread_set_event(event_t *event); +extern void thread_reset_event(event_t *_event); +extern int thread_wait_event(event_t *event, int timeout); +extern void thread_destroy_event(event_t *_event); + +extern void thread_sleep(int t); + + +#endif /*PLAT_THREAD_H*/ diff --git a/src/mem.c b/src/mem.c index b6651ad20..17b564a9e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -44,10 +44,25 @@ static mem_mapping_t ram_mid_mapping; static mem_mapping_t ram_remapped_mapping; mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; -static mem_mapping_t romext_mapping; +mem_mapping_t romext_mapping; + +uint8_t *ram; +uint32_t rammask; + +uint32_t pccache; +uint8_t *pccache2; + +int readlookup[256],readlookupp[256]; +uintptr_t *readlookup2; +int readlnext; +int writelookup[256],writelookupp[256]; +uintptr_t *writelookup2; +int writelnext; int shadowbios,shadowbios_write; +int mem_a20_state; + static unsigned char isram[0x10000]; static uint8_t ff_array[0x1000]; @@ -352,22 +367,32 @@ int loadbios() if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.f6",L"rb"); - if (!f) return 1; /*I don't really care if BASIC is there or not*/ - fread(rom+0x6000,8192,1,f); - fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.f8",L"rb"); - if (!f) break; /*But if some of it is there, then all of it must be*/ - fread(rom+0x8000,8192,1,f); - fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.fa",L"rb"); - if (!f) break; - fread(rom+0xA000,8192,1,f); - fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.fc",L"rb"); - if (!f) break; - fread(rom+0xC000,8192,1,f); - fclose(f); + f=romfopen(L"roms/ibmpc/ibm-basic-1.10.rom",L"rb"); + if (!f) + { + f=romfopen(L"roms/ibmpc/basicc11.f6",L"rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom+0x6000,8192,1,f); + fclose(f); + f=romfopen(L"roms/ibmpc/basicc11.f8",L"rb"); + if (!f) break; /*But if some of it is there, then all of it must be*/ + fread(rom+0x8000,8192,1,f); + fclose(f); + f=romfopen(L"roms/ibmpc/basicc11.fa",L"rb"); + if (!f) break; + fread(rom+0xA000,8192,1,f); + fclose(f); + f=romfopen(L"roms/ibmpc/basicc11.fc",L"rb"); + if (!f) break; + fread(rom+0xC000,8192,1,f); + fclose(f); + } + else + { + fread(rom+0x6000,32768,1,f); + fclose(f); + } + return 1; case ROM_MEGAPC: @@ -467,6 +492,14 @@ int loadbios() biosmask = 0x1ffff; return 1; + case ROM_IBMPS1_2133: + f = romfopen(L"roms/ibmps1_2133/PS1_2133_52G2974_ROM.bin", L"rb"); + if (!f) break; + fread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_DESKPRO_386: f=romfopen(L"roms/deskpro386/109592-005.U11.bin",L"rb"); ff=romfopen(L"roms/deskpro386/109591-005.U13.bin",L"rb"); @@ -493,6 +526,32 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); + f=romfopen(L"roms/ltxt/ibm-basic-1.10.rom",L"rb"); + if (!f) + { + f=romfopen(L"roms/ltxt/basicc11.f6",L"rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom+0x6000,8192,1,f); + fclose(f); + f=romfopen(L"roms/ltxt/basicc11.f8",L"rb"); + if (!f) break; /*But if some of it is there, then all of it must be*/ + fread(rom+0x8000,8192,1,f); + fclose(f); + f=romfopen(L"roms/ltxt/basicc11.fa",L"rb"); + if (!f) break; + fread(rom+0xA000,8192,1,f); + fclose(f); + f=romfopen(L"roms/ltxt/basicc11.fc",L"rb"); + if (!f) break; + fread(rom+0xC000,8192,1,f); + fclose(f); + } + else + { + fread(rom+0x6000,32768,1,f); + fclose(f); + } + return 1; case ROM_LXT3: @@ -500,6 +559,32 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); + f=romfopen(L"roms/lxt3/ibm-basic-1.10.rom",L"rb"); + if (!f) + { + f=romfopen(L"roms/lxt3/basicc11.f6",L"rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom+0x6000,8192,1,f); + fclose(f); + f=romfopen(L"roms/lxt3/basicc11.f8",L"rb"); + if (!f) break; /*But if some of it is there, then all of it must be*/ + fread(rom+0x8000,8192,1,f); + fclose(f); + f=romfopen(L"roms/lxt3/basicc11.fa",L"rb"); + if (!f) break; + fread(rom+0xA000,8192,1,f); + fclose(f); + f=romfopen(L"roms/lxt3/basicc11.fc",L"rb"); + if (!f) break; + fread(rom+0xC000,8192,1,f); + fclose(f); + } + else + { + fread(rom+0x6000,32768,1,f); + fclose(f); + } + return 1; case ROM_SPC4200P: /*Samsung SPC-4200P*/ @@ -1196,25 +1281,29 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) uint16_t readmemwl(uint32_t seg, uint32_t addr) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFE) - { - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14] && ram_mapped_addr[(addr2+1) >> 14]) - { - return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); - } - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; - if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; - } - if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); - else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); - } + if (seg==-1) { x86gpf("NULL segment", 0); return -1; } + if (addr2 & 1) + { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFFE) + { + if (cr0 >> 31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + } + if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); + else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); + } if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); @@ -1242,31 +1331,6 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) void writememwl(uint32_t seg, uint32_t addr, uint16_t val) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFE) - { - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - writemembl(seg+addr,val); - writemembl(seg+addr+1,val>>8); - return; - } - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+1) == 0xffffffff) return; - } - if (is386) - { - writememb386l(seg,addr,val); - writememb386l(seg,addr+1,val>>8); - } - else - { - writemembl(seg+addr,val); - writemembl(seg+addr+1,val>>8); - } - return; - } if (seg==-1) { @@ -1279,6 +1343,37 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) if(addr < mem_size * 1024) *((uint16_t *)&ram[addr]) = val; return; } + + if (addr2 & 1) + { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFFE) + { + if (cr0 >> 31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+1) == 0xffffffff) return; + } + if (is386) + { + writememb386l(seg,addr,val); + writememb386l(seg,addr+1,val>>8); + } + else + { + writemembl(seg+addr,val); + writemembl(seg+addr+1,val>>8); + } + return; + } + else if (writelookup2[addr2 >> 12] != -1) + { + *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } + if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); @@ -1312,19 +1407,6 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) uint32_t readmemll(uint32_t seg, uint32_t addr) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFC) - { - if (addr2 < 0x100000 && (ram_mapped_addr[addr2 >> 14] || ram_mapped_addr[(addr2+3) >> 14])) - { - return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); - } - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; - } - return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); - } if (seg==-1) { @@ -1338,6 +1420,24 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) if(addr < mem_size * 1024) return *((uint32_t *)&ram[addr]); return 0xFFFFFFFF; } + + if (addr2 & 3) + { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + cycles -= timing_misaligned; + if ((addr2&0xFFF)>0xFFC) + { + if (cr0>>31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; + } + return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); + } + if (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1359,17 +1459,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFC) - { - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+3) == 0xffffffff) return; - } - writememwl(seg,addr,val); - writememwl(seg,addr+2,val>>16); - return; - } if (seg==-1) { x86gpf("NULL segment", 0); @@ -1381,6 +1470,27 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) if(addr < mem_size * 1024) *((uint32_t *)&ram[addr]) = val; return; } + if (addr2 & 3) + { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFFC) + { + if (cr0>>31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+3) == 0xffffffff) return; + } + writememwl(seg,addr,val); + writememwl(seg,addr+2,val>>16); + return; + } + else if (writelookup2[addr2 >> 12] != -1) + { + *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); @@ -1418,15 +1528,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) uint64_t readmemql(uint32_t seg, uint32_t addr) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFF8) - { - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; - } - return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); - } if (seg==-1) { @@ -1440,6 +1541,23 @@ uint64_t readmemql(uint32_t seg, uint32_t addr) if(addr < mem_size * 1024) return *((uint64_t *)&ram[addr]); return -1; } + + if (addr2 & 7) + { + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFF8) + { + if (cr0>>31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + } + return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); + } + if (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1459,17 +1577,6 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2 & 0xFFF) > 0xFF8) - { - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+7) == 0xffffffff) return; - } - writememll(seg, addr, val); - writememll(seg, addr+4, val >> 32); - return; - } if (seg==-1) { x86gpf("NULL segment", 0); @@ -1481,6 +1588,26 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) if(addr < mem_size * 1024) *((uint64_t *)&ram[addr]) = val; return; } + if (addr2 & 7) + { + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFF8) + { + if (cr0>>31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+7) == 0xffffffff) return; + } + writememll(seg, addr, val); + writememll(seg, addr+4, val >> 32); + return; + } + else if (writelookup2[addr2 >> 12] != -1) + { + *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); diff --git a/src/mem.h b/src/mem.h index f4cef2a31..6bf127ecf 100644 --- a/src/mem.h +++ b/src/mem.h @@ -109,6 +109,7 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p); mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; +mem_mapping_t romext_mapping; extern mem_mapping_t ram_high_mapping; diff --git a/src/memregs.c b/src/memregs.c index ec832225a..6d002f512 100644 --- a/src/memregs.c +++ b/src/memregs.c @@ -1,10 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ /* - 0xE1 and 0xE2 Memory Registers - Used by just about any emulated machine -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the memory I/O scratch registers on ports 0xE1 + * and 0xE2, used by just about any emulated machine. + * + * Version: @(#)memregs.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/memregs.h b/src/memregs.h index 590aa2af2..cb8d626b7 100644 --- a/src/memregs.h +++ b/src/memregs.h @@ -1,5 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the memory I/O scratch registers on ports 0xE1 + * and 0xE2, used by just about any emulated machine. + * + * Version: @(#)memregs.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void memregs_init(); void powermate_memregs_init(); 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..9e4dc6b7e 100644 --- a/src/model.c +++ b/src/model.c @@ -1,13 +1,29 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the emulated machines. + * + * Version: @(#)model.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include + #include "ibm.h" #include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "rom.h" +#include "device.h" #include "model.h" #include "mouse.h" #include "mouse_ps2.h" @@ -17,7 +33,6 @@ #include "ali1429.h" #include "amstrad.h" #include "compaq.h" -#include "device.h" #include "disc.h" #include "dma.h" #include "fdc.h" @@ -42,6 +57,7 @@ #include "keyboard_olim24.h" #include "keyboard_pcjr.h" #include "keyboard_xt.h" +#include "laserxt.h" #include "lpt.h" #include "mem.h" #include "memregs.h" @@ -76,49 +92,57 @@ #include "xtide.h" #include "bugger.h" -void xt_init(); -void pcjr_init(); -void tandy1k_init(); -void tandy1ksl2_init(); -void ams_init(); -void europc_init(); -void olim24_init(); -void at_init(); -void ibm_at_init(); -void at_ide_init(); -void deskpro386_init(); -void ps1_m2011_init(); -void ps1_m2121_init(); -void ps2_m30_286_init(); -void ps2_model_50_init(); -void ps2_model_55sx_init(); -void ps2_model_80_init(); -void at_neat_init(); -void at_scat_init(); -void at_wd76c10_init(); -void at_ali1429_init(); -void at_headland_init(); -void at_opti495_init(); -void at_sis496_init(); -void at_i430vx_init(); -void at_batman_init(); -void at_endeavor_init(); -void at_dtk486_init(); -void at_r418_init(); -void at_586mc1_init(); -void at_plato_init(); -void at_mb500n_init(); -void at_p54tp4xe_init(); -void at_ap53_init(); -void at_p55t2s_init(); -void at_acerm3a_init(); -void at_acerv35n_init(); -void at_p55t2p4_init(); -void at_p55tvp4_init(); -void at_p55va_init(); -void at_i440fx_init(); -void at_s1668_init(); +extern void xt_init(void); +extern void pcjr_init(void); +extern void tandy1k_init(void); +extern void tandy1ksl2_init(void); +extern void ams_init(void); +extern void europc_init(void); +extern void olim24_init(void); +extern void at_init(void); +extern void ibm_at_init(void); +extern void at_ide_init(void); +extern void deskpro386_init(void); +extern void ps1_m2011_init(void); +extern void ps1_m2121_init(void); +extern void ps1_m2133_init(void); +extern void ps2_m30_286_init(void); +extern void ps2_model_50_init(void); +extern void ps2_model_55sx_init(void); +extern void ps2_model_80_init(void); +extern void at_neat_init(void); +extern void at_scat_init(void); +extern void at_wd76c10_init(void); +extern void at_ali1429_init(void); +extern void at_headland_init(void); +extern void at_opti495_init(void); +extern void at_sis496_init(void); +extern void at_i430vx_init(void); +extern void at_batman_init(void); +extern void at_endeavor_init(void); + +extern void at_dtk486_init(void); +extern void at_r418_init(void); +#if 0 +extern void at_586mc1_init(void); +#endif +extern void at_plato_init(void); +extern void at_mb500n_init(void); +extern void at_p54tp4xe_init(void); +extern void at_ap53_init(void); +extern void at_p55t2s_init(void); +extern void at_acerm3a_init(void); +#if 0 +extern void at_acerv35n_init(void); +#endif +extern void at_p55t2p4_init(void); +extern void at_p55tvp4_init(void); +extern void at_p55va_init(void); +extern void at_i440fx_init(void); +extern void at_s1668_init(void); + +extern void xt_laserxt_init(void); int model; @@ -129,6 +153,8 @@ PCI_RESET pci_reset_handler; int serial_enabled[2] = { 0, 0 }; int lpt_enabled = 0, bugger_enabled = 0; +int romset; + MODEL models[] = { {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, @@ -138,8 +164,8 @@ MODEL models[] = {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL}, {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, @@ -147,7 +173,7 @@ MODEL models[] = {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, @@ -176,39 +202,45 @@ MODEL models[] = {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, + {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, ps1_m2133_init, NULL}, {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_dtk486_init, NULL}, {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_sis496_init, NULL}, {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_r418_init, NULL}, {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_batman_init, NULL}, +#if 0 {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_586mc1_init, NULL}, +#endif {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_mb500n_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p54tp4xe_init, NULL}, - {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_ap53_init, NULL}, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p55t2s_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_acerm3a_init, NULL}, - {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p55t2p4_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p54tp4xe_init, NULL}, + {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_ap53_init, NULL}, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2s_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerm3a_init, NULL}, +#if 0 + {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerv35n_init, NULL}, +#endif + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2p4_init, NULL}, {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL}, {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL}, {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55tvp4_init, NULL}, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 1024, 1, at_i440fx_init, NULL}, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 1024, 1, at_s1668_init, NULL}, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i440fx_init, NULL}, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_s1668_init, NULL}, {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; -int model_count() + +int model_count(void) { return (sizeof(models) / sizeof(MODEL)) - 1; } -int model_getromset() +int model_getromset(void) { return models[model].id; } @@ -243,7 +275,7 @@ device_t *model_getdevice(int model) return models[model].device; } -char *model_get_internal_name() +char *model_get_internal_name(void) { return models[model].internal_name; } @@ -262,7 +294,7 @@ int model_get_model_from_internal_name(char *s) return 0; } -void common_init() +void common_init(void) { dma_init(); fdc_add(); @@ -282,7 +314,7 @@ void common_init() } } -void xt_init() +void xt_init(void) { common_init(); mem_add_bios(); @@ -296,7 +328,7 @@ void xt_init() } } -void pcjr_init() +void pcjr_init(void) { mem_add_bios(); fdc_add_pcjr(); @@ -312,7 +344,7 @@ void pcjr_init() nmi_mask = 0x80; } -void tandy1k_init() +void tandy1k_init(void) { TANDY = 1; common_init(); @@ -327,7 +359,7 @@ void tandy1k_init() device_add(&tandy_eeprom_device); if (joystick_type != 7) device_add(&gameport_device); } -void tandy1ksl2_init() +void tandy1ksl2_init(void) { common_init(); mem_add_bios(); @@ -339,7 +371,7 @@ void tandy1ksl2_init() if (joystick_type != 7) device_add(&gameport_device); } -void ams_init() +void ams_init(void) { AMSTRAD = 1; common_init(); @@ -352,7 +384,7 @@ void ams_init() if (joystick_type != 7) device_add(&gameport_device); } -void europc_init() +void europc_init(void) { common_init(); mem_add_bios(); @@ -362,7 +394,7 @@ void europc_init() if (joystick_type != 7) device_add(&gameport_device); } -void olim24_init() +void olim24_init(void) { common_init(); mem_add_bios(); @@ -373,7 +405,13 @@ void olim24_init() if (joystick_type != 7) device_add(&gameport_device); } -void at_init() +void xt_laserxt_init(void) +{ + xt_init(); + laserxt_init(); +} + +void at_init(void) { AT = 1; common_init(); @@ -394,25 +432,25 @@ void at_init() } } -void ibm_at_init() +void ibm_at_init(void) { at_init(); mem_remap_top_384k(); } -void at_ide_init() +void at_ide_init(void) { at_init(); ide_init(); } -void deskpro386_init() +void deskpro386_init(void) { at_init(); compaq_init(); } -void ps1_common_init() +void ps1_common_init(void) { AT = 1; common_init(); @@ -426,26 +464,35 @@ void ps1_common_init() keyboard_at_init(); nvr_init(); pic2_init(); - fdc_set_dskchg_activelow(); - device_add(&ps1_audio_device); + if (romset != ROM_IBMPS1_2133) + { + fdc_set_dskchg_activelow(); + device_add(&ps1_audio_device); + } /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ if (joystick_type != 7) device_add(&gameport_201_device); } -void ps1_m2011_init() +void ps1_m2011_init(void) { ps1_common_init(); ps1mb_init(); } -void ps1_m2121_init() +void ps1_m2121_init(void) { ps1_common_init(); ps1mb_m2121_init(); fdc_set_ps1(); } -void ps2_m30_286_init() +void ps1_m2133_init(void) +{ + ps1_common_init(); + ps1mb_m2133_init(); +} + +void ps2_m30_286_init(void) { AT = 1; common_init(); @@ -460,7 +507,7 @@ void ps2_m30_286_init() fdc_set_ps1(); } -static void ps2_common_init() +static void ps2_common_init(void) { AT = 1; common_init(); @@ -477,83 +524,84 @@ static void ps2_common_init() pit_ps2_init(); } -void ps2_model_50_init() +void ps2_model_50_init(void) { ps2_common_init(); ps2_mca_board_model_50_init(); } -void ps2_model_55sx_init() +void ps2_model_55sx_init(void) { ps2_common_init(); ps2_mca_board_model_55sx_init(); } -void ps2_model_80_init() +void ps2_model_80_init(void) { ps2_common_init(); ps2_mca_board_model_80_type2_init(); } -void at_neat_init() +void at_neat_init(void) { at_ide_init(); neat_init(); } -void at_scat_init() +void at_scat_init(void) { at_ide_init(); scat_init(); } -/* void at_acer386sx_init() +/* void at_acer386sx_init(void) { at_ide_init(); acer386sx_init(); } -void at_82335_init() +void at_82335_init(void) { at_ide_init(); i82335_init(); } */ -void at_wd76c10_init() +void at_wd76c10_init(void) { at_ide_init(); wd76c10_init(); } -void at_headland_init() +void at_headland_init(void) { at_ide_init(); headland_init(); } -void at_opti495_init() +void at_opti495_init(void) { at_ide_init(); opti495_init(); } -void secondary_ide_check() +void secondary_ide_check(void) { int i = 0; int secondary_cdroms = 0; 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() +void at_ali1429_init(void) { + ali1429_reset(); at_ide_init(); ali1429_init(); @@ -561,14 +609,14 @@ void at_ali1429_init() secondary_ide_check(); } -/* void at_um8881f_init() +/* void at_um8881f_init(void) { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); um8881f_init(); } */ -void at_dtk486_init() +void at_dtk486_init(void) { at_ide_init(); memregs_init(); @@ -576,225 +624,276 @@ void at_dtk486_init() secondary_ide_check(); } -void at_sis496_init() +void at_sis496_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xd); + pci_slot(0xf); sis496_init(); trc_init(); } -void at_r418_init() +void at_r418_init(void) { at_sis496_init(); fdc37c665_init(); } -void at_premiere_common_init() +void at_premiere_common_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); - sio_init(1); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + sio_init(2, 0xc, 0xe, 0x6, 0); fdc37c665_init(); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); } -void at_batman_init() +void at_batman_init(void) { at_premiere_common_init(); i430lx_init(); } -void at_586mc1_init() +#if 0 +void at_586mc1_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_2); i430lx_init(); - sio_init(1); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + sio_init(2, 0xc, 0xe, 0x6, 0); device_add(&intel_flash_bxt_device); secondary_ide_check(); } +#endif -void at_plato_init() +void at_plato_init(void) { at_premiere_common_init(); i430nx_init(); } -void at_advanced_common_init() +void at_advanced_common_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); pc87306_init(); } -void at_endeavor_init() +void at_endeavor_init(void) { at_advanced_common_init(); device_add(&intel_flash_bxt_ami_device); } -void at_mb500n_init() +void at_mb500n_init(void) { at_ide_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430fx_init(); - piix_init(7); + piix_init(7, 0x14, 0x13, 0x12, 0x11); fdc37c665_init(); device_add(&intel_flash_bxt_device); } -#if 0 -void at_powermate_v_init() -{ - at_ide_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - i430fx_init(); - piix_init(7); - fdc37c665_init(); - acerm3a_io_init(); - device_add(&intel_flash_bxt_device); -} -#endif - -void at_p54tp4xe_init() +void at_p54tp4xe_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(9); + pci_slot(10); + pci_slot(11); + pci_slot(12); i430fx_init(); - piix_init(7); + piix_init(7, 12, 11, 10, 9); fdc37c665_init(); device_add(&intel_flash_bxt_device); } -void at_ap53_init() +void at_ap53_init(void) { at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix3_init(7); + piix_init(7, 0x11, 0x12, 0x13, 0x14); fdc37c669_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); } -void at_p55t2s_init() +void at_p55t2s_init(void) { at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix3_init(7); + piix_init(7, 0x12, 0x13, 0x14, 0x11); pc87306_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); } -void at_acerm3a_init() +void at_acerm3a_init(void) { at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xc); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); i430hx_init(); - piix3_init(7); + piix_init(7, 0xc, 0xd, 0xe, 0xf); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); } -void at_acerv35n_init() +#if 0 +void at_acerv35n_init(void) { at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xc); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); i430hx_init(); - piix3_init(7); + piix_init(7, 0xc, 0xd, 0xe, 0xf); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); } +#endif -void at_p55t2p4_init() +void at_p55t2p4_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(9); + pci_slot(10); + pci_slot(11); + pci_slot(12); i430hx_init(); - piix3_init(7); + piix3_init(7, 12, 11, 10, 9); w83877f_init(); device_add(&intel_flash_bxt_device); } -void at_i430vx_init() +void at_i430vx_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 17, 18, 20, 19); um8669f_init(); device_add(&intel_flash_bxt_device); } -void at_p55tvp4_init() +void at_p55tvp4_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(9); + pci_slot(10); + pci_slot(11); + pci_slot(12); i430vx_init(); - piix3_init(7); + piix3_init(7, 12, 11, 10, 9); w83877f_init(); device_add(&intel_flash_bxt_device); } -void at_p55va_init() +void at_p55va_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(8); + pci_slot(9); + pci_slot(10); + pci_slot(11); i430vx_init(); - piix3_init(7); + piix3_init(7, 8, 9, 10, 11); fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } -void at_i440fx_init() +void at_i440fx_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - i440fx_init(); - piix3_init(7); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xc); + pci_slot(0xd); + pci_slot(0xe); + i430vx_init(); + piix3_init(7, 0xe, 0xd, 0xc, 0xb); fdc37c665_init(); device_add(&intel_flash_bxt_device); } -void at_s1668_init() +void at_s1668_init(void) { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xc); + pci_slot(0xd); + pci_slot(0xe); i440fx_init(); - piix3_init(7); + piix3_init(7, 0xe, 0xd, 0xc, 0xb); fdc37c665_init(); device_add(&intel_flash_bxt_device); } -void model_init() +void model_init(void) { pclog("Initializing as %s\n", model_getname()); AMSTRAD = AT = PCI = TANDY = 0; diff --git a/src/model.h b/src/model.h index bfdc19077..f483cd1aa 100644 --- a/src/model.h +++ b/src/model.h @@ -1,6 +1,24 @@ -/* Copyright holders: Sarah Walker, Tohka - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the emulated machines. + * + * Version: @(#)model.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_MODEL_H +# define EMU_MODEL_H + + #define MODEL_AT 1 #define MODEL_PS2 2 #define MODEL_AMSTRAD 4 @@ -13,34 +31,37 @@ #define MODEL_FUJITSU 512 #define MODEL_RM 1024 -typedef struct -{ - char name[32]; - int id; - char internal_name[24]; - struct - { - char name[16]; - CPU *cpus; - } cpu[5]; - int fixed_gfxcard; - int flags; - int min_ram, max_ram; - int ram_granularity; - void (*init)(); - struct device_t *device; + +typedef struct { + char name[32]; + int id; + char internal_name[24]; + struct { + char name[16]; + CPU *cpus; + } cpu[5]; + int fixed_gfxcard; + int flags; + int min_ram, max_ram; + int ram_granularity; + void (*init)(void); + device_t *device; } MODEL; -extern MODEL models[]; +extern MODEL models[]; extern int model; -int model_count(); -int model_getromset(); -int model_getmodel(int romset); -char *model_getname(); -char *model_get_internal_name(); -int model_get_model_from_internal_name(char *s); -void model_init(); -struct device_t *model_getdevice(int model); -int model_getromset_ex(int m); + +extern int model_count(void); +extern int model_getromset(void); +extern int model_getmodel(int romset); +extern char *model_getname(void); +extern char *model_get_internal_name(void); +extern int model_get_model_from_internal_name(char *s); +extern void model_init(void); +extern device_t *model_getdevice(int model); +extern int model_getromset_ex(int m); + + +#endif /*EMU_MODEL_H*/ diff --git a/src/mouse.c b/src/mouse.c index 3e11903dc..08850d4d7 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -14,8 +14,8 @@ static mouse_t *mouse_list[] = { &mouse_bus, /* 3 Logitech Bus Mouse 2-button */ &mouse_amstrad, /* 4 Amstrad PC System Mouse */ &mouse_olim24, /* 5 Olivetti M24 System Mouse */ -#if 0 &mouse_msystems, /* 6 Mouse Systems */ +#if 0 &mouse_genius, /* 7 Genius Bus Mouse */ #endif NULL diff --git a/src/mouse.h b/src/mouse.h index 4ae2d8d76..25aa07888 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -1,5 +1,5 @@ -#ifndef MOUSE_H -# define MOUSE_H +#ifndef EMU_MOUSE_H +# define EMU_MOUSE_H #define MOUSE_TYPE_SERIAL 0 /* Serial Mouse */ @@ -38,4 +38,4 @@ extern int mouse_get_type(int mouse); extern int mouse_get_ndev(void); -#endif /*MOUSE_H*/ +#endif /*EMU_MOUSE_H*/ diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 5d5d5e97e..32063bfb0 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -32,7 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * Version: @(#)mouse_bus.c 1.0.4 2017/05/17 + * Version: @(#)mouse_bus.c 1.0.5 2017/06/02 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -108,7 +108,7 @@ typedef struct { static void ms_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { -#if 1 +#if 0 pclog("BUSMOUSE: ms_write(%d,%02x)\n", port, val); #endif @@ -151,7 +151,7 @@ lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { uint8_t b = (ms->r_ctrl ^ val); -#if 1 +#if 0 pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val); #endif @@ -248,7 +248,7 @@ ms_read(mouse_bus_t *ms, uint16_t port) break; } -#if 1 +#if 0 pclog("BUSMOUSE: ms_read(%d): %02x\n", port, r); #endif @@ -367,7 +367,7 @@ lt_read(mouse_bus_t *ms, uint16_t port) break; } -#if 1 +#if 0 pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r); #endif diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 8afe9b3b3..6a2c9ef34 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -28,6 +28,7 @@ typedef struct mouse_serial_t { delay; int oldb; SERIAL *serial; + int is_ms_format; } mouse_serial_t; @@ -50,11 +51,12 @@ sermouse_timer(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; ms->delay = 0; - if (ms->pos == -1) { - ms->pos = 0; + if (ms->pos == -1) + { + ms->pos = 0; - /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M'); + /* This identifies a two-button Microsoft Serial mouse. */ + serial_write_fifo(ms->serial, 'M'); } } @@ -130,3 +132,61 @@ mouse_t mouse_serial_microsoft = { sermouse_close, sermouse_poll }; + +static uint8_t +mssystems_mouse_poll(int x, int y, int z, int b, void *priv) +{ + mouse_serial_t *ms = (mouse_serial_t *)priv; + uint8_t data[5]; + + if (!x && !y && b == ms->oldb) return(1); + + ms->oldb = b; + + y=-y; + + if (x>127) x = 127; + if (y>127) y = 127; + if (x<-128) x = -128; + if (y<-128) y = -128; + + data[0] = 0x80 | ((((b & 0x04) >> 1) + ((b & 0x02) << 1) + (b & 0x01)) ^ 0x07); + data[1] = x; + data[2] = y; + data[3] = 0; + data[4] = 0; + + pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); + + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); + serial_write_fifo(ms->serial, data[3]); + serial_write_fifo(ms->serial, data[4]); + + return(0); +} + +static void * +mssystems_mouse_init(void) +{ + mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(ms, 0x00, sizeof(mouse_serial_t)); + ms->port = SERMOUSE_PORT; + + /* Attach a serial port to the mouse. */ + ms->serial = serial_attach(ms->port, sermouse_callback, ms); + + timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); + + return(ms); +} + +mouse_t mouse_msystems = { + "Mouse Systems Mouse (serial)", + "mssystems", + MOUSE_TYPE_MSYSTEMS, + mssystems_mouse_init, + sermouse_close, + mssystems_mouse_poll +}; \ No newline at end of file diff --git a/src/mouse_serial.h b/src/mouse_serial.h index f37b32da2..c76dce483 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -22,6 +22,7 @@ extern mouse_t mouse_serial_microsoft; +extern mouse_t mouse_msystems; #endif /*MOUSE_SERIAL_H*/ diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 88b97cf40..7194adf68 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -8,10 +8,9 @@ * * Implementation of an NE2000/RTL8029AS network controller. * - * NOTE: Its still a mess, but we're getting there. The file will - * also implement an NE1000 for 8-bit ISA systems. + * NOTE: The file will also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.6 2017/05/23 + * Version: @(#)net_ne2000.c 1.0.10 2017/06/03 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -38,9 +37,16 @@ #include "net_ne2000.h" #include "bswap.h" -#ifdef WALTJE -# define ENABLE_NE2000_LOG 2 -#endif + +/* ROM BIOS file paths. */ +#define ROM_PATH_NE1000 L"roms/network/ne1000/ne1000.rom" +#define ROM_PATH_NE2000 L"roms/network/ne2000/ne2000.rom" +#define ROM_PATH_RTL8029 L"roms/network/rtl8029as/rtl8029as.rom" + +/* PCI info. */ +#define PCI_VENDID 0x10ec /* Realtek, Inc */ +#define PCI_DEVID 0x8029 /* RTL8029AS */ +#define PCI_REGSIZE 256 /* size of PCI space */ /* For PCI. */ @@ -50,13 +56,6 @@ typedef union { } bar_t; -#if ENABLE_NE2000_LOG -static int nic_do_log = ENABLE_NE2000_LOG; -#else -static int nic_do_log = 0; -#endif - - /* Never completely fill the ne2k ring so that we never hit the unclear completely full buffer condition. */ #define NE2K_NEVER_FULL_RING (1) @@ -211,12 +210,13 @@ typedef struct { bios_size, bios_mask; bar_t pci_bar[2]; - uint8_t pci_regs[256]; + uint8_t pci_regs[PCI_REGSIZE]; int tx_timer_index; int tx_timer_active; uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; + int card; /* PCI card slot */ } nic_t; @@ -227,7 +227,7 @@ static void nic_tx(nic_t *, uint32_t); static void nelog(int lvl, const char *fmt, ...) { -#ifdef ENABLE_NE2000_LOG +#ifdef ENABLE_NIC_LOG va_list ap; if (nic_do_log >= lvl) { @@ -240,9 +240,26 @@ nelog(int lvl, const char *fmt, ...) } +static void +nic_interrupt(nic_t *dev, int set) +{ + if ((PCI && dev->is_pci) && (dev->base_irq == 0xff)) { + if (set) + pci_set_irq(dev->card, PCI_INTA); + else + pci_clear_irq(dev->card, PCI_INTA); + } else { + if (set) + picint(1<base_irq); + else + picintc(1<base_irq); + } +} + + /* reset - restore state to power-up, cancelling all i/o */ static void -nic_reset(void *priv, int reset) +nic_reset(void *priv) { nic_t *dev = (nic_t *)priv; int i; @@ -305,18 +322,29 @@ nic_reset(void *priv, int reset) dev->ISR.reset = 1; dev->DCR.longaddr = 1; - picint(1<base_irq); - picintc(1<base_irq); + nic_interrupt(dev, 0); } -/* chipmem_read/chipmem_write - access the 64K private RAM. - The ne2000 memory is accessed through the data port of - the asic (offset 0) after setting up a remote-DMA transfer. - Both byte and word accesses are allowed. - The first 16 bytes contains the MAC address at even locations, - and there is 16K of buffer memory starting at 16K -*/ +static void +nic_soft_reset(void *priv) +{ + nic_t *dev = (nic_t *)priv; + + memset(&(dev->ISR), 0x00, sizeof(dev->ISR)); + dev->ISR.reset = 1; +} + + +/* + * Access the 32K private RAM. + * + * The NE2000 memory is accessed through the data port of the + * ASIC (offset 0) after setting up a remote-DMA transfer. + * Both byte and word accesses are allowed. + * The first 16 bytes contains the MAC address at even locations, + * and there is 16K of buffer memory starting at 16K. + */ static uint32_t chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) { @@ -390,15 +418,19 @@ chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) } -/* asic_read/asic_write - This is the high 16 bytes of i/o space - (the lower 16 bytes is for the DS8390). Only two locations - are used: offset 0, which is used for data transfer, and - offset 0xf, which is used to reset the device. - The data transfer port is used to as 'external' DMA to the - DS8390. The chip has to have the DMA registers set up, and - after that, insw/outsw instructions can be used to move - the appropriate number of bytes to/from the device. -*/ +/* + * Access the ASIC I/O space. + * + * This is the high 16 bytes of i/o space (the lower 16 bytes + * is for the DS8390). Only two locations are used: offset 0, + * which is used for data transfer, and offset 0x0f, which is + * used to reset the device. + * + * The data transfer port is used to as 'external' DMA to the + * DS8390. The chip has to have the DMA registers set up, and + * after that, insw/outsw instructions can be used to move + * the appropriate number of bytes to/from the device. + */ static uint32_t asic_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -445,14 +477,13 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) /* If all bytes have been written, signal remote-DMA complete */ if (dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) { - picint(1 << dev->base_irq); - } + if (dev->IMR.rdma_inte) + nic_interrupt(dev, 1); } break; case 0x0f: /* Reset register */ - nic_reset(dev, 1); + nic_soft_reset(dev); break; default: @@ -468,7 +499,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) static void asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - nelog(3, "%s: asic write addr=0x%02x, value=0x%04x\n", + nelog(3, "%s: ASIC write addr=0x%02x, value=0x%04x\n", dev->name, (unsigned)off, (unsigned) val); switch(off) { case 0x00: /* Data register - see asic_read for a description */ @@ -505,9 +536,8 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) /* If all bytes have been written, signal remote-DMA complete */ if (dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) { - picint(1 << dev->base_irq); - } + if (dev->IMR.rdma_inte) + nic_interrupt(dev, 1); } break; @@ -523,8 +553,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page0_read/page0_write - These routines handle reads/writes to - the 'zeroth' page of the DS8390 register file */ +/* Handle reads/writes to the 'zeroth' page of the DS8390 register file. */ static uint32_t page0_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -714,9 +743,8 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) (dev->IMR.rxerr_inte << 2) | (dev->IMR.tx_inte << 1) | (dev->IMR.rx_inte)); - if (val == 0x00) { - picintc(1 << dev->base_irq); - } + if (val == 0x00) + nic_interrupt(dev, 0); break; case 0x08: /* RSAR0 */ @@ -834,11 +862,10 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) (dev->ISR.rx_err << 2) | (dev->ISR.pkt_tx << 1) | (dev->ISR.pkt_rx)); - if (((val & val2) & 0x7f) == 0) { - picintc(1 << dev->base_irq); - } else { - picint(1 << dev->base_irq); - } + if (((val & val2) & 0x7f) == 0) + nic_interrupt(dev, 0); + else + nic_interrupt(dev, 1); break; default: @@ -849,8 +876,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page1_read/page1_write - These routines handle reads/writes to - the first page of the DS8390 register file */ +/* Handle reads/writes to the first page of the DS8390 register file. */ static uint32_t page1_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -934,8 +960,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page2_read/page2_write - These routines handle reads/writes to - the second page of the DS8390 register file */ +/* Handle reads/writes to the second page of the DS8390 register file. */ static uint32_t page2_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -1078,7 +1103,7 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page3_read/page3_write - writes to this page are illegal */ +/* Writes to this page are illegal. */ static uint32_t page3_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -1108,8 +1133,7 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* read_cr/write_cr - utility routines for handling reads/writes to - the Command Register */ +/* Routines for handling reads/writes to the Command Register. */ static uint32_t read_cr(nic_t *dev) { @@ -1203,9 +1227,9 @@ write_cr(nic_t *dev, uint32_t val) if (dev->CR.rdma_cmd == 0x01 && dev->CR.start && dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; if (dev->IMR.rdma_inte) { - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); if (! dev->is_pci) - picintc(1 << dev->base_irq); + nic_interrupt(dev, 0); } } } @@ -1410,7 +1434,9 @@ nic_update_bios(nic_t *dev) dev->bios_addr, dev->bios_size); nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); } else { + nelog(1, "%s: BIOS disabled\n", dev->name); mem_mapping_disable(&dev->bios_rom.mapping); + dev->bios_addr = 0; if (dev->is_pci) dev->pci_bar[1].addr = 0; } @@ -1421,68 +1447,105 @@ static uint8_t nic_pci_read(int func, int addr, void *priv) { nic_t *dev = (nic_t *)priv; + uint8_t ret = 0x00; switch(addr) { - case 0x00: - return 0xec; - case 0x01: - return 0x10; + case 0x00: /* PCI_VID_LO */ + case 0x01: /* PCI_VID_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x02: - return 0x29; - case 0x03: - return 0x80; + case 0x02: /* PCI_DID_LO */ + case 0x03: /* PCI_DID_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x2C: - return 0xF4; - case 0x2D: - return 0x1A; - case 0x2E: - return 0x00; - case 0x2F: - return 0x11; + case 0x04: /* PCI_COMMAND_LO */ + case 0x05: /* PCI_COMMAND_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x04: - return dev->pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return dev->pci_regs[0x05]; + case 0x06: /* PCI_STATUS_LO */ + case 0x07: /* PCI_STATUS_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x07: - return 2; + case 0x08: /* PCI_REVID */ + ret = 0x00; /* Rev. 00 */ + break; + case 0x09: /* PCI_PIFR */ + ret = 0x00; /* Rev. 00 */ + break; - case 0x08: - return 0; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ + case 0x0A: /* PCI_SCR */ + ret = dev->pci_regs[addr]; + break; - case 0x0B: - return dev->pci_regs[0x0B]; + case 0x0B: /* PCI_BCR */ + ret = dev->pci_regs[addr]; + break; - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return dev->pci_bar[0].addr_regs[1]; - case 0x12: - return dev->pci_bar[0].addr_regs[2]; - case 0x13: - return dev->pci_bar[0].addr_regs[3]; + case 0x0C: /* (reserved) */ + ret = dev->pci_regs[addr]; + break; - case 0x30: - return dev->pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ - case 0x31: - return (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; - case 0x32: - return dev->pci_bar[1].addr_regs[2]; - case 0x33: - return dev->pci_bar[1].addr_regs[3]; + case 0x0D: /* PCI_LTR */ + case 0x0E: /* PCI_HTR */ + ret = dev->pci_regs[addr]; + break; - case 0x3C: - return dev->pci_regs[0x3C]; - case 0x3D: - return dev->pci_regs[0x3D]; + case 0x0F: /* (reserved) */ + ret = dev->pci_regs[addr]; + break; + + case 0x10: /* PCI_BAR 7:5 */ + ret = (dev->pci_bar[0].addr_regs[1] & 0xe0) | 0x01; + break; + case 0x11: /* PCI_BAR 15:8 */ + ret = dev->pci_bar[0].addr_regs[1]; + break; + case 0x12: /* PCI_BAR 23:16 */ + ret = dev->pci_bar[0].addr_regs[2]; + break; + case 0x13: /* PCI_BAR 31:24 */ + ret = dev->pci_bar[0].addr_regs[3]; + break; + + case 0x2C: /* PCI_SVID_LO */ + case 0x2D: /* PCI_SVID_HI */ + ret = dev->pci_regs[addr]; + break; + + case 0x2E: /* PCI_SID_LO */ + case 0x2F: /* PCI_SID_HI */ + ret = dev->pci_regs[addr]; + break; + + case 0x30: /* PCI_ROMBAR */ + ret = dev->pci_bar[1].addr_regs[0] & 0x01; + break; + case 0x31: /* PCI_ROMBAR 15:11 */ + ret = (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; + break; + case 0x32: /* PCI_ROMBAR 23:16 */ + ret = dev->pci_bar[1].addr_regs[2]; + break; + case 0x33: /* PCI_ROMBAR 31:24 */ + ret = dev->pci_bar[1].addr_regs[3]; + break; + + case 0x3C: /* PCI_ILR */ + ret = dev->pci_regs[addr]; + break; + + case 0x3D: /* PCI_IPR */ + ret = dev->pci_regs[addr]; + break; } - return 0; + nelog(2, "%s: PCI_Read(%d, %04x) = %02x\n", dev->name, func, addr, ret); + + return(ret); } @@ -1491,28 +1554,54 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) { nic_t *dev = (nic_t *)priv; + nelog(2, "%s: PCI_Write(%d, %04x, %02x)\n", dev->name, func, addr, val); + switch(addr) { - case 0x04: + case 0x04: /* PCI_COMMAND_LO */ + val &= 0x03; nic_ioremove(dev, dev->base_address); - if (val & PCI_COMMAND_IO) { + if (val & PCI_COMMAND_IO) nic_ioset(dev, dev->base_address); +#if 0 + if (val & PCI_COMMAND_MEMORY) { + ... } +#endif dev->pci_regs[addr] = val; break; - case 0x10: - val &= 0xfc; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O, if old base was >= 0x280. */ + case 0x0C: /* (reserved) */ + dev->pci_regs[addr] = val; + break; + + case 0x0D: /* PCI_LTR */ + dev->pci_regs[addr] = val; + break; + + case 0x0E: /* PCI_HTR */ + dev->pci_regs[addr] = val; + break; + + case 0x0F: /* (reserved) */ + dev->pci_regs[addr] = val; + break; + + case 0x10: /* PCI_BAR */ + val &= 0xfc; /* 0xe0 acc to RTL DS */ + val |= 0x01; /* re-enable IOIN bit */ + /*FALLTHROUGH*/ + + case 0x11: /* PCI_BAR + case 0x12: /* PCI_BAR + case 0x13: /* PCI_BAR */ + /* Remove old I/O. */ nic_ioremove(dev, dev->base_address); - /* Then let's set the PCI regs. */ + /* Set new I/O as per PCI request. */ dev->pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - dev->base_address = dev->pci_bar[0].addr & 0xff00; + dev->base_address = dev->pci_bar[0].addr & 0xffe0; /* Log the new base. */ nelog(1, "%s: PCI: new I/O base is %04X\n", @@ -1520,9 +1609,12 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) /* We're done, so get out of the here. */ if (val & PCI_COMMAND_IO) nic_ioset(dev, dev->base_address); - return; + break; - case 0x30: case 0x31: case 0x32: case 0x33: + case 0x30: /* PCI_ROMBAR */ + case 0x31: /* PCI_ROMBAR */ + case 0x32: /* PCI_ROMBAR */ + case 0x33: /* PCI_ROMBAR */ dev->pci_bar[1].addr_regs[addr & 3] = val; dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; dev->pci_bar[1].addr &= 0xffffe000; @@ -1531,38 +1623,17 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) nic_update_bios(dev); return; -#if 0 - /* Commented out until an APIC controller is emulated for - * the PIIX3, otherwise the RTL-8029/AS will not get an IRQ - * on boards using the PIIX3. */ - case 0x3C: - dev->pci_regs[addr] = val; - if (val != 0xFF) { - nelog(1, "%s: IRQ now: %i\n", dev->name, val); - dev->base_irq = irq; - } + case 0x3C: /* PCI_ILR */ + nelog(1, "%s: IRQ now: %i\n", dev->name, val); + dev->base_irq = val; + dev->pci_regs[addr] = dev->base_irq; return; -#endif - } -} - - -static void -nic_tx(nic_t *dev, uint32_t val) -{ - dev->CR.tx_packet = 0; - dev->TSR.tx_ok = 1; - dev->ISR.pkt_tx = 1; - - /* Generate an interrupt if not masked */ - if (dev->IMR.tx_inte) - picint(1 << dev->base_irq); - dev->tx_timer_active = 0; + } } /* - * mcast_index() - return the 6-bit index into the multicast + * Return the 6-bit index into the multicast * table. Stolen unashamedly from FreeBSD's if_ed.c */ static int @@ -1593,12 +1664,25 @@ mcast_index(const void *dst) } +static void +nic_tx(nic_t *dev, uint32_t val) +{ + dev->CR.tx_packet = 0; + dev->TSR.tx_ok = 1; + dev->ISR.pkt_tx = 1; + + /* Generate an interrupt if not masked */ + if (dev->IMR.tx_inte) + nic_interrupt(dev, 1); + dev->tx_timer_active = 0; +} + + /* - * rx_frame() - called by the platform-specific code when an - * ethernet frame has been received. The destination address - * is tested to see if it should be accepted, and if the - * rx ring has enough room, it is copied into it and - * the receive process is updated + * Called by the platform-specific code when an Ethernet frame + * has been received. The destination address is tested to see + * if it should be accepted, and if the RX ring has enough room, + * it is copied into it and the receive process is updated. */ static void nic_rx(void *priv, uint8_t *buf, int io_len) @@ -1616,8 +1700,10 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; - /* Add the pkt header + CRC to the length, and work - out how many 256-byte pages the frame would occupy */ + /* + * Add the pkt header + CRC to the length, and work + * out how many 256-byte pages the frame would occupy. + */ pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256; if (dev->curr_page < dev->bound_ptr) { avail = dev->bound_ptr - dev->curr_page; @@ -1626,9 +1712,11 @@ nic_rx(void *priv, uint8_t *buf, int io_len) (dev->curr_page - dev->bound_ptr); } - /* Avoid getting into a buffer overflow condition by not attempting - to do partial receives. The emulation to handle this condition - seems particularly painful. */ + /* + * Avoid getting into a buffer overflow condition by + * not attempting to do partial receives. The emulation + * to handle this condition seems particularly painful. + */ if ((avail < pages) #if NE2K_NEVER_FULL_RING || (avail == pages) @@ -1647,7 +1735,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (io_len < 60) io_len = 60; - nelog(2, "%s: rx_frame %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", + nelog(2, "%s: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name, buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], @@ -1659,7 +1747,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (! memcmp(buf, bcast_addr, 6)) { /* Broadcast not enabled, we're done. */ if (! dev->RCR.broadcast) { - nelog(2, "%s: rx_frame BC disabled\n", dev->name); + nelog(2, "%s: RX BC disabled\n", dev->name); return; } } @@ -1669,7 +1757,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Multicast not enabled, we're done. */ if (! dev->RCR.multicast) { #if 1 - nelog(2, "%s: rx_frame MC disabled\n", dev->name); + nelog(2, "%s: RX MC disabled\n", dev->name); #endif return; } @@ -1677,7 +1765,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Are we listening to this multicast address? */ idx = mcast_index(buf); if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) { - nelog(2, "%s: rx_frame MC not listed\n", dev->name); + nelog(2, "%s: RX MC not listed\n", dev->name); return; } } @@ -1685,7 +1773,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Unicast, must be for us.. */ else if (memcmp(buf, dev->physaddr, 6)) return; } else { - nelog(2, "%s: rx_frame promiscuous receive\n", dev->name); + nelog(2, "%s: RX promiscuous receive\n", dev->name); } nextpage = dev->curr_page + pages; @@ -1699,7 +1787,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) pkthdr[1] = nextpage; /* ptr to next packet */ pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */ pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */ - nelog(2, "%s: rx_frame pkthdr [%02x %02x %02x %02x]\n", + nelog(2, "%s: RX pkthdr [%02x %02x %02x %02x]\n", dev->name, pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]); /* Copy into buffer, update curpage, and signal interrupt if config'd */ @@ -1717,66 +1805,61 @@ nic_rx(void *priv, uint8_t *buf, int io_len) dev->curr_page = nextpage; dev->RSR.rx_ok = 1; - if (buf[0] & 0x80) - dev->RSR.rx_mbit = 1; + dev->RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0; dev->ISR.pkt_rx = 1; if (dev->IMR.rx_inte) - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); } static void nic_rom_init(nic_t *dev, wchar_t *s) { - FILE *f = romfopen(s, L"rb"); uint32_t temp; + FILE *f; - if (f == NULL) { - dev->bios_addr = 0x00000; - nic_update_bios(dev); - return; + if (dev->bios_addr > 0) { + if ((f = romfopen(s, L"rb")) != NULL) { + fseek(f, 0L, SEEK_END); + temp = ftell(f); + fclose(f); + dev->bios_size = 0x10000; + if (temp <= 0x8000) + dev->bios_size = 0x8000; + if (temp <= 0x4000) + dev->bios_size = 0x4000; + if (temp <= 0x2000) + dev->bios_size = 0x2000; + dev->bios_mask = (dev->bios_size >> 8) & 0xff; + dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; + } else { + dev->bios_addr = 0x00000; + dev->bios_size = 0; + return; + } + + /* Create a memory mapping for the space. */ + rom_init(&dev->bios_rom, s, dev->bios_addr, + dev->bios_size, dev->bios_size-1, 0, MEM_MAPPING_EXTERNAL); } - fseek(f, 0, SEEK_END); - temp = ftell(f); - fclose(f); - dev->bios_size = 0x10000; - if (temp <= 0x8000) - dev->bios_size = 0x8000; - if (temp <= 0x4000) - dev->bios_size = 0x4000; - if (temp <= 0x2000) - dev->bios_size = 0x2000; - dev->bios_mask = (dev->bios_size >> 8) & 0xff; - dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; - rom_init(&dev->bios_rom, s, dev->bios_addr, - dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); - - nelog(1, "%s: BIOS enabled at %06lX (size %ld)\n", + nelog(1, "%s: BIOS configured at %06lX (size %ld)\n", dev->name, dev->bios_addr, dev->bios_size); } -/* Return the 'local' part of our configured MAC address. */ -static uint32_t -nic_get_maclocal(nic_t *dev) -{ - uint32_t temp; - - temp = (((int) dev->maclocal[3]) << 16); - temp |= (((int) dev->maclocal[4]) << 8); - temp |= ((int) dev->maclocal[5]); - - return(temp); -} - - static void * nic_init(int board) { uint32_t mac; + wchar_t *rom; nic_t *dev; + int i; + + /* Get the desired debug level. */ + i = device_get_config_int("debug"); + if (i > 0) nic_do_log = i; dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); @@ -1787,6 +1870,7 @@ nic_init(int board) dev->maclocal[0] = 0x00; /* 00:00:D8 (NE1000 ISA OID) */ dev->maclocal[1] = 0x00; dev->maclocal[2] = 0xD8; + rom = ROM_PATH_NE1000; break; case NE2K_NE2000: @@ -1794,6 +1878,7 @@ nic_init(int board) dev->maclocal[0] = 0x00; /* 00:A0:0C (NE2000 compatible OID) */ dev->maclocal[1] = 0xA0; dev->maclocal[2] = 0x0C; + rom = ROM_PATH_NE2000; break; case NE2K_RTL8029AS: @@ -1802,43 +1887,113 @@ nic_init(int board) dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI OID) */ dev->maclocal[1] = 0x20; dev->maclocal[2] = 0x18; + rom = ROM_PATH_RTL8029; break; } - dev->base_irq = device_get_config_int("irq"); - if (dev->is_pci) + 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_irq = 10; + } else { + 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); + + /* Set up our BIOS ROM space, if any. */ + nic_rom_init(dev, rom); + + if (dev->is_pci) { + /* + * Configure the PCI space registers. + * + * We do this here, so the I/O routines are generic. + */ + dev->pci_regs[0x00] = (PCI_VENDID&0xff); + dev->pci_regs[0x01] = (PCI_VENDID>>8); + dev->pci_regs[0x02] = (PCI_DEVID&0xff); + dev->pci_regs[0x03] = (PCI_DEVID>>8); + + dev->pci_regs[0x04] = 0x01; /* IOEN */ + dev->pci_regs[0x05] = 0x00; + dev->pci_regs[0x07] = 0x02; /* DST0, medium devsel */ + + dev->pci_regs[0x0B] = 0x02; /* BCR: Network Controller */ + dev->pci_regs[0x0A] = 0x00; /* SCR: Ethernet */ + + dev->pci_regs[0x2C] = (PCI_VENDID&0xff); + dev->pci_regs[0x2D] = (PCI_VENDID>>8); + dev->pci_regs[0x2E] = (PCI_DEVID&0xff); + dev->pci_regs[0x2F] = (PCI_DEVID>>8); + + dev->pci_regs[0x3C] = dev->base_irq; /* PCI_ILR */ + dev->pci_regs[0x3D] = 0x01; /* PCI_IPR */ + + /* Enable our address space in PCI. */ + dev->pci_bar[0].addr_regs[0] = 0x01; + + /* Enable our BIOS space in PCI, if needed. */ + if (dev->bios_addr > 0) { + dev->pci_bar[1].addr = 0x000F8000; + dev->pci_bar[1].addr_regs[1] = dev->bios_mask; + dev->pci_bar[1].addr |= 0x1801; + } else { + dev->pci_bar[1].addr = 0; + } + + /* Initialize the RTL8029 EEPROM. */ + memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); + dev->eeprom[0x76] = + dev->eeprom[0x7A] = + dev->eeprom[0x7E] = (PCI_DEVID&0xff); + dev->eeprom[0x77] = + dev->eeprom[0x7B] = + dev->eeprom[0x7F] = (PCI_DEVID>>8); + dev->eeprom[0x78] = + dev->eeprom[0x7C] = (PCI_VENDID&0xff); + dev->eeprom[0x79] = + dev->eeprom[0x7D] = (PCI_VENDID>>8); + + /* Insert this device onto the PCI bus, keep its slot number. */ + dev->card = pci_add(nic_pci_read, nic_pci_write, dev); + } /* Set up our BIA. */ if (mac & 0xff000000) { - /* Generating new MAC. */ + /* Generate new local MAC. */ dev->maclocal[3] = disc_random_generate(); dev->maclocal[4] = disc_random_generate(); - dev->maclocal[5] = disc_random_generate() | 1; - device_set_config_int("mac", nic_get_maclocal(dev)); + dev->maclocal[5] = disc_random_generate(); + mac = (((int) dev->maclocal[3]) << 16); + mac |= (((int) dev->maclocal[4]) << 8); + mac |= ((int) dev->maclocal[5]); + device_set_config_mac("mac", mac); } else { dev->maclocal[3] = (mac>>16) & 0xff; dev->maclocal[4] = (mac>>8) & 0xff; - dev->maclocal[5] = (mac & 0xfe); + dev->maclocal[5] = (mac & 0xff); } memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); - nelog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + nelog(0, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->base_address, dev->base_irq, dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]); + /* Reset the board. */ + nic_reset(dev); + if (network_attach(dev, dev->physaddr, nic_rx) < 0) { #if 0 msgbox_error_wstr(ghwnd, L"Unable to init platform network"); #endif - nelog(1, "%s: unable to init platform network type %d\n", + nelog(0, "%s: unable to init platform network type %d\n", dev->name, network_type); #if 0 /* @@ -1852,56 +2007,7 @@ nic_init(int board) #endif } - if (dev->is_pci) - pci_add(nic_pci_read, nic_pci_write, dev); - nic_ioset(dev, dev->base_address); - - if (dev->bios_addr > 0) { - nic_rom_init(dev, dev->is_pci ? L"roms/rtl8029as.rom" - : L"roms/ne2000.rom"); - if (dev->is_pci) - mem_mapping_disable(&dev->bios_rom.mapping); - } - - if (dev->is_pci) { - dev->pci_regs[0x04] = 1; - dev->pci_regs[0x05] = 0; - dev->pci_regs[0x07] = 2; - - /* Network controller. */ - dev->pci_regs[0x0B] = 2; - - dev->pci_bar[0].addr_regs[0] = 1; - - if (dev->bios_addr > 0) { - /* What is it.. F800 or D000 (bios_addr) ? */ - dev->pci_bar[1].addr = 0x000F8000; - dev->pci_bar[1].addr_regs[1] = dev->bios_mask; - dev->pci_bar[1].addr |= 0x1801; - } else { - dev->pci_bar[1].addr = 0; - } - - dev->pci_regs[0x3C] = dev->base_irq; - nelog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]); - dev->pci_regs[0x3D] = 1; - - memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); - dev->eeprom[0x76] = - dev->eeprom[0x7A] = - dev->eeprom[0x7E] = 0x29; - dev->eeprom[0x77] = - dev->eeprom[0x7B] = - dev->eeprom[0x7F] = 0x80; - dev->eeprom[0x78] = - dev->eeprom[0x7C] = 0x10; - dev->eeprom[0x79] = - dev->eeprom[0x7D] = 0xEC; - } - - nic_reset(dev, 0); - - nelog(1, "%s: %s init 0x%X %d\n", dev->name, + nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); return(dev); @@ -1948,7 +2054,7 @@ rtl8029as_init(void) static device_config_t ne1000_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x300, + "base", "Address", CONFIG_HEX16, "", 0x300, { { "0x280", 0x280 @@ -1994,7 +2100,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 @@ -2003,7 +2109,10 @@ static device_config_t ne1000_config[] = "D000", 0xD0000 }, { - "C000", 0xC0000 + "D800", 0xD8000 + }, + { + "C800", 0xC8000 }, { "" @@ -2018,7 +2127,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 @@ -2070,7 +2179,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 @@ -2079,7 +2188,10 @@ static device_config_t ne2000_config[] = "D000", 0xD0000 }, { - "C000", 0xC0000 + "D800", 0xD8000 + }, + { + "C800", 0xC8000 }, { "" @@ -2093,34 +2205,15 @@ static device_config_t ne2000_config[] = static device_config_t rtl8029as_config[] = { +#if 1 + /* + * WTF. + * Even though it is PCI, the user should still have control + * over whether or not it's Option ROM BIOS will be enabled + * or not. + */ { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, - { - "mac", "MAC Address", CONFIG_MAC, "", -1 - }, - { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, { { "Disabled", 0x00000 @@ -2129,13 +2222,20 @@ static device_config_t rtl8029as_config[] = "D000", 0xD0000 }, { - "C000", 0xC0000 + "D800", 0xD8000 + }, + { + "C800", 0xC8000 }, { "" } }, }, +#endif + { + "mac", "MAC Address", CONFIG_MAC, "", -1 + }, { "", "", -1 } diff --git a/src/net_pcap.c b/src/net_pcap.c index a1b2292b0..8e2860be2 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.4 2017/05/23 + * Version: @(#)net_pcap.c 1.0.5 2017/06/04 * * Author: Fred N. van Kempen, */ @@ -19,10 +19,10 @@ #include #include "ibm.h" #include "config.h" -#include "thread.h" #include "device.h" #include "network.h" #include "plat_dynld.h" +#include "plat_thread.h" static void *pcap_handle; /* handle to WinPcap DLL */ @@ -144,6 +144,16 @@ network_pcap_init(netdev_t *list) } +/* Initialize the (Win)Pcap module for use. */ +void +network_pcap_reset(void) +{ + /* Try loading the DLL. */ + pcap_handle = dynld_module("wpcap.dll", pcap_imports); + return; +} + + /* Initialize WinPcap for us. */ int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) @@ -156,11 +166,26 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) /* Did we already load the DLL? */ if (pcap_handle == NULL) return(-1); +#if 1 + /* Get the value of our capture interface. */ + dev = network_pcap; + if (dev == NULL) { + pclog(" PCap device is a null pointer!\n"); + return(-1); + } + if ((dev[0] == '\0') || !strcmp(dev, "none")) { + pclog(" No network device configured!\n"); + return(-1); + } + pclog(" Network interface: '%s'\n", dev); +#endif + strcpy(temp, f_pcap_lib_version()); dev = strchr(temp, '('); if (dev != NULL) *(dev-1) = '\0'; pclog("PCAP: initializing, %s\n", temp); +#if 0 /* Get the value of our capture interface. */ dev = network_pcap; if ((dev[0] == '\0') || !strcmp(dev, "none")) { @@ -168,6 +193,9 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) return(-1); } pclog(" Network interface: '%s'\n", dev); +#else + dev = network_pcap; +#endif pcap = f_pcap_open_live(dev, /* interface name */ 1518, /* maximum packet size */ diff --git a/src/net_slirp.c b/src/net_slirp.c index 4659d3d45..f49167cbd 100644 --- a/src/net_slirp.c +++ b/src/net_slirp.c @@ -21,8 +21,8 @@ #include "ibm.h" #include "config.h" #include "device.h" -#include "thread.h" #include "network.h" +#include "plat_thread.h" static queueADT slirpq; /* SLiRP library handle */ diff --git a/src/network.c b/src/network.c index c4cd9c547..cd6cc3ea5 100644 --- a/src/network.c +++ b/src/network.c @@ -12,10 +12,9 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.6 2017/05/22 + * Version: @(#)network.c 1.0.9 2017/06/03 * - * Authors: Kotori, - * Fred N. van Kempen, + * Author: Fred N. van Kempen, */ #include #include @@ -47,6 +46,7 @@ static netcard_t net_cards[] = { int network_card; int network_type; int network_ndev; +int nic_do_log; netdev_t network_devs[32]; char network_pcap[512]; @@ -63,8 +63,16 @@ network_init(void) { int i; +#if ENABLE_NIC_LOG + nic_do_log = ENABLE_NIC_LOG; +#else + nic_do_log = 0; +#endif + +#if 0 network_type = NET_TYPE_NONE; network_card = 0; +#endif /* Create a first device entry that's always there, as needed by UI. */ strcpy(network_devs[0].device, "none"); @@ -75,6 +83,9 @@ network_init(void) i = network_pcap_init(&network_devs[network_ndev]); if (i > 0) network_ndev += i; + + if (network_type != NET_TYPE_PCAP) + network_pcap_close(); } @@ -101,7 +112,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, IDS_2219); network_type = NET_TYPE_NONE; } break; @@ -143,6 +154,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 +164,8 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; + if (network_type==NET_TYPE_PCAP) network_pcap_reset(); + 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/network.h b/src/network.h index b8b98e2ae..1c3e748a1 100644 --- a/src/network.h +++ b/src/network.h @@ -8,13 +8,12 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.5 2017/05/21 + * Version: @(#)network.h 1.0.7 2017/06/03 * - * Authors: Kotori, - * Fred N. van Kempen, + * Author: Fred N. van Kempen, */ -#ifndef NETWORK_H -# define NETWORK_H +#ifndef EMU_NETWORK_H +# define EMU_NETWORK_H # include @@ -48,6 +47,7 @@ typedef struct { /* Global variables. */ +extern int nic_do_log; extern int network_card; extern int network_type; extern int network_ndev; @@ -63,6 +63,7 @@ extern void network_reset(void); extern void network_tx(uint8_t *, int); extern int network_pcap_init(netdev_t *); +extern void network_pcap_reset(void); extern int network_pcap_setup(uint8_t *, NETRXCB, void *); extern void network_pcap_close(void); extern void network_pcap_in(uint8_t *, int); @@ -80,4 +81,4 @@ extern int network_card_get_from_internal_name(char *); extern device_t *network_card_getdevice(int); -#endif /*NETWORK_H*/ +#endif /*EMU_NETWORK_H*/ diff --git a/src/nvr.c b/src/nvr.c index f3490260a..8862ec08f 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CMOS NVRAM emulation. + * + * Version: @(#)nvr.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Mahod, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 Mahod. + */ #include #include "ibm.h" #include "io.h" @@ -19,12 +38,12 @@ static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; static int rtctime; -void getnvrtime() +void getnvrtime(void) { time_get(nvrram); } -void nvr_recalc() +void nvr_recalc(void) { int c; int newrtctime; @@ -184,7 +203,7 @@ uint8_t readnvr(uint16_t addr, void *priv) return nvraddr; } -void loadnvr() +void loadnvr(void) { FILE *f; int c; @@ -245,6 +264,7 @@ void loadnvr() case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"rb"); nvrmask = 127; break; case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"rb"); nvrmask = 127; break; case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"rb"); nvrmask = 127; break; default: return; } if (!f) @@ -271,7 +291,7 @@ void loadnvr() c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); } -void savenvr() +void savenvr(void) { FILE *f; switch (oldromset) @@ -329,13 +349,14 @@ void savenvr() case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"wb"); break; case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"wb"); break; case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"wb"); break; + case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"wb"); break; default: return; } fwrite(nvrram,128,1,f); fclose(f); } -void nvr_init() +void nvr_init(void) { io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL); timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL); diff --git a/src/nvr.h b/src/nvr.h index 069a476a7..0c7780240 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -1,15 +1,35 @@ -/* Copyright holders: Mahod, Tenshi - see COPYING for more details -*/ -void nvr_init(); +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CMOS NVRAM emulation. + * + * Version: @(#)nvr.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Mahod, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 Mahod. + */ +#ifndef EMU_NVR_H +# define EMU_NVR_H + extern int enable_sync; - extern int nvr_dosave; -void time_get(char *nvrram); -void nvr_recalc(); +extern void nvr_init(void); +extern void time_get(char *nvrram); +extern void nvr_recalc(void); +extern void loadnvr(void); +extern void savenvr(void); -void loadnvr(); -void savenvr(); + +#endif /*EMU_NVR_H*/ diff --git a/src/pc.c b/src/pc.c index 66e0bb4ef..f60a03a3e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -1,9 +1,24 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation core dispatcher. + * + * Version: @(#)pc.c 1.0.3 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include #include + #include "86box.h" #include "ibm.h" #include "mem.h" @@ -49,6 +64,7 @@ #include "sound/sound.h" #include "sound/snd_cms.h" #include "sound/snd_dbopl.h" +#include "sound/snd_mpu401.h" #include "sound/snd_opl.h" #include "sound/snd_gus.h" #include "sound/snd_sb.h" @@ -64,6 +80,8 @@ #endif +wchar_t pcempath[512]; + wchar_t nvr_path[1024]; int path_len; @@ -261,8 +279,6 @@ void pc_reset(void) setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); else setpitclock(14318184.0); - - ali1429_reset(); } @@ -271,7 +287,7 @@ void initpc(int argc, wchar_t *argv[]) { wchar_t *p; wchar_t *config_file = NULL; - int c, i; + int c; FILE *ff; get_executable_name(pcempath, 511); pclog("executable_name = %ws\n", pcempath); @@ -330,16 +346,9 @@ void initpc(int argc, wchar_t *argv[]) } } - /* Initialize modules. */ - network_init(); - mouse_init(); - midi_init(); - serial_init(); - disc_random_init(); - if (config_file == NULL) { - append_filename_w(config_file_default, pcempath, L"86box.cfg", 511); + append_filename_w(config_file_default, pcempath, CONFIG_FILE_W, 511); } else { @@ -348,8 +357,22 @@ void initpc(int argc, wchar_t *argv[]) loadconfig(config_file); pclog("Config loaded\n"); +#if 0 if (config_file) saveconfig(); +#endif +} + +void initmodules(void) +{ + int i; + + /* Initialize modules. */ + network_init(); + mouse_init(); + midi_init(); + serial_init(); + disc_random_init(); joystick_init(); @@ -374,20 +397,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,21 +432,17 @@ void initpc(int argc, wchar_t *argv[]) scsi_card_init(); fullspeed(); - ali1429_reset(); shadowbios=0; for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].host_drive != 0) + if (cdrom_drives[i].host_drive == 200) { - if (cdrom_drives[i].host_drive == 200) - { - image_reset(i); - } - else - { - ioctl_reset(i); - } + image_reset(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_reset(i); } } } @@ -468,7 +484,9 @@ void resetpchard(void) suppress_overscan = 0; savenvr(); +#if 0 saveconfig(); +#endif device_close_all(); mouse_emu_close(); @@ -501,18 +519,12 @@ void resetpchard(void) ide_qua_init(); } - for (i = 0; i < CDROM_NUM; i++) - { - if (cdrom_drives[i].bus_type) - { - SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); - } - } - resetide(); scsi_card_init(); sound_card_init(); + if (mpu401_standalone_enable) + mpu401_device_add(); if (GUS) device_add(&gus_device); if (GAMEBLASTER) @@ -528,7 +540,6 @@ void resetpchard(void) loadnvr(); shadowbios = 0; - ali1429_reset(); keyboard_at_reset(); @@ -536,16 +547,13 @@ void resetpchard(void) for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].host_drive != 0) + if (cdrom_drives[i].host_drive == 200) { - if (cdrom_drives[i].host_drive == 200) - { - image_reset(i); - } - else - { - ioctl_reset(i); - } + image_reset(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_reset(i); } } @@ -651,7 +659,7 @@ void runpc(void) win_title_update=0; mbstowcs(wmodel, model_getname(), strlen(model_getname()) + 1); mbstowcs(wcpu, models[model].cpu[cpu_manufacturer].cpus[cpu].name, strlen(models[model].cpu[cpu_manufacturer].cpus[cpu].name) + 1); - _swprintf(s, L"86Box v%s - %i%% - %s - %s - %s", emulator_version_w, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); + _swprintf(s, L"%s v%s - %i%% - %s - %s - %s", EMU_NAME_W, EMU_VERSION_W, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); set_window_title(s); } done++; @@ -689,10 +697,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/pc87306.c b/src/pc87306.c index c0a6bb7d1..c0887451b 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -1,10 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ /* - National Semiconductors PC87306 Super I/O Chip - Used by Intel Advanced/EV -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the National Semiconductors PC87306 Super I/O + * chip. + * + * Version: @(#)pc87306.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/pc87306.h b/src/pc87306.h index 0f48f3d97..d1891fdd8 100644 --- a/src/pc87306.h +++ b/src/pc87306.h @@ -1,4 +1,18 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the National Semiconductors PC87306 Super I/O + * chip. + * + * Version: @(#)pc87306.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void pc87306_init(); diff --git a/src/pcap/libwpcapdelay.a b/src/pcap/libwpcapdelay.a deleted file mode 100644 index c9d175845..000000000 Binary files a/src/pcap/libwpcapdelay.a and /dev/null differ diff --git a/src/pcap_if.c b/src/pcap_if.c index 588ee01e8..3cf321a9d 100644 --- a/src/pcap_if.c +++ b/src/pcap_if.c @@ -10,14 +10,35 @@ * * Based on the "libpcap" examples. * - * Version: @(#)pcap_if.c 1.0.2 2017/05/09 + * Version: @(#)pcap_if.c 1.0.3 2017/06/04 * * Author: Fred N. van Kempen, */ #include #include +#include #include #include +#include "plat_dynld.h" + + +static void *pcap_handle; /* handle to WinPcap DLL */ + + +/* Pointers to the real functions. */ +static int (*f_pcap_findalldevs)(pcap_if_t **,char *); +static void (*f_pcap_freealldevs)(pcap_if_t *); +static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); +static int (*f_pcap_next_ex)(pcap_t*,struct pcap_pkthdr**,const unsigned char**); +static void (*f_pcap_close)(pcap_t *); +static dllimp_t pcap_imports[] = { + { "pcap_findalldevs", &f_pcap_findalldevs }, + { "pcap_freealldevs", &f_pcap_freealldevs }, + { "pcap_open_live", &f_pcap_open_live }, + { "pcap_next_ex", &f_pcap_next_ex }, + { "pcap_close", &f_pcap_close }, + { NULL, NULL }, +}; typedef struct { @@ -35,7 +56,7 @@ get_devlist(dev_t *list) int i = 0; /* Retrieve the device list from the local machine */ - if (pcap_findalldevs(&devlist, errbuf) == -1) { + if (f_pcap_findalldevs(&devlist, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); return(-1); } @@ -51,7 +72,7 @@ get_devlist(dev_t *list) } /* Release the memory. */ - pcap_freealldevs(devlist); + f_pcap_freealldevs(devlist); return(i); } @@ -130,11 +151,11 @@ start_cap(char *dev) int rc; /* Open the device for reading from it. */ - pcap = pcap_open_live(dev, - 1518, /* MTU */ - 1, /* promisc mode */ - 10, /* timeout */ - temp); + pcap = f_pcap_open_live(dev, + 1518, /* MTU */ + 1, /* promisc mode */ + 10, /* timeout */ + temp); if (pcap == NULL) { fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); return(2); @@ -142,7 +163,7 @@ start_cap(char *dev) printf("Listening on '%s'..\n", dev); for (;;) { - rc = pcap_next_ex(pcap, &hdr, &pkt); + rc = f_pcap_next_ex(pcap, &hdr, &pkt); if (rc < 0) break; /* Did we time out? */ @@ -161,7 +182,7 @@ start_cap(char *dev) } /* All done, close up. */ - pcap_close(pcap); + f_pcap_close(pcap); return(0); } @@ -191,6 +212,17 @@ show_devs(dev_t *list, int num) } +void +pclog(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + + int main(int argc, char **argv) { @@ -198,6 +230,13 @@ main(int argc, char **argv) dev_t *dev = interfaces; int numdev, i; + /* Try loading the DLL. */ + pcap_handle = dynld_module("wpcap.dll", pcap_imports); + if (pcap_handle == NULL) { + fprintf(stderr, "Unable to load WinPcap DLL !\n"); + return(1); + } + /* Get the list. */ numdev = get_devlist(interfaces); @@ -205,6 +244,8 @@ main(int argc, char **argv) /* No arguments, just show the list. */ show_devs(interfaces, numdev); + dynld_close(pcap_handle); + return(numdev); } @@ -213,11 +254,15 @@ main(int argc, char **argv) if (i < 0 || i > numdev) { fprintf(stderr, "Invalid interface number %d !\n", i); + dynld_close(pcap_handle); + return(1); } /* Looks good, go and listen.. */ i = start_cap(interfaces[i-1].device); + dynld_close(pcap_handle); + return(i); } diff --git a/src/pci.c b/src/pci.c index 73b056118..4edd4b14f 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,19 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include - #include "ibm.h" #include "io.h" #include "mem.h" +#include "pic.h" #include "pci.h" void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv); uint8_t (*pci_card_read[32])(int func, int addr, void *priv); void *pci_priv[32]; -static uint8_t pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; -static int pci_min_card, pci_max_card; +static int pci_irq_routing[32]; +static int pci_irq_active[32]; +static int pci_irqs[4]; +static int pci_card_valid[32]; + +static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; int pci_burst_time, pci_nonburst_time; void pci_cf8_write(uint16_t port, uint32_t val, void *p) @@ -37,7 +37,7 @@ void pci_write(uint16_t port, uint8_t val, void *priv) case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return; - + if (!pci_bus && pci_card_write[pci_card]) pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); @@ -57,10 +57,22 @@ uint8_t pci_read(uint16_t port, void *priv) return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); return 0xff; - - default: - return 0xff; } + return 0xff; +} + +uint8_t elcr[2] = { 0, 0 }; + +void elcr_write(uint16_t port, uint8_t val, void *priv) +{ + /* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */ + elcr[port & 1] = val; +} + +uint8_t elcr_read(uint16_t port, void *priv) +{ + /* pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */ + return elcr[port & 1]; } void pci_type2_write(uint16_t port, uint8_t val, void *priv); @@ -111,12 +123,72 @@ uint8_t pci_type2_read(uint16_t port, void *priv) } return 0xff; } - -void pci_init(int type, int min_card, int max_card) + +void pci_set_irq_routing(int pci_int, int irq) +{ + pci_irqs[pci_int - 1] = irq; +} + +void pci_set_card_routing(int card, int pci_int) +{ + pci_irq_routing[card] = pci_int; +} + +void pci_issue_irq(int irq) +{ + int real_irq = irq & 7; + int irq_elcr = 0; + + if (irq > 7) + { + irq_elcr = elcr[1] & (1 << real_irq); + } + else + { + irq_elcr = elcr[0] & (1 << real_irq); + } + + if (irq_elcr) + { + /* picintlevel(1 << irq); */ + picint(1 << irq); + } + else + { + picint(1 << irq); + } +} + +void pci_set_irq(int card, int pci_int) +{ + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) + pci_issue_irq(pci_irqs[irq]); + /* picint(1 << pci_irqs[irq]); */ + pci_irq_active[card] = 1; + } +} + +void pci_clear_irq(int card, int pci_int) +{ + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) + picintc(1 << pci_irqs[irq]); + pci_irq_active[card] = 0; + } +} + +void pci_init(int type) { int c; PCI = 1; + + io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL); if (type == PCI_CONFIG_TYPE_1) { @@ -130,14 +202,22 @@ void pci_init(int type, int min_card, int max_card) } for (c = 0; c < 32; c++) - { - pci_card_read[c] = NULL; - pci_card_write[c] = NULL; - pci_priv[c] = NULL; - } + { + pci_card_read[c] = NULL; + pci_card_write[c] = NULL; + pci_priv[c] = NULL; + pci_irq_routing[c] = 0; + pci_irq_active[c] = 0; + pci_card_valid[c] = 0; + } - pci_min_card = min_card; - pci_max_card = max_card; + for (c = 0; c < 4; c++) + pci_irqs[c] = PCI_IRQ_DISABLED; +} + +void pci_slot(int card) +{ + pci_card_valid[card] = 1; } void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) @@ -147,18 +227,20 @@ void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), pci_priv[card] = priv; } -void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { int c; - for (c = pci_min_card; c <= pci_max_card; c++) + for (c = 0; c < 32; c++) { - if (!pci_card_read[c] && !pci_card_write[c]) + if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) { pci_card_read[c] = read; pci_card_write[c] = write; pci_priv[c] = priv; - return; + return c; } } + + return -1; } diff --git a/src/pci.h b/src/pci.h index 6c6782e23..6a8778e0f 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,9 +1,11 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void pci_init(int type, int min_card, int max_card); +void pci_init(int type); +void pci_slot(int card); void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); -void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +void pci_set_irq_routing(int card, int irq); +void pci_set_card_routing(int card, int pci_int); +void pci_set_irq(int card, int pci_int); +void pci_clear_irq(int card, int pci_int); #define PCI_REG_COMMAND 0x04 @@ -13,4 +15,11 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 +#define PCI_INTA 1 +#define PCI_INTB 2 +#define PCI_INTC 3 +#define PCI_INTD 4 + +#define PCI_IRQ_DISABLED -1 + extern int pci_burst_time, pci_nonburst_time; diff --git a/src/pic.c b/src/pic.c index 128089924..7c20125e9 100644 --- a/src/pic.c +++ b/src/pic.c @@ -8,6 +8,8 @@ int intclear; int keywaiting=0; int pic_intpending; +PIC pic, pic2; + void pic_updatepending() { uint16_t temp_pending = 0; diff --git a/src/piix.c b/src/piix.c index 04cf62418..584f1ccc3 100644 --- a/src/piix.c +++ b/src/piix.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the Intel PIIX and PIIX3 Xcelerators. + * + * Emulation core dispatcher. + * + * Version: @(#)piix.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*PRD format : word 0 - base address @@ -92,12 +107,45 @@ void piix_write(int func, int addr, uint8_t val, void *priv) } else { + /* pclog("PIIX writing value %02X to register %02X\n", val, addr); */ + if ((addr >= 0x0f) && (addr < 0x4c)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0e: return; + + case 0x60: + pclog("Set IRQ routing: INT A -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + pclog("Set IRQ routing: INT B -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x62: + pclog("Set IRQ routing: INT C -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x63: + pclog("Set IRQ routing: INT D -> %02X\n", val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } if (addr == 0x4C) { @@ -561,7 +609,7 @@ void piix_reset(void) card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ card_piix[0x02] = 0x2e; card_piix[0x03] = 0x12; /*82371FB (PIIX)*/ card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; - card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; + card_piix[0x06] = 0x80; card_piix[0x07] = 0x02; card_piix[0x08] = 0x00; /*A0 stepping*/ card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; card_piix[0x0e] = 0x80; /*Multi-function device*/ @@ -589,7 +637,6 @@ void piix_reset(void) card_piix_ide[0x0d] = 0x00; card_piix_ide[0x0e] = 0x00; card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ - card_piix_ide[0x3c] = 14; /* Default IRQ */ card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; } @@ -600,7 +647,7 @@ void piix3_reset(void) card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ card_piix[0x02] = 0x00; card_piix[0x03] = 0x70; /*82371SB (PIIX3)*/ card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; - card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; + card_piix[0x06] = 0x80; card_piix[0x07] = 0x02; card_piix[0x08] = 0x00; /*A0 stepping*/ card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; card_piix[0x0e] = 0x80; /*Multi-function device*/ @@ -629,13 +676,12 @@ void piix3_reset(void) card_piix_ide[0x0d] = 0x00; card_piix_ide[0x0e] = 0x00; card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ - card_piix_ide[0x3c] = 14; /* Default IRQ */ card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; card_piix_ide[0x44] = 0x00; } -void piix_init(int card) +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -654,9 +700,14 @@ void piix_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = piix_reset; + + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); } -void piix3_init(int card) +void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -675,4 +726,9 @@ void piix3_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = piix3_reset; + + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/piix.h b/src/piix.h index c86a680ce..a922ff41e 100644 --- a/src/piix.h +++ b/src/piix.h @@ -1,8 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -void piix_init(int card); -void piix3_init(int card); +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the Intel PIIX and PIIX3 Xcelerators. + * + * Emulation core dispatcher. + * + * Version: @(#)piix.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); +void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); uint8_t piix_bus_master_read(uint16_t port, void *priv); void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); diff --git a/src/pit.c b/src/pit.c index b735656a5..53169d27f 100644 --- a/src/pit.c +++ b/src/pit.c @@ -25,6 +25,11 @@ double PITCONST; float cpuclock; float isa_timing, bus_timing; +float CGACONST; +float MDACONST; +float VGACONST1,VGACONST2; +float RTCCONST; + int firsttime=1; void setpitclock(float clock) { diff --git a/src/ppi.c b/src/ppi.c index e5d5a27ec..dfb315e2c 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -13,6 +13,9 @@ #include "plat_keyboard.h" #include "plat_mouse.h" +PPI ppi; +int ppispeakon; + void ppi_reset() { ppi.pa=0x0; diff --git a/src/ps1.c b/src/ps1.c index d54df75af..97b319e75 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -304,3 +304,23 @@ void ps1mb_m2121_init() mem_remap_top_384k(); } + +void ps1mb_m2133_init() +{ + io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0094, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + + ps1_190 = 0; + + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); + + serial_remove(1); + serial_remove(2); + + mem_remap_top_384k(); +} diff --git a/src/ps1.h b/src/ps1.h index d58466d69..506983665 100644 --- a/src/ps1.h +++ b/src/ps1.h @@ -3,3 +3,4 @@ */ void ps1mb_init(); void ps1mb_m2121_init(); +void ps1mb_m2133_init(); diff --git a/src/scsi.c b/src/scsi.c index c01458d44..4a2ce29fb 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -120,4 +120,10 @@ void SCSIReset(uint8_t id, uint8_t lun) SCSIDevices[id][lun].LunType = SCSI_NONE; } } + + if(SCSIDevices[id][lun].CmdBuffer != NULL) + { + free(SCSIDevices[id][lun].CmdBuffer); + SCSIDevices[id][lun].CmdBuffer = NULL; + } } diff --git a/src/scsi.h b/src/scsi.h index 2c9280c29..8c3efc3b5 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 */ @@ -224,7 +230,7 @@ extern int prev_status; struct { - uint8_t CmdBuffer[390144]; + uint8_t *CmdBuffer; uint32_t CmdBufferLength; int LunType; uint32_t InitLength; diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 7babc817a..72f615843 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -15,7 +15,7 @@ * Version: @(#)scsi_aha154x.c 1.0.6 2017/05/06 * * Authors: Fred N. van Kempen, - * Original Buslogic version by SA1988. + * Original Buslogic version by SA1988 and Miran Grca. * Copyright 2017 Fred N. van Kempen. */ #include @@ -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 @@ -1114,6 +1090,7 @@ aha_buf_alloc(Req_t *req, int Is24bit) uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t Address; if (Is24bit) { DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); @@ -1125,6 +1102,12 @@ aha_buf_alloc(Req_t *req, int Is24bit) pclog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { @@ -1142,8 +1125,6 @@ aha_buf_alloc(Req_t *req, int Is24bit) aha_rd_sge(Is24bit, SGAddrCurrent, SGRead, SGBuffer); for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - uint32_t Address; - pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); Address = SGBuffer[ScatterEntry].SegmentPointer; @@ -1159,6 +1140,10 @@ aha_buf_alloc(Req_t *req, int Is24bit) SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + pclog("Allocating buffer for Scatter/Gather (%i bytes)\n", DataToTransfer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer); + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without checking its length, so do this procedure for both no read/write commands. */ if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || @@ -1174,8 +1159,6 @@ aha_buf_alloc(Req_t *req, int Is24bit) SGRead, SGBuffer); for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - uint32_t Address; - pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); Address = SGBuffer[ScatterEntry].SegmentPointer; @@ -1192,9 +1175,14 @@ aha_buf_alloc(Req_t *req, int Is24bit) } } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { - uint32_t Address = DataPointer; + Address = DataPointer; SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + + pclog("Allocating buffer for direct transfer (%i bytes)\n", DataLength); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); + if (DataLength > 0) { DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, @@ -1219,6 +1207,7 @@ aha_buf_free(Req_t *req) uint32_t SGAddrCurrent; uint32_t Address; uint32_t Residual; + uint32_t DataToTransfer; if (req->Is24bit) { DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); @@ -1259,9 +1248,6 @@ aha_buf_free(Req_t *req) SGRead, SGBuffer); for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - uint32_t Address; - uint32_t DataToTransfer; - pclog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); Address = SGBuffer[ScatterEntry].SegmentPointer; @@ -1304,6 +1290,12 @@ aha_buf_free(Req_t *req) req->CmdBlock.new.DataLength); } } + + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } } @@ -1355,39 +1347,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 +1713,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 +1785,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 +1871,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); @@ -2006,9 +1971,6 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) SCSIStatus = SCSI_STATUS_OK; SCSIDevices[Id][Lun].InitLength = 0; - /* Do this here, so MODE SELECT data does not get lost in transit. */ - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - aha_buf_alloc(req, req->Is24bit); if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { @@ -2220,11 +2182,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, @@ -2242,13 +2204,12 @@ aha_init(int chip, int has_bios) if (scsi_hard_disks[i][j] != 0xff) { SCSIDevices[i][j].LunType = SCSI_DISK; } - } - } - - for (i=0; i + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + */ #include #include #include @@ -22,6 +34,7 @@ #include "timer.h" #include "device.h" #include "scsi.h" +#include "scsi_disk.h" #include "cdrom.h" #include "scsi_buslogic.h" @@ -476,6 +489,7 @@ typedef struct { int Lock; mem_mapping_t mmio_mapping; int chip; + int Card; } Buslogic_t; #pragma pack(pop) @@ -492,15 +506,7 @@ enum { }; -#ifdef WALTJE -int buslogic_do_log = 1; -# define ENABLE_BUSLOGIC_LOG -#else int buslogic_do_log = 0; -#endif - - -static void BuslogicStartMailbox(Buslogic_t *); static void @@ -520,18 +526,46 @@ BuslogicLog(const char *format, ...) #define pclog BuslogicLog +static void +BuslogicInterrupt(Buslogic_t *bl, int set) +{ + if ((bl->chip != CHIP_BUSLOGIC_PCI) || (bl->Irq != 255)) + { + if (set) + { + picint(1 << bl->Irq); + } + else + { + picintc(1 << bl->Irq); + } + } + else + { + if (set) + { + pci_set_irq(bl->Card, PCI_INTA); + } + else + { + pci_clear_irq(bl->Card, PCI_INTA); + } + } +} + + static void BuslogicClearInterrupt(Buslogic_t *bl) { pclog("Buslogic: Lowering Interrupt 0x%02X\n", bl->Interrupt); bl->Interrupt = 0; pclog("Lowering IRQ %i\n", bl->Irq); - picintc(1 << bl->Irq); + BuslogicInterrupt(bl, 0); if (bl->PendingInterrupt) { bl->Interrupt = bl->PendingInterrupt; pclog("Buslogic: Raising Interrupt 0x%02X (Pending)\n", bl->Interrupt); if (bl->MailboxOutInterrupts || !(bl->Interrupt & INTR_MBOA)) { - if (bl->IrqEnabled) picint(1 << bl->Irq); + if (bl->IrqEnabled) BuslogicInterrupt(bl, 1); } bl->PendingInterrupt = 0; } @@ -621,7 +655,7 @@ BuslogicCommandComplete(Buslogic_t *bl) bl->Interrupt = (INTR_ANY | INTR_HACC); pclog("Raising IRQ %i\n", bl->Irq); if (bl->IrqEnabled) - picint(1 << bl->Irq); + BuslogicInterrupt(bl, 1); } bl->Command = 0xFF; @@ -639,7 +673,7 @@ BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) bl->Interrupt = Interrupt; pclog("Raising IRQ %i\n", bl->Irq); if (bl->IrqEnabled) - picint(1 << bl->Irq); + BuslogicInterrupt(bl, 1); } } @@ -759,6 +793,12 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) pclog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { @@ -793,6 +833,9 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer); + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without checking its length, so do this procedure for both no read/write commands. */ if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || @@ -829,6 +872,10 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) uint32_t Address = DataPointer; SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); + if (DataLength > 0) { DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, @@ -938,6 +985,12 @@ BuslogicDataBufferFree(Req_t *req) req->CmdBlock.new.DataLength); } } + + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } } @@ -998,20 +1051,6 @@ BuslogicReadL(uint16_t Port, void *p) } -/* This is BS - we just need a 'dev_present' indication.. --FvK */ -static int -buslogic_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 BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); static void @@ -1020,7 +1059,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 +1168,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 +1183,7 @@ aha_0x01: bl->Status &= ~STAT_INIT; bl->DataReplyLeft = 0; - } - break; + break; case 0x03: bl->DataBuf[0] = 0x00; @@ -1210,7 +1245,14 @@ aha_0x01: case 0x0B: bl->DataBuf[0] = (1 << bl->DmaChannel); - bl->DataBuf[1] = (1<<(bl->Irq-9)); + if ((bl->Irq >= 9) && (bl->Irq <= 15)) + { + bl->DataBuf[1] = (1<<(bl->Irq-9)); + } + else + bl->DataBuf[1] = 0; + { + } bl->DataBuf[2] = 7; /* HOST ID */ bl->DataReplyLeft = 3; break; @@ -1324,7 +1366,7 @@ aha_0x01: else bl->IrqEnabled = 1; pclog("Lowering IRQ %i\n", bl->Irq); - picintc(1 << bl->Irq); + BuslogicInterrupt(bl, 0); break; case 0x81: @@ -1633,6 +1675,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 +1761,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); @@ -1815,9 +1861,6 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb SCSIStatus = SCSI_STATUS_OK; SCSIDevices[Id][Lun].InitLength = 0; - /* Do this here, so MODE SELECT data does not get lost in transit. */ - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - BuslogicDataBufferAllocate(req, req->Is24bit); if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { @@ -1913,7 +1956,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)); } @@ -2082,7 +2125,7 @@ BuslogicPCIRead(int func, int addr, void *p) case 0x3C: return bl->Irq; case 0x3D: - return 1; + return PCI_INTA; } return(0); @@ -2093,16 +2136,17 @@ static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) { Buslogic_t *bl = (Buslogic_t *)p; + uint8_t valxor; switch (addr) { case 0x04: - io_removehandler(bl->PCIBase, 4, + valxor = (val & 0x27) ^ buslogic_pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) { + io_removehandler(bl->PCIBase, 4, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, bl); - mem_mapping_disable(&bl->mmio_mapping); - if (val & PCI_COMMAND_IO) { - if (bl->PCIBase != 0) { + if ((bl->PCIBase != 0) && (val & PCI_COMMAND_IO)) { io_sethandler(bl->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, @@ -2110,13 +2154,14 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) bl); } } - if (val & PCI_COMMAND_MEM) { - if (bl->PCIBase != 0) { + if (valxor & PCI_COMMAND_MEM) { + mem_mapping_disable(&bl->mmio_mapping); + if ((bl->MMIOBase != 0) & (val & PCI_COMMAND_MEM)) { mem_mapping_set_addr(&bl->mmio_mapping, bl->MMIOBase, 0x20); } } - buslogic_pci_regs[addr] = val; + buslogic_pci_regs[addr] = val & 0x27; break; case 0x10: @@ -2170,18 +2215,13 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } return; -#if 0 - /* Commented out until an APIC controller is emulated for the PIIX3, - * otherwise the BT-958 will not get an IRQ on boards using the PIIX3. - */ case 0x3C: buslogic_pci_regs[addr] = val; if (val != 0xFF) { - buslogic_log("BusLogic IRQ now: %i\n", val); + BuslogicLog("BusLogic IRQ now: %i\n", val); bl->Irq = val; } return; -#endif } } @@ -2203,7 +2243,7 @@ BuslogicInit(int chip) chip = CHIP_BUSLOGIC_ISA; } bl->chip = chip; - bl->Base = device_get_config_int("addr"); + bl->Base = device_get_config_hex16("base"); bl->PCIBase = 0; bl->MMIOBase = 0; bl->Irq = device_get_config_int("irq"); @@ -2228,19 +2268,16 @@ BuslogicInit(int chip) build_scsi_cdrom_map(); for (i=0; i<16; i++) { - for (j=0; j<8; j++) - { - if (scsi_hard_disks[i][j] != 0xff) - { + for (j=0; j<8; j++) { + if (scsi_hard_disks[i][j] != 0xff) { SCSIDevices[i][j].LunType = SCSI_DISK; } - } - } - - for (i=0; immio_mapping, 0xfffd0000, 0x20, @@ -2299,7 +2338,7 @@ BuslogicClose(void *p) static device_config_t BuslogicConfig[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x334, + "base", "Address", CONFIG_HEX16, "", 0x334, { { "None", 0 diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h index c2d5dccc5..c952e06d1 100644 --- a/src/scsi_buslogic.h +++ b/src/scsi_buslogic.h @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI + * controllers. + * + * Version: @(#)scsi_buslogic.h 1.0.0 2017/05/30 + * + * Author: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + */ + #ifndef SCSI_BUSLOGIC_H # define SCSI_BUSLOGIC_H diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 26f900e55..69726cf0b 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -1,8 +1,21 @@ -/* SCSI hard disk emulation */ - +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of SCSI fixed and removable disks. + * + * Version: @(#)scsi_disk.c 1.0.1 2017/06/03 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _GNU_SOURCE +#include +#include #include #include #include @@ -10,17 +23,15 @@ #include #include -#include - -#include - #include "86box.h" #include "cdrom.h" #include "ibm.h" #include "ide.h" #include "piix.h" #include "scsi.h" +#include "scsi_disk.h" #include "timer.h" +#include "win/plat_iodev.h" /* Bits of 'status' */ #define ERR_STAT 0x01 @@ -41,6 +52,10 @@ #define scsi_hd_asc shdc[id].sense[12] #define scsi_hd_ascq shdc[id].sense[13] +scsi_hard_disk_t shdc[HDC_NUM]; + +FILE *shdf[HDC_NUM]; + uint8_t scsi_hard_disks[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, @@ -177,7 +192,15 @@ int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 4) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) + if ((wcslen(hdc[i].fn) == 0) && (hdc[i].bus != HDD_BUS_SCSI_REMOVABLE)) + { + continue; + } + if (((hdc[i].spt == 0) || (hdc[i].hpc == 0) || (hdc[i].tracks == 0)) && (hdc[i].bus != HDD_BUS_SCSI_REMOVABLE)) + { + continue; + } + if (((hdc[i].bus == HDD_BUS_SCSI) || (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE)) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) { return i; } @@ -185,27 +208,48 @@ int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) return 0xff; } -static void scsi_loadhd(int scsi_id, int scsi_lun, int id) +void scsi_disk_insert(uint8_t id) +{ + shdc[id].unit_attention = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; +} + +static char empty_sector[512]; +static char *empty_sector_1mb; + +void scsi_loadhd(int scsi_id, int scsi_lun, 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; - wchar_t *fn = hdd_fn[id]; + uint64_t i = 0, s = 0, t = 0; + wchar_t *fn = hdc[id].fn; + + memset(empty_sector, 0, sizeof(empty_sector)); shdc[id].base = 0; if (shdf[id] != NULL) { fclose(shdf[id]); - shdf[id] == NULL; + shdf[id] = NULL; } /* Try to open existing hard disk image */ if (fn[0] == '.') { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + scsi_hd_log("File name starts with .\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + shdc[id].cdb_len = 12; + } return; } shdf[id] = _wfopen(fn, L"rb+"); @@ -216,10 +260,26 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) { /* 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_load_error; + } + shdf[id] = _wfopen(fn, L"wb+"); if (shdf[id] == NULL) { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; +scsi_hd_load_error: + scsi_hd_log("Unable to open image\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + shdc[id].cdb_len = 12; + } return; } else @@ -227,6 +287,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) 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]); @@ -243,6 +304,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int 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]); @@ -253,15 +315,29 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) fwrite(&zero, 1, 4, shdf[id]); fwrite(&zero, 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; + 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 +348,380 @@ 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; + t = (s >> 11) << 11; + s -= t; + t >>= 11; + + empty_sector_1mb = (char *) malloc(1048576); + memset(empty_sector_1mb, 0, 1048576); + + if (s > 0) + { + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } + } + + if (t > 0) + { + for (i = 0; i < t; i++) + { + fwrite(empty_sector_1mb, 1, 1045876, shdf[id]); + } + } + + free(empty_sector_1mb); + } + + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + +#if 0 + fclose(shdf[id]); +#endif +} + +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, t = 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; + t = (s >> 11) << 11; + s -= t; + t >>= 11; + + empty_sector_1mb = (char *) malloc(1048576); + memset(empty_sector_1mb, 0, 1048576); + + if (s > 0) + { + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } + } + + if (t > 0) + { + for (i = 0; i < t; i++) + { + fwrite(empty_sector_1mb, 1, 1045876, shdf[id]); + } + } + + free(empty_sector_1mb); + } + + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + +#if 0 + fclose(shdf[id]); +#endif +} + +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 +741,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 +757,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 +899,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 +912,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 +932,14 @@ static void scsi_hd_not_ready(uint8_t id) scsi_hd_cmd_error(id); } +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; @@ -551,113 +981,6 @@ static void scsi_hd_data_phase_error(uint8_t id) scsi_hd_cmd_error(id); } -void scsi_hd_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) -{ - switch(cdb[0]) - { - case GPCMD_READ_6: - case GPCMD_WRITE_6: - cdb[1] = (lba_pos >> 16) & 0xff; - cdb[2] = (lba_pos >> 8) & 0xff; - cdb[3] = lba_pos & 0xff; - break; - - case GPCMD_READ_10: - case GPCMD_WRITE_10: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[7] = (number_of_blocks >> 8) & 0xff; - cdb[8] = number_of_blocks & 0xff; - break; - - case GPCMD_READ_12: - case GPCMD_WRITE_12: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[6] = (number_of_blocks >> 24) & 0xff; - cdb[7] = (number_of_blocks >> 16) & 0xff; - cdb[8] = (number_of_blocks >> 8) & 0xff; - cdb[9] = number_of_blocks & 0xff; - break; - } -} - -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 +1003,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 +1085,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); } @@ -788,7 +1117,7 @@ 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; } /* scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, hdbufferb[2], hdbufferb[12], hdbufferb[13]); */ @@ -808,10 +1137,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; } @@ -839,11 +1168,10 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l scsi_hd_request_sense(id, buffer, alloc_length); } -int scsi_hd_read_from_dma(uint8_t id); - void scsi_hd_command(uint8_t id, uint8_t *cdb) { - uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; + /* uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; */ + uint8_t *hdbufferb = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].CmdBuffer; uint32_t len; int pos=0; int max_len; @@ -851,10 +1179,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 }; + 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 }; + char *tempbuffer; #if 0 int CdbLength; @@ -864,13 +1192,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] = EMU_VERSION[0]; + device_identify_ex[12] = EMU_VERSION[2]; + device_identify_ex[13] = EMU_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); @@ -947,7 +1284,13 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - if (!shdc[id].sector_len) + if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector)) + { + scsi_hd_lba_out_of_range(id); + return; + } + + if ((!shdc[id].sector_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -958,23 +1301,29 @@ 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) + alloc_length = shdc[id].packet_len = max_len << 9; + + if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { - fseeko64(shdf[id], pos64 << 9, SEEK_SET); - fread(hdbufferb, (shdc[id].sector_len << 9), 1, shdf[id]); +#if 0 + shdf[id] = _wfopen(hdc[id].fn, L"rb+"); +#endif + fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); + if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + { + fread(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]); + } + else + { + fread(hdbufferb, 1, alloc_length, shdf[id]); + } +#if 0 + fclose(shdf[id]); +#endif } - alloc_length = shdc[id].packet_len = max_len << 9; if (shdc[id].requested_blocks > 1) { scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 0); @@ -986,17 +1335,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: @@ -1014,7 +1369,13 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - if (!shdc[id].sector_len) + if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector)) + { + scsi_hd_lba_out_of_range(id); + return; + } + + if ((!shdc[id].sector_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1025,17 +1386,29 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len = shdc[id].sector_len; shdc[id].requested_blocks = max_len; - scsi_hd_read_from_dma(id); - pos64 = (uint64_t) shdc[id].sector_pos; - if (shdc[id].requested_blocks > 0) + alloc_length = shdc[id].packet_len = max_len << 9; + + if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { - fseeko64(shdf[id], pos64 << 9, SEEK_SET); - fwrite(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); +#if 0 + shdf[id] = _wfopen(hdc[id].fn, L"rb+"); +#endif + fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); + if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + { + fwrite(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]); + } + else + { + fwrite(hdbufferb, 1, alloc_length, shdf[id]); + } +#if 0 + fclose(shdf[id]); +#endif } - alloc_length = shdc[id].packet_len = max_len << 9; if (shdc[id].requested_blocks > 1) { scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); @@ -1047,16 +1420,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 +1441,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; } @@ -1091,22 +1456,32 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len <<= 8; max_len |= cdb[4]; + if ((!max_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) + { + /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + shdc[id].callback = 20 * SCSI_TIME; + break; + } + + tempbuffer = malloc(1024); + if (cdb[1] & 1) { preamble_len = 4; size_idx = 3; - hdbufferb[idx++] = 05; - hdbufferb[idx++] = cdb[2]; - hdbufferb[idx++] = 0; + tempbuffer[idx++] = 05; + tempbuffer[idx++] = cdb[2]; + tempbuffer[idx++] = 0; idx++; switch (cdb[2]) { case 0x00: - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 0x83; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 0x83; break; case 0x83: if (idx + 24 > max_len) @@ -1115,10 +1490,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) return; } - hdbufferb[idx++] = 0x02; - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 20; + tempbuffer[idx++] = 0x02; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 20; ide_padstr8(hdbufferb + idx, 20, "53R141"); /* Serial */ idx += 20; @@ -1126,15 +1501,15 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) { goto atapi_out; } - hdbufferb[idx++] = 0x02; - hdbufferb[idx++] = 0x01; - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 68; - ide_padstr8(hdbufferb + idx, 8, "86Box"); /* Vendor */ + tempbuffer[idx++] = 0x02; + tempbuffer[idx++] = 0x01; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 68; + ide_padstr8(tempbuffer + idx, 8, EMU_NAME); /* Vendor */ idx += 8; - ide_padstr8(hdbufferb + idx, 40, device_identify_ex); /* Product */ + ide_padstr8(tempbuffer + idx, 40, device_identify_ex); /* Product */ idx += 40; - ide_padstr8(hdbufferb + idx, 20, "53R141"); /* Product */ + ide_padstr8(tempbuffer + idx, 20, "53R141"); /* Product */ idx += 20; break; default: @@ -1148,30 +1523,44 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) preamble_len = 5; size_idx = 4; - memset(hdbufferb, 0, 8); - hdbufferb[0] = 0; /*SCSI HD*/ - if (hdc[id].bus == 5) + memset(tempbuffer, 0, 8); + tempbuffer[0] = 0; /*SCSI HD*/ + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { - hdbufferb[1] = 0x80; /*Removable*/ + tempbuffer[1] = 0x80; /*Removable*/ } else { - hdbufferb[1] = 0; /*Fixed*/ + tempbuffer[1] = 0; /*Fixed*/ } - hdbufferb[2] = 0x02; /*SCSI-2 compliant*/ - hdbufferb[3] = 0x02; - hdbufferb[4] = 31; + tempbuffer[2] = 0x02; /*SCSI-2 compliant*/ + tempbuffer[3] = 0x02; + tempbuffer[4] = 31; - ide_padstr8(hdbufferb + 8, 8, "86Box"); /* Vendor */ - ide_padstr8(hdbufferb + 16, 16, device_identify); /* Product */ - ide_padstr8(hdbufferb + 32, 4, emulator_version); /* Revision */ + ide_padstr8(tempbuffer + 8, 8, EMU_NAME); /* Vendor */ + ide_padstr8(tempbuffer + 16, 16, device_identify); /* Product */ + ide_padstr8(tempbuffer + 32, 4, EMU_VERSION); /* Revision */ idx = 36; } atapi_out: - hdbufferb[size_idx] = idx - preamble_len; + tempbuffer[size_idx] = idx - preamble_len; len=idx; + if (len > max_len) + { + len = max_len; + } + + if (len > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + { + len = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength; + } + + memcpy(hdbufferb, tempbuffer, len); + + free(tempbuffer); + scsi_hd_data_command_finish(id, len, len, max_len, 0); break; @@ -1204,6 +1593,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; } @@ -1213,72 +1603,6 @@ atapi_out: void scsi_hd_callback(uint8_t id); -int scsi_hd_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t *hdbufferb; - - uint8_t id = scsi_hard_disks[scsi_id][scsi_lun]; - - hdbufferb = (uint8_t *) shdc[id].buffer; - - if (id > HDC_NUM) - { - return 0; - } - - scsi_hd_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); - memcpy(hdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSIDevices[scsi_id][scsi_lun].InitLength); - return 1; -} - -int scsi_hd_read_from_dma(uint8_t id) -{ - int ret = 0; - - ret = scsi_hd_read_from_scsi_dma(hdc[id].scsi_id, hdc[id].scsi_lun); - - if (!ret) - { - return 0; - } - - return 0; -} - -int scsi_hd_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t *hdbufferb; - - uint8_t id = scsi_hard_disks[scsi_id][scsi_lun]; - - if (id > HDC_NUM) - { - return 0; - } - - hdbufferb = (uint8_t *) shdc[id].buffer; - - scsi_hd_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, hdbufferb, SCSIDevices[scsi_id][scsi_lun].InitLength); - scsi_hd_log("SCSI HD %i: Data from HD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7]); - scsi_hd_log("SCSI HD %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); - return 1; -} - -int scsi_hd_write_to_dma(uint8_t id) -{ - int ret = 0; - - ret = scsi_hd_write_to_scsi_dma(hdc[id].scsi_id, hdc[id].scsi_lun); - - if (!ret) - { - return 0; - } - - return 1; -} - /* If the result is 1, issue an IRQ, otherwise not. */ void scsi_hd_callback(uint8_t id) { @@ -1290,18 +1614,12 @@ void scsi_hd_callback(uint8_t id) shdc[id].phase = 1; shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); return; - case CDROM_PHASE_COMMAND: - scsi_hd_log("SCSI HD %i: PHASE_COMMAND\n", id); - shdc[id].status = BUSY_STAT | (shdc[id].status &ERR_STAT); - memcpy(shdc[id].hd_cdb, (uint8_t *) shdc[id].buffer, shdc[id].cdb_len); - scsi_hd_command(id, shdc[id].hd_cdb); - return; case CDROM_PHASE_COMPLETE: scsi_hd_log("SCSI HD %i: PHASE_COMPLETE\n", 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); @@ -1310,11 +1628,10 @@ void scsi_hd_callback(uint8_t id) return; case CDROM_PHASE_DATA_OUT_DMA: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", id); - scsi_hd_read_from_dma(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); @@ -1323,11 +1640,10 @@ void scsi_hd_callback(uint8_t id) return; case CDROM_PHASE_DATA_IN_DMA: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", id); - scsi_hd_write_to_dma(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..95fdd9316 --- /dev/null +++ b/src/scsi_disk.h @@ -0,0 +1,58 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of SCSI fixed and removable disks. + * + * Version: @(#)scsi_disk.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + +#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; + 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); + +extern FILE *shdf[HDC_NUM]; diff --git a/src/serial.c b/src/serial.c index ae376960a..035e443f2 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,11 +33,12 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.5 2017/05/17 + * Version: @(#)serial.c 1.0.7 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. */ +#include #include "ibm.h" #include "io.h" #include "pic.h" @@ -46,6 +47,9 @@ #include "plat_serial.h" +#define NUM_SERIAL 2 /* we support 2 ports */ + + enum { SERINT_LSR = 1, SERINT_RECEIVE = 2, @@ -136,8 +140,24 @@ enum { #define MSR_MASK (0x0f) -static SERIAL serial1, /* serial port 1 data */ - serial2; /* serial port 2 data */ +static SERIAL ports[NUM_SERIAL]; /* serial port data */ + int serial_do_log; + + +static void +serial_log(int lvl, const char *fmt, ...) +{ +#ifdef ENABLE_SERIAL_LOG + va_list ap; + + if (serial_do_log >= lvl) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); + } +#endif +} static void @@ -216,19 +236,6 @@ read_fifo(SERIAL *sp) } -/* BHTTY WRITE COMPLETE handler. */ -static void -serial_wr_done(void *arg) -{ - SERIAL *sp = (SERIAL *)arg; - - /* The WRITE completed, we are ready for more. */ - sp->lsr |= LSR_THRE; - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); -} - - /* Handle a WRITE operation to one of our registers. */ static void serial_write(uint16_t addr, uint8_t val, void *priv) @@ -238,8 +245,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) uint16_t baud; long speed; -#if 0 - pclog("Serial%d: write(%04x, %02x)\n", sp->port, addr, val); +#if ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: write(%04x, %02x)\n", sp->port, addr, val); #endif switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ @@ -250,13 +257,12 @@ serial_write(uint16_t addr, uint8_t val, void *priv) sp->thr = val; if (sp->bh != NULL) { /* We are linked, so send to BH layer. */ -#if 0 - bhtty_write((BHTTY *)sp->bh, - sp->thr, serial_wr_done, sp); -#else bhtty_write((BHTTY *)sp->bh, sp->thr); - serial_wr_done(sp); -#endif + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); } else { /* Not linked. Just fake LOOPBACK mode. */ if (! (sp->mctrl & MCR_LMS)) @@ -288,15 +294,15 @@ serial_write(uint16_t addr, uint8_t val, void *priv) baud = ((sp->dlab2<<8) | sp->dlab1); if (baud > 0) { speed = 115200UL/baud; -#if 0 - pclog("Serial%d: divisor %u, baudrate %ld\n", +#ifdef ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", sp->port, baud, speed); #endif if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); -#if 0 } else { - pclog("Serial%d: divisor %u invalid!\n", +#ifdef ENABLE_SERIAL_LOG + serial_log(1, "Serial%d: divisor %u invalid!\n", sp->port, baud); #endif } @@ -304,8 +310,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) wl = (val & LCR_WLS) + 5; /* databits */ sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; -#if 0 - pclog("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); +#ifdef ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); #endif if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); @@ -322,24 +328,28 @@ serial_write(uint16_t addr, uint8_t val, void *priv) */ if (sp->rts_callback) { sp->rts_callback(sp->rts_callback_p); -#if 0 - pclog("RTS raised; sending ID\n"); +#ifdef ENABLE_SERIAL_LOG + serial_log(1, "RTS raised; sending ID\n"); #endif } } if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { if (sp->bh != NULL) { - /* Linked, start reading from host port. */ - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); + /* Linked, start host port. */ + (void)bhtty_active(sp->bh, 1); } else { /* Not linked, start RX timer. */ timer_add(serial_timer, &sp->receive_delay, &sp->receive_delay, sp); -#if 0 - pclog("Serial%d: RX timer started!\n",sp->port); -#endif + + /* Fake CTS, DSR and DCD (for now.) */ + sp->msr = (MSR_CTS | MSR_DCTS | + MSR_DSR | MSR_DDSR | + MSR_DCD | MSR_DDCD); + sp->int_status |= SERINT_MSR; + update_ints(sp); } } sp->mctrl = val; @@ -394,16 +404,15 @@ static void serial_rd_done(void *arg, int num) { SERIAL *sp = (SERIAL *)arg; -#if 0 -pclog("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); -#endif - /* Stuff the byte in the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); + /* We can do at least 'num' bytes.. */ + while (num-- > 0) { + /* Get a byte from them. */ + if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; - /* Start up the next read from the real port. */ - if (sp->bh != NULL) - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); + /* Stuff it into the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + } } @@ -418,21 +427,19 @@ serial_read(uint16_t addr, void *priv) case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { ret = sp->dlab1; - break; + } else { + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; } - sp->lsr &= ~LSR_DR; - sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); - if ((sp->bh == NULL) && (sp->fifo_read != sp->fifo_write)) - sp->receive_delay = 1000 * TIMER_USEC; break; case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) - ret = sp->dlab2; - else - ret = sp->ier; + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; break; case 2: /* IIR */ @@ -441,9 +448,8 @@ serial_read(uint16_t addr, void *priv) sp->int_status &= ~SERINT_TRANSMIT; update_ints(sp); } - if (sp->fcr & 0x01) { + if (sp->fcr & 0x01) ret |= 0xc0; - } break; case 3: /* LCR */ @@ -490,32 +496,25 @@ serial_setup(int port, uint16_t addr, int irq) { SERIAL *sp; - pclog("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); +#ifdef ENABLE_SERIAL_LOG + serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); +#endif /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; /* Set up the basic info. */ if (sp->addr != 0x0000) { /* Unlink the previous handler. Just in case. */ io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } sp->addr = addr; sp->irq = irq; /* Request an I/O range. */ io_sethandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); - -#if 1 - /* Do not disable here, it breaks the SIO chips. */ -#else - /* No DTR/RTS callback for now. */ - sp->rts_callback = NULL; -#endif + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } @@ -526,25 +525,18 @@ serial_remove(int port) SERIAL *sp; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; // FIXME: stop timer, if enabled! -#if 1 - /* Do not disable here, it breaks the SIO chips. */ -#else - /* Remove any callbacks. */ - sp->rts_callback = NULL; -#endif - /* Close the host device. */ - (void)serial_link(port, NULL); + if (sp->bh != NULL) + (void)serial_link(port, NULL); /* Release our I/O range. */ if (sp->addr != 0x0000) { io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } sp->addr = 0x0000; sp->irq = 0; @@ -555,13 +547,32 @@ serial_remove(int port) void serial_init(void) { - memset(&serial1, 0x00, sizeof(SERIAL)); - serial1.port = 1; - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + SERIAL *sp; + int i; - memset(&serial2, 0x00, sizeof(SERIAL)); - serial2.port = 2; - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); +#if ENABLE_SERIAL_LOG + serial_do_log = ENABLE_SERIAL_LOG; +#endif + + /* FIXME: we should probably initialize the platform module here. */ + + /* Initialize each port. */ + for (i=0; iport = (i+1); + + if (i == 0) + serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); + } + +#ifdef WALTJE + /* Link to host port. */ + serial_link(1, "COM1"); + serial_link(2, "COM2"); +#endif } @@ -573,11 +584,15 @@ serial_init(void) void serial_reset(void) { - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; + SERIAL *sp; + int i; - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial2.fifo_read = serial2.fifo_write = 0; + for (i=0; iiir = sp->ier = sp->lcr = sp->mctrl = 0x00; + sp->fifo_read = sp->fifo_write = 0x00; + } } @@ -589,19 +604,23 @@ serial_link(int port, char *arg) BHTTY *bh; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; if (arg != NULL) { /* Make sure we're not already linked. */ if (sp->bh != NULL) { - pclog("Serial%d already linked!\n", port); +#if ENABLE_SERIAL_LOG + serial_log(0, "Serial%d already linked!\n", port); +#endif return(-1); } /* Request a port from the host system. */ bh = bhtty_open(arg, 0); if (bh == NULL) { - pclog("Serial%d unable to link to '%s' !\n", port, arg); +#if ENABLE_SERIAL_LOG + serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); +#endif return(-1); } sp->bh = bh; @@ -629,7 +648,7 @@ serial_attach(int port, void *func, void *arg) SERIAL *sp; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; /* Set up callback info. */ sp->rts_callback = func; diff --git a/src/serial.h b/src/serial.h index bf361a0b1..4602429f0 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,13 +8,13 @@ * * Definitions for the SERIAL card. * - * Version: @(#)serial.h 1.0.3 2017/05/07 + * Version: @(#)serial.h 1.0.4 2017/06/03 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. */ -#ifndef SERIAL_H -# define SERIAL_H +#ifndef EMU_SERIAL_H +# define EMU_SERIAL_H /* Default settings for the standard ports. */ @@ -61,4 +61,4 @@ extern int serial_link(int, char *); extern void serial_write_fifo(SERIAL *, uint8_t); -#endif /*SERIAL_H*/ +#endif /*EMU_SERIAL_H*/ diff --git a/src/sio.c b/src/sio.c index 9ad476e38..96d2ef375 100644 --- a/src/sio.c +++ b/src/sio.c @@ -1,21 +1,29 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -/*PRD format : - - word 0 - base address - word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of Intel System I/O PCI chip. + * + * Version: @(#)sio.c 1.0.1 2017/06/02 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include + #include "ibm.h" -#include "cpu/cpu.h" #include "cdrom.h" #include "disc.h" #include "dma.h" #include "fdc.h" +#include "keyboard_at.h" #include "ide.h" #include "io.h" -#include "keyboard_at.h" #include "mem.h" #include "pci.h" @@ -25,66 +33,99 @@ static uint8_t card_sio[256]; void sio_write(int func, int addr, uint8_t val, void *priv) { -// pclog("sio_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); - - if ((addr & 0xff) < 4) return; - if (func > 0) - return; + return; - if (func == 0) - { - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + if (addr >= 0x0f && addr < 0x4c) return; - } - card_sio[addr] = val; - if (addr == 0x40) - { - if (!((val ^ card_sio[addr]) & 0x40)) - { - return; - } - if (val & 0x40) - { - dma_alias_remove(); - } - else - { - dma_alias_set(); - } - } - else if (addr == 0x4f) - { - if (!((val ^ card_sio[addr]) & 0x40)) - { - return; - } + switch (addr) + { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0e: + return; + + case 0x04: /*Command register*/ + val &= 0x08; + val |= 0x07; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - if (val & 0x40) - { - port_92_add(); - } - else - { - port_92_remove(); - } + case 0x40: + if (!((val ^ card_sio[addr]) & 0x40)) + { + return; } + + if (val & 0x40) + { + dma_alias_remove(); + } + else + { + dma_alias_set(); + } + break; + + case 0x4f: + if (!((val ^ card_sio[addr]) & 0x40)) + { + return; + } + + if (val & 0x40) + { + port_92_add(); + } + else + { + port_92_remove(); + } + + case 0x60: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x62: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x63: + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } + card_sio[addr] = val; } uint8_t sio_read(int func, int addr, void *priv) { -// pclog("sio_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); - if (func > 0) - return 0xff; + return 0xff; - return card_sio[addr]; + return card_sio[addr]; } static int trc_reg = 0; @@ -153,31 +194,30 @@ void sio_reset(void) { memset(card_sio, 0, 256); card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/ - card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378ZB (SIO)*/ + card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378IB (SIO)*/ card_sio[0x04] = 0x07; card_sio[0x05] = 0x00; - card_sio[0x06] = 0x00; card_sio[0x07] = 0x02; - card_sio[0x08] = 0x00; /*A0 stepping*/ - card_sio[0x40] = 0x20; - card_sio[0x42] = 0x24; - card_sio[0x45] = 0x10; - card_sio[0x46] = 0x0F; - card_sio[0x48] = 0x01; - card_sio[0x4A] = 0x10; - card_sio[0x4B] = 0x0F; - card_sio[0x4C] = 0x56; - card_sio[0x4D] = 0x40; - card_sio[0x4E] = 0x07; - card_sio[0x4F] = 0x4F; - card_sio[0x60] = card_sio[0x61] = card_sio[0x62] = card_sio[0x63] = 0x80; - card_sio[0x80] = 0x78; - card_sio[0xA0] = 0x08; - card_sio[0xA8] = 0x0F; + card_sio[0x06] = 0x00; card_sio[0x07] = 0x02; + card_sio[0x08] = 0x03; /*A0 stepping*/ + + card_sio[0x40] = 0x20; card_sio[0x41] = 0x00; + card_sio[0x42] = 0x04; card_sio[0x43] = 0x00; + card_sio[0x44] = 0x20; card_sio[0x45] = 0x10; + card_sio[0x46] = 0x0f; card_sio[0x47] = 0x00; + card_sio[0x48] = 0x01; card_sio[0x49] = 0x10; + card_sio[0x4a] = 0x10; card_sio[0x4b] = 0x0f; + card_sio[0x4c] = 0x56; card_sio[0x4d] = 0x40; + card_sio[0x4e] = 0x07; card_sio[0x4f] = 0x4f; + card_sio[0x54] = 0x00; card_sio[0x55] = 0x00; card_sio[0x56] = 0x00; + card_sio[0x60] = 0x80; card_sio[0x61] = 0x80; card_sio[0x62] = 0x80; card_sio[0x63] = 0x80; + card_sio[0x80] = 0x78; card_sio[0x81] = 0x00; + card_sio[0xa0] = 0x08; + card_sio[0xa8] = 0x0f; } -void sio_init(int card) +void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, sio_read, sio_write, NULL); - + sio_reset(); trc_init(); @@ -189,4 +229,13 @@ void sio_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = sio_reset; + + if (pci_a) + pci_set_card_routing(pci_a, PCI_INTA); + if (pci_b) + pci_set_card_routing(pci_b, PCI_INTB); + if (pci_c) + pci_set_card_routing(pci_c, PCI_INTC); + if (pci_d) + pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/sio.h b/src/sio.h index 38b0ff468..0e3ea651f 100644 --- a/src/sio.h +++ b/src/sio.h @@ -1,5 +1,18 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of Intel System I/O PCI chip. + * + * Version: @(#)sio.h 1.0.1 2017/06/02 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void trc_init(void); -void sio_init(int card); +void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); diff --git a/src/sis496.c b/src/sis496.c index a858102a3..cb4d9303d 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -68,8 +68,33 @@ void sis496_write(int func, int addr, uint8_t val, void *p) sis496_recalcmapping(); } break; - } + case 0xc0: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, val & 0xf); + else + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + break; + case 0xc1: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, val & 0xf); + else + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + break; + case 0xc2: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, val & 0xf); + else + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + break; + case 0xc3:// pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, val & 0xf); + else + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + break; + } + if ((addr >= 4 && addr < 8) || addr >= 0x40) sis496.pci_conf[addr] = val; } @@ -118,6 +143,10 @@ void sis496_init(void) sis496_reset(); pci_reset_handler.pci_master_reset = sis496_pci_reset; + + pci_set_card_routing(15, PCI_INTA); + pci_set_card_routing(13, PCI_INTD); + pci_set_card_routing(11, PCI_INTC); } void sis496_close(void *p) diff --git a/src/sis50x.c b/src/sis50x.c index ad4be95c6..59e887d78 100644 --- a/src/sis50x.c +++ b/src/sis50x.c @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 50x PCI chips. + * + * Version: @(#)sis50x.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + #include #include "ibm.h" #include "device.h" diff --git a/src/sis50x.h b/src/sis50x.h index d2028dc2b..df5565043 100644 --- a/src/sis50x.h +++ b/src/sis50x.h @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 50x PCI chips. + * + * Version: @(#)sis50x.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + extern device_t sis501_device; extern device_t sis503_device; extern device_t sis50x_device; diff --git a/src/sis85c471.c b/src/sis85c471.c index e7d5af86c..f56716f43 100644 --- a/src/sis85c471.c +++ b/src/sis85c471.c @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 85c471 chip. + * + * Version: @(#)sis85c471.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + /* SiS sis85c471 Super I/O Chip Used by Batman's Revenge diff --git a/src/sis85c471.h b/src/sis85c471.h index 5ccd63ab5..5a69fdf65 100644 --- a/src/sis85c471.h +++ b/src/sis85c471.h @@ -1,3 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 85c471 chip. + * + * Version: @(#)sis85c471.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + /* Copyright holders: Tenshi see COPYING for more details */ diff --git a/src/thread-pthread.c b/src/thread-pthread.c deleted file mode 100644 index dd56ef896..000000000 --- a/src/thread-pthread.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "thread.h" - -typedef struct event_pthread_t -{ - pthread_cond_t cond; - pthread_mutex_t mutex; -} event_pthread_t; - -thread_t *thread_create(void (*thread_rout)(void *param), void *param) -{ - pthread_t *thread = malloc(sizeof(pthread_t)); - - pthread_create(thread, NULL, thread_rout, param); - - return thread; -} - -void thread_kill(thread_t *handle) -{ - pthread_t *thread = (pthread_t *)handle; - - pthread_cancel(*thread); - pthread_join(*thread, NULL); - - free(thread); -} - -event_t *thread_create_event() -{ - event_pthread_t *event = malloc(sizeof(event_pthread_t)); - - pthread_cond_init(&event->cond, NULL); - pthread_mutex_init(&event->mutex, NULL); - - return (event_t *)event; -} - -void thread_set_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; - - pthread_mutex_lock(&event->mutex); - pthread_cond_broadcast(&event->cond); - pthread_mutex_unlock(&event->mutex); -} - -void thread_reset_event(event_t *handle) -{ -} - -int thread_wait_event(event_t *handle, int timeout) -{ - event_pthread_t *event = (event_pthread_t *)handle; - struct timespec abstime; - - clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_nsec += (timeout % 1000) * 1000000; - abstime.tv_sec += (timeout / 1000); - if (abstime.tv_nsec > 1000000000) - { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } - - pthread_mutex_lock(&event->mutex); - pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); - pthread_mutex_unlock(&event->mutex); - - return 0; -} - -void thread_destroy_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; - - pthread_cond_destroy(&event->cond); - pthread_mutex_destroy(&event->mutex); - - free(event); -} - -void thread_sleep(int t) -{ - usleep(t * 1000); -} diff --git a/src/thread.h b/src/thread.h deleted file mode 100644 index 3397760fe..000000000 --- a/src/thread.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef void thread_t; -thread_t *thread_create(void (*thread_rout)(void *param), void *param); -void thread_kill(thread_t *handle); - -typedef void event_t; -event_t *thread_create_event(); -void thread_set_event(event_t *event); -void thread_reset_event(event_t *_event); -int thread_wait_event(event_t *event, int timeout); -void thread_destroy_event(event_t *_event); - -void thread_sleep(int t); diff --git a/src/timer.c b/src/timer.c index 07cc7c336..d3fd618a7 100644 --- a/src/timer.c +++ b/src/timer.c @@ -39,6 +39,11 @@ void timer_process() for (c = 0; c < timers_present; c++) { + /* This is needed to avoid timer crashes on hard reset. */ + if ((timers[c].enable == NULL) || (timers[c].count == NULL)) + { + continue; + } enable[c] = *timers[c].enable; if (*timers[c].enable) { diff --git a/src/um8669f.c b/src/um8669f.c index 00433f24c..964f2613a 100644 --- a/src/um8669f.c +++ b/src/um8669f.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the UMC UM8669F Super I/O Chip. + * + * Version: @(#)um8669f.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*um8669f : aa to 108 unlocks diff --git a/src/um8669f.h b/src/um8669f.h index 19a56ba02..92052a151 100644 --- a/src/um8669f.h +++ b/src/um8669f.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the UMC UM8669F Super I/O Chip. + * + * Version: @(#)um8669f.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern void um8669f_init(); diff --git a/src/w83877f.c b/src/w83877f.c index cb980df09..6a6dd0552 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -1,6 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83877F Super I/O Chip. + * + * Version: @(#)w83877f.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + /* Winbond W83877F Super I/O Chip Used by the Award 430HX diff --git a/src/w83877f.h b/src/w83877f.h index 33120fbde..f4a103c94 100644 --- a/src/w83877f.h +++ b/src/w83877f.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83877F Super I/O Chip. + * + * Version: @(#)w83877f.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void w83877f_init(); diff --git a/src/xtide.c b/src/xtide.c index ce827151b..e7997d8fa 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,3 +1,20 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * XT IDE controller emulation. + * + * Version: @(#)xtide.c 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include #include "ibm.h" #include "io.h" @@ -8,6 +25,10 @@ #include "xtide.h" +#define XTIDE_ROM_PATH L"roms/ide_xt.bin" +#define ATIDE_ROM_PATH L"roms/ide_at.bin" + + typedef struct xtide_t { uint8_t data_high; @@ -22,12 +43,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(4, 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(4, (port & 0xf) | 0x1f0, val); return; case 0x8: @@ -35,7 +56,7 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) return; case 0xe: - writeide(0, 0x3f6, val); + writeide(4, 0x3f6, val); return; } } @@ -49,19 +70,19 @@ static uint8_t xtide_read(uint16_t port, void *p) switch (port & 0xf) { case 0x0: - tempw = readidew(0); + tempw = readidew(4); 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(4, (port & 0xf) | 0x1f0); case 0x8: return xtide->data_high; case 0xe: - return readide(0, 0x3f6); + return readide(4, 0x3f6); default: return 0xff; @@ -74,10 +95,8 @@ static void *xtide_init(void) xtide_t *xtide = malloc(sizeof(xtide_t)); 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(); + rom_init(&xtide->bios_rom, XTIDE_ROM_PATH, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + ide_xtide_init(); io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); return xtide; @@ -89,7 +108,7 @@ static void *xtide_at_init(void) xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, L"roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, ATIDE_ROM_PATH, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; @@ -102,9 +121,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; diff --git a/src/xtide.h b/src/xtide.h index 666783629..f1f0a3da2 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -1,4 +1,28 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * XT IDE controller emulation. + * + * Version: @(#)xtide.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_XTIDE_H +# define EMU_XTIDE_H + + extern device_t xtide_device; extern device_t xtide_at_device; extern device_t xtide_ps2_device; extern device_t xtide_at_ps2_device; + + +#endif /*EMU_XTIDE_H*/