From bf38c4adeff8ef83472899d5f5005e01deb51716 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 17 Aug 2023 02:46:37 +0200 Subject: [PATCH 01/30] More UI work, added Slovak and Catalan translations, and fixed mmutranslate on the 286/386, fixes #3587, #3591. --- src/cpu/386.c | 16 + src/cpu/386_common.h | 4 +- src/mem/mmu_2386.c | 948 ++++++++++++---------- src/qt/languages/ca-ES.po | 1221 +++++++++++++++++++++++++++++ src/qt/languages/cs-CZ.po | 6 + src/qt/languages/de-DE.po | 6 + src/qt/languages/en-GB.po | 6 + src/qt/languages/en-US.po | 6 + src/qt/languages/es-ES.po | 64 +- src/qt/languages/fi-FI.po | 6 + src/qt/languages/fr-FR.po | 6 + src/qt/languages/hr-HR.po | 6 + src/qt/languages/hu-HU.po | 6 + src/qt/languages/it-IT.po | 6 + src/qt/languages/ja-JP.po | 6 + src/qt/languages/ko-KR.po | 6 + src/qt/languages/pl-PL.po | 6 + src/qt/languages/pt-BR.po | 6 + src/qt/languages/pt-PT.po | 6 + src/qt/languages/ru-RU.po | 6 + src/qt/languages/sk-SK.po | 1220 ++++++++++++++++++++++++++++ src/qt/languages/sl-SI.po | 6 + src/qt/languages/tr-TR.po | 6 + src/qt/languages/uk-UA.po | 6 + src/qt/languages/zh-CN.po | 6 + src/qt/languages/zh-TW.po | 6 + src/qt/qt_mainwindow.ui | 4 +- src/qt/qt_platform.cpp | 14 +- src/qt/qt_settings.cpp | 40 +- src/qt/qt_settingsfloppycdrom.cpp | 13 - src/qt/qt_translations.qrc | 2 + 31 files changed, 3179 insertions(+), 487 deletions(-) create mode 100644 src/qt/languages/ca-ES.po create mode 100644 src/qt/languages/sk-SK.po diff --git a/src/cpu/386.c b/src/cpu/386.c index 4daa2936b..0fe7e6188 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -77,6 +77,7 @@ x386_log(const char *fmt, ...) static __inline void fetch_ea_32_long(uint32_t rmdat) { + eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; if (cpu_rm == 4) { uint8_t sib = rmdat >> 8; @@ -121,11 +122,19 @@ fetch_ea_32_long(uint32_t rmdat) cpu_state.eaaddr = getlong(); } } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } static __inline void fetch_ea_16_long(uint32_t rmdat) { + eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; if (!cpu_mod && cpu_rm == 6) { cpu_state.eaaddr = getword(); @@ -149,6 +158,13 @@ fetch_ea_16_long(uint32_t rmdat) } cpu_state.eaaddr &= 0xFFFF; } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } #define fetch_ea_16(rmdat) \ diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index f39733cff..22fbd4bff 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -347,7 +347,7 @@ fastreadw_fetch(uint32_t a) if ((a & 0xFFF) > 0xFFE) { val = fastreadb(a); if (opcode_length[val & 0xff] > 1) - val |= (fastreadb(a + 1) << 8); + val |= ((uint16_t) fastreadb(a + 1) << 8); return val; } @@ -362,7 +362,7 @@ fastreadl_fetch(uint32_t a) if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) { val = fastreadw_fetch(a); if (opcode_length[val & 0xff] > 2) - val |= (fastreadw(a + 2) << 16); + val |= ((uint32_t) fastreadw(a + 2) << 16); return val; } diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 4fd709f14..d4fe49742 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -38,181 +38,303 @@ #include <86box/rom.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC -# include "codegen_public.h" +# include "codegen_public.h" #else -#ifdef USE_NEW_DYNAREC -# define PAGE_MASK_SHIFT 6 -#else -# define PAGE_MASK_INDEX_MASK 3 -# define PAGE_MASK_INDEX_SHIFT 10 -# define PAGE_MASK_SHIFT 4 -#endif -# define PAGE_MASK_MASK 63 +# ifdef USE_NEW_DYNAREC +# define PAGE_MASK_SHIFT 6 +# else +# define PAGE_MASK_INDEX_MASK 3 +# define PAGE_MASK_INDEX_SHIFT 10 +# define PAGE_MASK_SHIFT 4 +# endif +# define PAGE_MASK_MASK 63 #endif #if (!defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) -#define BLOCK_PC_INVALID 0xffffffff -#define BLOCK_INVALID 0 +# define BLOCK_PC_INVALID 0xffffffff +# define BLOCK_INVALID 0 #endif +uint8_t +mem_readb_map(uint32_t addr) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + uint8_t ret = 0xff; + + mem_logical_addr = 0xffffffff; + + if (map && map->read_b) + ret = map->read_b(addr, map->priv); + + return ret; +} + +uint16_t +mem_readw_map(uint32_t addr) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + uint16_t ret; + const uint16_t *p; + + mem_logical_addr = 0xffffffff; + + if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) + ret = map->read_w(addr, map->priv); + else { + ret = mem_readb_phys(addr + 1) << 8; + ret |= mem_readb_phys(addr); + } + + return ret; +} + +uint32_t +mem_readl_map(uint32_t addr) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + uint32_t ret; + const uint32_t *p; + + mem_logical_addr = 0xffffffff; + + if (!cpu_16bitbus && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) + ret = map->read_l(addr, map->priv); + else { + ret = mem_readw_phys(addr + 2) << 16; + ret |= mem_readw_phys(addr); + } + + return ret; +} + +void +mem_writeb_map(uint32_t addr, uint8_t val) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + mem_logical_addr = 0xffffffff; + + if (map && map->write_b) + map->write_b(addr, val, map->priv); +} + +void +mem_writew_map(uint32_t addr, uint16_t val) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + const uint16_t *p; + + mem_logical_addr = 0xffffffff; + + if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) + map->write_w(addr, val, map->priv); + else { + mem_writeb_phys(addr, val & 0xff); + mem_writeb_phys(addr + 1, val >> 8); + } +} + +void +mem_writel_map(uint32_t addr, uint32_t val) +{ + mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + const uint32_t *p; + + mem_logical_addr = 0xffffffff; + + if (!cpu_16bitbus && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) + map->write_l(addr, val, map->priv); + else { + mem_writew_phys(addr, val & 0xffff); + mem_writew_phys(addr + 2, val >> 16); + } +} #define mmutranslate_read_2386(addr) mmutranslatereal_2386(addr,0) #define mmutranslate_write_2386(addr) mmutranslatereal_2386(addr,1) - uint64_t mmutranslatereal_2386(uint32_t addr, int rw) { - uint32_t temp, temp2, temp3; + uint32_t temp; + uint32_t temp2; + uint32_t temp3; uint32_t addr2; if (cpu_state.abrt) - return 0xffffffffffffffffULL; + return 0xffffffffffffffffULL; addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = mem_readl_phys(addr2); + temp = temp2 = mem_readl_map(addr2); if (!(temp & 1)) { - cr2 = addr; - temp &= 1; - if (CPL == 3) temp |= 4; - if (rw) temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + return 0xffffffffffffffffULL; } - temp = mem_readl_phys((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + if ((temp & 0x80) && (cr4 & CR4_PSE)) { + /*4MB page*/ + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + + return 0xffffffffffffffffULL; + } + + mmu_perm = temp & 4; + mem_writel_map(addr2, mem_readl_map(addr2) | (rw ? 0x60 : 0x20)); + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + + temp = mem_readl_map((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (is486 && (cr0 & WP_FLAG))))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return 0xffffffffffffffffULL; + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + return 0xffffffffffffffffULL; } mmu_perm = temp & 4; - mem_writel_phys(addr2, mem_readl_phys(addr) | 0x20); - mem_writel_phys((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), mem_readl_phys((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) | (rw ? 0x60 : 0x20)); + mem_writel_map(addr2, mem_readl_map(addr2) | 0x20); + mem_writel_map((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), + mem_readl_map((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) | (rw ? 0x60 : 0x20)); return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); } - uint64_t mmutranslate_noabrt_2386(uint32_t addr, int rw) { - uint32_t temp,temp2,temp3; + uint32_t temp; + uint32_t temp2; + uint32_t temp3; uint32_t addr2; if (cpu_state.abrt) - return 0xffffffffffffffffULL; + return 0xffffffffffffffffULL; addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = mem_readl_phys(addr2); + temp = temp2 = mem_readl_map(addr2); - if (! (temp & 1)) - return 0xffffffffffffffffULL; + if (!(temp & 1)) + return 0xffffffffffffffffULL; - temp = mem_readl_phys((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + if ((temp & 0x80) && (cr4 & CR4_PSE)) { + /*4MB page*/ + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + return 0xffffffffffffffffULL; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + + temp = mem_readl_map((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) - return 0xffffffffffffffffULL; + return 0xffffffffffffffffULL; return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); } - uint8_t readmembl_2386(uint32_t addr) { mem_mapping_t *map; - uint64_t a; - uint8_t ret = 0xff; + uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); - addr64 = (uint64_t) addr; + addr64 = (uint64_t) addr; mem_logical_addr = addr; high_page = 0; if (cr0 >> 31) { - a = mmutranslate_read_2386(addr); - addr64 = (uint32_t) a; + a = mmutranslate_read_2386(addr); + addr64 = (uint32_t) a; - if (a > 0xffffffffULL) + if (a > 0xffffffffULL) return 0xff; } addr = (uint32_t) (addr64 & rammask); map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - ret = map->read_b(addr, map->priv); + return map->read_b(addr, map->priv); - return ret; + return 0xff; } - void writemembl_2386(uint32_t addr, uint8_t val) { mem_mapping_t *map; - uint64_t a; + uint64_t a; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); - addr64 = (uint64_t) addr; + addr64 = (uint64_t) addr; mem_logical_addr = addr; high_page = 0; if (cr0 >> 31) { - a = mmutranslate_write_2386(addr); - addr64 = (uint32_t) a; + a = mmutranslate_write_2386(addr); + addr64 = (uint32_t) a; - if (a > 0xffffffffULL) - return; + if (a > 0xffffffffULL) + return; } addr = (uint32_t) (addr64 & rammask); map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_b) - map->write_b(addr, val, map->priv); + map->write_b(addr, val, map->priv); } - /* Read a byte from memory without MMU translation - result of previous MMU translation passed as value. */ uint8_t readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) { mem_mapping_t *map; - uint8_t ret = 0xff; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); mem_logical_addr = addr; if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xff; + if (cpu_state.abrt || high_page) + return 0xff; - addr = a64 & rammask; + addr = a64 & rammask; } else - addr &= rammask; + addr &= rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_b) - ret = map->read_b(addr, map->priv); + return map->read_b(addr, map->priv); - return ret; + return 0xff; } - /* Write a byte to memory without MMU translation - result of previous MMU translation passed as value. */ void writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val) @@ -224,26 +346,23 @@ writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val) mem_logical_addr = addr; if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; + if (cpu_state.abrt || high_page) + return; - addr = a64 & rammask; + addr = a64 & rammask; } else - addr &= rammask; + addr &= rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_b) - map->write_b(addr, val, map->priv); + map->write_b(addr, val, map->priv); } - uint16_t readmemwl_2386(uint32_t addr) { mem_mapping_t *map; - int i; - uint64_t a; - uint16_t ret = 0xffff; + uint64_t a; addr64a[0] = addr; addr64a[1] = addr + 1; @@ -254,54 +373,51 @@ readmemwl_2386(uint32_t addr) high_page = 0; if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - for (i = 0; i < 2; i++) { - a = mmutranslate_read_2386(addr + i); - addr64a[i] = (uint32_t) a; + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + for (uint8_t i = 0; i < 2; i++) { + a = mmutranslate_read_2386(addr + i); + addr64a[i] = (uint32_t) a; - if (a > 0xffffffffULL) - return 0xffff; - } - } + if (a > 0xffffffffULL) + return 0xffff; + } + } - return readmembl_no_mmut(addr, addr64a[0]) | - (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); - } + return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); + } } if (cr0 >> 31) { - a = mmutranslate_read_2386(addr); - addr64a[0] = (uint32_t) a; + a = mmutranslate_read_2386(addr); + addr64a[0] = (uint32_t) a; - if (a > 0xffffffffULL) - return 0xffff; + if (a > 0xffffffffULL) + return 0xffff; } else - addr64a[0] = (uint64_t) addr; + addr64a[0] = (uint64_t) addr; addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - ret = map->read_w(addr, map->priv); - else if (map && map->read_b) { - ret = map->read_b(addr, map->priv) | - ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); + return map->read_w(addr, map->priv); + + if (map && map->read_b) { + return map->read_b(addr, map->priv) | ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); } - return ret; + return 0xffff; } - void writememwl_2386(uint32_t addr, uint16_t val) { mem_mapping_t *map; - int i; - uint64_t a; + uint64_t a; addr64a[0] = addr; addr64a[1] = addr + 1; @@ -312,33 +428,37 @@ writememwl_2386(uint32_t addr, uint16_t val) high_page = 0; if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - for (i = 0; i < 2; i++) { - a = mmutranslate_write_2386(addr + i); - addr64a[i] = (uint32_t) a; + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + for (uint8_t i = 0; i < 2; i++) { + /* Do not translate a page that has a valid lookup, as that is by definition valid + and the whole purpose of the lookup is to avoid repeat identical translations. */ + if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { + a = mmutranslate_write_2386(addr + i); + addr64a[i] = (uint32_t) a; - if (a > 0xffffffffULL) - return; - } - } + if (a > 0xffffffffULL) + return; + } + } + } - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - writemembl_no_mmut(addr, addr64a[0], val); - writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); - return; - } + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + writemembl_no_mmut(addr, addr64a[0], val); + writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); + return; + } } if (cr0 >> 31) { - a = mmutranslate_write_2386(addr); - addr64a[0] = (uint32_t) a; + a = mmutranslate_write_2386(addr); + addr64a[0] = (uint32_t) a; - if (a > 0xffffffffULL) - return; + if (a > 0xffffffffULL) + return; } addr = addr64a[0] & rammask; @@ -346,64 +466,60 @@ writememwl_2386(uint32_t addr, uint16_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_w) { - map->write_w(addr, val, map->priv); - return; + map->write_w(addr, val, map->priv); + return; } if (map && map->write_b) { - map->write_b(addr, val, map->priv); - map->write_b(addr + 1, val >> 8, map->priv); - return; + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + return; } } - /* Read a word from memory without MMU translation - results of previous MMU translation passed as array. */ uint16_t readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) { mem_mapping_t *map; - uint16_t ret = 0xffff; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); mem_logical_addr = addr; if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffff; - } + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xffff; + } - return readmembl_no_mmut(addr, a64[0]) | - (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); - } + return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); + } } if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffff; + if (cpu_state.abrt || high_page) + return 0xffff; - addr = (uint32_t) (a64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else - addr &= rammask; + addr &= rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_w) - ret = map->read_w(addr, map->priv); - else if (map && map->read_b) { - ret = map->read_b(addr, map->priv) | - ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); + return map->read_w(addr, map->priv); + + if (map && map->read_b) { + return map->read_b(addr, map->priv) | ((uint16_t) (map->read_b(addr + 1, map->priv)) << 8); } - return ret; + return 0xffff; } - /* Write a word to memory without MMU translation - results of previous MMU translation passed as array. */ void writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) @@ -415,52 +531,51 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) mem_logical_addr = addr; if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - } + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffe) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + } - writemembl_no_mmut(addr, a64[0], val); - writemembl_no_mmut(addr + 1, a64[1], val >> 8); - return; - } + writemembl_no_mmut(addr, a64[0], val); + writemembl_no_mmut(addr + 1, a64[1], val >> 8); + return; + } } if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; + if (cpu_state.abrt || high_page) + return; - addr = (uint32_t) (a64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else - addr &= rammask; + addr &= rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_w) { - map->write_w(addr, val, map->priv); - return; + map->write_w(addr, val, map->priv); + return; } if (map && map->write_b) { - map->write_b(addr, val, map->priv); - map->write_b(addr + 1, val >> 8, map->priv); - return; + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + return; } } - uint32_t readmemll_2386(uint32_t addr) { mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; + int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 4; i++) - addr64a[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 4); mem_logical_addr = addr; @@ -468,44 +583,43 @@ readmemll_2386(uint32_t addr) high_page = 0; if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - for (i = 0; i < 4; i++) { - if (i == 0) { - a = mmutranslate_read_2386(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_read_2386(addr + 3); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } + if (!cpu_cyrix_alignment || (addr & 7) > 4) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + for (i = 0; i < 4; i++) { + if (i == 0) { + a = mmutranslate_read_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read_2386(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (a > 0xffffffffULL) - return 0xffff; - } - } + if (a > 0xffffffffULL) + return 0xffff; + } + } - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - return readmemwl_no_mmut(addr, addr64a) | - (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); - } + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + return readmemwl_no_mmut(addr, addr64a) | (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16); + } } if (cr0 >> 31) { - a = mmutranslate_read_2386(addr); - addr64a[0] = (uint32_t) a; + a = mmutranslate_read_2386(addr); + addr64a[0] = (uint32_t) a; - if (a > 0xffffffffULL) - return 0xffffffff; + if (a > 0xffffffffULL) + return 0xffffffff; } addr = addr64a[0] & rammask; @@ -513,31 +627,26 @@ readmemll_2386(uint32_t addr) map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) - return map->read_l(addr, map->priv); + return map->read_l(addr, map->priv); if (map && map->read_w) - return map->read_w(addr, map->priv) | - ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); + return map->read_w(addr, map->priv) | ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); if (map && map->read_b) - return map->read_b(addr, map->priv) | - ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | - ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | - ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); + return map->read_b(addr, map->priv) | ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); return 0xffffffff; } - void writememll_2386(uint32_t addr, uint32_t val) { mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; + int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 4; i++) - addr64a[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 4); mem_logical_addr = addr; @@ -545,45 +654,49 @@ writememll_2386(uint32_t addr, uint32_t val) high_page = 0; if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - for (i = 0; i < 4; i++) { - if (i == 0) { - a = mmutranslate_write_2386(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_write_2386(addr + 3); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } + if (!cpu_cyrix_alignment || (addr & 7) > 4) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + for (i = 0; i < 4; i++) { + /* Do not translate a page that has a valid lookup, as that is by definition valid + and the whole purpose of the lookup is to avoid repeat identical translations. */ + if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { + if (i == 0) { + a = mmutranslate_write_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write_2386(addr + 3); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (a > 0xffffffffULL) - return; - } - } + if (a > 0xffffffffULL) + return; + } + } + } - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - writememwl_no_mmut(addr, &(addr64a[0]), val); - writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); - return; - } + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + writememwl_no_mmut(addr, &(addr64a[0]), val); + writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); + return; + } } if (cr0 >> 31) { - a = mmutranslate_write_2386(addr); - addr64a[0] = (uint32_t) a; + a = mmutranslate_write_2386(addr); + addr64a[0] = (uint32_t) a; - if (a > 0xffffffffULL) - return; + if (a > 0xffffffffULL) + return; } addr = addr64a[0] & rammask; @@ -591,24 +704,23 @@ writememll_2386(uint32_t addr, uint32_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_l) { - map->write_l(addr, val, map->priv); - return; + map->write_l(addr, val, map->priv); + return; } if (map && map->write_w) { - map->write_w(addr, val, map->priv); - map->write_w(addr + 2, val >> 16, map->priv); - return; + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + return; } if (map && map->write_b) { - map->write_b(addr, val, map->priv); - map->write_b(addr + 1, val >> 8, map->priv); - map->write_b(addr + 2, val >> 16, map->priv); - map->write_b(addr + 3, val >> 24, map->priv); - return; + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + return; } } - /* Read a long from memory without MMU translation - results of previous MMU translation passed as array. */ uint32_t readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) @@ -620,46 +732,40 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) mem_logical_addr = addr; if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffffffff; - } + if (!cpu_cyrix_alignment || (addr & 7) > 4) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return 0xffffffff; + } - return readmemwl_no_mmut(addr, a64) | - ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); - } + return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); + } } if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return 0xffffffff; + if (cpu_state.abrt || high_page) + return 0xffffffff; - addr = (uint32_t) (a64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else - addr &= rammask; + addr &= rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) - return map->read_l(addr, map->priv); + return map->read_l(addr, map->priv); if (map && map->read_w) - return map->read_w(addr, map->priv) | - ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); + return map->read_w(addr, map->priv) | ((uint32_t) (map->read_w(addr + 2, map->priv)) << 16); if (map && map->read_b) - return map->read_b(addr, map->priv) | - ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | - ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | - ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); + return map->read_b(addr, map->priv) | ((uint32_t) (map->read_b(addr + 1, map->priv)) << 8) | ((uint32_t) (map->read_b(addr + 2, map->priv)) << 16) | ((uint32_t) (map->read_b(addr + 3, map->priv)) << 24); return 0xffffffff; } - /* Write a long to memory without MMU translation - results of previous MMU translation passed as array. */ void writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) @@ -671,58 +777,57 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) mem_logical_addr = addr; if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; - } + if (!cpu_cyrix_alignment || (addr & 7) > 4) + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (cpu_state.abrt || high_page) + return; + } - writememwl_no_mmut(addr, &(a64[0]), val); - writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); - return; - } + writememwl_no_mmut(addr, &(a64[0]), val); + writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); + return; + } } if (cr0 >> 31) { - if (cpu_state.abrt || high_page) - return; + if (cpu_state.abrt || high_page) + return; - addr = (uint32_t) (a64[0] & rammask); + addr = (uint32_t) (a64[0] & rammask); } else - addr &= rammask; + addr &= rammask; map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_l) { - map->write_l(addr, val, map->priv); - return; + map->write_l(addr, val, map->priv); + return; } if (map && map->write_w) { - map->write_w(addr, val, map->priv); - map->write_w(addr + 2, val >> 16, map->priv); - return; + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + return; } if (map && map->write_b) { - map->write_b(addr, val, map->priv); - map->write_b(addr + 1, val >> 8, map->priv); - map->write_b(addr + 2, val >> 16, map->priv); - map->write_b(addr + 3, val >> 24, map->priv); - return; + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + return; } } - uint64_t readmemql_2386(uint32_t addr) { mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; + int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 8; i++) - addr64a[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_READ, 8); mem_logical_addr = addr; @@ -730,64 +835,62 @@ readmemql_2386(uint32_t addr) high_page = 0; if (addr & 7) { - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xff8) { - if (cr0 >> 31) { - for (i = 0; i < 8; i++) { - if (i == 0) { - a = mmutranslate_read_2386(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_read_2386(addr + 7); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xff8) { + if (cr0 >> 31) { + for (i = 0; i < 8; i++) { + if (i == 0) { + a = mmutranslate_read_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_read_2386(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (a > 0xffffffffULL) - return 0xffff; - } - } + if (a > 0xffffffffULL) + return 0xffff; + } + } - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - return readmemll_no_mmut(addr, addr64a) | - (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); - } + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + return readmemll_no_mmut(addr, addr64a) | (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32); + } } if (cr0 >> 31) { - a = mmutranslate_read_2386(addr); + a = mmutranslate_read_2386(addr); addr64a[0] = (uint32_t) a; - if (a > 0xffffffffULL) - return 0xffffffffffffffffULL; + if (a > 0xffffffffULL) + return 0xffffffffffffffffULL; } addr = addr64a[0] & rammask; map = read_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->read_l) - return map->read_l(addr, map->priv) | ((uint64_t)map->read_l(addr + 4, map->priv) << 32); + return map->read_l(addr, map->priv) | ((uint64_t) map->read_l(addr + 4, map->priv) << 32); return readmemll(addr) | ((uint64_t) readmemll(addr + 4) << 32); } - void writememql_2386(uint32_t addr, uint64_t val) { mem_mapping_t *map; - int i; - uint64_t a = 0x0000000000000000ULL; + int i; + uint64_t a = 0x0000000000000000ULL; for (i = 0; i < 8; i++) - addr64a[i] = (uint64_t) (addr + i); + addr64a[i] = (uint64_t) (addr + i); GDBSTUB_MEM_ACCESS_FAST(addr64a, GDBSTUB_MEM_WRITE, 8); mem_logical_addr = addr; @@ -795,42 +898,46 @@ writememql_2386(uint32_t addr, uint64_t val) high_page = 0; if (addr & 7) { - cycles -= timing_misaligned; - if ((addr & 0xfff) > 0xff8) { - if (cr0 >> 31) { - for (i = 0; i < 8; i++) { - if (i == 0) { - a = mmutranslate_write_2386(addr + i); - addr64a[i] = (uint32_t) a; - } else if (!((addr + i) & 0xfff)) { - a = mmutranslate_write_2386(addr + 7); - addr64a[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } - } else { - a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); - addr64a[i] = (uint32_t) a; - } + cycles -= timing_misaligned; + if ((addr & 0xfff) > 0xff8) { + if (cr0 >> 31) { + for (i = 0; i < 8; i++) { + /* Do not translate a page that has a valid lookup, as that is by definition valid + and the whole purpose of the lookup is to avoid repeat identical translations. */ + if (!page_lookup[(addr + i) >> 12] || !page_lookup[(addr + i) >> 12]->write_b) { + if (i == 0) { + a = mmutranslate_write_2386(addr + i); + addr64a[i] = (uint32_t) a; + } else if (!((addr + i) & 0xfff)) { + a = mmutranslate_write_2386(addr + 7); + addr64a[i] = (uint32_t) a; + if (!cpu_state.abrt) { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } + } else { + a = (a & ~0xfffLL) | ((uint64_t) ((addr + i) & 0xfff)); + addr64a[i] = (uint32_t) a; + } - if (addr64a[i] > 0xffffffffULL) - return; - } - } + if (addr64a[i] > 0xffffffffULL) + return; + } + } + } - /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass - their result as a parameter to be used if needed. */ - writememll_no_mmut(addr, addr64a, val); - writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); - return; - } + /* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass + their result as a parameter to be used if needed. */ + writememll_no_mmut(addr, addr64a, val); + writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); + return; + } } if (cr0 >> 31) { - addr64a[0] = mmutranslate_write_2386(addr); - if (addr64a[0] > 0xffffffffULL) - return; + addr64a[0] = mmutranslate_write_2386(addr); + if (addr64a[0] > 0xffffffffULL) + return; } addr = addr64a[0] & rammask; @@ -838,31 +945,30 @@ writememql_2386(uint32_t addr, uint64_t val) map = write_mapping[addr >> MEM_GRANULARITY_BITS]; if (map && map->write_l) { - map->write_l(addr, val, map->priv); - map->write_l(addr + 4, val >> 32, map->priv); - return; + map->write_l(addr, val, map->priv); + map->write_l(addr + 4, val >> 32, map->priv); + return; } if (map && map->write_w) { - map->write_w(addr, val, map->priv); - map->write_w(addr + 2, val >> 16, map->priv); - map->write_w(addr + 4, val >> 32, map->priv); - map->write_w(addr + 6, val >> 48, map->priv); - return; + map->write_w(addr, val, map->priv); + map->write_w(addr + 2, val >> 16, map->priv); + map->write_w(addr + 4, val >> 32, map->priv); + map->write_w(addr + 6, val >> 48, map->priv); + return; } if (map && map->write_b) { - map->write_b(addr, val, map->priv); - map->write_b(addr + 1, val >> 8, map->priv); - map->write_b(addr + 2, val >> 16, map->priv); - map->write_b(addr + 3, val >> 24, map->priv); - map->write_b(addr + 4, val >> 32, map->priv); - map->write_b(addr + 5, val >> 40, map->priv); - map->write_b(addr + 6, val >> 48, map->priv); - map->write_b(addr + 7, val >> 56, map->priv); - return; + map->write_b(addr, val, map->priv); + map->write_b(addr + 1, val >> 8, map->priv); + map->write_b(addr + 2, val >> 16, map->priv); + map->write_b(addr + 3, val >> 24, map->priv); + map->write_b(addr + 4, val >> 32, map->priv); + map->write_b(addr + 5, val >> 40, map->priv); + map->write_b(addr + 6, val >> 48, map->priv); + map->write_b(addr + 7, val >> 56, map->priv); + return; } } - void do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) { @@ -875,29 +981,29 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) for (i = 0; i < num; i++) { if (cr0 >> 31) { - /* If we have encountered at least one page fault, mark all subsequent addresses as - having page faulted, prevents false negatives in readmem*l_no_mmut. */ - if ((i > 0) && cpu_state.abrt && !high_page) - a64[i] = a64[i - 1]; - /* If we are on the same page, there is no need to translate again, as we can just - reuse the previous result. */ - else if (i == 0) { - a = mmutranslatereal_2386(addr, write); - a64[i] = (uint32_t) a; - } else if (!(addr & 0xfff)) { - a = mmutranslatereal_2386(last_addr, write); - a64[i] = (uint32_t) a; + /* If we have encountered at least one page fault, mark all subsequent addresses as + having page faulted, prevents false negatives in readmem*l_no_mmut. */ + if ((i > 0) && cpu_state.abrt && !high_page) + a64[i] = a64[i - 1]; + /* If we are on the same page, there is no need to translate again, as we can just + reuse the previous result. */ + else if (i == 0) { + a = mmutranslatereal_2386(addr, write); + a64[i] = (uint32_t) a; + } else if (!(addr & 0xfff)) { + a = mmutranslatereal_2386(last_addr, write); + a64[i] = (uint32_t) a; - if (!cpu_state.abrt) { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } else { - a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); - a64[i] = (uint32_t) a; - } - } + if (!cpu_state.abrt) { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } else { + a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); + a64[i] = (uint32_t) a; + } + } - addr++; + addr++; } } diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po new file mode 100644 index 000000000..47ee23990 --- /dev/null +++ b/src/qt/languages/ca-ES.po @@ -0,0 +1,1221 @@ +msgid "&Action" +msgstr "&Acció" + +msgid "&Keyboard requires capture" +msgstr "&Teclat requereix captura" + +msgid "&Right CTRL is left ALT" +msgstr "CTRL &dret és ALT esquerre" + +msgid "&Hard Reset..." +msgstr "&Reinicialització completa..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pausa" + +msgid "E&xit..." +msgstr "&Sortir..." + +msgid "&View" +msgstr "&Vista" + +msgid "&Hide status bar" +msgstr "&Amagar barra d'estat" + +msgid "Hide &toolbar" +msgstr "Amagar &barra d'eines" + +msgid "&Resizeable window" +msgstr "&Finestra redimensionable" + +msgid "R&emember size && position" +msgstr "&Recordar mida i posició" + +msgid "Re&nderer" +msgstr "Re&nderitzador" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "E&specificar dimensions..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orçar ràtio 4:3" + +msgid "&Window scale factor" +msgstr "&Factor d'escalat de finestra" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "&Mètode de filtrat" + +msgid "&Nearest" +msgstr "&Més proper" + +msgid "&Linear" +msgstr "&Lineal" + +msgid "Hi&DPI scaling" +msgstr "&Escalat alta densitat" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "&Pantalla completa\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "Escalat pantalla completa" + +msgid "&Full screen stretch" +msgstr "&Estirar" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Píxels quadrats (Mant. aspecte)" + +msgid "&Integer scale" +msgstr "&Escalat valor sencer" + +msgid "E&GA/(S)VGA settings" +msgstr "&Ajustaments EGA/(S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Monitor VGA invertit" + +msgid "VGA screen &type" +msgstr "&Tipus de pantalla VGA" + +msgid "RGB &Color" +msgstr "RGB &Color" + +msgid "&RGB Grayscale" +msgstr "RGB &Grisos" + +msgid "&Amber monitor" +msgstr "Monitor & Ambre" + +msgid "&Green monitor" +msgstr "Monitor &Verd" + +msgid "&White monitor" +msgstr "Monitor &Blanc" + +msgid "Grayscale &conversion type" +msgstr "&Conversió a grisos" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Mitjana" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "&Overscan CGA/PCjr/Tandy/EGA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "Canviar contrast per a pantalla &monocroma" + +msgid "&Media" +msgstr "&Mitjans" + +msgid "&Tools" +msgstr "&Eines" + +msgid "&Settings..." +msgstr "&Ajustaments..." + +msgid "&Update status bar icons" +msgstr "&Actualitzar icones a la barra d'estat" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Prendre c&aptura\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Preferències..." + +msgid "Enable &Discord integration" +msgstr "Habilita la integració amb el &Discord" + +msgid "Sound &gain..." +msgstr "&Guany de so..." + +msgid "Begin trace\tCtrl+T" +msgstr "Començar traça\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Acabar traça\tCtrl+T" + +msgid "&Help" +msgstr "&Ajuda" + +msgid "&Documentation..." +msgstr "&Documentació..." + +msgid "&About 86Box..." +msgstr "&Quant a 86Box..." + +msgid "&New image..." +msgstr "&Nova imatge..." + +msgid "&Existing image..." +msgstr "Imatge &Existent..." + +msgid "Existing image (&Write-protected)..." +msgstr "Imatge Existent (&Només-lectura)..." + +msgid "&Record" +msgstr "&Gravar" + +msgid "&Play" +msgstr "&Reproduir" + +msgid "&Rewind to the beginning" +msgstr "&Rebobinar a l'inici" + +msgid "&Fast forward to the end" +msgstr "&Avanç ràpid al final" + +msgid "E&ject" +msgstr "E&xtreure" + +msgid "&Image..." +msgstr "&Imatge..." + +msgid "E&xport to 86F..." +msgstr "E&xportar a 86F..." + +msgid "&Mute" +msgstr "&Silenciar" + +msgid "E&mpty" +msgstr "E&xtreure disc" + +msgid "&Reload previous image" +msgstr "&Recarregar imatge prèvia" + +msgid "&Folder..." +msgstr "&Carpeta..." + +msgid "Target &framerate" +msgstr "&Taxa de refresc objectiu" + +msgid "&Sync with video" +msgstr "&Sincronitzar amb vídeo" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Seleccionar shader..." + +msgid "&Remove shader" +msgstr "&Eliminar shader" + +msgid "Preferences" +msgstr "Preferències" + +msgid "Sound Gain" +msgstr "Guany de So" + +msgid "New Image" +msgstr "Nova Imatge" + +msgid "Settings" +msgstr "Ajustaments" + +msgid "Specify Main Window Dimensions" +msgstr "Especificar Dimensions de la Finestra Principal" + +msgid "OK" +msgstr "D'acord" + +msgid "Cancel" +msgstr "Anuŀlació" + +msgid "Save these settings as &global defaults" +msgstr "Salvar aquests paràmetres com per &defecte globalment" + +msgid "&Default" +msgstr "&Per defecte" + +msgid "Language:" +msgstr "Idioma:" + +msgid "Icon set:" +msgstr "Conjunt d'icones:" + +msgid "Gain" +msgstr "Guany" + +msgid "File name:" +msgstr "Nom del fitxer:" + +msgid "Disk size:" +msgstr "Grandària de disc:" + +msgid "RPM mode:" +msgstr "Mode RPM:" + +msgid "Progress:" +msgstr "Progrés:" + +msgid "Width:" +msgstr "Amplada:" + +msgid "Height:" +msgstr "Alçada:" + +msgid "Lock to this size" +msgstr "Bloquejar aquesta mida" + +msgid "Machine type:" +msgstr "Tipus de màquina:" + +msgid "Machine:" +msgstr "Màquina:" + +msgid "Configure" +msgstr "Configurar" + +msgid "CPU type:" +msgstr "Tipus de CPU:" + +msgid "Speed:" +msgstr "Velocitat:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Estats en espera:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Memòria:" + +msgid "Time synchronization" +msgstr "Sincronització horària" + +msgid "Disabled" +msgstr "Desactuvat" + +msgid "Enabled (local time)" +msgstr "Activat (hora local)" + +msgid "Enabled (UTC)" +msgstr "Activat (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Recopilador Dinàmic" + +msgid "Video:" +msgstr "Vídeo:" + +msgid "Voodoo Graphics" +msgstr "Gràfics Voodoo" + +msgid "IBM 8514/a Graphics" +msgstr "Gràfics IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Gràfics XGA" + +msgid "Mouse:" +msgstr "Ratolí:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card 1:" +msgstr "Targeta de so 1:" + +msgid "Sound card 2:" +msgstr "Targeta de so 2:" + +msgid "Sound card 3:" +msgstr "Targeta de so 3:" + +msgid "Sound card 4:" +msgstr "Targeta de so 4:" + +msgid "MIDI Out Device:" +msgstr "Dispositiu de sortida MIDI:" + +msgid "MIDI In Device:" +msgstr "Dispositiu d'entrada MIDI:" + +msgid "Standalone MPU-401" +msgstr "MPU-401 autònom" + +msgid "Use FLOAT32 sound" +msgstr "Usar so FLOAT32" + +msgid "FM synth driver" +msgstr "Manejador de sintet. FM" + +msgid "Nuked (more accurate)" +msgstr "Nuked (més acurat)" + +msgid "YMFM (faster)" +msgstr "YMFM (més ràpid)" + +msgid "Network type:" +msgstr "Tipus de xarxa:" + +msgid "PCap device:" +msgstr "Dispositiu PCap:" + +msgid "Network adapter:" +msgstr "Adaptador de xarxa:" + +msgid "COM1 Device:" +msgstr "Dispositiu COM1:" + +msgid "COM2 Device:" +msgstr "Dispositiu COM2:" + +msgid "COM3 Device:" +msgstr "Dispositiu COM3:" + +msgid "COM4 Device:" +msgstr "Dispositiu COM4:" + +msgid "LPT1 Device:" +msgstr "Dispositiu LPT1:" + +msgid "LPT2 Device:" +msgstr "Dispositiu LPT2:" + +msgid "LPT3 Device:" +msgstr "Dispositiu LPT3:" + +msgid "LPT4 Device:" +msgstr "Dispositiu LPT4:" + +msgid "Serial port 1" +msgstr "Port sèrie 1" + +msgid "Serial port 2" +msgstr "Port sèrie 2" + +msgid "Serial port 3" +msgstr "Port sèrie 3" + +msgid "Serial port 4" +msgstr "Port sèrie 4" + +msgid "Parallel port 1" +msgstr "Port paral·lel 1" + +msgid "Parallel port 2" +msgstr "Port paral·lel 2" + +msgid "Parallel port 3" +msgstr "Port paral·lel 3" + +msgid "Parallel port 4" +msgstr "Port paral·lel 4" + +msgid "HD Controller:" +msgstr "Controlador de HD:" + +msgid "FD Controller:" +msgstr "Controlador de FD:" + +msgid "Tertiary IDE Controller" +msgstr "Controlador IDE terciari" + +msgid "Quaternary IDE Controller" +msgstr "Controlador IDE quaternari" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controlador 1:" + +msgid "Controller 2:" +msgstr "Controlador 2:" + +msgid "Controller 3:" +msgstr "Controlador 3:" + +msgid "Controller 4:" +msgstr "Controlador 4:" + +msgid "Cassette" +msgstr "Casset" + +msgid "Hard disks:" +msgstr "Discs durs:" + +msgid "&New..." +msgstr "&Nou..." + +msgid "&Existing..." +msgstr "&Existent..." + +msgid "&Remove" +msgstr "E&liminar" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Canal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "E&specificar..." + +msgid "Sectors:" +msgstr "Sectors:" + +msgid "Heads:" +msgstr "Caps:" + +msgid "Cylinders:" +msgstr "Cilindres:" + +msgid "Size (MB):" +msgstr "Mida (MB):" + +msgid "Type:" +msgstr "Tipus:" + +msgid "Image Format:" +msgstr "Format d'imatge:" + +msgid "Block Size:" +msgstr "Mida del bloc:" + +msgid "Floppy drives:" +msgstr "Unitats de disquet:" + +msgid "Turbo timings" +msgstr "Temps turbo" + +msgid "Check BPB" +msgstr "Comprovar BPB" + +msgid "CD-ROM drives:" +msgstr "Unitats de CD-ROM:" + +msgid "Earlier drive" +msgstr "Unitat anterior" + +msgid "MO drives:" +msgstr "Unitats MO:" + +msgid "ZIP drives:" +msgstr "Unitats ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "Expansió de memòria ISA" + +msgid "Card 1:" +msgstr "Targeta 1:" + +msgid "Card 2:" +msgstr "Targeta 2:" + +msgid "Card 3:" +msgstr "Targeta 3:" + +msgid "Card 4:" +msgstr "Targeta 4:" + +msgid "ISABugger device" +msgstr "Dispositiu ISABugger" + +msgid "POST card" +msgstr "Targeta POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Error" + +msgid "Fatal error" +msgstr "Error fatal" + +msgid " - PAUSED" +msgstr " - EN PAUSA" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Premeu Ctrl+Alt+PgDn per tornar al mode de finestra." + +msgid "Speed" +msgstr "Velocitat" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Imatges ZIP" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box no ha pogut trobar cap imatge ROM utilitzable.\n\nSi us plau, descarregueu un conjunt de ROM i extreu-lo al directori \"roms\"." + +msgid "(empty)" +msgstr "(buit)" + +msgid "All files" +msgstr "Tots els fitxers" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "On" + +msgid "Off" +msgstr "Off" + +msgid "All images" +msgstr "Totes les imatges" + +msgid "Basic sector images" +msgstr "Imatges sectorials bàsiques" + +msgid "Surface images" +msgstr "Imatges superficials" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "La màquina \"%hs\" no està disponible perquè falten ROM al directori roms/machines. Canvi a una màquina disponible." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "La targeta de vídeo \"%hs\" no està disponible perquè falten ROM al directori roms/video. Canvi a una targeta de vídeo disponible." + +msgid "Machine" +msgstr "Màquina" + +msgid "Display" +msgstr "Vídeo" + +msgid "Input devices" +msgstr "Dispositius d'entrada" + +msgid "Sound" +msgstr "So" + +msgid "Network" +msgstr "Xarxa" + +msgid "Ports (COM & LPT)" +msgstr "Ports (COM i LPT)" + +msgid "Storage controllers" +msgstr "Controladors d'emmagatzematge" + +msgid "Hard disks" +msgstr "Discs durs" + +msgid "Floppy & CD-ROM drives" +msgstr "Unitats de disquet i CD-ROM" + +msgid "Other removable devices" +msgstr "Altres dispositius extraïbles" + +msgid "Other peripherals" +msgstr "Altres perifèrics" + +msgid "Click to capture mouse" +msgstr "Feu clic per capturar el ratolí" + +msgid "Press F8+F12 to release mouse" +msgstr "Premeu F8+F12 per alliberar el ratolí" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Premeu F8+F12 o el botó central per alliberar el ratolí" + +msgid "Bus" +msgstr "Bus" + +msgid "File" +msgstr "Fitxer" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "No has estat possible inicialitzar el renderitzador de vídeo." + +msgid "Default" +msgstr "Per defecte" + +msgid "%i estat(s) d'espera" +msgstr "%i estado(s) de Espera" + +msgid "Type" +msgstr "Tipus" + +msgid "Failed to set up PCap" +msgstr "No s'ha pogut configurar PCap" + +msgid "No PCap devices found" +msgstr "No s'han trobat dispositius PCap" + +msgid "Invalid PCap device" +msgstr "El dispositiu PCap no és vàlid" + +msgid "Standard 2-button joystick(s)" +msgstr "Joystick(s) estàndard de 2 botons" + +msgid "Standard 4-button joystick" +msgstr "Joystick(s) estàndard de 4 botons" + +msgid "Standard 6-button joystick" +msgstr "Joystick(s) estàndard de 6 botons" + +msgid "Standard 8-button joystick" +msgstr "Joystick(s) estàndard de 8 botons" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Cap" + +msgid "Unable to load keyboard accelerators." +msgstr "No has estat possible carregar els acceleradors del teclat." + +msgid "Unable to register raw input." +msgstr "No has estat possible registrar l'entrada en brut." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disquet %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Imatges avançates del sector" + +msgid "Flux images" +msgstr "Imatges de flux" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "No has estat possible inicialitzar SDL, és necessari SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Esteu segur que voleu restablir la màquina emulada?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Esteu segur que voleu sortir de 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "No es pot inicialitzar Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Imatges MO" + +msgid "Welcome to 86Box!" +msgstr "Benvingut a 86Box!" + +msgid "Internal controller" +msgstr "Controlador intern" + +msgid "Exit" +msgstr "Sortir" + +msgid "No ROMs found" +msgstr "No s'ha trobat cap ROM" + +msgid "Do you want to save the settings?" +msgstr "Voleu desar les configuracions?" + +msgid "This will hard reset the emulated machine." +msgstr "Es farà una reinicialització completa de la màquina emulada." + +msgid "Save" +msgstr "Desar" + +msgid "About 86Box" +msgstr "Quant a 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Un emulador d'ordinadors antics\n\nAutors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho i altres.\n\nAlliberat sota la GNU General Public License versió 2 o posterior. Veure LLICENSE per a més informació." + +msgid "Hardware not available" +msgstr "Maquinari no disponible" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Assegureu-vos que el libpcap està instal·lat i que està en una connexió de xarxa compatible amb libpcap." + +msgid "Invalid configuration" +msgstr "Configuració invàlida" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " és necessària per a la conversió automàtica de fitxers PostScript a PDF.\n\nQualsevol document enviat a la impressora genèrica postScript es desarà com a fitxer PostScript (.ps)." + +msgid "Entering fullscreen mode" +msgstr "Entrant en mode pantalla completa" + +msgid "Don't show this message again" +msgstr "No mostreu més aquest missatge" + +msgid "Don't exit" +msgstr "No sortir" + +msgid "Reset" +msgstr "Resetejar" + +msgid "Don't reset" +msgstr "No resetejar" + +msgid "CD-ROM images" +msgstr "Imatges de CD-ROM" + +msgid "%hs Device Configuration" +msgstr "%hs Configuració de Dispositiu" + +msgid "Monitor in sleep mode" +msgstr "Monitor en mode estalvi" + +msgid "OpenGL Shaders" +msgstr "Shaders OpenGL" + +msgid "OpenGL options" +msgstr "Opcions OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "S'està carregant una configuració no suportada" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "El Filtratge de tipus de CPU basat en màquina seleccionada està deshabilitat per a aquesta màquina.\n\nAixò fa possible seleccionar una CPU que sigui incompatible amb aquesta màquina. Per això, poden aparèixer incompatibilitat amb la BIOS de la màquina o un altre programari.\n\nActivar aquest ajustament no està oficialment suportat i qualsevol informe de fallada pot ser tancat com a invàlid." + +msgid "Continue" +msgstr "Continuar" + +msgid "Cassette: %s" +msgstr "Casset: %s" + +msgid "Cassette images" +msgstr "Imatges de casset" + +msgid "Cartridge %i: %ls" +msgstr "Cartutx %i: %ls" + +msgid "Cartridge images" +msgstr "Imatges de cartutx" + +msgid "Error initializing renderer" +msgstr "Error en inicialitzar el renderitzador" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "No has estat possible inicialitzar el renderitzador OpenGL (3.0 Core). Utilitzar un altre renderitzador." + +msgid "Resume execution" +msgstr "Reprendre l'execució" + +msgid "Pause execution" +msgstr "Pausar l'execució" + +msgid "Press Ctrl+Alt+Del" +msgstr "Pulsar Ctrl+Alt+Supr" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Pulsar Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Reinicialització completa" + +msgid "ACPI shutdown" +msgstr "Apagada ACPI" + +msgid "Hard disk (%s)" +msgstr "Disc dur (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "Les unitats de CD-ROM MFM/RLL o ESDI no van existir mai" + +msgid "Custom..." +msgstr "Personalitzat..." + +msgid "Custom (large)..." +msgstr "Personalitzat (gran)..." + +msgid "Add New Hard Disk" +msgstr "Afegir disc dur nou" + +msgid "Add Existing Hard Disk" +msgstr "Afegir disc dur existent" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Les imatges de disc HDI no poden superar els 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Les imatges del disc no poden superar els 127 GB." + +msgid "Hard disk images" +msgstr "Imatges del disc dur" + +msgid "Unable to read file" +msgstr "No has estat possible llegir el fitxer" + +msgid "Unable to write file" +msgstr "No has estat possible escriure el fitxer" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Les imatges HDI o HDX amb una mida de sector diferent de 512 no s'admeten." + +msgid "USB is not yet supported" +msgstr "L'USB encara no s'admete" + +msgid "Disk image file already exists" +msgstr "El fitxer d'imatge de disc ja existeix" + +msgid "Please specify a valid file name." +msgstr "Especifiqueu un nom de fitxer vàlid." + +msgid "Disk image created" +msgstr "La imatge de disc ha estat creada" + +msgid "Make sure the file exists and is readable." +msgstr "Assegureu-vos que el fitxer existeix i és llegible." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Assegureu-vos que el fitxer s'està desant en un directori que es pugui escriure." + +msgid "Disk image too large" +msgstr "La imatge del disc és massa gran" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Recordeu particionar i formatar la unitat de nova creació." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "El fitxer seleccionat se sobreescriurà. Esteu segur que voleu utilitzar-lo?" + +msgid "Unsupported disk image" +msgstr "Imatge de disc no compatible" + +msgid "Overwrite" +msgstr "Sobreescriure" + +msgid "Don't overwrite" +msgstr "No sobreescriure" + +msgid "Raw image (.img)" +msgstr "Imatge crua (.img)" + +msgid "HDI image (.hdi)" +msgstr "Imatge HDI (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "Imatge HDX (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD de mida fixa (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD de mida dinàmica (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "VHD diferencial (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Blocs grans (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Blocs petits (512 KB)" + +msgid "VHD files" +msgstr "Fitxers VHD" + +msgid "Select the parent VHD" +msgstr "Seleccioneu el VHD pare" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "Això pot ser perquè la imatge pare es va modificar després que la imatge diferencial es creés.\n\nTambé pot passar si les imatges van ser mogudes o copiades, o per una fallada al programa que va crear aquest disc.\n\n¿ Voleu corregir els registres de temps?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Les marques de temps del pare i el fill no coincideixen" + +msgid "Could not fix VHD timestamp." +msgstr "No has estat possible corregir la marca de temps del VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (clúster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (clúster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5\" 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5\" 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25\" 1.3 GB" + +msgid "Perfect RPM" +msgstr "RPM perfectes" + +msgid "1% below perfect RPM" +msgstr "1% per sota de RPM perfectes" + +msgid "1.5% below perfect RPM" +msgstr "1.5% per sota de RPM perfectes" + +msgid "2% below perfect RPM" +msgstr "2% per sota de RPM perfectes" + +msgid "(System Default)" +msgstr "(Per defecte del sistema)" + +msgid "Failed to initialize network driver" +msgstr "No has estat possible inicialitzar el controlador de xarxa" + +msgid "The network configuration will be switched to the null driver" +msgstr "La configuració de la xarxa es canviarà al controlador nul" + +msgid "Mouse sensitivity:" +msgstr "Sensibilitat del ratolí:" + +msgid "Select media images from program working directory" +msgstr "Seleccioneu imatges multimèdia del directori de treball del programa" + +msgid "PIT mode:" +msgstr "Mode PIT:" + +msgid "Auto" +msgstr "Automàtic" + +msgid "Slow" +msgstr "Lent" + +msgid "Fast" +msgstr "Ràpid" + diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index bb7fd342e..ec543dbbc 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1201,6 +1201,12 @@ msgstr "Nepodařilo se inicializovat síťový ovladač" msgid "The network configuration will be switched to the null driver" msgstr "Konfigurace sítě bude přepnuta na nulový ovladač" +msgid "Mouse sensitivity:" +msgstr "Citlivost myší:" + +msgid "Select media images from program working directory" +msgstr "Výběr mediálních obrazů z pracovního adresáře programu" + msgid "PIT mode:" msgstr "Režim PIT:" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index e494d4910..80deb7d08 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1201,6 +1201,12 @@ msgstr "Netzwerktreiber konnte nicht initialisiert werden" msgid "The network configuration will be switched to the null driver" msgstr "Die Netzwerkkonfiguration wird auf den Nulltreiber umgestellt" +msgid "Mouse sensitivity:" +msgstr "Empfindlichkeit der Maus:" + +msgid "Select media images from program working directory" +msgstr "Medienbilder aus dem Arbeitsverzeichnis des Programms auswählen" + msgid "PIT mode:" msgstr "PIT-Modus:" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index d696a7ae2..d1288d5eb 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -1201,6 +1201,12 @@ msgstr "Failed to initialize network driver" msgid "The network configuration will be switched to the null driver" msgstr "The network configuration will be switched to the null driver" +msgid "Mouse sensitivity:" +msgstr "Mouse sensitivity:" + +msgid "Select media images from program working directory" +msgstr "Select media images from program working directory" + msgid "PIT mode:" msgstr "PIT mode:" diff --git a/src/qt/languages/en-US.po b/src/qt/languages/en-US.po index 8e8663566..31dc611be 100644 --- a/src/qt/languages/en-US.po +++ b/src/qt/languages/en-US.po @@ -1201,6 +1201,12 @@ msgstr "Failed to initialize network driver" msgid "The network configuration will be switched to the null driver" msgstr "The network configuration will be switched to the null driver" +msgid "Mouse sensitivity:" +msgstr "Mouse sensitivity:" + +msgid "Select media images from program working directory" +msgstr "Select media images from program working directory" + msgid "PIT mode:" msgstr "PIT mode:" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index c9cd2bb6a..c488208a4 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -29,7 +29,7 @@ msgid "&Hide status bar" msgstr "&Ocultar barra de estado" msgid "Hide &toolbar" -msgstr "Hide &toolbar" +msgstr "Ocultar &barra de herramientas" msgid "&Resizeable window" msgstr "&Ventana redimensionable" @@ -125,7 +125,7 @@ msgid "&Integer scale" msgstr "&Escalado valor entero" msgid "E&GA/(S)VGA settings" -msgstr "&Ajustes EGA/(S)VGA" +msgstr "&Configuraciones EGA/(S)VGA" msgid "&Inverted VGA monitor" msgstr "&Monitor VGA invertido" @@ -173,7 +173,7 @@ msgid "&Tools" msgstr "&Herramientas" msgid "&Settings..." -msgstr "&Ajustes..." +msgstr "&Configuraciones..." msgid "&Update status bar icons" msgstr "&Actualizar iconos en barra de estado" @@ -287,7 +287,7 @@ msgid "New Image" msgstr "Nueva Imagen" msgid "Settings" -msgstr "Ajustes" +msgstr "Configuraciones" msgid "Specify Main Window Dimensions" msgstr "Especificar Dimensiones de la Ventana Principal" @@ -299,7 +299,7 @@ msgid "Cancel" msgstr "Cancelar" msgid "Save these settings as &global defaults" -msgstr "Salvar estos ajustes como por &defecto globalmente" +msgstr "Salvar estos configuraciones como por &defecto globalmente" msgid "&Default" msgstr "&Por defecto" @@ -650,13 +650,13 @@ msgid "ZIP images" msgstr "Imagenes ZIP" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descarga un grupo de imágenes y extráelas en el directorio \"roms\"." +msgstr "86Box no pudo encontrar ninguna imagen ROM usable.\n\nPor favor descargue un conjunte de ROMs y extráigalo en el directorio \"roms\"." msgid "(empty)" msgstr "(vacío)" msgid "All files" -msgstr "All files" +msgstr "Todos los archivos" msgid "Turbo" msgstr "Turbo" @@ -716,13 +716,13 @@ msgid "Other peripherals" msgstr "Otros periféricos" msgid "Click to capture mouse" -msgstr "Haz click para capturar el ratón" +msgstr "Haga click para capturar el ratón" msgid "Press F8+F12 to release mouse" -msgstr "Pulsa F8+F12 para liberar el ratón" +msgstr "Pulse F8+F12 para liberar el ratón" msgid "Press F8+F12 or middle button to release mouse" -msgstr "Pulsa F8+F12 o el botón central para liberar el ratón" +msgstr "Pulse F8+F12 o el botón central para liberar el ratón" msgid "Bus" msgstr "Bus" @@ -743,7 +743,7 @@ msgid "KB" msgstr "KB" msgid "Could not initialize the video renderer." -msgstr "Incapaz de inicializar el renderizador de vídeo." +msgstr "No fué posible inicializar el renderizador de vídeo." msgid "Default" msgstr "Por defecto" @@ -788,10 +788,10 @@ msgid "None" msgstr "Ninguno" msgid "Unable to load keyboard accelerators." -msgstr "Incapaz de cargar aceleradores de teclado." +msgstr "No fué posible cargar aceleradores de teclado." msgid "Unable to register raw input." -msgstr "Incapaz de registrar entrada directa." +msgstr "No fué posible registrar entrada directa." msgid "%u" msgstr "%u" @@ -803,22 +803,22 @@ msgid "Floppy %i (%s): %ls" msgstr "Disquete %i (%s): %ls" msgid "Advanced sector images" -msgstr "Advanced sector images" +msgstr "Imágenes avanzadas de sector" msgid "Flux images" -msgstr "Flux images" +msgstr "Imágenes de fluxo" msgid "Unable to initialize SDL, SDL2.dll is required" msgstr "Incapaz de inicializar SDL, se requiere SDL2.dll" msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "¿Seguro que quieres resetear la máquina emulada?" +msgstr "¿Está seguro de que quieres hacer una reinicialización completa de la máquina emulada?" msgid "Are you sure you want to exit 86Box?" -msgstr "¿Seguro que quieres cerrar 86Box?" +msgstr "¿Está seguro de que quiere cerrar a 86Box?" msgid "Unable to initialize Ghostscript" -msgstr "Incapaz de inicializar Ghostscript" +msgstr "No fué posible inicializar Ghostscript" msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -839,10 +839,10 @@ msgid "No ROMs found" msgstr "No se encontraron ROMs" msgid "Do you want to save the settings?" -msgstr "¿Quieres guardar los ajustes?" +msgstr "¿Quiere guardar los configuraciones?" msgid "This will hard reset the emulated machine." -msgstr "Se hará hard reset de la máquina emulada." +msgstr "Se hará una reinicialización completa de la máquina emulada." msgid "Save" msgstr "Guardar" @@ -857,7 +857,7 @@ msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N msgstr "Un emulador de ordenadores antigüos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." msgid "Hardware not available" -msgstr "Hardware no disponible" +msgstr "Equipo no disponible" msgid "WinPcap" msgstr "WinPcap" @@ -890,10 +890,10 @@ msgid "Don't exit" msgstr "No salir" msgid "Reset" -msgstr "Resetear" +msgstr "Reinicializar" msgid "Don't reset" -msgstr "No resetear" +msgstr "No reinicializar" msgid "CD-ROM images" msgstr "Imágenes de CD-ROM" @@ -911,10 +911,10 @@ msgid "OpenGL options" msgstr "Opciones OpenGL" msgid "You are loading an unsupported configuration" -msgstr "Estás cargando una configuración no soportada" +msgstr "Está cargando una configuración no soportada" msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar este ajuste no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." +msgstr "El Filtrado de tipo de CPU basado en máquina seleccionada está deshabilitado para la esta máquina.\n\nEsto hace posible seleccionar una CPU que sea incompatible con esta máquina. Por ello, pueden aparecer incompatibilidader con la BIOS de la máquina u otro software.\n\nActivar esta configuración no está oficialmente soportado y cualquier reporte de fallo puede ser cerrado como inválido." msgid "Continue" msgstr "Continuar" @@ -935,7 +935,7 @@ msgid "Error initializing renderer" msgstr "Error al inicializar el renderizador" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "No se ha podido inicializar el renderizador OpenGL (3.0 Core). Utilice otro renderizador." +msgstr "No fué posible inicializar el renderizador OpenGL (3.0 Core). Utilice otro renderizador." msgid "Resume execution" msgstr "Retomar la ejecución" @@ -965,7 +965,7 @@ msgid "%01i" msgstr "%01i" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "Nunca hubo unidades de CD-ROM MFM/RLL o ESDI" +msgstr "Nunca existieron unidades de CD-ROM MFM/RLL o ESDI" msgid "Custom..." msgstr "A medida..." @@ -1070,7 +1070,7 @@ msgid "Parent and child disk timestamps do not match" msgstr "Las marcas de tiempo del padre e hijo no coinciden" msgid "Could not fix VHD timestamp." -msgstr "No se pudo corregir la marca de tiempo del VHD." +msgstr "No fué posible corregir la marca de tiempo del VHD." msgid "%01i:%02i" msgstr "%01i:%02i" @@ -1196,11 +1196,17 @@ msgid "(System Default)" msgstr "(Por defecto del sistema)" msgid "Failed to initialize network driver" -msgstr "Error al inicializar el controlador de red" +msgstr "No fué posible inicializar el controlador de red" msgid "The network configuration will be switched to the null driver" msgstr "La configuración de red se cambiará al controlador nulo" +msgid "Mouse sensitivity:" +msgstr "Sensibilidad del ratón:" + +msgid "Select media images from program working directory" +msgstr "Seleccionar imágenes de media del directorio de trabajo del programa" + msgid "PIT mode:" msgstr "Modalidad PIT:" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index c67ce81ca..b23543903 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -1201,6 +1201,12 @@ msgstr "Verkkoajurin alustaminen epäonnistui" msgid "The network configuration will be switched to the null driver" msgstr "Verkkokokoonpano vaihtuu nolla-ajuriin" +msgid "Mouse sensitivity:" +msgstr "Hiiren herkkyys:" + +msgid "Select media images from program working directory" +msgstr "Valitse mediakuvat ohjelman työhakemistosta" + msgid "PIT mode:" msgstr "PIT-tila:" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index e9be3aeb9..2882bf5df 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1201,6 +1201,12 @@ msgstr "Échec de l'initialisation du pilote réseau" msgid "The network configuration will be switched to the null driver" msgstr "La configuration du réseau passera au pilote nul" +msgid "Mouse sensitivity:" +msgstr "Sensibilité de la souris:" + +msgid "Select media images from program working directory" +msgstr "Sélectionner des images dans le répertoire de travail du programme" + msgid "PIT mode:" msgstr "Mode PIT:" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 7b14f99c1..996a1948e 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1201,6 +1201,12 @@ msgstr "Neuspješno pokretanje mrežnog upravljačkog programa" msgid "The network configuration will be switched to the null driver" msgstr "Konfiguracija mreže bit će prebačena na nulti upravljački program" +msgid "Mouse sensitivity:" +msgstr "Osjetljivost miša:" + +msgid "Select media images from program working directory" +msgstr "Medijske slike su odabrane iz radnog direktorija programa" + msgid "PIT mode:" msgstr "PIT način:" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index e2547cb43..c65d7663b 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -1201,6 +1201,12 @@ msgstr "Nem sikerült inicializálni a hálózati illesztőprogramot" msgid "The network configuration will be switched to the null driver" msgstr "A hálózati konfiguráció átvált a null illesztőprogramra" +msgid "Mouse sensitivity:" +msgstr "Egér érzékenység:" + +msgid "Select media images from program working directory" +msgstr "Médiaképek kiválasztása a program munkakönyvtárából" + msgid "PIT mode:" msgstr "PIT üzemmód:" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 39b19d4cf..aec72a039 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1201,6 +1201,12 @@ msgstr "Impossibile inizializzare il driver di rete" msgid "The network configuration will be switched to the null driver" msgstr "La configurazione di rete verrà commutata sul driver nullo" +msgid "Mouse sensitivity:" +msgstr "Sensitività del mouse:" + +msgid "Select media images from program working directory" +msgstr "Seleziona le immagini media dalla directory di lavoro del programma" + msgid "PIT mode:" msgstr "Modalità PIT:" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index c854ec4dc..e87df6747 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1201,6 +1201,12 @@ msgstr "ネットワークドライバの初期化に失敗しました" msgid "The network configuration will be switched to the null driver" msgstr "ネットワーク設定がヌル・ドライバに切り替わる" +msgid "Mouse sensitivity:" +msgstr "マウスの感度:" + +msgid "Select media images from program working directory" +msgstr "プログラムの作業ディレクトリからメディア画像を選択する" + msgid "PIT mode:" msgstr "PITモード:" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index a3654af49..ef574d137 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -1201,6 +1201,12 @@ msgstr "네트워크 드라이버를 초기화하지 못했습니다" msgid "The network configuration will be switched to the null driver" msgstr "네트워크 구성이 널 드라이버로 전환됩니다" +msgid "Mouse sensitivity:" +msgstr "마우스 감도:" + +msgid "Select media images from program working directory" +msgstr "프로그램 작업 디렉토리에서 미디어 이미지 선택" + msgid "PIT mode:" msgstr "PIT 모드:" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 5e05aa0bd..69c23ffa6 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -1201,6 +1201,12 @@ msgstr "Nie udało się zainicjować sterownika sieciowego" msgid "The network configuration will be switched to the null driver" msgstr "Konfiguracja sieci zostanie przełączona na sterownik null" +msgid "Mouse sensitivity:" +msgstr "Wrażliwość myszy:" + +msgid "Select media images from program working directory" +msgstr "Wybór obrazów multimedialnych z katalogu roboczego programu" + msgid "PIT mode:" msgstr "Tryb PIT:" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index e4a28e9d0..99b064d1f 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -1201,6 +1201,12 @@ msgstr "Falha ao inicializar o driver de rede" msgid "The network configuration will be switched to the null driver" msgstr "A configuração de rede será alterada para o driver nulo" +msgid "Mouse sensitivity:" +msgstr "Sensibilidade do rato:" + +msgid "Select media images from program working directory" +msgstr "Selecione imagens de mídia do diretório de trabalho do programa" + msgid "PIT mode:" msgstr "Modo PIT:" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index f1dd128a2..9df5e383b 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1201,6 +1201,12 @@ msgstr "Falha ao inicializar o driver de rede" msgid "The network configuration will be switched to the null driver" msgstr "A configuração da rede será alterada para o controlador nulo" +msgid "Mouse sensitivity:" +msgstr "Sensibilidade do rato:" + +msgid "Select media images from program working directory" +msgstr "Selecionar imagens multimédia do diretório de trabalho do programa" + msgid "PIT mode:" msgstr "Modo PIT:" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 198e3fe42..b6ecdfb7f 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -1201,6 +1201,12 @@ msgstr "Не удалось инициализировать сетевой др msgid "The network configuration will be switched to the null driver" msgstr "Сетевая конфигурация будет переключена на нулевой драйвер" +msgid "Mouse sensitivity:" +msgstr "Чувствительность мыши:" + +msgid "Select media images from program working directory" +msgstr "Выбор медиа-образов из рабочего каталога программы" + msgid "PIT mode:" msgstr "Режим PIT:" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po new file mode 100644 index 000000000..0d0af6032 --- /dev/null +++ b/src/qt/languages/sk-SK.po @@ -0,0 +1,1220 @@ +msgid "&Action" +msgstr "&Podujatia" + +msgid "&Keyboard requires capture" +msgstr "&Klávesnica vyžaduje záber" + +msgid "&Right CTRL is left ALT" +msgstr "&Pravý Ctrl je ľavý Alt" + +msgid "&Hard Reset..." +msgstr "&Resetovať" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "P&ozastaviť" + +msgid "E&xit..." +msgstr "&Ukončiť" + +msgid "&View" +msgstr "&Zobrazenie" + +msgid "&Hide status bar" +msgstr "&Skryť stavový riadok" + +msgid "Hide &toolbar" +msgstr "Skryť panel &nástrojov" + +msgid "&Resizeable window" +msgstr "&Premenná veľkosť okna" + +msgid "R&emember size && position" +msgstr "&Pamätať si veľkosť a polohu" + +msgid "Re&nderer" +msgstr "&Renderer" + +msgid "&SDL (Software)" +msgstr "&SDL (Software)" + +msgid "SDL (&Hardware)" +msgstr "SDL (&Hardware)" + +msgid "SDL (&OpenGL)" +msgstr "SDL (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "&Zadať veľkosť..." + +msgid "F&orce 4:3 display ratio" +msgstr "&Zachovať pomer strán 4:3" + +msgid "&Window scale factor" +msgstr "&Násobné zväčšenie okna" + +msgid "&0.5x" +msgstr "&0.5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1.&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "Spôsob &filtrovania" + +msgid "&Nearest" +msgstr "&Najbližší" + +msgid "&Linear" +msgstr "&Lineárny" + +msgid "Hi&DPI scaling" +msgstr "Š&kálovanie HiDPI" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "&Celá obrazovka\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "Režim roztia&hnutia na celú obrazovku" + +msgid "&Full screen stretch" +msgstr "&Rozšíriť" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Zachovať pomer strán" + +msgid "&Integer scale" +msgstr "&Celočíselné škálovanie" + +msgid "E&GA/(S)VGA settings" +msgstr "Nastavenia pre E&GA a (S)VGA" + +msgid "&Inverted VGA monitor" +msgstr "&Obrátiť farby" + +msgid "VGA screen &type" +msgstr "&Typ monitora VGA" + +msgid "RGB &Color" +msgstr "RGB &farebný" + +msgid "&RGB Grayscale" +msgstr "&Odtiene sivej" + +msgid "&Amber monitor" +msgstr "&Jantárová obrazovka" + +msgid "&Green monitor" +msgstr "&Zelená obrazovka" + +msgid "&White monitor" +msgstr "&Biela obrazovka" + +msgid "Grayscale &conversion type" +msgstr "Konverzia na &odtiene sivej" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Priemer" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "Prekrytie obrazu CGA/PCjr/Tandy/E&GA/(S)VGA" + +msgid "Change contrast for &monochrome display" +msgstr "&Úprava kontrastu čiernobielej obrazovky" + +msgid "&Media" +msgstr "&Média" + +msgid "&Tools" +msgstr "&Nástroje" + +msgid "&Settings..." +msgstr "&Nastavenia..." + +msgid "&Update status bar icons" +msgstr "&Aktualizovať ikony na stavovom riadku" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Urobiť snímku &obrazovky\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Predvoľby..." + +msgid "Enable &Discord integration" +msgstr "Povolenie integrácie s &Discordem" + +msgid "Sound &gain..." +msgstr "&Zosilnenie zvuku" + +msgid "Begin trace\tCtrl+T" +msgstr "Začať trace\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Zastaviť trace\tCtrl+T" + +msgid "&Help" +msgstr "&Pomoc" + +msgid "&Documentation..." +msgstr "&Dokumentácia" + +msgid "&About 86Box..." +msgstr "&O programu 86Box" + +msgid "&New image..." +msgstr "&Nový obraz..." + +msgid "&Existing image..." +msgstr "&Existujúci obraz..." + +msgid "Existing image (&Write-protected)..." +msgstr "Existujúci obraz (&ochrana proti zápisu)..." + +msgid "&Record" +msgstr "&Nahrávať" + +msgid "&Play" +msgstr "&Prehrať" + +msgid "&Rewind to the beginning" +msgstr "Previnuť na &začiatok" + +msgid "&Fast forward to the end" +msgstr "Previnuť na &koniec" + +msgid "E&ject" +msgstr "&Vystrihnúť" + +msgid "&Image..." +msgstr "&Obraz..." + +msgid "E&xport to 86F..." +msgstr "E&xportovať do 86F..." + +msgid "&Mute" +msgstr "&Stíšiť" + +msgid "E&mpty" +msgstr "&Vystrihnúť" + +msgid "&Reload previous image" +msgstr "&Načítať znova predchádzajúci obraz" + +msgid "&Folder..." +msgstr "&Zložka..." + +msgid "Target &framerate" +msgstr "&Cieľová snímková frekvencia" + +msgid "&Sync with video" +msgstr "&Synchronizovať s obrazom" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Zvoliť shader..." + +msgid "&Remove shader" +msgstr "&Odobrať shader" + +msgid "Preferences" +msgstr "Predvoľby" + +msgid "Sound Gain" +msgstr "Zosilnenie zvuku" + +msgid "New Image" +msgstr "Nový obraz" + +msgid "Settings" +msgstr "Nastavenia" + +msgid "Specify Main Window Dimensions" +msgstr "Zadať rozmery hlavného okna" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Storno" + +msgid "Save these settings as &global defaults" +msgstr "Uložiť toto nastavenie ako &globálny východiskový stav" + +msgid "&Default" +msgstr "&Východiskové" + +msgid "Language:" +msgstr "Jazyk:" + +msgid "Icon set:" +msgstr "Súprava ikon:" + +msgid "Gain" +msgstr "Zosilnenie" + +msgid "File name:" +msgstr "Názov súboru:" + +msgid "Disk size:" +msgstr "Veľkosť disku:" + +msgid "RPM mode:" +msgstr "Režim ot./m:" + +msgid "Progress:" +msgstr "Priebeh:" + +msgid "Width:" +msgstr "Šírka:" + +msgid "Height:" +msgstr "Výška:" + +msgid "Lock to this size" +msgstr "Uzamknúť na tieto rozmery" + +msgid "Machine type:" +msgstr "Typ počítača:" + +msgid "Machine:" +msgstr "Počítač:" + +msgid "Configure" +msgstr "Nastaviť" + +msgid "CPU type:" +msgstr "Procesor:" + +msgid "Speed:" +msgstr "Rýchlosť:" + +msgid "FPU:" +msgstr "Koprocesor:" + +msgid "Wait states:" +msgstr "Čakacie stavy:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Pamäť:" + +msgid "Time synchronization" +msgstr "Synchronizácia času" + +msgid "Disabled" +msgstr "Vypnutá" + +msgid "Enabled (local time)" +msgstr "Zapnutá (miestny čas)" + +msgid "Enabled (UTC)" +msgstr "Zapnutá (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamický prekladač" + +msgid "Video:" +msgstr "Grafika:" + +msgid "Voodoo Graphics" +msgstr "Použiť grafický akcelerátor Voodoo" + +msgid "IBM 8514/a Graphics" +msgstr "Grafika IBM 8514/a" + +msgid "XGA Graphics" +msgstr "Grafika XGA" + +msgid "Mouse:" +msgstr "Myš:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card 1:" +msgstr "Zvuková karta 1:" + +msgid "Sound card 2:" +msgstr "Zvuková karta 2:" + +msgid "Sound card 3:" +msgstr "Zvuková karta 3:" + +msgid "Sound card 4:" +msgstr "Zvuková karta 4:" + +msgid "MIDI Out Device:" +msgstr "MIDI výstup:" + +msgid "MIDI In Device:" +msgstr "MIDI vstup:" + +msgid "Standalone MPU-401" +msgstr "Samostatný MPU-401" + +msgid "Use FLOAT32 sound" +msgstr "Použiť zvuk FLOAT32" + +msgid "FM synth driver" +msgstr "Ovládač FM syntetizátora" + +msgid "Nuked (more accurate)" +msgstr "Nuked (presnejší)" + +msgid "YMFM (faster)" +msgstr "YMFM (rýchlejší)" + +msgid "Network type:" +msgstr "Druh siete:" + +msgid "PCap device:" +msgstr "PCap zariadenia:" + +msgid "Network adapter:" +msgstr "Sieťový adaptér:" + +msgid "COM1 Device:" +msgstr "Zariadenie na COM1:" + +msgid "COM2 Device:" +msgstr "Zariadenie na COM2:" + +msgid "COM3 Device:" +msgstr "Zariadenie na COM3:" + +msgid "COM4 Device:" +msgstr "Zariadenie na COM4:" + +msgid "LPT1 Device:" +msgstr "Zariadenie na LPT1:" + +msgid "LPT2 Device:" +msgstr "Zariadenie na LPT2:" + +msgid "LPT3 Device:" +msgstr "Zariadenie na LPT3:" + +msgid "LPT4 Device:" +msgstr "Zariadenie na LPT4:" + +msgid "Serial port 1" +msgstr "Povoliť port COM1" + +msgid "Serial port 2" +msgstr "Povoliť port COM2" + +msgid "Serial port 3" +msgstr "Povoliť port COM3" + +msgid "Serial port 4" +msgstr "Povoliť port COM4" + +msgid "Parallel port 1" +msgstr "Povoliť port LPT1" + +msgid "Parallel port 2" +msgstr "Povoliť port LPT2" + +msgid "Parallel port 3" +msgstr "Povoliť port LPT3" + +msgid "Parallel port 4" +msgstr "Povoliť port LPT4" + +msgid "HD Controller:" +msgstr "Radič disku:" + +msgid "FD Controller:" +msgstr "Disketový radič:" + +msgid "Tertiary IDE Controller" +msgstr "Tretí radič IDE" + +msgid "Quaternary IDE Controller" +msgstr "Štvrtý radič IDE" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Radič 1:" + +msgid "Controller 2:" +msgstr "Radič 2:" + +msgid "Controller 3:" +msgstr "Radič 3:" + +msgid "Controller 4:" +msgstr "Radič 4:" + +msgid "Cassette" +msgstr "Kazeta" + +msgid "Hard disks:" +msgstr "Pevné disky:" + +msgid "&New..." +msgstr "&Nový..." + +msgid "&Existing..." +msgstr "&Existujúcý..." + +msgid "&Remove" +msgstr "&Odobrať" + +msgid "Bus:" +msgstr "Zbernica:" + +msgid "Channel:" +msgstr "Kanál:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Zadať..." + +msgid "Sectors:" +msgstr "Sektory:" + +msgid "Heads:" +msgstr "Hlavy:" + +msgid "Cylinders:" +msgstr "Cylindre:" + +msgid "Size (MB):" +msgstr "Veľkosť (MB):" + +msgid "Type:" +msgstr "Typ:" + +msgid "Image Format:" +msgstr "Formát obrazu:" + +msgid "Block Size:" +msgstr "Veľkosť blokov:" + +msgid "Floppy drives:" +msgstr "Disketové mechaniky:" + +msgid "Turbo timings" +msgstr "Turbo časovanie" + +msgid "Check BPB" +msgstr "Kontrola BPB" + +msgid "CD-ROM drives:" +msgstr "Mechaniky CD-ROM:" + +msgid "Earlier drive" +msgstr "Skorá mechanika" + +msgid "MO drives:" +msgstr "Magnetooptické mechaniky:" + +msgid "ZIP drives:" +msgstr "Mechaniky ZIP:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA hodiny:" + +msgid "ISA Memory Expansion" +msgstr "ISA rozšírenie pamäte" + +msgid "Card 1:" +msgstr "Karta 1:" + +msgid "Card 2:" +msgstr "Karta 2:" + +msgid "Card 3:" +msgstr "Karta 3:" + +msgid "Card 4:" +msgstr "Karta 4:" + +msgid "ISABugger device" +msgstr "Zariadenie ISABugger" + +msgid "POST card" +msgstr "Karta pre kódy POST" + +msgid "FONT_SIZE" +msgstr "9" + +msgid "FONT_NAME" +msgstr "Segoe UI" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Chyba" + +msgid "Fatal error" +msgstr "Kritická chyba" + +msgid " - PAUSED" +msgstr " - POZASTAVENÝ" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Stlačte Ctrl+Alt+PgDn pre návrat z režimu celej obrazovky." + +msgid "Speed" +msgstr "Rýchlosť" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "Obrazy ZIP diskov" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "86Box nenašiel žiadne použiteľné imidž pamätí ROM.\n\nStiahnite sadu obrazov ROM a extrahujte ju do zložky \"roms\"." + +msgid "(empty)" +msgstr "(prázdne)" + +msgid "All files" +msgstr "Všetky súbory" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Zap." + +msgid "Off" +msgstr "Vyp." + +msgid "All images" +msgstr "Všetky obrazy diskov" + +msgid "Basic sector images" +msgstr "Základné sektorové obrazy" + +msgid "Surface images" +msgstr "Obrazy povrchu" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Počítač \"%hs\" ie je dostupný, pretože chýba obraz jeho pamäte ROM v zložke \"roms/machines\". Konfigurácia sa prepne na iný dostupný počítač." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Video adaptér \"%hs\" nie je dostupný, pretože chýba obraz jeho pamäte ROM v zložke \"roms/video\". Konfigurácia sa prepne na iný dostupný adaptér." + +msgid "Machine" +msgstr "Počítač" + +msgid "Display" +msgstr "Obraz" + +msgid "Input devices" +msgstr "Vstupné zariadenie" + +msgid "Sound" +msgstr "Zvuk" + +msgid "Network" +msgstr "Sieť" + +msgid "Ports (COM & LPT)" +msgstr "COM a LPT porty" + +msgid "Storage controllers" +msgstr "Radiče úložiska" + +msgid "Hard disks" +msgstr "Pevné disky" + +msgid "Floppy & CD-ROM drives" +msgstr "Disketové a CD-ROM mechaniky" + +msgid "Other removable devices" +msgstr "Ďalšie vymeniteľné zariadenia" + +msgid "Other peripherals" +msgstr "Iné príslušenstvo" + +msgid "Click to capture mouse" +msgstr "Kliknite pre zabráni myši" + +msgid "Press F8+F12 to release mouse" +msgstr "Stlačte F8+F12 pre uvoľnenie myši" + +msgid "Press F8+F12 or middle button to release mouse" +msgstr "Stlačte F8+F12 alebo prostredné tlačidlo na uvoľnenie myši" + +msgid "Bus" +msgstr "Zbernica" + +msgid "File" +msgstr "Súbor" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Nastala chyba pri inicializácii video renderera." + +msgid "Default" +msgstr "Východiskové" + +msgid "%i Wait state(s)" +msgstr "%i čakací stav(y)" + +msgid "Type" +msgstr "Typ" + +msgid "Failed to set up PCap" +msgstr "Nastala chyba pri inicializácii knižnice PCap" + +msgid "No PCap devices found" +msgstr "Neboli nájdené žiadne PCap zariadenia" + +msgid "Invalid PCap device" +msgstr "Neplatné PCap zariadenie" + +msgid "Standard 2-button joystick(s)" +msgstr "Štandardný 2tlačidlový joystick" + +msgid "Standard 4-button joystick" +msgstr "Štandardný 4tlačidlový joystick" + +msgid "Standard 6-button joystick" +msgstr "Štandardný 6tlačidlový joystick" + +msgid "Standard 8-button joystick" +msgstr "Štandardný 8tlačidlový joystick" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "None" +msgstr "Žiadne" + +msgid "Unable to load keyboard accelerators." +msgstr "Nebolo možné nahrať klávesnicové skratky." + +msgid "Unable to register raw input." +msgstr "Nebolo možné zaregistrovať raw input." + +msgid "%u" +msgstr "%u" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Disketová mechanika %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Rozšírené sektorové obrazy" + +msgid "Flux images" +msgstr "Obrazy magnetického toku" + +msgid "Unable to initialize SDL, SDL2.dll is required" +msgstr "Nastala chyba pri inicializácii knižnice SDL, je potreba SDL2.dll" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Naozaj chcete resetovať emulovaný počítač?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Naozaj chcete ukončiť 86Box?" + +msgid "Unable to initialize Ghostscript" +msgstr "Nastala chyba pri inicializácii knižnice Ghostscript" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "Obrazy MO" + +msgid "Welcome to 86Box!" +msgstr "Vitajte v programe 86Box!" + +msgid "Internal controller" +msgstr "Vstavaný radič" + +msgid "Exit" +msgstr "Ukončiť" + +msgid "No ROMs found" +msgstr "Neboli nájdené žiadne obrazy ROM" + +msgid "Do you want to save the settings?" +msgstr "Chcete uložiť nastavenia?" + +msgid "This will hard reset the emulated machine." +msgstr "Pokračovaním sa resetuje emulovaný počítač." + +msgid "Save" +msgstr "Uložiť" + +msgid "About 86Box" +msgstr "O programe 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Emulátor starých počítačov\n\nAutori: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nZverejnené pod licenciou GNU General Public License verzie 2 alebo novšej. Pozri súbor LICENSE pre viac informácií." + +msgid "Hardware not available" +msgstr "Hardvér nie je dostupný" + +msgid "WinPcap" +msgstr "WinPcap" + +msgid "libpcap" +msgstr "libpcap" + +msgid "Make sure libpcap is installed and that you are on a libpcap-compatible network connection." +msgstr "Uistite sa, že je nainštalovaný libpcap a používate sieťové pripojenie s ním kompatibilné." + +msgid "Invalid configuration" +msgstr "Neplatná konfigurácia" + +msgid "gsdll32.dll" +msgstr "gsdll32.dll" + +msgid "libgs" +msgstr "libgs" + +msgid " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files." +msgstr " je potrebná pre automatický prevod PostScript dokumentov do PDF.\n\nAkékoľvek dokumenty vytlačené cez všeobecnú PostScriptovú tlačiareň budú uložené ako PostScript (.ps) súbory." + +msgid "Entering fullscreen mode" +msgstr "Vstup do režimu celej obrazovky" + +msgid "Don't show this message again" +msgstr "Nezobrazovať ďalej túto správu" + +msgid "Don't exit" +msgstr "Neukončovať" + +msgid "Reset" +msgstr "Resetovať" + +msgid "Don't reset" +msgstr "Neresetovať" + +msgid "CD-ROM images" +msgstr "Obraz CD-ROM disku" + +msgid "%hs Device Configuration" +msgstr "Konfigurácia zariadenia %hs" + +msgid "Monitor in sleep mode" +msgstr "Monitor je v režime spánku" + +msgid "OpenGL Shaders" +msgstr "Shadery OpenGL" + +msgid "OpenGL options" +msgstr "Možnosti OpenGL" + +msgid "You are loading an unsupported configuration" +msgstr "Pokúšate sa spustiť nepodporovanú konfiguráciu" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "Pre túto konfiguráciu bolo vypnuté filtrovanie procesorov podľa zvoleného počítača.\n\nToto umožňuje zvoliť procesor, ktorý by inak so zvoleným počítačom nebol kompatibilný. Môžu však nastať problémy s BIOSom alebo iným softvérom.\n\nPovolenie tohto nastavenia nie je oficiálne podporované a akékoľvek hlásenia o chybách môžu byť uzavreté ako neplatné." + +msgid "Continue" +msgstr "Pokračovať" + +msgid "Cassette: %s" +msgstr "Kazeta: %s" + +msgid "Cassette images" +msgstr "Kazetové nahrávky" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Obrazy cartridge" + +msgid "Error initializing renderer" +msgstr "Chyba pri inicializácii vykresľovača" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "Vykresľovač OpenGL (3.0 Core) sa nepodarilo inicializovať. Použite iný renderer." + +msgid "Resume execution" +msgstr "Obnoviť" + +msgid "Pause execution" +msgstr "Pozastaviť" + +msgid "Press Ctrl+Alt+Del" +msgstr "Stlačiť Ctrl+Alt+Delete" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Stlačiť Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Resetovať" + +msgid "ACPI shutdown" +msgstr "Vypnúť cez rozhranie ACPI" + +msgid "Hard disk (%s)" +msgstr "Pevný disk (%s)" + +msgid "%01i:%01i" +msgstr "%01i:%01i" + +msgid "%01i" +msgstr "%01i" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "CD-ROM mechaniky pre rozhranie MFM/RLL alebo ESDI nikdy neexistovali" + +msgid "Custom..." +msgstr "Vlastná..." + +msgid "Custom (large)..." +msgstr "Vlastná (veľká)..." + +msgid "Add New Hard Disk" +msgstr "Pridať nový pevný disk" + +msgid "Add Existing Hard Disk" +msgstr "Pridať existujúci pevný disk" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "Obraz disku formátu HDI nemôžu byť väčší ako 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Obraz disku nemôžu byť väčší ako 127 GB." + +msgid "Hard disk images" +msgstr "Obrazy pevného disku" + +msgid "Unable to read file" +msgstr "Nebolo možné prečítať súbor" + +msgid "Unable to write file" +msgstr "Nebolo možné zapisovať do súboru" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "Obraz disku vo formáte HDI alebo HDX s veľkosťou sektora inou ako 512 bajtov nie sú podporované." + +msgid "USB is not yet supported" +msgstr "USB zatiaľ nie je podporované." + +msgid "Disk image file already exists" +msgstr "Súbor obrazu disku už existuje" + +msgid "Please specify a valid file name." +msgstr "Zadajte platný názov súboru." + +msgid "Disk image created" +msgstr "Obraz disku bol vytvorený" + +msgid "Make sure the file exists and is readable." +msgstr "Uistite sa, že súbor existuje a možno ho prečítať." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Uistite sa, že sa do zložky, kde sa má súbor uložiť, dá zapisovať." + +msgid "Disk image too large" +msgstr "Obraz disku je príliš veľký" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Nezabudnite novo vytvorený disk rozdeliť a naformátovať." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Zvolený súbor bude prepísaný. Naozaj ho chcete použiť?" + +msgid "Unsupported disk image" +msgstr "Nepodporovaný obraz disku" + +msgid "Overwrite" +msgstr "Prepísať" + +msgid "Don't overwrite" +msgstr "Neprepisovať" + +msgid "Raw image (.img)" +msgstr "Surový obraz (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI obraz (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX obraz (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD s pevnou veľkosťou (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD s dynamickou veľkosťou (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Rozdielový VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Veľké bloky (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Malé bloky (512 KB)" + +msgid "VHD files" +msgstr "Súbory VHD" + +msgid "Select the parent VHD" +msgstr "Vyberte nadradený virtuálny disk" + +msgid "This could mean that the parent image was modified after the differencing image was created.\n\nIt can also happen if the image files were moved or copied, or by a bug in the program that created this disk.\n\nDo you want to fix the timestamps?" +msgstr "To môže znamenať, že sa obsahy nadradeného disku zmenili po vytvorení rozdielového disku.\n\nTáto chyba tiež môže nastať, ak bol obraz disku kopírovaný alebo presunutý, alebo kvôli chybe v programe, ktorý ho vytvoril.\n\nChcete časové pečiatky opraviť?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Časové pečiatky nadradeného a podradeného disku nesúhlasia" + +msgid "Could not fix VHD timestamp." +msgstr "Nebolo možné opraviť časovú pečiatku VHD." + +msgid "%01i:%02i" +msgstr "%01i:%02i" + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "MFM/RLL (%01i:%01i)" +msgstr "MFM/RLL (%01i:%01i)" + +msgid "XTA (%01i:%01i)" +msgstr "XTA (%01i:%01i)" + +msgid "ESDI (%01i:%01i)" +msgstr "ESDI (%01i:%01i)" + +msgid "IDE (%01i:%01i)" +msgstr "IDE (%01i:%01i)" + +msgid "ATAPI (%01i:%01i)" +msgstr "ATAPI (%01i:%01i)" + +msgid "SCSI (%01i:%02i)" +msgstr "SCSI (%01i:%02i)" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 kB" +msgstr "160 kB" + +msgid "180 kB" +msgstr "180 kB" + +msgid "320 kB" +msgstr "320 kB" + +msgid "360 kB" +msgstr "360 kB" + +msgid "640 kB" +msgstr "640 kB" + +msgid "720 kB" +msgstr "720 kB" + +msgid "1.2 MB" +msgstr "1.2 MB" + +msgid "1.25 MB" +msgstr "1.25 MB" + +msgid "1.44 MB" +msgstr "1.44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2.88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3.5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3.5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3.5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3.5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3.5\" 1.3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3.5\" 2.3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5.25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5.25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5.25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5.25\" 1.3 GB" + +msgid "Perfect RPM" +msgstr "Dokonalé otáčky za minútu" + +msgid "1% below perfect RPM" +msgstr "1% pod dokonalými ot./m" + +msgid "1.5% below perfect RPM" +msgstr "1.5% pod dokonalými ot./m" + +msgid "2% below perfect RPM" +msgstr "2% pod dokonalými ot./m" + +msgid "(System Default)" +msgstr "(Predvolené nastavenie systému)" + +msgid "Failed to initialize network driver" +msgstr "Nepodarilo sa inicializovať sieťový ovládač" + +msgid "The network configuration will be switched to the null driver" +msgstr "Konfigurácia siete bude prepnutá na nulový ovládač" + +msgid "Mouse sensitivity:" +msgstr "Citlivosť myší:" + +msgid "Select media images from program working directory" +msgstr "Výber mediálnych obrazov z pracovného adresára programu" + +msgid "PIT mode:" +msgstr "Režim PIT:" + +msgid "Auto" +msgstr "Automatický" + +msgid "Slow" +msgstr "Pomalý" + +msgid "Fast" +msgstr "Rýchly" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 558990f83..a018be97c 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1201,6 +1201,12 @@ msgstr "Ni uspelo inicializirati omrežnega gonilnika" msgid "The network configuration will be switched to the null driver" msgstr "Omrežne nastavitve bodo preklopljene na ničelni gonilnik" +msgid "Mouse sensitivity:" +msgstr "Občutljivost miške:" + +msgid "Select media images from program working directory" +msgstr "Izberi slike medijev iz delovnega imenika programa" + msgid "PIT mode:" msgstr "Način PIT:" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index e607c70a3..ce23b27e2 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -1201,6 +1201,12 @@ msgstr "Ağ sürücüsü başlatılamadı" msgid "The network configuration will be switched to the null driver" msgstr "Ağ yapılandırması null sürücüye geçirilecektir" +msgid "Mouse sensitivity:" +msgstr "Fare hassasiyeti:" + +msgid "Select media images from program working directory" +msgstr "Program çalışma dizininden medya görüntülerini seçme" + msgid "PIT mode:" msgstr "PIT modu:" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index a1ba15357..1f18c6e62 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1201,6 +1201,12 @@ msgstr "Не вдалося ініціалізувати мережевий др msgid "The network configuration will be switched to the null driver" msgstr "Конфігурацію мережі буде змінено на нульовий драйвер" +msgid "Mouse sensitivity:" +msgstr "Чутливість миші:" + +msgid "Select media images from program working directory" +msgstr "Виберіть медіа-зображення з робочої директорії програми" + msgid "PIT mode:" msgstr "Режим PIT:" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 7151a28dd..d5b676e64 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1201,6 +1201,12 @@ msgstr "网络驱动程序初始化失败" msgid "The network configuration will be switched to the null driver" msgstr "网络配置将切换为空驱动程序" +msgid "Mouse sensitivity:" +msgstr "小鼠敏感性:" + +msgid "Select media images from program working directory" +msgstr "从程序工作目录中选择媒体图像" + msgid "PIT mode:" msgstr "PIT 模式:" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 86e83e1e4..b3bdbf7a5 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1201,6 +1201,12 @@ msgstr "初始化網絡驅動程序失敗" msgid "The network configuration will be switched to the null driver" msgstr "網絡配置將切換為空驅動程序" +msgid "Mouse sensitivity:" +msgstr "鼠標靈敏度:" + +msgid "Select media images from program working directory" +msgstr "從程序工作目錄中選擇媒體圖像" + msgid "PIT mode:" msgstr "點模式:" diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 6db17aaa9..b273716a6 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -754,10 +754,10 @@ :/menuicons/win/icons/acpi_shutdown.ico:/menuicons/win/icons/acpi_shutdown.ico - ACPI Shutdown + ACPI shutdown - ACPI Shutdown + ACPI shutdown true diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 7a028bfac..9e2264221 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -429,14 +429,16 @@ set_language(uint32_t id) extern "C++" { QMap> ProgSettings::lcid_langcode = { - {0x0405, { "cs-CZ", "Czech (Czech Republic)" } }, + { 0x0403, { "ca-ES", "Catalan (Spain)" } }, + { 0x0804, { "zh-CN", "Chinese (Simplified)" } }, + { 0x0404, { "zh-TW", "Chinese (Traditional)" } }, + { 0x041A, { "hr-HR", "Croatian (Croatia)" } }, + { 0x0405, { "cs-CZ", "Czech (Czech Republic)" } }, { 0x0407, { "de-DE", "German (Germany)" } }, - { 0x0409, { "en-US", "English (United States)" } }, { 0x0809, { "en-GB", "English (United Kingdom)" }}, - { 0x0C0A, { "es-ES", "Spanish (Spain)" } }, + { 0x0409, { "en-US", "English (United States)" } }, { 0x040B, { "fi-FI", "Finnish (Finland)" } }, { 0x040C, { "fr-FR", "French (France)" } }, - { 0x041A, { "hr-HR", "Croatian (Croatia)" } }, { 0x040E, { "hu-HU", "Hungarian (Hungary)" } }, { 0x0410, { "it-IT", "Italian (Italy)" } }, { 0x0411, { "ja-JP", "Japanese (Japan)" } }, @@ -445,11 +447,11 @@ QMap> ProgSettings::lcid_langcode = { { 0x0416, { "pt-BR", "Portuguese (Brazil)" } }, { 0x0816, { "pt-PT", "Portuguese (Portugal)" } }, { 0x0419, { "ru-RU", "Russian (Russia)" } }, + { 0x041B, { "sk-SK", "Slovak (Slovakia)" } }, { 0x0424, { "sl-SI", "Slovenian (Slovenia)" } }, + { 0x0C0A, { "es-ES", "Spanish (Spain, Modern Sort)" } }, { 0x041F, { "tr-TR", "Turkish (Turkey)" } }, { 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } }, - { 0x0804, { "zh-CN", "Chinese (China)" } }, - { 0x0404, { "zh-TW", "Chinese (Taiwan)" } }, { 0xFFFF, { "system", "(System Default)" } }, }; } diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index f9a6b8e14..c7cb99086 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -113,7 +113,8 @@ Settings::Settings(QWidget *parent) , ui(new Ui::Settings) { ui->setupUi(this); - ui->listView->setModel(new SettingsModel(this)); + auto *model = new SettingsModel(this); + ui->listView->setModel(model); Harddrives::busTrackClass = new SettingsBusTracking; machine = new SettingsMachine(this); @@ -140,18 +141,27 @@ Settings::Settings(QWidget *parent) ui->stackedWidget->addWidget(otherRemovable); ui->stackedWidget->addWidget(otherPeripherals); - connect(machine, &SettingsMachine::currentMachineChanged, display, &SettingsDisplay::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, input, &SettingsInput::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, sound, &SettingsSound::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, network, &SettingsNetwork::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, storageControllers, &SettingsStorageControllers::onCurrentMachineChanged); - connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, &SettingsOtherPeripherals::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, display, + &SettingsDisplay::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, input, + &SettingsInput::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, sound, + &SettingsSound::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, network, + &SettingsNetwork::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, storageControllers, + &SettingsStorageControllers::onCurrentMachineChanged); + connect(machine, &SettingsMachine::currentMachineChanged, otherPeripherals, + &SettingsOtherPeripherals::onCurrentMachineChanged); - connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { - ui->stackedWidget->setCurrentIndex(current.row()); - }); + connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, + [this](const QModelIndex ¤t, const QModelIndex &previous) { + ui->stackedWidget->setCurrentIndex(current.row()); }); - ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) + qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent)); + ui->listView->setMinimumWidth(ui->listView->sizeHintForColumn(0) + + qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent)); + + ui->listView->setCurrentIndex(model->index(0, 0)); Settings::settings = this; } @@ -184,13 +194,15 @@ void Settings::accept() { if (confirm_save && !settings_only) { - QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), tr("This will hard reset the emulated machine.")), QMessageBox::Save | QMessageBox::Cancel, this); + QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", + QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), + tr("This will hard reset the emulated machine.")), + QMessageBox::Save | QMessageBox::Cancel, this); QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_save); QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { - confirm_save = (state == Qt::CheckState::Unchecked); - }); + confirm_save = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); if (questionbox.result() == QMessageBox::Cancel) { confirm_save = true; diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 9aab398c4..e4adcd0c2 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -146,19 +146,6 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) for (int i = 0; i < 72; i++) Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1); -#if 0 - model = ui->comboBoxCDROMType->model(); - i = 0; - while (true) { - QString name = tr(cdrom_getname(i)); - if (name.isEmpty()) - break; - - Models::AddEntry(model, name, i); - ++i; - } -#endif - model = new QStandardItemModel(0, 3, this); ui->tableViewCDROM->setModel(model); model->setHeaderData(0, Qt::Horizontal, tr("Bus")); diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc index 845099436..017354f82 100644 --- a/src/qt/qt_translations.qrc +++ b/src/qt/qt_translations.qrc @@ -1,5 +1,6 @@ + 86box_ca-ES.qm 86box_cs-CZ.qm 86box_de-DE.qm 86box_en-US.qm @@ -16,6 +17,7 @@ 86box_pt-BR.qm 86box_pt-PT.qm 86box_ru-RU.qm + 86box_sk-SK.qm 86box_sl-SI.qm 86box_tr-TR.qm 86box_uk-UA.qm From 44ba846ae6d06b6a2089ddfab880a5b4a05b6d01 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 17 Aug 2023 02:52:49 +0200 Subject: [PATCH 02/30] Reverted some changes and reworked some lines in cpu/386.c. --- src/cpu/386.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 0fe7e6188..fb42a222f 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -77,7 +77,6 @@ x386_log(const char *fmt, ...) static __inline void fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; if (cpu_rm == 4) { uint8_t sib = rmdat >> 8; @@ -122,19 +121,11 @@ fetch_ea_32_long(uint32_t rmdat) cpu_state.eaaddr = getlong(); } } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); - } } static __inline void fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; if (!cpu_mod && cpu_rm == 6) { cpu_state.eaaddr = getword(); @@ -158,13 +149,6 @@ fetch_ea_16_long(uint32_t rmdat) } cpu_state.eaaddr &= 0xFFFF; } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); - } } #define fetch_ea_16(rmdat) \ @@ -225,15 +209,12 @@ fetch_ea_16_long(uint32_t rmdat) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) -#define CHECK_READ_CS(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - x86gpf("Limit check (READ)", 0); \ - if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL, (chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - } +#define CHECK_READ_CS(size) \ + if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \ + ((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \ + x86gpf("Limit check (READ)", 0); \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !(cpu_state.seg_cs.access & 0x80)) \ + x86np("Read from seg not present", cpu_state.seg_cs.seg & 0xfffc); \ #include "386_ops.h" @@ -277,11 +258,7 @@ exec386_2386(int cycs) fetchdat = fastreadl_fetch(cs + cpu_state.pc); ol = opcode_length[fetchdat & 0xff]; - if (ol < 4) { - CHECK_READ_CS(&cpu_state.seg_cs, cpu_state.pc, cpu_state.pc + ol - 1); - } else { - CHECK_READ_CS(&cpu_state.seg_cs, cpu_state.pc, cpu_state.pc + 3); - } + CHECK_READ_CS(MIN(ol, 4)); if (!cpu_state.abrt) { #ifdef ENABLE_386_LOG From 5c5a50a07587a247c98766ea6471613083859824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=99=E6=B2=99=E5=AE=AE=E7=B4=97=E5=A4=9C?= <117635969+kzmidze@users.noreply.github.com> Date: Thu, 17 Aug 2023 18:47:54 +0800 Subject: [PATCH 03/30] Add files via upload --- src/qt/languages/ja-JP.po | 4 ++-- src/qt/languages/zh-CN.po | 8 ++++---- src/qt/languages/zh-TW.po | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index e87df6747..466103429 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1205,13 +1205,13 @@ msgid "Mouse sensitivity:" msgstr "マウスの感度:" msgid "Select media images from program working directory" -msgstr "プログラムの作業ディレクトリからメディア画像を選択する" +msgstr "プログラムの作業ディレクトリからメディアイメージを選択する" msgid "PIT mode:" msgstr "PITモード:" msgid "Auto" -msgstr "オート" +msgstr "自動" msgid "Slow" msgstr "遅い" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index d5b676e64..b72183bde 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1202,20 +1202,20 @@ msgid "The network configuration will be switched to the null driver" msgstr "网络配置将切换为空驱动程序" msgid "Mouse sensitivity:" -msgstr "小鼠敏感性:" +msgstr "鼠标敏感度:" msgid "Select media images from program working directory" -msgstr "从程序工作目录中选择媒体图像" +msgstr "从程序工作目录中选择介质镜像" msgid "PIT mode:" msgstr "PIT 模式:" msgid "Auto" -msgstr "汽车" +msgstr "自动" msgid "Slow" msgstr "慢" msgid "Fast" -msgstr "快速" +msgstr "快" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index b3bdbf7a5..699ae2a65 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -1196,26 +1196,26 @@ msgid "(System Default)" msgstr "(系統預設)" msgid "Failed to initialize network driver" -msgstr "初始化網絡驅動程序失敗" +msgstr "初始化網路驅動程式失敗" msgid "The network configuration will be switched to the null driver" -msgstr "網絡配置將切換為空驅動程序" +msgstr "網路設定將切換為空驅動程式" msgid "Mouse sensitivity:" -msgstr "鼠標靈敏度:" +msgstr "滑鼠靈敏度:" msgid "Select media images from program working directory" -msgstr "從程序工作目錄中選擇媒體圖像" +msgstr "從程式工作目錄中選擇介質映像" msgid "PIT mode:" -msgstr "點模式:" +msgstr "PIT模式:" msgid "Auto" -msgstr "汽車" +msgstr "自動" msgid "Slow" -msgstr "慢的" +msgstr "慢" msgid "Fast" -msgstr "快速地" +msgstr "快" From 63b5e7e052a2b78332ac1fa5dc2d9939707d6a2f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 17 Aug 2023 17:50:36 +0200 Subject: [PATCH 04/30] MCA Cirrus 2401 fix. Eliminate the 2401 display error on MCA machines using the Cirrus cards. --- src/video/vid_cl54xx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 2d89df10b..5b086c72f 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1636,7 +1636,7 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) uint32_t base; uint32_t size; - if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) { + if (gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->mmio_mapping); @@ -3863,13 +3863,16 @@ gd5428_mca_write(int port, uint8_t val, void *priv) return; gd54xx->pos_regs[port & 7] = val; - gd543x_recalc_mapping(gd54xx); + mem_mapping_disable(&gd54xx->bios_rom.mapping); + if (gd54xx->pos_regs[2] & 0x01) + mem_mapping_enable(&gd54xx->bios_rom.mapping); } static uint8_t -gd5428_mca_feedb(UNUSED(void *priv)) +gd5428_mca_feedb(void *priv) { - return 1; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + return gd54xx->pos_regs[2] & 0x01; } static void @@ -3891,7 +3894,7 @@ gd54xx_reset(void *priv) io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); mem_mapping_disable(&gd54xx->vgablt_mapping); - if (gd54xx->has_bios && gd54xx->pci) + if (gd54xx->has_bios && (gd54xx->pci || gd54xx->mca)) mem_mapping_disable(&gd54xx->bios_rom.mapping); memset(gd54xx->pci_regs, 0x00, 256); @@ -4235,6 +4238,7 @@ gd54xx_init(const device_t *info) if (gd54xx->mca) { gd54xx->pos_regs[0] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x82 : 0x7b; gd54xx->pos_regs[1] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x81 : 0x91; + mem_mapping_disable(&gd54xx->bios_rom.mapping); mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx); io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); } From f0ab35132b412b3dfd6e65fe51a01180963c3914 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 03:16:37 +0200 Subject: [PATCH 05/30] Always allocate 16 more bytes of RAM to mitigate potential segmentation faults on certain accessed by the old recompilers. --- src/mem/mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mem/mem.c b/src/mem/mem.c index 46826361b..088d15f51 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2695,7 +2695,7 @@ mem_reset(void) } memset(ram, 0x00, ram_size); ram2_size = m - (1 << 30); - ram2 = (uint8_t *) plat_mmap(ram2_size, 0); /* allocate and clear the RAM block above 1 GB */ + ram2 = (uint8_t *) plat_mmap(ram2_size + 16, 0); /* allocate and clear the RAM block above 1 GB */ if (ram2 == NULL) { if (config_changed == 2) fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); @@ -2708,7 +2708,7 @@ mem_reset(void) #endif { ram_size = m; - ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block */ + ram = (uint8_t *) plat_mmap(ram_size + 16, 0); /* allocate and clear the RAM block */ if (ram == NULL) { fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; From 565421a252b2e7f54cd18f0239503210c0f07ce7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 05:57:32 +0200 Subject: [PATCH 06/30] Serial receive/transmit rework (uses the new fifo.c API) and a small GDB stub fix. --- src/CMakeLists.txt | 3 +- src/device/serial.c | 408 +++++++++++----------- src/device/serial_passthrough.c | 3 +- src/fifo.c | 582 ++++++++++++++++++++++++++++++++ src/gdbstub.c | 4 + src/include/86box/fifo.h | 68 ++++ src/include/86box/serial.h | 16 +- src/mem/mem.c | 6 +- src/win/Makefile.mingw | 4 +- 9 files changed, 870 insertions(+), 224 deletions(-) create mode 100644 src/fifo.c create mode 100644 src/include/86box/fifo.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3809ead73..bfa582e33 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,7 +20,8 @@ endif() add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c - mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c machine_status.c ini.c) + mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c + machine_status.c ini.c) if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1) diff --git a/src/device/serial.c b/src/device/serial.c index 3a5b237c2..5dd5d8420 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -35,17 +35,20 @@ #include <86box/pic.h> #include <86box/mem.h> #include <86box/rom.h> +#include <86box/fifo.h> #include <86box/serial.h> #include <86box/mouse.h> serial_port_t com_ports[SERIAL_MAX]; enum { - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8, - SERIAL_INT_TIMEOUT = 16 + SERIAL_INT_LSR = 1, + SERIAL_INT_TIMEOUT = 2, + SERIAL_INT_RECEIVE = 4, + SERIAL_INT_TRANSMIT = 8, + SERIAL_INT_MSR = 16, + SERIAL_INT_RX_DMA_TC = 32, + SERIAL_INT_TX_DMA_TC = 64 }; void serial_update_ints(serial_t *dev); @@ -53,7 +56,7 @@ void serial_update_ints(serial_t *dev); static int next_inst = 0; static serial_device_t serial_devices[SERIAL_MAX]; -// #define ENABLE_SERIAL_CONSOLE 1 +static void serial_xmit_d_empty_evt(void *priv); #ifdef ENABLE_SERIAL_LOG int serial_do_log = ENABLE_SERIAL_LOG; @@ -76,16 +79,23 @@ serial_log(const char *fmt, ...) void serial_reset_port(serial_t *dev) { + if (dev->type >= SERIAL_16550) { + if (dev->fifo_enabled) + fifo_reset_evt(dev->xmit_fifo); + else + fifo_reset(dev->xmit_fifo); + } + dev->lsr = 0x60; /* Mark that both THR/FIFO and TXSR are empty. */ dev->iir = dev->ier = dev->lcr = dev->fcr = 0; + dev->fifo_enabled = 0; - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->xmit_fifo_end = dev->rcvr_fifo_end = 0; - dev->rcvr_fifo_full = 0; - dev->baud_cycles = 0; - dev->out_new = 0xffff; - memset(dev->xmit_fifo, 0, 16); - memset(dev->rcvr_fifo, 0, 16); + dev->baud_cycles = 0; + dev->out_new = 0xffff; + + dev->txsr_empty = 1; + dev->thr_empty = 1; + serial_update_ints(dev); dev->irq_state = 0; } @@ -120,33 +130,22 @@ serial_do_irq(serial_t *dev, int set) void serial_update_ints(serial_t *dev) { - int stat = 0; + /* TODO: The IRQ priorities are 6 - we need to find a way to treat timeout and receive + as equal and still somehow distinguish them. */ + uint8_t ier_map[7] = { 0x04, 0x01, 0x01, 0x02, 0x08, 0x40, 0x80 }; + uint8_t iir_map[7] = { 0x06, 0x0c, 0x04, 0x02, 0x00, 0x0e, 0x0a }; + int i; - dev->iir = 1; + dev->iir = (dev->iir & 0xf0) | 0x01; - if ((dev->ier & 4) && (dev->int_status & SERIAL_INT_LSR)) { - /* Line status interrupt */ - stat = 1; - dev->iir = 6; - } else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_TIMEOUT)) { - /* Received data available */ - stat = 1; - dev->iir = 0x0c; - } else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_RECEIVE)) { - /* Received data available */ - stat = 1; - dev->iir = 4; - } else if ((dev->ier & 2) && (dev->int_status & SERIAL_INT_TRANSMIT)) { - /* Transmit data empty */ - stat = 1; - dev->iir = 2; - } else if ((dev->ier & 8) && (dev->int_status & SERIAL_INT_MSR)) { - /* Modem status interrupt */ - stat = 1; - dev->iir = 0; + for (i = 0; i < 7; i++) { + if ((dev->ier & ier_map[i]) && (dev->int_status & (1 << i))) { + dev->iir = (dev->iir & 0xf0) | iir_map[i]; + break; + } } - serial_do_irq(dev, stat && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))); + serial_do_irq(dev, !(dev->iir & 0x01) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))); } static void @@ -163,60 +162,46 @@ serial_receive_timer(void *priv) { serial_t *dev = (serial_t *) priv; -#if 0 serial_log("serial_receive_timer()\n"); -#endif timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period); - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { + if (dev->fifo_enabled) { /* FIFO mode. */ - if (dev->out_new != 0xffff) { /* We have received a byte into the RSR. */ /* Clear FIFO timeout. */ serial_clear_timeout(dev); - if (dev->rcvr_fifo_full) { - /* Overrun - just discard the byte in the RSR. */ - serial_log("FIFO overrun\n"); + fifo_write_evt((uint8_t) (dev->out_new & 0xff), dev->rcvr_fifo); + dev->out_new = 0xffff; + + /* pclog("serial_receive_timer(): lsr = %02X, ier = %02X, iir = %02X, int_status = %02X\n", + dev->lsr, dev->ier, dev->iir, dev->int_status); */ + + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + } + } else { + /* Non-FIFO mode. */ + if (dev->out_new != 0xffff) { + /* We have received a byte into the RSR. */ + serial_log("Byte received: %04X\n", dev->out_new); + + /* Indicate overrun. */ + if (dev->lsr & 0x01) dev->lsr |= 0x02; - } else { - /* We can input data into the FIFO. */ - dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff); -#if 0 - dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f; -#endif - /* Do not wrap around, makes sure it still triggers the interrupt - at 16 bytes. */ - dev->rcvr_fifo_end++; - serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff), - abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos), - dev->rcvr_fifo_end, dev->rcvr_fifo_pos); - dev->out_new = 0xffff; + dev->dat = (uint8_t) (dev->out_new & 0xff); + dev->out_new = 0xffff; - if (abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos) >= dev->rcvr_fifo_len) { - /* We have >= trigger level bytes, raise Data Ready interrupt. */ - serial_log("We have >= %i bytes in the FIFO, data ready!\n", dev->rcvr_fifo_len); - dev->lsr |= 0x01; - dev->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(dev); - } + /* Raise Data Ready interrupt. */ + dev->lsr |= 0x01; + dev->int_status |= SERIAL_INT_RECEIVE; - /* Now wrap around. */ - dev->rcvr_fifo_end &= 0x0f; - - if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos) - dev->rcvr_fifo_full = 1; - - timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); - } + serial_update_ints(dev); } } - - serial_update_ints(dev); } static void @@ -224,26 +209,8 @@ write_fifo(serial_t *dev, uint8_t dat) { serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, - ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? (dev->rcvr_fifo_pos % dev->rcvr_fifo_len) : 0); - - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { - /* FIFO mode. */ - - /* This is the first phase, we are sending the data to the RSR (Receiver Shift - Register), from where it's going to get dispatched to the FIFO. */ - } else { - /* Non-FIFO mode. */ - - /* Indicate overrun. */ - if (dev->lsr & 0x01) - dev->lsr |= 0x02; - - /* Raise Data Ready interrupt. */ - serial_log("To RHR: %02X\n", dat); - dev->lsr |= 0x01; - dev->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(dev); - } + ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? + fifo_get_count(dev->rcvr_fifo) : 0); /* Do this here, because in non-FIFO mode, this is read directly. */ dev->out_new = (uint16_t) dat; @@ -252,7 +219,10 @@ write_fifo(serial_t *dev, uint8_t dat) void serial_write_fifo(serial_t *dev, uint8_t dat) { - serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f); + serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, + (dev->type >= SERIAL_16550) && dev->fifo_enabled, + ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? + fifo_get_count(dev->rcvr_fifo) : 0); if (!(dev->mctrl & 0x10)) write_fifo(dev, dat); @@ -265,48 +235,43 @@ serial_transmit(serial_t *dev, uint8_t val) write_fifo(dev, val); else if (dev->sd->dev_write) dev->sd->dev_write(dev, dev->sd->priv, val); + #ifdef ENABLE_SERIAL_CONSOLE if ((val >= ' ' && val <= '~') || val == '\r' || val == '\n') { fputc(val, stdout); if (val == '\n') fflush(stdout); - } else { + } else fprintf(stdout, "[%02X]", val); - } #endif } static void serial_move_to_txsr(serial_t *dev) { - if (dev->fifo_enabled) { - dev->txsr = dev->xmit_fifo[0]; - if (dev->xmit_fifo_pos > 0) { - /* Move the entire fifo forward by one byte. */ - for (uint8_t i = 1; i < 16; i++) - dev->xmit_fifo[i - 1] = dev->xmit_fifo[i]; - /* Decrease FIFO position. */ - dev->xmit_fifo_pos--; - } - } else { + dev->txsr_empty = 0; + if (dev->fifo_enabled) + dev->txsr = fifo_read_evt(dev->xmit_fifo); + else { dev->txsr = dev->thr; dev->thr = 0; + dev->thr_empty = 1; + serial_xmit_d_empty_evt(dev); } dev->lsr &= ~0x40; - serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", dev->xmit_fifo_pos & 0x0f); + serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", + fifo_get_count(dev->xmit_fifo) & 0x0f); - if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) { + if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) { /* Update interrupts to signal THRE and that TXSR is no longer empty. */ - dev->lsr |= 0x20; - dev->int_status |= SERIAL_INT_TRANSMIT; serial_update_ints(dev); } if (dev->transmit_enabled & 2) dev->baud_cycles++; else dev->baud_cycles = 0; /* If not moving while transmitting, reset BAUDOUT cycle count. */ - if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) + if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) dev->transmit_enabled &= ~1; /* Stop moving. */ dev->transmit_enabled |= 2; /* Start transmitting. */ } @@ -317,20 +282,18 @@ serial_process_txsr(serial_t *dev) serial_log("serial_process_txsr(): FIFO %sabled\n", dev->fifo_enabled ? "en" : "dis"); serial_transmit(dev, dev->txsr); dev->txsr = 0; + dev->txsr_empty = 1; + serial_xmit_d_empty_evt(dev); /* Reset BAUDOUT cycle count. */ dev->baud_cycles = 0; /* If FIFO is enabled and there are bytes left to transmit, continue with the FIFO, otherwise stop. */ - if (dev->fifo_enabled && (dev->xmit_fifo_pos != 0x0)) + if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) != 0x0)) dev->transmit_enabled |= 1; - else { - /* Both FIFO/THR and TXSR are empty. */ - /* If bit 5 is set, also set bit 6 to mark both THR and shift register as empty. */ - if (dev->lsr & 0x20) - dev->lsr |= 0x40; + /* Both FIFO/THR and TXSR are empty. */ + else dev->transmit_enabled &= ~2; - } - dev->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(dev); } @@ -370,9 +333,7 @@ serial_timeout_timer(void *priv) { serial_t *dev = (serial_t *) priv; -#ifdef ENABLE_SERIAL_LOG serial_log("serial_timeout_timer()\n"); -#endif dev->lsr |= 0x01; dev->int_status |= SERIAL_INT_TIMEOUT; @@ -384,9 +345,7 @@ serial_device_timeout(void *priv) { serial_t *dev = (serial_t *) priv; -#ifdef ENABLE_SERIAL_LOG serial_log("serial_device_timeout()\n"); -#endif if (!dev->fifo_enabled) { dev->lsr |= 0x10; @@ -398,6 +357,7 @@ serial_device_timeout(void *priv) static void serial_update_speed(serial_t *dev) { + serial_log("serial_update_speed(%lf)\n", dev->transmit_period); timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period); if (dev->transmit_enabled & 3) @@ -410,11 +370,10 @@ serial_update_speed(serial_t *dev) static void serial_reset_fifo(serial_t *dev) { - dev->lsr = (dev->lsr & 0xfe) | 0x60; - dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | SERIAL_INT_TRANSMIT; + fifo_reset_evt(dev->xmit_fifo); + fifo_reset_evt(dev->rcvr_fifo); + serial_update_ints(dev); - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_full = 0; } void @@ -490,7 +449,6 @@ serial_write(uint16_t addr, uint8_t val, void *p) uint8_t new_msr; uint8_t old; - // serial_log("UART: Write %02X to port %02X\n", val, addr); serial_log("UART: [%04X:%08X] Write %02X to port %02X\n", CS, cpu_state.pc, val, addr); cycles -= ISA_CYCLES(8); @@ -504,21 +462,22 @@ serial_write(uint16_t addr, uint8_t val, void *p) return; } - /* Indicate FIFO/THR is no longer empty. */ - dev->lsr &= 0x9f; - dev->int_status &= ~SERIAL_INT_TRANSMIT; - serial_update_ints(dev); - - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) { + if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) < 16)) { /* FIFO mode, begin transmitting. */ timer_on_auto(&dev->transmit_timer, dev->transmit_period); dev->transmit_enabled |= 1; /* Start moving. */ - dev->xmit_fifo[dev->xmit_fifo_pos++] = val; - } else { + fifo_write_evt(val, dev->xmit_fifo); + } else if (!dev->fifo_enabled) { + /* Indicate THR is no longer empty. */ + dev->lsr &= 0x9f; + dev->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(dev); + /* Non-FIFO mode, begin transmitting. */ timer_on_auto(&dev->transmit_timer, dev->transmit_period); dev->transmit_enabled |= 1; /* Start moving. */ dev->thr = val; + dev->thr_empty = 0; } break; case 1: @@ -539,42 +498,42 @@ serial_write(uint16_t addr, uint8_t val, void *p) serial_reset_fifo(dev); dev->fcr = val & 0xf9; dev->fifo_enabled = val & 0x01; + /* TODO: When switching modes, shouldn't we reset the LSR + based on the new conditions? */ if (!dev->fifo_enabled) { - memset(dev->rcvr_fifo, 0, 14); - memset(dev->xmit_fifo, 0, 16); - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_full = 0; - dev->rcvr_fifo_len = 1; + fifo_reset(dev->xmit_fifo); + fifo_reset(dev->rcvr_fifo); break; } if (val & 0x02) { - memset(dev->rcvr_fifo, 0, 14); - dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_end = 0; - dev->rcvr_fifo_full = 0; + if (dev->fifo_enabled) + fifo_reset_evt(dev->rcvr_fifo); + else + fifo_reset(dev->rcvr_fifo); } if (val & 0x04) { - memset(dev->xmit_fifo, 0, 16); - dev->xmit_fifo_pos = 0; + if (dev->fifo_enabled) + fifo_reset_evt(dev->xmit_fifo); + else + fifo_reset(dev->xmit_fifo); } switch ((val >> 6) & 0x03) { case 0: - dev->rcvr_fifo_len = 1; + fifo_set_trigger_len(dev->rcvr_fifo, 1); break; case 1: - dev->rcvr_fifo_len = 4; + fifo_set_trigger_len(dev->rcvr_fifo, 4); break; case 2: - dev->rcvr_fifo_len = 8; + fifo_set_trigger_len(dev->rcvr_fifo, 8); break; case 3: - dev->rcvr_fifo_len = 14; - break; - default: + fifo_set_trigger_len(dev->rcvr_fifo, 14); break; } + fifo_set_trigger_len(dev->xmit_fifo, 16); dev->out_new = 0xffff; - serial_log("FIFO now %sabled, receive FIFO length = %i\n", dev->fifo_enabled ? "en" : "dis", dev->rcvr_fifo_len); + serial_log("FIFO now %sabled\n", dev->fifo_enabled ? "en" : "dis"); } break; case 3: @@ -600,8 +559,10 @@ serial_write(uint16_t addr, uint8_t val, void *p) break; case 4: if ((val & 2) && !(dev->mctrl & 2)) { - if (dev->sd && dev->sd->rcr_callback) + if (dev->sd && dev->sd->rcr_callback) { + serial_log("RTS toggle callback\n"); dev->sd->rcr_callback(dev, dev->sd->priv); + } } if (!(val & 8) && (dev->mctrl & 8)) serial_do_irq(dev, 0); @@ -624,8 +585,9 @@ serial_write(uint16_t addr, uint8_t val, void *p) dev->msr = new_msr; - dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0; - dev->rcvr_fifo_full = 0; + /* TODO: Why reset the FIFO's here?! */ + fifo_reset(dev->xmit_fifo); + fifo_reset(dev->rcvr_fifo); } break; case 5: @@ -674,41 +636,16 @@ serial_read(uint16_t addr, void *p) break; } - /* Clear timeout. */ - serial_clear_timeout(dev); - - if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { + if (dev->fifo_enabled) { /* FIFO mode. */ + serial_clear_timeout(dev); + ret = fifo_read_evt(dev->rcvr_fifo); - if (dev->rcvr_fifo_full || (dev->rcvr_fifo_pos != dev->rcvr_fifo_end)) { - /* There is data in the FIFO. */ - ret = dev->rcvr_fifo[dev->rcvr_fifo_pos]; - dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f; - - /* Make sure to clear the FIFO full condition. */ - dev->rcvr_fifo_full = 0; - - if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) { - /* Amount of data in the FIFO below trigger level, - clear Data Ready interrupt. */ - dev->int_status &= ~SERIAL_INT_RECEIVE; - serial_update_ints(dev); - } - - /* Make sure the Data Ready bit of the LSR is set if we still have - bytes left in the FIFO. */ - if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) { - dev->lsr |= 0x01; - /* There are bytes left in the FIFO, activate the FIFO Timeout timer. */ - timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); - } else - dev->lsr &= 0xfe; - } + if (dev->lsr & 0x01) + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); } else { /* Non-FIFO mode. */ - - ret = (uint8_t) (dev->out_new & 0xffff); - dev->out_new = 0xffff; + ret = dev->dat; /* Always clear Data Ready interrupt. */ dev->lsr &= 0xfe; @@ -716,7 +653,7 @@ serial_read(uint16_t addr, void *p) serial_update_ints(dev); } - // serial_log("Read data: %02X\n", ret); + serial_log("Read data: %02X\n", ret); break; case 1: if (dev->lcr & 0x80) @@ -759,7 +696,6 @@ serial_read(uint16_t addr, void *p) break; } - // serial_log("UART: Read %02X from port %02X\n", ret, addr); serial_log("UART: [%04X:%08X] Read %02X from port %02X\n", CS, cpu_state.pc, ret, addr); return ret; } @@ -801,6 +737,42 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq) dev->irq = irq; } +static void +serial_rcvr_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo); +} + +static void +serial_rcvr_d_overrun_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1); +} + +static void +serial_rcvr_d_ready_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0); + serial_update_ints(dev); +} + +static void +serial_xmit_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + uint8_t is_empty = dev->fifo_enabled ? fifo_get_empty(dev->xmit_fifo) : dev->thr_empty; + + dev->lsr = (dev->lsr & 0x9f) | (is_empty << 5) | ((dev->txsr_empty && is_empty) << 6); + dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) | (is_empty ? SERIAL_INT_TRANSMIT : 0); +} + serial_t * serial_attach_ex(int port, void (*rcr_callback)(struct serial_s *serial, void *p), @@ -835,6 +807,9 @@ serial_close(void *priv) next_inst--; + if (com_ports[dev->inst].enabled) + fifo_close(dev->rcvr_fifo); + free(dev); } @@ -843,27 +818,33 @@ serial_reset(void *priv) { serial_t *dev = (serial_t *) priv; - timer_disable(&dev->transmit_timer); - timer_disable(&dev->timeout_timer); - timer_disable(&dev->receive_timer); + if (com_ports[dev->inst].enabled) { + timer_disable(&dev->transmit_timer); + timer_disable(&dev->timeout_timer); + timer_disable(&dev->receive_timer); - dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00; - dev->iir = dev->ier = dev->lcr = dev->msr = 0x00; - dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00; - dev->fifo_enabled = dev->rcvr_fifo_len = dev->bits = dev->data_bits = 0x00; - dev->baud_cycles = dev->rcvr_fifo_full = dev->txsr = dev->out = 0x00; + dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00; + dev->iir = dev->ier = dev->lcr = dev->msr = 0x00; + dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00; + dev->fifo_enabled = dev->bits = 0x000; + dev->data_bits = dev->baud_cycles = 0x00; + dev->txsr = 0x00; + dev->txsr_empty = 0x01; + dev->thr_empty = 0x0001; - dev->dlab = dev->out_new = 0x0000; + dev->dlab = dev->out_new = 0x0000; - dev->rcvr_fifo_pos = dev->xmit_fifo_pos = dev->rcvr_fifo_end = dev->xmit_fifo_end = 0x00; + if (dev->rcvr_fifo != NULL) + fifo_reset(dev->rcvr_fifo); - serial_reset_port(dev); + serial_reset_port(dev); - dev->dlab = 96; - dev->fcr = 0x06; + dev->dlab = 96; + dev->fcr = 0x06; - serial_transmit_period(dev); - serial_update_speed(dev); + serial_transmit_period(dev); + serial_update_speed(dev); + } } static void * @@ -880,7 +861,6 @@ serial_init(const device_t *info) memset(&(serial_devices[next_inst]), 0, sizeof(serial_device_t)); dev->sd = &(serial_devices[next_inst]); dev->sd->serial = dev; - serial_reset_port(dev); if (next_inst == 3) serial_setup(dev, COM4_ADDR, COM4_IRQ); else if (next_inst == 2) @@ -902,6 +882,22 @@ serial_init(const device_t *info) timer_add(&dev->receive_timer, serial_receive_timer, dev, 0); serial_transmit_period(dev); serial_update_speed(dev); + + dev->rcvr_fifo = fifo64_init(); + fifo_set_priv(dev->rcvr_fifo, dev); + fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt); + fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt); + fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt); + fifo_reset_evt(dev->rcvr_fifo); + fifo_set_len(dev->rcvr_fifo, 16); + + dev->xmit_fifo = fifo64_init(); + fifo_set_priv(dev->xmit_fifo, dev); + fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt); + fifo_reset_evt(dev->xmit_fifo); + fifo_set_len(dev->xmit_fifo, 16); + + serial_reset_port(dev); } next_inst++; diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index b703cd67c..1b1c5e3bf 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -25,6 +25,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/fifo.h> #include <86box/timer.h> #include <86box/serial.h> #include <86box/serial_passthrough.h> @@ -78,7 +79,7 @@ host_to_serial_cb(void *priv) * can never fetch the bytes in time, so check if the fifo is full if in * fifo mode or if lsr has bit 0 set if not in fifo mode */ if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { - if (dev->serial->rcvr_fifo_full) { + if (fifo_get_full(dev->serial->rcvr_fifo)) { goto no_write_to_machine; } } else { diff --git a/src/fifo.c b/src/fifo.c new file mode 100644 index 000000000..e852fda31 --- /dev/null +++ b/src/fifo.c @@ -0,0 +1,582 @@ +/* + * 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. + * + * FIFO infrastructure. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#ifdef FIFO_STANDALONE +#define fatal printf +#define pclog_ex printf +#define pclog printf +#include "include/86box/fifo.h" +#else +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/fifo.h> +#endif + +#ifdef ENABLE_FIFO_LOG +int fifo_do_log = ENABLE_FIFO_LOG; + +static void +fifo_log(const char *fmt, ...) +{ + va_list ap; + + if (fifo_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define fifo_log(fmt, ...) +#endif + +int +fifo_get_count(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->len; + + if (fifo->end == fifo->start) + ret = fifo->full ? fifo->len : 0; + else + ret = abs(fifo->end - fifo->start); + + return ret; +} + +void +fifo_write(uint8_t val, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = fifo->d_overrun = 0; + + if (fifo->full) + fifo->overrun = 1; + else { + fifo->buf[fifo->end] = val; + fifo->end = (fifo->end + 1) & 0x0f; + + if (fifo->end == fifo->start) + fifo->full = 1; + + fifo->empty = 0; + + if (fifo_get_count(fifo) >= fifo->trigger_len) + fifo->ready = 1; + } +} + +void +fifo_write_evt(uint8_t val, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = fifo->d_overrun = 0; + + if (fifo->full) { + fifo->d_overrun = (fifo->overrun != 1); + fifo->overrun = 1; + if (fifo->d_overrun && (fifo->d_overrun_evt != NULL)) + fifo->d_overrun_evt(fifo->priv); + } else { + fifo->buf[fifo->end] = val; + fifo->end = (fifo->end + 1) & 0x0f; + + if (fifo->end == fifo->start) { + fifo->d_full = (fifo->full != 1); + fifo->full = 1; + if (fifo->d_full && (fifo->d_full_evt != NULL)) + fifo->d_full_evt(fifo->priv); + } + + fifo->d_empty = (fifo->empty != 0); + fifo->empty = 0; + if (fifo->d_empty && (fifo->d_empty_evt != NULL)) + fifo->d_empty_evt(fifo->priv); + + if (fifo_get_count(fifo) >= fifo->trigger_len) { + fifo->d_ready = (fifo->ready != 1); + fifo->ready = 1; + if (fifo->d_ready && (fifo->d_ready_evt != NULL)) + fifo->d_ready_evt(fifo->priv); + } + } +} + +uint8_t +fifo_read(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + uint8_t ret = 0x00; + int count; + + if (!fifo->empty) { + ret = fifo->buf[fifo->start]; + fifo->start = (fifo->start + 1) & 0x0f; + + fifo->full = 0; + + count = fifo_get_count(fifo); + + if (count < fifo->trigger_len) { + fifo->ready = 0; + + if (count == 0) + fifo->empty = 1; + } + } + + return ret; +} + +uint8_t +fifo_read_evt(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + uint8_t ret = 0x00; + int count; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = 0; + + if (!fifo->empty) { + ret = fifo->buf[fifo->start]; + fifo->start = (fifo->start + 1) & 0x0f; + + fifo->d_full = (fifo->full != 0); + fifo->full = 0; + if (fifo->d_full && (fifo->d_full_evt != NULL)) + fifo->d_full_evt(fifo->priv); + + count = fifo_get_count(fifo); + + if (count < fifo->trigger_len) { + fifo->d_ready = (fifo->ready != 0); + fifo->ready = 0; + if (fifo->d_ready && (fifo->d_ready_evt != NULL)) + fifo->d_ready_evt(fifo->priv); + + if (count == 0) { + fifo->d_empty = (fifo->empty != 1); + fifo->empty = 1; + if (fifo->d_empty && (fifo->d_empty_evt != NULL)) + fifo->d_empty_evt(fifo->priv); + } + } + } + + return ret; +} + +void +fifo_clear_overrun(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_overrun = (fifo->overrun != 0); + fifo->overrun = 0; +} + +int +fifo_get_full(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + return fifo->full; +} + +int +fifo_get_d_full(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_full; + + fifo->d_full = 0; + return ret; +} + +int +fifo_get_empty(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + return fifo->empty; +} + +int +fifo_get_d_empty(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_empty; + + fifo->d_empty = 0; + return ret; +} + +int +fifo_get_overrun(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + return fifo->overrun; +} + +int +fifo_get_d_overrun(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_overrun; + + fifo->d_overrun = 0; + return ret; +} + +int +fifo_get_ready(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + return fifo->ready; +} + +int +fifo_get_d_ready(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + int ret = fifo->d_ready; + + fifo->d_ready = 0; + return ret; +} + +int +fifo_get_trigger_len(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + return fifo->trigger_len; +} + +void +fifo_set_trigger_len(void *priv, int trigger_len) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->trigger_len = trigger_len; +} + +void +fifo_set_len(void *priv, int len) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->len = len; +} + +void +fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full_evt = d_full_evt; +} + +void +fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_empty_evt = d_empty_evt; +} + +void +fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_overrun_evt = d_overrun_evt; +} + +void +fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *)) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_ready_evt = d_ready_evt; +} + +void +fifo_set_priv(void *priv, void *sub_priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->priv = sub_priv; +} + +void +fifo_reset(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->start = fifo->end = 0; + fifo->full = fifo->overrun = 0; + fifo->empty = 1; + fifo->ready = 0; +} + +void +fifo_reset_evt(void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->start = fifo->end = 0; + fifo->full = fifo->overrun = 0; + fifo->empty = 1; + fifo->ready = 0; + fifo->d_full = fifo->d_overrun = 0; + fifo->d_empty = fifo->d_ready = 0; + + if (fifo->d_full_evt != NULL) + fifo->d_full_evt(fifo->priv); + + if (fifo->d_overrun_evt != NULL) + fifo->d_overrun_evt(fifo->priv); + + if (fifo->d_empty_evt != NULL) + fifo->d_empty_evt(fifo->priv); + + if (fifo->d_ready_evt != NULL) + fifo->d_ready_evt(fifo->priv); +} + +void +fifo_close(void *priv) +{ + free(priv); +} + +void * +fifo_init(int len) +{ + void *fifo = NULL; + + if (len == 64) + fifo = (void *) calloc(1, sizeof(fifo64_t)); + else if (len == 16) + fifo = (void *) calloc(1, sizeof(fifo16_t)); + else { + fatal("FIFO : Invalid FIFO length: %i\n", len); + return NULL; + } + + if (fifo == NULL) + fatal("FIFO%i: Failed to allocate memory for the FIFO\n", len); + else + ((fifo_t *) fifo)->len = len; + + return fifo; +} + +#ifdef FIFO_STANDALONE +enum { + SERIAL_INT_LSR = 1, + SERIAL_INT_RECEIVE = 2, + SERIAL_INT_TRANSMIT = 4, + SERIAL_INT_MSR = 8, + SERIAL_INT_TIMEOUT = 16 +}; + +typedef struct +{ + uint8_t lsr, int_status, tsr, tsr_empty; + + fifo16_t *rcvr_fifo, *xmit_fifo; +} serial_t; + +static void +serial_receive_timer(fifo16_t *f16, uint8_t val) +{ + fifo_write_evt(val, f16); + + printf("Write %02X to FIFO [F: %i, E: %i, O: %i, R: %i]\n", val, + fifo_get_full(f16), fifo_get_empty(f16), + fifo_get_overrun(f16), fifo_get_ready(f16)); + + /* + if (fifo_get_d_overrun(f16)) + dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(f16) << 1); + */ + if (fifo_get_d_overrun(f16)) printf(" FIFO overrun state changed: %i -> %i\n", + !fifo_get_overrun(f16), fifo_get_overrun(f16)); + + /* + if (fifo_get_d_empty(f16)) { + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16); + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + } + */ + if (fifo_get_d_empty(f16)) printf(" FIFO empty state changed: %i -> %i\n", + !fifo_get_empty(f16), fifo_get_empty(f16)); + + /* + if (fifo_get_d_ready(f16)) { + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0); + serial_update_ints(); + } + */ + if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n", + !fifo_get_ready(f16), fifo_get_ready(f16)); +} + +static uint8_t +serial_read(fifo16_t *f16) +{ + uint8_t ret; + + ret = fifo_read_evt(f16); + + printf("Read %02X from FIFO [F: %i, E: %i, O: %i, R: %i]\n", ret, + fifo_get_full(f16), fifo_get_empty(f16), + fifo_get_overrun(f16), fifo_get_ready(f16)); + + /* + if (fifo_get_d_ready(f16)) { + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0); + serial_update_ints(); + } + */ + if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n", + !fifo_get_ready(f16), fifo_get_ready(f16)); + + /* + if (fifo_get_d_empty(f16)) { + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16); + timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + } + */ + if (fifo_get_d_empty(f16)) printf(" FIFO empty state changed: %i -> %i\n", + !fifo_get_empty(f16), fifo_get_empty(f16)); + + return ret; +} + +static void +serial_xmit_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0x9f) | (fifo_get_empty(dev->xmit_fifo) << 5) | + ((dev->tsr_empty && fifo_get_empty(dev->xmit_fifo)) << 6); + dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) | + (fifo_get_empty(dev->xmit_fifo) ? SERIAL_INT_TRANSMIT : 0); + // serial_update_ints(); + + printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr); + printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status); +} + +static void +serial_rcvr_d_empty_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo); + // timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); + + printf("NS16550: serial_rcvr_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr); +} + +static void +serial_rcvr_d_overrun_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1); + + printf("NS16550: serial_rcvr_d_overrun_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr); +} + +static void +serial_rcvr_d_ready_evt(void *priv) +{ + serial_t *dev = (serial_t *) priv; + + dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | + (fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0); + // serial_update_ints(); + + printf("NS16550: serial_rcvr_d_ready_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status); +} + +int +main(int argc, char *argv[]) +{ + uint8_t val, ret; + + printf("Initializing serial...\n"); + serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t)); + dev->tsr_empty = 1; + + printf("Initializing dev->xmit_fifo...\n"); + dev->xmit_fifo = fifo16_init(); + fifo_set_trigger_len(dev->xmit_fifo, 255); + + fifo_set_priv(dev->xmit_fifo, dev); + fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt); + + printf("\nResetting dev->xmit_fifo...\n"); + fifo_reset_evt(dev->xmit_fifo); + + printf("\nInitializing dev->rcvr_fifo...\n"); + dev->rcvr_fifo = fifo16_init(); + fifo_set_trigger_len(dev->rcvr_fifo, 4); + + fifo_set_priv(dev->rcvr_fifo, dev); + fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt); + fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt); + fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt); + + printf("\nResetting dev->rcvr_fifo...\n"); + fifo_reset_evt(dev->rcvr_fifo); + + printf("\nSending/receiving data...\n"); + serial_receive_timer(dev->rcvr_fifo, '8'); + serial_receive_timer(dev->rcvr_fifo, '6'); + ret = serial_read(dev->rcvr_fifo); + serial_receive_timer(dev->rcvr_fifo, 'B'); + ret = serial_read(dev->rcvr_fifo); + serial_receive_timer(dev->rcvr_fifo, 'o'); + ret = serial_read(dev->rcvr_fifo); + serial_receive_timer(dev->rcvr_fifo, 'x'); + ret = serial_read(dev->rcvr_fifo); + ret = serial_read(dev->rcvr_fifo); + + fifo_close(dev->rcvr_fifo); + fifo_close(dev->xmit_fifo); + + free(dev); + + return 0; +} +#endif diff --git a/src/gdbstub.c b/src/gdbstub.c index 97bf82fc9..30785eeac 100644 --- a/src/gdbstub.c +++ b/src/gdbstub.c @@ -75,8 +75,10 @@ enum { GDB_REG_ES, GDB_REG_FS, GDB_REG_GS, +#if 0 GDB_REG_FS_BASE, GDB_REG_GS_BASE, +#endif GDB_REG_CR0, GDB_REG_CR2, GDB_REG_CR3, @@ -678,9 +680,11 @@ gdbstub_client_read_reg(int index, uint8_t *buf) *((uint16_t *) buf) = segment_regs[index - GDB_REG_CS]->seg; break; +#if 0 case GDB_REG_FS_BASE ... GDB_REG_GS_BASE: *((uint32_t *) buf) = segment_regs[(index - 16) + (GDB_REG_FS - GDB_REG_CS)]->base; break; +#endif case GDB_REG_CR0 ... GDB_REG_CR4: *((uint32_t *) buf) = *cr_regs[index - GDB_REG_CR0]; diff --git a/src/include/86box/fifo.h b/src/include/86box/fifo.h new file mode 100644 index 000000000..71a40b0ce --- /dev/null +++ b/src/include/86box/fifo.h @@ -0,0 +1,68 @@ +/* + * 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. + * + * FIFO infrastructure header. + * + * Authors: Miran Grca, + * + * Copyright 2023 Miran Grca. + */ +#define FIFO(size) \ + typedef struct \ + { \ + int start, end, \ + trigger_len, len, \ + empty, overrun, \ + full, ready, \ + d_empty, d_overrun, \ + d_full, d_ready; \ + \ + void *priv; \ + \ + void (*d_empty_evt)(void *); \ + void (*d_overrun_evt)(void *); \ + void (*d_full_evt)(void *); \ + void (*d_ready_evt)(void *); \ + \ + uint8_t buf[size]; \ + } fifo## size ##_t; + +FIFO() + +FIFO(16) +#define fifo16_init() fifo_init(16) + +FIFO(64) +#define fifo64_init() fifo_init(64) + +extern int fifo_get_count(void *priv); +extern void fifo_write(uint8_t val, void *priv); +extern void fifo_write_evt(uint8_t val, void *priv); +extern uint8_t fifo_read(void *priv); +extern uint8_t fifo_read_evt(void *priv); +extern void fifo_clear_overrun(void *priv); +extern int fifo_get_full(void *priv); +extern int fifo_get_d_full(void *priv); +extern int fifo_get_empty(void *priv); +extern int fifo_get_d_empty(void *priv); +extern int fifo_get_overrun(void *priv); +extern int fifo_get_d_overrun(void *priv); +extern int fifo_get_ready(void *priv); +extern int fifo_get_d_ready(void *priv); +extern int fifo_get_trigger_len(void *priv); +extern void fifo_set_trigger_len(void *priv, int trigger_len); +extern void fifo_set_len(void *priv, int len); +extern void fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *)); +extern void fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *)); +extern void fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *)); +extern void fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *)); +extern void fifo_set_priv(void *priv, void *sub_priv); +extern void fifo_reset(void *priv); +extern void fifo_reset_evt(void *priv); +extern void fifo_close(void *priv); +extern void * fifo_init(int len); diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 2b31a153b..724f2f90f 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -65,29 +65,21 @@ typedef struct serial_s { uint8_t inst; uint8_t transmit_enabled; uint8_t fifo_enabled; - uint8_t rcvr_fifo_len; uint8_t bits; uint8_t data_bits; uint8_t baud_cycles; - uint8_t rcvr_fifo_full; uint8_t txsr; - uint8_t out; + uint8_t txsr_empty; uint8_t msr_set; - uint8_t pad; uint8_t irq_state; - uint8_t pad0; uint16_t dlab; uint16_t base_address; uint16_t out_new; - uint16_t pad1; + uint16_t thr_empty; - uint8_t rcvr_fifo_pos; - uint8_t xmit_fifo_pos; - uint8_t rcvr_fifo_end; - uint8_t xmit_fifo_end; - uint8_t rcvr_fifo[SERIAL_FIFO_SIZE]; - uint8_t xmit_fifo[SERIAL_FIFO_SIZE]; + void *rcvr_fifo; + void *xmit_fifo; pc_timer_t transmit_timer; pc_timer_t timeout_timer; diff --git a/src/mem/mem.c b/src/mem/mem.c index 088d15f51..af80365e8 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2695,6 +2695,7 @@ mem_reset(void) } memset(ram, 0x00, ram_size); ram2_size = m - (1 << 30); + /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ ram2 = (uint8_t *) plat_mmap(ram2_size + 16, 0); /* allocate and clear the RAM block above 1 GB */ if (ram2 == NULL) { if (config_changed == 2) @@ -2703,17 +2704,18 @@ mem_reset(void) fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram2, 0x00, ram2_size); + memset(ram2, 0x00, ram2_size + 16); } else #endif { ram_size = m; + /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ ram = (uint8_t *) plat_mmap(ram_size + 16, 0); /* allocate and clear the RAM block */ if (ram == NULL) { fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); return; } - memset(ram, 0x00, ram_size); + memset(ram, 0x00, ram_size + 16); if (mem_size > 1048576) ram2 = &(ram[1 << 30]); } diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 9275d1ebf..b5cbfd9f7 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -564,8 +564,8 @@ CFLAGS += -Werror=implicit-int -Werror=implicit-function-declaration \ # Create the (final) list of objects to build. # ######################################################################### MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ + nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo.o \ + fifo8.o usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o ini.o \ $(VNCOBJ) MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o mmu_2386.o rom.o row.o \ From 975ae1f0057e2e133ef632ac584715c8f3ecf47b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 16:39:26 +0200 Subject: [PATCH 07/30] Fixed some MPU-401 bugs, including the IRQ being cleared where it should not have been, fixes the music on Princess Maker 2, fixes #3233. --- src/sound/snd_mpu401.c | 66 ++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index f4c12f2f6..0f693115e 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -18,6 +18,7 @@ * Copyright 2016-2020 Miran Grca. * Copyright 2016-2020 TheCollector1995. */ +#include #include #include #include @@ -104,12 +105,23 @@ MPU401_ReCalcClock(mpu_t *mpu) } } +static void +MPU401_ReStartClock(mpu_t *mpu) +{ + if (mpu->clock.active) { + timer_disable(&mpu->mpu401_event_callback); + timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); + } +} + static void MPU401_StartClock(mpu_t *mpu) { + mpu401_log("MPU401_StartClock(): %i, %i, %i, %i\n", mpu->clock.active, mpu->state.clock_to_host, + mpu->state.playing, (mpu->state.rec == M_RECON)); if (mpu->clock.active) return; - if (!(mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON))) + if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON)) return; mpu->clock.active = 1; @@ -119,7 +131,7 @@ MPU401_StartClock(mpu_t *mpu) static void MPU401_StopClock(mpu_t *mpu) { - if (mpu->state.clock_to_host || mpu->state.playing || (mpu->state.rec == M_RECON)) + if (!mpu->state.clock_to_host && !mpu->state.playing && (mpu->state.rec == M_RECOFF)) return; mpu->clock.active = 0; timer_disable(&mpu->mpu401_event_callback); @@ -132,8 +144,8 @@ MPU401_RunClock(mpu_t *mpu) timer_disable(&mpu->mpu401_event_callback); return; } - timer_set_delay_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); - mpu401_log("Next event after %i us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); + timer_advance_u64(&mpu->mpu401_event_callback, (MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC); + // mpu401_log("Next event after %" PRIu64 " us (time constant: %i)\n", (uint64_t) ((MPU401_TIMECONSTANT / mpu->clock.freq) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); } static void @@ -411,15 +423,16 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) } switch (val & 0xc) { /* Playing */ case 0x4: /* Stop */ - mpu->state.playing = 0; MPU401_StopClock(mpu); + mpu->state.playing = 0; for (i = 0; i < 16; i++) MPU401_NotesOff(mpu, i); mpu->filter.prchg_mask = 0; break; case 0x8: /* Start */ - mpu->state.playing = 1; MPU401_StartClock(mpu); + mpu->state.playing = 1; + MPU401_ClrQueue(mpu); break; default: @@ -429,14 +442,14 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) case 0: /* check if it waited for MIDI RT command */ if (((val & 3) < 2) || !mpu->filter.rt_affection || (mpu->state.rec != M_RECSTB)) break; - mpu->state.rec = M_RECON; MPU401_StartClock(mpu); + mpu->state.rec = M_RECON; if (mpu->filter.prchg_mask) send_prchg = 1; break; case 0x10: /* Stop */ - mpu->state.rec = M_RECOFF; MPU401_StopClock(mpu); + mpu->state.rec = M_RECOFF; MPU401_QueueByte(mpu, MSG_MPU_ACK); MPU401_QueueByte(mpu, mpu->clock.rec_counter); MPU401_QueueByte(mpu, MSG_MPU_END); @@ -579,12 +592,12 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) mpu->filter.rt_affection = !!(val & 1); break; case 0x94: /* Clock to host */ - mpu->state.clock_to_host = 0; MPU401_StopClock(mpu); + mpu->state.clock_to_host = 0; break; case 0x95: - mpu->state.clock_to_host = 1; MPU401_StartClock(mpu); + mpu->state.clock_to_host = 1; break; case 0x96: case 0x97: /* Sysex input allow */ @@ -659,6 +672,7 @@ MPU401_WriteCommand(mpu_t *mpu, uint8_t val) case 0xc8: mpu->clock.timebase = MPUClockBase[val - 0xc2]; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); break; case 0xdf: /* Send system message */ mpu->state.wsd = 0; @@ -733,16 +747,19 @@ MPU401_WriteData(mpu_t *mpu, uint8_t val) else mpu->clock.tempo = val; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); return; case 0xe1: /* Set relative tempo */ mpu->state.command_byte = 0; mpu->clock.old_tempo_rel = mpu->clock.tempo_rel; mpu->clock.tempo_rel = val; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); return; case 0xe2: /* Set gradation for relative tempo */ mpu->clock.tempo_grad = val; MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); return; case 0xe4: /* Set MIDI clocks for metronome ticks */ mpu->state.command_byte = 0; @@ -1079,25 +1096,6 @@ UpdateTrack(mpu_t *mpu, uint8_t track) } } -#if 0 -static void -UpdateConductor(mpu_t *mpu) -{ - if (mpu->condbuf.value[0] == 0xfc) { - mpu->condbuf.value[0] = 0; - mpu->state.conductor = 0; - mpu->state.req_mask &= ~(1 << 9); - if (mpu->state.amask == 0) - mpu->state.req_mask |= (1 << 12); - return; - } - - mpu->condbuf.vlength = 0; - mpu->condbuf.counter = 0xf0; - mpu->state.req_mask |= (1 << 9); -} -#endif - /* Updates counters and requests new data on "End of Input" */ static void MPU401_EOIHandler(void *priv) @@ -1121,16 +1119,15 @@ MPU401_EOIHandler(void *priv) if (mpu->state.rec_copy || !mpu->state.sysex_in_finished) return; + if (!mpu->state.req_mask || !mpu->clock.active) + return; + if (mpu->ext_irq_update) mpu->ext_irq_update(mpu->priv, 0); else { mpu->state.irq_pending = 0; - picintc(1 << mpu->irq); } - if (!(mpu->state.req_mask && mpu->clock.active)) - return; - i = 0; do { if (mpu->state.req_mask & (1 << i)) { @@ -1381,7 +1378,7 @@ MPU401_Event(void *priv) } } - if (MPU401_IRQPending(mpu) && mpu->state.req_mask) + if (!MPU401_IRQPending(mpu) && mpu->state.req_mask) MPU401_EOIHandler(mpu); next_event: @@ -1599,6 +1596,7 @@ MPU401_InputMsg(void *p, uint8_t *msg, uint32_t len) mpu->clock.freq_mod /= mpu->clock.ticks_in / (float) (tick); } MPU401_ReCalcClock(mpu); + MPU401_ReStartClock(mpu); } mpu->clock.ticks_in = 0; } From daa702c1b6e745fcd78c72b4e4b6539f2cda7434 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 17:52:30 +0200 Subject: [PATCH 08/30] Clean-ups in config.c - removed excess #if 0's block and sanitized the way file names are handled for all media, they are now all saved as relative. --- src/config.c | 323 ++++++++++++++++++++------------------------------- 1 file changed, 129 insertions(+), 194 deletions(-) diff --git a/src/config.c b/src/config.c index 427b81884..b480eeb1e 100644 --- a/src/config.c +++ b/src/config.c @@ -504,11 +504,6 @@ load_machine(void) fpu_type = fpu_get_type(cpu_f, cpu, p); mem_size = ini_section_get_int(cat, "mem_size", 64); -#if 0 - if (mem_size < ((machine_has_bus(machine, MACHINE_AT) && - (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) - mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); -#endif if (mem_size > machine_get_max_ram(machine)) mem_size = machine_get_max_ram(machine); @@ -893,12 +888,6 @@ load_ports(void) sprintf(temp, "serial%d_enabled", c + 1); com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1); -#if 0 - sprintf(temp, "serial%d_device", c + 1); - p = (char *) ini_section_get_string(cat, temp, "none"); - com_ports[c].device = com_device_get_from_internal_name(p); -#endif - sprintf(temp, "serial%d_passthrough_enabled", c + 1); serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0); @@ -1027,27 +1016,14 @@ load_storage_controllers(void) sprintf(temp, "cartridge_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c])); - } else -#endif - if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); - else - strncpy(cart_fns[c], p, 511); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_storage_controllers(): strlen(p) > 511 (cart_fns[%i])\n", c); + else + strncpy(cart_fns[c], p, 511); + } else + path_append_filename(cart_fns[c], usr_path, p); + path_normalize(cart_fns[c]); } } @@ -1198,33 +1174,18 @@ load_hard_disks(void) sprintf(temp, "hdd_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - /* - * ANOTHER NOTE: - * When loading differencing VHDs, the absolute path is required. - * So we should not convert absolute paths to relative. -sards - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { /* - * Yep, its absolute and prefixed - * with the CFG path. Just strip - * that off for now... + * NOTE: + * When loading differencing VHDs, the absolute path is required. + * So we should not convert absolute paths to relative. -sards */ - wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn)); - } else -#endif if (path_abs(p)) { - strncpy(hdd[c].fn, p, sizeof(hdd[c].fn) - 1); - } else { + if (strlen(p) > 511) + fatal("load_hard_disks(): strlen(p) > 511 (hdd[%i].fn)\n", c); + else + strncpy(hdd[c].fn, p, 511); + } else path_append_filename(hdd[c].fn, usr_path, p); - } path_normalize(hdd[c].fn); sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1); @@ -1284,30 +1245,17 @@ load_floppy_drives(void) p = ini_section_get_string(cat, temp, ""); ini_section_delete_var(cat, temp); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_drives(): strlen(p) > 511 (floppyfns[%i])\n", c); + else + strncpy(floppyfns[c], p, 511); } else -#endif - if (strlen(p) > 511) - fatal("load_floppy_drives(): strlen(p) > 511\n"); - else - strncpy(floppyfns[c], p, 511); + path_append_filename(floppyfns[c], usr_path, p); + path_normalize(floppyfns[c]); -#if 0 - if (*wp != L'\0') +#ifdef ENABLE_CONFIG_LOG + if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif sprintf(temp, "fdd_%02i_writeprot", c + 1); @@ -1352,30 +1300,17 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (floppyfns[%i])\n", c); + else + strncpy(floppyfns[c], p, 511); } else -#endif - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511\n"); - else - strncpy(floppyfns[c], p, 511); + path_append_filename(floppyfns[c], usr_path, p); + path_normalize(floppyfns[c]); -#if 0 - if (*wp != L'\0') +#ifdef ENABLE_CONFIG_LOG + if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif sprintf(temp, "fdd_%02i_writeprot", c + 1); @@ -1385,7 +1320,8 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_check_bpb", c + 1); fdd_set_check_bpb(c, !!ini_section_get_int(cat, temp, 1)); - /* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */ + /* 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(temp, "fdd_%02i_type", c + 1); ini_section_delete_var(cat, temp); @@ -1411,7 +1347,15 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - sprintf(fdd_image_history[c][i], "%s", p); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " + "(fdd_image_history[%i][%i])\n", c, i); + else + strncpy(fdd_image_history[c][i], p, 511); + } else + path_append_filename(fdd_image_history[c][i], usr_path, p); + path_normalize(fdd_image_history[c][i]); } } } @@ -1493,24 +1437,14 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (cdrom[%i].image_path)\n", c); + else + strncpy(cdrom[c].image_path, p, 511); } else -#endif - strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); + path_append_filename(cdrom[c].image_path, usr_path, p); + path_normalize(cdrom[c].image_path); if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) cdrom[c].host_drive = 0; @@ -1544,7 +1478,15 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - sprintf(cdrom[c].image_history[i], "%s", p); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " + "(cdrom[%i].image_history[%i])\n", c, i); + else + strncpy(cdrom[c].image_history[i], p, 511); + } else + path_append_filename(cdrom[c].image_history[i], usr_path, p); + path_normalize(cdrom[c].image_history[i]); } } } @@ -1557,7 +1499,7 @@ load_other_removable_devices(void) ini_section_t cat = ini_find_section(config, "Other removable devices"); char temp[512]; char tmp2[512]; - const char *p; + char *p; char s[512]; unsigned int board = 0; unsigned int dev = 0; @@ -1618,24 +1560,14 @@ load_other_removable_devices(void) p = ini_section_get_string(cat, temp, ""); ini_section_delete_var(cat, temp); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 (cdrom[%i].image_path)\n", c); + else + strncpy(cdrom[c].image_path, p, 511); } else -#endif - strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); + path_append_filename(cdrom[c].image_path, usr_path, p); + path_normalize(cdrom[c].image_path); if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) cdrom[c].host_drive = 0; @@ -1705,24 +1637,14 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); -#if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path)); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 (zip_drives[%i].image_path)\n", c); + else + strncpy(zip_drives[c].image_path, p, 511); } else -#endif - strncpy(zip_drives[c].image_path, p, sizeof(zip_drives[c].image_path) - 1); + path_append_filename(zip_drives[c].image_path, usr_path, p); + path_normalize(zip_drives[c].image_path); /* If the CD-ROM is disabled, delete all its variables. */ if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { @@ -1805,7 +1727,14 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); - strncpy(mo_drives[c].image_path, p, sizeof(mo_drives[c].image_path) - 1); + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 (mo_drives[%i].image_path)\n", c); + else + strncpy(mo_drives[c].image_path, p, 511); + } else + path_append_filename(mo_drives[c].image_path, usr_path, p); + path_normalize(mo_drives[c].image_path); /* If the CD-ROM is disabled, delete all its variables. */ if (mo_drives[c].bus_type == MO_BUS_DISABLED) { @@ -2543,19 +2472,16 @@ save_network(void) ini_section_delete_var(cat, temp); else ini_section_set_string(cat, temp, net_cards_conf[c].host_dev_name); - } else { -#if 0 - ini_section_set_string(cat, temp, "none"); -#endif + } else ini_section_delete_var(cat, temp); - } sprintf(temp, "net_%02i_link", c + 1); - if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD)) { + if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD | + NET_LINK_100_HD | NET_LINK_100_FD | + NET_LINK_1000_HD | NET_LINK_1000_FD)) ini_section_delete_var(cat, temp); - } else { + else ini_section_set_int(cat, temp, net_cards_conf[c].link_state); - } } ini_delete_section_if_empty(config, cat); @@ -2577,21 +2503,6 @@ save_ports(void) else ini_section_set_int(cat, temp, com_ports[c].enabled); -#if 0 - sprintf(temp, "serial%d_type", c + 1); - if (!com_ports[c].enabled)) - ini_section_delete_var(cat, temp); - // else - // ini_section_set_string(cat, temp, (char *) serial_type[c]) - - sprintf(temp, "serial%d_device", c + 1); - if (com_ports[c].device == 0) - ini_section_delete_var(cat, temp); - else - ini_section_set_string(cat, temp, - (char *) com_device_get_internal_name(com_ports[c].device)); -#endif - sprintf(temp, "serial%d_passthrough_enabled", c + 1); if (serial_passthrough_enabled[c]) { ini_section_set_int(cat, temp, 1); @@ -2868,7 +2779,11 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_writeprot", c + 1); ini_section_delete_var(cat, temp); } else { - ini_section_set_string(cat, temp, floppyfns[c]); + path_normalize(floppyfns[c]); + if (!strnicmp(floppyfns[c], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &floppyfns[c][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, floppyfns[c]); } sprintf(temp, "fdd_%02i_writeprot", c + 1); @@ -2891,10 +2806,14 @@ save_floppy_and_cdrom_drives(void) for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1); - if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) { + if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, fdd_image_history[c][i]); + else { + path_normalize(fdd_image_history[c][i]); + if (!strnicmp(fdd_image_history[c][i], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &fdd_image_history[c][i][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, fdd_image_history[c][i]); } } } @@ -2958,18 +2877,26 @@ save_floppy_and_cdrom_drives(void) } sprintf(temp, "cdrom_%02i_image_path", c + 1); - if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) { + if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, cdrom[c].image_path); + else { + path_normalize(cdrom[c].image_path); + if (!strnicmp(cdrom[c].image_path, usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &cdrom[c].image_path[strlen(usr_path)]); + else + ini_section_set_string(cat, temp, cdrom[c].image_path); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); - if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) { + if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, cdrom[c].image_history[i]); + else { + path_normalize(cdrom[c].image_history[i]); + if (!strnicmp(cdrom[c].image_history[i], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &cdrom[c].image_history[i][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, cdrom[c].image_history[i]); } } } @@ -3018,10 +2945,14 @@ save_other_removable_devices(void) } sprintf(temp, "zip_%02i_image_path", c + 1); - if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) { + if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, zip_drives[c].image_path); + else { + path_normalize(zip_drives[c].image_path); + if (!strnicmp(zip_drives[c].image_path, usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &zip_drives[c].image_path[strlen(usr_path)]); + else + ini_section_set_string(cat, temp, zip_drives[c].image_path); } } @@ -3057,10 +2988,14 @@ save_other_removable_devices(void) } sprintf(temp, "mo_%02i_image_path", c + 1); - if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) { + if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - } else { - ini_section_set_string(cat, temp, mo_drives[c].image_path); + else { + path_normalize(mo_drives[c].image_path); + if (!strnicmp(mo_drives[c].image_path, usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &mo_drives[c].image_path[strlen(usr_path)]); + else + ini_section_set_string(cat, temp, mo_drives[c].image_path); } } From 597a6640f44e93899ccbb91ecade7725da92668c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 18:28:38 +0200 Subject: [PATCH 09/30] More config.c clean-ups and added some plumbing for the future ZIP and MO image history. --- src/config.c | 101 ++++++++++++++++++++++++++++----------- src/include/86box/mo.h | 4 ++ src/include/86box/path.h | 1 + src/include/86box/zip.h | 4 ++ src/qt/qt_platform.cpp | 12 +++++ src/unix/unix.c | 11 +++++ src/win/win.c | 15 +++++- 7 files changed, 119 insertions(+), 29 deletions(-) diff --git a/src/config.c b/src/config.c index b480eeb1e..26a74ab74 100644 --- a/src/config.c +++ b/src/config.c @@ -1352,9 +1352,10 @@ load_floppy_and_cdrom_drives(void) fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " "(fdd_image_history[%i][%i])\n", c, i); else - strncpy(fdd_image_history[c][i], p, 511); + snprintf(fdd_image_history[c][i], 511, "%s", p); } else - path_append_filename(fdd_image_history[c][i], usr_path, p); + snprintf(fdd_image_history[c][i], 511, "%s%$s%s", usr_path, + path_get_slash(usr_path), p); path_normalize(fdd_image_history[c][i]); } } @@ -1452,6 +1453,24 @@ load_floppy_and_cdrom_drives(void) if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0)) cdrom[c].host_drive = 0; + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); + sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " + "(cdrom[%i].image_history[%i])\n", c, i); + else + snprintf(cdrom[c].image_history[i], 511, "%s", p); + } else + snprintf(cdrom[c].image_history[i], 511, "%s%$s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(cdrom[c].image_history[i]); + } + } + /* If the CD-ROM is disabled, delete all its variables. */ if (cdrom[c].bus_type == CDROM_BUS_DISABLED) { sprintf(temp, "cdrom_%02i_host_drive", c + 1); @@ -1468,27 +1487,15 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_image_path", c + 1); ini_section_delete_var(cat, temp); + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); + ini_section_delete_var(cat, temp); + } } sprintf(temp, "cdrom_%02i_iso_path", c + 1); ini_section_delete_var(cat, temp); - - for (int i = 0; i < MAX_PREV_IMAGES; i++) { - cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); - sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); - p = ini_section_get_string(cat, temp, NULL); - if (p) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " - "(cdrom[%i].image_history[%i])\n", c, i); - else - strncpy(cdrom[c].image_history[i], p, 511); - } else - path_append_filename(cdrom[c].image_history[i], usr_path, p); - path_normalize(cdrom[c].image_history[i]); - } - } } } @@ -1646,7 +1653,25 @@ load_other_removable_devices(void) path_append_filename(zip_drives[c].image_path, usr_path, p); path_normalize(zip_drives[c].image_path); - /* If the CD-ROM is disabled, delete all its variables. */ + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + zip_drives[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); + sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 " + "(zip_drives[%i].image_history[%i])\n", c, i); + else + snprintf(zip_drives[c].image_history[i], 511, "%s", p); + } else + snprintf(zip_drives[c].image_history[i], 511, "%s%$s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(zip_drives[c].image_history[i]); + } + } + + /* If the ZIP drive is disabled, delete all its variables. */ if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { sprintf(temp, "zip_%02i_host_drive", c + 1); ini_section_delete_var(cat, temp); @@ -1662,10 +1687,12 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_image_path", c + 1); ini_section_delete_var(cat, temp); - } - sprintf(temp, "zip_%02i_iso_path", c + 1); - ini_section_delete_var(cat, temp); + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); + ini_section_delete_var(cat, temp); + } + } } memset(temp, 0x00, sizeof(temp)); @@ -1736,7 +1763,25 @@ load_other_removable_devices(void) path_append_filename(mo_drives[c].image_path, usr_path, p); path_normalize(mo_drives[c].image_path); - /* If the CD-ROM is disabled, delete all its variables. */ + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + mo_drives[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); + sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (path_abs(p)) { + if (strlen(p) > 511) + fatal("load_other_removable_devices(): strlen(p) > 511 " + "(mo_drives[%i].image_history[%i])\n", c, i); + else + snprintf(mo_drives[c].image_history[i], 511, "%s", p); + } else + snprintf(mo_drives[c].image_history[i], 511, "%s%$s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(mo_drives[c].image_history[i]); + } + } + + /* If the MO drive is disabled, delete all its variables. */ if (mo_drives[c].bus_type == MO_BUS_DISABLED) { sprintf(temp, "mo_%02i_host_drive", c + 1); ini_section_delete_var(cat, temp); @@ -1752,10 +1797,12 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_image_path", c + 1); ini_section_delete_var(cat, temp); - } - sprintf(temp, "mo_%02i_iso_path", c + 1); - ini_section_delete_var(cat, temp); + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); + ini_section_delete_var(cat, temp); + } + } } } diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index a11c4d636..99b985635 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -27,6 +27,8 @@ #define MO_TIME 10.0 +#define MO_IMAGE_HISTORY 4 + typedef struct mo_type_t { uint32_t sectors; uint16_t bytes_per_sector; @@ -113,6 +115,8 @@ typedef struct mo_drive_t { char image_path[1024]; char prev_image_path[1024]; + char *image_history[MO_IMAGE_HISTORY]; + uint32_t type; uint32_t medium_size; uint32_t base; diff --git a/src/include/86box/path.h b/src/include/86box/path.h index 5ef0d9488..41ef5e65e 100644 --- a/src/include/86box/path.h +++ b/src/include/86box/path.h @@ -3,5 +3,6 @@ extern char *path_get_filename(char *s); extern char *path_get_extension(char *s); extern void path_append_filename(char *dest, const char *s1, const char *s2); extern void path_slash(char *path); +extern char *path_get_slash(char *path); extern void path_normalize(char *path); extern int path_abs(char *path); \ No newline at end of file diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index 9ff69d092..6e53fbf36 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -29,6 +29,8 @@ #define ZIP_250_SECTORS (489532) +#define ZIP_IMAGE_HISTORY 4 + enum { ZIP_BUS_DISABLED = 0, ZIP_BUS_ATAPI = 5, @@ -61,6 +63,8 @@ typedef struct zip_drive_t { char image_path[1024]; char prev_image_path[1024]; + char *image_history[ZIP_IMAGE_HISTORY]; + uint32_t is_250; uint32_t medium_size; uint32_t base; diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 9e2264221..a8f9591d7 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -304,6 +304,18 @@ path_slash(char *path) path_normalize(path); } +char * +path_get_slash(char *path) +{ + auto len = strlen(path); + std::string ret = ""; + + if (path[len - 1] != '/') + ret = "/"; + + return (char *) ret.c_str(); +} + void path_append_filename(char *dest, const char *s1, const char *s2) { diff --git a/src/unix/unix.c b/src/unix/unix.c index c389c9c45..770822919 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -310,6 +310,17 @@ path_slash(char *path) path_normalize(path); } +char * +path_get_slash(char *path) +{ + char *ret = ""; + + if (path[strlen(path) - 1] != '/') + ret = "/"; + + return ret; +} + void plat_put_backslash(char *s) { diff --git a/src/win/win.c b/src/win/win.c index 3e3535a32..7314370ce 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -734,9 +734,20 @@ path_normalize(char *path) void path_slash(char *path) { - if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) { + if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) strcat(path, "\\"); - } +} + +/* Return a trailing (back)slash if necessary. */ +char * +path_get_slash(char *path) +{ + char *ret = ""; + + if ((path[strlen(path) - 1] != '\\') && (path[strlen(path) - 1] != '/')) + ret = "\\"; + + return ret; } /* Check if the given path is absolute or not. */ From e387a6c2f53e99cb0b42353a056d6e7e6e0a82cb Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 19:14:50 +0200 Subject: [PATCH 10/30] The AAM instruction on NEC V20/V30 does in fact support bases other than 10, fixes #2939. --- src/cpu/808x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 84389874a..bd7bb30f1 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -3463,11 +3463,15 @@ execx86(int cycs) case 0xD4: /*AAM*/ wait(1, 0); +#ifdef NO_VARIANT_ON_NEC if (is_nec) { (void) pfq_fetchb(); cpu_src = 10; } else cpu_src = pfq_fetchb(); +#else + cpu_src = pfq_fetchb(); +#endif if (x86_div(AL, 0)) set_pzs(16); break; From 1cff8341c2b6f1f43da6c2fd78a72b9507ca6e5c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 22:50:12 +0200 Subject: [PATCH 11/30] Removed some excess logging from config.c. --- src/config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index 26a74ab74..aad7db0f9 100644 --- a/src/config.c +++ b/src/config.c @@ -88,7 +88,7 @@ static ini_t config; static int backwards_compat = 0; static int backwards_compat2 = 0; -#define ENABLE_CONFIG_LOG 1 +#define ENABLE_CONFIG_LOG 1 #ifdef ENABLE_CONFIG_LOG int config_do_log = ENABLE_CONFIG_LOG; @@ -1254,7 +1254,7 @@ load_floppy_drives(void) path_append_filename(floppyfns[c], usr_path, p); path_normalize(floppyfns[c]); -#ifdef ENABLE_CONFIG_LOG +#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif @@ -1309,7 +1309,7 @@ load_floppy_and_cdrom_drives(void) path_append_filename(floppyfns[c], usr_path, p); path_normalize(floppyfns[c]); -#ifdef ENABLE_CONFIG_LOG +#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif From 29c153d28743af963219252ae73fe671cfecf4f5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 23:16:54 +0200 Subject: [PATCH 12/30] Reverted Cacodemon345's broken USB OHCI implementation, fixes #3597. --- src/chipset/ali1543.c | 17 +- src/chipset/intel_piix.c | 21 +- src/chipset/sis_5571.c | 45 +- src/chipset/stpc.c | 21 +- src/include/86box/usb.h | 189 +------- src/usb.c | 991 +++++++-------------------------------- 6 files changed, 174 insertions(+), 1110 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index ba8ce4f3b..6227115fd 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -70,7 +70,6 @@ typedef struct ali1543_t { sff8038i_t *ide_controller[2]; smbus_ali7101_t *smbus; usb_t *usb; - usb_params_t usb_params; } ali1543_t; @@ -1472,17 +1471,6 @@ ali7101_read(int func, int addr, void *priv) return ret; } -static void -ali5237_usb_update_interrupt(usb_t* usb, void *priv) -{ - ali1543_t *dev = (ali1543_t *) priv; - - if (usb->irq_level) - pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]); - else - pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]); -} - static void ali1543_reset(void *priv) { @@ -1633,10 +1621,7 @@ ali1543_init(const device_t *info) dev->smbus = device_add(&ali7101_smbus_device); /* USB */ - dev->usb_params.parent_priv = dev; - dev->usb_params.smi_handle = NULL; - dev->usb_params.update_interrupt = ali5237_usb_update_interrupt; - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); + dev->usb = device_add(&usb_device); dev->type = info->local & 0xff; dev->offset = (info->local >> 8) & 0x7f; diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 878fd53ae..add421b96 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -66,7 +66,6 @@ typedef struct _piix_ { uint8_t max_func; uint8_t pci_slot; uint8_t no_mirq0; - uint8_t usb_irq_state; uint8_t regs[4][256]; uint8_t readout_regs[256]; uint8_t board_config[2]; @@ -84,7 +83,6 @@ typedef struct _piix_ { piix_io_trap_t io_traps[26]; port_92_t *port_92; pc_timer_t fast_off_timer; - usb_params_t usb_params; } piix_t; #ifdef ENABLE_PIIX_LOG @@ -1443,17 +1441,6 @@ piix_fast_off_count(void *priv) dev->regs[0][0xaa] |= 0x20; } -static void -piix_usb_update_interrupt(usb_t* usb, void *priv) -{ - piix_t *dev = (piix_t *) priv; - - if (usb->irq_level) - pci_set_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state); - else - pci_clear_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state); -} - static void piix_reset(void *priv) { @@ -1598,12 +1585,8 @@ piix_init(const device_t *info) sff_set_irq_mode(dev->bm[1], 1, 2); } - if (dev->type >= 3) { - dev->usb_params.parent_priv = dev; - dev->usb_params.smi_handle = NULL; - dev->usb_params.update_interrupt = piix_usb_update_interrupt; - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); - } + if (dev->type >= 3) + dev->usb = device_add(&usb_device); if (dev->type > 3) { dev->nvr = device_add(&piix4_nvr_device); diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 391cc4e8b..0761e4865 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -87,9 +87,6 @@ typedef struct sis_5571_t { sff8038i_t *ide_drive[2]; smram_t *smram; usb_t *usb; - - usb_params_t usb_params; - } sis_5571_t; static void @@ -669,43 +666,6 @@ pci_isa_bridge_read(int func, int addr, void *priv) } } -static void -sis_5571_usb_update_interrupt(usb_t* usb, void* priv) -{ - sis_5571_t *dev = (sis_5571_t *) priv; - - if (dev->pci_conf_sb[0][0x68] & 0x80) { - /* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */ - switch (dev->pci_conf_sb[0][0x68] & 0x0F) { - case 0x00: - case 0x01: - case 0x02: - case 0x08: - case 0x0d: - break; - - default: - if (usb->irq_level) - picint(1 << dev->pci_conf_sb[0][0x68] & 0x0f); - else - picintc(1 << dev->pci_conf_sb[0][0x68] & 0x0f); - break; - } - } else { - if (usb->irq_level) - pci_set_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state); - else - pci_clear_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state); - } -} - -static uint8_t -sis_5571_usb_handle_smi(UNUSED(usb_t* usb), UNUSED(void* priv)) -{ - /* Left unimplemented for now. */ - return 1; -} - static void sis_5571_reset(void *priv) { @@ -790,10 +750,7 @@ sis_5571_init(UNUSED(const device_t *info)) dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2); /* USB */ - dev->usb_params.parent_priv = dev; - dev->usb_params.update_interrupt = sis_5571_usb_update_interrupt; - dev->usb_params.smi_handle = sis_5571_usb_handle_smi; - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); + dev->usb = device_add(&usb_device); sis_5571_reset(dev); diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 59d01186a..aa5e1fb8b 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -73,9 +73,6 @@ typedef struct stpc_t { smram_t *smram; usb_t *usb; sff8038i_t *bm[2]; - - /* Miscellaneous */ - usb_params_t usb_params; } stpc_t; typedef struct stpc_serial_t { @@ -898,17 +895,6 @@ stpc_setup(stpc_t *dev) pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); } -static void -stpc_usb_update_interrupt(usb_t* usb, void* priv) -{ - stpc_t *dev = (stpc_t *) priv; - - if (usb->irq_level) - pci_set_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state); - else - pci_clear_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state); -} - static void stpc_close(void *priv) { @@ -934,12 +920,9 @@ stpc_init(const device_t *info) pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot); pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot); if (dev->local == STPC_ATLAS) { - dev->usb_params.smi_handle = NULL; - dev->usb_params.update_interrupt = stpc_usb_update_interrupt; - dev->usb_params.parent_priv = dev; - pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot); - dev->usb = device_add_parameters(&usb_device, &dev->usb_params); + + dev->usb = device_add(&usb_device); pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot); } diff --git a/src/include/86box/usb.h b/src/include/86box/usb.h index 7c2e13ee9..893a9f501 100644 --- a/src/include/86box/usb.h +++ b/src/include/86box/usb.h @@ -1,18 +1,18 @@ /* - * 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. + * 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. + * This file is part of the 86Box distribution. * - * Definitions for the Distributed DMA emulation. + * Definitions for the Distributed DMA emulation. * * * - * Authors: Miran Grca, + * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020 Miran Grca. */ #ifndef USB_H @@ -22,188 +22,21 @@ extern "C" { #endif -typedef struct usb_t usb_t; -typedef struct usb_device_t usb_device_t; - -enum usb_pid +typedef struct { - USB_PID_OUT = 0xE1, - USB_PID_IN = 0x69, - USB_PID_SETUP = 0x2D -}; - -enum usb_errors -{ - USB_ERROR_NO_ERROR = 0, - USB_ERROR_NAK = 1, - USB_ERROR_OVERRUN = 2, - USB_ERROR_UNDERRUN = 3 -}; - -enum usb_bus_types -{ - USB_BUS_OHCI = 0, - USB_BUS_UHCI = 1, - USB_BUS_MAX = 2 -}; - -/* USB device creation parameters struct */ -typedef struct usb_params_t -{ - void (*update_interrupt)(usb_t*, void*); - /* Handle (but do not raise) SMI. Returns 1 if SMI can be raised, 0 otherwise. */ - uint8_t (*smi_handle)(usb_t*, void*); - void* parent_priv; -} usb_params_t; - -typedef union { - uint32_t l; - uint16_t w[2]; - uint8_t b[4]; -} ohci_mmio_t; - -/* USB Host Controller device struct */ -typedef struct usb_t { - uint8_t uhci_io[32]; - ohci_mmio_t ohci_mmio[1024]; + uint8_t uhci_io[32], ohci_mmio[4096]; uint16_t uhci_io_base; - int uhci_enable; - int ohci_enable; + int uhci_enable, ohci_enable; uint32_t ohci_mem_base; - uint32_t irq_level; mem_mapping_t ohci_mmio_mapping; - pc_timer_t ohci_frame_timer; - pc_timer_t ohci_port_reset_timer[2]; - uint8_t ohci_interrupt_counter : 3; - usb_device_t *ohci_devices[2]; - usb_device_t *uhci_devices[2]; - uint8_t ohci_usb_buf[4096]; - uint8_t ohci_initial_start; - - usb_params_t *usb_params; } usb_t; -#pragma pack(push, 1) - -/* Base USB descriptor struct. */ -typedef struct usb_desc_base_t { - uint8_t bLength; - uint8_t bDescriptorType; -} usb_desc_base_t; - -enum usb_desc_setup_req_types { - USB_SETUP_TYPE_DEVICE = 0x0, - USB_SETUP_TYPE_INTERFACE = 0x1, - USB_SETUP_TYPE_ENDPOING = 0x2, - USB_SETUP_TYPE_OTHER = 0x3, -}; - -#define USB_SETUP_TYPE_MAX 0x1F - -#define USB_SETUP_DEV_TO_HOST 0x80 - -typedef struct usb_desc_setup_t { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} usb_desc_setup_t; - -typedef struct usb_desc_endpoint_t { - usb_desc_base_t base; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; -} usb_desc_endpoint_t; - -typedef struct usb_desc_hid_t { - usb_desc_base_t base; - - uint16_t bcdHID; - uint8_t bCountryCode; - uint8_t bNumDescriptors; - uint8_t bDescriptorType; - uint16_t wDescriptorLength; -} usb_desc_hid_t; - -typedef struct usb_desc_interface_t { - usb_desc_base_t base; - - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; - uint8_t bNumEndpoints; - uint8_t bInterfaceClass; - uint8_t bInterfaceSubClass; - uint8_t bInterfaceProtocol; - uint8_t iInterface; -} usb_desc_interface_t; - -typedef struct usb_desc_string_t { - usb_desc_base_t base; - uint16_t bString[]; -} usb_desc_string_t; - -typedef struct usb_desc_conf_t { - usb_desc_base_t base; - - uint16_t wTotalLength; - uint8_t bNumInterfaces; - uint8_t bConfigurationValue; - uint8_t iConfiguration; - uint8_t bmAttributes; - uint8_t bMaxPower; -} usb_desc_conf_t; - -typedef struct usb_desc_device_t { - usb_desc_base_t base; - - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} usb_desc_device_t; - -#pragma pack(pop) - -/* USB endpoint device struct. Incomplete and unused. */ -typedef struct usb_device_t { - usb_desc_device_t device_desc; - struct { - usb_desc_conf_t conf_desc; - usb_desc_base_t* other_descs[16]; - } conf_desc_items; - - /* General-purpose function for I/O. Non-zero value indicates error. */ - uint8_t (*device_process)(void* priv, uint8_t* data, uint32_t *len, uint8_t pid_token, uint8_t endpoint, uint8_t underrun_not_allowed); - /* Device reset. */ - void (*device_reset)(void* priv); - /* Get address. */ - uint8_t (*device_get_address)(void* priv); - - void* priv; -} usb_device_t; - /* Global variables. */ extern const device_t usb_device; -extern usb_t* usb_device_inst; /* Functions. */ extern void uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable); extern void ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable); -/* Attach USB device to a port of a USB bus. Returns the port to which it got attached to. */ -extern uint8_t usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type); -/* Detach USB device from a port. */ -extern void usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type); #ifdef __cplusplus } diff --git a/src/usb.c b/src/usb.c index e6818d849..75e60d438 100644 --- a/src/usb.c +++ b/src/usb.c @@ -20,18 +20,14 @@ #include #include #include -#include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> #include <86box/mem.h> -#include <86box/timer.h> #include <86box/usb.h> -#include <86box/dma.h> -#include <86box/plat_unused.h> +#include "cpu.h" #ifdef ENABLE_USB_LOG int usb_do_log = ENABLE_USB_LOG; @@ -51,104 +47,11 @@ usb_log(const char *fmt, ...) # define usb_log(fmt, ...) #endif -/* OHCI registers */ -enum { - OHCI_HcRevision = 0x00 /* 0x00 */, - OHCI_HcControl = 0x01 /* 0x04 */, - OHCI_HcCommandStatus = 0x02 /* 0x08 */, - OHCI_HcInterruptStatus = 0x03 /* 0x0c */, - OHCI_HcInterruptEnable = 0x04 /* 0x10 */, - OHCI_HcInterruptDisable = 0x05 /* 0x14 */, - OHCI_HcHCCA = 0x06 /* 0x18 */, - OHCI_HcPeriodCurrentED = 0x07 /* 0x1c */, - OHCI_HcControlHeadED = 0x08 /* 0x20 */, - OHCI_HcControlCurrentED = 0x09 /* 0x24 */, - OHCI_HcBulkHeadED = 0x0a /* 0x28 */, - OHCI_HcBulkCurrentED = 0x0b /* 0x2c */, - OHCI_HcDoneHead = 0x0c /* 0x30 */, - OHCI_HcFmInterval = 0x0d /* 0x34 */, - OHCI_HcFmRemaining = 0x0e /* 0x38 */, - OHCI_HcFmNumber = 0x0f /* 0x3c */, - OHCI_HcPeriodicStart = 0x10 /* 0x40 */, - OHCI_HcLSThreshold = 0x11 /* 0x44 */, - OHCI_HcRhDescriptorA = 0x12 /* 0x48 */, - OHCI_HcRhDescriptorB = 0x13 /* 0x4c */, - OHCI_HcRhStatus = 0x14 /* 0x50 */, - OHCI_HcRhPortStatus1 = 0x15 /* 0x54 */, - OHCI_HcRhPortStatus2 = 0x16 /* 0x58 */, - OHCI_HcRhPortStatus3 = 0x17 /* 0x5c */ -}; - -enum { - OHCI_aHcRevision = 0x00, - OHCI_aHcControl = 0x04, - OHCI_aHcCommandStatus = 0x08, - OHCI_aHcInterruptStatus = 0x0c, - OHCI_aHcInterruptEnable = 0x10, - OHCI_aHcInterruptDisable = 0x14, - OHCI_aHcHCCA = 0x18, - OHCI_aHcPeriodCurrentED = 0x1c, - OHCI_aHcControlHeadED = 0x20, - OHCI_aHcControlCurrentED = 0x24, - OHCI_aHcBulkHeadED = 0x28, - OHCI_aHcBulkCurrentED = 0x2c, - OHCI_aHcDoneHead = 0x30, - OHCI_aHcFmInterval = 0x34, - OHCI_aHcFmRemaining = 0x38, - OHCI_aHcFmNumber = 0x3c, - OHCI_aHcPeriodicStart = 0x40, - OHCI_aHcLSThreshold = 0x44, - OHCI_aHcRhDescriptorA = 0x48, - OHCI_aHcRhDescriptorB = 0x4c, - OHCI_aHcRhStatus = 0x50, - OHCI_aHcRhPortStatus1 = 0x54, - OHCI_aHcRhPortStatus2 = 0x58, - OHCI_aHcRhPortStatus3 = 0x5c -}; - -/* OHCI HcInterruptEnable/Disable bits */ -enum { - OHCI_HcInterruptEnable_SO = 1 << 0, - OHCI_HcInterruptEnable_WDH = 1 << 1, - OHCI_HcInterruptEnable_SF = 1 << 2, - OHCI_HcInterruptEnable_RD = 1 << 3, - OHCI_HcInterruptEnable_UE = 1 << 4, - OHCI_HcInterruptEnable_HNO = 1 << 5, - OHCI_HcInterruptEnable_RHSC = 1 << 6, -}; - -/* OHCI HcControl bits */ -enum { - OHCI_HcControl_ControlBulkServiceRatio = 1 << 0, - OHCI_HcControl_PeriodicListEnable = 1 << 1, - OHCI_HcControl_IsochronousEnable = 1 << 2, - OHCI_HcControl_ControlListEnable = 1 << 3, - OHCI_HcControl_BulkListEnable = 1 << 4 -}; - -usb_t* usb_device_inst = NULL; - -static void -usb_interrupt_ohci(usb_t *dev, uint32_t level) -{ - if (dev->ohci_mmio[OHCI_HcControl].b[1] & 1) { - if (dev->usb_params && dev->usb_params->smi_handle && !dev->usb_params->smi_handle(dev, dev->usb_params->parent_priv)) - return; - - if (level) - smi_raise(); - } else if (dev->usb_params != NULL) { - if ((dev->usb_params->parent_priv != NULL) && (dev->usb_params->update_interrupt != NULL)) - dev->usb_params->update_interrupt(dev, dev->usb_params->parent_priv); - } -} - static uint8_t -uhci_reg_read(uint16_t addr, void *priv) +uhci_reg_read(uint16_t addr, void *p) { - const usb_t *dev = (usb_t *) priv; - uint8_t ret; - const uint8_t *regs = dev->uhci_io; + usb_t *dev = (usb_t *) p; + uint8_t ret, *regs = dev->uhci_io; addr &= 0x0000001f; @@ -158,9 +61,9 @@ uhci_reg_read(uint16_t addr, void *priv) } static void -uhci_reg_write(uint16_t addr, uint8_t val, void *priv) +uhci_reg_write(uint16_t addr, uint8_t val, void *p) { - usb_t *dev = (usb_t *) priv; + usb_t *dev = (usb_t *) p; uint8_t *regs = dev->uhci_io; addr &= 0x0000001f; @@ -182,16 +85,13 @@ uhci_reg_write(uint16_t addr, uint8_t val, void *priv) case 0x0c: regs[0x0c] = (val & 0x7f); break; - - default: - break; } } static void -uhci_reg_writew(uint16_t addr, uint16_t val, void *priv) +uhci_reg_writew(uint16_t addr, uint16_t val, void *p) { - usb_t *dev = (usb_t *) priv; + usb_t *dev = (usb_t *) p; uint16_t *regs = (uint16_t *) dev->uhci_io; addr &= 0x0000001f; @@ -212,8 +112,8 @@ uhci_reg_writew(uint16_t addr, uint16_t val, void *priv) regs[addr >> 1] = ((regs[addr >> 1] & 0xedbb) | (val & 0x1244)) & ~(val & 0x080a); break; default: - uhci_reg_write(addr, val & 0xff, priv); - uhci_reg_write(addr + 1, (val >> 8) & 0xff, priv); + uhci_reg_write(addr, val & 0xff, p); + uhci_reg_write(addr + 1, (val >> 8) & 0xff, p); break; } } @@ -231,728 +131,218 @@ uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable) io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); } -typedef struct -{ - uint32_t HccaInterrruptTable[32]; - uint16_t HccaFrameNumber; - uint16_t HccaPad1; - uint32_t HccaDoneHead; -} usb_hcca_t; - -/* Transfer descriptors */ -typedef struct -{ - uint32_t Control; - uint32_t CBP; - uint32_t NextTD; - uint32_t BE; -} usb_td_t; - -/* Endpoint descriptors */ -typedef struct -{ - uint32_t Control; - uint32_t TailP; - uint32_t HeadP; - uint32_t NextED; -} usb_ed_t; - -#define ENDPOINT_DESC_LIMIT 32 - static uint8_t -ohci_mmio_read(uint32_t addr, void *priv) +ohci_mmio_read(uint32_t addr, void *p) { - const usb_t *dev = (usb_t *) priv; - uint8_t ret = 0x00; -#ifdef ENABLE_USB_LOG - uint32_t old_addr = addr; -#endif + usb_t *dev = (usb_t *) p; + uint8_t ret = 0x00; addr &= 0x00000fff; - ret = dev->ohci_mmio[addr >> 2].b[addr & 3]; - - switch (addr) { - case 0x101: - ret = (ret & 0xfe) | (!!mem_a20_key); - break; - case OHCI_aHcRhPortStatus1 + 1: - case OHCI_aHcRhPortStatus2 + 1: - case OHCI_aHcRhPortStatus3 + 1: - ret |= 0x1; - break; - case OHCI_aHcInterruptDisable: - case OHCI_aHcInterruptDisable + 1: - case OHCI_aHcInterruptDisable + 2: - case OHCI_aHcInterruptDisable + 3: - ret = dev->ohci_mmio[OHCI_HcInterruptEnable].b[addr & 3]; - default: - break; - } + ret = dev->ohci_mmio[addr]; if (addr == 0x101) ret = (ret & 0xfe) | (!!mem_a20_key); -#ifdef ENABLE_USB_LOG - usb_log("[R] %08X = %04X\n", old_addr, ret); -#endif - return ret; } -static uint16_t -ohci_mmio_readw(uint32_t addr, void *priv) -{ - return ohci_mmio_read(addr, priv) | (ohci_mmio_read(addr + 1, priv) << 8); -} - -static uint32_t -ohci_mmio_readl(uint32_t addr, void *priv) -{ - return ohci_mmio_readw(addr, priv) | (ohci_mmio_readw(addr + 2, priv) << 16); -} - static void -ohci_update_irq(usb_t *dev) +ohci_mmio_write(uint32_t addr, uint8_t val, void *p) { - uint32_t level = !!(dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l); - -#ifdef STATE_KEEPING - if (level != dev->irq_level) { -#endif - dev->irq_level = level; - usb_interrupt_ohci(dev, level); -#ifdef STATE_KEEPING - } -#endif -} - -void -ohci_set_interrupt(usb_t *dev, uint8_t bit) -{ - if (!(dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] & 0x80)) - return; - - if (!(dev->ohci_mmio[OHCI_HcInterruptEnable].b[0] & bit)) - return; - - if (dev->ohci_mmio[OHCI_HcInterruptDisable].b[0] & bit) - return; - - dev->ohci_mmio[OHCI_HcInterruptStatus].b[0] |= bit; - - /* TODO: Does setting UnrecoverableError also assert PERR# on any emulated USB chipsets? */ - - ohci_update_irq(dev); -} - -/* TODO: Actually use this function somewhere. */ -#if 0 -/* Next two functions ported over from QEMU. */ -static int ohci_copy_td_input(usb_t* dev, usb_td_t *td, - uint8_t *buf, int len) -{ - uint32_t ptr; - uint32_t n; - - ptr = td->CBP; - n = 0x1000 - (ptr & 0xfff); - if (n > len) { - n = len; - } - dma_bm_write(ptr, buf, n, 1); - if (n == len) { - return 0; - } - ptr = td->BE & ~0xfffu; - buf += n; - dma_bm_write(ptr, buf, len - n, 1); - return 0; -} -#endif - -static int ohci_copy_td_output(UNUSED(usb_t* dev), usb_td_t *td, - uint8_t *buf, int len) -{ - uint32_t ptr; - uint32_t n; - - ptr = td->CBP; - n = 0x1000 - (ptr & 0xfff); - if (n > len) { - n = len; - } - dma_bm_read(ptr, buf, n, 1); - if (n == len) { - return 0; - } - ptr = td->BE & ~0xfffu; - buf += n; - dma_bm_read(ptr, buf, len - n, 1); - return 0; -} - -#define OHCI_TD_DIR(val) ((val >> 19) & 3) -#define OHCI_ED_DIR(val) ((val >> 11) & 3) - -uint8_t -ohci_service_transfer_desc(usb_t* dev, usb_ed_t* endpoint_desc) -{ - uint32_t td_addr = endpoint_desc->HeadP & ~0xf; - usb_td_t td; - uint8_t dir; - uint8_t pid_token = 255; - uint32_t len = 0; - uint32_t pktlen = 0; - uint32_t actual_length = 0; - uint32_t i = 0; - uint8_t device_result = 0; - usb_device_t* target = NULL; - - dma_bm_read(td_addr, (uint8_t*)&td, sizeof(usb_td_t), 4); - - switch (dir = OHCI_ED_DIR(endpoint_desc->Control)) { - case 1: - case 2: - break; - default: - dir = OHCI_TD_DIR(td.Control); - break; - } - - switch (dir) { - case 0: /* Setup */ - pid_token = USB_PID_SETUP; - break; - case 1: /* OUT */ - pid_token = USB_PID_OUT; - break; - case 2: /* IN */ - pid_token = USB_PID_IN; - break; - default: - return 1; - } - - if (td.CBP && td.BE) { - if ((td.CBP & 0xfffff000) != (td.BE & 0xfffff000)) { - len = (td.BE & 0xfff) + 0x1001 - (td.CBP & 0xfff); - } else { - if (td.CBP > td.BE) { - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_UE); - return 1; - } - - len = (td.BE - td.CBP) + 1; - } - if (len > sizeof(dev->ohci_usb_buf)) { - len = sizeof(dev->ohci_usb_buf); - } - - pktlen = len; - if (len && pid_token != USB_PID_IN) { - pktlen = (endpoint_desc->Control >> 16) & 0xFFF; - if (pktlen > len) { - pktlen = len; - } - ohci_copy_td_output(dev, &td, dev->ohci_usb_buf, pktlen); - } - } - - for (i = 0; i < 2; i++) { - if (!dev->ohci_devices[i]) - continue; - - assert(dev->ohci_devices[i]->device_get_address != NULL); - - if (dev->ohci_devices[i]->device_get_address(dev->ohci_devices[i]->priv) != (endpoint_desc->Control & 0x7f)) - continue; - - target = dev->ohci_devices[i]; - break; - } - - if (!target) - return 1; - - device_result = target->device_process(target->priv, dev->ohci_usb_buf, &actual_length, pid_token, (endpoint_desc->Control & 0x780) >> 7, !(endpoint_desc->Control & (1 << 18))); - - if ((actual_length == pktlen) || (pid_token == USB_PID_IN && (endpoint_desc->Control & (1 << 18)) && device_result == USB_ERROR_NO_ERROR)) { - if (len == actual_length) { - td.CBP = 0; - } else { - if ((td.CBP & 0xfff) + actual_length > 0xfff) { - td.CBP = (td.BE & ~0xfff) + ((td.CBP + actual_length) & 0xfff); - } else { - td.CBP += actual_length; - } - } - - td.Control |= (1 << 25); /* dataToggle[1] */ - td.Control ^= (1 << 24); /* dataToggle[0] */ - td.Control &= ~0xFC000000; /* Set both ErrorCount and ConditionCode to 0. */ - - if (pid_token != USB_PID_IN && len != actual_length) { - goto exit_no_retire; - } - - endpoint_desc->HeadP &= ~0x2; - if (td.Control & (1 << 24)) { - endpoint_desc->HeadP |= 0x2; - } - } else { - if (actual_length != 0xFFFFFFFF && actual_length >= 0) { - td.Control &= ~0xF0000000; - td.Control |= 0x90000000; - } else { - switch (device_result) { - case USB_ERROR_NAK: - return 1; - - default: - break; - } - dev->ohci_interrupt_counter = 0; - } - - endpoint_desc->HeadP |= 0x1; - } - - endpoint_desc->HeadP &= 0xf; - endpoint_desc->HeadP |= td.NextTD & ~0xf; - td.NextTD = dev->ohci_mmio[OHCI_HcDoneHead].l; - dev->ohci_mmio[OHCI_HcDoneHead].l = td_addr; - i = (td.Control >> 21) & 7; - if (i < dev->ohci_interrupt_counter) { - dev->ohci_interrupt_counter = i; - } -exit_no_retire: - dma_bm_write(td_addr, (uint8_t*)&td, sizeof(usb_td_t), 4); - return !(td.Control & 0xF0000000); -} - -uint8_t -ohci_service_endpoint_desc(usb_t* dev, uint32_t head) -{ - usb_ed_t endpoint_desc; - uint8_t active = 0; - uint32_t next = 0; - uint32_t limit_counter = 0; - - if (head == 0) - return 0; - - for (uint32_t cur = head; cur && limit_counter++ < ENDPOINT_DESC_LIMIT; cur = next) { - dma_bm_read(cur, (uint8_t*)&endpoint_desc, sizeof(usb_ed_t), 4); - - next = endpoint_desc.NextED & ~0xFu; - - if ((endpoint_desc.Control & (1 << 13)) || (endpoint_desc.HeadP & (1 << 0))) - continue; - - if (endpoint_desc.Control & 0x8000) { - fatal("OHCI: Isochronous transfers not implemented!\n"); - } - - active = 1; - - while ((endpoint_desc.HeadP & ~0xFu) != endpoint_desc.TailP) { - ohci_service_transfer_desc(dev, &endpoint_desc); - } - - dma_bm_write(cur, (uint8_t*)&endpoint_desc, sizeof(usb_ed_t), 4); - } - - return active; -} - -void -ohci_end_of_frame(usb_t* dev) -{ - usb_hcca_t hcca; - if (dev->ohci_initial_start) - return; - dma_bm_read(dev->ohci_mmio[OHCI_HcHCCA].l, (uint8_t*)&hcca, sizeof(usb_hcca_t), 4); - - if (dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_PeriodicListEnable) { - ohci_service_endpoint_desc(dev, hcca.HccaInterrruptTable[dev->ohci_mmio[OHCI_HcFmNumber].l & 0x1f]); - } - - if ((dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_ControlListEnable) - && (dev->ohci_mmio[OHCI_HcCommandStatus].l & 0x2)) { - uint8_t result = ohci_service_endpoint_desc(dev, dev->ohci_mmio[OHCI_HcControlHeadED].l); - if (!result) { - dev->ohci_mmio[OHCI_HcControlHeadED].l = 0; - dev->ohci_mmio[OHCI_HcCommandStatus].l &= ~0x2; - } - } - - if ((dev->ohci_mmio[OHCI_HcControl].l & OHCI_HcControl_BulkListEnable) - && (dev->ohci_mmio[OHCI_HcCommandStatus].l & 0x4)) { - uint8_t result = ohci_service_endpoint_desc(dev, dev->ohci_mmio[OHCI_HcBulkHeadED].l); - if (!result) { - dev->ohci_mmio[OHCI_HcBulkHeadED].l = 0; - dev->ohci_mmio[OHCI_HcCommandStatus].l &= ~0x4; - } - } - - if (dev->ohci_interrupt_counter == 0 && !(dev->ohci_mmio[OHCI_HcInterruptStatus].l & OHCI_HcInterruptEnable_WDH)) { - if (dev->ohci_mmio[OHCI_HcDoneHead].l == 0) { - fatal("OHCI: HcDoneHead is still NULL!"); - } - - if (dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l) { - dev->ohci_mmio[OHCI_HcDoneHead].l |= 1; - } - - hcca.HccaDoneHead = dev->ohci_mmio[OHCI_HcDoneHead].l; - dev->ohci_mmio[OHCI_HcDoneHead].l = 0; - dev->ohci_interrupt_counter = 7; - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_WDH); - } - - if (dev->ohci_interrupt_counter != 0 && dev->ohci_interrupt_counter != 7) { - dev->ohci_interrupt_counter--; - } - - dev->ohci_mmio[OHCI_HcFmNumber].w[0]++; - hcca.HccaFrameNumber = dev->ohci_mmio[OHCI_HcFmNumber].w[0]; - - dma_bm_write(dev->ohci_mmio[OHCI_HcHCCA].l, (uint8_t*)&hcca, sizeof(usb_hcca_t), 4); -} - -void -ohci_start_of_frame(usb_t* dev) -{ - dev->ohci_initial_start = 0; - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_SO); -} - -void -ohci_update_frame_counter(void* priv) -{ - usb_t *dev = (usb_t *) priv; - - dev->ohci_mmio[OHCI_HcFmRemaining].w[0] &= 0x3fff; - if (dev->ohci_mmio[OHCI_HcFmRemaining].w[0] == 0) { - ohci_end_of_frame(dev); - dev->ohci_mmio[OHCI_HcFmRemaining].w[0] = dev->ohci_mmio[OHCI_HcFmInterval].w[0] & 0x3fff; - dev->ohci_mmio[OHCI_HcFmRemaining].l &= ~(1 << 31); - dev->ohci_mmio[OHCI_HcFmRemaining].l |= dev->ohci_mmio[OHCI_HcFmInterval].l & (1 << 31); - ohci_start_of_frame(dev); - timer_on_auto(&dev->ohci_frame_timer, 1. / 12.); - return; - } - dev->ohci_mmio[OHCI_HcFmRemaining].w[0]--; - timer_on_auto(&dev->ohci_frame_timer, 1. / 12.); -} - -void -ohci_port_reset_callback(void* priv) -{ - usb_t *dev = (usb_t *) priv; - - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x10; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] |= 0x10; -} - -void -ohci_port_reset_callback_2(void* priv) -{ - usb_t *dev = (usb_t *) priv; - - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x10; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] |= 0x10; -} - -static void -ohci_soft_reset(usb_t* dev) -{ - uint32_t old_HcControl = (dev->ohci_mmio[OHCI_HcControl].l & 0x100) | 0xc0; - memset(dev->ohci_mmio, 0x00, 4096); - dev->ohci_mmio[OHCI_HcRevision].b[0] = 0x10; - dev->ohci_mmio[OHCI_HcRevision].b[1] = 0x01; - dev->ohci_mmio[OHCI_HcRhDescriptorA].b[0] = 0x02; - dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] = 0x02; - dev->ohci_mmio[OHCI_HcFmInterval].l = 0x27782edf; /* FrameInterval = 11999, FSLargestDataPacket = 10104 */ - dev->ohci_mmio[OHCI_HcLSThreshold].l = 0x628; - dev->ohci_mmio[OHCI_HcInterruptEnable].l |= (1 << 31); - dev->ohci_mmio[OHCI_HcControl].l = old_HcControl; - dev->ohci_interrupt_counter = 7; - ohci_update_irq(dev); -} - -static void -ohci_mmio_write(uint32_t addr, uint8_t val, void *priv) -{ - usb_t *dev = (usb_t *) priv; + usb_t *dev = (usb_t *) p; uint8_t old; -#ifdef ENABLE_USB_LOG - usb_log("[W] %08X = %04X\n", addr, val); -#endif - addr &= 0x00000fff; switch (addr) { - case OHCI_aHcControl: - old = dev->ohci_mmio[OHCI_HcControl].b[0]; -#ifdef ENABLE_USB_LOG - usb_log("OHCI: OHCI state 0x%X\n", (val & 0xc0)); -#endif + case 0x04: if ((val & 0xc0) == 0x00) { /* UsbReset */ - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] = dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] = 0x16; - for (int i = 0; i < 2; i++) { - if (dev->ohci_devices[i]) { - dev->ohci_devices[i]->device_reset(dev->ohci_devices[i]->priv); - } - } - } else if ((val & 0xc0) == 0x80 && (old & 0xc0) != (val & 0xc0)) { - dev->ohci_mmio[OHCI_HcFmRemaining].l = 0; - dev->ohci_initial_start = 1; - timer_on_auto(&dev->ohci_frame_timer, 1000.); + dev->ohci_mmio[0x56] = dev->ohci_mmio[0x5a] = 0x16; } break; - case OHCI_aHcCommandStatus: + case 0x08: /* HCCOMMANDSTATUS */ /* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */ if (val & 0x08) { - dev->ohci_mmio[OHCI_HcInterruptStatus].b[3] = 0x40; - if ((dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] & 0x40) == 0x40) { + dev->ohci_mmio[0x0f] = 0x40; + if ((dev->ohci_mmio[0x13] & 0xc0) == 0xc0) smi_raise(); - } } /* bit HostControllerReset must be cleared for the controller to be seen as initialized */ if (val & 0x01) { - ohci_soft_reset(dev); - + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; val &= ~0x01; } break; - case OHCI_aHcHCCA: + case 0x0c: + dev->ohci_mmio[addr] &= ~(val & 0x7f); return; - case OHCI_aHcInterruptEnable: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x7f); - dev->ohci_mmio[OHCI_HcInterruptDisable].b[0] &= ~(val & 0x7f); - ohci_update_irq(dev); + case 0x0d: + case 0x0e: return; - case OHCI_aHcInterruptEnable + 1: - case OHCI_aHcInterruptEnable + 2: + case 0x0f: + dev->ohci_mmio[addr] &= ~(val & 0x40); return; - case OHCI_aHcInterruptEnable + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xc0); - dev->ohci_mmio[OHCI_HcInterruptDisable].b[3] &= ~(val & 0xc0); - ohci_update_irq(dev); + case 0x3b: + dev->ohci_mmio[addr] = (val & 0x80); return; - case OHCI_aHcInterruptDisable: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x7f); - dev->ohci_mmio[OHCI_HcInterruptEnable].b[0] &= ~(val & 0x7f); - ohci_update_irq(dev); + case 0x39: + case 0x41: + dev->ohci_mmio[addr] = (val & 0x3f); return; - case OHCI_aHcInterruptDisable + 1: - case OHCI_aHcInterruptDisable + 2: + case 0x45: + dev->ohci_mmio[addr] = (val & 0x0f); return; - case OHCI_aHcInterruptDisable + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xc0); - dev->ohci_mmio[OHCI_HcInterruptEnable].b[3] &= ~(val & 0xc0); - ohci_update_irq(dev); + case 0x3a: + case 0x3e: + case 0x3f: + case 0x42: + case 0x43: + case 0x46: + case 0x47: + case 0x48: + case 0x4a: return; - case OHCI_aHcInterruptStatus: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x7f); - return; - case OHCI_aHcInterruptStatus + 1: - case OHCI_aHcInterruptStatus + 2: - return; - case OHCI_aHcInterruptStatus + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x40); - return; - case OHCI_aHcFmRemaining + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x80); - return; - case OHCI_aHcFmRemaining + 1: - case OHCI_aHcPeriodicStart + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x3f); - return; - case OHCI_aHcLSThreshold + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x0f); - return; - case OHCI_aHcFmRemaining + 2: - case OHCI_aHcFmNumber + 2: - case OHCI_aHcFmNumber + 3: - case OHCI_aHcPeriodicStart + 2: - case OHCI_aHcPeriodicStart + 3: - case OHCI_aHcLSThreshold + 2: - case OHCI_aHcLSThreshold + 3: - case OHCI_aHcRhDescriptorA: - case OHCI_aHcRhDescriptorA + 2: - return; - case OHCI_aHcRhDescriptorA + 1: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x1b); + case 0x49: + dev->ohci_mmio[addr] = (val & 0x1b); if (val & 0x02) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01; + dev->ohci_mmio[0x55] |= 0x01; + dev->ohci_mmio[0x59] |= 0x01; } return; - case OHCI_aHcRhDescriptorA + 3: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x03); + case 0x4b: + dev->ohci_mmio[addr] = (val & 0x03); return; - case OHCI_aHcRhDescriptorB: - case OHCI_aHcRhDescriptorB + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0x06); - if ((addr == OHCI_HcRhDescriptorB) && !(val & 0x04)) { - if (!(dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] & 0x01)) - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] |= 0x01; + case 0x4c: + case 0x4e: + dev->ohci_mmio[addr] = (val & 0x06); + if ((addr == 0x4c) && !(val & 0x04)) { + if (!(dev->ohci_mmio[0x58] & 0x01)) + dev->ohci_mmio[0x5a] |= 0x01; + dev->ohci_mmio[0x58] |= 0x01; } - if ((addr == OHCI_HcRhDescriptorB) && !(val & 0x02)) { - if (!(dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] & 0x01)) - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] |= 0x01; + if ((addr == 0x4c) && !(val & 0x02)) { + if (!(dev->ohci_mmio[0x54] & 0x01)) + dev->ohci_mmio[0x56] |= 0x01; + dev->ohci_mmio[0x54] |= 0x01; } return; - case OHCI_aHcRhDescriptorB + 1: - case OHCI_aHcRhDescriptorB + 3: + case 0x4d: + case 0x4f: return; - case OHCI_aHcRhStatus: + case 0x50: if (val & 0x01) { - if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17; - } else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x01) { - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17; + if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { + dev->ohci_mmio[0x55] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; + dev->ohci_mmio[0x59] &= ~0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; + } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { + if (!(dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[0x55] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; } - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) { - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17; + if (!(dev->ohci_mmio[0x4e] & 0x04)) { + dev->ohci_mmio[0x59] &= ~0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; } } } return; - case OHCI_aHcRhStatus + 1: + case 0x51: if (val & 0x80) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x80; + dev->ohci_mmio[addr] |= 0x80; return; - case OHCI_aHcRhStatus + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x02); + case 0x52: + dev->ohci_mmio[addr] &= ~(val & 0x02); if (val & 0x01) { - if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) { - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01; - } else if ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x01) { - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[1] |= 0x01; - if (!(dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[1] |= 0x01; + if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { + dev->ohci_mmio[0x55] |= 0x01; + dev->ohci_mmio[0x59] |= 0x01; + } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { + if (!(dev->ohci_mmio[0x4e] & 0x02)) + dev->ohci_mmio[0x55] |= 0x01; + if (!(dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[0x59] |= 0x01; } } return; - case OHCI_aHcRhStatus + 3: + case 0x53: if (val & 0x80) - dev->ohci_mmio[OHCI_HcRhStatus].b[1] &= ~0x80; + dev->ohci_mmio[0x51] &= ~0x80; return; - case OHCI_aHcRhPortStatus1: - case OHCI_aHcRhPortStatus2: - old = dev->ohci_mmio[addr >> 2].b[addr & 3]; + case 0x54: + case 0x58: + old = dev->ohci_mmio[addr]; if (val & 0x10) { if (old & 0x01) { - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x10; - timer_on_auto(&dev->ohci_port_reset_timer[(addr - OHCI_aHcRhPortStatus1) / 4], 10000.); - if (dev->ohci_devices[(addr - OHCI_aHcRhPortStatus1) >> 2]) - dev->ohci_devices[(addr - OHCI_aHcRhPortStatus1) >> 2]->device_reset(dev->ohci_devices[(addr - OHCI_aHcRhPortStatus1) >> 2]->priv); + dev->ohci_mmio[addr] |= 0x10; + /* TODO: The clear should be on a 10 ms timer. */ + dev->ohci_mmio[addr] &= ~0x10; + dev->ohci_mmio[addr + 2] |= 0x10; } else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; + dev->ohci_mmio[addr + 2] |= 0x01; } if (val & 0x08) - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x04; - if (val & 0x04) { - if (old & 0x01) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x04; - else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; - } + dev->ohci_mmio[addr] &= ~0x04; + if (val & 0x04) + dev->ohci_mmio[addr] |= 0x04; if (val & 0x02) { if (old & 0x01) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x02; + dev->ohci_mmio[addr] |= 0x02; else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; + dev->ohci_mmio[addr + 2] |= 0x01; } if (val & 0x01) { if (old & 0x01) - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x02; + dev->ohci_mmio[addr] &= ~0x02; else - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x01; + dev->ohci_mmio[addr + 2] |= 0x01; } - if (!(dev->ohci_mmio[addr >> 2].b[addr & 3] & 0x04) && (old & 0x04)) - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x04; -#if 0 - if (!(dev->ohci_mmio[addr >> 2].b[addr & 3] & 0x02)) - dev->ohci_mmio[(addr + 2) >> 2].b[(addr + 2) & 3] |= 0x02; -#endif + if (!(dev->ohci_mmio[addr] & 0x04) && (old & 0x04)) + dev->ohci_mmio[addr + 2] |= 0x04; + /* if (!(dev->ohci_mmio[addr] & 0x02)) + dev->ohci_mmio[addr + 2] |= 0x02; */ return; - case OHCI_aHcRhPortStatus1 + 1: - if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) { - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus1].b[2] &= ~0x17; + case 0x55: + if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[addr] &= ~0x01; + dev->ohci_mmio[0x54] &= ~0x17; + dev->ohci_mmio[0x56] &= ~0x17; } - if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x02)) { - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x01; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[0] &= ~0x17; - dev->ohci_mmio[OHCI_HcRhPortStatus2].b[2] &= ~0x17; + if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { + dev->ohci_mmio[addr] |= 0x01; + dev->ohci_mmio[0x58] &= ~0x17; + dev->ohci_mmio[0x5a] &= ~0x17; } return; - case OHCI_aHcRhPortStatus2 + 1: - if ((val & 0x02) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~0x01; - if ((val & 0x01) && ((dev->ohci_mmio[OHCI_HcRhDescriptorA].b[1] & 0x03) == 0x00) && (dev->ohci_mmio[OHCI_HcRhDescriptorB].b[2] & 0x04)) - dev->ohci_mmio[addr >> 2].b[addr & 3] |= 0x01; + case 0x59: + if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[addr] &= ~0x01; + if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) + dev->ohci_mmio[addr] |= 0x01; return; - case OHCI_aHcRhPortStatus1 + 2: - case OHCI_aHcRhPortStatus2 + 2: - dev->ohci_mmio[addr >> 2].b[addr & 3] &= ~(val & 0x1f); + case 0x56: + case 0x5a: + dev->ohci_mmio[addr] &= ~(val & 0x1f); return; - case OHCI_aHcRhPortStatus1 + 3: - case OHCI_aHcRhPortStatus2 + 3: + case 0x57: + case 0x5b: return; - case OHCI_aHcDoneHead: - case OHCI_aHcBulkCurrentED: - case OHCI_aHcBulkHeadED: - case OHCI_aHcControlCurrentED: - case OHCI_aHcControlHeadED: - case OHCI_aHcPeriodCurrentED: - dev->ohci_mmio[addr >> 2].b[addr & 3] = (val & 0xf0); - return; - - default: - break; } - dev->ohci_mmio[addr >> 2].b[addr & 3] = val; -} - -static void -ohci_mmio_writew(uint32_t addr, uint16_t val, void *priv) -{ - ohci_mmio_write(addr, val & 0xff, priv); - ohci_mmio_write(addr + 1, val >> 8, priv); -} - -static void -ohci_mmio_writel(uint32_t addr, uint32_t val, void *priv) -{ - ohci_mmio_writew(addr, val & 0xffff, priv); - ohci_mmio_writew(addr + 2, val >> 16, priv); + dev->ohci_mmio[addr] = val; } void @@ -966,71 +356,6 @@ ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000)) mem_mapping_set_addr(&dev->ohci_mmio_mapping, dev->ohci_mem_base, 0x1000); - - usb_log("ohci_update_mem_mapping(): OHCI %sabled at %08X\n", dev->ohci_enable ? "en" : "dis", dev->ohci_mem_base); -} - -uint8_t -usb_attach_device(usb_t *dev, usb_device_t* device, uint8_t bus_type) -{ - switch (bus_type) { - case USB_BUS_OHCI: - { - for (uint8_t i = 0; i < 2; i++) { - if (!dev->ohci_devices[i]) { - uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l; - dev->ohci_devices[i] = device; - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[0] |= 0x1; - if ((dev->ohci_mmio[OHCI_HcControl].b[0] & 0xc0) == 0xc0) { - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RD); - } - if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].l) { - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * i)].b[2] |= 0x1; - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC); - } - return i; - } - } - } - break; - - default: - break; - } - return 0xff; -} - -void -usb_detach_device(usb_t *dev, uint8_t port, uint8_t bus_type) -{ - switch (bus_type) { - case USB_BUS_OHCI: - { - if (port > 2) - return; - if (dev->ohci_devices[port]) { - uint32_t old = dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l; - dev->ohci_devices[port] = NULL; - if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 0x1) { - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] &= ~0x1; - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[2] |= 0x1; - } - if (dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] & 0x2) { - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[0] &= ~0x2; - dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].b[2] |= 0x2; - } - if (old != dev->ohci_mmio[OHCI_HcRhPortStatus1 + (4 * port)].l) - ohci_set_interrupt(dev, OHCI_HcInterruptEnable_RHSC); - return; - } - - } - break; - - default: - break; - } - return; } static void @@ -1038,21 +363,20 @@ usb_reset(void *priv) { usb_t *dev = (usb_t *) priv; - memset(dev->uhci_io, 0x00, sizeof(dev->uhci_io)); + memset(dev->uhci_io, 0x00, 128); dev->uhci_io[0x0c] = 0x40; dev->uhci_io[0x10] = dev->uhci_io[0x12] = 0x80; - ohci_soft_reset(dev); - dev->ohci_mmio[OHCI_HcControl].l = 0x00; + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; io_removehandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); dev->uhci_enable = 0; mem_mapping_disable(&dev->ohci_mmio_mapping); dev->ohci_enable = 0; - - usb_log("usb_reset(): OHCI %sabled at %08X\n", dev->ohci_enable ? "en" : "dis", dev->ohci_mem_base); - usb_log("usb_reset(): map = %08X\n", &dev->ohci_mmio_mapping); } static void @@ -1064,40 +388,39 @@ usb_close(void *priv) } static void * -usb_init_ext(UNUSED(const device_t *info), void *params) +usb_init(const device_t *info) { usb_t *dev; - dev = (usb_t *) calloc(1, sizeof(usb_t)); + dev = (usb_t *) malloc(sizeof(usb_t)); if (dev == NULL) return (NULL); + memset(dev, 0x00, sizeof(usb_t)); - dev->usb_params = (usb_params_t *) params; + memset(dev->uhci_io, 0x00, 128); + dev->uhci_io[0x0c] = 0x40; + dev->uhci_io[0x10] = dev->uhci_io[0x12] = 0x80; - mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0x1000, - ohci_mmio_read, ohci_mmio_readw, ohci_mmio_readl, - ohci_mmio_write, ohci_mmio_writew, ohci_mmio_writel, + memset(dev->ohci_mmio, 0x00, 4096); + dev->ohci_mmio[0x00] = 0x10; + dev->ohci_mmio[0x01] = 0x01; + dev->ohci_mmio[0x48] = 0x02; + + mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0, + ohci_mmio_read, NULL, NULL, + ohci_mmio_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, dev); - - mem_mapping_disable(&dev->ohci_mmio_mapping); - - timer_add(&dev->ohci_frame_timer, ohci_update_frame_counter, dev, 0); /* Unused for now, to be used for frame counting. */ - timer_add(&dev->ohci_port_reset_timer[0], ohci_port_reset_callback, dev, 0); - timer_add(&dev->ohci_port_reset_timer[1], ohci_port_reset_callback_2, dev, 0); - usb_reset(dev); - usb_device_inst = dev; - return dev; } const device_t usb_device = { .name = "Universal Serial Bus", .internal_name = "usb", - .flags = DEVICE_PCI | DEVICE_EXTPARAMS, + .flags = DEVICE_PCI, .local = 0, - .init_ext = usb_init_ext, + .init = usb_init, .close = usb_close, .reset = usb_reset, { .available = NULL }, From 250b756af785ed406e23c71cf41b1a0d35b5a686 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 18 Aug 2023 23:43:08 +0200 Subject: [PATCH 13/30] Changed the IDE status return on empty slave with non-empty master, fixes Award BIOS excess waits. --- src/disk/hdc_ide.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 01d1d28bf..52c1dc69e 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1939,7 +1939,7 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch) if ((ide->type == IDE_NONE) && ((ide_other->type == IDE_NONE) || !(ch & 1))) return 0x7f; /* Bit 7 pulled down, all other bits pulled up, per the spec. */ else if ((ide->type == IDE_NONE) && (ch & 1)) - return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */ + return 0x7f /*0x00*/; /* On real hardware, a slave with a present master always returns a status of 0x00. */ else if (ide->type == IDE_ATAPI) return (ide->sc->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); else From 274b44ab007521c96c61539f31bc9ab8271aae75 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 19 Aug 2023 01:39:30 +0200 Subject: [PATCH 14/30] Reimplemented ALi M1543(C) NVR SMI# handling, fixes #3278. --- src/chipset/ali1543.c | 31 +++++++++++++++++++++---------- src/include/86box/nvr.h | 3 +++ src/nvr_at.c | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 6227115fd..ccdaf0c46 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -1068,7 +1068,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) case 0x40: dev->pmu_conf[addr] = val & 0x1f; - pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03)); + nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr); break; case 0x41: dev->pmu_conf[addr] = val & 0x10; @@ -1079,6 +1079,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) /* TODO: Is the status R/W or R/WC? */ case 0x42: dev->pmu_conf[addr] &= ~(val & 0x1f); + if (val & 0x08) + nvr_smi_status_clear(dev->nvr); break; case 0x43: dev->pmu_conf[addr] &= ~(val & 0x10); @@ -1216,8 +1218,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) case 0x77: /* TODO: If bit 1 is clear, then status bit is set even if SMI is disabled. */ dev->pmu_conf[addr] = val; - pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03)); ali1543_log("PMU77: %02X\n", val); + nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr); apm_set_do_smi(dev->acpi->apm, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x41] & 0x10)); break; @@ -1422,14 +1424,23 @@ ali7101_read(int func, int addr, void *priv) return 0xff; /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ - if (addr == 0x43) - ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; - else if (addr == 0x7f) - ret = 0x80; - else if (addr == 0xbc) - ret = inb(0x70); - else - ret = dev->pmu_conf[addr]; + switch (addr) { + default: + ret = dev->pmu_conf[addr]; + break; + case 0x42: + ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); + break; + case 0x43: + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; + break; + case 0x7f: + ret = 0x80; + break; + case 0xbc: + ret = inb(0x70); + break; + } if (dev->pmu_conf[0x77] & 0x10) { switch (addr) { diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 8f2b45041..d24ca903c 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -127,5 +127,8 @@ extern void nvr_via_wp_set(int set, int reg, nvr_t *nvr); extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr); extern void nvr_lock_set(int base, int size, int lock, nvr_t *nvr); extern void nvr_irq_set(int irq, nvr_t *nvr); +extern void nvr_smi_enable(int enable, nvr_t *nvr); +extern uint8_t nvr_smi_status(nvr_t *nvr); +extern void nvr_smi_status_clear(nvr_t *nvr); #endif /*EMU_NVR_H*/ diff --git a/src/nvr_at.c b/src/nvr_at.c index 187e42a25..990d1f1e7 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -307,7 +307,7 @@ typedef struct local_t { uint8_t wp_0d; uint8_t wp_32; uint8_t irq_state; - uint8_t pad0; + uint8_t smi_status; uint8_t addr[8]; uint8_t wp[2]; @@ -317,6 +317,8 @@ typedef struct local_t { int16_t count; int16_t state; + int32_t smi_enable; + uint64_t ecount; uint64_t rtc_time; pc_timer_t update_timer; @@ -444,6 +446,10 @@ timer_update_irq(nvr_t *nvr) if (irq) { nvr->regs[RTC_REGC] |= REGC_IRQF; picintlevel(1 << nvr->irq, &local->irq_state); + if (local->smi_enable) { + smi_raise(); + local->smi_status = 1; + } } else { nvr->regs[RTC_REGC] &= ~REGC_IRQF; picintclevel(1 << nvr->irq, &local->irq_state); @@ -981,6 +987,33 @@ nvr_irq_set(int irq, nvr_t *nvr) nvr->irq = irq; } +void +nvr_smi_enable(int enable, nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->smi_enable = enable; + + if (!enable) + local->smi_status = 0; +} + +uint8_t +nvr_smi_status(nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + return local->smi_status; +} + +void +nvr_smi_status_clear(nvr_t *nvr) +{ + local_t *local = (local_t *) nvr->data; + + local->smi_status = 0; +} + static void nvr_at_reset(void *priv) { From 6c4a4be6be5b48fa94662a2f5e22080c4cc7a4e0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 19 Aug 2023 05:26:49 +0200 Subject: [PATCH 15/30] Timer clean-ups. --- src/chipset/intel_420ex.c | 2 +- src/chipset/intel_piix.c | 4 +- src/chipset/intel_sio.c | 2 +- src/cpu/386.c | 2 +- src/cpu/386_dynarec.c | 6 +- src/device/serial.c | 2 +- src/include/86box/timer.h | 39 +---------- src/scsi/scsi_ncr5380.c | 12 ++-- src/scsi/scsi_spock.c | 2 +- src/scsi/scsi_x54x.c | 2 +- src/timer.c | 138 ++++++++++++++++++-------------------- 11 files changed, 86 insertions(+), 125 deletions(-) diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 03720b668..4d810f65b 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -522,7 +522,7 @@ i420ex_speed_changed(void *priv) if (te) timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); - te = timer_is_enabled(&dev->fast_off_timer); + te = timer_is_on(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); if (te) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index add421b96..4066abe31 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1541,10 +1541,10 @@ piix_speed_changed(void *priv) if (!dev) return; - int te = timer_is_enabled(&dev->fast_off_timer); + int to = timer_is_on(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); - if (te) + if (to) timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period); } diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 0f32eb4c8..03a292da8 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -497,7 +497,7 @@ sio_speed_changed(void *priv) timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); if (dev->id == 0x03) { - te = timer_is_enabled(&dev->fast_off_timer); + te = timer_is_on(&dev->fast_off_timer); timer_stop(&dev->fast_off_timer); if (te) diff --git a/src/cpu/386.c b/src/cpu/386.c index fb42a222f..20b67ff89 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -369,7 +369,7 @@ exec386_2386(int cycs) } if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); #ifdef USE_GDBSTUB if (gdbstub_instruction()) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index a31704c1b..ab01d28b8 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -256,7 +256,7 @@ update_tsc(void) if (cycdiff > 0) { if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); } } @@ -782,7 +782,7 @@ exec386_dynarec(int cycs) if (cycdiff > 0) { if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); } # ifdef USE_GDBSTUB @@ -943,7 +943,7 @@ exec386(int cycs) } if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + timer_process(); #ifdef USE_GDBSTUB if (gdbstub_instruction()) diff --git a/src/device/serial.c b/src/device/serial.c index 5dd5d8420..da34fd212 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -363,7 +363,7 @@ serial_update_speed(serial_t *dev) if (dev->transmit_enabled & 3) timer_on_auto(&dev->transmit_timer, dev->transmit_period); - if (timer_is_enabled(&dev->timeout_timer)) + if (timer_is_on(&dev->timeout_timer)) timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period); } diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index 586e3d2fe..45b648151 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -122,7 +122,7 @@ timer_is_enabled(pc_timer_t *timer) static __inline int timer_is_on(pc_timer_t *timer) { - return ((timer->flags & TIMER_ENABLED) && (timer->period > 0.0)); + return ((timer->flags & TIMER_SPLIT) && (timer->flags & TIMER_ENABLED)); } /*Return integer timestamp of timer*/ @@ -184,45 +184,8 @@ timer_set_p(pc_timer_t *timer, void *priv) /* The API for big timer periods starts here. */ extern void timer_stop(pc_timer_t *timer); -extern void timer_advance_ex(pc_timer_t *timer, int start); -extern void timer_on(pc_timer_t *timer, double period, int start); extern void timer_on_auto(pc_timer_t *timer, double period); -extern void timer_remove_head(void); - -extern pc_timer_t *timer_head; -extern int timer_inited; - -static __inline void -timer_process_inline(void) -{ - pc_timer_t *timer; - - if (!timer_head) - return; - - while (1) { - timer = timer_head; - - if (!TIMER_LESS_THAN_VAL(timer, (uint32_t) tsc)) - break; - - timer_head = timer->next; - if (timer_head) - timer_head->prev = NULL; - - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - - if (timer->flags & TIMER_SPLIT) - timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ - else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */ - timer->callback(timer->priv); - } - - timer_target = timer_head->ts.ts32.integer; -} - #ifdef __cplusplus } #endif diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 8b0ae3c0c..c4bec884d 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -639,7 +639,8 @@ ncr_write(uint16_t port, uint8_t val, void *priv) } } else { /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && + !timer_is_on(&ncr_dev->timer)) { ncr_log("Continuing DMA mode\n"); ncr_timer_on(ncr_dev, ncr, 0); } @@ -671,7 +672,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) if (dev->buffer_length > 0) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); - ncr_log("DMA send timer start, enabled? = %i\n", timer_is_enabled(&ncr_dev->timer)); + ncr_log("DMA send timer start, enabled? = %i\n", timer_is_on(&ncr_dev->timer)); ncr_dev->t128.block_count = dev->buffer_length >> 9; ncr_dev->t128.block_loaded = 1; @@ -679,7 +680,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr_dev->t128.status |= 0x04; } } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); ncr_log("DMA send timer on\n"); @@ -693,7 +694,8 @@ ncr_write(uint16_t port, uint8_t val, void *priv) /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_INITIATOR_RECEIVE; if (ncr_dev->type == 3) { - ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", timer_is_enabled(&ncr_dev->timer), ncr->command[0], dev->buffer_length); + ncr_log("DMA receive timer start, enabled? = %i, cdb[0] = %02x, buflen = %i\n", + timer_is_on(&ncr_dev->timer), ncr->command[0], dev->buffer_length); if (dev->buffer_length > 0) { memset(ncr_dev->t128.buffer, 0, MIN(512, dev->buffer_length)); @@ -709,7 +711,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) timer_on_auto(&ncr_dev->timer, 0.02); } } else { - if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + if ((ncr->mode & MODE_DMA) && !timer_is_on(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); ncr_log("DMA receive timer start\n"); diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index 3b9f5108c..d70afca76 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -1055,7 +1055,7 @@ spock_callback(void *priv) spock_process_scsi(scsi, scb); period = 0.2 * ((double) scsi->temp_period); - timer_on(&scsi->callback_timer, (scsi->media_period + period + 10.0), 0); + timer_on_auto(&scsi->callback_timer, (scsi->media_period + period + 10.0)); spock_log("Temporary period: %lf us (%" PRIi64 " periods)\n", scsi->callback_timer.period, scsi->temp_period); } diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 96088e200..dc3fdfac3 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -1293,7 +1293,7 @@ x54x_cmd_callback(void *priv) } period = (1000000.0 / dev->ha_bps) * ((double) dev->temp_period); - timer_on(&dev->timer, dev->media_period + period + 10.0, 0); + timer_on_auto(&dev->timer, dev->media_period + period + 10.0); #if 0 x54x_log("Temporary period: %lf us (%" PRIi64 " periods)\n", dev->timer.period, dev->temp_period); #endif diff --git a/src/timer.c b/src/timer.c index 90ee3ca49..e45fc4398 100644 --- a/src/timer.c +++ b/src/timer.c @@ -15,10 +15,13 @@ pc_timer_t *timer_head = NULL; /* Are we initialized? */ int timer_inited = 0; +static void timer_advance_ex(pc_timer_t *timer); + void timer_enable(pc_timer_t *timer) { pc_timer_t *timer_node = timer_head; + int ret = 0; if (!timer_inited || (timer == NULL)) return; @@ -29,59 +32,63 @@ timer_enable(pc_timer_t *timer) if (timer->next || timer->prev) fatal("timer_enable - timer->next\n"); - timer->flags |= TIMER_ENABLED; - /*List currently empty - add to head*/ if (!timer_head) { timer_head = timer; timer->next = timer->prev = NULL; timer_target = timer_head->ts.ts32.integer; - return; - } - - if (TIMER_LESS_THAN(timer, timer_head)) { + ret = 1; + } else if (TIMER_LESS_THAN(timer, timer_head)) { timer->next = timer_head; timer->prev = NULL; timer_head->prev = timer; timer_head = timer; timer_target = timer_head->ts.ts32.integer; - return; - } - - if (!timer_head->next) { + ret = 1; + } else if (!timer_head->next) { timer_head->next = timer; timer->prev = timer_head; - return; + ret = 1; } - pc_timer_t *prev = timer_head; - timer_node = timer_head->next; + if (ret == 0) { + pc_timer_t *prev = timer_head; + timer_node = timer_head->next; - while (1) { - /*Timer expires before timer_node. Add to list in front of timer_node*/ - if (TIMER_LESS_THAN(timer, timer_node)) { - timer->next = timer_node; - timer->prev = prev; - timer_node->prev = timer; - prev->next = timer; - return; + while (1) { + /*Timer expires before timer_node. Add to list in front of timer_node*/ + if (TIMER_LESS_THAN(timer, timer_node)) { + timer->next = timer_node; + timer->prev = prev; + timer_node->prev = timer; + prev->next = timer; + ret = 1; + break; + } + + /*timer_node is last in the list. Add timer to end of list*/ + if (!timer_node->next) { + timer_node->next = timer; + timer->prev = timer_node; + ret = 1; + break; + } + + prev = timer_node; + timer_node = timer_node->next; } - - /*timer_node is last in the list. Add timer to end of list*/ - if (!timer_node->next) { - timer_node->next = timer; - timer->prev = timer_node; - return; - } - - prev = timer_node; - timer_node = timer_node->next; } + + /* Do not mark it as enabled if it has failed every single condition. */ + if (ret == 1) + timer->flags |= TIMER_ENABLED; } void timer_disable(pc_timer_t *timer) { + pc_timer_t *cur, *temp; + if (!timer_inited || (timer == NULL) || !(timer->flags & TIMER_ENABLED)) return; @@ -120,13 +127,15 @@ timer_process(void) timer->next = timer->prev = NULL; timer->flags &= ~TIMER_ENABLED; + timer->flags |= TIMER_PROCESS; if (timer->flags & TIMER_SPLIT) - timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ - else if (timer->callback != NULL) {/* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */ - timer->flags |= TIMER_PROCESS; + timer_advance_ex(timer); /* We're splitting a > 1 s period into + multiple <= 1 s periods. */ + else if (timer->callback != NULL) /* Make sure it's not NULL, so that we can + have a NULL callback when no operation + is needed. */ timer->callback(timer->priv); - timer->flags &= ~TIMER_PROCESS; - } + timer->flags &= ~TIMER_PROCESS; } timer_target = timer_head->ts.ts32.integer; @@ -182,60 +191,47 @@ timer_stop(pc_timer_t *timer) return; timer->period = 0.0; - timer_disable(timer); + if (timer_is_enabled(timer)) + timer_disable(timer); timer->flags &= ~TIMER_SPLIT; } static void -timer_do_period(pc_timer_t *timer, uint64_t period, int start) +timer_do_period(pc_timer_t *timer, uint64_t period) { - if (!timer_inited || (timer == NULL)) - return; - - if (start) - timer_set_delay_u64(timer, period); - else + if (timer->flags & TIMER_PROCESS) timer_advance_u64(timer, period); + else + timer_set_delay_u64(timer, period); } -void -timer_advance_ex(pc_timer_t *timer, int start) +static void +timer_advance_ex(pc_timer_t *timer) { - if (!timer_inited || (timer == NULL)) - return; + double dusec = ((double) TIMER_USEC); + double period; - if (timer->period > MAX_USEC) { - timer_do_period(timer, MAX_USEC64 * TIMER_USEC, start); - timer->period -= MAX_USEC; - timer->flags |= TIMER_SPLIT; - } else { - if (timer->period > 0.0) - timer_do_period(timer, (uint64_t) (timer->period * ((double) TIMER_USEC)), start); - else - timer_disable(timer); - timer->period = 0.0; + period = (timer->period > MAX_USEC) ? MAX_USEC64 : timer->period; + + if (timer->period > 0.0) { + timer_do_period(timer, (uint64_t) (period * dusec)); + timer->period -= period; + timer->flags = (timer->flags & ~TIMER_SPLIT) | ((timer->period > MAX_USEC) ? TIMER_SPLIT : 0); + } else if (timer_is_enabled(timer)) { + timer_disable(timer); timer->flags &= ~TIMER_SPLIT; } } -void -timer_on(pc_timer_t *timer, double period, int start) -{ - if (!timer_inited || (timer == NULL)) - return; - - timer->period = period; - timer_advance_ex(timer, start); -} - void timer_on_auto(pc_timer_t *timer, double period) { if (!timer_inited || (timer == NULL)) return; - if (period > 0.0) - timer_on(timer, period, !(timer->flags & TIMER_PROCESS) && (timer->period <= 0.0)); - else + if (period > 0.0) { + timer->period = period; + timer_advance_ex(timer); + } else if (timer_is_on(timer)) timer_stop(timer); } From 5b56f3a450873d37d70b14a3742a43a26e9ae247 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 19 Aug 2023 06:05:52 +0200 Subject: [PATCH 16/30] Some small fixes. --- src/config.c | 8 ++++---- src/device/serial.c | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/config.c b/src/config.c index aad7db0f9..7db7cb040 100644 --- a/src/config.c +++ b/src/config.c @@ -1348,13 +1348,13 @@ load_floppy_and_cdrom_drives(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " + if (strlen(p) > 255) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 255 " "(fdd_image_history[%i][%i])\n", c, i); else - snprintf(fdd_image_history[c][i], 511, "%s", p); + snprintf(fdd_image_history[c][i], 255, "%s", p); } else - snprintf(fdd_image_history[c][i], 511, "%s%$s%s", usr_path, + snprintf(fdd_image_history[c][i], 255, "%s%$s%s", usr_path, path_get_slash(usr_path), p); path_normalize(fdd_image_history[c][i]); } diff --git a/src/device/serial.c b/src/device/serial.c index da34fd212..817a1fede 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -12,11 +12,9 @@ * * * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ @@ -742,7 +740,7 @@ serial_rcvr_d_empty_evt(void *priv) { serial_t *dev = (serial_t *) priv; - dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo); + dev->lsr = (dev->lsr & 0xfe) | (fifo_get_empty(dev->rcvr_fifo) ? 0 : 1); } static void From 13659d7a4cd5f18a5dbf6245ccc0028afd83d491 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Aug 2023 00:04:52 +0200 Subject: [PATCH 17/30] More timer fixes, fixes Trantor T128b. --- src/cpu/cpu_table.c | 6 ++-- src/timer.c | 69 +++++++++++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 3afaf055e..cec3c4874 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -378,7 +378,7 @@ const cpu_family_t cpu_families[] = { }, { .package = CPU_PKG_SOCKET1, .manufacturer = "Intel", - .name = "i486SX (SL-Enhanced)", + .name = "i486SX-S", .internal_name = "i486sx_slenh", .cpus = (const CPU[]) { {"25", CPU_i486SX_SLENH, fpus_486sx, 25000000, 1, 5000, 0x423, 0x423, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3}, @@ -409,7 +409,7 @@ const cpu_family_t cpu_families[] = { }, { .package = CPU_PKG_SOCKET1, .manufacturer = "Intel", - .name = "i486DX (SL-Enhanced)", + .name = "i486DX-S", .internal_name = "i486dx_slenh", .cpus = (const CPU[]) { {"33", CPU_i486DX_SLENH, fpus_internal, 33333333, 1, 5000, 0x414, 0x414, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4}, @@ -430,7 +430,7 @@ const cpu_family_t cpu_families[] = { }, { .package = CPU_PKG_SOCKET1, .manufacturer = "Intel", - .name = "i486DX2 (SL-Enhanced)", + .name = "i486DX2-S", .internal_name = "i486dx2_slenh", .cpus = (const CPU[]) { {"40", CPU_i486DX_SLENH, fpus_internal, 40000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, diff --git a/src/timer.c b/src/timer.c index e45fc4398..13e5d836f 100644 --- a/src/timer.c +++ b/src/timer.c @@ -15,7 +15,9 @@ pc_timer_t *timer_head = NULL; /* Are we initialized? */ int timer_inited = 0; -static void timer_advance_ex(pc_timer_t *timer); +static int timer_in_process = 0; + +static void timer_advance_ex(pc_timer_t *timer, int start); void timer_enable(pc_timer_t *timer) @@ -114,6 +116,8 @@ timer_process(void) if (!timer_head) return; + timer_in_process = 0; + while (1) { timer = timer_head; @@ -127,18 +131,18 @@ timer_process(void) timer->next = timer->prev = NULL; timer->flags &= ~TIMER_ENABLED; - timer->flags |= TIMER_PROCESS; if (timer->flags & TIMER_SPLIT) - timer_advance_ex(timer); /* We're splitting a > 1 s period into + timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ else if (timer->callback != NULL) /* Make sure it's not NULL, so that we can have a NULL callback when no operation is needed. */ timer->callback(timer->priv); - timer->flags &= ~TIMER_PROCESS; } timer_target = timer_head->ts.ts32.integer; + + timer_in_process = 1; } void @@ -191,47 +195,62 @@ timer_stop(pc_timer_t *timer) return; timer->period = 0.0; - if (timer_is_enabled(timer)) - timer_disable(timer); + timer_disable(timer); timer->flags &= ~TIMER_SPLIT; } static void -timer_do_period(pc_timer_t *timer, uint64_t period) +timer_do_period(pc_timer_t *timer, uint64_t period, int start) { - if (timer->flags & TIMER_PROCESS) - timer_advance_u64(timer, period); - else + if (!timer_inited || (timer == NULL)) + return; + + if (start) timer_set_delay_u64(timer, period); + else + timer_advance_u64(timer, period); } static void -timer_advance_ex(pc_timer_t *timer) +timer_advance_ex(pc_timer_t *timer, int start) { - double dusec = ((double) TIMER_USEC); - double period; + if (!timer_inited || (timer == NULL)) + return; - period = (timer->period > MAX_USEC) ? MAX_USEC64 : timer->period; - - if (timer->period > 0.0) { - timer_do_period(timer, (uint64_t) (period * dusec)); - timer->period -= period; - timer->flags = (timer->flags & ~TIMER_SPLIT) | ((timer->period > MAX_USEC) ? TIMER_SPLIT : 0); - } else if (timer_is_enabled(timer)) { - timer_disable(timer); + if (timer->period > MAX_USEC) { + timer_do_period(timer, MAX_USEC64 * TIMER_USEC, start); + timer->period -= MAX_USEC; + timer->flags |= TIMER_SPLIT; + } else { + if (timer->period > 0.0) + timer_do_period(timer, (uint64_t) (timer->period * ((double) TIMER_USEC)), start); + else + timer_disable(timer); + timer->period = 0.0; timer->flags &= ~TIMER_SPLIT; } } +static void +timer_on(pc_timer_t *timer, double period, int start) +{ + if (!timer_inited || (timer == NULL)) + return; + + timer->period = period; + timer_advance_ex(timer, start); +} + void timer_on_auto(pc_timer_t *timer, double period) { + uint32_t *p = NULL; + if (!timer_inited || (timer == NULL)) return; - if (period > 0.0) { - timer->period = period; - timer_advance_ex(timer); - } else if (timer_is_on(timer)) + if (period > 0.0) + timer_on(timer, period, !timer_in_process && (timer->period <= 0.0)); + else timer_stop(timer); } From 66db65e69b07aa9b796d4e3d1e8f9451bf952e71 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Aug 2023 02:04:42 +0200 Subject: [PATCH 18/30] The PIC now once again returns IRR in invalid modes, fixes #3602. --- src/pic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pic.c b/src/pic.c index 56a6a927f..3db41b4c2 100644 --- a/src/pic.c +++ b/src/pic.c @@ -442,6 +442,10 @@ pic_read(uint16_t addr, void *priv) } } else { /* Standard 8259 PIC read */ +#ifndef UNDEFINED_READ + /* Put the IRR on to the data bus by default until the real PIC is probed. */ + dev->data_bus = dev->irr; +#endif if (dev->ocw3 & 0x04) { if (dev->int_pending) { dev->data_bus = 0x80 | (dev->interrupt & 7); From 5492836562ad1f9b5d5a1bf4014f731cc5773a4c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Aug 2023 02:33:18 +0200 Subject: [PATCH 19/30] VISO now supports all DOS characters, fixes #3605. --- src/cdrom/cdrom_image_viso.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 94b4e44ca..c0c3bbf51 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -247,17 +247,28 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size) c -= 'a' - 'A'; \ break; \ \ - case ' ': \ case '!': \ - case '"': \ + case '#': \ + case '$': \ case '%': \ case '&': \ case '\'': \ case '(': \ case ')': \ + case '-': \ + case '@': \ + case '^': \ + case '`': \ + case '{': \ + case '}': \ + case '~': \ + /* Valid on all sets (non-complying DOS characters). */ \ + break; \ + \ + case ' ': \ + case '"': \ case '+': \ case ',': \ - case '-': \ case '.': \ case '<': \ case '=': \ From c16e151365024599f399546cdeeb199481dfdc50 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Aug 2023 03:59:54 +0200 Subject: [PATCH 20/30] Corrected the Hercules Plus 48 RAM Font mode attributes, fixes #3529. --- src/video/vid_herculesplus.c | 124 +++++++++++------------------------ 1 file changed, 40 insertions(+), 84 deletions(-) diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 0c2c0270c..a3e3b832e 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -231,9 +231,10 @@ draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) int elg; int blk; int cw = HERCULESPLUS_CW; + int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; blk = 0; - if (dev->ctrl & HERCULESPLUS_CTRL_BLINK) { + if (blink) { if (attr & 0x80) blk = (dev->blink & 16); attr &= 0x7f; @@ -318,35 +319,22 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) elg = 0; else elg = ((chr >= 0xc0) && (chr <= 0xdf)); + fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; if (blk) { - /* Blinking, draw all background */ - val = 0x000; + val = 0x000; /* Blinking, draw all background */ } else if (dev->sc == ull) { - /* Underscore, draw all foreground */ - val = 0x1ff; + val = 0x1ff; /* Underscore, draw all foreground */ } else { - val = fnt[0x00000] << 1; + val = fnt[0] << 1; if (elg) val |= (val >> 1) & 1; } for (int i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = 0; - - if (val & 0x100) - cfg = ifg; - else - cfg = ibg; - - /* cfg = colour of foreground pixels */ - if ((attr & 0x77) == 0) - cfg = ibg; /* 'blank' attribute */ - - buffer32->line[dev->displine][x * cw + i] = dev->cols[attr][!!blink][cfg]; + buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; val = val << 1; } } @@ -354,98 +342,66 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) static void draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { - int elg; - int blk; - int ul; - int ol; - int bld; - unsigned ull; - unsigned oll; - unsigned ulc = 0; - unsigned olc = 0; - unsigned val; - unsigned ibg; - unsigned cfg; - const unsigned char *fnt; - int cw = HERCULESPLUS_CW; - int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; - int font = (attr & 0x0F); + unsigned ull; + unsigned val; + unsigned ifg; + unsigned ibg; + unsigned cfg; + const uint8_t *fnt; + int elg; + int blk; + int cw = HERCULESPLUS_CW; + int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; + int font = (attr & 0x0F); if (font >= 12) font &= 7; + attr = (attr >> 4) ^ 0x0f;; + blk = 0; if (blink) { - if (attr & 0x40) + if (attr & 0x80) blk = (dev->blink & 16); attr &= 0x7f; } /* MDA-compatible attributes */ - if (blink) { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } else { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - - if (ul) { - ull = dev->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F; - ulc = (dev->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) - ulc = 7; - } else { - ull = 0xFFFF; - } - - if (ol) { - oll = dev->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F; - olc = (dev->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) - olc = 7; - } else { - oll = 0xFFFF; + ibg = 0; + ifg = 7; + if ((attr & 0x77) == 0x70) { /* Invert */ + ifg = 0; + ibg = 7; } + if (attr & 8) + ifg |= 8; /* High intensity FG */ + if (attr & 0x80) + ibg |= 8; /* High intensity BG */ + if ((attr & 0x77) == 0) /* Blank */ + ifg = ibg; + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) elg = 0; else elg = ((chr >= 0xc0) && (chr <= 0xdf)); + fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; - if (blk) { /* Blinking, draw all background */ - val = 0x000; + if (blk) { + val = 0x000; /* Blinking, draw all background */ } else if (dev->sc == ull) { - /* Underscore, draw all foreground */ - val = 0x1ff; + val = 0x1ff; /* Underscore, draw all foreground */ } else { - val = fnt[0x00000] << 1; + val = fnt[0] << 1; if (elg) val |= (val >> 1) & 1; - if (bld) - val |= (val >> 1); } for (int i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = val & 0x100; - if (dev->sc == oll) - cfg = olc ^ ibg; /* Strikethrough */ - else if (dev->sc == ull) - cfg = ulc ^ ibg; /* Underline */ - else if (val & 0x100) - cfg |= ~ibg; - else - cfg |= ibg; - - buffer32->line[dev->displine][(x * cw) + i] = dev->cols[attr][!!blink][cfg]; - val = val << 1; + buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; + val = val << 1; } } From f1174247fabd31f5cdfae40b0d7cf096605e85c8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Aug 2023 04:58:51 +0200 Subject: [PATCH 21/30] One last timer fix to fix the slowness reported by Ompronce. --- src/timer.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/timer.c b/src/timer.c index 13e5d836f..9a3ed805f 100644 --- a/src/timer.c +++ b/src/timer.c @@ -15,8 +15,6 @@ pc_timer_t *timer_head = NULL; /* Are we initialized? */ int timer_inited = 0; -static int timer_in_process = 0; - static void timer_advance_ex(pc_timer_t *timer, int start); void @@ -116,8 +114,6 @@ timer_process(void) if (!timer_head) return; - timer_in_process = 0; - while (1) { timer = timer_head; @@ -141,8 +137,6 @@ timer_process(void) } timer_target = timer_head->ts.ts32.integer; - - timer_in_process = 1; } void @@ -250,7 +244,7 @@ timer_on_auto(pc_timer_t *timer, double period) return; if (period > 0.0) - timer_on(timer, period, !timer_in_process && (timer->period <= 0.0)); + timer_on(timer, period, timer->period <= 0.0); else timer_stop(timer); } From 5ac598378f7ec0d20411f01b8c97ed196614183a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Aug 2023 17:26:52 +0200 Subject: [PATCH 22/30] XTA fixes for both the regular and IBM PS/1 variants. --- src/disk/hdc_xta.c | 52 +++++++-------------- src/machine/m_ps1_hdc.c | 100 +++++++++++++++++++++++++++------------- 2 files changed, 85 insertions(+), 67 deletions(-) diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index 9325c8f91..95eb517df 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -102,7 +102,7 @@ #include <86box/hdc.h> #include <86box/hdd.h> -#define HDC_TIME (50 * TIMER_USEC) +#define HDC_TIME (250 * TIMER_USEC) #define WD_REV_1_BIOS_FILE "roms/hdd/xta/idexywd2.bin" #define WD_REV_2_BIOS_FILE "roms/hdd/xta/infowdbios.rom" @@ -248,7 +248,6 @@ typedef struct hdc_t { uint8_t sense; /* current SENSE ERROR value */ uint8_t status; /* current operational status */ uint8_t intr; - uint64_t callback; pc_timer_t timer; /* Data transfer. */ @@ -343,22 +342,6 @@ next_sector(hdc_t *dev, drive_t *drive) } } -static void -xta_set_callback(hdc_t *dev, uint64_t callback) -{ - if (!dev) { - return; - } - - if (callback) { - dev->callback = callback; - timer_set_delay_u64(&dev->timer, dev->callback); - } else { - dev->callback = 0; - timer_disable(&dev->timer); - } -} - /* Perform the seek operation. */ static void do_seek(hdc_t *dev, drive_t *drive, int cyl) @@ -457,9 +440,6 @@ hdc_callback(void *priv) int no_data = 0; int val; - /* Cancel timer. */ - xta_set_callback(dev, 0); - drive = &dev->drives[dcb->drvsel]; dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00; dev->status |= STAT_DCB; @@ -558,12 +538,12 @@ do_send: dev->buf_idx = 0; if (no_data) { /* Delay a bit, no actual transfer. */ - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { if (dev->intr & DMA_ENA) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* Copy from sector to data. */ memcpy(dev->data, @@ -586,14 +566,14 @@ do_send: xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len); dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); return; } dev->buf_ptr++; dev->buf_idx++; } } - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); dev->state = STATE_SDONE; break; @@ -654,7 +634,7 @@ do_recv: if (dev->intr & DMA_ENA) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* No DMA, do PIO. */ dev->buf_ptr = dev->data; @@ -673,7 +653,7 @@ do_recv: xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name); dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); return; } @@ -681,7 +661,7 @@ do_recv: dev->buf_idx++; } dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } break; @@ -785,7 +765,7 @@ do_recv: dev->state = STATE_RDATA; if (dev->intr & DMA_ENA) { dev->buf_ptr = dev->sector_buf; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { dev->buf_ptr = dev->data; dev->status |= STAT_REQ; @@ -800,7 +780,7 @@ do_recv: if (val == DMA_NODATA) { xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name); dev->status |= (STAT_CD | STAT_IO | STAT_REQ); - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); return; } @@ -808,7 +788,7 @@ do_recv: dev->buf_idx++; } dev->state = STATE_RDONE; - xta_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } break; @@ -828,7 +808,7 @@ do_recv: switch (dev->state) { case STATE_IDLE: dev->state = STATE_RDONE; - xta_set_callback(dev, 5 * HDC_TIME); + timer_advance_u64(&dev->timer, 5 * HDC_TIME); break; case STATE_RDONE: @@ -845,7 +825,7 @@ do_recv: case STATE_IDLE: if (drive->present) { dev->state = STATE_RDONE; - xta_set_callback(dev, 5 * HDC_TIME); + timer_advance_u64(&dev->timer, 5 * HDC_TIME); } else { dev->comp |= COMP_ERR; dev->sense = ERR_NOTRDY; @@ -866,7 +846,7 @@ do_recv: switch (dev->state) { case STATE_IDLE: dev->state = STATE_RDONE; - xta_set_callback(dev, 10 * HDC_TIME); + timer_advance_u64(&dev->timer, 10 * HDC_TIME); break; case STATE_RDONE: @@ -911,7 +891,7 @@ hdc_read(uint16_t port, void *priv) /* All data sent. */ dev->status &= ~STAT_REQ; dev->state = STATE_SDONE; - xta_set_callback(dev, HDC_TIME); + timer_set_delay_u64(&dev->timer, HDC_TIME); } } else if (dev->state == STATE_COMPL) { xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp); @@ -969,7 +949,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) else dev->state = STATE_IDLE; dev->status &= ~STAT_CD; - xta_set_callback(dev, HDC_TIME); + timer_set_delay_u64(&dev->timer, HDC_TIME); } } break; diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index 2636812d4..116acbf11 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -99,7 +99,7 @@ #include <86box/ui.h> #include <86box/machine.h> -#define HDC_TIME (50 * TIMER_USEC) +#define HDC_TIME (250 * TIMER_USEC) #define HDC_TYPE_USER 47 /* user drive type */ enum { @@ -380,7 +380,6 @@ typedef struct hdc_t { uint8_t *reg_91; /* handle to system board's register 0x91 */ /* Controller state. */ - uint64_t callback; pc_timer_t timer; int8_t state; /* controller state */ int8_t reset; /* reset state counter */ @@ -463,6 +462,7 @@ static const geom_t ibm_type_table[] = { // clang-format on }; +#define ENABLE_PS1_HDC_LOG 1 #ifdef ENABLE_PS1_HDC_LOG int ps1_hdc_do_log = ENABLE_PS1_HDC_LOG; @@ -481,22 +481,6 @@ ps1_hdc_log(const char *fmt, ...) # define ps1_hdc_log(fmt, ...) #endif -static void -hdc_set_callback(hdc_t *dev, uint64_t callback) -{ - if (!dev) { - return; - } - - if (callback) { - dev->callback = callback; - timer_set_delay_u64(&dev->timer, dev->callback); - } else { - dev->callback = 0; - timer_disable(&dev->timer); - } -} - /* FIXME: we should use the disk/hdd_table.c code with custom tables! */ static int ibm_drive_type(drive_t *drive) @@ -633,7 +617,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) /* Enable for PIO or DMA, as needed. */ #if NOT_USED if (dev->ctrl & ACR_DMA_EN) - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); else #endif dev->status |= ASR_DATA_REQ; @@ -653,7 +637,7 @@ do_format(hdc_t *dev, drive_t *drive, ccb_t *ccb) dev->buf_idx++; } dev->state = STATE_RDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_RDONE: @@ -737,9 +721,7 @@ hdc_callback(void *priv) off64_t addr; int no_data = 0; int val; - - /* Cancel timer. */ - dev->callback = 0; + uint8_t cmd = ccb->cmd & 0x0f; /* Clear the SSB error bits. */ dev->ssb.track_0 = 0; @@ -758,6 +740,8 @@ hdc_callback(void *priv) /* We really only support one drive, but ohwell. */ drive = &dev->drives[0]; + ps1_hdc_log("hdc_callback(): %02X\n", cmd); + switch (ccb->cmd) { case CMD_READ_VERIFY: no_data = 1; @@ -812,12 +796,12 @@ do_send: dev->buf_idx = 0; if (no_data) { /* Delay a bit, no actual transfer. */ - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { if (dev->ctrl & ACR_DMA_EN) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* No DMA, do PIO. */ dev->status |= (ASR_DATA_REQ | ASR_DIR); @@ -852,7 +836,7 @@ do_send: } } dev->state = STATE_SDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_SDONE: @@ -880,7 +864,6 @@ do_send: } break; - case CMD_READ_EXT: /* READ_EXT */ case CMD_READ_ID: /* READ_ID */ if (!drive->present) { dev->ssb.not_ready = 1; @@ -888,6 +871,56 @@ do_send: return; } + switch (dev->state) { + case STATE_IDLE: + /* Seek to cylinder if requested. */ + if (ccb->auto_seek) { + if (do_seek(dev, drive, + (ccb->cyl_low | (ccb->cyl_high << 8)))) { + do_finish(dev); + return; + } + } + dev->head = ccb->head; + + /* Get sector count and size. */ + dev->count = (int) ccb->count; + dev->buf_len = (128 << dev->ssb.sect_size); + + /* Activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 1); + + /* Ready to transfer the data out. */ + dev->state = STATE_SDONE; + dev->buf_idx = 0; + /* Delay a bit, no actual transfer. */ + timer_advance_u64(&dev->timer, HDC_TIME); + break; + + case STATE_SDONE: + dev->buf_idx = 0; + + /* De-activate the status icon. */ + ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); + + if (!(dev->ctrl & ACR_DMA_EN)) + dev->status &= ~(ASR_DATA_REQ | ASR_DIR); + dev->ssb.cmd_syndrome = 0x14; + do_finish(dev); + break; + + default: + break; + } + break; + + case CMD_READ_EXT: /* READ_EXT */ + if (!drive->present) { + dev->ssb.not_ready = 1; + do_finish(dev); + return; + } + dev->intstat |= ISR_INVALID_CMD; do_finish(dev); break; @@ -943,12 +976,12 @@ do_recv: dev->buf_idx = 0; if (no_data) { /* Delay a bit, no actual transfer. */ - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { if (dev->ctrl & ACR_DMA_EN) { /* DMA enabled. */ dev->buf_ptr = dev->sector_buf; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); } else { /* No DMA, do PIO. */ dev->buf_ptr = dev->data; @@ -978,7 +1011,7 @@ do_recv: } } dev->state = STATE_RDONE; - hdc_set_callback(dev, HDC_TIME); + timer_advance_u64(&dev->timer, HDC_TIME); break; case STATE_RDONE: @@ -1140,6 +1173,8 @@ hdc_read(uint16_t port, void *priv) break; } + ps1_hdc_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + return ret; } @@ -1148,6 +1183,8 @@ hdc_write(uint16_t port, uint8_t val, void *priv) { hdc_t *dev = (hdc_t *) priv; + ps1_hdc_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + /* TRM: tell system board we are alive. */ *dev->reg_91 |= 0x01; @@ -1164,6 +1201,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) /* Store the data into the buffer. */ dev->buf_ptr[dev->buf_idx] = val; + ps1_hdc_log("dev->buf_ptr[%02X] = %02X\n", dev->buf_idx, val); if (++dev->buf_idx == dev->buf_len) { /* We got all the data we need. */ dev->status &= ~ASR_DATA_REQ; @@ -1182,7 +1220,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) dev->status |= ASR_BUSY; /* Schedule command execution. */ - hdc_set_callback(dev, HDC_TIME); + timer_set_delay_u64(&dev->timer, HDC_TIME); } } } From 4325d6103cd8b8479458f4eb1ec5324e5a8bfca4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 20 Aug 2023 21:22:02 +0200 Subject: [PATCH 23/30] Compaq Deskpro 386 1988 BIOS ROM changed to the May 1988 due to malformed status of the January 1988 one. --- src/include/86box/machine.h | 2 +- src/machine/m_at_compaq.c | 10 +++++----- src/machine/machine_table.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 1f9ed480f..62da55c9b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -560,7 +560,7 @@ extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_portableiii386_init(const machine_t *); extern int machine_at_deskpro386_init(const machine_t *); -extern int machine_at_deskpro386_01_1988_init(const machine_t *); +extern int machine_at_deskpro386_05_1988_init(const machine_t *); /* m_at_socket4.c */ extern void machine_at_premiere_common_init(const machine_t *, int); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index fe1236ed8..1d208dea2 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -52,7 +52,7 @@ enum { COMPAQ_PORTABLEIII, COMPAQ_PORTABLEIII386, COMPAQ_DESKPRO386, - COMPAQ_DESKPRO386_01_1988 + COMPAQ_DESKPRO386_05_1988 }; #define CGA_RGB 0 @@ -829,7 +829,7 @@ machine_at_compaq_init(const machine_t *model, int type) break; case COMPAQ_DESKPRO386: - case COMPAQ_DESKPRO386_01_1988: + case COMPAQ_DESKPRO386_05_1988: if (hdc_current == 1) device_add(&ide_isa_device); device_add(&compaq_386_device); @@ -909,17 +909,17 @@ machine_at_deskpro386_init(const machine_t *model) } int -machine_at_deskpro386_01_1988_init(const machine_t *model) +machine_at_deskpro386_05_1988_init(const machine_t *model) { int ret; - ret = bios_load_linearr("roms/machines/deskpro386/1988-01-28.json.bin", + ret = bios_load_linearr("roms/machines/deskpro386/1988-05-10.json.bin", 0x000f8000, 65536, 0); if (bios_only || !ret) return ret; - machine_at_compaq_init(model, COMPAQ_DESKPRO386_01_1988); + machine_at_compaq_init(model, COMPAQ_DESKPRO386_05_1988); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 899284318..a1fa60f7d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4708,11 +4708,11 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[ISA] Compaq Deskpro 386 (January 1988)", - .internal_name = "deskpro386_01_1988", + .name = "[ISA] Compaq Deskpro 386 (May 1988)", + .internal_name = "deskpro386_05_1988", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_deskpro386_01_1988_init, + .init = machine_at_deskpro386_05_1988_init, .pad = 0, .pad0 = 0, .pad1 = MACHINE_AVAILABLE, From 1d48363803d532946848276ef587aa180a8bdd5b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 02:56:33 +0200 Subject: [PATCH 24/30] The 286/386 interpreter now has its own variant of x86seg.c. --- src/codegen/codegen_ops.c | 2 + src/codegen/codegen_x86-64.c | 2 + src/codegen/codegen_x86.c | 2 + src/codegen_new/codegen.c | 2 + src/codegen_new/codegen_backend_arm.c | 2 + src/codegen_new/codegen_backend_arm64.c | 2 + src/codegen_new/codegen_backend_arm64_uops.c | 2 + src/codegen_new/codegen_backend_arm_uops.c | 2 + src/codegen_new/codegen_backend_x86-64.c | 2 + src/codegen_new/codegen_backend_x86-64_uops.c | 2 + src/codegen_new/codegen_backend_x86.c | 2 + src/codegen_new/codegen_backend_x86_uops.c | 2 + src/codegen_new/codegen_block.c | 2 + src/codegen_new/codegen_ops_3dnow.c | 2 + src/codegen_new/codegen_ops_arith.c | 2 + src/codegen_new/codegen_ops_branch.c | 2 + src/codegen_new/codegen_ops_fpu_arith.c | 2 + src/codegen_new/codegen_ops_fpu_constant.c | 2 + src/codegen_new/codegen_ops_fpu_loadstore.c | 2 + src/codegen_new/codegen_ops_fpu_misc.c | 2 + src/codegen_new/codegen_ops_helpers.c | 2 + src/codegen_new/codegen_ops_jump.c | 2 + src/codegen_new/codegen_ops_logic.c | 2 + src/codegen_new/codegen_ops_misc.c | 2 + src/codegen_new/codegen_ops_mmx_arith.c | 2 + src/codegen_new/codegen_ops_mmx_cmp.c | 2 + src/codegen_new/codegen_ops_mmx_loadstore.c | 2 + src/codegen_new/codegen_ops_mmx_logic.c | 2 + src/codegen_new/codegen_ops_mmx_pack.c | 2 + src/codegen_new/codegen_ops_mmx_shift.c | 2 + src/codegen_new/codegen_ops_mov.c | 2 + src/codegen_new/codegen_ops_shift.c | 2 + src/codegen_new/codegen_ops_stack.c | 2 + src/cpu/386.c | 10 +- src/cpu/386_common.c | 24 +- src/cpu/386_dynarec.c | 2 + src/cpu/386_dynarec_ops.c | 2 + src/cpu/386_ops.h | 1 - src/cpu/CMakeLists.txt | 3 +- src/cpu/codegen_timing_k6.c | 1 + src/cpu/codegen_timing_p6.c | 1 + src/cpu/cpu.c | 1 + src/cpu/cpu.h | 28 --- src/cpu/x86.c | 7 +- src/cpu/x86.h | 48 ++-- src/cpu/x86_ops_call.h | 48 ++-- src/cpu/x86_ops_jump.h | 4 +- src/cpu/x86_ops_mmx.c | 3 +- src/cpu/x86_ops_mov_seg.h | 44 ++-- src/cpu/x86_ops_ret.h | 30 +-- src/cpu/x86_ops_stack.h | 8 +- src/cpu/x86seg.c | 221 ++++++++---------- src/cpu/x86seg.h | 78 ++++++- src/cpu/x86seg_2386.c | 22 ++ src/cpu/x86seg_common.c | 124 ++++++++++ src/cpu/x86seg_common.h | 52 +++++ src/cpu/x87.c | 1 + src/cpu/x886seg_2386.c | 22 ++ src/device/kbc_at.c | 3 +- src/mem/mem.c | 1 + src/mem/mmu_2386.c | 1 + 61 files changed, 596 insertions(+), 260 deletions(-) create mode 100644 src/cpu/x86seg_2386.c create mode 100644 src/cpu/x86seg_common.c create mode 100644 src/cpu/x86seg_common.h create mode 100644 src/cpu/x886seg_2386.c diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index 894ebb100..801f83d7f 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -9,6 +9,8 @@ #include "x86.h" #include "x86_ops.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include "386_common.h" #include "cpu.h" diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index 3934b4ac5..38a353f55 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -11,6 +11,8 @@ # include "x86.h" # include "x86_flags.h" # include "x86_ops.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include <86box/mem.h> diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 712fbe087..68fc40f17 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -49,6 +49,8 @@ # include "x86.h" # include "x86_flags.h" # include "x86_ops.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" /*ex*/ # include <86box/nmi.h> diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index b0250fb7d..66d232357 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -6,6 +6,8 @@ #include "x86_ops.h" #include "codegen.h" #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c index a389f239f..50d1c6bf9 100644 --- a/src/codegen_new/codegen_backend_arm.c +++ b/src/codegen_new/codegen_backend_arm.c @@ -13,6 +13,8 @@ # include "codegen_backend_arm_ops.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # if defined(__linux__) || defined(__APPLE__) diff --git a/src/codegen_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c index 48d949406..0d7440013 100644 --- a/src/codegen_new/codegen_backend_arm64.c +++ b/src/codegen_new/codegen_backend_arm64.c @@ -13,6 +13,8 @@ # include "codegen_backend_arm64_ops.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # if defined(__linux__) || defined(__APPLE__) diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index a3a38ab22..c2fa6680b 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -6,6 +6,8 @@ # include <86box/mem.h> # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include "386_common.h" # include "codegen.h" diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index d0b8b86c1..0213f2e28 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -7,6 +7,8 @@ # include <86box/mem.h> # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include "386_common.h" # include "codegen.h" diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index a57cb4282..67355539b 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -14,6 +14,8 @@ # include "codegen_backend_x86-64_ops_sse.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # if defined(__linux__) || defined(__APPLE__) # include diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index e9c08cbc8..a5f9259f0 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -6,6 +6,8 @@ # include <86box/mem.h> # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "x87.h" # include "386_common.h" # include "codegen.h" diff --git a/src/codegen_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c index f656e708f..18235e2b2 100644 --- a/src/codegen_new/codegen_backend_x86.c +++ b/src/codegen_new/codegen_backend_x86.c @@ -15,6 +15,8 @@ # include "codegen_backend_x86_ops_sse.h" # include "codegen_reg.h" # include "x86.h" +# include "x86seg_common.h" +# include "x86seg.h" # if defined(__linux__) || defined(__APPLE__) # include diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 00ae453c3..470a6ac54 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -7,6 +7,8 @@ # include "x86.h" # include "x86_ops.h" +# include "x86seg_common.h" +# include "x86seg.h" # include "386_common.h" # include "codegen.h" # include "codegen_allocator.h" diff --git a/src/codegen_new/codegen_block.c b/src/codegen_new/codegen_block.c index 95e422408..d10f72353 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -9,6 +9,8 @@ #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include "386_common.h" diff --git a/src/codegen_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c index c2b04584c..75059d168 100644 --- a/src/codegen_new/codegen_ops_3dnow.c +++ b/src/codegen_new/codegen_ops_3dnow.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c index 5325b282b..a952811a4 100644 --- a/src/codegen_new/codegen_ops_arith.c +++ b/src/codegen_new/codegen_ops_arith.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c index 9a6722342..b2726b28b 100644 --- a/src/codegen_new/codegen_ops_branch.c +++ b/src/codegen_new/codegen_ops_branch.c @@ -4,6 +4,8 @@ #include <86box/mem.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x86_flags.h" #include "codegen.h" diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 98d77250c..e31f6281b 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index 89c138637..5ba787e24 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c index 06709913d..ec563cbbf 100644 --- a/src/codegen_new/codegen_ops_fpu_loadstore.c +++ b/src/codegen_new/codegen_ops_fpu_loadstore.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index cca9f4e4f..9524e62c0 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x87.h" #include "codegen.h" diff --git a/src/codegen_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c index 242cbb818..891780a90 100644 --- a/src/codegen_new/codegen_ops_helpers.c +++ b/src/codegen_new/codegen_ops_helpers.c @@ -4,6 +4,8 @@ #include <86box/mem.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c index 0bd4db24a..9118174e5 100644 --- a/src/codegen_new/codegen_ops_jump.c +++ b/src/codegen_new/codegen_ops_jump.c @@ -4,6 +4,8 @@ #include <86box/mem.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c index 6db452a45..6d79016e3 100644 --- a/src/codegen_new/codegen_ops_logic.c +++ b/src/codegen_new/codegen_ops_logic.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index 9a23536ed..84958eb82 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index b352c402a..2a176e374 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index c8d4909f9..4973ef486 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index a20e18e68..510956e36 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 664bfd14c..a7599334c 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 99016352e..40691e54c 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index 32449d188..64411ecb5 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -5,6 +5,8 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_accumulate.h" diff --git a/src/codegen_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c index 68e8fb011..1d1b7df99 100644 --- a/src/codegen_new/codegen_ops_mov.c +++ b/src/codegen_new/codegen_ops_mov.c @@ -4,6 +4,8 @@ #include <86box/mem.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_shift.c b/src/codegen_new/codegen_ops_shift.c index 8ccf7d9e7..a2444e541 100644 --- a/src/codegen_new/codegen_ops_shift.c +++ b/src/codegen_new/codegen_ops_shift.c @@ -4,6 +4,8 @@ #include <86box/mem.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x86_flags.h" #include "386_common.h" #include "codegen.h" diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index b7afdce25..3ad7219aa 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -4,6 +4,8 @@ #include <86box/mem.h> #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x86_flags.h" #include "386_common.h" #include "codegen.h" diff --git a/src/cpu/386.c b/src/cpu/386.c index 20b67ff89..1b255fe5f 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -14,6 +14,7 @@ #include "cpu.h" #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include <86box/io.h> #include <86box/nmi.h> @@ -28,6 +29,7 @@ #ifndef OPS_286_386 # define OPS_286_386 #endif +#include "x86seg.h" #include "386_common.h" #ifdef USE_NEW_DYNAREC # include "codegen.h" @@ -291,7 +293,7 @@ exec386_2386(int cycs) flags_rebuild(); tempi = cpu_state.abrt & ABRT_MASK; cpu_state.abrt = 0; - x86_doabrt(tempi); + x86_doabrt_2386(tempi); if (cpu_state.abrt) { cpu_state.abrt = 0; #ifndef USE_NEW_DYNAREC @@ -299,7 +301,7 @@ exec386_2386(int cycs) #endif cpu_state.pc = cpu_state.oldpc; x386_log("Double fault\n"); - pmodeint(8, 0); + pmodeint_2386(8, 0); if (cpu_state.abrt) { cpu_state.abrt = 0; softresetx86(); @@ -342,7 +344,7 @@ exec386_2386(int cycs) if (vector != -1) { flags_rebuild(); if (msw & 1) - pmodeint(vector, 0); + pmodeint_2386(vector, 0); else { writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); writememw(ss, (SP - 4) & 0xFFFF, CS); @@ -352,7 +354,7 @@ exec386_2386(int cycs) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + loadcs_2386(readmemw(0, addr + 2)); } } } diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 5c6b43980..60ecd8954 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -13,6 +13,7 @@ #include "cpu.h" #include <86box/timer.h> #include "x86.h" +#include "x86seg_common.h" #include "x87.h" #include <86box/nmi.h> #include <86box/mem.h> @@ -23,9 +24,10 @@ #include <86box/fdc.h> #include <86box/keyboard.h> #include <86box/timer.h> + +#include "x86seg.h" #include "386_common.h" #include "x86_flags.h" -#include "x86seg.h" #include <86box/plat_unused.h> #ifdef USE_DYNAREC @@ -1184,7 +1186,10 @@ enter_smm(int in_hlt) if (is_cxsmm) { cpu_state.pc = 0x0000; cpl_override = 1; - cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + if (is486) + cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + else + cyrix_write_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs); cpl_override = 0; cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); cpu_state.seg_cs.base = cyrix.arr[3].base; @@ -1317,7 +1322,10 @@ leave_smm(void) saved_state[3] = readmeml(0, smram_state - 0x10); saved_state[4] = readmeml(0, smram_state - 0x14); saved_state[5] = readmeml(0, smram_state - 0x18); - cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + if (is486) + cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + else + cyrix_load_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs); saved_state[6] = readmeml(0, smram_state - 0x24); } else { for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { @@ -1403,7 +1411,7 @@ x86_int(int num) cpu_state.pc = cpu_state.oldpc; if (msw & 1) - pmodeint(num, 0); + is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0); else { addr = (num << 2) + idt.base; @@ -1436,7 +1444,7 @@ x86_int(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); } } @@ -1453,7 +1461,7 @@ x86_int_sw(int num) cycles -= timing_int; if (msw & 1) - pmodeint(num, 1); + is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1); else { addr = (num << 2) + idt.base; @@ -1478,7 +1486,7 @@ x86_int_sw(int num) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2)); cycles -= timing_int_rm; } } @@ -1520,7 +1528,7 @@ x86_int_sw_rm(int num) cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; - loadcs(new_cs); + is486 ? loadcs(new_cs) : loadcs_2386(new_cs); #ifndef USE_NEW_DYNAREC oxpc = cpu_state.pc; #endif diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index ab01d28b8..f53b216de 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -17,6 +17,8 @@ #include "cpu.h" #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include <86box/io.h> #include <86box/mem.h> diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index f46062bcc..77b72ef59 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -13,6 +13,8 @@ #include <86box/timer.h> #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" +#include "x86seg.h" #include "x87.h" #include "x86_flags.h" #include <86box/io.h> diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index dc5eea606..8a0f4cd5a 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -173,7 +173,6 @@ extern void x386_dynarec_log(const char *fmt, ...); # endif #endif -#include "x86seg.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index e4d8e71b2..27e89c523 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -14,7 +14,8 @@ # add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c - 386_dynarec.c x86_ops_mmx.c x86seg.c x87.c x87_timings.c 8080.c) + 386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c + x87_timings.c 8080.c) if(AMD_K5) target_compile_definitions(cpu PRIVATE USE_AMD_K5) diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 88215bb17..4a9f23cd8 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -11,6 +11,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include "386_common.h" #include "codegen.h" diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index 008e36594..2c087ae86 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -12,6 +12,7 @@ #include "x86.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include "386_common.h" #include "codegen.h" diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 42ad8aa70..0f12cf773 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -33,6 +33,7 @@ #include <86box/machine.h> #include <86box/io.h> #include "x86_ops.h" +#include "x86seg_common.h" #include <86box/mem.h> #include <86box/nmi.h> #include <86box/pic.h> diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 7fdfcb3d4..66ccc05c9 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -590,7 +590,6 @@ extern uint64_t cpu_CR4_mask; extern uint64_t tsc; extern msr_t msr; extern uint8_t opcode; -extern int cgate16; extern int cpl_override; extern int CPUID; extern uint64_t xt_cpu_multi; @@ -721,15 +720,6 @@ extern uint32_t cpu_fast_off_flags; /* Functions. */ extern int cpu_has_feature(int feature); -#ifdef USE_NEW_DYNAREC -extern void loadseg_dynarec(uint16_t seg, x86seg *s); -extern int loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); -#else -extern void loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); -#endif - extern char *cpu_current_pc(char *bufp); extern void cpu_update_waitstates(void); @@ -757,19 +747,6 @@ extern void exec386_2386(int cycs); extern void exec386(int cycs); extern void exec386_dynarec(int cycs); extern int idivl(int32_t val); -#ifdef USE_NEW_DYNAREC -extern void loadcscall(uint16_t seg, uint32_t old_pc); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); -#else -extern void loadcscall(uint16_t seg); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); -#endif extern void resetmcr(void); extern void resetx86(void); extern void refreshread(void); @@ -779,11 +756,6 @@ extern void hardresetx86(void); extern void x86_int(int num); extern void x86_int_sw(int num); extern int x86_int_sw_rm(int num); -extern void x86de(char *s, uint16_t error); -extern void x86gpf(char *s, uint16_t error); -extern void x86np(char *s, uint16_t error); -extern void x86ss(char *s, uint16_t error); -extern void x86ts(char *s, uint16_t error); #ifdef ENABLE_808X_LOG extern void dumpregs(int __force); diff --git a/src/cpu/x86.c b/src/cpu/x86.c index f994e1946..328ab8887 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -25,6 +25,8 @@ #include <86box/86box.h> #include "cpu.h" #include "x86.h" +#include "x86seg_common.h" +#include "x86seg.h" #include <86box/machine.h> #include <86box/device.h> #include <86box/dma.h> @@ -270,7 +272,10 @@ reset_common(int hard) cpu_state.eflags = 0; cgate32 = 0; if (is286) { - loadcs(0xF000); + if (is486) + loadcs(0xF000); + else + loadcs_2386(0xF000); cpu_state.pc = 0xFFF0; if (hard) { rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; diff --git a/src/cpu/x86.h b/src/cpu/x86.h index 77d9329fe..5736dc665 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -1,3 +1,26 @@ +/* + * 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. + * + * Second CPU header. + * + * + * + * Authors: Sarah Walker, + * leilei, + * Miran Grca, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2018 leilei. + * Copyright 2016-2020 Miran Grca. + */ +#ifndef EMU_X86_H +#define EMU_X86_H + #define ABRT_MASK 0x3f /*An 'expected' exception is one that would be expected to occur on every execution of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is @@ -10,7 +33,7 @@ #define ABRT_EXPECTED 0x80 extern uint8_t opcode; -extern uint8_t opcode2; + extern uint8_t flags_p; extern uint8_t znptable8[256]; @@ -31,7 +54,6 @@ extern int trap; extern int optype; extern int stack32; extern int oldcpl; -extern int cgate32; extern int cpl_override; extern int nmi_enable; extern int oddeven; @@ -75,24 +97,6 @@ extern uint32_t *eal_w; fetcheal(); \ } -#define JMP 1 -#define CALL 2 -#define IRET 3 -#define OPTYPE_INT 4 - -enum { - ABRT_NONE = 0, - ABRT_GEN = 1, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE, - ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ -}; - -extern void x86_doabrt(int x86_abrt); extern void x86illegal(void); -extern void x86seg_reset(void); -extern void x86gpf(char *s, uint16_t error); -extern void x86gpf_expected(char *s, uint16_t error); + +#endif /*EMU_X86_H*/ diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 731f58ec8..9d52a2764 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -6,9 +6,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg, old_pc); \ + op_loadcscall(new_seg, old_pc); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -54,9 +54,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg, old_pc); \ + op_loadcscall(new_seg, old_pc); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -103,9 +103,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg); \ + op_loadcscall(new_seg); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -148,9 +148,9 @@ optype = CALL; \ cgate16 = cgate32 = 0; \ if (msw & 1) \ - loadcscall(new_seg); \ + op_loadcscall(new_seg); \ else { \ - loadcs(new_seg); \ + op_loadcs(new_seg); \ cycles -= timing_call_rm; \ } \ optype = 0; \ @@ -362,14 +362,12 @@ opFF_w_a16(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0); PREFETCH_FLUSH(); @@ -526,14 +524,12 @@ opFF_w_a32(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1); PREFETCH_FLUSH(); @@ -691,14 +687,12 @@ opFF_l_a16(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0); PREFETCH_FLUSH(); @@ -857,14 +851,12 @@ opFF_l_a32(uint32_t fetchdat) return 1; cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); - if (cpu_state.abrt) - return 1; + op_loadcsjmp(new_cs, old_pc); #else - loadcsjmp(new_cs, oxpc); + op_loadcsjmp(new_cs, oxpc); +#endif if (cpu_state.abrt) return 1; -#endif CPU_BLOCK_END(); PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); PREFETCH_FLUSH(); diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 091e0da35..97ca673d7 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -282,7 +282,7 @@ opJMP_far_a16(uint32_t fetchdat) return 1; old_pc = cpu_state.pc; cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + op_loadcsjmp(seg, old_pc); CPU_BLOCK_END(); PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0); PREFETCH_FLUSH(); @@ -301,7 +301,7 @@ opJMP_far_a32(uint32_t fetchdat) return 1; old_pc = cpu_state.pc; cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + op_loadcsjmp(seg, old_pc); CPU_BLOCK_END(); PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0); PREFETCH_FLUSH(); diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c index 6d4dd5557..f26c903f9 100644 --- a/src/cpu/x86_ops_mmx.c +++ b/src/cpu/x86_ops_mmx.c @@ -23,9 +23,10 @@ #include <86box/fdc.h> #include <86box/keyboard.h> #include <86box/timer.h> +#include "x86seg_common.h" +#include "x86seg.h" #include "386_common.h" #include "x86_flags.h" -#include "x86seg.h" MMX_REG *MMP[8]; uint16_t *MMEP[8]; diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 2498a7d90..2a798db5c 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -178,13 +178,13 @@ opMOV_seg_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); + op_loadseg(new_seg, &cpu_state.seg_es); break; case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); + op_loadseg(new_seg, &cpu_state.seg_ds); break; case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); + op_loadseg(new_seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.oldpc = cpu_state.pc; @@ -198,10 +198,10 @@ opMOV_seg_w_a16(uint32_t fetchdat) x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); return 1; case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); + op_loadseg(new_seg, &cpu_state.seg_fs); break; case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); + op_loadseg(new_seg, &cpu_state.seg_gs); break; } @@ -223,13 +223,13 @@ opMOV_seg_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); + op_loadseg(new_seg, &cpu_state.seg_es); break; case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); + op_loadseg(new_seg, &cpu_state.seg_ds); break; case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); + op_loadseg(new_seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.oldpc = cpu_state.pc; @@ -243,10 +243,10 @@ opMOV_seg_w_a32(uint32_t fetchdat) x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); return 1; case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); + op_loadseg(new_seg, &cpu_state.seg_fs); break; case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); + op_loadseg(new_seg, &cpu_state.seg_gs); break; } @@ -269,7 +269,7 @@ opLDS_w_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -292,7 +292,7 @@ opLDS_w_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -315,7 +315,7 @@ opLDS_l_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -338,7 +338,7 @@ opLDS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); + op_loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -362,7 +362,7 @@ opLSS_w_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -385,7 +385,7 @@ opLSS_w_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; @@ -408,7 +408,7 @@ opLSS_l_a16(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -431,7 +431,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); + op_loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; @@ -454,7 +454,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].w = addr; \ @@ -476,7 +476,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 2); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].w = addr; \ @@ -499,7 +499,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].l = addr; \ @@ -522,7 +522,7 @@ opLSS_l_a32(uint32_t fetchdat) seg = readmemw(easeg, cpu_state.eaaddr + 4); \ if (cpu_state.abrt) \ return 1; \ - loadseg(seg, &sel); \ + op_loadseg(seg, &sel); \ if (cpu_state.abrt) \ return 1; \ cpu_state.regs[cpu_reg].l = addr; \ diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 64da566d3..0d9a6370b 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -6,16 +6,16 @@ #define RETF_a16(stack_offset) \ if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ - pmoderetf(0, stack_offset); \ + op_pmoderetf(0, stack_offset); \ return 1; \ } \ CPU_SET_OXPC \ if (stack32) { \ cpu_state.pc = readmemw(ss, ESP); \ - loadcs(readmemw(ss, ESP + 2)); \ + op_loadcs(readmemw(ss, ESP + 2)); \ } else { \ cpu_state.pc = readmemw(ss, SP); \ - loadcs(readmemw(ss, SP + 2)); \ + op_loadcs(readmemw(ss, SP + 2)); \ } \ if (cpu_state.abrt) \ return 1; \ @@ -27,16 +27,16 @@ #define RETF_a32(stack_offset) \ if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ - pmoderetf(1, stack_offset); \ + op_pmoderetf(1, stack_offset); \ return 1; \ } \ CPU_SET_OXPC \ if (stack32) { \ cpu_state.pc = readmeml(ss, ESP); \ - loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \ } else { \ cpu_state.pc = readmeml(ss, SP); \ - loadcs(readmeml(ss, SP + 4) & 0xffff); \ + op_loadcs(readmeml(ss, SP + 4) & 0xffff); \ } \ if (cpu_state.abrt) \ return 1; \ @@ -114,7 +114,7 @@ opIRET_186(uint32_t fetchdat) } if (msw & 1) { optype = IRET; - pmodeiret(0); + op_pmodeiret(0); optype = 0; } else { uint16_t new_cs; @@ -130,7 +130,7 @@ opIRET_186(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; SP += 6; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } flags_extract(); @@ -154,7 +154,7 @@ opIRET_286(uint32_t fetchdat) } if (msw & 1) { optype = IRET; - pmodeiret(0); + op_pmodeiret(0); optype = 0; } else { uint16_t new_cs; @@ -170,7 +170,7 @@ opIRET_286(uint32_t fetchdat) cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; SP += 6; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } flags_extract(); @@ -210,7 +210,7 @@ opIRET(uint32_t fetchdat) else cpu_state.eflags &= ~VIF_FLAG; cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); + op_loadcs(new_cs); cpu_state.pc = new_pc; cycles -= timing_iret_rm; @@ -221,7 +221,7 @@ opIRET(uint32_t fetchdat) } else { if (msw & 1) { optype = IRET; - pmodeiret(0); + op_pmodeiret(0); optype = 0; } else { uint16_t new_cs; @@ -237,7 +237,7 @@ opIRET(uint32_t fetchdat) cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; SP += 6; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } } @@ -262,7 +262,7 @@ opIRETD(uint32_t fetchdat) } if (msw & 1) { optype = IRET; - pmodeiret(1); + op_pmodeiret(1); optype = 0; } else { uint16_t new_cs; @@ -280,7 +280,7 @@ opIRETD(uint32_t fetchdat) cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); SP += 12; } - loadcs(new_cs); + op_loadcs(new_cs); cycles -= timing_iret_rm; } flags_extract(); diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 8fa66e082..13eb883d3 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -610,7 +610,7 @@ opLEAVE_l(uint32_t fetchdat) temp_seg = POP_W(); \ if (cpu_state.abrt) \ return 1; \ - loadseg(temp_seg, realseg); \ + op_loadseg(temp_seg, realseg); \ if (cpu_state.abrt) \ ESP = temp_esp; \ CLOCK_CYCLES(is486 ? 3 : 7); \ @@ -624,7 +624,7 @@ opLEAVE_l(uint32_t fetchdat) temp_seg = POP_L(); \ if (cpu_state.abrt) \ return 1; \ - loadseg(temp_seg & 0xffff, realseg); \ + op_loadseg(temp_seg & 0xffff, realseg); \ if (cpu_state.abrt) \ ESP = temp_esp; \ CLOCK_CYCLES(is486 ? 3 : 7); \ @@ -651,7 +651,7 @@ opPOP_SS_w(uint32_t fetchdat) temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); + op_loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; @@ -679,7 +679,7 @@ opPOP_SS_l(uint32_t fetchdat) temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); + op_loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 3c4847a36..eaa63f846 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -36,17 +36,25 @@ #include "x86.h" #include "x86_flags.h" +#include "x86seg.h" +#include "x86seg_common.h" #include "386_common.h" -uint8_t opcode2; - -int cgate16; -int cgate32; -int intgatesize; - -void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); - -void pmodeint(int num, int soft); +#ifdef OPS_286_386 +#define seg_readmembl readmembl_2386 +#define seg_readmemwl readmemwl_2386 +#define seg_readmemll readmemll_2386 +#define seg_writemembl writemembl_2386 +#define seg_writememwl writememwl_2386 +#define seg_writememll writememll_2386 +#else +#define seg_readmembl readmembl_2386 +#define seg_readmemwl readmemwl_2386 +#define seg_readmemll readmemll_2386 +#define seg_writemembl writemembl_2386 +#define seg_writememwl writememwl_2386 +#define seg_writememll writememll_2386 +#endif #define DPL ((segdat[2] >> 13) & 3) #define DPL2 ((segdat2[2] >> 13) & 3) @@ -70,41 +78,12 @@ x86seg_log(const char *fmt, ...) # define x86seg_log(fmt, ...) #endif -static void -seg_reset(x86seg *s) -{ - s->access = 0x82; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; - s->limit_high = 0xffff; - if (s == &cpu_state.seg_cs) { - if (!cpu_inited) - fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); - if (is6117) - s->base = 0x03ff0000; - else - s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; - s->seg = is286 ? 0xf000 : 0xffff; - } else { - s->base = 0; - s->seg = 0; - } -} - -void -x86seg_reset(void) -{ - seg_reset(&cpu_state.seg_cs); - seg_reset(&cpu_state.seg_ds); - seg_reset(&cpu_state.seg_es); - seg_reset(&cpu_state.seg_fs); - seg_reset(&cpu_state.seg_gs); - seg_reset(&cpu_state.seg_ss); -} - void +#ifdef OPS_286_386 +x86_doabrt_2386(int x86_abrt) +#else x86_doabrt(int x86_abrt) +#endif { #ifndef USE_NEW_DYNAREC CS = oldcs; @@ -114,7 +93,7 @@ x86_doabrt(int x86_abrt) cpu_state.seg_cs.ar_high = 0x10; if (msw & 1) - pmodeint(x86_abrt, 0); + op_pmodeint(x86_abrt, 0); else { uint32_t addr = (x86_abrt << 2) + idt.base; if (stack32) { @@ -134,7 +113,7 @@ x86_doabrt(int x86_abrt) oxpc = cpu_state.pc; #endif cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); + op_loadcs(readmemw(0, addr + 2)); return; } @@ -160,52 +139,6 @@ x86_doabrt(int x86_abrt) } } -void -x86de(UNUSED(char *s), UNUSED(uint16_t error)) -{ -#ifdef BAD_CODE - cpu_state.abrt = ABRT_DE; - abrt_error = error; -#else - x86_int(0); -#endif -} - -void -x86gpf(UNUSED(char *s), uint16_t error) -{ - cpu_state.abrt = ABRT_GPF; - abrt_error = error; -} - -void -x86gpf_expected(UNUSED(char *s), uint16_t error) -{ - cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; - abrt_error = error; -} - -void -x86ss(UNUSED(char *s), uint16_t error) -{ - cpu_state.abrt = ABRT_SS; - abrt_error = error; -} - -void -x86ts(UNUSED(char *s), uint16_t error) -{ - cpu_state.abrt = ABRT_TS; - abrt_error = error; -} - -void -x86np(UNUSED(char *s), uint16_t error) -{ - cpu_state.abrt = ABRT_NP; - abrt_error = error; -} - static void set_stack32(int s) { @@ -228,6 +161,7 @@ set_use32(int u) cpu_cur_status &= ~CPU_STATUS_USE32; } +#ifndef OPS_286_386 void do_seg_load(x86seg *s, uint16_t *segdat) { @@ -262,6 +196,7 @@ do_seg_load(x86seg *s, uint16_t *segdat) cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } +#endif static void do_seg_v86_init(x86seg *s) @@ -310,7 +245,7 @@ check_seg_valid(x86seg *s) } if (!valid) - loadseg(0, s); + op_loadseg(0, s); } static void @@ -336,7 +271,11 @@ int #else void #endif +#ifdef OPS_286_386 +loadseg_2386(uint16_t seg, x86seg *s) +#else loadseg(uint16_t seg, x86seg *s) +#endif { uint16_t segdat[4]; uint32_t addr; @@ -534,7 +473,11 @@ loadseg(uint16_t seg, x86seg *s) } void +#ifdef OPS_286_386 +loadcs_2386(uint16_t seg) +#else loadcs(uint16_t seg) +#endif { uint16_t segdat[4]; uint32_t addr; @@ -623,7 +566,11 @@ loadcs(uint16_t seg) } void +#ifdef OPS_286_386 +loadcsjmp_2386(uint16_t seg, uint32_t old_pc) +#else loadcsjmp(uint16_t seg, uint32_t old_pc) +#endif { uint16_t type; uint16_t seg2; @@ -783,7 +730,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) cpu_state.pc = old_pc; optype = JMP; cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x800); + op_taskswitch286(seg, segdat, segdat[2] & 0x800); cpu_state.flags &= ~NT_FLAG; cpl_override = 0; return; @@ -810,7 +757,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) } } -void +static void PUSHW(uint16_t v) { if (stack32) { @@ -826,7 +773,7 @@ PUSHW(uint16_t v) } } -void +static void PUSHL(uint32_t v) { if (cpu_16bitbus) { @@ -847,7 +794,7 @@ PUSHL(uint32_t v) } } -uint16_t +static uint16_t POPW(void) { uint16_t tempw; @@ -865,7 +812,7 @@ POPW(void) return tempw; } -uint32_t +static uint32_t POPL(void) { uint32_t templ; @@ -890,6 +837,15 @@ POPL(void) return templ; } +#ifdef OPS_286_386 +#ifdef USE_NEW_DYNAREC +void +loadcscall_2386(uint16_t seg, uint32_t old_pc) +#else +void +loadcscall_2386(uint16_t seg) +#endif +#else #ifdef USE_NEW_DYNAREC void loadcscall(uint16_t seg, uint32_t old_pc) @@ -897,6 +853,7 @@ loadcscall(uint16_t seg, uint32_t old_pc) void loadcscall(uint16_t seg) #endif +#endif { uint16_t seg2; uint16_t newss; @@ -1225,7 +1182,7 @@ loadcscall(uint16_t seg) cpu_state.pc = oxpc; #endif cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x0800); + op_taskswitch286(seg, segdat, segdat[2] & 0x0800); cpl_override = 0; break; @@ -1251,7 +1208,11 @@ loadcscall(uint16_t seg) } void +#ifdef OPS_286_386 +pmoderetf_2386(int is32, uint16_t off) +#else pmoderetf(int is32, uint16_t off) +#endif { uint16_t segdat[4]; uint16_t segdat2[4]; @@ -1487,7 +1448,11 @@ pmoderetf(int is32, uint16_t off) } void +#ifdef OPS_286_386 +pmodeint_2386(int num, int soft) +#else pmodeint(int num, int soft) +#endif { uint16_t segdat[4]; uint16_t segdat2[4]; @@ -1518,7 +1483,7 @@ pmodeint(int num, int soft) softresetx86(); cpu_set_edx(); } else if (num == 0x0d) - pmodeint(8, 0); + op_pmodeint(8, 0); else x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); x86seg_log("addr >= IDT.limit\n"); @@ -1659,10 +1624,10 @@ pmodeint(int num, int soft) PUSHL(ES); if (cpu_state.abrt) return; - loadseg(0, &cpu_state.seg_ds); - loadseg(0, &cpu_state.seg_es); - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); + op_loadseg(0, &cpu_state.seg_ds); + op_loadseg(0, &cpu_state.seg_es); + op_loadseg(0, &cpu_state.seg_fs); + op_loadseg(0, &cpu_state.seg_gs); } PUSHL(oldss); PUSHL(oldsp); @@ -1764,7 +1729,7 @@ pmodeint(int num, int soft) } optype = OPTYPE_INT; cpl_override = 1; - taskswitch286(seg, segdat2, segdat2[2] & 0x0800); + op_taskswitch286(seg, segdat2, segdat2[2] & 0x0800); cpl_override = 0; break; @@ -1775,7 +1740,11 @@ pmodeint(int num, int soft) } void +#ifdef OPS_286_386 +pmodeiret_2386(int is32) +#else pmodeiret(int is32) +#endif { uint16_t newss; uint16_t seg = 0; @@ -1842,7 +1811,7 @@ pmodeiret(int is32) } cpl_override = 1; read_descriptor(addr, segdat, segdat32, 1); - taskswitch286(seg, segdat, segdat[2] & 0x0800); + op_taskswitch286(seg, segdat, segdat[2] & 0x0800); cpl_override = 0; return; } @@ -1876,14 +1845,14 @@ pmodeiret(int is32) } cpu_state.eflags = tempflags >> 16; cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0], &cpu_state.seg_es); + op_loadseg(segs[0], &cpu_state.seg_es); do_seg_v86_init(&cpu_state.seg_es); - loadseg(segs[1], &cpu_state.seg_ds); + op_loadseg(segs[1], &cpu_state.seg_ds); do_seg_v86_init(&cpu_state.seg_ds); cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2], &cpu_state.seg_fs); + op_loadseg(segs[2], &cpu_state.seg_fs); do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3], &cpu_state.seg_gs); + op_loadseg(segs[3], &cpu_state.seg_gs); do_seg_v86_init(&cpu_state.seg_gs); cpu_state.pc = newpc & 0xffff; @@ -1901,7 +1870,7 @@ pmodeiret(int is32) #endif ESP = newsp; - loadseg(newss, &cpu_state.seg_ss); + op_loadseg(newss, &cpu_state.seg_ss); do_seg_v86_init(&cpu_state.seg_ss); cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32 = 0; @@ -2088,7 +2057,11 @@ pmodeiret(int is32) } void +#ifdef OPS_286_386 +taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32) +#else taskswitch286(uint16_t seg, uint16_t *segdat, int is32) +#endif { uint16_t tempw; uint16_t new_ldt; @@ -2235,7 +2208,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); if (cpu_state.eflags & VM_FLAG) { - loadcs(new_cs); + op_loadcs(new_cs); set_use32(0); cpu_cur_status |= CPU_STATUS_V86; } else { @@ -2299,11 +2272,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ESI = new_esi; EDI = new_edi; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); - loadseg(new_fs, &cpu_state.seg_fs); - loadseg(new_gs, &cpu_state.seg_gs); + op_loadseg(new_es, &cpu_state.seg_es); + op_loadseg(new_ss, &cpu_state.seg_ss); + op_loadseg(new_ds, &cpu_state.seg_ds); + op_loadseg(new_fs, &cpu_state.seg_fs); + op_loadseg(new_gs, &cpu_state.seg_gs); } else { if (limit < 43) { x86ts(NULL, seg); @@ -2465,12 +2438,12 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ESI = new_esi | 0xffff0000; EDI = new_edi | 0xffff0000; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); + op_loadseg(new_es, &cpu_state.seg_es); + op_loadseg(new_ss, &cpu_state.seg_ss); + op_loadseg(new_ds, &cpu_state.seg_ds); if (is386) { - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); + op_loadseg(0, &cpu_state.seg_fs); + op_loadseg(0, &cpu_state.seg_gs); } } @@ -2482,7 +2455,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } void +#ifdef OPS_286_386 +cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg) +#else cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) +#endif { uint32_t limit_raw = seg->limit; @@ -2494,7 +2471,11 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) } void +#ifdef OPS_286_386 +cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg) +#else cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) +#endif { uint16_t segdat[4]; uint16_t selector; diff --git a/src/cpu/x86seg.h b/src/cpu/x86seg.h index 715251f2d..dcc8c9ef8 100644 --- a/src/cpu/x86seg.h +++ b/src/cpu/x86seg.h @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * x86 CPU segment emulation. + * x86 CPU segment emulation header. * * * @@ -14,8 +14,82 @@ * * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_X86SEG_H +#define EMU_X86SEG_H -extern void do_seg_load(x86seg *s, uint16_t *segdat); +#ifdef OPS_286_386 + +extern void x86_doabrt_2386(int x86_abrt); +#ifdef USE_NEW_DYNAREC +extern int loadseg_2386(uint16_t seg, x86seg *s); +#else +extern void loadseg_2386(uint16_t seg, x86seg *s); +#endif +extern void loadcs_2386(uint16_t seg); +extern void loadcsjmp_2386(uint16_t seg, uint32_t old_pc); +#ifdef USE_NEW_DYNAREC +extern void loadcscall_2386(uint16_t seg, uint32_t old_pc); +#else +extern void loadcscall_2386(uint16_t seg); +#endif +extern void pmoderetf_2386(int is32, uint16_t off); +extern void pmodeint_2386(int num, int soft); +extern void pmodeiret_2386(int is32); +extern void taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32); + +/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */ +#define op_doabrt x86_doabrt_2386 +#define op_loadseg loadseg_2386 +#define op_loadcs loadcs_2386 +#define op_loadcsjmp loadcsjmp_2386 +#define op_loadcscall loadcscall_2386 +#define op_pmoderetf pmoderetf_2386 +#define op_pmodeint pmodeint_2386 +#define op_pmodeiret pmodeiret_2386 +#define op_taskswitch taskswitch_2386 +#define op_taskswitch286 taskswitch286_2386 + +#else + +extern void x86_doabrt(int x86_abrt); +#ifdef USE_NEW_DYNAREC +extern int loadseg(uint16_t seg, x86seg *s); +#else +extern void loadseg(uint16_t seg, x86seg *s); +#endif +/* The prototype of loadcs_2386() is needed here for reset. */ +extern void loadcs_2386(uint16_t seg); +extern void loadcs(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +#ifdef USE_NEW_DYNAREC +extern void loadcscall(uint16_t seg, uint32_t old_pc); +#else +extern void loadcscall(uint16_t seg); +#endif +extern void pmoderetf(int is32, uint16_t off); +/* The prototype of pmodeint_2386() is needed here for 386_common.c interrupts. */ +extern void pmodeint_2386(int num, int soft); +extern void pmodeint(int num, int soft); +extern void pmodeiret(int is32); +extern void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); + +/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */ +#define op_doabrt x86_doabrt +#define op_loadseg loadseg +#define op_loadcs loadcs +#define op_loadcsjmp loadcsjmp +#define op_loadcscall loadcscall +#define op_pmoderetf pmoderetf +#define op_pmodeint pmodeint +#define op_pmodeiret pmodeiret +#define op_taskswitch286 taskswitch286 + +#endif + +extern void cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg); +extern void cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg); extern void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); extern void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg); + +#endif /*EMU_X86SEG_H*/ diff --git a/src/cpu/x86seg_2386.c b/src/cpu/x86seg_2386.c new file mode 100644 index 000000000..335c757e4 --- /dev/null +++ b/src/cpu/x86seg_2386.c @@ -0,0 +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. + * + * x86 CPU segment emulation for the 286/386 interpreter. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.c" diff --git a/src/cpu/x86seg_common.c b/src/cpu/x86seg_common.c new file mode 100644 index 000000000..1d27c5c66 --- /dev/null +++ b/src/cpu/x86seg_common.c @@ -0,0 +1,124 @@ +/* + * 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 commmon parts. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86.h" +#include "x86seg_common.h" +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + +uint8_t opcode2; + +int cgate16; +int cgate32; + +int intgatesize; + +static void +seg_reset(x86seg *s) +{ + s->access = 0x82; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; + s->limit_high = 0xffff; + if (s == &cpu_state.seg_cs) { + if (!cpu_inited) + fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); + if (is6117) + s->base = 0x03ff0000; + else + s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; + s->seg = is286 ? 0xf000 : 0xffff; + } else { + s->base = 0; + s->seg = 0; + } +} + +void +x86seg_reset(void) +{ + seg_reset(&cpu_state.seg_cs); + seg_reset(&cpu_state.seg_ds); + seg_reset(&cpu_state.seg_es); + seg_reset(&cpu_state.seg_fs); + seg_reset(&cpu_state.seg_gs); + seg_reset(&cpu_state.seg_ss); +} + +void +x86de(UNUSED(char *s), UNUSED(uint16_t error)) +{ +#ifdef BAD_CODE + cpu_state.abrt = ABRT_DE; + abrt_error = error; +#else + x86_int(0); +#endif +} + +void +x86gpf(UNUSED(char *s), uint16_t error) +{ + pclog("GPF %04X: %s\n", error, s); + cpu_state.abrt = ABRT_GPF; + abrt_error = error; +} + +void +x86gpf_expected(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; + abrt_error = error; +} + +void +x86ss(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_SS; + abrt_error = error; +} + +void +x86ts(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_TS; + abrt_error = error; +} + +void +x86np(UNUSED(char *s), uint16_t error) +{ + cpu_state.abrt = ABRT_NP; + abrt_error = error; +} diff --git a/src/cpu/x86seg_common.h b/src/cpu/x86seg_common.h new file mode 100644 index 000000000..f4bffed40 --- /dev/null +++ b/src/cpu/x86seg_common.h @@ -0,0 +1,52 @@ +/* + * 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 common parts header. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_X86SEG_COMMON_H +#define EMU_X86SEG_COMMON_H + +#define JMP 1 +#define CALL 2 +#define IRET 3 +#define OPTYPE_INT 4 + +enum { + ABRT_NONE = 0, + ABRT_GEN = 1, + ABRT_TS = 0xA, + ABRT_NP = 0xB, + ABRT_SS = 0xC, + ABRT_GPF = 0xD, + ABRT_PF = 0xE, + ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ +}; + +extern uint8_t opcode2; + +extern int cgate16; +extern int cgate32; + +extern int intgatesize; + +extern void x86seg_reset(void); +extern void x86de(char *s, uint16_t error); +extern void x86gpf(char *s, uint16_t error); +extern void x86gpf_expected(char *s, uint16_t error); +extern void x86np(char *s, uint16_t error); +extern void x86ss(char *s, uint16_t error); +extern void x86ts(char *s, uint16_t error); +extern void do_seg_load(x86seg *s, uint16_t *segdat); + +#endif /*EMU_X86SEG_COMMON_H*/ diff --git a/src/cpu/x87.c b/src/cpu/x87.c index c75dac569..1f7643453 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -13,6 +13,7 @@ #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" +#include "x86seg_common.h" #include "x87.h" #include "386_common.h" #include "softfloat/softfloat-specialize.h" diff --git a/src/cpu/x886seg_2386.c b/src/cpu/x886seg_2386.c new file mode 100644 index 000000000..335c757e4 --- /dev/null +++ b/src/cpu/x886seg_2386.c @@ -0,0 +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. + * + * x86 CPU segment emulation for the 286/386 interpreter. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#ifndef OPS_286_386 +# define OPS_286_386 +#endif +#include "x86seg.c" diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index f40c032c7..4a5911caf 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -25,6 +25,7 @@ #include #include <86box/86box.h> #include "cpu.h" +#include "x86seg.h" #include <86box/timer.h> #include <86box/io.h> #include <86box/pic.h> @@ -759,7 +760,7 @@ write_p2(atkbc_t *dev, uint8_t val) correctly despite A20 being gated when the CPU is reset, this will have to do. */ else if (kbc_ven == KBC_VEN_SIEMENS) - loadcs(0xF000); + is486 ? loadcs(0xf000) : loadcs_2386(0xf000); } } } diff --git a/src/mem/mem.c b/src/mem/mem.c index af80365e8..0b002b302 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -29,6 +29,7 @@ #include "cpu.h" #include "x86_ops.h" #include "x86.h" +#include "x86seg_common.h" #include <86box/machine.h> #include <86box/m_xt_xi8088.h> #include <86box/config.h> diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index d4fe49742..735c15592 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -29,6 +29,7 @@ #include "cpu.h" #include "x86_ops.h" #include "x86.h" +#include "x86seg_common.h" #include <86box/machine.h> #include <86box/m_xt_xi8088.h> #include <86box/config.h> From c273a81f8deb78a30eb0b47b0c6095ef6d138780 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 02:57:41 +0200 Subject: [PATCH 25/30] Updated win/Makefile.mingw. --- src/win/Makefile.mingw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b5cbfd9f7..7cb5ec3a7 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -577,7 +577,7 @@ CPUOBJ := $(DYNARECOBJ) \ $(CGTOBJ) \ cpu.o cpu_table.o fpu.o x86.o \ 8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ - x86_ops_mmx.o x86seg.o x87.o x87_timings.o \ + x86_ops_mmx.o x86seg_common.o x86seg_2386.o x86seg.o x87.o x87_timings.o \ f2xm1.o fpatan.o fprem.o fsincos.o fyl2x.o softfloat_poly.o softfloat.o softfloat16.o \ softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o From 5b4bc444cbe2325eb535fedc6823b97c9f96d4dd Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 03:00:56 +0200 Subject: [PATCH 26/30] Removed some excess logging from cpu/x86seg_common.c. --- src/cpu/x86seg_common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpu/x86seg_common.c b/src/cpu/x86seg_common.c index 1d27c5c66..8926af0d7 100644 --- a/src/cpu/x86seg_common.c +++ b/src/cpu/x86seg_common.c @@ -90,7 +90,6 @@ x86de(UNUSED(char *s), UNUSED(uint16_t error)) void x86gpf(UNUSED(char *s), uint16_t error) { - pclog("GPF %04X: %s\n", error, s); cpu_state.abrt = ABRT_GPF; abrt_error = error; } From 2ab8bdee0ead409fe16586503365e82f7a72fcae Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 05:41:37 +0200 Subject: [PATCH 27/30] Fixed Phoenix XT Clone and Tandy RAM detection, fixes #3219. --- src/machine/m_tandy.c | 26 ++++++++++++++++++++------ src/machine/m_xt.c | 4 +++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 5784eb4df..6cd1afde9 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -128,6 +128,7 @@ typedef struct tandy_t { int rom_offset; /* SL2 */ uint32_t base; + uint32_t mask; int is_sl2; t1kvid_t *vid; @@ -1319,8 +1320,19 @@ tandy_write(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x00a0: - mem_mapping_set_addr(&dev->ram_mapping, - ((val >> 1) & 7) * 128 * 1024, 0x20000); + if (val & 0x10) { + dev->base = (mem_size - 256) * 1024; + dev->mask = 0x3ffff; + mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); + mem_mapping_set_addr(&dev->ram_mapping, + ((val >> 1) & 7) * 128 * 1024, 0x40000); + } else { + dev->base = (mem_size - 128) * 1024; + dev->mask = 0x1ffff; + mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); + mem_mapping_set_addr(&dev->ram_mapping, + ((val >> 1) & 7) * 128 * 1024, 0x20000); + } dev->ram_bank = val; break; @@ -1378,7 +1390,7 @@ write_ram(uint32_t addr, uint8_t val, void *priv) { const tandy_t *dev = (tandy_t *) priv; - ram[dev->base + (addr & 0x1ffff)] = val; + ram[dev->base + (addr & dev->mask)] = val; } static uint8_t @@ -1386,7 +1398,7 @@ read_ram(uint32_t addr, void *priv) { const tandy_t *dev = (tandy_t *) priv; - return (ram[dev->base + (addr & 0x1ffff)]); + return (ram[dev->base + (addr & dev->mask)]); } static uint8_t @@ -1462,8 +1474,10 @@ machine_tandy1k_init(const machine_t *model, int type) * 0xFFE8 (SL2), so we remove it from the main mapping. */ dev->base = (mem_size - 128) * 1024; - mem_mapping_add(&dev->ram_mapping, 0x80000, 0x20000, - read_ram, NULL, NULL, write_ram, NULL, NULL, NULL, 0, dev); + dev->mask = 0x1ffff; + mem_mapping_add(&dev->ram_mapping, 0x60000, 0x20000, + read_ram, NULL, NULL, write_ram, NULL, NULL, NULL, + MEM_MAPPING_INTERNAL, dev); mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); device_add(&keyboard_tandy_device); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 84eb517c8..fe519c65b 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -310,7 +310,9 @@ machine_xt_pxxt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_xt_clone_init(model); + device_add(&keyboard_xt_device); + + machine_xt_common_init(model); return ret; } From 4db738cd53dca2fc47fc1e5720c7146bf25372c4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 07:17:45 +0200 Subject: [PATCH 28/30] Limited the 8086 Amstrads to a maximum of 10 MHz CPU's. --- src/machine/machine_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a1fa60f7d..8a242d984 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1892,7 +1892,7 @@ const machine_t machines[] = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -1930,7 +1930,7 @@ const machine_t machines[] = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -1968,7 +1968,7 @@ const machine_t machines[] = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2006,7 +2006,7 @@ const machine_t machines[] = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2044,7 +2044,7 @@ const machine_t machines[] = { .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, - .max_bus = 0, + .max_bus = 10000000, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, From 1ace98f656abbdd9e84fe92e26fd985f4961ed5b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 07:21:19 +0200 Subject: [PATCH 29/30] Corrected the Amstrad keyboards. --- src/machine/m_amstrad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 091642287..826474c16 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2598,10 +2598,10 @@ machine_amstrad_init(const machine_t *model, int type) io_sethandler(0x0060, 7, kbd_read, NULL, NULL, kbd_write, NULL, NULL, ams); timer_add(&ams->send_delay_timer, kbd_poll, ams, 1); - if (type == AMS_PC200) - keyboard_set_table(scancode_pc200); - else + if (type == AMS_PC1512) keyboard_set_table(scancode_xt); + else + keyboard_set_table(scancode_pc200); keyboard_send = kbd_adddata_ex; keyboard_scan = 1; keyboard_set_is_amstrad(((type == AMS_PC1512) || (type == AMS_PC1640)) ? 0 : 1); From ed675ca9cd1c095e9e6287db56cb36552fd03f60 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 21 Aug 2023 20:02:26 +0200 Subject: [PATCH 30/30] A fix in device/keyboard_xt.c to fix Toshiba T1x00 keyboard on Dev builds. --- src/device/keyboard_xt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index a5b5579a6..0f573ea5a 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -662,7 +662,7 @@ kbd_read(uint16_t port, void *priv) /* LaserXT = Always 512k RAM; LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ #if defined(DEV_BRANCH) && defined(USE_LASERXT) - if (kbd->type == KBD_TYPE_TOSHIBA) + if (kbd->type == KBD_TYPE_VTECH) ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00); else #endif